|
From: <tre...@us...> - 2007-09-24 06:53:27
|
Revision: 433
http://ogoglio.svn.sourceforge.net/ogoglio/?rev=433&view=rev
Author: trevorolio
Date: 2007-09-23 23:53:23 -0700 (Sun, 23 Sep 2007)
Log Message:
-----------
Added a data manager which holds all template geometry and appearance in a cache for reuse, and eventually for smarter memory management. Firefox really likes to crash the entire browser when its JVM stack is full so we're going to need to prevent that from happening. We can't just catch the OutOfMemoryExceptions because by then it has segfaulted. *sigh*
Modified Paths:
--------------
maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/J3DRenderableLoader.java
maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/J3DRenderer.java
maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/J3DUserRenderable.java
maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/body/BodyAnimator.java
maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/obj/MtlParser.java
maven/trunk/ogoglio-common/src/main/resources/avatar/female.obj
maven/trunk/ogoglio-common/src/main/resources/avatar/female.smap
Added Paths:
-----------
maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/J3DDataCache.java
maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/J3DDataManager.java
maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/J3DTemplateData.java
Added: maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/J3DDataCache.java
===================================================================
--- maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/J3DDataCache.java (rev 0)
+++ maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/J3DDataCache.java 2007-09-24 06:53:23 UTC (rev 433)
@@ -0,0 +1,41 @@
+/* Copyright 2007 Transmutable (http://transmutable.com/)
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License. */
+package com.ogoglio.viewer.j3d;
+
+import java.util.HashMap;
+
+public class J3DDataCache {
+
+ private HashMap templateDataMap = new HashMap(); //maps template guid to GeometryCacheEntry objects
+
+ public J3DTemplateData getTemplateData(long templateID, int lod) {
+ return (J3DTemplateData) templateDataMap.get(createGUID(templateID, lod));
+ }
+
+ public void putTemplateData(long templateID, int lod, J3DTemplateData entry) {
+ templateDataMap.put(createGUID(templateID, lod), entry);
+ }
+
+ private String createGUID(long id, int lod){
+ return id + "-" + lod;
+ }
+
+ private long getIDFromGUID(String guid){
+ return Long.parseLong(guid.split("-")[0]);
+ }
+
+ private long getLODFromGUID(String guid){
+ return Long.parseLong(guid.split("-")[1]);
+ }
+}
Added: maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/J3DDataManager.java
===================================================================
--- maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/J3DDataManager.java (rev 0)
+++ maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/J3DDataManager.java 2007-09-24 06:53:23 UTC (rev 433)
@@ -0,0 +1,315 @@
+package com.ogoglio.viewer.j3d;
+
+import java.awt.Image;
+import java.io.BufferedInputStream;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Vector;
+
+import javax.imageio.ImageIO;
+import javax.media.j3d.Appearance;
+import javax.media.j3d.Geometry;
+import javax.media.j3d.GeometryArray;
+import javax.media.j3d.ImageComponent;
+import javax.media.j3d.Material;
+import javax.media.j3d.RenderingAttributes;
+import javax.media.j3d.Texture;
+import javax.media.j3d.TextureAttributes;
+import javax.media.j3d.TransparencyAttributes;
+import javax.vecmath.Color3f;
+import javax.vecmath.Point3f;
+import javax.vecmath.TexCoord2f;
+
+import com.ogoglio.client.model.GeometryProvider;
+import com.ogoglio.util.Log;
+import com.ogoglio.viewer.j3d.obj.Obj;
+import com.ogoglio.viewer.j3d.obj.ObjMtl;
+import com.ogoglio.viewer.j3d.obj.ObjParseException;
+import com.ogoglio.viewer.j3d.obj.ObjParser;
+import com.sun.j3d.utils.geometry.GeometryInfo;
+import com.sun.j3d.utils.geometry.NormalGenerator;
+import com.sun.j3d.utils.geometry.Stripifier;
+import com.sun.j3d.utils.image.TextureLoader;
+
+public class J3DDataManager {
+
+ public static Appearance DEFAULT_APPEARANCE = new Appearance();
+
+ private static Material DEFAULT_MATERIAL = new Material();
+ static {
+ DEFAULT_MATERIAL.setAmbientColor(new Color3f(1, 1, 1));
+ DEFAULT_MATERIAL.setDiffuseColor(new Color3f(0.1f, 0.1f, 0.1f));
+ DEFAULT_MATERIAL.setSpecularColor(new Color3f(1, 1, 1));
+ DEFAULT_MATERIAL.setShininess(1);
+ DEFAULT_MATERIAL.setLightingEnable(true);
+
+ DEFAULT_APPEARANCE.setMaterial(DEFAULT_MATERIAL);
+ }
+
+ private GeometryProvider errorGeometryProvider = null;
+
+ private J3DDataCache dataCache = new J3DDataCache();
+
+ private boolean loadAppearances = true;
+
+ public J3DDataManager(boolean loadAppearances) {
+ this.loadAppearances = loadAppearances;
+ }
+
+ public J3DTemplateData[] getTemplateData(long templateID, GeometryProvider geoProvider, boolean useCache) {
+ J3DTemplateData[] results = new J3DTemplateData[GeometryProvider.LOD_DISTANCES.length + 1];
+ if (useCache) {
+ boolean hitCache = false;
+ for (int i = 0; i < results.length; i++) {
+ results[i] = dataCache.getTemplateData(templateID, i);
+ hitCache = hitCache || results[i] != null;
+ }
+ if (hitCache) {
+ return results;
+ }
+ }
+
+ fetchTemplateData(templateID, geoProvider, results);
+ for (int i = 0; i < results.length; i++) {
+ if (results[i] == null) {
+ continue;
+ }
+ dataCache.putTemplateData(templateID, i, results[i]);
+ }
+
+ return results;
+ }
+
+ private void fetchTemplateData(long templateID, GeometryProvider geoProvider, J3DTemplateData[] results) {
+ Obj[] objs = getObjs(geoProvider, templateID);
+
+ HashMap textures = new HashMap();
+ for (int i = 0; i < objs.length; i++) {
+ if (objs[i] == null) {
+ continue;
+ }
+ results[i] = new J3DTemplateData();
+
+ Obj.Group[] groups = objs[i].getGroups();
+ for (int g = 0; g < groups.length; g++) {
+ Geometry geometry = generateGeometry(geoProvider, groups[g]);
+ results[i].putGeometry(groups[g].getName(), geometry);
+ Appearance appearance = generateAppearance(geoProvider, groups[g], textures);
+ results[i].putAppearances(groups[g].getName(), appearance);
+ }
+ }
+ textures.clear();
+ }
+
+ private Geometry generateGeometry(GeometryProvider geoProvider, Obj.Group group) {
+ //TODO consider a more memory efficient way to load shapes
+ Obj.Range[] ranges = group.getRanges();
+ if (ranges.length == 0) {
+ Log.error("Zero range group: " + group.getName());
+ return null;
+ }
+
+ Vector textureVertices = new Vector();
+ Vector vertices = new Vector();
+ Vector stripCounts = new Vector();
+ for (int i = 0; i < ranges.length; i++) { //for each range
+ for (int j = ranges[i].getLower(); j <= ranges[i].getUpper(); j++) { //for each face in range
+ stripCounts.add(new Integer(addFaceVertices(group.getObj(), j, vertices, textureVertices)));
+ }
+ }
+
+ if (vertices.size() == 0) {
+ Log.error("Empty group: " + group.getName());
+ return null;
+ }
+
+ Point3f[] vertexPoints = (Point3f[]) vertices.toArray(new Point3f[0]);
+ int[] stripCountInts = new int[stripCounts.size()];
+ int total = 0;
+ for (int i = 0; i < stripCounts.size(); i++) {
+ stripCountInts[i] = ((Integer) stripCounts.get(i)).intValue();
+ total += stripCountInts[i];
+ }
+
+ int[] coordinateIndices = new int[vertexPoints.length];
+ for (int i = 0; i < coordinateIndices.length; i++) {
+ coordinateIndices[i] = i;
+ }
+
+ GeometryInfo gi = new GeometryInfo(GeometryInfo.POLYGON_ARRAY);
+ gi.setStripCounts(stripCountInts);
+ gi.setCoordinates(vertexPoints);
+ gi.setCoordinateIndices(coordinateIndices);
+
+ TexCoord2f[] texCoords = new TexCoord2f[vertexPoints.length];
+ int[] texCoordIndices = new int[vertexPoints.length];
+ for (int i = 0; i < texCoordIndices.length; i++) {
+ texCoordIndices[i] = i;
+ }
+
+ Point3f textVertex = null;
+ for (int i = 0; i < texCoords.length; i++) {
+ textVertex = (Point3f) textureVertices.get(i);
+ texCoords[i] = new TexCoord2f(textVertex.x, textVertex.y);
+ }
+
+ gi.setTextureCoordinateParams(1, 2); //one set with two dimensions
+ gi.setTextureCoordinateIndices(0, texCoordIndices);
+ gi.setTextureCoordinates(0, texCoords);
+
+ new NormalGenerator(-1.0f).generateNormals(gi);
+ new Stripifier().stripify(gi);
+ GeometryArray geometryArray = gi.getGeometryArray(false, false, false);
+ geometryArray.setCapability(GeometryArray.ALLOW_COORDINATE_READ);
+ geometryArray.setCapability(GeometryArray.ALLOW_COUNT_READ);
+ geometryArray.setCapability(GeometryArray.ALLOW_FORMAT_READ);
+ geometryArray.setCapability(GeometryArray.ALLOW_INTERSECT);
+
+ return geometryArray;
+ }
+
+ private int addFaceVertices(Obj obj, int faceIndex, Vector vertices, Vector textureCoordinates) {
+ int[][] faceIndices = obj.getFaceIndices(faceIndex);
+ for (int i = 0; i < faceIndices.length; i++) {
+ vertices.add(obj.getVertex(faceIndices[i][0]));
+ if (faceIndices[i].length > 1 && faceIndices[i][1] != -1) {
+ textureCoordinates.add(obj.getTextureVertex(faceIndices[i][1]));
+ } else {
+ textureCoordinates.add(new Point3f());
+ }
+ }
+ return faceIndices.length;
+ }
+
+ private Appearance generateAppearance(GeometryProvider geoProvider, Obj.Group group, HashMap textures) {
+ Obj.Range[] ranges = group.getRanges();
+ ObjMtl.Material material = group.getObj().getMaterialForFace(ranges[0].getLower());
+ if (material == null) {
+ return DEFAULT_APPEARANCE;
+ }
+
+ Appearance appearance = new Appearance();
+ appearance.setCapability(Appearance.ALLOW_TEXTURE_WRITE);
+ Material j3dMaterial = new Material();
+ appearance.setMaterial(j3dMaterial);
+
+ Color3f ambientColor = new Color3f();
+ material.getAmbientColor(ambientColor);
+ j3dMaterial.setAmbientColor(ambientColor);
+
+ Color3f diffuseColor = new Color3f();
+ material.getDiffuseColor(diffuseColor);
+ j3dMaterial.setDiffuseColor(diffuseColor);
+
+ Color3f specularColor = new Color3f();
+ material.getSpecularColor(specularColor);
+ j3dMaterial.setSpecularColor(specularColor);
+
+ if (material.getDissolve() != 1) {
+ TransparencyAttributes tAttribs = new TransparencyAttributes(TransparencyAttributes.BLENDED, material.getDissolve());
+ appearance.setTransparencyAttributes(tAttribs);
+ }
+
+ if (material.getSpecularExponent() != -1) {
+ //TODO figure out why shininess appears to have no effect
+ }
+
+ if (material.getDiffuseMapName() != null) { //Woot, texture!
+ try {
+ Texture texImage = (Texture) textures.get(material.getDiffuseMapName());
+
+ if (texImage == null) {
+ InputStream imageStream = geoProvider.getSubGeometryStream(material.getDiffuseMapName());
+ if (imageStream != null) {
+ Image image = ImageIO.read(new BufferedInputStream(imageStream));
+ if (image != null) {
+ //I don't really care for any of these formats
+ // LUMINANCE is nice for a film noir effect
+ if (material.getDiffuseMapName().startsWith("transparent_")) {
+ texImage = new TextureLoader(image, "RGBA", null).getTexture();
+ } else {
+ texImage = new TextureLoader(image, "RGB", null).getTexture();
+ }
+ textures.put(material.getDiffuseMapName(), texImage);
+ }
+ imageStream.close();
+ }
+ }
+ if (texImage != null) {
+ texImage.getImage(0).setCapability(ImageComponent.ALLOW_SIZE_READ);
+ texImage.getImage(0).setCapability(ImageComponent.ALLOW_IMAGE_READ);
+ texImage.getImage(0).setCapability(ImageComponent.ALLOW_IMAGE_WRITE);
+ appearance.setTexture(texImage);
+
+ TextureAttributes textureAttributes = new TextureAttributes();
+ textureAttributes.setTextureMode(TextureAttributes.MODULATE);
+ appearance.setTextureAttributes(textureAttributes);
+
+ // this is a hack so that only textures named transparent_* get these attributes set
+ // otherwise we get all kinds of bad ordering problems
+ //TODO figure out what the right thing is for transparent texture attributes
+ if (material.getDiffuseMapName().startsWith("transparent_")) {
+ TextureAttributes textureAtts = new TextureAttributes();
+ textureAtts.setTextureMode(TextureAttributes.REPLACE);
+ appearance.setTextureAttributes(textureAtts);
+
+ TransparencyAttributes tAttribs = new TransparencyAttributes(TransparencyAttributes.BLENDED, 0, TransparencyAttributes.BLEND_SRC_ALPHA, TransparencyAttributes.BLEND_ONE_MINUS_SRC_ALPHA);
+ appearance.setTransparencyAttributes(tAttribs);
+ appearance.setRenderingAttributes(new RenderingAttributes());
+ }
+
+ }
+
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+
+ return appearance;
+ }
+
+ private Obj[] getObjs(GeometryProvider geoProvider, long templateID) {
+ boolean gotObj = false;
+ Obj[] objs = new Obj[GeometryProvider.LOD_DISTANCES.length + 1];
+ try {
+ for (int i = 0; i < objs.length; i++) {
+ objs[i] = getObj(geoProvider, i);
+ if (objs[i] != null && objs[i].getGroups().length == 0) {
+ Log.error("Got obj with no groups for template " + templateID);
+ objs[i] = null;
+ }
+ if (!gotObj && objs[i] != null) {
+ gotObj = true;
+ }
+ }
+ } catch (ObjParseException e) {
+ Log.error("Error parsing obj: " + e);
+ }
+ if (!gotObj) {
+ try {
+ objs[0] = getObj(errorGeometryProvider, 0);
+ } catch (ObjParseException e) {
+ throw new IllegalStateException("Error parsing the error template?!?");
+ }
+
+ }
+ if (objs[0] == null) {
+ throw new IllegalStateException("Where's my error template?");
+ }
+ return objs;
+ }
+
+ private Obj getObj(GeometryProvider provider, int lodIndex) throws ObjParseException {
+ if (lodIndex != 0) {
+ return null;
+ }
+ try {
+ ObjParser parser = new ObjParser(provider, lodIndex);
+ return parser.parse();
+ } catch (Exception e) {
+ System.err.println("Could not load obj: " + e);
+ return null;
+ }
+ }
+
+}
Modified: maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/J3DRenderableLoader.java
===================================================================
--- maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/J3DRenderableLoader.java 2007-09-23 00:32:43 UTC (rev 432)
+++ maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/J3DRenderableLoader.java 2007-09-24 06:53:23 UTC (rev 433)
@@ -14,289 +14,88 @@
package com.ogoglio.viewer.j3d;
-import java.awt.Image;
-import java.io.BufferedInputStream;
-import java.io.InputStream;
import java.util.HashMap;
import java.util.Vector;
-import javax.imageio.ImageIO;
import javax.media.j3d.Appearance;
-import javax.media.j3d.GeometryArray;
-import javax.media.j3d.ImageComponent;
-import javax.media.j3d.Material;
-import javax.media.j3d.RenderingAttributes;
+import javax.media.j3d.Geometry;
import javax.media.j3d.Shape3D;
-import javax.media.j3d.Texture;
-import javax.media.j3d.TextureAttributes;
-import javax.media.j3d.TransparencyAttributes;
-import javax.vecmath.Color3f;
-import javax.vecmath.Point3f;
-import javax.vecmath.TexCoord2f;
import com.ogoglio.client.model.Door;
import com.ogoglio.client.model.GeometryProvider;
import com.ogoglio.client.model.Shape;
import com.ogoglio.client.model.Thing;
-import com.ogoglio.util.Log;
-import com.ogoglio.viewer.j3d.obj.Obj;
-import com.ogoglio.viewer.j3d.obj.ObjMtl;
+import com.ogoglio.util.ArgumentUtils;
import com.ogoglio.viewer.render.Renderable;
-import com.sun.j3d.utils.geometry.GeometryInfo;
-import com.sun.j3d.utils.geometry.NormalGenerator;
-import com.sun.j3d.utils.image.TextureLoader;
public class J3DRenderableLoader {
- public static Appearance DEFAULT_APPEARANCE = new Appearance();
+ private J3DTemplateData[] templateData = null;
- private static Material DEFAULT_MATERIAL = new Material();
- static {
- DEFAULT_MATERIAL.setAmbientColor(new Color3f(1, 1, 1));
- DEFAULT_MATERIAL.setDiffuseColor(new Color3f(0.1f, 0.1f, 0.1f));
- DEFAULT_MATERIAL.setSpecularColor(new Color3f(1, 1, 1));
- DEFAULT_MATERIAL.setShininess(1);
- DEFAULT_MATERIAL.setLightingEnable(true);
-
- DEFAULT_APPEARANCE.setMaterial(DEFAULT_MATERIAL);
+ public J3DRenderableLoader(J3DTemplateData[] templateData) {
+ this.templateData = templateData;
}
- private Obj[] objs = null;
-
- private HashMap textures = new HashMap();
-
- boolean loadMaterials = true;
-
- public J3DRenderableLoader(Obj[] objs, boolean loadMaterials) {
- this.objs = objs;
- this.loadMaterials = loadMaterials;
- }
-
- private J3DShapeRenderable generateShape(GeometryProvider geoProvider, Renderable renderable, Obj.Group group) {
- //TODO consider a more memory efficient way to load shapes
- Obj.Range[] ranges = group.getRanges();
- if (ranges.length == 0) {
- Log.error("Zero range group: " + group.getName());
- return null;
- }
-
- Vector textureVertices = new Vector();
- Vector vertices = new Vector();
- Vector stripCounts = new Vector();
- for (int i = 0; i < ranges.length; i++) { //for each range
- for (int j = ranges[i].getLower(); j <= ranges[i].getUpper(); j++) { //for each face in range
- stripCounts.add(new Integer(addFaceVertices(group.getObj(), j, vertices, textureVertices)));
- }
- }
-
- if (vertices.size() == 0) {
- Log.error("Empty group: " + group.getName());
- return null;
- }
-
- Point3f[] vertexPoints = (Point3f[]) vertices.toArray(new Point3f[0]);
- int[] stripCountInts = new int[stripCounts.size()];
- int total = 0;
- for (int i = 0; i < stripCounts.size(); i++) {
- stripCountInts[i] = ((Integer) stripCounts.get(i)).intValue();
- total += stripCountInts[i];
- }
-
- int[] coordinateIndices = new int[vertexPoints.length];
- for (int i = 0; i < coordinateIndices.length; i++) {
- coordinateIndices[i] = i;
- }
-
- GeometryInfo gi = new GeometryInfo(GeometryInfo.POLYGON_ARRAY);
- gi.setStripCounts(stripCountInts);
- gi.setCoordinates(vertexPoints);
- gi.setCoordinateIndices(coordinateIndices);
-
- TexCoord2f[] texCoords = new TexCoord2f[vertexPoints.length];
- int[] texCoordIndices = new int[vertexPoints.length];
- for (int i = 0; i < texCoordIndices.length; i++) {
- texCoordIndices[i] = i;
- }
-
- Point3f textVertex = null;
- for (int i = 0; i < texCoords.length; i++) {
- textVertex = (Point3f) textureVertices.get(i);
- texCoords[i] = new TexCoord2f(textVertex.x, textVertex.y);
- }
-
- gi.setTextureCoordinateParams(1, 2); //one set with two dimensions
- gi.setTextureCoordinateIndices(0, texCoordIndices);
- gi.setTextureCoordinates(0, texCoords);
-
- new NormalGenerator(-1.0f).generateNormals(gi);
- GeometryArray geometryArray = gi.getGeometryArray(false, false, false);
- geometryArray.setCapability(GeometryArray.ALLOW_COORDINATE_READ);
- geometryArray.setCapability(GeometryArray.ALLOW_COUNT_READ);
- geometryArray.setCapability(GeometryArray.ALLOW_FORMAT_READ);
- geometryArray.setCapability(GeometryArray.ALLOW_INTERSECT);
-
- Shape shape = null;
- if (renderable instanceof J3DThingRenderable) {
- Thing thing = ((J3DThingRenderable) renderable).getThing();
- shape = thing.getShape(group.getName());
- if (shape == null) {
- shape = new Shape(thing, group.getName());
- ((J3DThingRenderable) renderable).getThing().addShape(shape);
- }
- }
-
- J3DShapeRenderable shapeRenderable = new J3DShapeRenderable(renderable, shape);
- shapeRenderable.getInnerShape().setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
- shapeRenderable.getInnerShape().setCapability(Shape3D.ALLOW_GEOMETRY_READ);
- shapeRenderable.getInnerShape().setCapability(Shape3D.ALLOW_PICKABLE_READ);
- shapeRenderable.getInnerShape().addGeometry(geometryArray);
-
- ObjMtl.Material objMat = group.getObj().getMaterialForFace(ranges[0].getLower());
- if (loadMaterials && objMat != null) {
- shapeRenderable.getInnerShape().setAppearance(getAppearance(geoProvider, objMat));
- } else {
- shapeRenderable.getInnerShape().setAppearance(DEFAULT_APPEARANCE);
- }
- shapeRenderable.setCapability(Shape3D.ALLOW_APPEARANCE_READ);
- shapeRenderable.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
- return shapeRenderable;
- }
-
- private Appearance getAppearance(GeometryProvider geoProvider, ObjMtl.Material material) {
-
- Appearance appearance = new Appearance();
- appearance.setCapability(Appearance.ALLOW_TEXTURE_WRITE);
- Material j3dMaterial = new Material();
- appearance.setMaterial(j3dMaterial);
-
- Color3f ambientColor = new Color3f();
- material.getAmbientColor(ambientColor);
- j3dMaterial.setAmbientColor(ambientColor);
-
- Color3f diffuseColor = new Color3f();
- material.getDiffuseColor(diffuseColor);
- j3dMaterial.setDiffuseColor(diffuseColor);
-
- Color3f specularColor = new Color3f();
- material.getSpecularColor(specularColor);
- j3dMaterial.setSpecularColor(specularColor);
-
- if (material.getDissolve() != 1) {
- TransparencyAttributes tAttribs = new TransparencyAttributes(TransparencyAttributes.BLENDED, material.getDissolve());
- appearance.setTransparencyAttributes(tAttribs);
- }
-
- if (material.getSpecularExponent() != -1) {
- //TODO figure out why shininess appears to have no effect
- }
-
- if (material.getDiffuseMapName() != null) { //Woot, texture!
- try {
- Texture texImage = (Texture) textures.get(material.getDiffuseMapName());
- if (texImage == null) {
- InputStream imageStream = geoProvider.getSubGeometryStream(material.getDiffuseMapName());
- if (imageStream != null) {
- Image image = ImageIO.read(new BufferedInputStream(imageStream));
- if (image != null) {
- //I don't really care for any of these formats
- // LUMINANCE is nice for a film noir effect
- if (material.getDiffuseMapName().startsWith("transparent_")) {
- texImage = new TextureLoader(image, "RGBA", null).getTexture();
- } else {
- texImage = new TextureLoader(image, "RGB", null).getTexture();
- }
- textures.put(material.getDiffuseMapName(), texImage);
- }
- imageStream.close();
- }
- }
- if (texImage != null) {
- texImage.getImage(0).setCapability(ImageComponent.ALLOW_SIZE_READ);
- texImage.getImage(0).setCapability(ImageComponent.ALLOW_IMAGE_READ);
- texImage.getImage(0).setCapability(ImageComponent.ALLOW_IMAGE_WRITE);
- appearance.setTexture(texImage);
- // this is a hack so that only textures named transparent_* get these attributes set
- // otherwise we get all kinds of bad ordering problems
- //TODO figure out what the right thing is for transparent texture attributes
- if (material.getDiffuseMapName().startsWith("transparent_")) {
- TextureAttributes textureAtts = new TextureAttributes();
- textureAtts.setTextureMode(TextureAttributes.REPLACE);
- appearance.setTextureAttributes(textureAtts);
-
- TransparencyAttributes tAttribs = new TransparencyAttributes(TransparencyAttributes.BLENDED, 0, TransparencyAttributes.BLEND_SRC_ALPHA, TransparencyAttributes.BLEND_ONE_MINUS_SRC_ALPHA);
- appearance.setTransparencyAttributes(tAttribs);
- appearance.setRenderingAttributes(new RenderingAttributes());
- }
-
- }
-
- } catch (Throwable e) {
- e.printStackTrace();
- }
- }
-
- return appearance;
- }
-
- private int addFaceVertices(Obj obj, int faceIndex, Vector vertices, Vector textureCoordinates) {
- int[][] faceIndices = obj.getFaceIndices(faceIndex);
- for (int i = 0; i < faceIndices.length; i++) {
- vertices.add(obj.getVertex(faceIndices[i][0]));
- if (faceIndices[i].length > 1 && faceIndices[i][1] != -1) {
- textureCoordinates.add(obj.getTextureVertex(faceIndices[i][1]));
- } else {
- textureCoordinates.add(new Point3f());
- }
- }
- return faceIndices.length;
- }
-
public J3DThingRenderable loadThing(Thing thing) {
J3DThingRenderable renderable = new J3DThingRenderable(thing);
Vector lodDistances = new Vector();
Vector lodGroups = new Vector();
-
- for (int i = 0; i < objs.length; i++) {
- if (objs[i] == null) {
+ for (int i = 0; i < templateData.length; i++) {
+ if (templateData[i] == null) {
continue;
}
HashMap shapeGroup = new HashMap();
- Obj.Group[] groups = objs[i].getGroups();
- for (int g = 0; g < groups.length; g++) {
- J3DShapeRenderable shape = generateShape(thing, renderable, groups[g]);
- if (shape != null) {
- shapeGroup.put(shape.getName(), shape);
+ String[] shapeNames = templateData[i].getShapeNames();
+ for (int g = 0; g < shapeNames.length; g++) {
+ Shape shape = thing.getShape(shapeNames[g]);
+ if (shape == null) {
+ shape = new Shape(thing, shapeNames[g]);
+ thing.addShape(shape);
}
+ Geometry geometry = templateData[i].getGeometry(shapeNames[g]);
+ Appearance appearance = templateData[i].getAppearance(shapeNames[g]);
+ J3DShapeRenderable shapeRenderable = generateShapeRenderable(renderable, shape, geometry, appearance);
+ shapeGroup.put(shape.getName(), shapeRenderable);
}
- if (shapeGroup.size() > 0) {
- if (lodGroups.size() > 0) { //there is one less distance than shapeGroup
- lodDistances.add(new Float(GeometryProvider.LOD_DISTANCES[i - 1]));
- }
- lodGroups.add(shapeGroup);
+ if (lodGroups.size() > 0) { //there is one less distance than shapeGroup
+ lodDistances.add(new Float(GeometryProvider.LOD_DISTANCES[i - 1]));
}
+ lodGroups.add(shapeGroup);
}
float[] distances = new float[lodDistances.size()];
for (int i = 0; i < distances.length; i++) {
distances[i] = ((Float) lodDistances.elementAt(i)).floatValue();
}
renderable.setGeometries(distances, (HashMap[]) lodGroups.toArray(new HashMap[0]));
- textures.clear();
return renderable;
}
public J3DDoorRenderable loadDoor(Door door) {
+ ArgumentUtils.assertNotNull(templateData[0]); //doors completely ignore LODs other than 0
+
J3DDoorRenderable renderable = new J3DDoorRenderable(door);
-
- Obj.Group[] groups = objs[0].getGroups();
- for (int i = 0; i < groups.length; i++) {
- J3DShapeRenderable shape = generateShape(door, renderable, groups[i]);
- if (shape != null) {
- renderable.addShapeRenderable(shape, 0);
- }
+ String[] shapeNames = templateData[0].getShapeNames();
+ for (int g = 0; g < shapeNames.length; g++) {
+ Geometry geometry = templateData[0].getGeometry(shapeNames[g]);
+ Appearance appearance = templateData[0].getAppearance(shapeNames[g]);
+ J3DShapeRenderable shapeRenderable = generateShapeRenderable(renderable, null, geometry, appearance);
+ renderable.addShapeRenderable(shapeRenderable, 0);
}
- textures.clear();
return renderable;
}
+ private J3DShapeRenderable generateShapeRenderable(Renderable renderable, Shape shape, Geometry geometry, Appearance appearance) {
+
+ J3DShapeRenderable shapeRenderable = new J3DShapeRenderable(renderable, shape);
+ shapeRenderable.getInnerShape().setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
+ shapeRenderable.getInnerShape().setCapability(Shape3D.ALLOW_GEOMETRY_READ);
+ shapeRenderable.getInnerShape().setCapability(Shape3D.ALLOW_PICKABLE_READ);
+ shapeRenderable.getInnerShape().addGeometry(geometry);
+ shapeRenderable.getInnerShape().setAppearance(appearance);
+
+ shapeRenderable.setCapability(Shape3D.ALLOW_APPEARANCE_READ);
+ shapeRenderable.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
+ return shapeRenderable;
+ }
}
Modified: maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/J3DRenderer.java
===================================================================
--- maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/J3DRenderer.java 2007-09-23 00:32:43 UTC (rev 432)
+++ maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/J3DRenderer.java 2007-09-24 06:53:23 UTC (rev 433)
@@ -98,8 +98,6 @@
private String username = null; //may be null if we're rendering in the sim
- private GeometryProvider errorGeometryProvider = null;
-
private boolean offScreen = false;
private boolean movable = true;
@@ -114,6 +112,8 @@
private boolean completedInitialLoad = false;
+ private J3DDataManager dataManager = null;
+
public J3DRenderer(SpaceClient spaceClient, boolean offScreen) {
this(spaceClient.getSpace(), spaceClient.getUsername(), spaceClient, spaceClient.getErrorGeometryProvider(), offScreen);
}
@@ -122,8 +122,8 @@
super(space);
this.username = username;
this.userInputListener = userInputListener;
- this.errorGeometryProvider = errorGeometryProvider;
this.offScreen = offScreen;
+ this.dataManager = new J3DDataManager(!offScreen);
setCapabilities(sceneRoot);
setCapabilities(usersGroup);
@@ -307,7 +307,7 @@
return;
}
try {
- ThingRenderable renderable = createThingRenderable(thing);
+ ThingRenderable renderable = createThingRenderable(thing, true);
addThingRenderable(renderable);
Shape[] shapes = thing.getShapes();
for (int i = 0; i < shapes.length; i++) {
@@ -358,7 +358,7 @@
}
removeWorldObject(renderable);
}
- renderable = (J3DThingRenderable) createThingRenderable(thing);
+ renderable = (J3DThingRenderable) createThingRenderable(thing, false);
addThingRenderable(renderable);
Shape[] shapes = thing.getShapes();
@@ -539,27 +539,11 @@
}
private DoorRenderable createDoorRenderable(Door door) throws IOException, RenderableParseException {
- try {
- Obj[] objs = new Obj[GeometryProvider.LOD_DISTANCES.length];
- for (int i = 1; i < objs.length; i++) {
- objs[i] = null;
- }
- objs[0] = getObj(door, 0);
- if (objs[0] == null) {
- Log.error("Could not load the door geometry!");
- objs[0] = getObj(errorGeometryProvider, 0);
- }
- if (objs[0] == null) {
- throw new IllegalStateException("Where's my error?");
- }
- J3DRenderableLoader loader = new J3DRenderableLoader(objs, !offScreen);
- J3DDoorRenderable renderable = loader.loadDoor(door);
- renderable.setID(DOOR_ID_PREFIX + door.getDoorID());
- renderable.setPosition(door.getPosition());
- return renderable;
- } catch (ObjParseException e) {
- throw new RenderableParseException("Error parsing geometry: " + e.getMessage());
- }
+ J3DRenderableLoader loader = new J3DRenderableLoader(dataManager.getTemplateData(door.getTemplate().getTemplateID(), door, true));
+ J3DDoorRenderable renderable = loader.loadDoor(door);
+ renderable.setID(DOOR_ID_PREFIX + door.getDoorID());
+ renderable.setPosition(door.getPosition());
+ return renderable;
}
private void addDoorRenderable(DoorRenderable renderable) {
@@ -694,53 +678,18 @@
worldGroup.addChild(cameraBranch);
}
- private Obj getObj(GeometryProvider provider, int lodIndex) throws ObjParseException {
- if (lodIndex != 0) {
- return null;
- }
- try {
- ObjParser parser = new ObjParser(provider, lodIndex);
- return parser.parse();
- } catch (Exception e) {
- return null;
- }
- }
+ private ThingRenderable createThingRenderable(Thing thing, boolean useCache) throws IOException, RenderableParseException {
+ J3DRenderableLoader loader = new J3DRenderableLoader(dataManager.getTemplateData(thing.getTemplate().getTemplateID(), thing, useCache));
+ J3DThingRenderable renderable = loader.loadThing(thing);
+ renderable.setPosition(thing.getPosition());
- private ThingRenderable createThingRenderable(Thing thing) throws IOException, RenderableParseException {
- try {
- boolean gotObj = false;
- Obj[] objs = new Obj[GeometryProvider.LOD_DISTANCES.length + 1];
- for (int i = 0; i < objs.length; i++) {
- objs[i] = getObj(thing, i);
- if (objs[i] != null && objs[i].getGroups().length == 0) {
- Log.error("Got obj with no groups for thing " + thing.getThingID() + ": " + thing.getName());
- objs[i] = null;
- }
- if (!gotObj && objs[i] != null) {
- gotObj = true;
- }
- }
- if (!gotObj) {
- objs[0] = getObj(errorGeometryProvider, 0);
- }
- if (objs[0] == null) {
- throw new IllegalStateException("Where's my error template?");
- }
- J3DRenderableLoader loader = new J3DRenderableLoader(objs, !offScreen);
- J3DThingRenderable renderable = loader.loadThing(thing);
- renderable.setPosition(thing.getPosition());
-
- Page[] pages = thing.getPages();
- for (int i = 0; i < pages.length; i++) {
- J3DPageRenderable pageRenderable = new J3DPageRenderable(renderable/*not used!*/, pages[i]);
- renderable.addPageRenderable(pageRenderable);
- }
-
- return renderable;
- } catch (ObjParseException e) {
- e.printStackTrace();
- throw new RenderableParseException("Error parsing geometry: " + e.getMessage());
+ Page[] pages = thing.getPages();
+ for (int i = 0; i < pages.length; i++) {
+ J3DPageRenderable pageRenderable = new J3DPageRenderable(renderable/*not used!*/, pages[i]);
+ renderable.addPageRenderable(pageRenderable);
}
+
+ return renderable;
}
private static GraphicsConfiguration getGraphicsConfiguration() {
Added: maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/J3DTemplateData.java
===================================================================
--- maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/J3DTemplateData.java (rev 0)
+++ maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/J3DTemplateData.java 2007-09-24 06:53:23 UTC (rev 433)
@@ -0,0 +1,37 @@
+package com.ogoglio.viewer.j3d;
+
+import java.util.HashMap;
+
+import javax.media.j3d.Appearance;
+import javax.media.j3d.Geometry;
+
+public class J3DTemplateData {
+ private HashMap geometries = new HashMap(); //maps String shape names to Geometry objects
+
+ private HashMap appearances = new HashMap();
+
+ public J3DTemplateData() {
+ }
+
+ public Geometry getGeometry(String shapeName) {
+ return (Geometry) geometries.get(shapeName);
+ }
+
+ public void putGeometry(String shapeName, Geometry geometry) {
+ geometries.put(shapeName, geometry);
+ }
+
+ public Appearance getAppearance(String shapeName) {
+ return (Appearance) appearances.get(shapeName);
+ }
+
+ public void putAppearances(String shapeName, Appearance appearance) {
+ appearances.put(shapeName, appearance);
+ }
+
+ public String[] getShapeNames() {
+ return (String[])geometries.keySet().toArray(new String[0]);
+
+ }
+
+}
Modified: maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/J3DUserRenderable.java
===================================================================
--- maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/J3DUserRenderable.java 2007-09-23 00:32:43 UTC (rev 432)
+++ maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/J3DUserRenderable.java 2007-09-24 06:53:23 UTC (rev 433)
@@ -138,6 +138,9 @@
float bvhHeight = bvh.getHeight();
if (bvhHeight != userHeight) {
skeletonScale = userHeight / bvhHeight / MAGIC_SKELETON_SCALE; //TODO figure out why we need this magic scale number
+ if(skeletonScale == 1){
+ return;
+ }
bvh.scale(skeletonScale, skeletonScale, skeletonScale);
}
}
@@ -256,7 +259,6 @@
if (animator != null) {
animator.cleanup();
}
-
if (skeleton != null && bvh != null && skin != null) {
scaleBVH(bvh);
animator = new BodyAnimator(skeleton, bvh, skin, bodyAnimatorListener);
Modified: maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/body/BodyAnimator.java
===================================================================
--- maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/body/BodyAnimator.java 2007-09-23 00:32:43 UTC (rev 432)
+++ maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/body/BodyAnimator.java 2007-09-24 06:53:23 UTC (rev 433)
@@ -90,8 +90,8 @@
if (loop) {
frameIndex = 0;
} else {
+ listener.bodyAnimationCompleted(this);
cleanup();
- listener.bodyAnimationCompleted(this);
return;
}
}
Modified: maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/obj/MtlParser.java
===================================================================
--- maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/obj/MtlParser.java 2007-09-23 00:32:43 UTC (rev 432)
+++ maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/obj/MtlParser.java 2007-09-24 06:53:23 UTC (rev 433)
@@ -112,7 +112,7 @@
if (tokens.length != 2) {
throw new ObjParseException("bad specular exponent: " + toString(tokens));
}
- workingMaterial.setIlluminationModel(parseInt(tokens[1], 1, 10, true));
+ workingMaterial.setIlluminationModel(parseInt(tokens[1], 0, 10, true));
}
private void parseNs(String[] tokens) throws ObjParseException {
@@ -142,7 +142,7 @@
if (tokens.length != 4) {
throw new ObjParseException("bad color: " + toString(tokens));
}
- workingMaterial.setAmbient(new Color3f(parseFloat(tokens[1], 0, 1, true), parseFloat(tokens[2], 0, 1, true), parseFloat(tokens[3], 0, 1, true)));
+ workingMaterial.setAmbient(new Color3f(parseFloat(tokens[1], 0, 2, true), parseFloat(tokens[2], 0, 2, true), parseFloat(tokens[3], 0, 2, true)));
}
private void parseKd(String[] tokens) throws ObjParseException {
@@ -152,7 +152,7 @@
if (tokens.length != 4) {
throw new ObjParseException("bad color: " + toString(tokens));
}
- workingMaterial.setDiffuse(new Color3f(parseFloat(tokens[1], 0, 1, true), parseFloat(tokens[2], 0, 1, true), parseFloat(tokens[3], 0, 1, true)));
+ workingMaterial.setDiffuse(new Color3f(parseFloat(tokens[1], 0, 2, true), parseFloat(tokens[2], 0, 2, true), parseFloat(tokens[3], 0, 2, true)));
}
private void parseKs(String[] tokens) throws ObjParseException {
@@ -162,7 +162,7 @@
if (tokens.length != 4) {
throw new ObjParseException("bad color: " + toString(tokens));
}
- workingMaterial.setSpecular(new Color3f(parseFloat(tokens[1], 0, 1, true), parseFloat(tokens[2], 0, 1, true), parseFloat(tokens[3], 0, 1, true)));
+ workingMaterial.setSpecular(new Color3f(parseFloat(tokens[1], 0, 2, true), parseFloat(tokens[2], 0, 2, true), parseFloat(tokens[3], 0, 2, true)));
}
private void parseNewmtl(String[] tokens) throws ObjParseException {
Modified: maven/trunk/ogoglio-common/src/main/resources/avatar/female.obj
===================================================================
--- maven/trunk/ogoglio-common/src/main/resources/avatar/female.obj 2007-09-23 00:32:43 UTC (rev 432)
+++ maven/trunk/ogoglio-common/src/main/resources/avatar/female.obj 2007-09-24 06:53:23 UTC (rev 433)
@@ -1,15324 +1,23186 @@
-# Blender3D v244 OBJ File: andrea.blend
+# Blender3D v245 OBJ File: fem.blend
# www.blender3d.org
-o Andrea
-v 0.072444 0.431344 -0.019903
-v 0.068896 0.420338 0.003628
-v 0.105751 0.423702 -0.018323
-v -0.105751 0.423702 -0.018323
-v -0.068896 0.420338 0.003628
-v -0.072444 0.431344 -0.019903
-v 0.000000 -0.393034 0.007298
-v 0.000000 -0.372789 0.043782
-v -0.012783 -0.385010 0.045911
-v 0.012783 -0.385010 0.045911
-v 0.000000 -0.008021 0.094634
-v 0.000000 -0.089941 0.089685
-v 0.057792 -0.089020 0.084403
-v 0.058209 -0.013620 0.089661
-v -0.057792 -0.089020 0.084403
-v -0.058209 -0.013620 0.089661
-v 0.000000 0.094034 0.098980
-v 0.050715 0.092738 0.094812
-v -0.050715 0.092738 0.094812
-v 0.000000 0.164555 0.102934
-v 0.041652 0.171488 0.118493
-v -0.041652 0.171488 0.118493
-v 0.000000 0.223170 0.115909
-v 0.050379 0.231945 0.134207
-v -0.050379 0.231945 0.134207
-v 0.000000 0.270250 0.109425
-v 0.054861 0.281394 0.123434
-v -0.054861 0.281394 0.123434
-v 0.000000 0.298406 0.093584
-v 0.053147 0.304501 0.107590
-v -0.053147 0.304501 0.107590
-v 0.000000 0.337909 0.072363
-v 0.058648 0.331418 0.084937
-v -0.058648 0.331418 0.084937
-v 0.000000 0.374800 0.051486
-v 0.065565 0.367155 0.054023
-v -0.065565 0.367155 0.054023
-v 0.112832 -0.080882 0.069332
-v 0.104618 -0.017584 0.075114
-v -0.112832 -0.080882 0.069332
-v -0.104618 -0.017584 0.075114
-v 0.098308 0.080239 0.078745
-v -0.098308 0.080239 0.078745
-v 0.102195 0.169117 0.101175
-v -0.102195 0.169117 0.101175
-v 0.102112 0.330140 0.060913
-v 0.106231 0.370701 0.039329
-v -0.102112 0.330140 0.060913
-v -0.106231 0.370701 0.039329
-v 0.069847 0.403127 0.028194
-v 0.106717 0.402655 0.018780
-v -0.069847 0.403127 0.028194
-v -0.106717 0.402655 0.018780
-v 0.135726 -0.079896 0.047087
-v 0.123153 -0.026271 0.050171
-v -0.135726 -0.079896 0.047087
-v -0.123153 -0.026271 0.050171
-v 0.116639 0.077631 0.053781
-v -0.116639 0.077631 0.053781
-v 0.125536 0.157508 0.063685
-v -0.125536 0.157508 0.063685
-v 0.111490 0.211376 0.105764
-v 0.130803 0.200028 0.064521
-v -0.111490 0.211376 0.105764
-v -0.130803 0.200028 0.064521
-v 0.120670 0.255090 0.089817
-v 0.136371 0.233204 0.056783
-v -0.120670 0.255090 0.089817
-v -0.136371 0.233204 0.056783
-v 0.138667 0.297800 0.067260
-v 0.155276 0.277073 0.042864
-v -0.138667 0.297800 0.067260
-v -0.155276 0.277073 0.042864
-v 0.132172 -0.084556 -0.005840
-v 0.125661 -0.035915 0.000978
-v -0.132172 -0.084556 -0.005840
-v -0.125661 -0.035915 0.000978
-v 0.118146 0.071094 -0.001888
-v -0.118146 0.071094 -0.001888
-v 0.127805 0.148104 0.000387
-v -0.127805 0.148104 0.000387
-v 0.133882 0.192800 0.005342
-v -0.133882 0.192800 0.005342
-v 0.138960 0.223855 0.004306
-v -0.138960 0.223855 0.004306
-v 0.145903 0.264764 -0.002847
-v -0.145903 0.264764 -0.002847
-v 0.122883 -0.089829 -0.038321
-v 0.118085 -0.039110 -0.030806
-v -0.122883 -0.089829 -0.038321
-v -0.118085 -0.039110 -0.030806
-v 0.108614 0.072554 -0.026710
-v -0.108614 0.072554 -0.026710
-v 0.116975 0.148400 -0.033306
-v -0.116975 0.148400 -0.033306
-v 0.128076 0.196613 -0.030121
-v -0.128076 0.196613 -0.030121
-v 0.135916 0.228366 -0.031156
-v -0.135916 0.228366 -0.031156
-v 0.152495 0.267770 -0.037227
-v -0.152495 0.267770 -0.037227
-v 0.104679 -0.096463 -0.059816
-v 0.100855 -0.038797 -0.047297
-v -0.104679 -0.096463 -0.059816
-v -0.100855 -0.038797 -0.047297
-v 0.092459 0.074649 -0.041860
-v -0.092459 0.074649 -0.041860
-v 0.097363 0.153283 -0.051233
-v -0.097363 0.153283 -0.051233
-v 0.103373 0.205267 -0.057511
-v -0.103373 0.205267 -0.057511
-v 0.116110 0.247952 -0.062148
-v -0.116110 0.247952 -0.062148
-v 0.125405 0.290520 -0.067071
-v -0.125405 0.290520 -0.067071
-v 0.068164 -0.102327 -0.070171
-v 0.061873 -0.041381 -0.052230
-v -0.068164 -0.102327 -0.070171
-v -0.061873 -0.041381 -0.052230
-v 0.055306 0.073755 -0.047743
-v -0.055306 0.073755 -0.047743
-v 0.052221 0.153746 -0.054210
-v -0.052221 0.153746 -0.054210
-v 0.053126 0.207744 -0.060426
-v -0.053126 0.207744 -0.060426
-v 0.059103 0.256004 -0.065803
-v -0.059103 0.256004 -0.065803
-v 0.070452 0.314732 -0.083436
-v -0.070452 0.314732 -0.083436
-v 0.000000 -0.105634 -0.069203
-v 0.000000 -0.040280 -0.052491
-v 0.000000 0.072419 -0.048181
-v 0.000000 0.151638 -0.054129
-v 0.000000 0.208307 -0.060015
-v 0.000000 0.254949 -0.070937
-v 0.000000 0.316027 -0.084885
-v 0.073417 0.359692 -0.087206
-v 0.120339 0.352896 -0.078341
-v -0.073417 0.359692 -0.087206
-v -0.120339 0.352896 -0.078341
-v 0.000000 0.363071 -0.086311
-v 0.071927 0.411779 -0.071083
-v 0.117045 0.401216 -0.062277
-v -0.071927 0.411779 -0.071083
-v -0.117045 0.401216 -0.062277
-v 0.072444 0.431344 -0.019903
-v 0.105751 0.423702 -0.018323
-v -0.072444 0.431344 -0.019903
-v -0.105751 0.423702 -0.018323
-v 0.092854 0.224217 0.125561
-v 0.091015 0.272517 0.112949
-v -0.091015 0.272517 0.112949
-v -0.092854 0.224217 0.125561
-v 0.096625 0.300218 0.087818
-v -0.096625 0.300218 0.087818
-v 0.166400 0.322243 0.045884
-v 0.160419 0.347146 0.040013
-v -0.166400 0.322243 0.045884
-v -0.160419 0.347146 0.040013
-v 0.155416 0.378447 0.031719
-v -0.155416 0.378447 0.031719
-v 0.152422 0.401623 0.014026
-v -0.152422 0.401623 0.014026
-v 0.171227 0.297964 0.026533
-v -0.171227 0.297964 0.026533
-v 0.164801 0.308772 -0.004621
-v -0.164801 0.308772 -0.004621
-v 0.173611 0.295002 -0.030238
-v -0.173611 0.295002 -0.030238
-v 0.165293 0.323442 -0.063805
-v -0.165293 0.323442 -0.063805
-v 0.161076 0.356632 -0.069383
-v -0.161076 0.356632 -0.069383
-v 0.154754 0.399035 -0.056921
-v -0.154754 0.399035 -0.056921
-v 0.150386 0.418480 -0.017331
-v -0.150386 0.418480 -0.017331
-v 0.216401 0.339678 0.034547
-v 0.214465 0.356975 0.032762
-v -0.216401 0.339678 0.034547
-v -0.214465 0.356975 0.032762
-v 0.210018 0.381776 0.027264
-v -0.210018 0.381776 0.027264
-v 0.204425 0.404079 0.011413
-v -0.204425 0.404079 0.011413
-v 0.216476 0.324061 0.021081
-v -0.216476 0.324061 0.021081
-v 0.214426 0.329137 -0.002652
-v -0.214426 0.329137 -0.002652
-v 0.216295 0.320349 -0.024596
-v -0.216295 0.320349 -0.024596
-v 0.214267 0.336599 -0.045264
-v -0.214267 0.336599 -0.045264
-v 0.213328 0.366624 -0.059141
-v -0.213328 0.366624 -0.059141
-v 0.208223 0.404733 -0.047266
-v -0.208223 0.404733 -0.047266
-v 0.203466 0.419033 -0.012613
-v -0.203466 0.419033 -0.012613
-v 0.488831 0.356390 0.023890
-v 0.489977 0.345045 0.021617
-v 0.520610 0.345124 0.024929
-v 0.521134 0.357213 0.018884
-v -0.520610 0.345124 0.024929
-v -0.489977 0.345045 0.021617
-v -0.488831 0.356390 0.023890
-v -0.521134 0.357213 0.018884
-v 0.487437 0.374388 0.018113
-v 0.521405 0.372480 0.014779
-v -0.487437 0.374388 0.018113
-v -0.521405 0.372480 0.014779
-v 0.486707 0.386003 0.008811
-v 0.521428 0.386809 0.008662
-v -0.486707 0.386003 0.008811
-v -0.521428 0.386809 0.008662
-v 0.493371 0.335005 0.015946
-v 0.521196 0.333077 0.018413
-v -0.521196 0.333077 0.018413
-v -0.493371 0.335005 0.015946
-v 0.494359 0.330594 -0.002983
-v 0.518669 0.325532 -0.003920
-v -0.518669 0.325532 -0.003920
-v -0.494359 0.330594 -0.002983
-v 0.494024 0.334879 -0.022015
-v 0.518389 0.329385 -0.022644
-v -0.518389 0.329385 -0.022644
-v -0.494024 0.334879 -0.022015
-v 0.492412 0.341375 -0.038531
-v 0.518372 0.341479 -0.041156
-v -0.518372 0.341479 -0.041156
-v -0.492412 0.341375 -0.038531
-v 0.489828 0.368057 -0.042244
-v 0.518233 0.364301 -0.045253
-v -0.518233 0.364301 -0.045253
-v -0.489828 0.368057 -0.042244
-v 0.488771 0.383914 -0.037272
-v 0.519243 0.380672 -0.037743
-v -0.519243 0.380672 -0.037743
-v -0.488771 0.383914 -0.037272
-v 0.488865 0.390568 -0.013032
-v 0.520728 0.393244 -0.015684
-v -0.520728 0.393244 -0.015684
-v -0.488865 0.390568 -0.013032
-v 0.692376 0.341604 0.019592
-v 0.691333 0.349349 0.021623
-v -0.692376 0.341604 0.019592
-v -0.691333 0.349349 0.021623
-v 0.691961 0.360002 0.018008
-v -0.691961 0.360002 0.018008
-v 0.692377 0.367216 0.008419
-v -0.692377 0.367216 0.008419
-v 0.690457 0.332916 0.009755
-v -0.690457 0.332916 0.009755
-v 0.689124 0.329597 -0.003385
-v -0.689124 0.329597 -0.003385
-v 0.688861 0.332637 -0.016127
-v -0.688861 0.332637 -0.016127
-v 0.687995 0.340210 -0.030483
-v -0.687995 0.340210 -0.030483
-v 0.688442 0.353105 -0.033631
-v -0.688442 0.353105 -0.033631
-v 0.690693 0.364958 -0.026027
-v -0.690693 0.364958 -0.026027
-v 0.693298 0.365888 -0.008105
-v -0.693298 0.365888 -0.008105
-v 0.806378 0.340617 0.025688
-v -0.806378 0.340617 0.025688
-v 0.806820 0.356133 0.026379
-v -0.806820 0.356133 0.026379
-v 0.806221 0.362954 0.017113
-v -0.806221 0.362954 0.017113
-v 0.805809 0.333323 0.016058
-v -0.805809 0.333323 0.016058
-v 0.804907 0.331306 0.004464
-v -0.804907 0.331306 0.004464
-v 0.804885 0.331186 -0.007792
-v -0.804885 0.331186 -0.007792
-v 0.806006 0.335533 -0.021118
-v -0.806006 0.335533 -0.021118
-v 0.807614 0.350365 -0.027273
-v -0.807614 0.350365 -0.027273
-v 0.807693 0.359023 -0.020037
-v -0.807693 0.359023 -0.020037
-v 0.806064 0.362992 -0.000051
-v -0.806064 0.362992 -0.000051
-v 0.000000 -0.186187 0.101558
-v 0.069624 -0.171457 0.096532
-v -0.069624 -0.171457 0.096532
-v 0.127068 -0.141359 0.070270
-v -0.127068 -0.141359 0.070270
-v 0.153729 -0.129082 0.048406
-v -0.153729 -0.129082 0.048406
-v 0.149725 -0.134013 -0.010278
-v -0.149725 -0.134013 -0.010278
-v 0.138767 -0.151550 -0.050662
-v -0.138767 -0.151550 -0.050662
-v 0.116209 -0.168172 -0.087439
-v -0.116209 -0.168172 -0.087439
-v 0.077981 -0.186699 -0.106863
-v -0.077981 -0.186699 -0.106863
-v 0.000000 -0.202136 -0.098890
-v 0.000000 -0.243467 0.102964
-v 0.079334 -0.207165 0.094609
-v -0.079334 -0.207165 0.094609
-v 0.137730 -0.179296 0.079383
-v -0.137730 -0.179296 0.079383
-v 0.170517 -0.165461 0.045509
-v -0.170517 -0.165461 0.045509
-v 0.167940 -0.172402 -0.007351
-v -0.167940 -0.172402 -0.007351
-v 0.158518 -0.198068 -0.047313
-v -0.158518 -0.198068 -0.047313
-v 0.129888 -0.226457 -0.083776
-v -0.129888 -0.226457 -0.083776
-v 0.080208 -0.253490 -0.109962
-v -0.080208 -0.253490 -0.109962
-v 0.000000 -0.258291 -0.106410
-v 0.000000 -0.311995 0.094923
-v 0.093020 -0.258325 0.099785
-v -0.093020 -0.258325 0.099785
-v 0.143769 -0.233862 0.080608
-v -0.143769 -0.233862 0.080608
-v 0.174905 -0.223524 0.049887
-v -0.174905 -0.223524 0.049887
-v 0.177616 -0.226994 -0.002974
-v -0.177616 -0.226994 -0.002974
-v 0.169730 -0.254398 -0.044118
-v -0.169730 -0.254398 -0.044118
-v 0.136650 -0.283899 -0.070695
-v -0.136650 -0.283899 -0.070695
-v 0.083666 -0.310461 -0.091053
-v -0.083666 -0.310461 -0.091053
-v 0.000000 -0.331772 -0.084989
-v 0.103268 -0.423815 0.090462
-v 0.065629 -0.423751 0.086896
-v 0.076433 -0.557391 0.057693
-v 0.102900 -0.551560 0.061142
-v -0.076433 -0.557391 0.057693
-v -0.065629 -0.423751 0.086896
-v -0.103268 -0.423815 0.090462
-v -0.102900 -0.551560 0.061142
-v 0.140697 -0.421586 0.068706
-v 0.132262 -0.543893 0.041001
-v -0.140697 -0.421586 0.068706
-v -0.132262 -0.543893 0.041001
-v 0.163602 -0.421783 0.039912
-v 0.155167 -0.539764 0.016662
-v -0.163602 -0.421783 0.039912
-v -0.155167 -0.539764 0.016662
-v 0.166559 -0.424371 -0.004855
-v 0.158124 -0.537545 -0.028330
-v -0.166559 -0.424371 -0.004855
-v -0.158124 -0.537545 -0.028330
-v 0.156671 -0.427175 -0.043549
-v 0.148236 -0.539045 -0.067626
-v -0.156671 -0.427175 -0.043549
-v -0.148236 -0.539045 -0.067626
-v 0.133496 -0.431901 -0.066263
-v 0.125062 -0.544528 -0.082891
-v -0.133496 -0.431901 -0.066263
-v -0.125062 -0.544528 -0.082891
-v 0.088396 -0.437785 -0.071549
-v 0.079962 -0.553541 -0.087463
-v -0.088396 -0.437785 -0.071549
-v -0.079962 -0.553541 -0.087463
-v 0.048401 -0.439291 -0.071294
-v 0.055434 -0.557113 -0.076402
-v -0.048401 -0.439291 -0.071294
-v -0.055434 -0.557113 -0.076402
-v 0.078320 -0.632359 0.039968
-v 0.103072 -0.626232 0.041520
-v -0.078320 -0.632359 0.039968
-v -0.103072 -0.626232 0.041520
-v 0.131713 -0.621652 0.023575
-v -0.131713 -0.621652 0.023575
-v 0.152979 -0.617556 -0.000565
-v -0.152979 -0.617556 -0.000565
-v 0.155712 -0.618497 -0.044676
-v -0.155712 -0.618497 -0.044676
-v 0.146520 -0.622028 -0.072679
-v -0.146520 -0.622028 -0.072679
-v 0.124977 -0.632606 -0.094791
-v -0.124977 -0.632606 -0.094791
-v 0.083156 -0.641483 -0.098322
-v -0.083156 -0.641483 -0.098322
-v 0.087826 -0.734290 0.013064
-v 0.103760 -0.735007 0.015215
-v -0.087826 -0.734290 0.013064
-v -0.103760 -0.735007 0.015215
-v 0.131006 -0.737313 0.005287
-v -0.131006 -0.737313 0.005287
-v 0.147233 -0.741317 -0.018640
-v -0.147233 -0.741317 -0.018640
-v 0.154056 -0.744697 -0.053215
-v -0.154056 -0.744697 -0.053215
-v 0.141099 -0.739783 -0.085196
-v -0.141099 -0.739783 -0.085196
-v 0.125548 -0.735819 -0.103837
-v -0.125548 -0.735819 -0.103837
-v 0.087572 -0.733156 -0.105790
-v -0.087572 -0.733156 -0.105790
-v 0.028208 -0.430363 0.039591
-v 0.042134 -0.565713 0.021245
-v -0.042134 -0.565713 0.021245
-v -0.028208 -0.430363 0.039591
-v 0.022680 -0.429541 -0.020282
-v 0.034753 -0.562994 -0.037362
-v -0.034753 -0.562994 -0.037362
-v -0.022680 -0.429541 -0.020282
-v 0.060216 -0.644380 -0.078672
-v -0.060216 -0.644380 -0.078672
-v 0.073062 -0.732420 -0.086498
-v -0.073062 -0.732420 -0.086498
-v 0.045699 -0.638742 -0.046610
-v -0.045699 -0.638742 -0.046610
-v 0.049570 -0.639812 -0.000320
-v -0.049570 -0.639812 -0.000320
-v 0.059220 -0.730183 -0.060637
-v -0.059220 -0.730183 -0.060637
-v 0.061322 -0.731764 -0.013247
-v -0.061322 -0.731764 -0.013247
-v 0.174386 -0.283555 0.045101
-v 0.177794 -0.284006 -0.006727
-v -0.177794 -0.284006 -0.006727
-v -0.174386 -0.283555 0.045101
-v 0.164694 -0.303724 -0.045351
-v -0.164694 -0.303724 -0.045351
-v 0.087619 -0.341069 -0.076522
-v 0.019462 -0.361788 -0.074514
-v -0.019462 -0.361788 -0.074514
-v -0.087619 -0.341069 -0.076522
-v 0.000000 -0.365169 -0.058059
-v 0.138006 -0.321613 -0.068252
-v -0.138006 -0.321613 -0.068252
-v 0.000000 -0.393034 0.007298
-v 0.046978 -0.344842 0.094157
-v 0.098144 -0.311260 0.100673
-v -0.046978 -0.344842 0.094157
-v -0.098144 -0.311260 0.100673
-v 0.000000 -0.342486 0.080007
-v 0.026180 -0.366067 0.084524
-v -0.026180 -0.366067 0.084524
-v 0.148279 -0.285636 0.075962
-v -0.148279 -0.285636 0.075962
-v 0.083111 -0.826219 0.010766
-v 0.106922 -0.826375 0.012166
-v -0.106922 -0.826375 0.012166
-v -0.083111 -0.826219 0.010766
-v 0.079469 -0.893976 0.012477
-v 0.106418 -0.896411 0.018160
-v -0.106418 -0.896411 0.018160
-v -0.079469 -0.893976 0.012477
-v 0.132188 -0.828770 0.005815
-v -0.132188 -0.828770 0.005815
-v 0.132514 -0.898475 0.010654
-v -0.132514 -0.898475 0.010654
-v 0.161708 -0.834564 -0.015031
-v -0.161708 -0.834564 -0.015031
-v 0.161360 -0.904617 -0.009743
-v -0.161360 -0.904617 -0.009743
-v 0.166054 -0.835136 -0.053750
-v -0.166054 -0.835136 -0.053750
-v 0.170493 -0.900871 -0.051503
-v -0.170493 -0.900871 -0.051503
-v 0.153633 -0.832713 -0.083566
-v -0.153633 -0.832713 -0.083566
-v 0.155576 -0.900182 -0.079390
-v -0.155576 -0.900182 -0.079390
-v 0.124894 -0.828009 -0.102885
-v -0.124894 -0.828009 -0.102885
-v 0.129381 -0.896004 -0.100691
-v -0.129381 -0.896004 -0.100691
-v 0.092745 -0.824780 -0.109876
-v -0.092745 -0.824780 -0.109876
-v 0.094862 -0.892207 -0.110491
-v -0.094862 -0.892207 -0.110491
-v 0.074839 -0.823463 -0.092812
-v -0.074839 -0.823463 -0.092812
-v 0.077633 -0.889320 -0.093210
-v -0.077633 -0.889320 -0.093210
-v 0.065963 -0.822783 -0.018036
-v -0.065963 -0.822783 -0.018036
-v 0.065918 -0.888732 -0.012730
-v -0.065918 -0.888732 -0.012730
-v 0.060040 -0.820384 -0.064480
-v -0.060040 -0.820384 -0.064480
-v 0.061383 -0.884859 -0.063527
-v -0.061383 -0.884859 -0.063527
-v 0.074989 -0.971918 0.016239
-v 0.100867 -0.976108 0.028397
-v -0.100867 -0.976108 0.028397
-v -0.074989 -0.971918 0.016239
-v 0.074166 -1.072515 0.030019
-v 0.099655 -1.066070 0.049588
-v -0.099655 -1.066070 0.049588
-v -0.074166 -1.072515 0.030019
-v 0.134041 -0.978316 0.016510
-v -0.134041 -0.978316 0.016510
-v 0.134743 -1.064431 0.03462...
[truncated message content] |