📄 transformgroupretained.java
字号:
// save and reset the keepTG and needNormalsTransform flags boolean saveKeepTG = compState.keepTG; compState.keepTG = false; boolean saveNeedNormalsTransform = compState.needNormalsTransform; compState.needNormalsTransform = false; super.compile(compState); if (compState.keepTG) { // keep this transform group, don't merge it mergeFlag = SceneGraphObjectRetained.DONT_MERGE; } if (J3dDebug.devPhase && J3dDebug.debug) { compState.numTransformGroups++; if (isStatic()) compState.numStaticTransformGroups++; if (mergeFlag == SceneGraphObjectRetained.MERGE) compState.numMergedTransformGroups++; } if (mergeFlag == SceneGraphObjectRetained.DONT_MERGE) { // a non-mergeable TG will trigger a merge of its subtree compState.staticTransform = null; compState.parentGroup = null; super.merge(compState); } else { // flag this TG as to be merged later on mergeFlag = SceneGraphObjectRetained.MERGE; } // restore compile state compState.keepTG = saveKeepTG; this.needNormalsTransform = compState.needNormalsTransform; compState.needNormalsTransform = saveNeedNormalsTransform; } void merge(CompileState compState) { TransformGroupRetained saveStaticTransform; // merge the transforms if (compState.staticTransform != null) { staticTransform = compState.staticTransform; mergeTransform(compState.staticTransform); } if (mergeFlag == SceneGraphObjectRetained.MERGE) { // before we push down the static transform, check // to see if the transform will be pushed down to shapes // with geometry_with_normals and if so, check if // the normal transform has uniform scale or not. If // it doesn't, don't push it down. if (this.needNormalsTransform) { Transform3D normalXform = this.getNormalTransform(); if (!normalXform.isCongruent()) { mergeFlag = SceneGraphObjectRetained.DONT_MERGE; } } } if (mergeFlag == SceneGraphObjectRetained.MERGE) { saveStaticTransform = compState.staticTransform; compState.staticTransform = this; // go to the merge method of the group node to start // pushing down the static transform until it hits // a leaf or a subtree which is already merged. super.merge(compState); // reset the compile state compState.staticTransform = saveStaticTransform; } else { compState.parentGroup.compiledChildrenList.add(this); parent = compState.parentGroup; } mergeFlag = SceneGraphObjectRetained.MERGE_DONE; } /** * This setlive simply concatinates it's transform onto all the ones * passed in. */ void setLive(SetLiveState s) { int i,j; Transform3D trans = null; Targets[] newTargets = null; Targets[] savedTransformTargets = null; int oldTraverseFlags = 0; int len; Object obj; // XXXX - optimization for targetThreads computation, require // cleanup in GroupRetained.doSetLive() //int savedTargetThreads = 0; //savedTargetThreads = s.transformTargetThreads; //s.transformTargetThreads = 0; oldTraverseFlags = s.traverseFlags; savedTransformTargets = s.transformTargets; int numPaths = (s.inSharedGroup)? s.keys.length : 1; newTargets = new Targets[numPaths]; for(i=0; i<numPaths; i++) { newTargets[i] = new Targets(); } s.transformTargets = newTargets; s.traverseFlags = 0; // This is needed b/c super.setlive is called after inSharedGroup check. inSharedGroup = s.inSharedGroup; trans = new Transform3D(); transform.getWithLock(trans); currentTransform.set(trans); ArrayList savedChildTransformLinks = s.childTransformLinks; GroupRetained savedParentTransformLink = s.parentTransformLink; Transform3D[][] oldCurrentList = s.currentTransforms; int[][] oldCurrentIndexList = s.currentTransformsIndex; super.doSetLive(s); if (! inSharedGroup) { if (s.transformTargets[0] != null) { cachedTargets[0] = s.transformTargets[0].snapShotInit(); } if (s.switchTargets != null && s.switchTargets[0] != null) { s.switchTargets[0].addNode(this, Targets.GRP_TARGETS); } } else { int hkIndex; for(i=0; i<numPaths; i++) { if (s.transformTargets[i] != null) { hkIndex = s.keys[i].equals(localToVworldKeys, 0, localToVworldKeys.length); cachedTargets[hkIndex] = s.transformTargets[i].snapShotInit(); } if (s.switchTargets != null && s.switchTargets[i] != null) { s.switchTargets[i].addNode(this, Targets.GRP_TARGETS); } } } // Assign data in cachedTargets to j3dCTs. j3dCTs = new CachedTargets[cachedTargets.length]; copyCachedTargets(TargetsInterface.TRANSFORM_TARGETS, j3dCTs); computeTargetThreads(TargetsInterface.TRANSFORM_TARGETS, cachedTargets); // restore setLiveState from it's local variables. // setNodeData did keep a reference to these variables. s.localToVworld = localToVworld; s.localToVworldIndex = localToVworldIndex; s.currentTransforms = oldCurrentList; s.currentTransformsIndex = oldCurrentIndexList; s.childTransformLinks = savedChildTransformLinks; s.parentTransformLink = savedParentTransformLink; s.transformTargets = savedTransformTargets; if (!s.inSharedGroup) { s.transformLevels[0] -= 1; } else { for (i=0; i<s.keys.length; i++) { s.transformLevels[i] -= 1; } } if ((s.traverseFlags & NodeRetained.CONTAINS_VIEWPLATFORM) != 0) { aboveAViewPlatform = true; } s.traverseFlags |= oldTraverseFlags; if (aboveAViewPlatform && !trans.isCongruent()) { throw new BadTransformException(J3dI18N.getString("ViewPlatformRetained0")); } super.markAsLive(); } /** * remove the localToVworld transform for a transformGroup */ void removeNodeData(SetLiveState s) { synchronized (this) { // synchronized with TransformStructure if (refCount <= 0) { childLocalToVworld = null; childLocalToVworldIndex = null; transformLevels = null; // only use by TransformStruct. cachedTargets = null; perPathData = null; targetThreads = 0; if (parentTransformLink != null) { ArrayList obj; if (parentTransformLink instanceof TransformGroupRetained) { obj = ((TransformGroupRetained) parentTransformLink).childTransformLinks; } else { obj = ((SharedGroupRetained) parentTransformLink).childTransformLinks; } synchronized(obj) { obj.remove(this); } } aboveAViewPlatform = false; } else { int i, index, len; // Remove the localToVworld key int newLen = localToVworld.length - s.keys.length; Transform3D[][] newChildTList = new Transform3D[newLen][]; int[][] newChildIndexList = new int[newLen][]; int[] newTransformLevels = new int[newLen]; ArrayList[] newChildPTG = new ArrayList[newLen]; CachedTargets[] newTargets = new CachedTargets[newLen]; TransformGroupData[] newPerPathData = new TransformGroupData[newLen]; int[] tempIndex = new int[s.keys.length]; int curStart =0, newStart =0; boolean found = false; for(i=0;i<s.keys.length;i++) { index = s.keys[i].equals(localToVworldKeys, 0, localToVworldKeys.length); tempIndex[i] = index; if(index >= 0) { found = true; if(index == curStart) { curStart++; } else { len = index - curStart; System.arraycopy(childLocalToVworld, curStart, newChildTList, newStart, len); System.arraycopy(childLocalToVworldIndex, curStart, newChildIndexList, newStart, len); System.arraycopy(transformLevels, curStart, newTransformLevels, newStart, len); System.arraycopy(cachedTargets, curStart, newTargets, newStart, len); System.arraycopy(perPathData, curStart, newPerPathData, newStart, len); curStart = index+1; newStart = newStart + len; } } else { found = false; MasterControl.getCoreLogger().severe("TG.removeNodeData-Can't find matching hashKey."); } } if((found == true) && (curStart < localToVworld.length)) { len = localToVworld.length - curStart; System.arraycopy(childLocalToVworld, curStart, newChildTList, newStart, len); System.arraycopy(childLocalToVworldIndex, curStart, newChildIndexList, newStart, len); System.arraycopy(transformLevels, curStart, newTransformLevels, newStart, len); System.arraycopy(cachedTargets, curStart, newTargets, newStart, len); System.arraycopy(perPathData, curStart, newPerPathData, newStart, len); } childLocalToVworld = newChildTList; childLocalToVworldIndex = newChildIndexList; transformLevels = newTransformLevels; cachedTargets = newTargets; perPathData = newPerPathData; } super.removeNodeData(s); // Set it back to its parent localToVworld data. // This is b/c the parent has changed it localToVworld data arrays. s.localToVworld = childLocalToVworld; s.localToVworldIndex = childLocalToVworldIndex; } } void clearLive(SetLiveState s) { Targets[] savedTransformTargets = null; savedTransformTargets = s.transformTargets; // no need to gather targets from tg in clear live s.transformTargets = null; super.clearLive(s); // restore setLiveState from it's local variables. // removeNodeData has altered these variables. s.localToVworld = localToVworld; s.localToVworldIndex = localToVworldIndex; s.transformTargets = savedTransformTargets; synchronized (this) { // synchronized with TransformStructure if (inSharedGroup) { if (transformLevels != null) { maxTransformLevel = transformLevels[0]; for (int i=1; i<transformLevels.length; i++) { if (transformLevels[i] > maxTransformLevel) { maxTransformLevel = transformLevels[i]; } } } else { maxTransformLevel = -1; } if (s.switchTargets != null) { for (int i=0; i<s.switchTargets.length; i++) { if (s.switchTargets[i] != null) { s.switchTargets[i].addNode(this, Targets.GRP_TARGETS); } } } } else { maxTransformLevel = -1; if (s.switchTargets != null && s.switchTargets[0] != null) { s.switchTargets[0].addNode(this, Targets.GRP_TARGETS); } } } // XXXX: recontruct targetThreads } void computeCombineBounds(Bounds bounds) { if (cachedBounds!=null && boundsAutoCompute) { Bounds b = (Bounds) cachedBounds.clone(); // Should this be lock too ? ( MT safe ? ) // Thoughts : // Make a temp copy with lock : transform.getWithLock(trans);, but this will cause gc ... synchronized(transform) { b.transform(transform); } bounds.combine(b); return; } NodeRetained child; BoundingSphere boundingSphere = new BoundingSphere(); boundingSphere.setRadius(-1.0); if(boundsAutoCompute) { for (int i=children.size()-1; i>=0; i--) { child = (NodeRetained)children.get(i); if(child != null) child.computeCombineBounds(boundingSphere); } if (VirtualUniverse.mc.cacheAutoComputedBounds) { cachedBounds = (Bounds) boundingSphere.clone(); } } else { // Should this be lock too ? ( MT safe ? ) synchronized(localBounds) { boundingSphere.set(localBounds); } } // Should this be lock too ? ( MT safe ? ) // Thoughts : // Make a temp copy with lock : transform.getWithLock(trans);, but this will cause gc ... synchronized(transform) { boundingSphere.transform(transform); } bounds.combine(boundingSphere); } void processChildLocalToVworld(ArrayList dirtyTransformGroups, ArrayList keySet, UpdateTargets targets, ArrayList blUsers) { synchronized(this) { // sync with setLive/clearLive if (inSharedGroup) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -