Point3f [] vertices = this.vertices.toArray(new Point3f [this.vertices.size()]);
TexCoord2f [] textureCoodinates =
this.textureCoodinates.toArray(new TexCoord2f [this.textureCoodinates.size()]);
Vector3f [] normals = this.normals.toArray(new Vector3f [this.normals.size()]);
SceneBase scene = new SceneBase();
BranchGroup sceneRoot = new BranchGroup();
scene.setSceneGroup(sceneRoot);
for (Group group : this.groups.values()) {
List<Geometry> geometries = group.getGeometry();
if (geometries != null
&& !geometries.isEmpty()) {
int i = 0;
while (i < geometries.size()) {
Geometry firstGeometry = geometries.get(i);
boolean firstGeometryHasTextureCoordinateIndices = firstGeometry.hasTextureCoordinateIndices();
boolean firstFaceHasNormalIndices = (firstGeometry instanceof Face) && ((Face)firstGeometry).hasNormalIndices();
String firstGeometryMaterial = firstGeometry.getMaterial();
Appearance appearance = getAppearance(firstGeometryMaterial);
// Search how many geometries share the same characteristics
int max = i;
while (++max < geometries.size()) {
Geometry geometry = geometries.get(max);
String material = geometry.getMaterial();
if (geometry.getClass() != firstGeometry.getClass()
|| material == null && firstGeometryMaterial != null
|| material != null && getAppearance(material) != appearance
|| (firstGeometryHasTextureCoordinateIndices ^ geometry.hasTextureCoordinateIndices())
|| (firstFaceHasNormalIndices ^ ((firstGeometry instanceof Face) && ((Face)geometry).hasNormalIndices()))) {
break;
}
}
// Create indices arrays for the faces with an index between i and max
int faceCount = max - i;
int indexCount = 0;
for (int j = 0; j < faceCount; j++) {
indexCount += geometries.get(i + j).getVertexIndices().length;
}
int [] coordinatesIndices = new int [indexCount];
int [] stripCounts = new int [faceCount];
for (int j = 0, destIndex = 0; j < faceCount; j++) {
int [] geometryVertexIndices = geometries.get(i + j).getVertexIndices();
System.arraycopy(geometryVertexIndices, 0, coordinatesIndices, destIndex, geometryVertexIndices.length);
stripCounts [j] = geometryVertexIndices.length;
destIndex += geometryVertexIndices.length;
}
int [] textureCoordinateIndices = null;
if (firstGeometryHasTextureCoordinateIndices) {
textureCoordinateIndices = new int [indexCount];
for (int j = 0, destIndex = 0; j < faceCount; j++) {
int [] geometryTextureCoordinateIndices = geometries.get(i + j).getTextureCoordinateIndices();
System.arraycopy(geometryTextureCoordinateIndices, 0, textureCoordinateIndices, destIndex, geometryTextureCoordinateIndices.length);
destIndex += geometryTextureCoordinateIndices.length;
}
}
GeometryArray geometryArray;
if (firstGeometry instanceof Face) {
GeometryInfo geometryInfo = new GeometryInfo(GeometryInfo.POLYGON_ARRAY);
geometryInfo.setCoordinates(vertices);
geometryInfo.setCoordinateIndices(coordinatesIndices);
geometryInfo.setStripCounts(stripCounts);
if (firstGeometryHasTextureCoordinateIndices) {
geometryInfo.setTextureCoordinateParams(1, 2);
geometryInfo.setTextureCoordinates(0, textureCoodinates);
geometryInfo.setTextureCoordinateIndices(0, textureCoordinateIndices);
}
if (firstFaceHasNormalIndices) {
int [] normalIndices = new int [indexCount];
for (int j = 0, destIndex = 0; j < faceCount; j++) {
int [] faceNormalIndices = ((Face)geometries.get(i + j)).getNormalIndices();
System.arraycopy(faceNormalIndices, 0, normalIndices, destIndex, faceNormalIndices.length);
destIndex += faceNormalIndices.length;
}
geometryInfo.setNormals(normals);
geometryInfo.setNormalIndices(normalIndices);
} else {
NormalGenerator normalGenerator = new NormalGenerator(Math.PI / 2);
if (!group.isSmooth()) {
normalGenerator.setCreaseAngle(0);
}
normalGenerator.generateNormals(geometryInfo);
}
geometryArray = geometryInfo.getGeometryArray(true, true, false);
} else { // Line
int format = IndexedGeometryArray.COORDINATES;
if (firstGeometryHasTextureCoordinateIndices) {
format |= IndexedGeometryArray.TEXTURE_COORDINATE_2;
}
// Use non indexed line array to avoid referencing the whole vertices
geometryArray = new LineStripArray(coordinatesIndices.length, format, stripCounts);
for (int j = 0; j < coordinatesIndices.length; j++) {
geometryArray.setCoordinate(j, vertices [coordinatesIndices [j]]);
}
if (firstGeometryHasTextureCoordinateIndices) {
for (int j = 0; j < coordinatesIndices.length; j++) {
geometryArray.setTextureCoordinate(0, j, textureCoodinates [textureCoordinateIndices [j]]);
}
}
}
// Clone appearance to avoid sharing it
if (appearance != null) {
appearance = (Appearance)appearance.cloneNodeComponent(false);
// Create texture coordinates if geometry doesn't define its own coordinates
// and appearance contains a texture
if (!firstGeometryHasTextureCoordinateIndices
&& appearance.getTexture() != null) {
appearance.setTexCoordGeneration(new TexCoordGeneration());
}
}
Shape3D shape = new Shape3D(geometryArray, appearance);
sceneRoot.addChild(shape);
scene.addNamedObject(group.getName() + (i == 0 ? "" : String.valueOf(i)), shape);
i = max;
}
}
}