📄 billboard.java
字号:
/* * $RCSfile: Billboard.java,v $ * * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved. * * Use is subject to license terms. * * $Revision: 1.5 $ * $Date: 2007/02/09 17:17:52 $ * $State: Exp $ */package javax.media.j3d;import java.util.Enumeration;import javax.vecmath.Point3f;import javax.vecmath.Point3d;import javax.vecmath.Vector3d;import javax.vecmath.Vector3f;import javax.vecmath.AxisAngle4d;/** * The Billboard behavior node operates on the TransformGroup node * to cause the local +z axis of the TransformGroup to point at * the viewer's eye position. This is done regardless of the transforms * above the specified TransformGroup node in the scene graph. * * <p> * If the alignment mode is ROTATE_ABOUT_AXIS, the rotation will be * around the specified axis. If the alignment mode is * ROTATE_ABOUT_POINT, the rotation will be about the specified * point, with an additional rotation to align the +y axis of the * TransformGroup with the +y axis in the View. * * <p> * Note that in a multiple View system, the alignment is done to * the primary View only. * * <p> * Billboard nodes are ideal for drawing screen aligned-text or * for drawing roughly-symmetrical objects. A typical use might * consist of a quadrilateral that contains a texture of a tree. * * @see OrientedShape3D */public class Billboard extends Behavior { /** * Specifies that rotation should be about the specified axis. */ public static final int ROTATE_ABOUT_AXIS = 0; /** * Specifies that rotation should be about the specified point and * that the children's Y-axis should match the view object's Y-axis. */ public static final int ROTATE_ABOUT_POINT = 1; // Wakeup condition for Billboard node WakeupOnElapsedFrames wakeupFrame = new WakeupOnElapsedFrames(0, true); // Specifies the billboard's mode of operation. One of ROTATE_AXIAL, // ROTATE_POINT_VIEW, or ROTATE_POINT_WORLD. int mode = ROTATE_ABOUT_AXIS; // Axis about which to rotate. Vector3f axis = new Vector3f(0.0f, 1.0f, 0.0f); Point3f rotationPoint = new Point3f(0.0f, 0.0f, 1.0f); private Vector3d nAxis = new Vector3d(0.0, 1.0, 0.0); // normalized axis // TransformGroup to operate on. TransformGroup tg = null; // reused temporaries private Point3d viewPosition = new Point3d(); private Point3d yUpPoint = new Point3d(); private Vector3d eyeVec = new Vector3d(); private Vector3d yUp = new Vector3d(); private Vector3d zAxis = new Vector3d(); private Vector3d yAxis = new Vector3d(); private Vector3d vector = new Vector3d(); private AxisAngle4d aa = new AxisAngle4d(); static final double EPSILON = 1.0e-6; /** * Constructs a Billboard node with default parameters. * The default values are as follows: * <ul> * alignment mode : ROTATE_ABOUT_AXIS<br> * alignment axis : Y-axis (0,1,0)<br> * rotation point : (0,0,1)<br> * target transform group: null<br> *</ul> */ public Billboard() { nAxis.x = 0.0; nAxis.y = 1.0; nAxis.z = 0.0; } /** * Constructs a Billboard node with default parameters that operates * on the specified TransformGroup node. * The default alignment mode is ROTATE_ABOUT_AXIS rotation with the axis * pointing along the Y axis. * @param tg the TransformGroup node that this Billboard * node operates upon */ public Billboard(TransformGroup tg) { this.tg = tg; nAxis.x = 0.0; nAxis.y = 1.0; nAxis.z = 0.0; } /** * Constructs a Billboard node with the specified axis and mode * that operates on the specified TransformGroup node. * The specified axis must not be parallel to the <i>Z</i> * axis--(0,0,<i>z</i>) for any value of <i>z</i>. It is not * possible for the +<i>Z</i> axis to point at the viewer's eye * position by rotating about itself. The target transform will * be set to the identity if the axis is (0,0,<i>z</i>). * * @param tg the TransformGroup node that this Billboard * node operates upon * @param mode alignment mode, one of ROTATE_ABOUT_AXIS or * ROTATE_ABOUT_POINT * @param axis the ray about which the billboard rotates */ public Billboard(TransformGroup tg, int mode, Vector3f axis) { this.tg = tg; this.mode = mode; this.axis.set(axis); double invMag; invMag = 1.0/Math.sqrt(axis.x*axis.x + axis.y*axis.y + axis.z*axis.z); nAxis.x = (double)axis.x*invMag; nAxis.y = (double)axis.y*invMag; nAxis.z = (double)axis.z*invMag; } /** * Constructs a Billboard node with the specified rotation point and mode * that operates on the specified TransformGroup node. * @param tg the TransformGroup node that this Billboard * node operates upon * @param mode alignment mode, one of ROTATE_ABOUT_AXIS or * ROTATE_ABOUT_POINT * @param point the position about which the billboard rotates */ public Billboard(TransformGroup tg, int mode, Point3f point) { this.tg = tg; this.mode = mode; this.rotationPoint.set(point); } /** * Sets the alignment mode. * @param mode one of: ROTATE_ABOUT_AXIS or ROTATE_ABOUT_POINT */ public void setAlignmentMode(int mode) { this.mode = mode; } /** * Gets the alignment mode. * @return one of: ROTATE_ABOUT_AXIS or ROTATE_ABOUT_POINT */ public int getAlignmentMode() { return this.mode; } /** * Sets the alignment axis. * The specified axis must not be parallel to the <i>Z</i> * axis--(0,0,<i>z</i>) for any value of <i>z</i>. It is not * possible for the +<i>Z</i> axis to point at the viewer's eye * position by rotating about itself. The target transform will * be set to the identity if the axis is (0,0,<i>z</i>). * * @param axis the ray about which the billboard rotates */ public void setAlignmentAxis(Vector3f axis) { this.axis.set(axis); double invMag; invMag = 1.0/Math.sqrt(axis.x*axis.x + axis.y*axis.y + axis.z*axis.z); nAxis.x = (double)axis.x*invMag; nAxis.y = (double)axis.y*invMag; nAxis.z = (double)axis.z*invMag; } /** * Sets the alignment axis. * The specified axis must not be parallel to the <i>Z</i> * axis--(0,0,<i>z</i>) for any value of <i>z</i>. It is not * possible for the +<i>Z</i> axis to point at the viewer's eye * position by rotating about itself. The target transform will * be set to the identity if the axis is (0,0,<i>z</i>). * * @param x the x component of the ray about which the billboard rotates * @param y the y component of the ray about which the billboard rotates * @param z the z component of the ray about which the billboard rotates */ public void setAlignmentAxis(float x, float y, float z) { this.axis.set(x, y, z); this.axis.set(axis); double invMag; invMag = 1.0/Math.sqrt(axis.x*axis.x + axis.y*axis.y + axis.z*axis.z); nAxis.x = (double)axis.x*invMag; nAxis.y = (double)axis.y*invMag; nAxis.z = (double)axis.z*invMag; } /** * Gets the alignment axis and sets the parameter to this value. * @param axis the vector that will contain the ray about which * the billboard rotates */ public void getAlignmentAxis(Vector3f axis) { axis.set(this.axis); } /** * Sets the rotation point. * @param point the point about which the billboard rotates */ public void setRotationPoint(Point3f point) { this.rotationPoint.set(point); } /** * Sets the rotation point. * @param x the x component of the point about which the billboard rotates * @param y the y component of the point about which the billboard rotates * @param z the z component of the point about which the billboard rotates */ public void setRotationPoint(float x, float y, float z) { this.rotationPoint.set(x, y, z); } /** * Gets the rotation point and sets the parameter to this value. * @param point the position the Billboard rotates about */ public void getRotationPoint(Point3f point) { point.set(this.rotationPoint); } /** * Sets the tranformGroup for this Billboard object. * @param tg the transformGroup node which replaces the current * transformGroup node for this Billboard */ public void setTarget(TransformGroup tg ) { this.tg = tg; } /** * Returns a copy of the transformGroup associated with this Billboard. * @return the TranformGroup for this Billboard */ public TransformGroup getTarget() { return(tg); } /** * Initialize method that sets up initial wakeup criteria. */ public void initialize() { // Insert wakeup condition into queue wakeupOn(wakeupFrame); } /** * Process stimulus method that computes appropriate transform. * @param criteria an enumeration of the criteria that caused the * stimulus */ public void processStimulus(Enumeration criteria) { double angle = 0.0; double mag,sign; double tx,ty,tz; if( tg == null ){ wakeupOn(wakeupFrame); return; } // get viewplatforms's location in virutal world View v = this.getView(); if( v == null ) { wakeupOn(wakeupFrame); return; } Canvas3D canvas = (Canvas3D)v.getCanvas3D(0); boolean status; Transform3D xform = new Transform3D(); Transform3D bbXform = new Transform3D(); Transform3D prevTransform = new Transform3D(); ((TransformGroupRetained) tg.retained).getTransform(prevTransform); if (mode == ROTATE_ABOUT_AXIS ) { // rotate about axis canvas.getCenterEyeInImagePlate(viewPosition); canvas.getImagePlateToVworld(xform); // xform is imagePlateToLocal xform.transform(viewPosition); // get billboard's transform // since we are using getTransform() to get the transform // of the transformGroup, we need to use getLocalToVworld()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -