> From: [EMAIL PROTECTED] (Alexander Lazovsky)
>
> How can I get coordinates of object of graph scene 
> after it has being moved from its initial place on live scene?

If you want get the current VWorld coordinates of a Node, inquire the 
LocalToVworld transform for the Node and transform the point 0,0,0 to Vworld 
coords.  To transform the points of a piece of geometry, inquire the points from 
the Geometry and transform them through the LocalToVworld transform.

You'll need to set the capability bits to be able to inquire the data when the 
scene graph is live.

If you want to transform the local coordinates to window coordinates, use the 
utility class attached below.

Doug Gehringer
/**
 * Utility class for doing local->window transformations for case where 
 * Canvas3D is a simple display such as a monitor. This won't work for the 
 * more complex cases (i.e. a multiple canvases, head tracking, etc).
 * 
 * Usage:
 *    // after the canvas and node are created
 *    LocalToWindow locToWindow = LocalToWindow(node, canvas);
 *    ...
 *    // when we need to transform (canvas location and node transforms may have
 *    // changed)
 *    locToWindow.update(); // make sure transforms are up to date
 *
 *    Point3d[] localPts = <some local coords to transform >
 *    Point[] windowPts = <the area to put the tranformed pts >
 *    for (int i = 0; i < localPts.length; i++) {
 *       locToWindow.transformPt(localPts[i], windowPts[i]);
 *    }
 */

// standard j3d packages
import javax.media.j3d.*;
import javax.vecmath.*;
import java.awt.Point;
import java.awt.Dimension;

public class LocalToWindow {

    Canvas3D    canvas = null;
    Node        node = null;

    // inquired/derived data
    Transform3D localToVworld = new Transform3D();
    Transform3D vworldToImagePlate  = new Transform3D();
    Transform3D localToImagePlate = new Transform3D();
    Point3d     eyePos = new Point3d();
    int         projType;
    Point       canvasScr;
    Dimension   screenSize;
    double      metersPerPixelX;
    double      metersPerPixelY;

    // Temporaries
    Point3d     imagePlatePt = new Point3d();
    Vector3d    projVec = new Vector3d();
    Point2d     screenPt = new Point2d();

    /** 
     * Called with the Node which specifies the local coordinates for the
     * points to be transformed and the Canvas3D where the points are
     * displayed
     */
    public LocalToWindow(Node node, Canvas3D canvas) {
        this.canvas = canvas;
        this.node = node;
        update();
    }

    /**
     * Either create LocalToWindow() just before transforming points or call
     * this method to ensure that the transforms are up to date.  Note: if 
     * you are transforming several points, you only need to call this method 
     * once.  
     */
    public void update() {
        node.getLocalToVworld(localToVworld);
        canvas.getVworldToImagePlate(vworldToImagePlate);

        // Make a composite transform:
        // vWorldPt = LocalToVworld * localPt;
        // imagePlatePt = VworldToImagePlate * vWorldPt;
        // imagePlatePt = VworldToImagePlate * LocalToVworld * localPt;
        localToImagePlate.mul(vworldToImagePlate, localToVworld);

        // we need these to project the point from Image Plate coords to 
        // the actual image plate (i.e. perpsective)
        canvas.getCenterEyeInImagePlate(eyePos);
        //System.out.println("eyePos = " + eyePos);
        projType = canvas.getView().getProjectionPolicy();

        // this stuff is to go from image plate coords to window coords
        canvasScr = canvas.getLocationOnScreen();
        //System.out.println("canvasScr = " + canvasScr);
        screenSize = canvas.getScreen3D().getSize();
        double physicalScreenWidth =
            canvas.getScreen3D().getPhysicalScreenWidth();
        double physicalScreenHeight =
            canvas.getScreen3D().getPhysicalScreenHeight();
        metersPerPixelX = physicalScreenWidth / (double) screenSize.width;
        metersPerPixelY = physicalScreenHeight / (double) screenSize.height;

    }

    /** 
     * Transform the point from local coords to window coords
     */
    public void transformPt(Point3d localPt, Point windowPt) { 

        // System.out.println("vWorld Pt = " + local);

        localToImagePlate.transform(localPt, imagePlatePt);
        //System.out.println("imagePlatePt = " + imagePlatePt);

        double zScale = 1.0; // default, used for PARALELL_PROJECTION
        if (projType == View.PERSPECTIVE_PROJECTION) {
            // get the vector from eyePos to imagePlatePt
            projVec.sub(imagePlatePt, eyePos);

            // Scale this vector to make it end at the projection plane.
            // Scale is ratio : 
            //     eye->imagePlate Plane dist  / eye->imagePlatePt dist
            // eye dist to plane is eyePos.z (eye is in +z space)
            // image->eye dist is -projVec.z (image->eye is in -z dir)
            //System.out.println("eye dist = " + (eyePos.z));
            //System.out.println("image dist = " + (-projVec.z));
            zScale = eyePos.z / (-projVec.z);

            screenPt.x = eyePos.x + projVec.x * zScale;
            screenPt.y = eyePos.y + projVec.y * zScale;
        } 
        //System.out.println("screenPt = " + screenPt);
        // Note: screenPt is in image plate coords, at z=0

        // Transform from image plate coords to screen coords
        windowPt.x = (int)Math.round(screenPt.x / metersPerPixelX) - 
                canvasScr.x;
        windowPt.y = screenSize.height - 1 -
            (int)Math.round(screenPt.y / metersPerPixelY) - canvasScr.y;
        //System.out.println("windowPt = " + windowPt);

    }
}

Reply via email to