[source] [x3d-public] Extrusions, take 3 - animated snake example works everywhere but Xj3D

John Carlson john.carlson3 at sbcglobal.net
Tue Jan 26 20:11:55 PST 2016


Okay, I imported Doug’s example into Blender and got a box.  Is there some way to import this into Blender and get a snake?  Possibly by converting
to another format first?

Thanks,

John
> On Jan 26, 2016, at 10:59 PM, John Carlson <john.carlson3 at sbcglobal.net> wrote:
> 
> Can someone try importing then exporting this from Blender (back to X3D) and see what comes out?  Thanks, I will try but I’m not too good with Blender.
> 
> John
>> On Jan 26, 2016, at 9:50 PM, Don Brutzman <brutzman at nps.edu> wrote:
>> 
>> [added cc: source mailing list for Xj3D]
>> 
>> On 1/26/2016 5:11 PM, doug sanden wrote:
>>> 
>>> http://dug9.users.sourceforge.net/web3d/tests/41.x3d
>>> 
>>> snake animation animating extrusion spine
>> 
>> Hi Doug.  So that others might also know the genesis of this example, I believe X3D adaptations of the original version are found here:
>> 
>> X3D Example Archives: VRML 2.0 Sourcebook, Chapter 15 - Extrusion
>> http://www.web3d.org/x3d/content/examples/Vrml2.0Sourcebook/Chapter15-Extrusion/
>> 
>> Figure 15.17 Wiggling Snake
>> A wiggling snake whose spine is animated using a CoordinateInterpolator node.
>> http://www.web3d.org/x3d/content/examples/Vrml2.0Sourcebook/Chapter15-Extrusion/Figure15.17WigglingSnake.x3d
>> http://www.web3d.org/x3d/content/examples/Vrml2.0Sourcebook/Chapter15-Extrusion/Figure15.17WigglingSnake.xhtml
>> 
>> Figure 15.17 Wiggling Snake With Axes (which help you discern how the animation works)
>> A wiggling snake whose spine is animated using a CoordinateInterpolator node.
>> http://www.web3d.org/x3d/content/examples/Vrml2.0Sourcebook/Chapter15-Extrusion/Figure15.17WigglingSnakeWithAxes.x3d
>> http://www.web3d.org/x3d/content/examples/Vrml2.0Sourcebook/Chapter15-Extrusion/Figure15.17WigglingSnakeWithAxes.xhtml
>> 
>> X3D Scene Metadata for original authors:
>> creator:	Figure 15.17, The VRML 2.0 Sourcebook, Copyright [1997] By Andrea L. Ames, David R. Nadeau, and John L. Moreland
>> reference:	http://www.wiley.com/legacy/compbooks/vrml2sbk/ch15/15fig17.htm
>> reference:	http://www.wiley.com/legacy/compbooks/vrml2sbk/ch15/15fig17.wrl
>> 
>> The xhtml links listed above show that X3DOM works fine on this example.
>> 
>> I tested this scene with Cobweb by using X3D-Edit to generate a local html file in the same directory.  Works nicely!  Page and screenshot attached.
>> 
>> Hopefully the presence of this scene in your test suite means that FreeWrl supports this Extrusion animation OK... yes indeed, launching FreeWRL from X3D-Edit displays and animates correctly.  Screenshot attached.
>> 
>> Autolaunching other X3D players simultaneously from X3D-Edit shows everything else working OK: Instant Reality, BS Contact (plugin and application), H3DViewer, Octaga, amd view3dscene (with accompanying animation of bounding boxes).
>> 
>> Xj3D remains the problem child - our last holdout perhaps.  It animates the spine OK, but doesn't get the cross section computed correctly. Screenshot attached.  I haven't been able to figure out the error in that code.  Perhaps someone with close knowledge of Extrusion math will spot the computational error - source excerpts follow.
>> 
>> https://sourceforge.net/projects/xj3d/
>> 
>> https://sourceforge.net/p/xj3d/code/HEAD/tree/trunk/src/java/org/web3d/vrml/renderer/ogl/nodes/geom3d/OGLExtrusion.java
>> =========================================
>>   /**
>>    * Result: Completed "coords" array: An array of all the float information
>>    * describing each vertex in the extrusion, created by applying the
>>    * transforms to the vfCrossSection points
>>    *
>>    * @author Eric Fickenscher
>>    */
>>   private void createExtrusionCoordinates(){
>> 
>>       // calculate the number of coordinates needed for the sides
>>       // of the extrusion: 3 coordinates per vertex, one vertex per
>>       // crossSectionPoint, and one set of crossSectionPoints per spinePoint
>>       coords = new float[ numSpine * uniqueCrossSectionPoints * 3 ];
>> 
>>       for(int i = 0; i < numSpine; i++) {
>> 
>>           Matrix4f tx = transforms[i];
>> 
>>           for(int j = 0; j < uniqueCrossSectionPoints; j++) {
>> 
>>               int ind = (i * uniqueCrossSectionPoints + j) * 3;
>> 
>>               // basically a transform, in place
>>               float c_x = vfCrossSection[j*2   ];
>>               float c_z = vfCrossSection[j*2 +1];
>> 
>>               float x = c_x * tx.m00 + c_z * tx.m02 + tx.m03;
>>               float y = c_x * tx.m10 + c_z * tx.m12 + tx.m13;
>>               float z = c_x * tx.m20 + c_z * tx.m22 + tx.m23;
>> 
>>               coords[ind] = x;
>>               coords[ind + 1] = y;
>>               coords[ind + 2] = z;
>>           }
>>       }
>>   }
>> =========================================
>>   /**
>>    * Result: Completed "coordIndex" array: an int array representing an
>>    * IndexedFaceSet representation of the extrusion.
>>    *
>>    * @author Eric Fickenscher
>>    */
>>   private void createIndicesTriangleArray(){
>> 
>>       int sizeOfCoordIndex = 5*(numCrossSection-1) * (numSpine-1);
>>       if( vfBeginCap) sizeOfCoordIndex += uniqueCrossSectionPoints+1;
>>       if( vfEndCap)   sizeOfCoordIndex += uniqueCrossSectionPoints+1;
>> 
>>       coordIndex = new int[sizeOfCoordIndex];
>> 
>>       int indx = 0;
>>       int curIndex;
>> 
>>       // for each separate segment between two spine points
>>       for(int i = 0; i<numSpine-1; i++){
>> 
>>           curIndex = i*uniqueCrossSectionPoints;
>> 
>>           // build a quadrilateral for every crossSection-to-crossSection side around that segment
>>           // note that Xj3D wireframe mode shows triangulation even though quads are being built here
>>           for(int j = 0; j < numCrossSection-1; j++){
>> 
>>               if(vfCCW){
>>                   coordIndex[ indx++ ] = j + curIndex;
>>                   coordIndex[ indx++ ] = j + curIndex +1;
>>                   coordIndex[ indx++ ] = j + curIndex + uniqueCrossSectionPoints +1;
>>                   coordIndex[ indx++ ] = j + curIndex + uniqueCrossSectionPoints;
>>               } else {
>>                   coordIndex[ indx++ ] = j + curIndex + uniqueCrossSectionPoints;
>>                   coordIndex[ indx++ ] = j + curIndex + uniqueCrossSectionPoints +1;
>>                   coordIndex[ indx++ ] = j + curIndex +1;
>>                   coordIndex[ indx++ ] = j + curIndex;
>>               }
>> 
>>               coordIndex[ indx++ ] = -1;
>>           }
>> 
>>           if(crossSectionClosed){
>>               coordIndex[indx -4] -= uniqueCrossSectionPoints;
>>               coordIndex[indx -3] -= uniqueCrossSectionPoints;
>>           }
>>       }
>> 
>>       // note that Xj3D wireframe mode shows triangulation even though N-sided polygons are being built here
>>       if( vfBeginCap) {
>> 
>>           for(int i = 0; i < uniqueCrossSectionPoints; i++){
>>               if(vfCCW) coordIndex[ indx++ ] = uniqueCrossSectionPoints -i -1;
>>               else coordIndex[ indx++ ] = i;
>>           }
>>           coordIndex[ indx++ ] = -1;
>>       }
>>       if( vfEndCap) {
>> 
>>           for(int i = 0; i < uniqueCrossSectionPoints; i++){
>>               if(vfCCW) coordIndex[ indx++ ] = (numSpine-1)*uniqueCrossSectionPoints + i;
>>               else coordIndex[ indx++ ] = numSpine*uniqueCrossSectionPoints -i -1;
>>           }
>>           coordIndex[ indx ] = -1;
>>       }
>>   }
>> =========================================
>>   /**
>>    * Creates a rotation for each spine point to avoid twisting of the profile
>>    * when the orientation of SCP changes.
>>    * @author Pasi Paasiala
>>    * @param z the vector containing the z unit vectors for each spine point
>>    */
>>   private Matrix3f[] createCorrectionRotations(Vector3f[] z) {
>> 
>>       Matrix3f[] correctionRotations = new Matrix3f[spines.length];
>>       correctionRotations[0] = new Matrix3f();
>>       correctionRotations[0].setIdentity();
>>       AxisAngle4f checkAngle = new AxisAngle4f();
>> 
>>       // testPoint is used to find the angle that gives the smallest distance
>>       // between the previous and current rotation. Find a point that is not
>>       // in the origin.
>>       Point3f testPoint = new Point3f(vfCrossSection[0], 0, vfCrossSection[1]);
>> 
>>       for(int i = 0; i < numCrossSection; i++) {
>>           if(vfCrossSection[i*2] != 0 || vfCrossSection[i*2 +1] != 0) {
>>               testPoint = new Point3f(vfCrossSection[i*2], 0, vfCrossSection[i*2 +1]);
>>               break;
>>           }
>>       }
>> 
>>       // Fix the orientations by using the angle between previous z and current z
>>       for(int i = 1; i < spines.length; i++) {
>>           float angle = z[i].angle(z[i - 1]);
>>           correctionRotations[i] = correctionRotations[i - 1];
>>           if(angle != 0) {
>>               correctionRotations[i] = new Matrix3f(correctionRotations[i - 1]);
>>               Point3f previous = new Point3f();
>>               //Point3f previous = testPoint;
>>               // Test with negative angle:
>>               Matrix3f previousRotation = new Matrix3f(rotations[i - 1]);
>>               previousRotation.mul(correctionRotations[i - 1]);
>>               previousRotation.transform(testPoint, previous);
>>               Matrix3f delta = new Matrix3f();
>>               delta.setIdentity();
>>               delta.rotY(-angle);
>>               correctionRotations[i].mul(delta);
>> 
>>               Matrix3f negativeRotation = new Matrix3f(rotations[i]);
>>               negativeRotation.mul(correctionRotations[i]);
>> 
>>               Point3f pointNegative = new Point3f();
>>               negativeRotation.transform(testPoint,pointNegative);
>> 
>>               float distNegative = pointNegative.distance(previous);
>> 
>>               // Test with positive angle
>>               delta.rotY(angle*2);
>>               correctionRotations[i].mul(delta);
>>               Matrix3f positiveRotation = new Matrix3f(rotations[i]);
>>               positiveRotation.mul(correctionRotations[i]);
>>               Point3f pointPositive = new Point3f();
>>               positiveRotation.transform(pointPositive);
>>               float distPositive = pointPositive.distance(previous);
>> 
>>               if(distPositive > distNegative) {
>>                   // Reset correctionRotations to negative angle
>>                   delta.rotY(-angle*2);
>>                   correctionRotations[i].mul(delta);
>>               }
>> 
>>               // Check that the angle is not more than PI.
>>               // If it is subtract PI from angle
>>               checkAngle.set(correctionRotations[i]);
>>               if(((float)Math.PI - checkAngle.angle) < 0.001) {
>>                   correctionRotations[i].rotY((float)(checkAngle.angle - Math.PI));
>>               }
>>           }
>>       }
>> 
>>       return correctionRotations;
>>   }
>> =========================================
>> 
>> There are also some trace methods available in there...
>> 
>> perhaps we should trace the some piece of the resulting IFS in another X3D player and compare? that might help us isolate where the math error occurs in Xj3D.
>> 
>> all the best, Don
>> -- 
>> Don Brutzman  Naval Postgraduate School, Code USW/Br       brutzman at nps.edu
>> Watkins 270,  MOVES Institute, Monterey CA 93943-5000 USA   +1.831.656.2149
>> X3D graphics, virtual worlds, navy robotics http://faculty.nps.edu/brutzman
>> <Figure15.17WigglingSnakeCobweb.png><Figure15.17WigglingSnakeCobweb.html><Figure15.17WigglingSnakeFreeWRL.png><Figure15.17WigglingSnakeXj3D.png>_______________________________________________
>> source mailing list
>> source at web3d.org
>> http://web3d.org/mailman/listinfo/source_web3d.org
> 
> 
> _______________________________________________
> source mailing list
> source at web3d.org
> http://web3d.org/mailman/listinfo/source_web3d.org




More information about the source mailing list