Man... I can't believe I wrote that slop.

If you run the test program I just posted, you will see a cylinder
object rooted at the origin of the scene and a sphere.  All well and
good, but the cylinder ends out in free space someplace.  It should
connect to the blue sphere, but its pointing off in the wrong direction.

Since my last posting I cleaned up the translation from the cylinder
origin and put it after the rotation, but it still doesn't work.  Really
strange....

-- John


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;

// Origin and termination vector...

                Vector3d originVec = new Vector3d(
                                lastx,
                                lasty,
                                lastz
                                );

                Vector3d termVec = new Vector3d(
                                x,
                                y,
                                z
                                );

        Vector3d diffVec = new Vector3d(originVec);
        diffVec.sub(termVec);

// Length of the cylinder...

        float height = (float) diffVec.length();

// 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);

// Calculate the translaton from the cylinder origin...

        diffVec.scale(0.5);

        originVec.sub(diffVec);
        termVec.sub(diffVec);

// 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);
}

}

Reply via email to