I try to mirror one element along Z axis. I made it with such a matrix

1 0 0 0
0 1 0 0
0 0 -1 0
0 0 0 1

The problem is, after mirroring, culling behavies exactly oposite to its
expected behaviour: back side of polygons is seen and front side not.
Additionaly, light source seens to light in opposite direction too.

I tried to negate normals, without efect.
Only if I disable culling it all polygons are seen, but lighting works
still incorrect.

Please try test programm, it is one half of the cube.


import java.awt.GraphicsConfiguration;

import javax.media.j3d.AmbientLight;
import javax.media.j3d.Appearance;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.ColoringAttributes;
import javax.media.j3d.DirectionalLight;
import javax.media.j3d.LineArray;
import javax.media.j3d.Material;
import javax.media.j3d.PolygonAttributes;
import javax.media.j3d.QuadArray;
import javax.media.j3d.Shape3D;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.swing.JFrame;
import javax.vecmath.Color3f;
import javax.vecmath.Matrix4d;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;
import javax.vecmath.Vector3f;

import com.sun.j3d.utils.behaviors.keyboard.KeyNavigatorBehavior;
import com.sun.j3d.utils.universe.SimpleUniverse;

public class MirrorTest extends JFrame {

        private static Point3d x0y0z0 =new Point3d(0,0,0);
        private static Point3d x0y0z1 =new Point3d(0,0,1);
        private static Point3d x0y1z0 =new Point3d(0,1,0);
        private static Point3d x0y1z1 =new Point3d(0,1,1);
        private static Point3d x1y0z0 =new Point3d(1,0,0);
        private static Point3d x1y0z1 =new Point3d(1,0,1);
        private static Point3d x1y1z0 =new Point3d(1,1,0);
        private static Point3d x1y1z1 =new Point3d(1,1,1);

        public MirrorTest(){
                setDefaultCloseOperation(EXIT_ON_CLOSE);
                GraphicsConfiguration config = 
SimpleUniverse.getPreferredConfiguration();
                Canvas3D        canvas3D = new Canvas3D(config);
                getContentPane().add(canvas3D);

                SimpleUniverse universe = new SimpleUniverse(canvas3D);
                universe.getViewingPlatform().setNominalViewingTransform();

                //prepare custom Geometry
                QuadArray geometry = new QuadArray(3*4, QuadArray.COORDINATES | 
QuadArray.NORMALS);
                boolean negateNormalsX = false;
                boolean negateNormalsY = false;
                boolean negateNormalsZ = false;
                int i=0;
                Vector3f normal;
                //z1
                normal = new Vector3f(0,0,1);
                if(negateNormalsZ) normal.z = -normal.z;
                for(int k = i; k<i+4; k++){
                        geometry.setNormal(k, normal);
                }
                geometry.setCoordinate(i++, x0y0z1);
                geometry.setCoordinate(i++, x1y0z1);
                geometry.setCoordinate(i++, x1y1z1);
                geometry.setCoordinate(i++, x0y1z1);
                //x1
                normal = new Vector3f(1,0,0);
                if(negateNormalsX) normal.x = -normal.x;
                for(int k = i; k<i+4; k++){
                        geometry.setNormal(k, normal);
                }
                geometry.setCoordinate(i++, x1y0z0);
                geometry.setCoordinate(i++, x1y1z0);
                geometry.setCoordinate(i++, x1y1z1);
                geometry.setCoordinate(i++, x1y0z1);
                //y1
                normal = new Vector3f(0,1,0);
                if(negateNormalsY) normal.y = -normal.y;
                for(int k = i; k<i+4; k++){
                        geometry.setNormal(k, normal);
                }
                geometry.setCoordinate(i++, x0y1z0);
                geometry.setCoordinate(i++, x0y1z1);
                geometry.setCoordinate(i++, x1y1z1);
                geometry.setCoordinate(i++, x1y1z0);


                //make scene
                BranchGroup scene = new BranchGroup();

                //add navigator
                TransformGroup vpTG = 
universe.getViewingPlatform().getViewPlatformTransform();
                BoundingSphere boundingSphere = new BoundingSphere( new 
Point3d(),1000.0);
                KeyNavigatorBehavior keyboardNavigator = new 
KeyNavigatorBehavior(vpTG);
                keyboardNavigator.setSchedulingBounds(boundingSphere);
                scene.addChild(keyboardNavigator);


                //set lighting
                BoundingSphere lightBounds = new BoundingSphere();
                lightBounds.setCenter(new Point3d(0,0,0));
                lightBounds.setRadius(100);

                AmbientLight ambientLight = new AmbientLight(new 
Color3f(0.3f,0.3f,0.3f));
                ambientLight.setInfluencingBounds(new BoundingSphere(lightBounds));
                scene.addChild(ambientLight);

                DirectionalLight directLight = new DirectionalLight();
                directLight.setInfluencingBounds(lightBounds);
                scene.addChild(directLight);

                //add box with mirror transformation
                Appearance ap = new Appearance();
                Color3f black = new Color3f(0,0,0);
                Color3f green = new Color3f(0,1f,0);
                Material material = new Material(green, black, green, green, 64);
                ap.setMaterial(material);
                PolygonAttributes pa = new PolygonAttributes();
                pa.setCullFace(PolygonAttributes.CULL_FRONT);
                pa.setBackFaceNormalFlip(true);
                //ap.setPolygonAttributes(pa);
                Shape3D shape  = new Shape3D(geometry, ap);
                Transform3D mirror = new Transform3D();
                mirror.set(new Matrix4d( new double [] {
                        1, 0, 0, 0,
                        0, 1, 0, 0,
                        0, 0, -1,0,
                        0, 0, 0, 1
                }));
                TransformGroup tg = new TransformGroup(mirror);
                /*
                Transform3D rot = new Transform3D();
                rot.rotX(-Math.PI);
                TransformGroup tg = new TransformGroup(rot);
                */

                tg.addChild(shape);
                tg.addChild(new Axies(3, 3, 3));
                scene.addChild(tg);

                universe.addBranchGraph(scene);
                setSize(500, 500);
        }

        public static void main(String[] args){
                new MirrorTest().setVisible(true);
        }

        private class Axies extends BranchGroup {
                public Axies(double lengthX, double lengthY, double lengthZ){
                        setCapability(ALLOW_DETACH);
                        Color3f colorX = new Color3f(1, 0, 0);
                        Color3f colorY = new Color3f(0, 1, 0);
                        Color3f colorZ = new Color3f(0, 0, 1);
                        Point3d zero = new Point3d(0,0,0);

                        LineArray lines = new LineArray(6, LineArray.COORDINATES | 
LineArray.COLOR_3);
                        int i=0;
                        //axis X
                        lines.setColor(i, colorX);
                        lines.setCoordinate(i++, zero);
                        lines.setColor(i, colorX);
                        lines.setCoordinate(i++, new Point3d(lengthX, 0, 0));
                        //axis Y
                        lines.setColor(i, colorY);
                        lines.setCoordinate(i++, zero);
                        lines.setColor(i, colorY);
                        lines.setCoordinate(i++, new Point3d(0, lengthY, 0));
                        //axis Z
                        lines.setColor(i, colorZ);
                        lines.setCoordinate(i++, zero);
                        lines.setColor(i, colorZ);
                        lines.setCoordinate(i++, new Point3d(0, 0, lengthZ));

                        addChild(new Shape3D(lines));

                        //prepare arrow Geometry
                        LineArray arrow = new LineArray(2*4, LineArray.COORDINATES);
                        i=0;
                        arrow.setCoordinate(i++, zero);
                        arrow.setCoordinate(i++, new Point3d(-2, 1, 0));
                        arrow.setCoordinate(i++, zero);
                        arrow.setCoordinate(i++, new Point3d(-2, 0, 1));
                        arrow.setCoordinate(i++, zero);
                        arrow.setCoordinate(i++, new Point3d(-2, -1, 0));
                        arrow.setCoordinate(i++, zero);
                        arrow.setCoordinate(i++, new Point3d(-2, 0, -1));

                        //prepare X character
                        LineArray charX = new LineArray(2*2, LineArray.COORDINATES);
                        i=0;
                        charX.setCoordinate(i++, new Point3d(-1, -2, 0));
                        charX.setCoordinate(i++, new Point3d(1, 2, 0));
                        charX.setCoordinate(i++, new Point3d(1, -2, 0));
                        charX.setCoordinate(i++, new Point3d(-1, 2, 0));
                        //prepare Y character
                        LineArray charY = new LineArray(3*2, LineArray.COORDINATES);
                        i=0;
                        charY.setCoordinate(i++, new Point3d(0, -2, 0));
                        charY.setCoordinate(i++, new Point3d(0, 0, 0));
                        charY.setCoordinate(i++, new Point3d(0, 0, 0));
                        charY.setCoordinate(i++, new Point3d(-1, 2, 0));
                        charY.setCoordinate(i++, new Point3d(0, 0, 0));
                        charY.setCoordinate(i++, new Point3d(1, 2, 0));

                        LineArray charZ = new LineArray(3*2, LineArray.COORDINATES);
                        i=0;
                        charZ.setCoordinate(i++, new Point3d(-1, 0, -2));
                        charZ.setCoordinate(i++, new Point3d(1, 0, -2));
                        charZ.setCoordinate(i++, new Point3d(1, 0, -2));
                        charZ.setCoordinate(i++, new Point3d(-1, 0, 2));
                        charZ.setCoordinate(i++, new Point3d(-1, 0, 2));
                        charZ.setCoordinate(i++, new Point3d(1, 0, 2));

                        //make arrows
                        //calculate arrow size
                        double arrowSize = (lengthX + lengthY + lengthZ ) / 3 / 20;
                        Transform3D tr = new Transform3D();
                        TransformGroup tg;
                        Appearance ap;
                        ColoringAttributes ca;

                        //X arrow
                        tr.set(arrowSize, new Vector3d(lengthX, 0,0));
                        tg=new TransformGroup(tr);
                        ap = new Appearance();
                        ca = new ColoringAttributes(colorX, 
ColoringAttributes.FASTEST);
                        ap.setColoringAttributes(ca);
                        tg.addChild(new Shape3D(arrow, ap));
                        addChild(tg);
                        //X character
                        tr.set(arrowSize/2, new Vector3d(lengthX, arrowSize*2, 0));
                        tg = new TransformGroup(tr);
                        tg.addChild(new Shape3D(charX, ap));
                        addChild(tg);

                        //Y arrow
                        tr.set(arrowSize, new Vector3d(0, lengthY,0));
                        Transform3D rotY = new Transform3D();
                        rotY.rotZ(Math.PI/2);
                        tr.mul(rotY);
                        tg=new TransformGroup(tr);
                        ap = new Appearance();
                        ca = new ColoringAttributes(colorY, 
ColoringAttributes.FASTEST);
                        ap.setColoringAttributes(ca);
                        tg.addChild(new Shape3D(arrow, ap));
                        addChild(tg);
                        //Y character
                        tr.set(arrowSize/2, new Vector3d(- arrowSize*2, lengthY, 0));
                        tg = new TransformGroup(tr);
                        tg.addChild(new Shape3D(charY, ap));
                        addChild(tg);

                        //Z arrow
                        tr.set(arrowSize, new Vector3d(0, 0, lengthZ));
                        Transform3D rotZ = new Transform3D();
                        rotZ.rotY(-Math.PI/2);
                        tr.mul(rotZ);
                        tg=new TransformGroup(tr);
                        ap = new Appearance();
                        ca = new ColoringAttributes(colorZ, 
ColoringAttributes.FASTEST);
                        ap.setColoringAttributes(ca);
                        tg.addChild(new Shape3D(arrow, ap));
                        addChild(tg);
                        //Z character
                        tr.set(arrowSize/2, new Vector3d(- arrowSize*2, 0, lengthZ));
                        tg = new TransformGroup(tr);
                        tg.addChild(new Shape3D(charZ, ap));
                        addChild(tg);
                }
        }
}



Radek Wisniewski

===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA3D-INTEREST".  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".

Reply via email to