CSGnode.java
package com.gwief.jTrace;
/*
CSGnode.java by Damian Newport
acts as a node in the CSGtree
Implements behavior to trace the tree
*/
import java.util.ArrayList;
public class CSGnode {
Transform3D transform;
CSGnode nodea;
CSGnode nodeb;
int op; // 0 = union, 1 = intersection, 2 = difference, 3 = subtraction
public CSGnode(){
// do nothing
}
public CSGnode(CSGnode x ,int operator ,CSGnode y) {
nodea = x;
op = operator;
nodeb = y;
transform = new Transform3D();
}
public void settransform(Transform3D a){transform = a; }
public Transform3D gettransform(){return transform; }
Intersection[] getBranch(Ray ray){
Intersection[] setA = nodea.getBranch(ray);
Intersection[] setB = nodeb.getBranch(ray);
int length = setA.length + setB.length;
ArrayList output = new ArrayList();
int current = 0;
Intersection[] sorted = new Intersection[0];
if (length == 0){ return sorted; }
switch(op){
case 0 : // union
if (setA.length == 0) {return setB; }
if (setB.length == 0) {return setA; }
sorted = Intersection.mergeIntersections(setA, setB);
for(int i = 0; i < length; i++){
current = current + sorted[i].type;
if((current == 1) && (sorted[i].type > 0)){
output.add(sorted[i]);
}else if((current == 0) && (sorted[i].type < 0)){
output.add(sorted[i]);
}
}
break;
case 1 : // intersection
if (setA.length == 0) {return sorted; }
if (setB.length == 0) {return sorted; }
sorted = Intersection.mergeIntersections(setA, setB);
for(int i = 0; i < length; i++){
current = current + sorted[i].type;
if((current == 2) && (sorted[i].type > 0)){
output.add(sorted[i]);
}else if((current == 1) && (sorted[i].type < 0)){
output.add(sorted[i]);
}
}
break;
case 2 : // difference
if (setA.length == 0) {return setB; }
if (setB.length == 0) {return setA; }
sorted = Intersection.mergeIntersections(setA, setB);
for(int i = 0; i < length; i++){
current = current + sorted[i].type;
if((current == 1) && (sorted[i].type > 0)){
output.add(sorted[i]);
}else if((current == 2) && (sorted[i].type > 0)){
sorted[i].type = -1;
output.add(sorted[i]);
}else if((current == 1) && (sorted[i].type < 0)){
sorted[i].type = 1;
output.add(sorted[i]);
}else if((current == 0) && (sorted[i].type < 0)){
output.add(sorted[i]);
}
}
break;
case 3 : // subtraction
if (setA.length == 0) {return sorted; }
if (setB.length == 0) {return setA; }
int lengthB = setB.length;
for(int j = 0; j < lengthB; j++){
setB[j].type = setB[j].type * -1;
}
sorted = Intersection.mergeIntersections(setA, setB);
for(int i = 0; i < length; i++){
current = current + sorted[i].type;
if((current == 1) && (sorted[i].type > 0)){
output.add(sorted[i]);
}else if((current == 0) && (sorted[i].type < 0)){
output.add(sorted[i]);
}
}
break;
default :
System.out.println("Error! Unidentified operator in CSGnode : " + op);
System.exit(1);
}
Intersection[] empty = new Intersection[output.size()];
output.toArray(empty);
return empty;
}
public void build(Transform3D ntrans){
Transform3D ttrans = new Transform3D(ntrans);
ttrans.multiply(transform);
nodea.build(ttrans);
nodeb.build(ttrans);
}
}