📄 transformstructure.java
字号:
/* * $RCSfile: TransformStructure.java,v $ * * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved. * * Use is subject to license terms. * * $Revision: 1.8 $ * $Date: 2007/02/15 19:48:59 $ * $State: Exp $ */package javax.media.j3d;import java.util.*;/** * A transform update is a object that manages TransformGroups */class TransformStructure extends J3dStructure implements ObjectUpdate { /** * A set of TransformGroups and associated Transform3Ds to traverse */ private HashSet<TransformData> transformSet = new HashSet<TransformData>(); private ArrayList objectList = new ArrayList(); /** * arraylist of the bounding leaf users affected by the transform */ private ArrayList blUsers = new ArrayList(); // to gather transform targets private UpdateTargets targets = new UpdateTargets(); /** * An arrayList of nodes that need collisionBounds updates */ private ArrayList collisionObjectList = new ArrayList(); // List of dirty TransformGroups private ArrayList dirtyTransformGroups = new ArrayList(); // Associated Keys with the dirtyNodeGroup private ArrayList keySet = new ArrayList(); // the active list contains changed TransformGroup minus those that // have been switched-off, plus those that have been changed but // just switched-on private ArrayList<TransformGroupRetained> activeTraverseList = new ArrayList<TransformGroupRetained>(); // contains TG that have been previously changed but just switched-on private ArrayList switchDirtyTgList = new ArrayList(1); private boolean lazyUpdate = false; // ArrayList of switches that have changed, use for lastSwitchOn updates private ArrayList switchChangedList = new ArrayList(); // true if already in MasterControl's update object list private boolean inUpdateObjectList = false; /** * This constructor does nothing */ TransformStructure(VirtualUniverse u) { super(u, J3dThread.UPDATE_TRANSFORM); } void processMessages(long referenceTime) { J3dMessage[] messages = getMessages(referenceTime); int nMsg = getNumMessage(); J3dMessage m; int i; if (nMsg <= 0) { return; } targets.clearNodes(); objectList.clear(); blUsers.clear(); inUpdateObjectList = false; synchronized (universe.sceneGraphLock) { // first compact the TRANSFORM_CHANGED messages by going // backwards through the messages for (i = (nMsg-1); i >= 0; i--) { m = messages[i]; if (m.type == J3dMessage.TRANSFORM_CHANGED) { // Add the TG and associated transform. Since this is a // set, duplicates will be culled. transformSet.add(new TransformData((TransformGroupRetained)m.args[1], (Transform3D)m.args[2])); } } for (i=0; i<nMsg; i++) { m = messages[i]; switch (m.type) { case J3dMessage.INSERT_NODES: objectList.add(m.args[0]); if (m.args[1] != null) { TargetsInterface ti = (TargetsInterface)m.args[1]; ti.updateCachedTargets( TargetsInterface.TRANSFORM_TARGETS, (CachedTargets[])m.args[2]); } break; case J3dMessage.REMOVE_NODES: removeNodes(m); break; case J3dMessage.SWITCH_CHANGED: processSwitchChanged(m); break; case J3dMessage.SHAPE3D_CHANGED: objectList.add(m.args[3]); if (m.args[4] != null) { TargetsInterface ti = (TargetsInterface)m.args[4]; ti.updateCachedTargets( TargetsInterface.TRANSFORM_TARGETS, (CachedTargets[])m.args[5]); } break; case J3dMessage.GEOMETRY_CHANGED: objectList.add(m.args[0]); break; case J3dMessage.MORPH_CHANGED: objectList.add(m.args[3]); break; case J3dMessage.TEXT3D_DATA_CHANGED: objectList.add(m.args[1]); Object tiArr[] = (Object[])m.args[2]; if (tiArr != null) { Object newCtArr[] = (Object[])m.args[3]; for (int j=0; j<tiArr.length;j++) { TargetsInterface ti = (TargetsInterface)tiArr[j]; ti.updateCachedTargets( TargetsInterface.TRANSFORM_TARGETS, (CachedTargets[])newCtArr[j]); } } break; case J3dMessage.TEXT3D_TRANSFORM_CHANGED: objectList.add(m.args[0]); break; case J3dMessage.BOUNDS_AUTO_COMPUTE_CHANGED: processBoundsAutoComputeChanged(m); break; case J3dMessage.REGION_BOUND_CHANGED: processRegionBoundChanged(m); break; case J3dMessage.COLLISION_BOUND_CHANGED: processCollisionBoundChanged(m); break; } m.decRefcount(); } processCurrentLocalToVworld(); // XXXX: temporary -- processVwcBounds will be // done in GeometryStructure if (objectList.size() > 0) { processGeometryAtomVwcBounds(); } processVwcBounds(); } // Issue 434: clear references to objects that have been processed objectList.clear(); Arrays.fill(messages, 0, nMsg, null); } void processCurrentLocalToVworld() { int i, j, tSize, sSize; TransformGroupRetained tg; BranchGroupRetained bgr; Transform3D t; TransformGroupData data; lazyUpdate = false; tSize = transformSet.size(); sSize = switchDirtyTgList.size(); if (tSize <= 0 && sSize <= 0) { return; } // process TG with setTransform changes // update Transform3D, switchDirty and lToVwDrity flags if (tSize > 0) { Iterator<TransformData> it = transformSet.iterator(); while(it.hasNext()) { TransformData lData = it.next(); tg = lData.getTransformGroupRetained(); tg.currentTransform.set(lData.getTransform3D()); synchronized(tg) { // synchronized with tg.set/clearLive if(tg.perPathData != null) { if (! tg.inSharedGroup) { data = tg.perPathData[0]; if (! data.switchState.inSwitch) { // always add to activetraverseList if not in switch activeTraverseList.add(tg); data.markedDirty = true; data.switchDirty = false; } else { // if in switch, add to activetraverseList only if it is // currently switched on, otherwise, mark it as // switchDirty if (data.switchState.currentSwitchOn) { activeTraverseList.add(tg); data.switchDirty = false; data.markedDirty = true; } else { data.switchDirty = true; data.markedDirty = false; } } } else { int npaths = tg.perPathData.length; boolean added = false; for (int k=0; k<npaths; k++) { data = tg.perPathData[k]; if (!data.switchState.inSwitch) { if (!added) { // add to activetraverseList if not in switch added = true; activeTraverseList.add(tg); } data.markedDirty = true; data.switchDirty = false; } else { // if in switch, add to activetraverseList only if // it is currently switched on, otherwise, // mark it as switchDirty if (data.switchState.currentSwitchOn) { if (!added) { added = true; activeTraverseList.add(tg); } data.switchDirty = false; data.markedDirty = true; } else { data.switchDirty = true; data.markedDirty = false; } } } } } } } } // merge switchDirty into activeTraverseList if (sSize > 0) { activeTraverseList.addAll(switchDirtyTgList); switchDirtyTgList.clear(); lazyUpdate = true; } // activeTraverseList contains switched-on tg as well tSize = activeTraverseList.size(); TransformGroupRetained[] tgs = (TransformGroupRetained[])activeTraverseList.toArray(new TransformGroupRetained[tSize]); // process active TGs if (tSize > 0) { sortTransformGroups(tSize, tgs); // update lToVw and gather targets for (i=0; i<tSize; i++) { tgs[i].processChildLocalToVworld(dirtyTransformGroups, keySet, targets, blUsers); } if (!inUpdateObjectList) { VirtualUniverse.mc.addMirrorObject(this); inUpdateObjectList = true; } } transformSet.clear(); activeTraverseList.clear(); } private void sortTransformGroups(int size, TransformGroupRetained[] tgs) { if (size < 7) { insertSort(size, tgs); } else { quicksort(0, size-1, tgs); } } // Insertion sort on smallest arrays private void insertSort(int size, TransformGroupRetained[] tgs) { for (int i=0; i<size; i++) { for (int j=i; j>0 && (tgs[j-1].maxTransformLevel > tgs[j].maxTransformLevel); j--) { TransformGroupRetained tmptg = tgs[j]; tgs[j] = tgs[j-1]; tgs[j-1] = tmptg; } } } private void quicksort( int l, int r, TransformGroupRetained[] tgs ) { int i = l; int j = r; double k = tgs[(l+r) / 2].maxTransformLevel; do { while (tgs[i].maxTransformLevel<k) i++; while (k<tgs[j].maxTransformLevel) j--; if (i<=j) { TransformGroupRetained tmptg = tgs[i]; tgs[i] = tgs[j]; tgs[j] = tmptg; i++; j--; } } while (i<=j); if (l<j) quicksort(l,j, tgs); if (l<r) quicksort(i,r, tgs); } public void updateObject() { processLastLocalToVworld(); processLastSwitchOn(); } void processLastSwitchOn() { int size = switchChangedList.size(); if (size > 0) { SwitchState switchState; for (int i = 0; i < size; i++) { switchState = (SwitchState)switchChangedList.get(i); switchState.updateLastSwitchOn(); } switchChangedList.clear(); } } void processLastLocalToVworld() { int i, j, k; TransformGroupRetained tg; HashKey key; int dTGSize = dirtyTransformGroups.size(); if (J3dDebug.devPhase && J3dDebug.debug) { J3dDebug.doDebug(J3dDebug.transformStructure, J3dDebug.LEVEL_5, "processLastLocalToVworld(): dTGSize= " + dTGSize + "\n"); } for (i=0, k=0; i < dTGSize; i++) { tg = (TransformGroupRetained)dirtyTransformGroups.get(i); // Check if the transformGroup is still alive
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -