All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javax.media.j3d.Behavior Maven / Gradle / Ivy

/*
 * 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.Enumeration;

/**
 * The Behavior leaf node provides a framework for adding user-defined
 * actions into the scene graph.  Behavior is an abstract class that
 * defines two methods that must be overridden by a subclass: An
 * initialization method, called once when the behavior
 * becomes "live," and a processStimulus method called
 * whenever appropriate by the Java 3D behavior scheduler. The
 * Behavior node also contains an enable flag, a scheduling region,
 * a scheduling interval, and a wakeup condition.
 *
 * 

* The scheduling region defines a spatial volume that serves * to enable the scheduling of Behavior nodes. A Behavior node is * active (can receive stimuli) whenever an active ViewPlatform's * activation volume intersects a Behavior object's scheduling * region. Only active behaviors can receive stimuli. * *

* The scheduling interval defines a partial order of execution * for behaviors that wake up in response to the same wakeup condition * (that is, those behaviors that are processed at the same "time"). * Given a set of behaviors whose wakeup conditions are satisfied at * the same time, the behavior scheduler will execute all behaviors in * a lower scheduling interval before executing any behavior in a * higher scheduling interval. Within a scheduling interval, * behaviors can be executed in any order, or in parallel. Note that * this partial ordering is only guaranteed for those behaviors that * wake up at the same time in response to the same wakeup condition, * for example, the set of behaviors that wake up every frame in * response to a WakeupOnElapsedFrames(0) wakeup condition. * *

* The initialize method allows a Behavior object to * initialize its internal state and specify its initial wakeup * condition(s). Java 3D invokes a behavior's initialize code when the * behavior's containing BranchGroup node is added to the virtual * universe. Java 3D does not invoke the initialize method in a new * thread. Thus, for Java 3D to regain control, the initialize method * must not execute an infinite loop; it must return. Furthermore, a * wakeup condition must be set or else the behavior's processStimulus * method is never executed. * *

* The processStimulus method receives and processes a * behavior's ongoing messages. The Java 3D behavior scheduler invokes * a Behavior node's processStimulus method when an active ViewPlatform's * activation volume intersects a Behavior object's scheduling region * and all of that behavior's wakeup criteria are satisfied. The * processStimulus method performs its computations and actions * (possibly including the registration of state change information * that could cause Java 3D to wake other Behavior objects), * establishes its next wakeup condition, and finally exits. * A typical behavior will modify one or more nodes or node components * in the scene graph. These modifications can happen in parallel * with rendering. In general, applications cannot count on behavior * execution being synchronized with rendering. There are two * exceptions to this general rule: *

    *
  1. All modifications to scene graph objects (not including geometry * by-reference or texture by-reference) made from the * processStimulus method of a single behavior instance * are guaranteed to take effect in the same rendering frame.
  2. *
  3. All modifications to scene graph objects (not including geometry * by-reference or texture by-reference) made from the * processStimulus methods of the set of behaviors that * wake up in response to a WakeupOnElapsedFrames(0) wakeup condition * are guaranteed to take effect in the same rendering frame.
  4. *
* * Note that modifications to geometry by-reference or texture * by-reference are not guaranteed to show up in the same frame as * other scene graph changes. * *

* Code Structure *

* When the Java 3D behavior scheduler invokes a Behavior object's * processStimulus method, that method may perform any computation it * wishes. Usually, it will change its internal state and specify its * new wakeup conditions. Most probably, it will manipulate scene * graph elements. However, the behavior code can only change those * aspects of a scene graph element permitted by the capabilities * associated with that scene graph element. A scene graph's * capabilities restrict behavioral manipulation to those * manipulations explicitly allowed. * *

* The application must provide the Behavior object with references to * those scene graph elements that the Behavior object will * manipulate. The application provides those references as arguments * to the behavior's constructor when it creates the Behavior * object. Alternatively, the Behavior object itself can obtain access * to the relevant scene graph elements either when Java 3D invokes * its initialize method or each time Java 3D invokes its * processStimulus method. * *

* Behavior methods have a very rigid structure. Java 3D assumes that * they always run to completion (if needed, they can spawn * threads). Each method's basic structure consists of the following: * *

*

    *
  • Code to decode and extract references from the WakeupCondition * enumeration that caused the object's awakening.
  • *
  • Code to perform the manipulations associated with the * WakeupCondition
  • *
  • Code to establish this behavior's new WakeupCondition
  • *
  • A path to Exit (so that execution returns to the Java 3D * behavior scheduler)
  • *
* *

* WakeupCondition Object *

* A WakeupCondition object is an abstract class specialized to * fourteen different WakeupCriterion objects and to four combining * objects containing multiple WakeupCriterion objects. A Behavior * node provides the Java 3D behavior scheduler with a WakeupCondition * object. When that object's WakeupCondition has been satisfied, the * behavior scheduler hands that same WakeupCondition back to the * Behavior via an enumeration. * *

* WakeupCriterion Object *

* Java 3D provides a rich set of wakeup criteria that Behavior * objects can use in specifying a complex WakeupCondition. These * wakeup criteria can cause Java 3D's behavior scheduler to invoke a * behavior's processStimulus method whenever * *

    *
  • The center of a ViewPlatform enters a specified region
  • *
  • The center of a ViewPlatform exits a specified region
  • *
  • A behavior is activated
  • *
  • A behavior is deactivated
  • *
  • A specified TransformGroup node's transform changes
  • *
  • Collision is detected between a specified Shape3D node's * Geometry object and any other object
  • *
  • Movement occurs between a specified Shape3D node's Geometry * object and any other object with which it collides
  • *
  • A specified Shape3D node's Geometry object no longer collides * with any other object
  • *
  • A specified Behavior object posts a specific event
  • *
  • A specified AWT event occurs
  • *
  • A specified time interval elapses
  • *
  • A specified number of frames have been drawn
  • *
  • The center of a specified Sensor enters a specified region
  • *
  • The center of a specified Sensor exits a specified region
  • *
* *

* A Behavior object constructs a WakeupCriterion by constructing the * appropriate criterion object. The Behavior object must provide the * appropriate arguments (usually a reference to some scene graph * object and possibly a region of interest). Thus, to specify a * WakeupOnViewPlatformEntry, a behavior would specify the region that * will cause the behavior to execute if an active ViewPlatform enters it. * *

* Note that a unique WakeupCriterion object must be used with each * instance of a Behavior. Sharing wakeup criteria among different * instances of a Behavior is illegal. * *

* Additional Information *

* For more information, see the * Introduction to the Java 3D API and * Behaviors and Interpolators * documents. * * @see WakeupCondition */ public abstract class Behavior extends Leaf { /** * Constructs a Behavior node with default parameters. The default * values are as follows: *

    * enable flag : true
    * scheduling bounds : null
    * scheduling bounding leaf : null
    * scheduling interval : numSchedulingIntervals / 2
    *
*/ public Behavior() { } /** * Initialize this behavior. Classes that extend Behavior must * provide their own initialize method. *
* NOTE: Applications should not call this method. It is called * by the Java 3D behavior scheduler. */ public abstract void initialize(); /** * Process a stimulus meant for this behavior. This method is invoked * if the Behavior's wakeup criteria are satisfied and an active * ViewPlatform's * activation volume intersects with the Behavior's scheduling region. * Classes that extend Behavior must provide their own processStimulus * method. *
* NOTE: Applications should not call this method. It is called * by the Java 3D behavior scheduler. * @param criteria an enumeration of triggered wakeup criteria for this * behavior */ public abstract void processStimulus(Enumeration criteria); /** * Set the Behavior's scheduling region to the specified bounds. * This is used when the scheduling bounding leaf is set to null. * @param region the bounds that contains the Behavior's new scheduling * region */ public void setSchedulingBounds(Bounds region) { ((BehaviorRetained)this.retained).setSchedulingBounds(region); } /** * Retrieves the Behavior node's scheduling bounds. * @return this Behavior's scheduling bounds information */ public Bounds getSchedulingBounds() { return ((BehaviorRetained)this.retained).getSchedulingBounds(); } /** * Set the Behavior's scheduling region to the specified bounding leaf. * When set to a value other than null, this overrides the scheduling * bounds object. * @param region the bounding leaf node used to specify the Behavior * node's new scheduling region */ public void setSchedulingBoundingLeaf(BoundingLeaf region) { ((BehaviorRetained)this.retained).setSchedulingBoundingLeaf(region); } /** * Retrieves the Behavior node's scheduling bounding leaf. * @return this Behavior's scheduling bounding leaf information */ public BoundingLeaf getSchedulingBoundingLeaf() { return ((BehaviorRetained)this.retained).getSchedulingBoundingLeaf(); } /** * Creates the retained mode BehaviorRetained object that this * Behavior object will point to. */ @Override void createRetained() { this.retained = new BehaviorRetained(); this.retained.setSource(this); } /** * Defines this behavior's wakeup criteria. This method * may only be called from a Behavior object's initialize * or processStimulus methods to (re)arm the next wakeup. * It should be the last thing done by those methods. * @param criteria the wakeup criteria for this behavior * @exception IllegalStateException if this method is called by * a method other than initialize or processStimulus */ protected void wakeupOn(WakeupCondition criteria) { BehaviorRetained behavret = (BehaviorRetained) this.retained; synchronized (behavret) { if (!behavret.inCallback) { throw new IllegalStateException(J3dI18N.getString("Behavior0")); } } behavret.wakeupOn(criteria); } /** * Retrieves this behavior's current wakeup condition as set by * the wakeupOn method. If no wakeup condition is currently * active, null will be returned. In particular, this means that * null will be returned if Java 3D is executing this behavior's * processStimulus routine and wakeupOn has not yet been called to * re-arm the wakeup condition for next time. * * @return the current wakeup condition for this behavior * * @since Java 3D 1.3 */ protected WakeupCondition getWakeupCondition() { return ((BehaviorRetained)this.retained).getWakeupCondition(); } /** * Posts the specified postId to the Behavior Scheduler. All behaviors * that have registered WakeupOnBehaviorPost with this postId, or a postId * of 0, and with this behavior, or a null behavior, will have that wakeup * condition met. *

* This feature allows applications to send arbitrary events into the * behavior scheduler stream. It can be used as a notification scheme * for communicating events to behaviors in the system. *

* @param postId the Id being posted * * @see WakeupOnBehaviorPost */ public void postId(int postId){ ((BehaviorRetained)this.retained).postId(postId); } /** * Enables or disables this Behavior. The default state is enabled. * @param state true or false to enable or disable this Behavior */ public void setEnable(boolean state) { ((BehaviorRetained)this.retained).setEnable(state); } /** * Retrieves the state of the Behavior enable flag. * @return the Behavior enable state */ public boolean getEnable() { return ((BehaviorRetained)this.retained).getEnable(); } /** * Returns the number of scheduling intervals supported by this * implementation of Java 3D. The minimum number of supported * intervals must be at least 10. The default scheduling interval * for each behavior instance is set to * numSchedulingIntervals / 2. * * @return the number of supported scheduling intervals * * @since Java 3D 1.3 */ public static int getNumSchedulingIntervals() { return BehaviorRetained.NUM_SCHEDULING_INTERVALS; } /** * Sets the scheduling interval of this Behavior node to the * specified value. * * The scheduling interval defines a partial order of execution * for behaviors that wake up in response to the same wakeup * condition (that is, those behaviors that are processed at the * same "time"). Given a set of behaviors whose wakeup conditions * are satisfied at the same time, the behavior scheduler will * execute all behaviors in a lower scheduling interval before * executing any behavior in a higher scheduling interval. Within * a scheduling interval, behaviors can be executed in any order, * or in parallel. Note that this partial ordering is only * guaranteed for those behaviors that wake up at the same time in * response to the same wakeup condition, for example, the set of * behaviors that wake up every frame in response to a * WakeupOnElapsedFrames(0) wakeup condition. * * The default value is numSchedulingIntervals / 2. * * @param schedulingInterval the new scheduling interval * * @exception IllegalArgumentException if * schedulingInterval < 0 or * schedulingInterval >= * numSchedulingIntervals * * @since Java 3D 1.3 */ public void setSchedulingInterval(int schedulingInterval) { if (schedulingInterval < 0 || schedulingInterval >= getNumSchedulingIntervals()) { throw new IllegalStateException(J3dI18N.getString("Behavior1")); } ((BehaviorRetained)this.retained). setSchedulingInterval(schedulingInterval); } /** * Retrieves the current scheduling interval of this Behavior * node. * * @return the current scheduling interval * * @since Java 3D 1.3 */ public int getSchedulingInterval() { return ((BehaviorRetained)this.retained).getSchedulingInterval(); } /** * Returns the primary view associated with this behavior. This method * is useful with certain types of behaviors (e.g., Billboard, LOD) that * rely on per-View information and with behaviors in general in regards * to scheduling (the distance from the view platform determines the * active behaviors). The "primary" view is defined to be the first * View attached to a live ViewPlatform, if there is more than one active * View. So, for instance, Billboard behaviors would be oriented toward * this primary view, in the case of multiple active views into the same * scene graph. */ protected View getView() { return ((BehaviorRetained)this.retained).getView(); } /** * Copies all Behavior information from * originalNode into * the current node. This method is called from the * cloneNode method which is, in turn, called by the * cloneTree method.

* * @param originalNode the original node to duplicate * @param forceDuplicate when set to true, causes the * duplicateOnCloneTree flag to be ignored. When * false, the value of each node's * duplicateOnCloneTree variable determines whether * NodeComponent data is duplicated or copied. * * @exception RestrictedAccessException if this object is part of a live * or compiled scenegraph. * * @see Node#duplicateNode * @see Node#cloneTree * @see NodeComponent#setDuplicateOnCloneTree */ @Override void duplicateAttributes(Node originalNode, boolean forceDuplicate) { super.duplicateAttributes(originalNode, forceDuplicate); BehaviorRetained attr = (BehaviorRetained) originalNode.retained; BehaviorRetained rt = (BehaviorRetained) retained; rt.setEnable(attr.getEnable()); rt.setSchedulingBounds(attr.getSchedulingBounds()); rt.setSchedulingInterval(attr.getSchedulingInterval()); // will set to the correct one in updateNodeReferences rt.setSchedulingBoundingLeaf(attr.getSchedulingBoundingLeaf()); } /** * Callback used to allow a node to check if any scene graph objects * referenced * by that node have been duplicated via a call to cloneTree. * This method is called by cloneTree after all nodes in * the sub-graph have been duplicated. The cloned Leaf node's method * will be called and the Leaf node can then look up any object references * by using the getNewObjectReference method found in the * NodeReferenceTable object. If a match is found, a * reference to the corresponding object in the newly cloned sub-graph * is returned. If no corresponding reference is found, either a * DanglingReferenceException is thrown or a reference to the original * object is returned depending on the value of the * allowDanglingReferences parameter passed in the * cloneTree call. *

* NOTE: Applications should not call this method directly. * It should only be called by the cloneTree method. * * @param referenceTable a NodeReferenceTableObject that contains the * getNewObjectReference method needed to search for * new object instances. * * @see NodeReferenceTable * @see Node#cloneTree * @see DanglingReferenceException */ @Override public void updateNodeReferences(NodeReferenceTable referenceTable) { super.updateNodeReferences(referenceTable); BehaviorRetained rt = (BehaviorRetained) retained; BoundingLeaf bl= rt.getSchedulingBoundingLeaf(); // check for schedulingBoundingLeaf if (bl != null) { Object o = referenceTable.getNewObjectReference(bl); rt.setSchedulingBoundingLeaf((BoundingLeaf) o); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy