[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