Shape3D.java
package com.gwief.jTrace;
/*
Shape3D.java by Damian Newport
Stores and implements behavior of a shape
*/
public class Shape3D extends CSGnode{
/* constants */
final int DEFAULT = 0;
String name;
int shape; // 0 = sphere, 1 = cube, 2 = cylinder, 3 = cone, 4 = hyperboloid, 5 = plane
Transform3D transform;
Material material;
Transform3D ntransform;
public Shape3D(String Name){
name = Name;
shape = DEFAULT;
transform = new Transform3D();
material = new Material();
}
public Shape3D(String Name, int type){
name = Name;
shape = type;
transform = new Transform3D();
material = new Material();
}
final public void setshape(int a){shape = a;}
final public void settransform(Transform3D a){transform = a;}
final public void setmaterial(Material a){material = a; }
final public int getshape(){return shape;}
final public Transform3D gettransform(){return transform; }
final public Material getmaterial(){return material; }
public final void build(Transform3D ntrans){
ntransform = new Transform3D(ntrans);
ntransform.multiply(transform);
}
final Intersection[] getBranch(Ray ray){
Ray temp = ntransform.Transform(ray);
double[] result;
temp.direction.unit();
if (rayTrace.bugmode){
System.out.println("---------"+name+"---------------");
System.out.println(ntransform.out());
System.out.println(name + ".ray.org=" + ray.origin.out());
System.out.println(name + ".ray.dir=" + ray.direction.out());
System.out.println(name + ".temp.org=" + temp.origin.out());
System.out.println(name + ".temp.dir=" + temp.direction.out());
}
switch(shape){
case 0 : // sphere
result = Sphere.intersect(temp);
break;
case 1 : // cube
result = Box.intersect(temp);
break;
case 2 : // cylinder
result = Cylinder.intersect(temp);
break;
case 3 : // cone
result = Cone.intersect(temp);
break;
case 4 : // hyperboloid
result = Hyperboloid.intersect(temp);
case 5 : // plane
result = Plane.intersect(temp);
break;
default :
result = new double[0];
}
int length = result.length;
if (length > 0){
int type = 1;
Intersection[] inters = new Intersection[length];
for (int i = 0; i < length; i++){
Vector3D work = new Vector3D(temp.direction);
work.multiply(result[i]);
work.add(temp.origin);
work = ntransform.iTransform(work);
work.minus(ray.origin);
if (result[i] < 0){ // to keep original sign
result[i] = -1;
}else{
result[i] = 1;
}
result[i] *= work.modulus();
inters[i] = new Intersection(type, result[i], this);
type *= -1;
if (rayTrace.bugmode){
System.out.println(name + ".result["+i+"]="+result[i]);
}
}
return inters;
}else{
return new Intersection[0];
}
}
public final Vector3D getNormal(Vector3D a){
switch(shape){
case 0 : // sphere
return sphereNormal(a);
case 1 : // box
return boxNormal(a);
case 2 : // cylinder
return cylinderNormal(a);
case 3 : // cone
return coneNormal(a);
case 4 : // hyperboloid
return hyperboloidNormal(a);
case 5 : // hyperboloid
return planeNormal(a);
default :
System.out.println("Error! Unknown shape '" + shape + "'");
System.exit(1);
return a;
}
}
private final Vector3D sphereNormal(Vector3D a){
Vector3D temp = ntransform.Transform(a);
temp = Sphere.normal(temp);
temp = ntransform.piTransform(temp);
temp.unit();
return temp;
}
private final Vector3D boxNormal(Vector3D a){
Vector3D temp = ntransform.Transform(a);
temp = Box.normal(temp);
temp = ntransform.piTransform(temp);
temp.unit();
return temp;
}
private final Vector3D cylinderNormal(Vector3D a){
Vector3D temp = ntransform.Transform(a);
temp = Cylinder.normal(temp);
temp = ntransform.piTransform(temp);
temp.unit();
return temp;
}
private final Vector3D coneNormal(Vector3D a){
Vector3D temp = ntransform.Transform(a);
temp = Cone.normal(temp);
temp = ntransform.piTransform(temp);
temp.unit();
return temp;
}
private final Vector3D hyperboloidNormal(Vector3D a){
Vector3D temp = ntransform.Transform(a);
temp = Hyperboloid.normal(temp);
temp = ntransform.piTransform(temp);
temp.unit();
return temp;
}
private final Vector3D planeNormal(Vector3D a){
Vector3D temp = ntransform.Transform(a);
temp = Plane.normal(temp);
temp = ntransform.piTransform(temp);
temp.unit();
return temp;
}
}