📄 morphretained.java
字号:
/* * $RCSfile: MorphRetained.java,v $ * * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved. * * Use is subject to license terms. * * $Revision: 1.9 $ * $Date: 2007/04/12 17:34:05 $ * $State: Exp $ */package javax.media.j3d;import javax.vecmath.*;import java.util.ArrayList;import java.util.Vector;/** * A morph leaf node consisting of geometery and appearance properties. */class MorphRetained extends LeafRetained implements GeometryUpdater { // These bits should match the Shape3D bits ...(Since the mirrors for // both are Shape3DRetained static final int GEOMETRY_CHANGED = 0x00001; static final int APPEARANCE_CHANGED = 0x00002; static final int COLLISION_CHANGED = 0x00004; static final int BOUNDS_CHANGED = 0x00008; static final int APPEARANCEOVERRIDE_CHANGED = 0x00010; static final int UPDATE_MORPH = 0x00020; private static final double TOLERANCE = 1.0e-4; /** * The mirror Shape3DRetained nodes for this object. There is one * mirror for each instance of this Shape3D node. If it is not in * a SharedGroup, only index 0 is valid. */ ArrayList mirrorShape3D = new ArrayList(); // Target threads to be notified when morph changes final static int targetThreads = (J3dThread.UPDATE_RENDER | J3dThread.UPDATE_GEOMETRY); /** * The appearance component of the morph node. */ AppearanceRetained appearance = null; /** * The Geosets associated with the morph node. */ GeometryArrayRetained geometryArrays[]; private int numGeometryArrays = 0; /** * The weight vector the morph node. */ double weights[]; /** * Reference to the BranchGroup path of this mirror shape * This is used for picking only. */ BranchGroupRetained branchGroupPath[]; // cache value for picking in mirror shape. // True if all the node of the path from this to root are all pickable boolean isPickable = true; // cache value for collidable in mirror shape. // True if all the node of the path from this to root are all collidable boolean isCollidable = true; // closest switch parent SwitchRetained closestSwitchParent = null; // the child index from the closest switch parent int closestSwitchIndex = -1; // Is this Morph visible ? The default is true. boolean visible = true; // geometry Bounds in local coordinate Bounds bounds = null; // geometry Bounds in virtual world coordinate BoundingBox vwcBounds = new BoundingBox(); // collision Bound in local coordinate Bounds collisionBound = null; // collision Bounds in virtual world coordinate Bounds collisionVwcBound = null; GeometryArray morphedGeometryArray = null; // Morph data float[] Mcoord = null; float[] Mcolor = null; float[] Mnormal = null; // First dimension is the coordSet, second dimenension is the vertex index // each vertex has 2 or 3floats float[][]MtexCoord = null; // Whether the normal appearance is overrided by the alternate app boolean appearanceOverrideEnable = false; int changedFrequent = 0; MorphRetained() { this.nodeType = NodeRetained.MORPH; localBounds = new BoundingBox(); ((BoundingBox)localBounds).setLower( 1.0, 1.0, 1.0); ((BoundingBox)localBounds).setUpper(-1.0,-1.0,-1.0); } /** * Sets the collision bounds of a node. * @param bounds the bounding object for the node */ void setCollisionBounds(Bounds bounds) { if (bounds != null) { collisionBound = (Bounds)bounds.clone(); } else { collisionBound = null; } if (source.isLive()) { // Notify Geometry Structure to set mirror shape collision // bound and check for collision J3dMessage message = new J3dMessage(); message.type = J3dMessage.COLLISION_BOUND_CHANGED; message.threads = J3dThread.UPDATE_TRANSFORM; message.universe = universe; message.args[1] = collisionBound; VirtualUniverse.mc.processMessage(message); } } /** * Sets the geometric bounds of a node. * @param bounds the bounding object for the node */ void setBounds(Bounds bounds) { super.setBounds(bounds); if (source.isLive() && !boundsAutoCompute) { J3dMessage message = new J3dMessage(); message.type = J3dMessage.REGION_BOUND_CHANGED; message.threads = J3dThread.UPDATE_TRANSFORM | targetThreads; message.universe = universe; message.args[0] = Shape3DRetained.getGeomAtomsArray(mirrorShape3D); message.args[1] = localBounds; VirtualUniverse.mc.processMessage(message); } } /** * Gets the collision bounds of a node. * @return the node's bounding object */ Bounds getCollisionBounds() { return (collisionBound == null? null : (Bounds)collisionBound.clone()); } /** * Sets the geometryArrays component of the Morph node. * @param geometryArrays the new vector of geometryArrays for the morph node */ void setGeometryArrays(GeometryArray geometryArrays[]) { int i; if ((geometryArrays == null || geometryArrays.length == 0) && numGeometryArrays == 0) return; GeometryArrayRetained geo, prevGeo; if (numGeometryArrays != 0 && (geometryArrays == null || numGeometryArrays != geometryArrays.length)) throw new IllegalArgumentException(J3dI18N.getString("MorphRetained0")); for (i=1;i < geometryArrays.length;i++) { if (geometryArrays[i] == null || geometryArrays[i-1] == null) throw new IllegalArgumentException(J3dI18N.getString("MorphRetained1")); geo = (GeometryArrayRetained)geometryArrays[i].retained; prevGeo = (GeometryArrayRetained)geometryArrays[i-1].retained; if (prevGeo == null || geo == null) { throw new IllegalArgumentException(J3dI18N.getString("MorphRetained1")); } doErrorCheck(prevGeo, geo); } // Check the first one for vertex attributes geo = (GeometryArrayRetained)geometryArrays[0].retained; if ((geo.vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { throw new UnsupportedOperationException(J3dI18N.getString("MorphRetained9")); } // Check if the first one is in Immediate context if (geometryArrays[0] != null) { geo = (GeometryArrayRetained)geometryArrays[0].retained; } if (numGeometryArrays == 0) { this.geometryArrays = new GeometryArrayRetained[geometryArrays.length]; numGeometryArrays = geometryArrays.length; } for (i=0;i < numGeometryArrays;i++) { geo = (GeometryArrayRetained)geometryArrays[i].retained; if (((Morph)this.source).isLive()) { if (this.geometryArrays[i] != null) { this.geometryArrays[i].clearLive(refCount); this.geometryArrays[i].removeMorphUser(this); } if (geo != null) { geo.setLive(inBackgroundGroup, refCount); geo.addMorphUser(this); } } this.geometryArrays[i] = geo; } if (this.geometryArrays[0] == null) return; if (weights == null) { weights = new double[numGeometryArrays]; weights[0] = 1.0; int vFormat = this.geometryArrays[0].vertexFormat; // default is zero when new array //for (i=1; i < numGeometryArrays;i++) weights[i] = 0.0; int texCoordSetCount = this.geometryArrays[0].getTexCoordSetCount(); if (this.geometryArrays[0] instanceof IndexedGeometryArrayRetained) { Mcoord = new float[this.geometryArrays[0].getNumCoordCount()* 3]; if ((vFormat & GeometryArray.COLOR_4) == GeometryArray.COLOR_3) Mcolor = new float[this.geometryArrays[0].getNumColorCount()* 3]; else if ((vFormat & GeometryArray.COLOR_4) == GeometryArray.COLOR_4) Mcolor = new float[this.geometryArrays[0].getNumColorCount()* 4]; MtexCoord = new float[texCoordSetCount][]; if ((vFormat & GeometryArray.NORMALS) != 0) Mnormal = new float[this.geometryArrays[0].getNumNormalCount() *3]; for (int k = 0; k < texCoordSetCount; k++) { if ((vFormat & GeometryArray.TEXTURE_COORDINATE_2) != 0) MtexCoord[k] = new float[this.geometryArrays[0].getNumTexCoordCount(k) * 2]; else if (((vFormat & GeometryArray.TEXTURE_COORDINATE_3) != 0)) MtexCoord[k] = new float[this.geometryArrays[0].getNumTexCoordCount(k) * 3]; else if (((vFormat & GeometryArray.TEXTURE_COORDINATE_4) != 0)) MtexCoord[k] = new float[this.geometryArrays[0].getNumTexCoordCount(k) * 4]; } } else { Mcoord = new float[this.geometryArrays[0].validVertexCount* 3]; if ((vFormat & GeometryArray.COLOR_4) == GeometryArray.COLOR_3) { Mcolor = new float[this.geometryArrays[0].validVertexCount* 3]; } else if ((vFormat & GeometryArray.COLOR_4) == GeometryArray.COLOR_4) { Mcolor = new float[this.geometryArrays[0].validVertexCount* 4]; } MtexCoord = new float[texCoordSetCount][]; if ((vFormat & GeometryArray.NORMALS) != 0) { Mnormal = new float[this.geometryArrays[0].validVertexCount *3]; } for (int k = 0; k < texCoordSetCount; k++) { if ((vFormat & GeometryArray.TEXTURE_COORDINATE_2) != 0) MtexCoord[k] = new float[this.geometryArrays[0].validVertexCount * 2]; else if (((vFormat & GeometryArray.TEXTURE_COORDINATE_3) != 0)) MtexCoord[k] = new float[this.geometryArrays[0].validVertexCount * 3]; else if (((vFormat & GeometryArray.TEXTURE_COORDINATE_4) != 0)) MtexCoord[k] = new float[this.geometryArrays[0].validVertexCount * 4]; } } } // create a new morphedGeometryArray initMorphedGeometry(); if (source.isLive()) { Shape3DRetained shape = (Shape3DRetained)mirrorShape3D.get(0); shape.setMorphGeometry(morphedGeometryArray, mirrorShape3D); J3dMessage mChangeMessage = null; mChangeMessage = new J3dMessage(); mChangeMessage.type = J3dMessage.MORPH_CHANGED; mChangeMessage.threads = (J3dThread.UPDATE_GEOMETRY | J3dThread.UPDATE_TRANSFORM); // If its a indexed geometry array, unindexify in renderBin if (this.geometryArrays[0] instanceof IndexedGeometryArrayRetained) mChangeMessage.threads |= J3dThread.UPDATE_RENDERING_ATTRIBUTES; mChangeMessage.args[0] = this; mChangeMessage.args[1]= new Integer(GEOMETRY_CHANGED); // a shadow copy of this ArrayList instance. (The elements themselves are not copied.) mChangeMessage.args[3] = Shape3DRetained.getGeomAtomsArray(mirrorShape3D); mChangeMessage.universe = universe; VirtualUniverse.mc.processMessage(mChangeMessage); if (boundsAutoCompute) { GeometryArrayRetained mga = (GeometryArrayRetained)morphedGeometryArray.retained; // Compute the bounds once mga.incrComputeGeoBounds();// This compute the bbox if dirty mga.decrComputeGeoBounds(); } } } /** * Retrieves the geometryArrays component of this Morph node. * @param index the index of GeometryArray to be returned * @return the geometryArray component of this morph node */ GeometryArray getGeometryArray(int index) { return (GeometryArray)this.geometryArrays[index].source; } /** * Sets the appearance component of this Morph node. * @param appearance the new apearance component for this morph node */ void setAppearance(Appearance newAppearance) { boolean visibleIsDirty = false; if (((Morph)this.source).isLive()) { if (appearance != null) { this.appearance.clearLive(refCount); for (int i=mirrorShape3D.size()-1; i>=0; i--) { this.appearance.removeAMirrorUser( (Shape3DRetained)mirrorShape3D.get(i)); } } if (newAppearance != null) { ((AppearanceRetained)newAppearance.retained).setLive(inBackgroundGroup, refCount); appearance = ((AppearanceRetained)newAppearance.retained); int size= mirrorShape3D.size(); for (int i=0; i<size; i++) { appearance.addAMirrorUser((Shape3DRetained)mirrorShape3D.get(i)); } if((appearance.renderingAttributes != null) && (visible != appearance.renderingAttributes.visible)) { visible = appearance.renderingAttributes.visible; visibleIsDirty = true; } } else { if(visible == false) { visible = true; visibleIsDirty = true; } } // Send a message int size = 0; if (visibleIsDirty) size = 2; else size = 1; J3dMessage[] createMessage = new J3dMessage[size]; createMessage[0] = new J3dMessage(); createMessage[0].threads = J3dThread.UPDATE_RENDERING_ENVIRONMENT | J3dThread.UPDATE_RENDER; createMessage[0].type = J3dMessage.MORPH_CHANGED; createMessage[0].universe = universe; createMessage[0].args[0] = this; createMessage[0].args[1]= new Integer(APPEARANCE_CHANGED); Shape3DRetained[] s3dArr = new Shape3DRetained[mirrorShape3D.size()]; mirrorShape3D.toArray(s3dArr); createMessage[0].args[2] = s3dArr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -