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

John Carlson john.carlson3 at sbcglobal.net
Tue Jan 26 19:59:39 PST 2016


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




More information about the source mailing list