All,
I'm trying to connect the dots with cylinder objects but can't quite get
it right. The endpoints of the cylinder should connect to two of the
spheres, but clearly this isn't happening. The meat of the issue is in
the method "makeConnector".
My suspician is that since I do the rotation transform FIRST, that the o
to seerigin of the cylinder is getting moved away from where it should
be by the time the translation is performed. Running the test program,
this is easy to see., then
But if I do the translation FIRST, then the rotation gets messed up,
apparently because the origin of the rotation is changed.
So this is actually an interesting problem. How do you composite
transforms without pulling the rug out from under yourself.
I'm sorry if I haven't explained this well. Those of you familiar with
string geometries and this stuff will likely recognize the issue. I
just don't know how to deal with it. Any ideas?
-- John
--
_________________________________________________________
John T. Nelson
President | Computation.com Inc.
mail: | [EMAIL PROTECTED]
company: | http://www.computation.com/
journal: | http://www.computation.org/
_________________________________________________________
package stand;
import java.applet.Applet;
import java.awt.*;
import java.io.*;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.Sphere;
import com.sun.j3d.utils.geometry.Cylinder;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import java.util.Enumeration;
public class Test extends Applet {
// Constants for type of light to use
private static final int DIRECTIONAL_LIGHT = 0;
private static final int POINT_LIGHT = 1;
private static final int SPOT_LIGHT = 2;
private static final float LATTICE_QUANT = 1.0f;
private static final int lightType = POINT_LIGHT;
Color3f eColor = new Color3f(0.0f, 0.0f, 0.0f);
Color3f sColor = new Color3f(1.0f, 1.0f, 1.0f);
Color3f lColor1 = new Color3f(1.0f, 1.0f, 1.0f);
Color3f alColor = new Color3f(0.1f, 0.1f, 0.4f);
Color3f bgColor = new Color3f(0.01f, 0.01f, 0.05f);
Color3f hColor = new Color3f(0.6f, 0.1f, 0.1f); // Red
Color3f pColor = new Color3f(0.1f, 0.1f, 0.6f); // Blue
Color3f gColor = new Color3f(0.6f, 0.6f, 0.6f); // Grey
private SimpleUniverse u = null;
BranchGroup scene;
TransformGroup objScale;
public BranchGroup createSceneGraph(SimpleUniverse u)
{
BranchGroup objRoot = new BranchGroup();
// Global transform group...
objScale = new TransformGroup();
Transform3D t3d = new Transform3D();
t3d.setScale(0.2);
objScale.setTransform(t3d);
// Set up the background
// Create a bounds for the background and lights
BoundingSphere bounds =
new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
Background bg = new Background(bgColor);
bg.setApplicationBounds(bounds);
objScale.addChild(bg);
objRoot.addChild(objScale);
return objRoot;
}
private void createLights()
{
Transform3D t;
// Create a transformation for the light
t = new Transform3D();
Vector3d lPos1 = new Vector3d(10.0, 10.0, 10.0);
t.set(lPos1);
TransformGroup l1Trans = new TransformGroup(t);
objScale.addChild(l1Trans);
// Create a Geometry for the light
ColoringAttributes caL1 = new ColoringAttributes();
caL1.setColor(lColor1);
Appearance appL1 = new Appearance();
appL1.setColoringAttributes(caL1);
l1Trans.addChild(new Sphere(0.05f, appL1));
// Create light
AmbientLight aLgt = new AmbientLight(alColor);
Light lgt1 = null;
Point3f lPoint = new Point3f(0.0f, 0.0f, 0.0f);
Point3f atten = new Point3f(10.0f, 0.0f, 0.0f);
Vector3f lDirect1 = new Vector3f(lPos1);
lDirect1.negate();
lgt1 = new DirectionalLight(lColor1, lDirect1);
// Set the influencing bounds
BoundingSphere bounds =
new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
aLgt.setInfluencingBounds(bounds);
lgt1.setInfluencingBounds(bounds);
// Add the lights into the scene graph
objScale.addChild(aLgt);
objScale.addChild(lgt1);
}
private void makeBall(double x, double y, double z, Color3f color)
{
Transform3D t;
t = new Transform3D();
Vector3d pos = new Vector3d(x, y, z);
t.set(pos);
TransformGroup transGroup1 = new TransformGroup(t);
transGroup1.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
transGroup1.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
Material m = new Material(color, eColor, color, sColor, 100.0f);
m.setLightingEnable(true);
Appearance a = new Appearance();
a.setMaterial(m);
// Sphere sph = new Sphere(0.5f, Sphere.GENERATE_NORMALS, a);
Sphere sph = new Sphere(0.25f, a);
transGroup1.addChild(sph);
objScale.addChild(transGroup1);
}
private double testx[];
private double testy[];
private double testz[];
private int n = 3;
private void buildTests()
{
testx = new double[n];
testy = new double[n];
testz = new double[n];
this.loadit(0, 0.0, 0.0, 0.0);
this.loadit(1, 1.5, 1.5, 0.0);
this.loadit(2, -1.5, 1.5, 0.0);
}
private void loadit(int i, double x, double y, double z)
{
testx[i] = x;
testy[i] = y;
testz[i] = z;
}
private void doit()
{
this.buildTests();
for ( int i = 0; i < n; i++ ) {
double x = testx[i];
double y = testy[i];
double z = testz[i];
if ( i % 2 == 0 )
this.makeBall(x, y, z, hColor);
else
this.makeBall(x, y, z, pColor);
if ( i < n - 1 )
makeConnector(
x,
y,
z,
testx[ i + 1 ],
testy[ i + 1 ],
testz[ i + 1 ]
);
}
}
private void makeConnector(double lastx, double lasty, double lastz,
double x, double y, double z)
{
Transform3D t;
Vector3d pos;
float radius = 0.05f;
// Length of the cylinder...
Vector3d vec = new Vector3d(
lastx - x,
lasty - y,
lastz - z
);
float height = (float) vec.length();
// Translation vector...
Vector3d originVec = new Vector3d(
lastx,
lasty,
lastz
);
Vector3d termVec = new Vector3d(
x,
y,
z
);
Vector3d diffVec = new Vector3d(originVec);
diffVec.sub(termVec);
diffVec.scale(0.5);
originVec.sub(diffVec);
termVec.sub(diffVec);
// Define end points as new vectors
Vector3d fromDir = new Vector3d(originVec);
Vector3d toDir = new Vector3d(termVec);
// Compute the value of the angle between them...
double rotInRadians = fromDir.angle(toDir);
// Compute an orthagonal vector to later define the rotation axis
Vector3d orthagonalAxis = new Vector3d();
orthagonalAxis.cross(fromDir, toDir);
orthagonalAxis.normalize();
// Create new rotation matrix
AxisAngle4d rotAxis = new AxisAngle4d(orthagonalAxis, rotInRadians);
// TransformGroup1 will handle the translation...
TransformGroup transGroup1 = new TransformGroup();
transGroup1.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
transGroup1.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
// Now set the transform up...
t = new Transform3D();
transGroup1.getTransform(t);
t.setRotation(rotAxis);
transGroup1.setTransform(t);
// TransformGroup2 handles the rotation...
TransformGroup transGroup2 = new TransformGroup();
transGroup2.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
transGroup2.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
// Now set the transform up...
t = new Transform3D();
transGroup2.getTransform(t);
t.setTranslation(originVec);
transGroup2.setTransform(t);
// Appearance and materials...
Material m = new Material(gColor, eColor, gColor, sColor, 100.0f);
m.setLightingEnable(true);
Appearance a = new Appearance();
a.setMaterial(m);
// Now build the cylinder...
Cylinder cyl = new Cylinder(radius, height, a);
transGroup2.addChild(cyl);
transGroup1.addChild(transGroup2);
objScale.addChild(transGroup1);
}
public Test()
{
}
public void init()
{
setLayout(new BorderLayout());
GraphicsConfiguration config =
SimpleUniverse.getPreferredConfiguration();
Canvas3D c = new Canvas3D(config);
add("Center", c);
// Set up the universe...
u = new SimpleUniverse(c);
scene = this.createSceneGraph(u);
this.doit();
this.createLights();
// Let Java 3D perform optimizations on this scene graph.
scene.compile();
// This will move the ViewPlatform back a bit so the
// objects in the scene can be viewed.
u.getViewingPlatform().setNominalViewingTransform();
u.addBranchGraph(scene);
}
public void destroy()
{
u.removeAllLocales();
}
protected void finalize() throws Throwable
{
System.err.println("Finalizing");
super.finalize();
}
// The following allows Vis to be run as an application
// as well as an applet.
public static void main(String[] args)
{
new MainFrame(new Test(), 700, 700);
}
}