package framework.model3D;
import java.util.ArrayList;
import java.util.Stack;
import javax.media.j3d.Geometry;
import javax.media.j3d.IndexedGeometryArray;
import javax.media.j3d.IndexedTriangleArray;
import javax.media.j3d.IndexedTriangleStripArray;
import javax.media.j3d.Shape3D;
import javax.media.j3d.Transform3D;
import com.sun.j3d.utils.geometry.GeometryInfo;
import com.sun.j3d.utils.geometry.Stripifier;
public class GeometryCollector extends ObjectVisitor{
private int totalVertexCount = 0;
private int totalIndexCount = 0;
private ArrayList<Geometry> geometryList = new ArrayList<Geometry>(); // 葉のとき、Geometryを保存
IndexedGeometryArray geometry = null;
// private Stack<Transform3D> transforms = new Stack<Transform3D>();
int i=0;
int j=0;
//コンストラクタ
// public GeometryCollector() {
// Transform3D t = new Transform3D();
// transforms.push(t);
// }
@Override
public void preVisit(Object3D obj) {
// TODO Auto-generated method stub
if(obj.hasChildren()){
// System.out.println("pre"+i);
// i++;
}else{
// System.out.println("pre"+i+" Leaf");
// i++;
Geometry g = ((Shape3D)obj.getBody().getPrimitiveNode()).getGeometry();
geometryList.add(g);
totalVertexCount += ((IndexedGeometryArray)g).getVertexCount();
totalIndexCount += ((IndexedGeometryArray)g).getIndexCount();
}
}
@Override
public void postVisit(Object3D obj) {
// TODO Auto-generated method stub
if(obj.hasChildren()){
// System.out.println("post"+j);
j++;
}else{
// System.out.println("post"+j+" Leaf");
j++;
}
}
public Geometry getGeometry(){
if (geometry == null) {
// リスト中の複数の Geometry を1つにまとめる
int coordinateOfs = 0;
int indexOfs = 0;
double coodinates[] = new double[totalVertexCount * 3];
int indicies[] = new int[totalIndexCount];
for (int n = 0; n < geometryList.size(); n++) {
IndexedGeometryArray geometry = (IndexedGeometryArray)geometryList.get(n);
double tmpCoordinates[] = new double[geometry.getVertexCount() * 3];
geometry.getCoordinates(0, tmpCoordinates);
System.arraycopy(tmpCoordinates, 0, coodinates, coordinateOfs * 3, geometry.getVertexCount() * 3);
int tmpIndicies[] = new int[geometry.getIndexCount()];
geometry.getCoordinateIndices(0, tmpIndicies);
for (int m = 0; m < geometry.getIndexCount(); m++) {
tmpIndicies[m] += coordinateOfs;
}
System.arraycopy(tmpIndicies, 0, indicies, indexOfs, geometry.getIndexCount());
coordinateOfs += geometry.getVertexCount();
indexOfs += geometry.getIndexCount();
}
geometry = new IndexedTriangleArray(totalVertexCount, IndexedTriangleArray.COORDINATES, totalIndexCount);
geometry.setCoordinates(0, coodinates);
geometry.setCoordinateIndices(0, indicies);
// 重複している頂点を1つにまとめる
GeometryUtility.compressGeometry(geometry);
// // IndexedTriangleStripArray に変換(重複している頂点を1つにまとめるため)
// GeometryInfo gi = new GeometryInfo(geometry);
// Stripifier sf = new Stripifier();
// sf.stripify(gi);
// geometry = gi.getIndexedGeometryArray(); // IndexedTriangleStripArray が返される
//
// // IndexedTriangleArray に変換(GeometryGraph が IndexedTriangleStripArray に未対応のため)
// if (geometry instanceof IndexedTriangleStripArray) {
// int numStrips = ((IndexedTriangleStripArray)geometry).getNumStrips();
// int indexCounts[] = new int[numStrips];
// ((IndexedTriangleStripArray)geometry).getStripIndexCounts(indexCounts);
// int dstIndicies[] = new int[(((IndexedTriangleStripArray)geometry).getIndexCount() - numStrips * 2) * 3];
// int dstOfs = 0;
// int srcOfs = 0;
// for (int s = 0; s < numStrips; s++) {
// for (int i = 2; i < indexCounts[s]; i += 2) {
// dstIndicies[dstOfs] = ((IndexedTriangleStripArray)geometry).getCoordinateIndex(srcOfs + i - 2);
// dstIndicies[dstOfs + 1] = ((IndexedTriangleStripArray)geometry).getCoordinateIndex(srcOfs + i - 1);
// dstIndicies[dstOfs + 2] = ((IndexedTriangleStripArray)geometry).getCoordinateIndex(srcOfs + i);
// dstOfs += 3;
// if (i + 1 < indexCounts[s]) {
// dstIndicies[dstOfs] = ((IndexedTriangleStripArray)geometry).getCoordinateIndex(srcOfs + i);
// dstIndicies[dstOfs + 1] = ((IndexedTriangleStripArray)geometry).getCoordinateIndex(srcOfs + i - 1);
// dstIndicies[dstOfs + 2] = ((IndexedTriangleStripArray)geometry).getCoordinateIndex(srcOfs + i + 1);
// dstOfs += 3;
// }
// }
// srcOfs += indexCounts[s];
// }
//
// int vertexCount = ((IndexedTriangleStripArray)geometry).getVertexCount();
// coodinates = new double[vertexCount * 3];
// ((IndexedTriangleStripArray)geometry).getCoordinates(0, coodinates);
//
// geometry = new IndexedTriangleArray(vertexCount, IndexedTriangleArray.COORDINATES, dstIndicies.length);
// geometry.setCoordinates(0, coodinates);
// geometry.setCoordinateIndices(0, dstIndicies);
// }
}
return geometry;
}
}