diff options
author | Julien Gouesse <[email protected]> | 2015-11-28 15:11:48 +0100 |
---|---|---|
committer | Julien Gouesse <[email protected]> | 2015-11-28 15:11:48 +0100 |
commit | dbc98deea1884e44da2c74d6ea807253cdefa693 (patch) | |
tree | 29c3ee7dea82d7dd773d81f33f645dde67e43a17 /src/javax/media/j3d/Shape3DRetained.java | |
parent | 2c99f1329dc55bd496bce91b9aba956ecba3c67e (diff) |
Relocate package prefix to org.jogamp.java3d
Diffstat (limited to 'src/javax/media/j3d/Shape3DRetained.java')
-rw-r--r-- | src/javax/media/j3d/Shape3DRetained.java | 2844 |
1 files changed, 0 insertions, 2844 deletions
diff --git a/src/javax/media/j3d/Shape3DRetained.java b/src/javax/media/j3d/Shape3DRetained.java deleted file mode 100644 index 7af82a7..0000000 --- a/src/javax/media/j3d/Shape3DRetained.java +++ /dev/null @@ -1,2844 +0,0 @@ -/* - * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - */ - -package javax.media.j3d; - -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.Vector; - -import javax.vecmath.Point3d; - -/** - * A shape leaf node consisting of geometry and appearance properties. - */ - -class Shape3DRetained extends LeafRetained { - - 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 LAST_DEFINED_BIT = 0x00010; - - - // Target threads to be notified when light changes - static final int targetThreads = J3dThread.UPDATE_RENDERING_ENVIRONMENT | - J3dThread.UPDATE_RENDER; - - /** - * The appearance component of the shape node. - */ - AppearanceRetained appearance = null; - -/** - * The arraylist of geometry component of the shape node. - */ -ArrayList<GeometryRetained> geometryList = null; - - /** - * A 2D storage of all geometry atoms associated with this shape node. - * There may be more than one geometry for a Shape3D node. - * Do not change the following private variables to public, its access need to synchronize - * via mirrorShape3DLock. - */ - - // geomAtomArr should always be a 1 element array, unless S3D contains multiple Text3Ds. - private GeometryAtom geomAtom = null; - - /** - * To sychronize access of the mirrorShape3D's geomAtomArray*. - * A multiple read single write Lock to sychronize access into mirrorShape3D. - * To prevent deadlock a call to read/write lock must end with a read/write unlock - * respectively. - */ - private MRSWLock mirrorShape3DLock = null; - - /** - * 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. - * Do not change the following private variables to public, its access need to synchronize - * via mirrorShape3DLock. - */ - ArrayList<Shape3DRetained> mirrorShape3D = new ArrayList<Shape3DRetained>(1); - - /** - * This field is used for mirror Shape3D nodes accessing their - * original nodes. It is a NodeRetained because the original - * node may be a Shape3DRetained or a MorphRetained node. - */ - NodeRetained sourceNode = null; - - /** - * The hashkey for this Shape3DRetained mirror object - */ - HashKey key = null; - - // This is true when this geometry is referenced in an IMM mode context - boolean inImmCtx = false; - - // A bitmask to indicate when something has changed - int isDirty = 0xffff; - - // The list of lights that are scoped to this node - LightRetained[] lights =null; - - // The number of lights in the above array, may be less than lights.length - int numlights = 0; - - // The list of fogs that are scoped to this node - FogRetained[] fogs = null; - - // The number of fogs in the above array, may be less than fogs.length - int numfogs = 0; - - // The list of modelClips that are scoped to this node - ModelClipRetained[] modelClips = null; - - // The number of modelClips in the above array, may be less than modelClips.length - int numModelClips = 0; - - // The list of alt app that are scoped to this node - AlternateAppearanceRetained[] altApps = null; - - //The number of alt app in the above array, may be less than alt app.length - int numAltApps = 0; - - /** - * Reference to the BranchGroup path of this mirror shape - * This is used for picking and GeometryStructure 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 S3D visible ? The default is true. - boolean visible = true; - - // Whether the normal appearance is overrided by the alternate app - boolean appearanceOverrideEnable = false; - - // AlternateAppearance retained that is applicable to this - // mirror shape when the override flag is true - AppearanceRetained otherAppearance = null; - - // geometry Bounds in local coordinate - Bounds bounds = null; - - // geometry Bounds in virtual world coordinate - BoundingBox vwcBounds = null; - - // collision Bounds in local coordinate - Bounds collisionBound = null; - - // collision Bounds in virtual world coordinate - Bounds collisionVwcBound = null; - - // a path of OrderedGroup, childrenId pairs which leads to this node - OrderedPath orderedPath = null; - -// List of views that a mirror object is scoped to -ArrayList<View> viewList = null; - - int changedFrequent = 0; - - Shape3DRetained() { - super(); - this.nodeType = NodeRetained.SHAPE; - numlights = 0; - numfogs = 0; - numModelClips = 0; - numAltApps = 0; - localBounds = new BoundingBox((BoundingBox) null); - - mirrorShape3DLock = new MRSWLock(); - geometryList = new ArrayList<GeometryRetained>(1); - geometryList.add(null); - } - - /** - * Sets the collision bounds of a node. - * @param bounds the bounding object for the node - */ - void setCollisionBounds(Bounds bounds) { - if (bounds == null) { - this.collisionBound = null; - } else { - this.collisionBound = (Bounds)bounds.clone(); - } - - if (source.isLive()) { - // Notify Geometry Structure to check for collision - J3dMessage message = new J3dMessage(); - message.type = J3dMessage.COLLISION_BOUND_CHANGED; - message.threads = J3dThread.UPDATE_TRANSFORM; - message.universe = universe; - message.args[0] = getGeomAtomsArray(mirrorShape3D); - // no need to clone collisionBound - message.args[1] = collisionBound; - VirtualUniverse.mc.processMessage(message); - } - } - - @Override - Bounds getLocalBounds(Bounds bounds) { - if(localBounds != null) { - localBounds.set(bounds); - } - else { - localBounds = new BoundingBox(bounds); - } - return localBounds; - } - - - /** - * Sets the geometric bounds of a node. - * @param bounds the bounding object for the node - */ - @Override - 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 | - J3dThread.UPDATE_GEOMETRY | - J3dThread.UPDATE_RENDER; - - message.universe = universe; - message.args[0] = getGeomAtomsArray(mirrorShape3D); - // no need to clone localBounds - message.args[1] = localBounds; - VirtualUniverse.mc.processMessage(message); - } - } - - /** - * Gets the collision bounds of a node. - * @return the node's bounding object - */ - Bounds getCollisionBounds(int id) { - return (collisionBound == null ? - null: (Bounds)collisionBound.clone()); - } - - /** - * Appends the specified geometry component to this Shape3D - * node's list of geometry components. - * If there are existing geometry components in the list, the new - * geometry component must be of the same equivalence class - * (point, line, polygon, CompressedGeometry, Raster, Text3D) as - * the others. - * @param geometry the geometry component to be appended. - * @exception IllegalArgumentException if the new geometry - * component is not of of the same equivalence class as the - * existing geometry components. - * - * @since Java 3D 1.2 - */ - void addGeometry(Geometry geometry) { - GeometryRetained newGeom = null; - - checkEquivalenceClass(geometry, -1); - - if(((Shape3D)this.source).isLive()) { - if (geometry != null) { - - newGeom = ((GeometryRetained)geometry.retained); - newGeom.setLive(inBackgroundGroup, refCount); - - geometryList.add(newGeom); - - } else { - geometryList.add(null); - newGeom = null; - } - sendDataChangedMessage(newGeom); - - } else { - if (geometry != null) { - geometryList.add((GeometryRetained) geometry.retained); - } else { - geometryList.add(null); - } - } - dirtyBoundsCache(); - } - - /** - * Replaces the geometry component at the specified index in this - * Shape3D node's list of geometry components with the specified - * geometry component. - * If there are existing geometry components in the list (besides - * the one being replaced), the new geometry component must be of - * the same equivalence class (point, line, polygon, CompressedGeometry, - * Raster, Text3D) as the others. - * @param geometry the geometry component to be stored at the - * specified index. - * @param index the index of the geometry component to be replaced. - * @exception IllegalArgumentException if the new geometry - * component is not of of the same equivalence class as the - * existing geometry components. - * - * @since Java 3D 1.2 - */ - void setGeometry(Geometry geometry, int index) { - int i; - Shape3DRetained mShape; - GeometryRetained newGeom = null; - GeometryRetained oldGeom = null; - - checkEquivalenceClass(geometry, index); - - if (((Shape3D)this.source).isLive()) { - - oldGeom = geometryList.get(index); - if (oldGeom != null) { - oldGeom.clearLive(refCount); - for (i=0; i<mirrorShape3D.size(); i++) { - mShape = mirrorShape3D.get(i); - oldGeom.removeUser(mShape); - } - oldGeom.decRefCnt(); - } - - if (geometry != null) { - newGeom = (GeometryRetained) geometry.retained; - newGeom.incRefCnt(); - newGeom.setLive(inBackgroundGroup, refCount); - geometryList.set(index, newGeom); - sendDataChangedMessage(newGeom); - } else { - geometryList.set(index, null); - sendDataChangedMessage(null); - } - - } else { - - oldGeom = geometryList.get(index); - if (oldGeom != null) { - oldGeom.decRefCnt(); - } - if (geometry != null) { - geometryList.set(index,(GeometryRetained) geometry.retained); - ((GeometryRetained)geometry.retained).incRefCnt(); - } else { - geometryList.set(index,null); - } - } - dirtyBoundsCache(); - } - - /** - * Inserts the specified geometry component into this Shape3D - * node's list of geometry components at the specified index. - * If there are existing geometry components in the list, the new - * geometry component must be of the same equivalence class - * (point, line, polygon, CompressedGeometry, Raster, Text3D) as - * the others. - * @param geometry the geometry component to be inserted at the - * specified index. - * @param index the index at which the geometry component is inserted. - * - * @since Java 3D 1.2 - */ - void insertGeometry(Geometry geometry, int index) { - GeometryRetained newGeom = null; - - checkEquivalenceClass(geometry, -1); - - if (((Shape3D)this.source).isLive()) { - - if (geometry != null) { - // Note : The order of the statements in important. Want ArrayList class to do index bounds - // check before creating internal object. - newGeom = (GeometryRetained) geometry.retained; - newGeom.incRefCnt(); - geometryList.add(index, newGeom); - newGeom.setLive(inBackgroundGroup, refCount); - sendDataChangedMessage(newGeom); - } else { - geometryList.add(index, null); - sendDataChangedMessage(null); - } - - } else { - - if (geometry != null) { - geometryList.add(index,(GeometryRetained) geometry.retained); - ((GeometryRetained)geometry.retained).incRefCnt(); - } else { - geometryList.add(index,null); - } - } - dirtyBoundsCache(); - } - - /** - * Removes the geometry component at the specified index from - * this Shape3D node's list of geometry components. - * @param index the index of the geometry component to be removed. - * - * @since Java 3D 1.2 - */ - void removeGeometry(int index) { - int i; - Shape3DRetained mShape; - GeometryRetained oldGeom = null; - - if (((Shape3D)this.source).isLive()) { - - oldGeom = geometryList.get(index); - if (oldGeom != null) { - oldGeom.clearLive(refCount); - oldGeom.decRefCnt(); - for (i=0; i<mirrorShape3D.size(); i++) { - mShape = mirrorShape3D.get(i); - oldGeom.removeUser(mShape); - - } - } - - geometryList.remove(index); - sendDataChangedMessage(null); - - } else { - oldGeom = geometryList.get(index); - if (oldGeom != null) { - oldGeom.decRefCnt(); - } - geometryList.remove(index); - } - - dirtyBoundsCache(); - - } - -/** - * Retrieves the geometry component of this Shape3D node. - * @return the geometry component of this shape node - * @since Java 3D 1.2 - */ -Geometry getGeometry(int index, int id) { - GeometryRetained ga = geometryList.get(index); - if (ga == null) - return null; - else - return (Geometry)ga.source; -} - - /** - * Returns an enumeration of this Shape3D node's list of geometry - * components. - * @return an Enumeration object containing all geometry components in - * this Shape3D node's list of geometry components. - * - * @since Java 3D 1.2 - */ -Enumeration getAllGeometries(int id) { - Vector<Geometry> geomList = new Vector<Geometry>(geometryList.size()); - - for (int i = 0; i < geometryList.size(); i++) { - GeometryRetained ga = geometryList.get(i); - if (ga != null) - geomList.add((Geometry) ga.source); - else - geomList.add(null); - } - - return geomList.elements(); -} - - /** - * Returns the number of geometry components in this Shape3D node's - * list of geometry components. - * @return the number of geometry components in this Shape3D node's - * list of geometry components. - * - * @since Java 3D 1.2 - */ - int numGeometries(int id) { - - return geometryList.size(); - } - - /** - * Sets the appearance component of this Shape3D node. - * @param appearance the new apearance component for this shape node - */ - void setAppearance(Appearance newAppearance) { - - Shape3DRetained s; - boolean visibleIsDirty = false; - - if (((Shape3D)this.source).isLive()) { - if (appearance != null) { - appearance.clearLive(refCount); - for (int i=0; i<mirrorShape3D.size(); i++) { - s = mirrorShape3D.get(i); - appearance.removeAMirrorUser(s); - } - } - - if (newAppearance != null) { - ((AppearanceRetained)newAppearance.retained).setLive(inBackgroundGroup, refCount); - appearance = ((AppearanceRetained)newAppearance.retained); - for (int i=0; i<mirrorShape3D.size(); i++) { - s = mirrorShape3D.get(i); - appearance.addAMirrorUser(s); - } - if((appearance.renderingAttributes != null) && - (visible != appearance.renderingAttributes.visible)) { - visible = appearance.renderingAttributes.visible; - visibleIsDirty = true; - } - } - else { - if(visible == false) { - visible = true; - visibleIsDirty = true; - } - } - int size = 0; - if (visibleIsDirty) - size = 2; - else - size = 1; - J3dMessage[] createMessage = new J3dMessage[size]; - // Send a message - createMessage[0] = new J3dMessage(); - createMessage[0].threads = targetThreads; - createMessage[0].type = J3dMessage.SHAPE3D_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; - Object[] obj = new Object[2]; - if (newAppearance == null) { - obj[0] = null; - } - else { - obj[0] = appearance.mirror; - } - obj[1] = new Integer(changedFrequent); - createMessage[0].args[3] = obj; - createMessage[0].args[4] = getGeomAtomsArray(mirrorShape3D); - if(visibleIsDirty) { - createMessage[1] = new J3dMessage(); - createMessage[1].threads = J3dThread.UPDATE_GEOMETRY; - createMessage[1].type = J3dMessage.SHAPE3D_CHANGED; - createMessage[1].universe = universe; - createMessage[1].args[0] = this; - createMessage[1].args[1]= new Integer(APPEARANCE_CHANGED); - createMessage[1].args[2]= visible?Boolean.TRUE:Boolean.FALSE; - createMessage[1].args[3]= createMessage[0].args[4]; - } - VirtualUniverse.mc.processMessage(createMessage); - - } - else { // not live. - if (newAppearance == null) { - appearance = null; - } else { - appearance = (AppearanceRetained) newAppearance.retained; - } - } - } - - /** - * Retrieves the shape node's appearance component. - * @return the shape node's appearance - */ - Appearance getAppearance() { - return (appearance == null ? null: (Appearance) appearance.source); - } - - void setAppearanceOverrideEnable(boolean flag) { - if (((Shape3D)this.source).isLive()) { - - // Send a message - J3dMessage createMessage = new J3dMessage(); - createMessage.threads = targetThreads; - createMessage.type = J3dMessage.SHAPE3D_CHANGED; - createMessage.universe = universe; - createMessage.args[0] = this; - createMessage.args[1]= new Integer(APPEARANCEOVERRIDE_CHANGED); - Shape3DRetained[] s3dArr = new Shape3DRetained[mirrorShape3D.size()]; - mirrorShape3D.toArray(s3dArr); - createMessage.args[2] = s3dArr; - Object[] obj = new Object[2]; - if (flag) { - obj[0] = Boolean.TRUE; - } - else { - obj[0] = Boolean.FALSE; - } - obj[1] = new Integer(changedFrequent); - createMessage.args[3] = obj; - createMessage.args[4] = getGeomAtomsArray(mirrorShape3D); - - VirtualUniverse.mc.processMessage(createMessage); - } - appearanceOverrideEnable = flag; - } - - boolean getAppearanceOverrideEnable() { - return appearanceOverrideEnable; - } - - boolean intersect(PickInfo pickInfo, PickShape pickShape, int flags ) { - - Transform3D localToVworld = pickInfo.getLocalToVWorldRef(); - - // Support OrientedShape3D here. - // Note - BugId : 4363899 - APIs issue : OrientedShape3D's intersect needs view - // info. temp. fix use the primary view. - if (this instanceof OrientedShape3DRetained) { - Transform3D orientedTransform = ((OrientedShape3DRetained)this). - getOrientedTransform(getPrimaryViewIdx()); - localToVworld.mul(orientedTransform); - } - - Transform3D t3d = new Transform3D(); - t3d.invert(localToVworld); - PickShape newPS = pickShape.transform(t3d); - - // Note: For optimization - Should do a geobounds check of - // each geometry first. But this doesn't work for - // OrientedShape3D case... - int geomListSize = geometryList.size(); - GeometryRetained geometry; - - if (((flags & PickInfo.CLOSEST_INTERSECTION_POINT) == 0) && - ((flags & PickInfo.CLOSEST_DISTANCE) == 0) && - ((flags & PickInfo.CLOSEST_GEOM_INFO) == 0) && - ((flags & PickInfo.ALL_GEOM_INFO) == 0)) { - - for (int i=0; i < geomListSize; i++) { - geometry = geometryList.get(i); - if (geometry != null) { - if (geometry.mirrorGeometry != null) { - geometry = geometry.mirrorGeometry; - } - if (geometry.intersect(newPS, null, 0, null, null, 0)) { - return true; - } - } - } - } else { - double distance; - double minDist = Double.POSITIVE_INFINITY; - Point3d closestIPnt = new Point3d(); - Point3d iPnt = new Point3d(); - Point3d iPntVW = new Point3d(); - - for (int i=0; i < geomListSize; i++) { - geometry = geometryList.get(i); - if (geometry != null) { - if (geometry.mirrorGeometry != null) { - geometry = geometry.mirrorGeometry; - } - //if (geometry.intersect(newPS, intersectionInfo, flags, iPnt)) { - if(geometry.intersect(newPS, pickInfo, flags, iPnt, geometry, i)) { - - iPntVW.set(iPnt); - localToVworld.transform(iPntVW); - distance = pickShape.distance(iPntVW); - - if (minDist > distance) { - minDist = distance; - closestIPnt.set(iPnt); - } - } - } - } - - if (minDist < Double.POSITIVE_INFINITY) { - if ((flags & PickInfo.CLOSEST_DISTANCE) != 0) { - pickInfo.setClosestDistance(minDist); - } - if((flags & PickInfo.CLOSEST_INTERSECTION_POINT) != 0) { - pickInfo.setClosestIntersectionPoint(closestIPnt); - } - return true; - } - } - - return false; - - } - - - /** - * Check if the geometry component of this shape node under path - * intersects with the pickShape. - * This is an expensive method. It should only be called if and only - * if the path's bound intersects pickShape. - * @exception IllegalArgumentException if <code>path</code> is - * invalid. - */ - - boolean intersect(SceneGraphPath path, - PickShape pickShape, double[] dist) { - - int flags; - PickInfo pickInfo = new PickInfo(); - - Transform3D localToVworld = path.getTransform(); - if (localToVworld == null) { - throw new IllegalArgumentException(J3dI18N.getString("Shape3DRetained3")); - } - pickInfo.setLocalToVWorldRef( localToVworld); - //System.err.println("Shape3DRetained.intersect() : "); - if (dist == null) { - //System.err.println(" no dist request ...."); - return intersect(pickInfo, pickShape, 0); - } - - flags = PickInfo.CLOSEST_DISTANCE; - if (intersect(pickInfo, pickShape, flags)) { - dist[0] = pickInfo.getClosestDistance(); - return true; - } - - return false; - - } - - /** - * This sets the immedate mode context flag - */ - void setInImmCtx(boolean inCtx) { - inImmCtx = inCtx; - } - - /** - * This gets the immedate mode context flag - */ - boolean getInImmCtx() { - return (inImmCtx); - } - - /** - * This updates the mirror shape to reflect the state of the - * real shape3d. - */ - private void initMirrorShape3D(SetLiveState s, Shape3DRetained ms, int index) { - - // New 1.2.1 code - - ms.inBackgroundGroup = inBackgroundGroup; - ms.geometryBackground = geometryBackground; - ms.source = source; - ms.universe = universe; - // Has to be false. We have a instance of mirror for every link to the shape3d. - ms.inSharedGroup = false; - ms.locale = locale; - ms.parent = parent; - - // New 1.3.2 - // Used when user supplied their own bounds for transparency sorting - // GeometryAtom uses this to change how it computes the centroid - ms.boundsAutoCompute = boundsAutoCompute; - ms.localBounds = localBounds; - // End new 1.3.2 - - OrderedPath op = s.orderedPaths.get(index); - if (op.pathElements.size() == 0) { - ms.orderedPath = null; - } else { - ms.orderedPath = op; -/* - System.err.println("initMirrorShape3D ms.orderedPath "); - ms.orderedPath.printPath(); -*/ - } - - // all mirror shapes point to the same transformGroupRetained - // for the static transform - ms.staticTransform = staticTransform; - - - ms.appearanceOverrideEnable = appearanceOverrideEnable; - - ms.geometryList = geometryList; - - // Assign the parent of this mirror shape node - ms.sourceNode = this; - - if (this instanceof OrientedShape3DRetained) { - OrientedShape3DRetained os = (OrientedShape3DRetained)this; - OrientedShape3DRetained oms = (OrientedShape3DRetained)ms; - oms.initAlignmentMode(os.mode); - oms.initAlignmentAxis(os.axis); - oms.initRotationPoint(os.rotationPoint); - oms.initConstantScaleEnable(os.constantScale); - oms.initScale(os.scaleFactor); - } - - } - - void updateImmediateMirrorObject(Object[] objs) { - int component = ((Integer)objs[1]).intValue(); - - Shape3DRetained[] msArr = (Shape3DRetained[]) objs[2]; - int i; - if ((component & APPEARANCE_CHANGED) != 0) { - Object[] arg = (Object[])objs[3]; - int val = ((Integer)arg[1]).intValue(); - for ( i = msArr.length-1; i >=0; i--) { - msArr[i].appearance = (AppearanceRetained)arg[0]; - msArr[i].changedFrequent = val; - } - } - if ((component & APPEARANCEOVERRIDE_CHANGED) != 0) { - Object[] arg = (Object[])objs[3]; - int val = ((Integer)arg[1]).intValue(); - for ( i = msArr.length-1; i >=0; i--) { - msArr[i].appearanceOverrideEnable = ((Boolean)arg[0]).booleanValue(); - msArr[i].changedFrequent = val; - } - } - } - - /** - * Gets the bounding object of a node. - * @return the node's bounding object - */ - - @Override - Bounds getBounds() { - - if(boundsAutoCompute) { - // System.err.println("getBounds ---- localBounds is " + localBounds); - // Issue 514 : NPE in Wonderland : triggered in cached bounds computation - if (validCachedBounds) { - return (Bounds) cachedBounds.clone(); - } - - if(geometryList != null) { - BoundingBox bbox = new BoundingBox((Bounds) null); - GeometryRetained geometry; - for(int i=0; i<geometryList.size(); i++) { - geometry = geometryList.get(i); - if ((geometry != null) && - (geometry.geoType != GeometryRetained.GEO_TYPE_NONE)) { - geometry.computeBoundingBox(); - synchronized(geometry.geoBounds) { - bbox.combine(geometry.geoBounds); - } - } - } - return bbox; - - } else { - return null; - } - - } else { - return super.getBounds(); - } - } - - @Override - Bounds getEffectiveBounds() { - if(boundsAutoCompute) { - return getBounds(); - } - else { - return super.getEffectiveBounds(); - } - } - - - /** - * ONLY needed for SHAPE, MORPH, and LINK node type. - * Compute the combine bounds of bounds and its localBounds. - */ - @Override - void computeCombineBounds(Bounds bounds) { - - if(boundsAutoCompute) { - if(geometryList != null) { - GeometryRetained geometry; - BoundingBox bbox = null; - - if (staticTransform != null) { - bbox = new BoundingBox((BoundingBox) null); - } - - if (!VirtualUniverse.mc.cacheAutoComputedBounds) { - for(int i=0; i<geometryList.size(); i++) { - geometry = geometryList.get(i); - if ((geometry != null) && - (geometry.geoType != GeometryRetained.GEO_TYPE_NONE)) { - geometry.computeBoundingBox(); - // Should this be lock too ? ( MT safe ? ) - synchronized(geometry.geoBounds) { - if (staticTransform != null) { - bbox.set(geometry.geoBounds); - bbox.transform(staticTransform.transform); - bounds.combine(bbox); - } else { - bounds.combine(geometry.geoBounds); - } - } - } - } - } else { - // Issue 514 : NPE in Wonderland : triggered in cached bounds computation - if (!validCachedBounds) { - validCachedBounds = true; - cachedBounds = new BoundingBox((BoundingBox) null); - - for(int i=0; i<geometryList.size(); i++) { - geometry = geometryList.get(i); - if ((geometry != null) && - (geometry.geoType != GeometryRetained.GEO_TYPE_NONE)) { - geometry.computeBoundingBox(); - // Should this be lock too ? ( MT safe ? ) - synchronized(geometry.geoBounds) { - if (staticTransform != null) { - bbox.set(geometry.geoBounds); - bbox.transform(staticTransform.transform); - cachedBounds.combine(bbox); - } else { - cachedBounds.combine(geometry.geoBounds); - } - } - } - } - } - bounds.combine(cachedBounds); - } - } - } else { - - // Should this be lock too ? ( MT safe ? ) - synchronized(localBounds) { - bounds.combine(localBounds); - } - } - } - - /** - * assign a name to this node when it is made live. - */ - - @Override - void setLive(SetLiveState s) { - doSetLive(s); - markAsLive(); - } - - @Override - void doSetLive(SetLiveState s) { - // System.err.println("S3DRetained : setLive " + s); - Shape3DRetained shape; - GeometryRetained geometry; - int i, j, k, gaCnt; - ArrayList<Shape3DRetained> msList = new ArrayList<Shape3DRetained>(); - - super.doSetLive(s); - - nodeId = universe.getNodeId(); - - - if (inSharedGroup) { - for (i=0; i<s.keys.length; i++) { - if (this instanceof OrientedShape3DRetained) { - shape = new OrientedShape3DRetained(); - } else { - shape = new Shape3DRetained(); - } - shape.key = s.keys[i]; - shape.localToVworld = new Transform3D[1][]; - shape.localToVworldIndex = new int[1][]; - - j = s.keys[i].equals(localToVworldKeys, 0, - localToVworldKeys.length); - /* - System.err.print("s.keys[i] = "+s.keys[i]+" j = "+j); - if(j < 0) { - System.err.println("Shape3dRetained : Can't find hashKey"); - } - */ - shape.localToVworld[0] = localToVworld[j]; - shape.localToVworldIndex[0] = localToVworldIndex[j]; - shape.branchGroupPath = branchGroupPaths.get(j); - shape.isPickable = s.pickable[i]; - shape.isCollidable = s.collidable[i]; - - initMirrorShape3D(s, shape, j); - - if (s.switchTargets != null && - s.switchTargets[i] != null) { - s.switchTargets[i].addNode(shape, Targets.GEO_TARGETS); - shape.closestSwitchParent = s.closestSwitchParents[i]; - shape.closestSwitchIndex = s.closestSwitchIndices[i]; - } - shape.switchState = s.switchStates.get(j); - - // Add any scoped lights to the mirror shape - if (s.lights != null) { - ArrayList<LightRetained> l = s.lights.get(j); - if (l != null) { - for (int m = 0; m < l.size(); m++) { - shape.addLight(l.get(m)); - } - } - } - - // Add any scoped fog - if (s.fogs != null) { - ArrayList<FogRetained> l = s.fogs.get(j); - if (l != null) { - for (int m = 0; m < l.size(); m++) { - shape.addFog(l.get(m)); - } - } - } - - // Add any scoped modelClip - if (s.modelClips != null) { - ArrayList<ModelClipRetained> l = s.modelClips.get(j); - if (l != null) { - for (int m = 0; m < l.size(); m++) { - shape.addModelClip(l.get(m)); - } - } - } - - // Add any scoped alt app - if (s.altAppearances != null) { - ArrayList<AlternateAppearanceRetained> l = s.altAppearances.get(j); - if (l != null) { - for (int m = 0; m < l.size(); m++) { - shape.addAltApp(l.get(m)); - } - } - } - synchronized(mirrorShape3D) { - mirrorShape3D.add(j,shape); - } - - msList.add(shape); - if (s.viewLists != null) { - shape.viewList = s.viewLists.get(j); - } else { - shape.viewList = null; - } - } - } else { - if (this instanceof OrientedShape3DRetained) { - shape = new OrientedShape3DRetained(); - } else { - shape = new Shape3DRetained(); - } - - shape.localToVworld = new Transform3D[1][]; - shape.localToVworldIndex = new int[1][]; - shape.localToVworld[0] = localToVworld[0]; - shape.localToVworldIndex[0] = localToVworldIndex[0]; - shape.branchGroupPath = branchGroupPaths.get(0); - shape.isPickable = s.pickable[0]; - shape.isCollidable = s.collidable[0]; - initMirrorShape3D(s, shape, 0); - - // Add any scoped lights to the mirror shape - if (s.lights != null) { - ArrayList<LightRetained> l = s.lights.get(0); - for (i = 0; i < l.size(); i++) { - shape.addLight(l.get(i)); - } - } - - // Add any scoped fog - if (s.fogs != null) { - ArrayList<FogRetained> l = s.fogs.get(0); - for (i = 0; i < l.size(); i++) { - shape.addFog(l.get(i)); - } - } - - // Add any scoped modelClip - if (s.modelClips != null) { - ArrayList<ModelClipRetained> l = s.modelClips.get(0); - for (i = 0; i < l.size(); i++) { - shape.addModelClip(l.get(i)); - } - - } - - // Add any scoped alt app - if (s.altAppearances != null) { - ArrayList<AlternateAppearanceRetained> l = s.altAppearances.get(0); - for (i = 0; i < l.size(); i++) { - shape.addAltApp(l.get(i)); - } - } - synchronized(mirrorShape3D) { - mirrorShape3D.add(shape); - } - - msList.add(shape); - if (s.viewLists != null) - shape.viewList = s.viewLists.get(0); - else - shape.viewList = null; - - if (s.switchTargets != null && - s.switchTargets[0] != null) { - s.switchTargets[0].addNode(shape, Targets.GEO_TARGETS); - shape.closestSwitchParent = s.closestSwitchParents[0]; - shape.closestSwitchIndex = s.closestSwitchIndices[0]; - } - shape.switchState = s.switchStates.get(0); - } - - for (k = 0; k < msList.size(); k++) { - Shape3DRetained sh = msList.get(k); - - if (appearance != null) { - synchronized(appearance.liveStateLock) { - if (k == 0) { // Do only first time - appearance.setLive(inBackgroundGroup, s.refCount); - appearance.initMirrorObject(); - if (appearance.renderingAttributes != null) - visible = appearance.renderingAttributes.visible; - } - sh.appearance = (AppearanceRetained)appearance.mirror; - appearance.addAMirrorUser(sh); - - } - } - else { - sh.appearance = null; - } - - if (geometryList != null) { - for(gaCnt=0; gaCnt<geometryList.size(); gaCnt++) { - geometry = geometryList.get(gaCnt); - if(geometry != null) { - synchronized(geometry.liveStateLock) { - if (k == 0) { // Do only first time - geometry.setLive(inBackgroundGroup, s.refCount); - } - geometry.addUser(sh); - } - } - } - - } - - // after the geometry has been setLived and bounds computed - if (k== 0 && boundsAutoCompute) { // Do only once - // user may call setBounds with a bounds other than boundingBox - if (! (localBounds instanceof BoundingBox)) { - localBounds = new BoundingBox((BoundingBox) null); - } - getCombineBounds((BoundingBox)localBounds); - - } - // Assign GAtom and set the bounds if we are not using switch - initializeGAtom(sh); - - GeometryAtom ga = getGeomAtom(sh); - - // Add the geometry atom for this shape to the nodeList - s.nodeList.add(ga); - - if (s.transformTargets != null && - s.transformTargets[k] != null) { - // Add the geometry atom for this shape to the transformTargets - - s.transformTargets[k].addNode(ga, Targets.GEO_TARGETS); - } - } - - s.notifyThreads |= (J3dThread.UPDATE_GEOMETRY | - J3dThread.UPDATE_TRANSFORM | - J3dThread.UPDATE_RENDER | - J3dThread.UPDATE_RENDERING_ENVIRONMENT); - - } - - /** - * This clears all references in a mirror shape - */ - // This is call in RenderingEnvironmentStructure.removeNode() because that is the - // last point that will reference this ms. - // called on the mirror shape .. - void clearMirrorShape() { - int i; - - source = null; - sourceNode = null; - parent = null; - - if (otherAppearance != null) { - otherAppearance.sgApp.removeAMirrorUser(this); - otherAppearance = null; - } - - appearance = null; - - branchGroupPath = null; - isPickable = true; - isCollidable = true; - branchGroupPath = null; - // No locking needed. Owner, s3dR, has already been destory. - // DO NOT clear geometryList, ie. geometryList.clear(). - // It is referred by the source s3DRetained. - geometryList = null; - - // Clear the mirror scoping info - // Remove all the fogs - for (i = 0; i < numfogs; i++) - fogs[i] = null; - numfogs = 0; - - // Remove all the modelClips - for (i = 0; i < numModelClips; i++) - modelClips[i] = null; - numModelClips = 0; - - // Remove all the lights - for (i = 0; i < numlights; i++) - lights[i] = null; - numlights = 0; - - // Remove all the al app - for (i = 0; i < numAltApps; i++) - altApps[i] = null; - numAltApps = 0; - - viewList = null; - - } - - /** - * assign a name to this node when it is made live. - */ - @Override - void clearLive(SetLiveState s) { - - //System.err.println("S3DRetained : clearLive " + s); - - int i, j, gaCnt; - GeometryRetained geometry; - ArrayList<Shape3DRetained> msList = new ArrayList<Shape3DRetained>(); - - super.clearLive(s); - - - - if (inSharedGroup) { - synchronized(mirrorShape3D) { - Shape3DRetained[] shapes = mirrorShape3D.toArray(new Shape3DRetained[mirrorShape3D.size()]); - for (i=0; i<s.keys.length; i++) { - for (j=0; j<shapes.length; j++) { - Shape3DRetained shape = shapes[j]; - if (shape.key.equals(s.keys[i])) { - mirrorShape3D.remove(mirrorShape3D.indexOf(shape)); - if (s.switchTargets != null && - s.switchTargets[i] != null) { - s.switchTargets[i].addNode( - shape, Targets.GEO_TARGETS); - } - msList.add(shape); - GeometryAtom ga = getGeomAtom(shape); - - // Add the geometry atom for this shape to the nodeList - s.nodeList.add(ga); - if (s.transformTargets != null && - s.transformTargets[i] != null) { - s.transformTargets[i].addNode(ga, Targets.GEO_TARGETS); - } - } - } - } - } - } else { - // Only entry 0 is valid - Shape3DRetained shape = mirrorShape3D.get(0); - synchronized(mirrorShape3D) { - mirrorShape3D.remove(0); - } - - if (s.switchTargets != null && - s.switchTargets[0] != null) { - s.switchTargets[0].addNode(shape, Targets.GEO_TARGETS); - } - - - msList.add(shape); - - GeometryAtom ga = getGeomAtom(shape); - - // Add the geometry atom for this shape to the nodeList - s.nodeList.add(ga); - if (s.transformTargets != null && - s.transformTargets[0] != null) { - s.transformTargets[0].addNode(ga, Targets.GEO_TARGETS); - } - } - - - for (int k = 0; k < msList.size(); k++) { - Shape3DRetained sh = msList.get(k); - if (appearance != null) { - synchronized(appearance.liveStateLock) { - if (k == 0) { - appearance.clearLive(s.refCount); - } - appearance.removeAMirrorUser(sh); - } - } - if (geometryList != null) { - for(gaCnt=0; gaCnt<geometryList.size(); gaCnt++) { - geometry = geometryList.get(gaCnt); - if(geometry != null) { - synchronized(geometry.liveStateLock) { - if (k == 0) { - geometry.clearLive(s.refCount); - } - geometry.removeUser(sh); - } - } - } - } - } - - s.notifyThreads |= (J3dThread.UPDATE_GEOMETRY | - J3dThread.UPDATE_TRANSFORM | - // This is used to clear the scope info - // of all the mirror shapes - J3dThread.UPDATE_RENDERING_ENVIRONMENT | - J3dThread.UPDATE_RENDER); - - if (!source.isLive()) { - // Clear the mirror scoping info - // Remove all the fogs - for (i = 0; i < numfogs; i++) - fogs[i] = null; - numfogs = 0; - - // Remove all the modelClips - for (i = 0; i < numModelClips; i++) - modelClips[i] = null; - numModelClips = 0; - - // Remove all the lights - for (i = 0; i < numlights; i++) - lights[i] = null; - numlights = 0; - - // Remove all the al app - for (i = 0; i < numAltApps; i++) - altApps[i] = null; - numAltApps = 0; - } - } - - @Override - boolean isStatic() { - if (source.getCapability(Shape3D.ALLOW_APPEARANCE_WRITE) || - source.getCapability(Shape3D.ALLOW_GEOMETRY_WRITE) || - source.getCapability(Shape3D.ALLOW_APPEARANCE_OVERRIDE_WRITE)) { - return false; - } else { - return true; - } - } - - boolean staticXformCanBeApplied() { - - // static xform can be applied if - // . shape is not pickable or collidable - // . geometry is not being shared by more than one shape nodes - // . geometry will be put in display list - // . geometry is not readable - - // no static xform if shape is pickable or collidable because - // otherwise the static xform will have to be applied to the - // currentLocalToVworld in the intersect test, it will then - // be more costly and really beat the purpose of eliminating - // the static transform group - if (isPickable || isCollidable || - source.getCapability(Shape3D.ALLOW_PICKABLE_WRITE) || - source.getCapability(Shape3D.ALLOW_COLLIDABLE_WRITE)) { - return false; - } - - if (appearance != null && - (appearance.transparencyAttributes != null && appearance.transparencyAttributes.transparencyMode != TransparencyAttributes.NONE)) - return false; - - GeometryRetained geo; - boolean alphaEditable; - - for (int i=0; i<geometryList.size(); i++) { - geo = geometryList.get(i); - if (geo != null) { - if (geo.refCnt > 1) { - return false; - } - alphaEditable = isAlphaEditable(geo); - if (geo instanceof GeometryArrayRetained) { - geo.isEditable = !((GeometryArrayRetained)geo).isWriteStatic(); - - // TODO: for now if vertex data can be returned, then - // don't apply static transform - if (geo.source.getCapability( - GeometryArray.ALLOW_COORDINATE_READ) || - geo.source.getCapability( - GeometryArray.ALLOW_NORMAL_READ)) - return false; - - } - - if (!geo.canBeInDisplayList(alphaEditable)) { - return false; - } - } - } - return true; - } - - - @Override - void compile(CompileState compState) { - AppearanceRetained newApp; - - super.compile(compState); - - if (isStatic() && staticXformCanBeApplied()) { - mergeFlag = SceneGraphObjectRetained.MERGE; - if (J3dDebug.devPhase && J3dDebug.debug) { - compState.numShapesWStaticTG++; - } - } else - { - mergeFlag = SceneGraphObjectRetained.DONT_MERGE; - compState.keepTG = true; - } - - if (J3dDebug.devPhase && J3dDebug.debug) { - compState.numShapes++; - } - - if (appearance != null) { - appearance.compile(compState); - // Non-static apperanace can still be compiled, since in compile - // state we will be grouping all shapes that have same appearance - // so, when the appearance changes, all the shapes will be affected - // For non-static appearances, we don't get an equivalent appearance - // from the compile state - if (appearance.isStatic()) { - newApp = compState.getAppearance(appearance); - appearance = newApp; - } - } - - for (int i = 0; i < geometryList.size(); i++) { - GeometryRetained geo = geometryList.get(i); - if (geo != null) - geo.compile(compState); - } - - } - - @Override - void merge(CompileState compState) { - - - if (mergeFlag == SceneGraphObjectRetained.DONT_MERGE) { - - // no need to save the staticTransform here - - TransformGroupRetained saveStaticTransform = - compState.staticTransform; - compState.staticTransform = null; - super.merge(compState); - compState.staticTransform = saveStaticTransform; - } else { - super.merge(compState); - } - - if (shapeIsMergeable(compState)) { - compState.addShape(this); - } - } - - - boolean shapeIsMergeable(CompileState compState) { - boolean mergeable = true; - int i; - - GeometryRetained geometry = null; - int index = 0; - i = 0; - /* - if (isPickable) - return false; - */ - - // For now, don't merge if the shape has static transform - if (staticTransform != null) - return false; - - // If this shape's to be immediate parent is orderedGroup or a switchNode - // this shape is not mergerable - if (parent instanceof OrderedGroupRetained || - parent instanceof SwitchRetained) - return false; - - // Get the first geometry that is non-null - while (geometry == null && index < geometryList.size()) { - geometry = geometryList.get(index); - index++; - } - - if (!(geometry instanceof GeometryArrayRetained)) { - return false; - } - - GeometryArrayRetained firstGeo = (GeometryArrayRetained) geometry; - - for(i=index; (i<geometryList.size() && mergeable); i++) { - geometry = geometryList.get(i); - if (geometry != null) { - GeometryArrayRetained geo = (GeometryArrayRetained)geometry; - - if (! geo.isWriteStatic()) - mergeable = false; - - if (geo.vertexFormat != firstGeo.vertexFormat) - mergeable = false; - - - } - } - - // For now, turn off lots of capability bits - if (source.getCapability(Shape3D.ALLOW_COLLISION_BOUNDS_WRITE) || - source.getCapability(Shape3D.ALLOW_APPEARANCE_WRITE) || - source.getCapability(Shape3D.ALLOW_APPEARANCE_OVERRIDE_WRITE) || - source.getCapability(Shape3D.ALLOW_AUTO_COMPUTE_BOUNDS_WRITE) || - source.getCapability(Shape3D.ALLOW_BOUNDS_WRITE) || - source.getCapability(Shape3D.ALLOW_COLLIDABLE_WRITE) || - source.getCapability(Shape3D.ALLOW_PICKABLE_WRITE) || - source.getCapability(Shape3D.ALLOW_GEOMETRY_WRITE)) { - mergeable = false; - } - - return mergeable; - - } - - - @Override - void getMirrorObjects( ArrayList list, HashKey k) { - Shape3DRetained ms; - if (inSharedGroup) { - if (k.count == 0) { - // System.err.println("===> CAN NEVER BE TRUE"); - return; - } - else { - ms = getMirrorShape(k); - } - } - else { - ms = mirrorShape3D.get(0); - } - - list.add(getGeomAtom(ms)); - - } - - - // Called on the mirror Object - void addLight(LightRetained light) { - LightRetained[] newlights; - int i; - - if (lights == null) { - lights = new LightRetained[10]; - } - else if (lights.length == numlights) { - newlights = new LightRetained[numlights*2]; - for (i=0; i<numlights; i++) { - newlights[i] = lights[i]; - } - lights = newlights; - } - lights[numlights] = light; - numlights++; - } - - // called on the mirror object - void removeLight(LightRetained light) { - int i; - - for (i=0; i<numlights; i++) { - if (lights[i] == light) { - lights[i] = null; - break; - } - } - - // Shift everyone down one. - for (i++; i<numlights; i++) { - lights[i-1] = lights[i]; - } - numlights--; - } - - // Called on the mirror object - void addFog(FogRetained fog) { - FogRetained[] newfogs; - int i; - - if (fogs == null) { - fogs = new FogRetained[10]; - } - else if (fogs.length == numfogs) { - newfogs = new FogRetained[numfogs*2]; - for (i=0; i<numfogs; i++) { - newfogs[i] = fogs[i]; - } - fogs = newfogs; - } - fogs[numfogs] = fog; - numfogs++; - } - - // called on the mirror object - void removeFog(FogRetained fog) { - int i; - - for (i=0; i<numfogs; i++) { - if (fogs[i] == fog) { - fogs[i] = null; - break; - } - } - - // Shift everyone down one. - for (i++; i<numfogs; i++) { - fogs[i-1] = fogs[i]; - } - numfogs--; - - } - - // Called on the mirror object - void addModelClip(ModelClipRetained modelClip) { - ModelClipRetained[] newModelClips; - int i; - - - if (modelClips == null) { - modelClips = new ModelClipRetained[10]; - } - else if (modelClips.length == numModelClips) { - newModelClips = new ModelClipRetained[numModelClips*2]; - for (i=0; i<numModelClips; i++) { - newModelClips[i] = modelClips[i]; - } - modelClips = newModelClips; - } - modelClips[numModelClips] = modelClip; - numModelClips++; - } - - // called on the mirror object - void removeModelClip(ModelClipRetained modelClip) { - int i; - - for (i=0; i<numModelClips; i++) { - if (modelClips[i] == modelClip) { - modelClips[i] = null; - break; - } - } - - // Shift everyone down one. - for (i++; i<numModelClips; i++) { - modelClips[i-1] = modelClips[i]; - } - numModelClips--; - - } - - // Called on the mirror object - void addAltApp(AlternateAppearanceRetained aApp) { - AlternateAppearanceRetained[] newAltApps; - int i; - if (altApps == null) { - altApps = new AlternateAppearanceRetained[10]; - } - else if (altApps.length == numAltApps) { - newAltApps = new AlternateAppearanceRetained[numAltApps*2]; - for (i=0; i<numAltApps; i++) { - newAltApps[i] = altApps[i]; - } - altApps = newAltApps; - } - altApps[numAltApps] = aApp; - numAltApps++; - } - - // called on the mirror object - void removeAltApp(AlternateAppearanceRetained aApp) { - int i; - - for (i=0; i<numAltApps; i++) { - if (altApps[i] == aApp) { - altApps[i] = null; - break; - } - } - - // Shift everyone down one. - for (i++; i<numAltApps; i++) { - altApps[i-1] = altApps[i]; - } - numAltApps--; - - } - - - - @Override - void updatePickable(HashKey keys[], boolean pick[]) { - super.updatePickable(keys, pick); - Shape3DRetained shape; - - if (!inSharedGroup) { - shape = mirrorShape3D.get(0); - shape.isPickable = pick[0]; - } else { - int size = mirrorShape3D.size(); - for (int j=0; j< keys.length; j++) { - for (int i=0; i < size; i++) { - shape = mirrorShape3D.get(i); - if (keys[j].equals(shape.key)) { - shape.isPickable = pick[j]; - break; - } - - } - } - } - } - - - @Override - void updateCollidable(HashKey keys[], boolean collide[]) { - super.updateCollidable(keys, collide); - Shape3DRetained shape; - - if (!inSharedGroup) { - shape = mirrorShape3D.get(0); - shape.isCollidable = collide[0]; - } else { - int size = mirrorShape3D.size(); - for (int j=0; j< keys.length; j++) { - for (int i=0; i < size; i++) { - shape = mirrorShape3D.get(i); - if (keys[j].equals(shape.key)) { - shape.isCollidable = collide[j]; - break; - } - - } - } - } - } - - - - - // New 1.2.1 code .... - - // Remove the old geometry atoms and reInsert - // the new geometry atoms and update the transform - // target list - - private void sendDataChangedMessage( GeometryRetained newGeom ) { - - int i, j, gaCnt; - GeometryAtom[] newGAArray = null; - GeometryAtom[] oldGAArray = null; - int geometryCnt = 0; - GeometryRetained geometry = null; - - int s3dMSize = mirrorShape3D.size(); - - if(s3dMSize < 1) - return; - - Shape3DRetained mS3d = mirrorShape3D.get(0); - - mS3d.mirrorShape3DLock.writeLock(); - - GeometryAtom oldGA = mS3d.geomAtom; - - GeometryAtom newGA = new GeometryAtom(); - - if(newGeom != null) { - newGeom.addUser(mS3d); - } - - int gSize = geometryList.size(); - - for(i=0; i<gSize; i++) { - geometry = geometryList.get(i); - if(geometry != null) { - newGA.geoType = geometry.geoType; - newGA.alphaEditable = mS3d.isAlphaEditable(geometry); - break; - } - } - - if((geometry != null) && - (geometry.geoType == GeometryRetained.GEO_TYPE_TEXT3D)) { - - for(i = 0; i<gSize; i++) { - geometry = geometryList.get(i); - if(geometry != null) { - Text3DRetained tempT3d = (Text3DRetained)geometry; - geometryCnt += tempT3d.numChars; - } - else { - // This is slightly wasteful, but not quite worth to optimize yet. - geometryCnt++; - } - } - newGA.geometryArray = new GeometryRetained[geometryCnt]; - newGA.lastLocalTransformArray = new Transform3D[geometryCnt]; - // Reset geometryCnt; - geometryCnt = 0; - - } - else { - newGA.geometryArray = new GeometryRetained[gSize]; - } - - newGA.locale = mS3d.locale; - newGA.visible = visible; - newGA.source = mS3d; - - - for(gaCnt = 0; gaCnt<gSize; gaCnt++) { - geometry = geometryList.get(gaCnt); - if(geometry == null) { - newGA.geometryArray[geometryCnt++] = null; - } - else { - if (geometry.geoType == GeometryRetained.GEO_TYPE_TEXT3D) { - Text3DRetained t = (Text3DRetained)geometry; - GeometryRetained geo; - for (i=0; i<t.numChars; i++, geometryCnt++) { - geo = t.geometryList[i]; - if (geo!= null) { - newGA.geometryArray[geometryCnt] = geo; - newGA.lastLocalTransformArray[geometryCnt] = - t.charTransforms[i]; - - } else { - newGA.geometryArray[geometryCnt] = null; - newGA.lastLocalTransformArray[geometryCnt] = null; - } - - } - - } else { - newGA.geometryArray[geometryCnt++] = geometry; - } - } - } - - oldGAArray = new GeometryAtom[s3dMSize]; - newGAArray = new GeometryAtom[s3dMSize]; - oldGAArray[0] = oldGA; - newGAArray[0] = newGA; - - mS3d.geomAtom = newGA; - mS3d.mirrorShape3DLock.writeUnlock(); - - // ..... clone the rest of mirrorS3D's GA with the above newGA, but modify - // its source. - - for (i = 1; i < s3dMSize; i++) { - mS3d = mirrorShape3D.get(i); - mS3d.mirrorShape3DLock.writeLock(); - oldGA = mS3d.geomAtom; - newGA = new GeometryAtom(); - - if(newGeom != null) { - newGeom.addUser(mS3d); - } - - newGA.geoType = newGAArray[0].geoType; - newGA.locale = mS3d.locale; - newGA.visible = visible; - newGA.source = mS3d; - newGA.alphaEditable = newGAArray[0].alphaEditable; - - newGA.geometryArray = new GeometryRetained[newGAArray[0].geometryArray.length]; - for(j=0; j<newGA.geometryArray.length; j++) { - newGA.geometryArray[j] = newGAArray[0].geometryArray[j]; - } - - oldGAArray[i] = oldGA; - newGAArray[i] = newGA; - - mS3d.geomAtom = newGA; - mS3d.mirrorShape3DLock.writeUnlock(); - } - - TargetsInterface ti = - ((GroupRetained)parent).getClosestTargetsInterface( - TargetsInterface.TRANSFORM_TARGETS); - CachedTargets[] newCtArr = null; - - if (ti != null) { - CachedTargets ct; - newCtArr = new CachedTargets[s3dMSize]; - - for (i=0; i<s3dMSize; i++) { - - ct = ti.getCachedTargets( - TargetsInterface.TRANSFORM_TARGETS, i, -1); - if (ct != null) { - newCtArr[i] = new CachedTargets(); - newCtArr[i].copy(ct); - newCtArr[i].replace(oldGAArray[i], newGAArray[i], - Targets.GEO_TARGETS); - } else { - newCtArr[i] = null; - } - } - ti.resetCachedTargets(TargetsInterface.TRANSFORM_TARGETS, - newCtArr, -1); - } - - - J3dMessage changeMessage = new J3dMessage(); - changeMessage.type = J3dMessage.SHAPE3D_CHANGED; - // Who to send this message to ? - changeMessage.threads = J3dThread.UPDATE_RENDER | - J3dThread.UPDATE_TRANSFORM | - J3dThread.UPDATE_GEOMETRY; - changeMessage.universe = universe; - changeMessage.args[0] = this; - changeMessage.args[1] = new Integer(GEOMETRY_CHANGED); - changeMessage.args[2] = oldGAArray; - changeMessage.args[3] = newGAArray; - if (ti != null) { - changeMessage.args[4] = ti; - changeMessage.args[5] = newCtArr; - } - if (boundsAutoCompute) { - getCombineBounds((BoundingBox)localBounds); - } - VirtualUniverse.mc.processMessage(changeMessage); - - } - - - // ********** End of New 1.2.1 code .... - - - - - - Shape3DRetained getMirrorShape(SceneGraphPath path) { - if (!inSharedGroup) { - return mirrorShape3D.get(0); - } - HashKey key = new HashKey(""); - path.getHashKey(key); - return getMirrorShape(key); - } - - Shape3DRetained getMirrorShape(HashKey key) { - if (key == null) { - return mirrorShape3D.get(0); - } else { - int i = key.equals(localToVworldKeys, 0, localToVworldKeys.length); - - if (i>=0) { - return mirrorShape3D.get(i); - } - } - // Not possible - throw new RuntimeException("Shape3DRetained: MirrorShape Not found!"); - } - - @Override - void setBoundsAutoCompute(boolean autoCompute) { - GeometryRetained geometry; - if (autoCompute != boundsAutoCompute) { - if (autoCompute) { - // localBounds may not have been set to bbox - localBounds = new BoundingBox((BoundingBox) null); - if (source.isLive() && geometryList != null) { - int size = geometryList.size()*mirrorShape3D.size(); - for (int i=0; i<size; i++) { - geometry = geometryList.get(i); - geometry.incrComputeGeoBounds(); - } - } - - getCombineBounds((BoundingBox)localBounds); - } - else { - if (source.isLive() && geometryList != null) { - int size = geometryList.size()*mirrorShape3D.size(); - for (int i=0; i<size; i++) { - geometry = geometryList.get(i); - geometry.decrComputeGeoBounds(); - } - - } - } - super.setBoundsAutoCompute(autoCompute); - if (source.isLive()) { - J3dMessage message = new J3dMessage(); - message.type = J3dMessage.BOUNDS_AUTO_COMPUTE_CHANGED; - message.threads = J3dThread.UPDATE_TRANSFORM | - J3dThread.UPDATE_GEOMETRY | - J3dThread.UPDATE_RENDER; - message.universe = universe; - message.args[0] = getGeomAtomsArray(mirrorShape3D); - // no need to clone localBounds - message.args[1] = localBounds; - VirtualUniverse.mc.processMessage(message); - } - } - } - // This method is called when coordinates of a geometry in the geometrylist - // changed and autoBoundsCompute is true - - @Override - void updateBounds() { - localBounds = new BoundingBox((BoundingBox) null); - getCombineBounds((BoundingBox)localBounds); - synchronized(mirrorShape3D) { - if (source.isLive()) { - J3dMessage message = new J3dMessage(); - message.type = J3dMessage.BOUNDS_AUTO_COMPUTE_CHANGED; - message.threads = J3dThread.UPDATE_TRANSFORM | - J3dThread.UPDATE_GEOMETRY | - J3dThread.UPDATE_RENDER; - message.universe = universe; - message.args[0] = getGeomAtomsArray(mirrorShape3D); - // no need to clone localBounds - message.args[1] = localBounds; - VirtualUniverse.mc.processMessage(message); - } - } - } - - boolean allowIntersect() { - GeometryRetained ga = null; - - for(int i=0; i<geometryList.size(); i++) { - ga = geometryList.get(i); - if(ga != null) - if (!ga.source.getCapability(Geometry.ALLOW_INTERSECT)) { - return false; - } - } - return true; - } - boolean intersectGeometryList(Shape3DRetained otherShape) { - GeometryRetained geom1, geom2; - ArrayList<GeometryRetained> gaList = otherShape.geometryList; - int gaSize = gaList.size(); - Transform3D otherLocalToVworld = otherShape.getCurrentLocalToVworld(); - Transform3D thisLocalToVworld = getCurrentLocalToVworld(); - int primaryViewIdx = -1; - - - if (this instanceof OrientedShape3DRetained) { - primaryViewIdx = getPrimaryViewIdx(); - thisLocalToVworld.mul(((OrientedShape3DRetained)this). - getOrientedTransform(primaryViewIdx)); - } - - if (otherShape instanceof OrientedShape3DRetained) { - if (primaryViewIdx < 0) { - primaryViewIdx = getPrimaryViewIdx(); - } - otherLocalToVworld.mul(((OrientedShape3DRetained)otherShape). - getOrientedTransform(primaryViewIdx)); - } - - for (int i=geometryList.size()-1; i >=0; i--) { - geom1 = geometryList.get(i); - if (geom1 != null) { - for (int j=gaSize-1; j >=0; j--) { - geom2 = gaList.get(j); - if ((geom2 != null) && - geom1.intersect(thisLocalToVworld, - otherLocalToVworld, geom2)) { - return true; - } - } - } - } - - return false; - } - - boolean intersectGeometryList(Transform3D thisLocalToVworld, Bounds targetBound) { - - GeometryRetained geometry; - - if (this instanceof OrientedShape3DRetained) { - Transform3D orientedTransform = - ((OrientedShape3DRetained)this). - getOrientedTransform(getPrimaryViewIdx()); - thisLocalToVworld.mul(orientedTransform); - } - - for (int i=geometryList.size() - 1; i >=0; i--) { - geometry = geometryList.get(i); - if ((geometry != null) && - geometry.intersect(thisLocalToVworld, targetBound)) { - return true; - } - } - - return false; - - } - - - /** - * This initialize the mirror shape to reflect the state of the - * real Morph. - */ - void initMirrorShape3D(SetLiveState s, MorphRetained morph, int index) { - - GeometryRetained geometry; - - universe = morph.universe; - inSharedGroup = morph.inSharedGroup; - inBackgroundGroup = morph.inBackgroundGroup; - geometryBackground = morph.geometryBackground; - parent = morph.parent; - locale = morph.locale; - - OrderedPath op = s.orderedPaths.get(index); - if (op.pathElements.size() == 0) { - orderedPath = null; - } else { - orderedPath = op; - } - - staticTransform = morph.staticTransform; - if (morph.boundsAutoCompute) { - localBounds.set(morph.localBounds); - } - bounds = localBounds; - vwcBounds = new BoundingBox((BoundingBox) null); - vwcBounds.transform(bounds, getCurrentLocalToVworld(0)); - - if (morph.collisionBound == null) { - collisionBound = null; - collisionVwcBound = vwcBounds; - } else { - collisionBound = morph.collisionBound; - collisionVwcBound = (Bounds)collisionBound.clone(); - collisionVwcBound.transform(getCurrentLocalToVworld(0)); - } - - appearanceOverrideEnable = morph.appearanceOverrideEnable; - - // mga is the final geometry we're interested. - geometryList = new ArrayList<GeometryRetained>(1); - geometryList.add((GeometryArrayRetained)morph.morphedGeometryArray.retained); - - GeometryAtom gAtom = new GeometryAtom(); - gAtom.geometryArray = new GeometryRetained[1]; - - gAtom.locale = locale; - gAtom.visible = morph.visible; - gAtom.source = this; - - geometry = geometryList.get(0); - - if(geometry ==null) { - gAtom.geometryArray[0] = null; - } else { - gAtom.geometryArray[0] = (GeometryArrayRetained)morph. - morphedGeometryArray.retained; - gAtom.geoType = gAtom.geometryArray[0].geoType; - } - geomAtom = gAtom; - - // Assign the parent of this mirror shape node - sourceNode = morph; - } - - // geometries in morph object is modified, update the geometry - // list in the mirror shapes and the geometry array in the geometry atom - - void setMorphGeometry(Geometry geometry, ArrayList mirrorShapes) { - GeometryAtom oldGA, newGA; - Shape3DRetained ms; - int nMirrorShapes = mirrorShapes.size(); - int i; - - GeometryAtom oldGAArray[] = new GeometryAtom[nMirrorShapes]; - GeometryAtom newGAArray[] = new GeometryAtom[nMirrorShapes]; - - - for (i = 0; i < nMirrorShapes; i++) { - ms = (Shape3DRetained) mirrorShapes.get(i); - - oldGA = Shape3DRetained.getGeomAtom(ms); - - ms.geometryList = new ArrayList<GeometryRetained>(1); - ms.geometryList.add((GeometryArrayRetained)geometry.retained); - - newGA = new GeometryAtom(); - newGA.geometryArray = new GeometryRetained[1]; - - if (geometry ==null) { - newGA.geometryArray[0] = null; - } else { - newGA.geometryArray[0] = - (GeometryArrayRetained)geometry.retained; - newGA.geoType = newGA.geometryArray[0].geoType; - } - - newGA.locale = locale; - newGA.visible = oldGA.visible; - newGA.source = this; - - oldGAArray[i] = oldGA; - newGAArray[i] = newGA; - - Shape3DRetained.setGeomAtom(ms, newGA); - } - - TargetsInterface ti = - ((GroupRetained)parent).getClosestTargetsInterface( - TargetsInterface.TRANSFORM_TARGETS); - CachedTargets[] newCtArr = null; - - if (ti != null) { - CachedTargets ct; - newCtArr = new CachedTargets[nMirrorShapes]; - - for (i=0; i<nMirrorShapes; i++) { - - ct = ti.getCachedTargets( - TargetsInterface.TRANSFORM_TARGETS, i, -1); - if (ct != null) { - newCtArr[i] = new CachedTargets(); - newCtArr[i].copy(ct); - newCtArr[i].replace(oldGAArray[i], newGAArray[i], - Targets.GEO_TARGETS); - } else { - newCtArr[i] = null; - } - } - } - - // send a Shape GEOMETRY_CHANGED message for all geometry atoms - - J3dMessage changeMessage = new J3dMessage(); - changeMessage.type = J3dMessage.SHAPE3D_CHANGED; - changeMessage.threads = J3dThread.UPDATE_RENDER | - J3dThread.UPDATE_TRANSFORM | - J3dThread.UPDATE_GEOMETRY; - changeMessage.universe = universe; - changeMessage.args[0] = this; - changeMessage.args[1] = new Integer(GEOMETRY_CHANGED); - changeMessage.args[2] = oldGAArray; - changeMessage.args[3] = newGAArray; - if (ti != null) { - changeMessage.args[4] = ti; - changeMessage.args[5] = newCtArr; - } - VirtualUniverse.mc.processMessage(changeMessage); - } - - - /** - * Return an array of geometry atoms belongs to userList. - * The input is an arraylist of Shape3DRetained type. - * This is used to send a message of the snapshot of the - * geometry atoms that are affected by this change. - */ - final static GeometryAtom[] getGeomAtomsArray(ArrayList<Shape3DRetained> userList) { - Shape3DRetained ms = null; - GeometryAtom[] gaArr = null; - int size, nullCnt=0, i, j; - - synchronized(userList) { - size = userList.size(); - gaArr = new GeometryAtom[size]; - for (i = 0; i < size; i++) { - ms = userList.get(i); - ms.mirrorShape3DLock.readLock(); - if(ms.geomAtom == null) { - nullCnt++; - } - gaArr[i] = ms.geomAtom; - ms.mirrorShape3DLock.readUnlock(); - } - } - if(nullCnt == 0) { - return gaArr; - } - else if(nullCnt == size) { - return null; - } - else { - GeometryAtom[] newGaArr = new GeometryAtom[size - nullCnt]; - - for (i=0, j=0; i < size; i++) { - if(gaArr[i] != null) { - newGaArr[j++] = gaArr[i]; - } - } - return newGaArr; - } - } - - /** - * Return a list of geometry atoms belongs to userList and places a list of - * universe found in userList in univList. - * The input is an array of Shape3DRetained type. - * univList is assume to be empty. - * This is used to send a message of the snapshot of the - * geometry atoms that are affected by this change. - */ -final static ArrayList<ArrayList<GeometryAtom>> getGeomAtomsList(ArrayList userList, ArrayList<VirtualUniverse> univList) { - ArrayList<ArrayList<GeometryAtom>> listPerUniverse = new ArrayList<ArrayList<GeometryAtom>>(); - int index; - ArrayList<GeometryAtom> gaList = null; - Shape3DRetained ms = null; - boolean moreThanOneUniv = false; - VirtualUniverse firstFndUniv = null; - - synchronized(userList) { - for (int i = userList.size()-1; i >=0; i--) { - ms = (Shape3DRetained) userList.get(i); - - if(moreThanOneUniv == false) { - if(firstFndUniv == null) { - firstFndUniv = ms.universe; - univList.add(ms.universe); - - gaList = new ArrayList<GeometryAtom>(); - listPerUniverse.add(gaList); - } - else if(firstFndUniv != ms.universe) { - moreThanOneUniv = true; - univList.add(ms.universe); - gaList = new ArrayList<GeometryAtom>(); - listPerUniverse.add(gaList); - } - } - else { - index = univList.indexOf(ms.universe); - if (index < 0) { - univList.add(ms.universe); - gaList = new ArrayList<GeometryAtom>(); - listPerUniverse.add(gaList); - } - else { - gaList = listPerUniverse.get(index); - } - } - - - ms.mirrorShape3DLock.readLock(); - - if(ms.geomAtom != null) { - gaList.add(ms.geomAtom); - } - ms.mirrorShape3DLock.readUnlock(); - - } - } - return listPerUniverse; - } - - final static GeometryAtom getGeomAtom(Shape3DRetained shape) { - GeometryAtom ga; - - shape.mirrorShape3DLock.readLock(); - ga = shape.geomAtom; - shape.mirrorShape3DLock.readUnlock(); - - return ga; - } - - final static void setGeomAtom(Shape3DRetained shape, GeometryAtom ga) { - shape.mirrorShape3DLock.writeLock(); - shape.geomAtom = ga; - shape.mirrorShape3DLock.writeUnlock(); - } - - - // Alpha is editable due to the appearance - boolean isAlphaEditable(GeometryRetained geo) { - - boolean alphaEditable = false; - - if (appearanceOverrideEnable) { - alphaEditable = true; - } else if (geo != null && - appearance != null) { - - AppearanceRetained app = appearance; - - if (source.getCapability( - Shape3D.ALLOW_APPEARANCE_WRITE) || - source.getCapability( - Shape3D.ALLOW_APPEARANCE_OVERRIDE_WRITE) || - - app.source.getCapability( - Appearance.ALLOW_RENDERING_ATTRIBUTES_WRITE) || - - app.source.getCapability( - Appearance.ALLOW_TRANSPARENCY_ATTRIBUTES_WRITE) || - - (app.renderingAttributes != null && - (app.renderingAttributes.source.getCapability( - RenderingAttributes.ALLOW_ALPHA_TEST_FUNCTION_WRITE) || - app.renderingAttributes.source.getCapability( - RenderingAttributes.ALLOW_IGNORE_VERTEX_COLORS_WRITE))) || - - (app.transparencyAttributes != null && - (app.transparencyAttributes.source.getCapability( - TransparencyAttributes.ALLOW_MODE_WRITE) || - app.transparencyAttributes.source.getCapability( - TransparencyAttributes.ALLOW_VALUE_WRITE)))) { - - alphaEditable = true; - - } else if (geo instanceof GeometryArrayRetained && - (app.source.getCapability( - Appearance.ALLOW_TEXTURE_ATTRIBUTES_WRITE) || - - (app.textureAttributes != null && - app.textureAttributes.source.getCapability( - TextureAttributes.ALLOW_MODE_WRITE)))) { - - alphaEditable = true; - - } else if (geo instanceof RasterRetained) { - if ((((RasterRetained)geo).type & Raster.RASTER_COLOR) != -0 - && ((RasterRetained)geo).source.getCapability( - Raster.ALLOW_IMAGE_WRITE)) { - - alphaEditable = true; - } - } - } - return alphaEditable; - } - - // getCombineBounds is faster than computeCombineBounds since it - // does not recompute the geometry.geoBounds - void getCombineBounds(BoundingBox bounds) { - - if(geometryList != null) { - BoundingBox bbox = null; - GeometryRetained geometry; - - if (staticTransform != null) { - bbox = new BoundingBox((BoundingBox) null); - } - - synchronized(bounds) { - bounds.setLower( 1.0, 1.0, 1.0); - bounds.setUpper(-1.0,-1.0,-1.0); - for(int i=0; i<geometryList.size(); i++) { - geometry = geometryList.get(i); - if ((geometry != null) && - (geometry.geoType != GeometryRetained.GEO_TYPE_NONE)) { - synchronized(geometry.geoBounds) { - if (staticTransform != null) { - bbox.set(geometry.geoBounds); - bbox.transform(staticTransform.transform); - bounds.combine(bbox); - } else { - bounds.combine(geometry.geoBounds); - } - } - } - } - } - - // System.err.println("Shape3DRetained - getCombineBounds"); - // Enlarge boundingBox to the "minmium bounds" that encompasses all possible - // orientation. - if (this instanceof OrientedShape3DRetained) { - double maxVal = Math.abs(bounds.lower.x); - double tempVal = Math.abs(bounds.upper.x); - if(tempVal > maxVal) - maxVal = tempVal; - tempVal = Math.abs(bounds.lower.y); - if(tempVal > maxVal) - maxVal = tempVal; - tempVal = Math.abs(bounds.upper.y); - if(tempVal > maxVal) - maxVal = tempVal; - tempVal = Math.abs(bounds.lower.z); - if(tempVal > maxVal) - maxVal = tempVal; - tempVal = Math.abs(bounds.upper.z); - if(tempVal > maxVal) - maxVal = tempVal; - - // System.err.println("Shape3DRetained - bounds (Before) " + bounds); - bounds.setLower(-maxVal, -maxVal, -maxVal); - bounds.setUpper(maxVal, maxVal, maxVal); - // System.err.println("Shape3DRetained - bounds (After) " + bounds); - } - - } - } - - - boolean isEquivalent(Shape3DRetained shape) { - if (this.appearance != shape.appearance || - // Scoping info should be same since they are under same group - this.appearanceOverrideEnable != shape.appearanceOverrideEnable || - this.isPickable != shape.isPickable || - this.isCollidable != shape.isCollidable) { - - return false; - } - if (this.boundsAutoCompute) { - if (!shape.boundsAutoCompute) - return false; - } - else { - // If bounds autoCompute is false - // Then check if both bounds are equal - if (this.localBounds != null) { - if (shape.localBounds != null) { - return this.localBounds.equals(shape.localBounds); - } - } - else if (shape.localBounds != null) { - return false; - } - } - if (collisionBound != null) { - if (shape.collisionBound == null) - return false; - else - return collisionBound.equals(shape.collisionBound); - } - else if (shape.collisionBound != null) - return false; - - return true; - } - - // Bounds can only be set after the geometry is setLived, so has to be done - // here, if we are not using switchVwcBounds - void initializeGAtom(Shape3DRetained ms) { - int i, gaCnt; - int geometryCnt = 0; - int gSize = geometryList.size(); - GeometryRetained geometry = null; - - ms.bounds = localBounds; - ms.vwcBounds = new BoundingBox((BoundingBox) null); - ms.vwcBounds.transform(ms.bounds, ms.getCurrentLocalToVworld(0)); - - if (collisionBound == null) { - ms.collisionBound = null; - ms.collisionVwcBound = ms.vwcBounds; - } else { - ms.collisionBound = collisionBound; - ms.collisionVwcBound = (Bounds)ms.collisionBound.clone(); - ms.collisionVwcBound.transform(ms.getCurrentLocalToVworld(0)); - } - GeometryAtom gAtom = new GeometryAtom(); - for(gaCnt=0; gaCnt<gSize; gaCnt++) { - geometry = geometryList.get(gaCnt); - if(geometry != null) { - gAtom.geoType = geometry.geoType; - gAtom.alphaEditable = ms.isAlphaEditable(geometry); - break; - } - } - if((geometry != null) && - (geometry.geoType == GeometryRetained.GEO_TYPE_TEXT3D)) { - - for(gaCnt = 0; gaCnt<gSize; gaCnt++) { - geometry = geometryList.get(gaCnt); - if(geometry != null) { - Text3DRetained tempT3d = (Text3DRetained)geometry; - geometryCnt += tempT3d.numChars; - } - else { - // This is slightly wasteful, but not quite worth to optimize yet. - geometryCnt++; - } - } - gAtom.geometryArray = new GeometryRetained[geometryCnt]; - gAtom.lastLocalTransformArray = new Transform3D[geometryCnt]; - // Reset geometryCnt; - geometryCnt = 0; - - } - else { - gAtom.geometryArray = new GeometryRetained[gSize]; - } - - - for(gaCnt = 0; gaCnt<geometryList.size(); gaCnt++) { - geometry = geometryList.get(gaCnt); - if(geometry == null) { - gAtom.geometryArray[gaCnt] = null; - } - else { - if (geometry.geoType == GeometryRetained.GEO_TYPE_TEXT3D) { - Text3DRetained t = (Text3DRetained)geometry; - GeometryRetained geo; - for (i=0; i<t.numChars; i++, geometryCnt++) { - geo = t.geometryList[i]; - if (geo != null) { - gAtom.geometryArray[geometryCnt] = geo; - gAtom.lastLocalTransformArray[geometryCnt] = - t.charTransforms[i]; - } else { - gAtom.geometryArray[geometryCnt] = null; - gAtom.lastLocalTransformArray[geometryCnt] = null; - } - - } - - } else { - gAtom.geometryArray[gaCnt] = geometry; - } - } - } - gAtom.locale = ms.locale; - gAtom.visible = visible; - gAtom.source = ms; - ms.geomAtom = gAtom; - } - - // Check if geomRetained's class is equivalence with the geometry class. - void checkEquivalenceClass(Geometry geometry, int index) { - - if (geometry != null) { - for (int i=geometryList.size()-1; i >= 0; i--) { - GeometryRetained geomRetained = geometryList.get(i); - if ((geomRetained != null) && - (index != i)) { // this geometry will replace - // current one so there is no need to check - if (!geomRetained.isEquivalenceClass((GeometryRetained)geometry.retained)) { - throw new IllegalArgumentException(J3dI18N.getString("Shape3DRetained5")); - } - break; - } - } - } - } - - int indexOfGeometry(Geometry geometry) { - if(geometry != null) - return geometryList.indexOf(geometry.retained); - else - return geometryList.indexOf(null); - } - - - // Removes the specified geometry from this Shape3DRetained's list of geometries - void removeGeometry(Geometry geometry) { - int ind = indexOfGeometry(geometry); - if(ind >= 0) - removeGeometry(ind); - } - - // Removes all the geometries from this node - void removeAllGeometries() { - int n = geometryList.size(); - - int i; - Shape3DRetained mShape; - GeometryRetained oldGeom = null; - - if (((Shape3D)this.source).isLive()) { - for(int index = n-1; index >= 0; index--) { - oldGeom = geometryList.get(index); - if (oldGeom != null) { - oldGeom.clearLive(refCount); - oldGeom.decRefCnt(); - for (i=0; i<mirrorShape3D.size(); i++) { - mShape = mirrorShape3D.get(i); - oldGeom.removeUser(mShape); - } - } - geometryList.remove(index); - } - sendDataChangedMessage(null); - } else { - for(int index = n-1; index >= 0; index--) { - oldGeom = geometryList.get(index); - if (oldGeom != null) { - oldGeom.decRefCnt(); - } - geometryList.remove(index); - } - } - dirtyBoundsCache(); - } - - boolean willRemainOpaque(int geoType) { - if (appearance == null || - (appearance.isStatic() && - appearance.isOpaque(geoType))) { - return true; - } - else { - return false; - } - - } - - @Override - void handleFrequencyChange(int bit) { - int mask = 0; - if (bit == Shape3D.ALLOW_GEOMETRY_WRITE) { - mask = GEOMETRY_CHANGED; - } - else if (bit == Shape3D.ALLOW_APPEARANCE_WRITE) { - mask = APPEARANCE_CHANGED; - } - else if (bit == Shape3D.ALLOW_APPEARANCE_OVERRIDE_WRITE) { - mask = APPEARANCEOVERRIDE_CHANGED; - } - if (mask != 0) { - if (source.getCapabilityIsFrequent(bit)) - changedFrequent |= mask; - else if (!source.isLive()) { - changedFrequent &= ~mask; - } - } - } - - - // Alpha is editable due to the appearance(Called on the MirrorShape3D) - boolean isAlphaFrequentlyEditable(GeometryRetained geo) { - - boolean alphaFrequentlyEditable = false; - if (appearanceOverrideEnable) { - alphaFrequentlyEditable = true; - } else if (geo != null && - appearance != null) { - AppearanceRetained app = appearance; - - if (((changedFrequent &(APPEARANCE_CHANGED|APPEARANCEOVERRIDE_CHANGED)) != 0)|| - ((app.changedFrequent &(AppearanceRetained.RENDERING|AppearanceRetained.TRANSPARENCY)) != 0) || - (app.renderingAttributes != null && - (((app.renderingAttributes.changedFrequent & (RenderingAttributesRetained.IGNORE_VCOLOR |RenderingAttributesRetained.ALPHA_TEST_FUNC)) != 0))) || - - (app.transparencyAttributes != null && - ((app.transparencyAttributes.changedFrequent != 0)))) { - - alphaFrequentlyEditable = true; - - } else if (geo instanceof GeometryArrayRetained && - ((app.changedFrequent & AppearanceRetained.TEXTURE_ATTR) != 0) || - (app.textureAttributes != null && - ((app.textureAttributes.changedFrequent & TextureAttributes.ALLOW_MODE_WRITE) != 0))) { - alphaFrequentlyEditable = true; - - } else if (geo instanceof RasterRetained) { - if (((((RasterRetained)geo).type & Raster.RASTER_COLOR) != -0) - && (((RasterRetained)geo).cachedChangedFrequent != 0)) { - - alphaFrequentlyEditable = true; - } - } - } - // System.err.println("changedFrequent="+changedFrequent+" sourceNode = "+sourceNode+" isAlphaFrequentlyEditable, = "+alphaFrequentlyEditable); - return alphaFrequentlyEditable; - } - - - int getPrimaryViewIdx() { - // To avoid MT-safe issues when using View, just clone it. - UnorderList viewList = VirtualUniverse.mc.cloneView(); - View views[] = (View []) viewList.toArray(false); - int size = viewList.arraySize(); - - for (int i=0; i < size; i++) { - if (views[i].primaryView) { - return views[i].viewIndex; - } - } - return 0; - } - - @Override - void searchGeometryAtoms(UnorderList list) { - list.add(getGeomAtom(getMirrorShape(key))); - } -} - |