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".