Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
javax.media.j3d.BehaviorStructure Maven / Gradle / Ivy
/*
* Copyright 1998-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.awt.AWTEvent;
import java.awt.event.ComponentEvent;
import java.awt.event.FocusEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.util.Arrays;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;
/**
* 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);
}
@Override
void processMessages(long referenceTime) {
J3dMessage[] messages = getMessages(referenceTime);
int nMsg = getNumMessage();
J3dMessage m;
if (nMsg > 0) {
for (int i=0; i 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=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 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);
}
}
}
@Override
void removeNodes(J3dMessage m) {
Object[] nodes = (Object[]) m.args[0];
boolean behavRemove = false;
for (int i=0; i= FocusEvent.FOCUS_FIRST && awtId <= FocusEvent.FOCUS_LAST) ||
(eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0) {
focusEnable = true;
}
if ((awtId >= KeyEvent.KEY_FIRST && awtId <= KeyEvent.KEY_LAST) ||
(eventMask & AWTEvent.KEY_EVENT_MASK) != 0) {
keyEnable = true;
}
if ((awtId >= MouseEvent.MOUSE_FIRST) &&
(awtId <= MouseEvent.MOUSE_LAST)) {
if ((awtId == MouseEvent.MOUSE_DRAGGED) ||
(awtId == MouseEvent.MOUSE_MOVED)) {
mouseMotionEnable = true;
}
else if ((awtId == MouseEvent.MOUSE_ENTERED) ||
(awtId == MouseEvent.MOUSE_EXITED) ||
(awtId == MouseEvent.MOUSE_CLICKED) ||
(awtId == MouseEvent.MOUSE_PRESSED) ||
(awtId == MouseEvent.MOUSE_RELEASED) ) {
mouseEnable = true;
}
else if (awtId == MouseEvent.MOUSE_WHEEL) {
mouseWheelEnable = true;
}
} else {
if ((eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0) {
mouseEnable = true;
}
if ((eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0) {
mouseMotionEnable = true;
}
if ((eventMask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0) {
mouseWheelEnable = true;
}
}
}
if (!focusEnable && universe.enableFocus) {
incTimestamp = true;
universe.disableFocusEvents();
}
if (!keyEnable && universe.enableKey) {
// key event use for toggle to fullscreen/window mode
incTimestamp = true;
universe.disableKeyEvents();
}
if (!mouseWheelEnable && universe.enableMouseWheel) {
incTimestamp = true;
universe.disableMouseWheelEvents();
}
if (!mouseMotionEnable && universe.enableMouseMotion) {
incTimestamp = true;
universe.disableMouseMotionEvents();
}
if (!mouseEnable && universe.enableMouse) {
incTimestamp = true;
universe.disableMouseEvents();
}
if (incTimestamp) {
awtEventTimestamp++;
}
}
}
void removeViewPlatform(ViewPlatformRetained vp) {
BehaviorRetained behav;
int i;
viewPlatforms.remove(vp);
BehaviorRetained scheduleArr[] = (BehaviorRetained [])
scheduleList.toArray(false);
// handle Deactive
for (i=scheduleList.arraySize()-1; i >=0 ; i--) {
behav = scheduleArr[i];
// This vp may contribute to the reason that
// behavior is in schedule list
if (!intersectVPRegion(behav.transformedRegion)) {
removeFromScheduleList(behav);
}
}
// handle ViewPlatform Entry
WakeupOnViewPlatformEntry boundsEntryArr[] =
(WakeupOnViewPlatformEntry []) boundsEntryList.toArray(false);
WakeupOnViewPlatformEntry wentry;
ViewPlatformRetained triggeredVP;
for (i=boundsEntryList.arraySize()-1; i >=0; i--) {
wentry = boundsEntryArr[i];
// only this thread can modify wentry.transformedRegion, so
// no need to getWithLock()
triggeredVP = intersectVPCenter(wentry.transformedRegion);
if (triggeredVP == null) {
boundsEntryList.remove(wentry);
}
}
// handle ViewPlatform Exit
WakeupOnViewPlatformExit boundsExitArr[] =
(WakeupOnViewPlatformExit []) boundsExitList.toArray(false);
WakeupOnViewPlatformExit wexit;
for (i=boundsExitList.arraySize()-1; i >=0; i--) {
wexit = boundsExitArr[i];
// only this thread can modify wentry.transformedRegion, so
// no need to getWithLock()
triggeredVP = intersectVPCenter(wexit.transformedRegion);
if (triggeredVP == null) {
boundsExitList.remove(wexit);
wexit.setTriggered();
}
}
}
void removeBehavior(BehaviorRetained behav) {
behaviors.remove(behav);
if ((behav.wakeupCondition != null) &&
(behav.wakeupCondition.behav != null)) {
behav.wakeupCondition.cleanTree(this);
if (behav.universe == universe) {
behav.conditionSet = false;
}
}
// cleanup boundsEntryList
// since we didn't remove it on removeVPEntryCondition
WakeupOnViewPlatformEntry boundsEntryArr[] =
(WakeupOnViewPlatformEntry []) boundsEntryList.toArray(false);
WakeupOnViewPlatformEntry wentry;
for (int i=boundsEntryList.arraySize()-1; i>=0; i--) {
wentry = boundsEntryArr[i];
if (wentry.behav == behav) {
boundsEntryList.remove(wentry);
}
}
// cleanup boundsExitList
// since we didn't remove it on removeVPExitCondition
WakeupOnViewPlatformExit boundsExitArr[] =
(WakeupOnViewPlatformExit []) boundsExitList.toArray(false);
WakeupOnViewPlatformExit wexit;
for (int i=boundsExitList.arraySize()-1; i>=0; i--) {
wexit = boundsExitArr[i];
if (wexit.behav == behav) {
boundsExitList.remove(wexit);
}
}
// cleanup currentSensorEntryList
// since we didn't remove it on removeSensorEntryCondition
WakeupOnSensorEntry currentSensorEntryArr[] =
(WakeupOnSensorEntry []) currentSensorEntryList.toArray(false);
WakeupOnSensorEntry sentry;
for (int i=currentSensorEntryList.arraySize()-1; i>=0; i--) {
sentry = currentSensorEntryArr[i];
if (sentry.behav == behav) {
currentSensorEntryList.remove(sentry);
}
}
// cleanup currentSensorExitList
// since we didn't remove it on removeSensorExitCondition
WakeupOnSensorExit currentSensorExitArr[] =
(WakeupOnSensorExit []) currentSensorExitList.toArray(false);
WakeupOnSensorExit sexit;
for (int i=currentSensorExitList.arraySize()-1; i>=0; i--) {
sexit = currentSensorExitArr[i];
if (sexit.behav == behav) {
currentSensorExitList.remove(sexit);
}
}
removeFromScheduleList(behav);
}
void handleAWTEvent(AWTEvent evt) {
awtEventsBuffer.add(evt);
VirtualUniverse.mc.sendRunMessage(universe,
J3dThread.BEHAVIOR_SCHEDULER);
}
/**
* This routine takes the awt event list and gives then to the awt event
* conditions
*/
void handleAWTEvent() {
WakeupOnAWTEvent awtConds[] = (WakeupOnAWTEvent [])
wakeupOnAWTEvent.toArray();
AWTEvent events[];
int eventSize = wakeupOnAWTEvent.arraySize();
int awtBufferSize;
synchronized (awtEventsBuffer) {
events = (AWTEvent []) awtEventsBuffer.toArray();
awtBufferSize = awtEventsBuffer.size();
awtEventsBuffer.clear();
}
WakeupOnAWTEvent awtCond;
AWTEvent evt;
int id;
for (int i=0; i < eventSize; i++) {
awtCond = awtConds[i];
for (int j=0; j < awtBufferSize; j++) {
evt = events[j];
id = evt.getID();
if (awtCond.AwtId != 0) {
if (awtCond.AwtId == id) {
// XXXX: how do we clone this event (do we need to?)
// Bug: 4181321
awtCond.addAWTEvent(evt);
}
} else {
if (id >= ComponentEvent.COMPONENT_FIRST &&
id <= ComponentEvent.COMPONENT_LAST &&
(awtCond.EventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0) {
awtCond.addAWTEvent(evt);
}
else if (id >= FocusEvent.FOCUS_FIRST &&
id <= FocusEvent.FOCUS_LAST &&
(awtCond.EventMask & AWTEvent.FOCUS_EVENT_MASK) != 0) {
awtCond.addAWTEvent(evt);
}
else if (id >= KeyEvent.KEY_FIRST &&
id <= KeyEvent.KEY_LAST &&
(awtCond.EventMask & AWTEvent.KEY_EVENT_MASK) != 0) {
awtCond.addAWTEvent(evt);
}
else if ((id == MouseEvent.MOUSE_CLICKED ||
id == MouseEvent.MOUSE_ENTERED ||
id == MouseEvent.MOUSE_EXITED ||
id == MouseEvent.MOUSE_PRESSED ||
id == MouseEvent.MOUSE_RELEASED) &&
(awtCond.EventMask & AWTEvent.MOUSE_EVENT_MASK) != 0) {
awtCond.addAWTEvent(evt);
}
else if ((id == MouseEvent.MOUSE_DRAGGED ||
id == MouseEvent.MOUSE_MOVED) &&
(awtCond.EventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0) {
awtCond.addAWTEvent(evt);
}
else if ((id == MouseEvent.MOUSE_WHEEL) &&
(awtCond.EventMask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0) {
awtCond.addAWTEvent(evt);
}
}
}
}
}
void handleBehaviorPost(Behavior behav, int postid) {
synchronized (behaviorPostBuffer) {
int size = behaviorPostBuffer.size();
if (postIDBuffer.length == size) {
int oldbuffer[] = postIDBuffer;
postIDBuffer = new int[size << 1];
System.arraycopy(oldbuffer, 0, postIDBuffer, 0, size);
}
postIDBuffer[size] = postid;
behaviorPostBuffer.add(behav);
}
VirtualUniverse.mc.sendRunMessage(universe, J3dThread.BEHAVIOR_SCHEDULER);
}
/**
* This goes through all of the criteria waiting for Behavior Posts
* and notifys them.
*/
void handleBehaviorPost() {
Behavior behav;
int postid;
WakeupOnBehaviorPost wakeup;
WakeupOnBehaviorPost wakeupConds[] = (WakeupOnBehaviorPost [])
wakeupOnBehaviorPost.toArray();
Behavior behavArr[];
int behavBufferSize;
synchronized (behaviorPostBuffer) {
behavArr = (Behavior []) behaviorPostBuffer.toArray();
behavBufferSize = behaviorPostBuffer.size();
if (clonePostIDBuffer.length < behavBufferSize) {
clonePostIDBuffer = new int[behavBufferSize];
}
System.arraycopy(postIDBuffer, 0, clonePostIDBuffer, 0,
behavBufferSize);
behaviorPostBuffer.clear();
}
int size = wakeupOnBehaviorPost.arraySize();
for (int i=0; i < size; i++) {
wakeup = wakeupConds[i];
for (int j=0; j < behavBufferSize; j++) {
behav = behavArr[j];
postid = clonePostIDBuffer[j];
if ((wakeup.post == postid || wakeup.post == 0) &&
(behav == wakeup.armingBehavior || wakeup.armingBehavior == null)) {
wakeup.triggeringBehavior = behav;
wakeup.triggeringPost = postid;
wakeup.setTriggered();
}
}
}
}
/**
* This goes through all of the criteria waiting for Elapsed Frames
* and notified them.
*/
void incElapsedFrames() {
WakeupOnElapsedFrames wakeupConds[] = (WakeupOnElapsedFrames [])
wakeupOnElapsedFrames.toArray(true);
int size = wakeupOnElapsedFrames.arraySize();
int i = 0;
while (i < size) {
wakeupConds[i++].newFrame();
}
if ( size > 0) {
VirtualUniverse.mc.sendRunMessage(universe,
J3dThread.BEHAVIOR_SCHEDULER|J3dThread.UPDATE_BEHAVIOR);
}
if (branchDetach) {
// Since this procedure may call by immediate mode user
// thread, we can't just clear it in removeNodes()
wakeupOnElapsedFrames.clearMirror();
branchDetach = false;
}
}
void removeVPEntryCondition(WakeupCondition w) {
wakeupOnViewPlatformEntry.remove(w);
// don't remove boundsEntryList, it is use next time
// when addVPExitCondition invoke to determine whether to
// trigger an event or not.
}
void addVPEntryCondition(WakeupOnViewPlatformEntry w) {
boolean needTrigger = true;
// see if the matching wakeupOnViewPlatformEntry
// condition exists & do cleanup
WakeupOnViewPlatformEntry boundsEntryArr[] =
(WakeupOnViewPlatformEntry []) boundsEntryList.toArray(false);
WakeupOnViewPlatformEntry wentry;
for (int i=boundsEntryList.arraySize()-1; i>=0; i--) {
wentry = boundsEntryArr[i];
if ((wentry.behav == w.behav) &&
(wentry.region.equals(w.region))) {
boundsEntryList.remove(i);
// Case where we wakeOr() both condition together.
// we should avoid calling setTrigger() every time.
needTrigger = false;
break;
}
}
wakeupOnViewPlatformEntry.add(w);
ViewPlatformRetained triggeredVP = intersectVPCenter(w.transformedRegion);
if (triggeredVP != null) {
boundsEntryList.add(w);
}
// we always trigger bound is inside during initialize
if (needTrigger && (triggeredVP != null)) {
w.triggeredVP = triggeredVP;
w.setTriggered();
}
}
void removeVPExitCondition(WakeupOnViewPlatformExit w) {
wakeupOnViewPlatformExit.remove(w);
// don't remove boundsExitList, it is use next time
// when addVPEntryCondition invoke to determine whether to
// trigger an event or not.
}
void addVPExitCondition(WakeupOnViewPlatformExit w) {
// Cleanup, since collideEntryList did not remove
// its condition in removeVPEntryCondition
boolean needTrigger = true;
WakeupOnViewPlatformExit boundsExitArr[] =
(WakeupOnViewPlatformExit []) boundsExitList.toArray(false);
WakeupOnViewPlatformExit wexit;
for (int i=boundsExitList.arraySize()-1; i>=0; i--) {
wexit = boundsExitArr[i];
if ((wexit.behav == w.behav) &&
(wexit.region.equals(w.region))) {
boundsExitList.remove(i);
needTrigger = false;
break;
}
}
ViewPlatformRetained triggeredVP = intersectVPCenter(w.transformedRegion);
wakeupOnViewPlatformExit.add(w);
if (triggeredVP != null) {
w.triggeredVP = triggeredVP;
boundsExitList.add(w);
}
if (!needTrigger) {
return;
}
// see if the matching wakeupOnViewPlatformEntry
// condition exists
WakeupOnViewPlatformEntry boundsEntryArr[] =
(WakeupOnViewPlatformEntry []) boundsEntryList.toArray(false);
WakeupOnViewPlatformEntry wentry;
for (int i=boundsEntryList.arraySize()-1; i>=0; i--) {
wentry = boundsEntryArr[i];
if ((wentry.behav == w.behav) &&
(wentry.region.equals(w.region))) {
// Don't remove this since if user wakeupOr()
// Entry and Exit condition together we may have trouble
// boundsEntryList.remove(i);
if (triggeredVP == null) {
w.setTriggered();
}
break;
}
}
}
void removeSensorEntryCondition(WakeupOnSensorEntry w) {
wakeupOnSensorEntry.remove(w);
// don't remove currentSensorEntryList, it is use next time
// when addSensorExitCondition invoke to determine whether to
// trigger an event or not.
}
void addSensorEntryCondition(WakeupOnSensorEntry w) {
boolean needTrigger = true;
// see if the matching wakeupOnSensorEntry
// condition exists
WakeupOnSensorEntry sensorEntryArr[] =
(WakeupOnSensorEntry []) currentSensorEntryList.toArray(false);
WakeupOnSensorEntry wentry;
for (int i=currentSensorEntryList.arraySize()-1; i>=0; i--) {
wentry = sensorEntryArr[i];
if ((wentry.behav == w.behav) &&
(wentry.region.equals(w.region))) {
currentSensorEntryList.remove(i);
needTrigger = false;
break;
}
}
wakeupOnSensorEntry.add(w);
w.updateTransformRegion();
Sensor target = sensorIntersect(w.transformedRegion);
if (target != null) {
w.setTarget(target);
currentSensorEntryList.add(w);
}
if (needTrigger && (target != null)) {
w.setTriggered();
}
VirtualUniverse.mc.sendRunMessage(universe,
J3dThread.UPDATE_BEHAVIOR);
}
void removeSensorExitCondition(WakeupOnSensorExit w) {
wakeupOnSensorExit.remove(w);
// don't remove currentSensorExitList, it is use next time
// when addSensorEntryCondition invoke to determine whether to
// trigger an event or not
}
void addSensorExitCondition(WakeupOnSensorExit w) {
// Cleanup
boolean needTrigger = true;
WakeupOnSensorExit currentSensorExitArr[] =
(WakeupOnSensorExit []) currentSensorExitList.toArray(false);
WakeupOnSensorExit wexit;
for (int i=currentSensorExitList.arraySize()-1; i>=0; i--) {
wexit = currentSensorExitArr[i];
if ((wexit.behav == w.behav) &&
(wexit.region.equals(w.region))) {
currentSensorExitList.remove(i);
needTrigger = false;
break;
}
}
w.updateTransformRegion();
Sensor target = sensorIntersect(w.transformedRegion);
wakeupOnSensorExit.add(w);
if (target != null) {
w.setTarget(target);
currentSensorExitList.add(w);
}
if (!needTrigger) {
return;
}
// see if the matching wakeupOnSensorEntry
// condition exists
WakeupOnSensorEntry sensorEntryArr[] =
(WakeupOnSensorEntry []) currentSensorEntryList.toArray(false);
WakeupOnSensorEntry wentry;
for (int i=currentSensorEntryList.arraySize()-1; i>=0; i--) {
wentry = sensorEntryArr[i];
if ((wentry.behav == w.behav) &&
(wentry.region.equals(w.region))) {
// No need to invoke currentSensorEntryList.remove(i);
if (target == null) {
w.setTriggered();
}
break;
}
}
VirtualUniverse.mc.sendRunMessage(universe,
J3dThread.UPDATE_BEHAVIOR);
}
void processConditionMet(BehaviorRetained behav,
Boolean checkSchedulingRegion) {
// Since we reuse wakeup condition, the old wakeupCondition
// will not reactivate again while processStimulus is running
// which may set another wakeupCondition.
// Previously we don't reuse wakeupCondition and cleanTree()
// everytime before calling processStimulus() so the flag
// inCallback is not necessary to check.
if (!behav.inCallback &&
((checkSchedulingRegion == Boolean.FALSE) ||
behav.active)) {
processList[behav.schedulingInterval].add(behav);
} else {
if (((behav.wakeupMask &
BehaviorRetained.WAKEUP_TIME) != 0) &&
(behav.source != null) &&
(behav.source.isLive()) &&
(behav.wakeupCondition != null)) {
// need to add back wakeupOnElapsedTime condition
// to TimerThread
behav.wakeupCondition.reInsertElapseTimeCond();
}
}
}
final void processBehXformChanged(UnorderList arrList) {
BehaviorRetained beh;
Object[] nodes, nodesArr;
int size = arrList.size();
nodesArr = arrList.toArray(false);
for (int i = 0; i < size; i++) {
nodes = (Object[])nodesArr[i];
for (int j=0; j 0) {
ViewPlatformRetained vpArr[] = (ViewPlatformRetained [])
transformViewPlatformList.toArray(false);
int size = transformViewPlatformList.arraySize();
for (i=0; i < size; i++) {
processViewPlatformTransform(vpArr[i]);
}
transformViewPlatformList.clear();
}
}
// assume behav.updateTransformRegion() invoke before
final void processBehaviorTransform(BehaviorRetained behav) {
if ((behav.wakeupMask & BehaviorRetained.WAKEUP_VP_ENTRY) != 0) {
updateVPEntryTransformRegion(behav);
}
if ((behav.wakeupMask & BehaviorRetained.WAKEUP_VP_EXIT) != 0) {
updateVPExitTransformRegion(behav);
}
if (behav.active) {
if (!intersectVPRegion(behav.transformedRegion)) {
removeFromScheduleList(behav);
}
} else {
addToScheduleList(behav);
}
}
void processViewPlatformTransform(ViewPlatformRetained vp) {
int i;
BehaviorRetained behav;
vp.updateTransformRegion();
if (!vp.isActiveViewPlatform()) {
return;
}
BehaviorRetained behavArr[] = (BehaviorRetained []) behaviors.toArray(false);
// re-evaulate all behaviors affected by this vp
for (i=behaviors.arraySize()-1; i>=0; i--) {
behav = behavArr[i];
if (behav.active) {
if (!intersectVPRegion(behav.transformedRegion)) {
removeFromScheduleList(behav);
}
} else {
addToScheduleList(behav);
}
}
// handle wakeupOnViewPlatformEntry
WakeupOnViewPlatformEntry wakeupOnViewPlatformEntryArr[] =
(WakeupOnViewPlatformEntry []) wakeupOnViewPlatformEntry.toArray(false);
WakeupOnViewPlatformEntry wentry;
int idx;
ViewPlatformRetained triggeredVP;
for (i=wakeupOnViewPlatformEntry.arraySize()-1; i >=0; i--) {
wentry = wakeupOnViewPlatformEntryArr[i];
idx = boundsEntryList.indexOf(wentry);
if (idx < 0) {
if (wentry.transformedRegion.intersect(vp.center)) {
boundsEntryList.add(wentry);
wentry.triggeredVP = vp;
wentry.setTriggered();
}
} else {
triggeredVP = intersectVPCenter(wentry.transformedRegion);
if (triggeredVP == null) {
boundsEntryList.remove(idx);
}
}
}
// handle wakeupOnViewPlatformExit;
WakeupOnViewPlatformExit wakeupOnViewPlatformExitArr[] =
(WakeupOnViewPlatformExit []) wakeupOnViewPlatformExit.toArray(false);
WakeupOnViewPlatformExit wexit;
for (i=wakeupOnViewPlatformExit.arraySize()-1; i >=0; i--) {
wexit = wakeupOnViewPlatformExitArr[i];
idx = boundsExitList.indexOf(wexit);
if (idx < 0) {
if (wexit.transformedRegion.intersect(vp.center)) {
wexit.triggeredVP = vp;
boundsExitList.add(wexit);
}
} else {
triggeredVP = intersectVPCenter(wexit.transformedRegion);
if (triggeredVP == null) {
boundsExitList.remove(idx);
wexit.setTriggered();
}
}
}
}
void updateVPEntryTransformRegion(BehaviorRetained behav) {
WakeupOnViewPlatformEntry wakeupOnViewPlatformEntryArr[] =
(WakeupOnViewPlatformEntry []) wakeupOnViewPlatformEntry.toArray(false);
WakeupOnViewPlatformEntry wentry;
ViewPlatformRetained triggeredVP;
for (int i=wakeupOnViewPlatformEntry.arraySize()-1; i >=0; i--) {
wentry = wakeupOnViewPlatformEntryArr[i];
if (wentry.behav == behav) {
wentry.updateTransformRegion(behav);
int idx = boundsEntryList.indexOf(wentry);
triggeredVP = intersectVPCenter(wentry.transformedRegion);
if (triggeredVP != null) {
if (idx < 0) {
boundsEntryList.add(wentry);
wentry.triggeredVP = triggeredVP;
wentry.setTriggered();
}
} else {
if (idx >=0) {
boundsEntryList.remove(idx);
}
}
}
}
}
void updateVPExitTransformRegion(BehaviorRetained behav) {
WakeupOnViewPlatformExit wakeupOnViewPlatformExitArr[] =
(WakeupOnViewPlatformExit []) wakeupOnViewPlatformExit.toArray(false);
WakeupOnViewPlatformExit wexit;
ViewPlatformRetained triggeredVP;
for (int i=wakeupOnViewPlatformExit.arraySize()-1; i >=0; i--) {
wexit = wakeupOnViewPlatformExitArr[i];
if (wexit.behav == behav) {
wexit.updateTransformRegion(behav);
wexit = wakeupOnViewPlatformExitArr[i];
int idx = boundsExitList.indexOf(wexit);
triggeredVP = intersectVPCenter(wexit.transformedRegion);
if (triggeredVP != null) {
if (idx < 0) {
wexit.triggeredVP = triggeredVP;
boundsExitList.add(wexit);
}
} else {
if (idx >= 0) {
boundsExitList.remove(idx);
wexit.setTriggered();
}
}
}
}
}
void reEvaluatePhysicalEnvironments() {
// we can't just add or remove from the list since
// physicalEnvironment may be share by multiple view
ViewPlatformRetained[] vpr = universe.getViewPlatformList();
physicalEnvironments.clear();
for (int i = vpr.length - 1; i >= 0; i--) {
View[] views = vpr[i].getViewList();
for (int j = views.length - 1; j >= 0; j--) {
View v = views[j];
if (!v.active)
continue;
if (!physicalEnvironments.contains(v.physicalEnvironment)) {
physicalEnvironments.add(v.physicalEnvironment);
}
}
}
}
void checkSensorEntryExit() {
int i, idx;
Sensor target;
// handle WakeupOnSensorEntry
WakeupOnSensorEntry wentry;
WakeupOnSensorEntry wentryArr[] = (WakeupOnSensorEntry [])
wakeupOnSensorEntry.toArray();
for (i=wakeupOnSensorEntry.arraySize()-1; i>=0; i--) {
wentry = wentryArr[i];
idx = currentSensorEntryList.indexOf(wentry);
wentry.updateTransformRegion();
target = sensorIntersect(wentry.transformedRegion);
if (target != null) {
if (idx < 0) {
currentSensorEntryList.add(wentry);
wentry.setTarget(target);
wentry.setTriggered();
}
} else {
if (idx >= 0) {
currentSensorEntryList.remove(idx);
}
}
}
// handle WakeupOnSensorExit
WakeupOnSensorExit wexit;
WakeupOnSensorExit wexitArr[] = (WakeupOnSensorExit [])
wakeupOnSensorExit.toArray();
for (i=wakeupOnSensorExit.arraySize()-1; i>=0; i--) {
wexit = wexitArr[i];
idx = currentSensorExitList.indexOf(wexit);
wexit.updateTransformRegion();
target = sensorIntersect(wexit.transformedRegion);
if (target != null) {
if (idx < 0) {
currentSensorExitList.add(wexit);
wexit.setTarget(target);
}
} else {
if (idx >= 0) {
currentSensorExitList.remove(idx);
wexit.setTriggered();
}
}
}
}
/**
* return the Sensor that intersect with behregion or null
*/
Sensor sensorIntersect(Bounds behregion) {
if (behregion == null)
return null;
PhysicalEnvironment env[] = (PhysicalEnvironment [])
physicalEnvironments.toArray(false);
for (int i = physicalEnvironments.arraySize() - 1; i >= 0; i--) {
if (env[i].activeViewRef <= 0)
continue;
Sensor[] sensors = env[i].getSensorList();
if (sensors == null)
continue;
for (int j = env[i].users.size() - 1; j >= 0; j--) {
View v = env[i].users.get(j);
synchronized (sensors) {
for (int k = sensors.length - 1; k >= 0; k--) {
Sensor s = sensors[k];
if (s == null)
continue;
v.getSensorToVworld(s, sensorTransform);
sensorTransform.get(sensorLoc);
ptSensorLoc.set(sensorLoc);
if (behregion.intersect(ptSensorLoc)) {
return s;
}
}
}
}
}
return null;
}
/**
* return true if one of ViewPlatforms intersect behregion
*/
final boolean intersectVPRegion(Bounds behregion) {
if (behregion == null) {
return false;
}
ViewPlatformRetained vp;
ViewPlatformRetained vpLists[] = (ViewPlatformRetained [])
viewPlatforms.toArray(false);
for (int i=viewPlatforms.arraySize()- 1; i>=0; i--) {
vp = vpLists[i];
if (vp.isActiveViewPlatform() &&
vp.schedSphere.intersect(behregion)) {
return true;
}
}
return false;
}
/**
* return true if one of ViewPlatforms center intersect behregion
*/
final ViewPlatformRetained intersectVPCenter(Bounds behregion) {
if (behregion == null) {
return null;
}
ViewPlatformRetained vp;
ViewPlatformRetained vpLists[] = (ViewPlatformRetained [])
viewPlatforms.toArray(false);
for (int i=viewPlatforms.arraySize()- 1; i>=0; i--) {
vp = vpLists[i];
if (vp.isActiveViewPlatform() &&
behregion.intersect(vp.center)) {
return vp;
}
}
return null;
}
void notifyDeactivationCondition(BehaviorRetained behav) {
WakeupOnDeactivation wakeup;
WakeupOnDeactivation wakeupConds[] = (WakeupOnDeactivation [])
wakeupOnDeactivation.toArray(false);
for (int i=wakeupOnDeactivation.arraySize()-1; i>=0; i--) {
wakeup = wakeupConds[i];
if (wakeup.behav == behav) {
wakeup.setTriggered();
}
}
}
void notifyActivationCondition(BehaviorRetained behav) {
WakeupOnActivation wakeup;
WakeupOnActivation wakeupConds[] = (WakeupOnActivation [])
wakeupOnActivation.toArray(false);
for (int i=wakeupOnActivation.arraySize()-1; i>=0; i--) {
wakeup = wakeupConds[i];
if (wakeup.behav == behav) {
wakeup.setTriggered();
}
}
}
void processSwitchChanged(J3dMessage m) {
int i,j;
UnorderList arrList;
int size;
Object[] nodes, nodesArr;
UpdateTargets targets = (UpdateTargets)m.args[0];
arrList = targets.targetList[Targets.VPF_TARGETS];
if (arrList != null) {
ViewPlatformRetained vp;
size = arrList.size();
nodesArr = arrList.toArray(false);
for (j=0; j=0; i--) {
vp = (ViewPlatformRetained) nodes[i];
vp.processSwitchChanged();
}
}
}
arrList = targets.targetList[Targets.BEH_TARGETS];
if (arrList != null) {
BehaviorRetained behav;
size = arrList.size();
nodesArr = arrList.toArray(false);
for (j=0; j=0; i--) {
behav = (BehaviorRetained) nodes[i];
if (behav.switchState.currentSwitchOn) {
addToScheduleList(behav);
} else {
removeFromScheduleList(behav);
}
}
}
}
arrList = targets.targetList[Targets.BLN_TARGETS];
if (arrList != null) {
size = arrList.size();
nodesArr = arrList.toArray(false);
Object[] objArr = (Object[])m.args[1];
Object[] obj;
for (int h=0; h=0; i--) {
Object[] users = (Object[])obj[i];
Object[] leafObj = new Object[1];
for (j = 0; j < users.length; j++) {
if (users[j] instanceof BehaviorRetained) {
leafObj[0] = users[j];
processTransformChanged(leafObj);
}
}
}
}
}
}
void processBoundingLeafChanged(Object users[],
Bounds bound) {
Object leaf;
BehaviorRetained behav;
for (int i=users.length-1; i>=0; i--) {
leaf = users[i];
if (leaf instanceof BehaviorRetained) {
behav = (BehaviorRetained) leaf;
behav.updateTransformRegion(bound);
processBehaviorTransform(behav);
}
}
}
final void removeFromScheduleList(BehaviorRetained behav) {
if (behav.active) {
if ((behav.wakeupMask &
BehaviorRetained.WAKEUP_DEACTIVATE) != 0) {
notifyDeactivationCondition(behav);
}
scheduleList.remove(behav);
behav.active = false;
if (behav.universe != universe) {
J3dMessage m = new J3dMessage();
m.threads = J3dThread.UPDATE_BEHAVIOR;
m.type = J3dMessage.BEHAVIOR_REEVALUATE;
m.universe = behav.universe;
m.args[0] = behav;
VirtualUniverse.mc.processMessage(m);
}
}
}
final void addToScheduleList(BehaviorRetained behav) {
if (!behav.inCallback &&
!behav.active &&
behav.enable &&
behav.switchState.currentSwitchOn &&
(behav.wakeupCondition != null) &&
((Behavior) behav.source).isLive() &&
intersectVPRegion(behav.transformedRegion)) {
scheduleList.add(behav);
behav.active = true;
if ((behav.wakeupMask &
BehaviorRetained.WAKEUP_ACTIVATE) != 0) {
notifyActivationCondition(behav);
}
if (behav.wakeupCondition != null) {
// This reset the conditionMet, otherwise
// if conditionMet is true then WakeupCondition
// will never post message to BehaviorStructure
behav.wakeupCondition.conditionMet = false;
}
}
}
/**
* This prevents wakeupCondition sent out message and sets
* conditionMet to true, but the
* BehaviorStructure/BehaviorScheduler is not fast enough to
* process the message and reset conditionMet to false
* when view deactivate/unregister.
*/
void resetConditionMet() {
resetConditionMet(wakeupOnAWTEvent);
resetConditionMet(wakeupOnActivation);
resetConditionMet(wakeupOnDeactivation);
resetConditionMet(wakeupOnBehaviorPost);
resetConditionMet(wakeupOnElapsedFrames);
resetConditionMet(wakeupOnViewPlatformEntry);
resetConditionMet(wakeupOnViewPlatformExit);
resetConditionMet(wakeupOnSensorEntry);
resetConditionMet(wakeupOnSensorExit);
}
static void resetConditionMet(WakeupIndexedList list) {
WakeupCondition wakeups[] = (WakeupCondition []) list.toArray(false);
int i = list.size()-1;
while (i >= 0) {
wakeups[i--].conditionMet = false;
}
}
void reEvaluateWakeupCount() {
WakeupOnElapsedFrames wakeupConds[] = (WakeupOnElapsedFrames [])
wakeupOnElapsedFrames.toArray(true);
int size = wakeupOnElapsedFrames.arraySize();
int i = 0;
WakeupOnElapsedFrames cond;
activeWakeupOnFrameCount = 0;
while (i < size) {
cond = wakeupConds[i++];
if (!cond.passive &&
(cond.behav != null) &&
cond.behav.enable) {
activeWakeupOnFrameCount++;
}
}
activeWakeupOnSensorCount = 0;
WakeupOnSensorEntry wentry;
WakeupOnSensorEntry wentryArr[] = (WakeupOnSensorEntry [])
wakeupOnSensorEntry.toArray();
for (i=wakeupOnSensorEntry.arraySize()-1; i>=0; i--) {
wentry = wentryArr[i];
if ((wentry.behav != null) &&
(wentry.behav.enable)) {
activeWakeupOnSensorCount++;
}
}
WakeupOnSensorExit wexit;
WakeupOnSensorExit wexitArr[] = (WakeupOnSensorExit [])
wakeupOnSensorExit.toArray();
for (i=wakeupOnSensorExit.arraySize()-1; i>=0; i--) {
wexit = wexitArr[i];
if ((wexit.behav != null) &&
(wexit.behav.enable)) {
activeWakeupOnSensorCount++;
}
}
}
@Override
void cleanup() {
behaviors.clear();
viewPlatforms.clear();
scheduleList.clear();
boundsEntryList.clear();
boundsExitList.clear();
currentSensorEntryList.clear();
currentSensorExitList.clear();
wakeupOnAWTEvent.clear();
wakeupOnActivation.clear();
wakeupOnDeactivation.clear();
wakeupOnBehaviorPost.clear();
wakeupOnElapsedFrames.clear();
wakeupOnViewPlatformEntry.clear();
wakeupOnViewPlatformExit.clear();
wakeupOnSensorEntry.clear();
wakeupOnSensorExit.clear();
}
}