📄 behaviorstructure.java
字号:
/* * $RCSfile: BehaviorStructure.java,v $ * * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved. * * Use is subject to license terms. * * $Revision: 1.7 $ * $Date: 2007/02/09 17:17:52 $ * $State: Exp $ */package javax.media.j3d;import javax.vecmath.*;import java.util.ArrayList;import java.awt.*;import java.awt.event.*;import java.util.Arrays;/** * A behavior structure is a object that organizes behaviors, * wakeup conditions, and other behavior scheduler entities. */class BehaviorStructure extends J3dStructure { /** * The list of behaviors */ IndexedUnorderSet behaviors; /** * The list of view platforms */ IndexedUnorderSet viewPlatforms; /** * An array of schedulable behaviors, use in * removeViewPlatform() to go through only active behaviors */ IndexedUnorderSet scheduleList; /** * An array of process behaviors */ UnorderList processList[] = new UnorderList[BehaviorRetained.NUM_SCHEDULING_INTERVALS]; /** * A bounds used for getting a view platform scheduling BoundingSphere */ // BoundingSphere tempSphere = new BoundingSphere(); // BoundingSphere vpsphere = new BoundingSphere(); Point3d vpCenter = new Point3d(); Point3d vpTransCenter = new Point3d(); /** * A list of bounds WakeupOnViewPlatformEntry objects that * have seen ViewPlatformEntry */ WakeupIndexedList boundsEntryList; /** * A list of bounds WakeupOnViewPlatformExit objects that have * seen ViewPlatformEntry */ WakeupIndexedList boundsExitList; /** * A list of WakeupOnSensorEntry objects that have seen a sensor */ WakeupIndexedList currentSensorEntryList; /** * A list of WakeupOnSensorExit objects that have seen a sensor */ WakeupIndexedList currentSensorExitList; /** * The lists of the WakeupCriterion objects that the * behavior scheduler keeps. */ WakeupIndexedList wakeupOnAWTEvent; WakeupIndexedList wakeupOnActivation; WakeupIndexedList wakeupOnDeactivation; WakeupIndexedList wakeupOnBehaviorPost; WakeupIndexedList wakeupOnElapsedFrames; WakeupIndexedList wakeupOnViewPlatformEntry; WakeupIndexedList wakeupOnViewPlatformExit; WakeupIndexedList wakeupOnSensorEntry; WakeupIndexedList wakeupOnSensorExit; // Temporary array for processTransformChanged() UnorderList transformViewPlatformList = new UnorderList(ViewPlatformRetained.class); // The number of active wakeup condition in wakeupOnElapsedFrames int activeWakeupOnFrameCount = 0; // The number of active wakeup condition in wakeupOnSensorEntry/Exit int activeWakeupOnSensorCount = 0; /** * Buffers to hold events when user thread is in processStimulus() * while this event is receiving. This avoid any lost of event. * We did not remove individual element from the following list * (except clear()) so the order is still preserve. */ UnorderList awtEventsBuffer = new UnorderList(AWTEvent.class); // Use generic integer array to avoid new Integer() for individual element int postIDBuffer[] = new int[10]; // size of default UnorderList int clonePostIDBuffer[] = new int[postIDBuffer.length]; UnorderList behaviorPostBuffer = new UnorderList(Behavior.class); // temp values for transformed hotspot used in // wakeupOnSensorEntry/ExitupdateSensorsHotspot Transform3D sensorTransform = new Transform3D(); Vector3d sensorLoc = new Vector3d(); Point3d ptSensorLoc = new Point3d(); // list of active physical environments UnorderList physicalEnvironments = new UnorderList(1, PhysicalEnvironment.class); // list of Behavior waiting to be add to behavior list and buildTree() UnorderList pendingBehaviors = new UnorderList(BehaviorRetained.class); // true if branch detach boolean branchDetach = false; // This is used to notify WakeupOnAWTEvent re-enable Canvas3D events long awtEventTimestamp = 1; // used to process transform messages boolean transformMsg = false; UpdateTargets targets = null; BehaviorStructure(VirtualUniverse u) { super(u, J3dThread.UPDATE_BEHAVIOR); for (int i=BehaviorRetained.NUM_SCHEDULING_INTERVALS-1; i >= 0; i--) { processList[i] = new UnorderList(BehaviorRetained.class); } behaviors = new IndexedUnorderSet(BehaviorRetained.class, BehaviorRetained.BEHAIVORS_IN_BS_LIST, u); viewPlatforms = new IndexedUnorderSet(ViewPlatformRetained.class, ViewPlatformRetained.VP_IN_BS_LIST, u); scheduleList = new IndexedUnorderSet(BehaviorRetained.class, BehaviorRetained.SCHEDULE_IN_BS_LIST, u); boundsEntryList = new WakeupIndexedList(WakeupOnViewPlatformEntry.class, WakeupOnViewPlatformEntry.BOUNDSENTRY_IN_BS_LIST, u); boundsExitList = new WakeupIndexedList(WakeupOnViewPlatformExit.class, WakeupOnViewPlatformExit.BOUNDSEXIT_IN_BS_LIST, u); currentSensorEntryList = new WakeupIndexedList(WakeupOnSensorEntry.class, WakeupOnSensorEntry.SENSORENTRY_IN_BS_LIST, u); currentSensorExitList = new WakeupIndexedList(WakeupOnSensorExit.class, WakeupOnSensorExit.SENSOREXIT_IN_BS_LIST, u); wakeupOnAWTEvent = new WakeupIndexedList(WakeupOnAWTEvent.class, WakeupOnAWTEvent.COND_IN_BS_LIST, u); wakeupOnActivation = new WakeupIndexedList(WakeupOnActivation.class, WakeupOnActivation.COND_IN_BS_LIST, u); wakeupOnDeactivation = new WakeupIndexedList(WakeupOnDeactivation.class, WakeupOnDeactivation.COND_IN_BS_LIST, u); wakeupOnBehaviorPost = new WakeupIndexedList(WakeupOnBehaviorPost.class, WakeupOnBehaviorPost.COND_IN_BS_LIST, u); wakeupOnElapsedFrames = new WakeupIndexedList(WakeupOnElapsedFrames.class, WakeupOnElapsedFrames.COND_IN_BS_LIST, u); wakeupOnViewPlatformEntry = new WakeupIndexedList(WakeupOnViewPlatformEntry.class, WakeupOnViewPlatformEntry.COND_IN_BS_LIST, u); wakeupOnViewPlatformExit = new WakeupIndexedList(WakeupOnViewPlatformExit.class, WakeupOnViewPlatformExit.COND_IN_BS_LIST, u); wakeupOnSensorEntry = new WakeupIndexedList(WakeupOnSensorEntry.class, WakeupOnSensorEntry.COND_IN_BS_LIST, u); wakeupOnSensorExit = new WakeupIndexedList(WakeupOnSensorExit.class, WakeupOnSensorExit.COND_IN_BS_LIST, u); } void processMessages(long referenceTime) { J3dMessage[] messages = getMessages(referenceTime); int nMsg = getNumMessage(); J3dMessage m; if (nMsg > 0) { for (int i=0; i<nMsg; i++) { m = messages[i]; switch (m.type) { case J3dMessage.TRANSFORM_CHANGED: // Compress Message transformMsg = true; break; case J3dMessage.COND_MET: // No need to compress Message since wakeupCondition // will make sure that only one message is sent. processConditionMet((BehaviorRetained) m.args[0], (Boolean) m.args[1]); break; case J3dMessage.INSERT_NODES: insertNodes((Object[])m.args[0]); break; case J3dMessage.REMOVE_NODES: removeNodes(m); break; case J3dMessage.BEHAVIOR_ACTIVATE: activateBehaviors(); break; case J3dMessage.BEHAVIOR_ENABLE: addToScheduleList((BehaviorRetained) m.args[1]); reEvaluateWakeupCount(); break; case J3dMessage.BEHAVIOR_DISABLE: removeFromScheduleList((BehaviorRetained) m.args[1]); reEvaluateWakeupCount(); break; case J3dMessage.SCHEDULING_INTERVAL_CHANGED: ((BehaviorRetained) m.args[1]).schedulingInterval = ((Integer) m.args[2]).intValue(); break; case J3dMessage.SWITCH_CHANGED: processSwitchChanged(m); // may need to process dirty switched-on transform if (universe.transformStructure.getLazyUpdate()) { transformMsg = true; } break; case J3dMessage.BOUNDINGLEAF_CHANGED: processBoundingLeafChanged((Object []) m.args[3], (Bounds) m.args[2]); break; case J3dMessage.UPDATE_VIEW: reEvaluatePhysicalEnvironments(); ViewPlatform v = ((View) m.args[0]).getViewPlatform(); if (v != null) { // ViewPlatform may set to null when deactivate() processViewPlatformTransform((ViewPlatformRetained) v.retained); } break; case J3dMessage.UPDATE_VIEWPLATFORM: ViewPlatformRetained vp = (ViewPlatformRetained) m.args[0]; // update cached scheduling region first vp.updateActivationRadius(((Float) m.args[1]).floatValue()); // then process the VP transform processViewPlatformTransform(vp); break; case J3dMessage.REGION_BOUND_CHANGED: { BehaviorRetained behav = (BehaviorRetained) m.args[1]; behav.updateTransformRegion(); processBehaviorTransform(behav); } break; case J3dMessage.BEHAVIOR_REEVALUATE: { BehaviorRetained behav = (BehaviorRetained) m.args[0]; behav.active = false; addToScheduleList(behav); } break; } m.decRefcount(); } if (transformMsg) { // get the targets from the transform structure targets = universe.transformStructure.getTargetList(); // process the transform changed for each target UnorderList arrList; arrList = targets.targetList[Targets.BEH_TARGETS]; if (arrList != null) { processBehXformChanged(arrList); } arrList = targets.targetList[Targets.VPF_TARGETS]; if (arrList != null) { processVpfXformChanged(arrList); } transformMsg = false; targets = null; } Arrays.fill(messages, 0, nMsg, null); } // wakeup even when message is null since wakeupOnElapsedFrame // will wakeup this if (activeWakeupOnSensorCount <= 0) { if (activeWakeupOnFrameCount > 0) { // Wakeup render thread when there is pending wakeupOnElapsedFrames VirtualUniverse.mc.sendRunMessage(universe, J3dThread.BEHAVIOR_SCHEDULER| J3dThread.RENDER_THREAD); } else { VirtualUniverse.mc.sendRunMessage(universe, J3dThread.BEHAVIOR_SCHEDULER); } } else { checkSensorEntryExit(); // we have to invoke checkSensorEntryExit() next time if (activeWakeupOnFrameCount > 0) { VirtualUniverse.mc.sendRunMessage(universe, J3dThread.UPDATE_BEHAVIOR| J3dThread.BEHAVIOR_SCHEDULER| J3dThread.RENDER_THREAD); } else { VirtualUniverse.mc.sendRunMessage(universe, J3dThread.UPDATE_BEHAVIOR| J3dThread.BEHAVIOR_SCHEDULER); } } } void insertNodes(Object[] nodes) { for (int i=0; i<nodes.length; i++) { Object node = (Object) nodes[i]; if (node instanceof BehaviorRetained) { pendingBehaviors.add(node); } else if (node instanceof ViewPlatformRetained) { addViewPlatform((ViewPlatformRetained) node); } } } void activateBehaviors() { BehaviorRetained behav; BehaviorRetained behavArr[] = (BehaviorRetained []) pendingBehaviors.toArray(false); for (int i=pendingBehaviors.arraySize()-1; i>=0; i--) { behav = behavArr[i]; behav.wakeupCondition = behav.newWakeupCondition; if (behav.wakeupCondition != null) { behav.wakeupCondition.buildTree(null, 0, behav); behav.conditionSet = true; behaviors.add(behav); behav.updateTransformRegion(); addToScheduleList(behav); } } pendingBehaviors.clear(); } void addViewPlatform(ViewPlatformRetained vp) { int i; BehaviorRetained behav; BehaviorRetained behavArr[] = (BehaviorRetained []) behaviors.toArray(false); viewPlatforms.add(vp); vp.updateTransformRegion(); if (!vp.isActiveViewPlatform()) { return; } // re-evaulate all behaviors to see if we need to put // more behaviors in scheduleList for (i=behaviors.arraySize()-1; i>=0; i--) { addToScheduleList(behavArr[i]); } // handle ViewPlatform Entry WakeupOnViewPlatformEntry wakeupOnViewPlatformEntryArr[] = (WakeupOnViewPlatformEntry []) wakeupOnViewPlatformEntry.toArray(false); WakeupOnViewPlatformEntry wentry; for (i=wakeupOnViewPlatformEntry.arraySize()-1; i >=0; i--) { wentry = wakeupOnViewPlatformEntryArr[i]; if (!boundsEntryList.contains(wentry) && wentry.transformedRegion.intersect(vp.center)) { boundsEntryList.add(wentry); wentry.triggeredVP = vp; wentry.setTriggered(); } } // handle ViewPlatform Exit WakeupOnViewPlatformExit wakeupOnViewPlatformExitArr[] = (WakeupOnViewPlatformExit []) wakeupOnViewPlatformExit.toArray(false); WakeupOnViewPlatformExit wexit; for (i=wakeupOnViewPlatformExit.arraySize()-1; i >=0; i--) { wexit = wakeupOnViewPlatformExitArr[i]; if (!boundsExitList.contains(wexit) && wexit.transformedRegion.intersect(vp.center)) { wexit.triggeredVP = vp; boundsExitList.add(wexit); } } } void removeNodes(J3dMessage m) { Object[] nodes = (Object[]) m.args[0]; boolean behavRemove = false; for (int i=0; i<nodes.length; i++) { Object node = nodes[i]; if (node instanceof BehaviorRetained) { behavRemove = true; removeBehavior((BehaviorRetained) node); } else if (node instanceof ViewPlatformRetained) { removeViewPlatform((ViewPlatformRetained) node); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -