⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 billboard.java

📁 JAVA3D矩陈的相关类
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
            // to get the localToVworld which includes the static transform	    ((NodeRetained)tg.retained).getLocalToVworld(xform);	    xform.invert(); // xform is now vWorldToLocal	    // transform the eye position into the billboard's coordinate system	    xform.transform(viewPosition);	    // eyeVec is a vector from the local origin to the eye pt in local	    eyeVec.set(viewPosition);	    eyeVec.normalize();	    // project the eye into the rotation plane	    status = projectToPlane(eyeVec, nAxis);	    // If the first project was successful .. 	    if (status) {		// project the z axis into the rotation plane		zAxis.x = 0.0;		zAxis.y = 0.0;		zAxis.z = 1.0;		status = projectToPlane(zAxis, nAxis);	    }	    ((TransformGroupRetained) tg.retained).getTransform(xform);	    if (status) {		// compute the sign of the angle by checking if the cross product 		// of the two vectors is in the same direction as the normal axis		vector.cross(eyeVec, zAxis); 		if (vector.dot(nAxis) > 0.0) {		    sign = 1.0;		} else { 		    sign = -1.0;		}		// compute the angle between the projected eye vector and the 		// projected z		double dot = eyeVec.dot(zAxis);		if (dot > 1.0f) {		    dot = 1.0f;		} else if (dot < -1.0f) {		    dot = -1.0f;		}				angle = sign*Math.acos(dot);		// use -angle because xform is to *undo* rotation by angle		aa.x = nAxis.x; 		aa.y = nAxis.y; 		aa.z = nAxis.z;		aa.angle = -angle;		bbXform.set(aa);		if( !prevTransform.epsilonEquals(bbXform, EPSILON)) {		    // Optimization for Billboard since it use passive		    // behavior		    // set the transform on the Billboard TG		    tg.setTransform(bbXform);		}	    }	    else {		bbXform.setIdentity();		if (!prevTransform.epsilonEquals(bbXform, EPSILON)) {		    tg.setTransform(bbXform);		}	    }        } else { // rotate about point	    // Need to rotate Z axis to point to eye, and Y axis to be 	    // parallel to view platform Y axis, rotating around rotation pt 	    Transform3D zRotate = new Transform3D();	    // get the eye point 	    canvas.getCenterEyeInImagePlate(viewPosition);	    // derive the yUp point	    yUpPoint.set(viewPosition);	    yUpPoint.y += 0.01; // one cm in Physical space	    // transform the points to the Billboard's space	    canvas.getImagePlateToVworld(xform); // xform is ImagePlateToVworld	    xform.transform(viewPosition);	    xform.transform(yUpPoint);	    // get billboard's transform	    // since we are using getTransform() to get the transform	    // of the transformGroup, we need to use getLocalToVworld()            // to get the localToVworld which includes the static transform	    ((NodeRetained)tg.retained).getLocalToVworld(xform);	    xform.invert(); // xform is vWorldToLocal	    // transfom points to local coord sys	    xform.transform(viewPosition);	    xform.transform(yUpPoint);	    // Make a vector from viewPostion to 0,0,0 in the BB coord sys	    eyeVec.set(viewPosition);	    eyeVec.normalize();	    // create a yUp vector	    yUp.set(yUpPoint);	    yUp.sub(viewPosition);	    yUp.normalize();	    // find the plane to rotate z	    zAxis.x = 0.0;	    zAxis.y = 0.0;	    zAxis.z = 1.0;	    // rotation axis is cross product of eyeVec and zAxis	    vector.cross(eyeVec, zAxis); // vector is cross product	    // if cross product is non-zero, vector is rotation axis and 	    // rotation angle is acos(eyeVec.dot(zAxis)));	    double length = vector.length();	    if (length > 0.0001) {		double dot = eyeVec.dot(zAxis);		if (dot > 1.0f) {		    dot = 1.0f;		} else if (dot < -1.0f) {		    dot = -1.0f;		}		angle = Math.acos(dot);		aa.x = vector.x;		aa.y = vector.y;		aa.z = vector.z;		aa.angle = -angle;		zRotate.set(aa);	    } else {		// no rotation needed, set to identity (scale = 1.0)		zRotate.set(1.0);	    }	    // Transform the yAxis by zRotate	    yAxis.x = 0.0;	    yAxis.y = 1.0;	    yAxis.z = 0.0;	    zRotate.transform(yAxis);	    // project the yAxis onto the plane perp to the eyeVec 	    status = projectToPlane(yAxis, eyeVec);	    if (status) {		// project the yUp onto the plane perp to the eyeVec 		status = projectToPlane(yUp, eyeVec);	    }	    ((TransformGroupRetained) tg.retained).getTransform(xform);	    if (status) {		// rotation angle is acos(yUp.dot(yAxis));		double dot = yUp.dot(yAxis);		// Fix numerical error, otherwise acos return NULL		if (dot > 1.0f) {		    dot = 1.0f;		} else if (dot < -1.0f) {		    dot = -1.0f;		}		angle = Math.acos(dot);		// check the sign by looking a the cross product vs the eyeVec 		vector.cross(yUp, yAxis);  // vector is cross product		if (eyeVec.dot(vector) < 0) {		    angle *= -1;		} 		aa.x = eyeVec.x;		aa.y = eyeVec.y;		aa.z = eyeVec.z;		aa.angle = -angle;		xform.set(aa); // xform is now yRotate		// rotate around the rotation point		vector.x = rotationPoint.x;		vector.y = rotationPoint.y;		vector.z = rotationPoint.z; // vector to translate to RP		bbXform.set(vector);  // translate to RP		bbXform.mul(xform);   // yRotate		bbXform.mul(zRotate); // zRotate		vector.scale(-1.0);   // vector to translate back		xform.set(vector);    // xform to translate back 		bbXform.mul(xform);   // translate back		if (!prevTransform.epsilonEquals(bbXform, EPSILON)) {		    // set the transform on the Billboard TG		    tg.setTransform(bbXform);		}	    }	    else {		bbXform.setIdentity();		if (!prevTransform.epsilonEquals(bbXform, EPSILON)) {		    tg.setTransform(bbXform);		}	    }	}	// Insert wakeup condition into queue	wakeupOn(wakeupFrame);}private boolean projectToPlane(Vector3d projVec, Vector3d planeVec)  {    double dis = planeVec.dot(projVec);    projVec.x = projVec.x - planeVec.x*dis;    projVec.y = projVec.y - planeVec.y*dis;    projVec.z = projVec.z - planeVec.z*dis;    double length = projVec.length();        if (length < EPSILON) {	return false;    }     projVec.scale(1 / length);    return true;}    /**     * Creates a new instance of the node.  This routine is called     * by <code>cloneTree</code> to duplicate the current node.     * @param forceDuplicate when set to <code>true</code>, causes the     *  <code>duplicateOnCloneTree</code> flag to be ignored.  When     *  <code>false</code>, the value of each node's     *  <code>duplicateOnCloneTree</code> variable determines whether     *  NodeComponent data is duplicated or copied.     *     * @see Node#cloneTree     * @see Node#cloneNode     * @see Node#duplicateNode     * @see NodeComponent#setDuplicateOnCloneTree     */    public Node cloneNode(boolean forceDuplicate) {        Billboard b = new Billboard();        b.duplicateNode(this, forceDuplicate);        return b;    }       /**     * Copies all Billboard information from     * <code>originalNode</code> into     * the current node.  This method is called from the     * <code>cloneNode</code> method which is, in turn, called by the     * <code>cloneTree</code> method.<P>      *     * @param originalNode the original node to duplicate.     * @param forceDuplicate when set to <code>true</code>, causes the     *  <code>duplicateOnCloneTree</code> flag to be ignored.  When     *  <code>false</code>, the value of each node's     *  <code>duplicateOnCloneTree</code> variable determines whether     *  NodeComponent data is duplicated or copied.     *     * @exception RestrictedAccessException if this object is part of a live     *  or compiled scenegraph.     *     * @see Node#duplicateNode     * @see Node#cloneTree     * @see NodeComponent#setDuplicateOnCloneTree     */    void duplicateAttributes(Node originalNode, boolean forceDuplicate) {        super.duplicateAttributes(originalNode, forceDuplicate);	Billboard bb = (Billboard) originalNode;         setAlignmentMode(bb.getAlignmentMode());        Vector3f v = new Vector3f();        bb.getAlignmentAxis(v);	setAlignmentAxis(v);		Point3f p = new Point3f();	bb.getRotationPoint(p);        setRotationPoint(p);	// this will be updated by updateNodeReferences() later        setTarget(bb.getTarget());    }        /**     * Callback used to allow a node to check if any scene graph objects     * referenced     * by that node have been duplicated via a call to <code>cloneTree</code>.     * This method is called by <code>cloneTree</code> after all nodes in     * the sub-graph have been duplicated. The cloned Leaf node's method     * will be called and the Leaf node can then look up any object references     * by using the <code>getNewObjectReference</code> method found in the     * <code>NodeReferenceTable</code> object.  If a match is found, a     * reference to the corresponding object in the newly cloned sub-graph     * is returned.  If no corresponding reference is found, either a     * DanglingReferenceException is thrown or a reference to the original     * object is returned depending on the value of the     * <code>allowDanglingReferences</code> parameter passed in the     * <code>cloneTree</code> call.     * <p>     * NOTE: Applications should <i>not</i> call this method directly.     * It should only be called by the cloneTree method.     *     * @param referenceTable a NodeReferenceTableObject that contains the     *  <code>getNewObjectReference</code> method needed to search for     *  new object instances.     * @see NodeReferenceTable     * @see Node#cloneTree     * @see DanglingReferenceException     */    public void updateNodeReferences(NodeReferenceTable referenceTable) {	super.updateNodeReferences(referenceTable);	        // check for new TransformGroup	TransformGroup g = getTarget();        if (g != null) {            setTarget((TransformGroup) referenceTable.getNewObjectReference(g));        }    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -