package framework.physics;
import java.util.ArrayList;
import java3d.BoundingSphere;
import framework.model3D.OBB;
import framework.model3D.Object3D;
import framework.model3D.ObjectVisitor;
public class BoundingBoxVisitor extends ObjectVisitor {
private ArrayList<OBB> obbList = new ArrayList<OBB>(); // 全構成要素のOBBのリスト
private ArrayList<BoundingSphere> bsStack = new ArrayList<BoundingSphere>(); // オブジェクトの階層毎のBoundingSphereのスタック
private String partName = null; // 部品を指定する場合に使う
private boolean inPart = false;
public BoundingBoxVisitor() {
partName = null;
}
public BoundingBoxVisitor(String partName) {
this.partName = partName;
}
public void preVisit(Object3D obj) {
pushTransform(obj);
if (partName != null && obj.name.equals(partName)) {
inPart = true;
}
if (obj.hasChildren() && obj.bs == null) {
// 子供がいる場合、下の階層用にnullをpushする
bsStack.add(null);
}
}
public void postVisit(Object3D obj) {
int pattern = 2;
if (!obj.hasChildren()) {
// 葉の場合
OBB obb = obj.getOBB(pattern);
if (obb != null) {
if (obj.bs == null) {
obj.bs = obb.getBoundingSphere();
}
obb = (OBB)obb.clone();
BoundingSphere bs = (BoundingSphere)obj.bs.clone();
for (int i = stackList.size() - 1; i >= 0; i--) {
obb.transform(stackList.get(i));
bs.transform(stackList.get(i));
}
if (partName == null || partName.length() == 0 || inPart) {
obbList.add(obb); // Transform3Dを適応させたBoundsをboundsListに追加
int stackTop = bsStack.size() - 1;
if (bs != null && stackTop >= 0) {
if (bsStack.get(stackTop) == null) {
// その階層の最初のオブジェクトの場合、nullを置き換え
bsStack.set(stackTop, bs);
} else {
// その階層の2番目以降のオブジェクトの場合、結合
bsStack.get(stackTop).combine(bs);
}
}
}
}
} else {
// 子供がいる場合
int stackTop = bsStack.size() - 1;
if (obj.bs == null) {
// 下の階層の結合結果をpopして利用する
obj.bs = bsStack.remove(stackTop);
stackTop--;
}
if (obj.bs != null && stackTop >= 0) {
if (bsStack.get(stackTop) == null) {
// その階層の最初のオブジェクトの場合、nullを置き換え
bsStack.set(stackTop, obj.bs);
} else {
// その階層の2番目以降のオブジェクトの場合、結合
bsStack.get(stackTop).combine(obj.bs);
}
}
}
popTransform();
if (partName != null && obj.name.equals(partName)) {
inPart = false;
}
}
public ArrayList<OBB> getObbList() {
return obbList;
}
}