|
From: <tre...@us...> - 2007-10-01 13:57:59
|
Revision: 462
http://ogoglio.svn.sourceforge.net/ogoglio/?rev=462&view=rev
Author: trevorolio
Date: 2007-10-01 06:57:55 -0700 (Mon, 01 Oct 2007)
Log Message:
-----------
Now the body morphs are arranged in an ADG and applied to the body mesh in depth first order.
This implies that there is only one morph with no parent, and there are no cycles.
Both cases are detected, logged, and fail gracefully.
Modified Paths:
--------------
maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/J3DDataManager.java
maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/body/MorphDeltaMap.java
maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/body/MorphDeltaMapParser.java
maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/body/SkinLoader.java
maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/obj/LineTokenizer.java
maven/trunk/ogoglio-common/src/test/java/com/ogoglio/viewer/j3d/body/test/MorphTest.java
maven/trunk/ogoglio-common/src/test/resources/sample-art3d/MorphTest1.ogmorph
Modified: 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 2007-10-01 13:57:49 UTC (rev 461)
+++ maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/J3DDataManager.java 2007-10-01 13:57:55 UTC (rev 462)
@@ -150,9 +150,76 @@
} catch (MorphDeltaMapParseException e) {
throw new IllegalStateException("Trevor didn't implement an error body: " + e);
}
- return new J3DBodyData(array, (Bvh[]) animations.toArray(new Bvh[0]), skinMap, baseTexture, (MorphDeltaMap[])morphDeltas.toArray(new MorphDeltaMap[0]));
+
+ sortMorphDeltas(morphDeltas);
+
+ return new J3DBodyData(array, (Bvh[]) animations.toArray(new Bvh[0]), skinMap, baseTexture, (MorphDeltaMap[]) morphDeltas.toArray(new MorphDeltaMap[0]));
}
+ /**
+ * arranges the morph delta maps in depth first order
+ */
+ private void sortMorphDeltas(Vector morphDeltas) {
+ if(morphDeltas.size() == 0){
+ return;
+ }
+ MorphDeltaMap[] deltas = (MorphDeltaMap[]) morphDeltas.toArray(new MorphDeltaMap[0]);
+
+ HashMap nodeMap = new HashMap();
+ for (int i = 0; i < deltas.length; i++) {
+ nodeMap.put(deltas[i].getName(), new MorphTreeNode(deltas[i]));
+ }
+ MorphTreeNode rootNode = null;
+ for (int i = 0; i < deltas.length; i++) {
+ if(deltas[i].getParentName() == null){
+ if(rootNode == null){
+ rootNode = (MorphTreeNode)nodeMap.get(deltas[i].getName());
+ } else {
+ Log.warn("Found multiple morph delta maps with no parent, adding " + deltas[i].getName() + " to " + rootNode.map.getName());
+ rootNode.children.add(nodeMap.get(deltas[i].getName()));
+ }
+ } else {
+ MorphTreeNode parentNode = (MorphTreeNode)nodeMap.get(deltas[i].getParentName());
+ if(parentNode == null){
+ Log.warn("MorphDeltaMap (" + deltas[i].getName() + ") has unknown parent: " + deltas[i].getParentName() + ", ignoring.");
+ } else {
+ parentNode.children.add(nodeMap.get(deltas[i].getName()));
+ }
+ }
+ }
+ if(rootNode == null){
+ throw new IllegalStateException("Cannot have a morph tree with no root");
+ }
+
+ morphDeltas.clear();
+ serializeMorphTree(0, rootNode, morphDeltas);
+ }
+
+ /**
+ * depth first serialization of the ADG of MorphDeltaMaps
+ */
+ private void serializeMorphTree(int depth, MorphTreeNode node, Vector morphDeltas) {
+ depth++;
+ if(depth > 30){
+ Log.error("Morph tree depth was greater than 30, which probably indicates a cyclic tree. Aborting");
+ return;
+ }
+ for (int i = 0; i < node.children.size(); i++) {
+ serializeMorphTree(depth, (MorphTreeNode)node.children.get(i), morphDeltas);
+ }
+ morphDeltas.add(node.map);
+ }
+
+ private class MorphTreeNode {
+ MorphDeltaMap map = null;
+
+ Vector children = new Vector();
+
+ MorphTreeNode(MorphDeltaMap map) {
+ this.map = map;
+ }
+ }
+
private IndexedTriangleArray generateBodyGeometry(Obj obj) {
int indicesTotal = obj.faceCount() * 3;
int[] coordinateIndices = new int[indicesTotal];
@@ -234,7 +301,7 @@
private void fetchTemplateData(String username, long templateID, J3DTemplateData[] results) {
ArgumentUtils.assertNotNull(username);
ArgumentUtils.assertNotNegative(templateID);
-
+
Obj[] objs = getObjs(username, templateID);
HashMap textures = new HashMap();
Modified: maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/body/MorphDeltaMap.java
===================================================================
--- maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/body/MorphDeltaMap.java 2007-10-01 13:57:49 UTC (rev 461)
+++ maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/body/MorphDeltaMap.java 2007-10-01 13:57:55 UTC (rev 462)
@@ -23,11 +23,14 @@
public class MorphDeltaMap {
String name = null;
+
+ String parentName = null;
Vector ranges = new Vector();
- public MorphDeltaMap(String name) {
+ public MorphDeltaMap(String name, String parentName) {
this.name = name;
+ this.parentName = parentName;
}
public void addRange(Range range) {
@@ -38,6 +41,10 @@
return (Range[]) ranges.toArray(new Range[0]);
}
+ public String getParentName() {
+ return parentName;
+ }
+
public String getName() {
return name;
}
@@ -47,7 +54,7 @@
Vector3f[] deltas = null;
- public Range(int lower,Vector3f[] deltas) {
+ public Range(int lower, Vector3f[] deltas) {
ArgumentUtils.assertNotNegative(lower);
this.lower = lower;
ArgumentUtils.assertNotNull(deltas);
@@ -82,7 +89,10 @@
public String toString() {
StringBuffer result = new StringBuffer();
result.append("# MorphDeltaMap\n");
- result.append(name + "\n\n");
+ result.append("name: " + name + "\n\n");
+ if (parentName != null) {
+ result.append("parent: " + parentName + "\n\n");
+ }
Range[] ranges = getRanges();
for (int i = 0; i < ranges.length; i++) {
result.append(ranges[i].lower);
@@ -94,7 +104,8 @@
}
return result.toString();
}
- private String format(float value){
+
+ private String format(float value) {
Object[] args = { new Float(value) };
return String.format("%f", args);
}
Modified: maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/body/MorphDeltaMapParser.java
===================================================================
--- maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/body/MorphDeltaMapParser.java 2007-10-01 13:57:49 UTC (rev 461)
+++ maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/body/MorphDeltaMapParser.java 2007-10-01 13:57:55 UTC (rev 462)
@@ -29,6 +29,10 @@
private LineTokenizer tokenizer = null;
+ private String name = null;
+
+ private String parentName = null;
+
private MorphDeltaMap map = null;
public MorphDeltaMapParser(InputStream input) {
@@ -43,8 +47,10 @@
while ((tokens = tokenizer.readNextLine()) != null) {
if (tokens.length == 0 || tokens[0].startsWith("#")) {
continue;
- } else if (map == null) {
+ } else if (map == null && tokens[0].equals("name:")) {
parseName(tokens);
+ } else if (map == null && tokens[0].equals("parent:")) {
+ parseParentName(tokens);
} else {
parseRange(tokens);
}
@@ -56,11 +62,25 @@
return map;
}
+ private void parseParentName(String[] tokens) throws MorphDeltaMapParseException {
+ if(tokens.length < 2){
+ throw new MorphDeltaMapParseException("Bad parent name definition: " + LineTokenizer.toString(tokens));
+ }
+ parentName = LineTokenizer.toString(tokens, 1);
+ }
+
private void parseName(String[] tokens) throws MorphDeltaMapParseException {
- map = new MorphDeltaMap(LineTokenizer.toString(tokens));
+ if(tokens.length < 2){
+ throw new MorphDeltaMapParseException("Bad name definition: " + LineTokenizer.toString(tokens));
+ }
+ name = LineTokenizer.toString(tokens, 1);
}
private void parseRange(String[] tokens) throws MorphDeltaMapParseException {
+ if(map == null){
+ map = new MorphDeltaMap(name, parentName);
+ }
+
if(tokens.length < 2){
throw new MorphDeltaMapParseException("Bad range: " + LineTokenizer.toString(tokens));
}
Modified: maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/body/SkinLoader.java
===================================================================
--- maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/body/SkinLoader.java 2007-10-01 13:57:49 UTC (rev 461)
+++ maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/body/SkinLoader.java 2007-10-01 13:57:55 UTC (rev 462)
@@ -41,15 +41,12 @@
public Skin generateSkin() {
float[] vertices = geometry.getCoordRefFloat();
- //TODO make these happen in depth first order of the morph ADG
for (int i = 0; i < morphDeltaMaps.length; i++) {
MorphDeltaMap.Range[] ranges = morphDeltaMaps[i].getRanges();
for (int r = 0; r < ranges.length; r++) {
Vector3f[] deltas = ranges[r].getDeltas();
for (int d = 0; d < deltas.length; d++) {
int index = (ranges[r].getLower() - 1 + d) * 3;
- System.out.println(vertices[index] + "," + vertices[index + 1] + "," + vertices[index + 2]);
- System.out.println("Deltas " + deltas[d].x + "," + deltas[d].y + "," + deltas[d].z);
vertices[index] = vertices[index] + deltas[d].x;
vertices[index + 1] = vertices[index + 1] + deltas[d].y;
vertices[index + 2] = vertices[index + 2] + deltas[d].z;
Modified: maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/obj/LineTokenizer.java
===================================================================
--- maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/obj/LineTokenizer.java 2007-10-01 13:57:49 UTC (rev 461)
+++ maven/trunk/ogoglio-common/src/main/java/com/ogoglio/viewer/j3d/obj/LineTokenizer.java 2007-10-01 13:57:55 UTC (rev 462)
@@ -51,8 +51,12 @@
}
public static String toString(String[] tokens) {
+ return toString(tokens, 0);
+ }
+
+ public static String toString(String[] tokens, int startingIndex) {
StringBuffer result = new StringBuffer();
- for (int i = 0; i < tokens.length; i++) {
+ for (int i = startingIndex; i < tokens.length; i++) {
result.append(tokens[i] + " ");
}
return result.toString().trim();
Modified: maven/trunk/ogoglio-common/src/test/java/com/ogoglio/viewer/j3d/body/test/MorphTest.java
===================================================================
--- maven/trunk/ogoglio-common/src/test/java/com/ogoglio/viewer/j3d/body/test/MorphTest.java 2007-10-01 13:57:49 UTC (rev 461)
+++ maven/trunk/ogoglio-common/src/test/java/com/ogoglio/viewer/j3d/body/test/MorphTest.java 2007-10-01 13:57:55 UTC (rev 462)
@@ -16,7 +16,9 @@
public void testMorphDeltaMapParse() throws IOException, MorphDeltaMapParseException {
MorphDeltaMap map1 = new MorphDeltaMapParser(UIConstants.getResource(MORPH1_RESOURCE_PATH)).parse();
- assertNotNull(map1.getName());
+ assertEquals("testMorph1", map1.getName());
+ assertEquals("parentMorph1", map1.getParentName());
+
assertTrue(map1.getName().length() > 0);
assertTrue(map1.getRanges().length > 0);
assertTrue(map1.getRanges()[0].getDeltas().length > 0);
@@ -27,6 +29,7 @@
private void assertMapsEqual(MorphDeltaMap map1, MorphDeltaMap map2) {
assertEquals(map1.getName(), map2.getName());
+ assertEquals(map1.getParentName(), map2.getParentName());
assertEquals(map1.getVertexCount(), map2.getVertexCount());
assertEquals(map1.getRanges().length, map2.getRanges().length);
for (int i = 0; i < map1.getRanges().length; i++) {
Modified: maven/trunk/ogoglio-common/src/test/resources/sample-art3d/MorphTest1.ogmorph
===================================================================
--- maven/trunk/ogoglio-common/src/test/resources/sample-art3d/MorphTest1.ogmorph 2007-10-01 13:57:49 UTC (rev 461)
+++ maven/trunk/ogoglio-common/src/test/resources/sample-art3d/MorphTest1.ogmorph 2007-10-01 13:57:55 UTC (rev 462)
@@ -1,5 +1,6 @@
# MorphDeltaMap
-testMorph1
+name: testMorph1
+parent: parentMorph1
3 0.000000,0.000000,1.733333 0.000000,0.000000,1.600000 0.000000,0.000000,1.466667 0.000000,0.000000,1.333333 0.000000,0.000000,1.200000 0.000000,0.000000,1.066667 0.000000,0.000000,0.933333 0.000000,0.000000,0.800000 0.000000,0.000000,0.666667 0.000000,0.000000,0.533333 0.000000,0.000000,0.400000 0.000000,0.000000,0.266667
18 0.000000,0.000000,0.000000 0.000000,0.000000,0.133334 0.000000,0.000000,0.266667 0.000000,0.000000,0.400000 0.000000,0.000000,0.533334 0.000000,0.000000,0.666667 0.000000,0.000000,0.800000 0.000000,0.000000,0.933334 0.000000,0.000000,1.066667 0.000000,0.000000,1.200000 0.000000,0.000000,1.333334 0.000000,0.000000,1.466667 0.000000,0.000000,1.600000 0.000000,0.000000,1.733334
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|