Since this is not considered a bug because the API does not specify order importance,  
I
believe that the below explanation or other should be inserted into the API 
documentation in
the appropriate place.

Realize, of course, that this is a VERY significant issue, because a large set of apps 
will
move the view based on some other objects motion, for example, practically every game 
developer
that tries to use Java3D!  Not every 3D app uses head-tracking...in fact almost none 
do.

If Java3D cannot guarantee some kind of execution order then this effectively means 
that many
Java3D apps should NOT use the Java3D behavior system at all, which is exactly what we 
had to
do for our apps.


Kelvin Chung wrote:

> Hi,
>
>    To better understand this problem, let's take a look at
> the simply version has only one behavior to both rotate
> the cube and modify the camera viewpoint so that
> we expect the cube appear stationary. This example is modify
> from HelloUniverse example.
>
> If we write the behavior in this way :
>
>   public void processStimulus(Enumeration criteria) {
>     Modify Camera View point using the object transform
>     Modify Object transform as in RotationInterpolator
>   }
>
> Using J3D v1.2 we will see the cube jitters
> (more serious under windows than solaris).
>
> However if we write the behavior in this way :
>
>
>  public void processStimulus(Enumeration criteria) {
>     Modify Object transform as in RotationInterpolator
>     Modify Camera View point using object transform
>
> }
>
> There is NO jitter at all under both platform.
>
> In fact you will also see the cube jitter
> when using J3D 1.1.3 under windows.
>
> This is not a bug. Here is the explanation :
>
> -------------------
> The object transform that that camera view point get is
> ONE frame before what RotationInterpolator is about to
> be set. If the timing of frame is equal between every
> successive processStimulus() invocation. Then the
> different between the alpha values of rotation interpolator
> get from one frame to another should be the same and you
> will always see the same offset from the camera to the cube.
> i.e. the cube appear did not move at all without any jitter.
>
> However, in reality the interval processStimulus() is invoked
> is not exactly the same from frame to frame. It all depends
> on the OS scheduling. So the offset of view from camera to
> the cube may varies from frame to frame and you will see the
> cube jitters all the time. This phenomenon is more obvious
> under windows than sparc solaris - the later has finer time
> resolution and better scheduling. Thats why you may
> see the program run fine under solaris but jitter under windows.
>
> To solve the problem, the user behavior has to ganrantee
> that the transform set by the camera and the cube are the
> in sync by putting them in a single behaviors and same
> transform is apply to interpolators first if it is need
> to compute the camera viewpoint.
>
> --------------
>
> In the two example programs given (attach in the email),
> there are two behaviors :
>
> (A) Modify the object transformation matrix using some
>     kinds of Interpolator.
> (B) Read back the transform matrix (which is modify by A)
>     and use it to transform camea under View
>
> If behavior A is always schedule to run before behavior B
> in Java3D, you will not see any jitter. However there is
> no gaurantee for the order of behaviors execute under Java3D.
> So you may see (A) run before (B) or (B) run befores (A)
> or (A)&(B) may run in parallel if there are two CPU in your system.
>
> Currently there is no API to gaurantee order of behaviors running
> in Java3D. The solution is to make sure if camera viewpoint
> transformation matrix depends on result of other behaviors,
> we should put them in a single behavior to sync both
> transform.
>
> Attach is a program modify from the original CameraFollow
> behavior to see how it works. Running this program in
> both windows & solaris and you wouldn't see the jitter.
>
> Thanks.
>
> - Kelvin
> -----------------
> Java 3D Team
> Sun Microsystems Inc.
>
>   ------------------------------------------------------------------------
>
> Subject: Message from mail server
> Date: Mon, 26 Jun 2000 17:59:25 -0700 (PDT)
> From: Postmaster
>
> Delete.
> This is a system message.
>
> --END+PSEUDO--
>
> >From [EMAIL PROTECTED]  Sat Apr  8 10:58:36 2000
> X-Unix-From: [EMAIL PROTECTED]  Sat Apr  8 10:58:36 2000
> Return-Path: <[EMAIL PROTECTED]>
> Received: from engmail4.Eng.Sun.COM by ha3mpk.eng.sun.com (8.8.8+Sun/SMI-SVR4)
>         id KAA03610; Sat, 8 Apr 2000 10:58:20 -0700 (PDT)
> Received: from venus.Sun.COM (venus.EBay.Sun.COM [129.150.69.5])
>         by engmail4.Eng.Sun.COM (8.9.1b+Sun/8.9.1/ENSMAIL,v1.6) with ESMTP id 
>KAA01181;
>         Sat, 8 Apr 2000 10:58:20 -0700 (PDT)
> Received: from mail2.java.sun.com (mail2.javasoft.com [204.160.241.38])
>         by venus.Sun.COM (8.9.3+Sun/8.9.3) with ESMTP id KAA18644;
>         Sat, 8 Apr 2000 10:58:18 -0700 (PDT)
> Received: from mail (mail.javasoft.com [204.160.241.28])
>         by mail2.java.sun.com (8.10.0.Beta13+Sun/8.10.0.Beta13) with ESMTP id 
>e38HqYb29923;
>         Sat, 8 Apr 2000 10:52:34 -0700 (PDT)
> Received: from JAVA.SUN.COM by JAVA.SUN.COM (LISTSERV-TCP/IP release 1.8d) with
>           spool id 7666503 for [EMAIL PROTECTED]; Sat, 8 Apr 2000
>           10:52:54 -0700
> Received: from indyio.rz.uni-sb.de (indyio.rz.uni-sb.de [134.96.7.3]) by
>           mail.java.sun.com (8.10.0.Beta13+Sun/8.10.0.Beta13) with ESMTP id
>           e38Hqqd07575 for <[EMAIL PROTECTED]>; Sat, 8 Apr 2000
>           10:52:52 -0700 (PDT)
> Received: from sbustd.stud.uni-sb.de
>           (IDENT:[EMAIL PROTECTED]
>           [134.96.7.8]) by indyio.rz.uni-sb.de (8.9.3/8.9.3) with ESMTP id
>           TAA3229414 for <[EMAIL PROTECTED]>; Sat, 8 Apr 2000
>           19:51:52 +0200 (CST)
> Received: from marco (maxtnt-028.telip.uni-sb.de [134.96.70.155]) by
>           sbustd.stud.uni-sb.de (8.9.3/8.9.3) with SMTP id TAA06676 for
>           <[EMAIL PROTECTED]>; Sat, 8 Apr 2000 19:51:51 +0200 (CST)
> MIME-Version: 1.0
> Content-Type: multipart/mixed;
>               boundary="----=_NextPart_000_0011_01BFA195.1B426B80"
> X-Priority: 3
> X-MSMail-Priority: Normal
> X-Mailer: Microsoft Outlook Express 5.00.2615.200
> X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2615.200
> Message-ID:  <001401bfa184$5816afa0$9b466086@marco>
> Date:         Sat, 8 Apr 2000 20:00:36 +0200
> Reply-To: Discussion list for Java 3D API <[EMAIL PROTECTED]>
> Sender: Discussion list for Java 3D API <[EMAIL PROTECTED]>
> From: Marco Lohse <[EMAIL PROTECTED]>
> Subject:      [JAVA3D] LookAtBehavior
> To: [EMAIL PROTECTED]
> Content-Length: 9379
> Status: RO
> X-Status: $$$$
> X-UID: 0000000001
>
> This is a multi-part message in MIME format.
>
> ------=_NextPart_000_0011_01BFA195.1B426B80
> Content-Type: text/plain;
>         charset="iso-8859-1"
> Content-Transfer-Encoding: 7bit
>
> Hi,
> I just wrote some code which might be interesting for some of you. It is a
> behavior which updates a TransformGroup so that you will always look at
> another moving object. Attached is a simple example with a bouncing sphere
> which is always followed by the camera. Unfortunately, this animation is
> really jerky. Any help or comments to make this code faster would be very
> helpful.
>
> Regards,
> Marco.
>
> ------=_NextPart_000_0011_01BFA195.1B426B80
> Content-Type: application/octet-stream;
>         name="LookAtBehavior.java"
> Content-Transfer-Encoding: quoted-printable
> Content-Disposition: attachment;
>         filename="LookAtBehavior.java"
>
> import javax.media.j3d.*;
> import javax.vecmath.*;
> import java.util.Enumeration;
>
> /**
>  * This Behavior can be used to keep looking at a specific object. =20
>  * @author Marco Lohse
>  * @version 0.1
>  */
> public class LookAtBehavior extends Behavior
> {
>   // behavior=20
>   private WakeupCriterion[] wakeupCriterions;
>   private WakeupOr          wakeupOr;
>   private WakeupOnTransformChange criterion;
>
>   // the watchingTarget will change in response to the=20
>   // movingTarget=B4s changes
>   protected TransformGroup watchingTarget;
>   protected TransformGroup movingTarget;
>
>   // objects for computations
>   private Transform3D trans1 =3D new Transform3D();
>   private Transform3D trans2 =3D new Transform3D();
>   private Transform3D trans3 =3D new Transform3D();
>   private Point3d point1 =3D new Point3d();
>   private Point3d point2 =3D new Point3d();
>   private Vector3d translation1 =3D new Vector3d();
>   private Vector3d translation2 =3D new Vector3d();
>   private Vector3d up           =3D new Vector3d(0, 1, 0);
>  =20
>  /**
>   * Creates a behavior which will update one TransformGroup=B4s =
> Transform3D=20
>   * in response to changes of the other TransformGroup=B4s Transform3D.=20
>   * @param t1 this TransformGroup=B4s Transform3D object will be updated
>   * @param t2 this TransformGroup=B4s Transform3D=B4s translational =
> component will be used
>   * @param bounds bounding volume for this behavior
>   */=20
>   public LookAtBehavior(TransformGroup t1, TransformGroup t2, Bounds =
> bounds)=20
>   {
>     if(t1.getCapability(TransformGroup.ALLOW_TRANSFORM_WRITE) &&
>        t1.getCapability(TransformGroup.ALLOW_TRANSFORM_READ)  &&
>        t2.getCapability(TransformGroup.ALLOW_TRANSFORM_READ))=20
>     {
>       watchingTarget =3D t1;
>       movingTarget =3D t2;
>  =20
>       wakeupCriterions =3D new WakeupCriterion[1];
>       criterion =3D new WakeupOnTransformChange(movingTarget);
>  =20
>       this.setSchedulingBounds(bounds);
>      =20
>       // setup watchingTarget to look at movingTarget
>       watchingTarget.getTransform(trans1);
>       movingTarget.getTransform(trans2);
>       trans1.get(translation1);
>       trans2.get(translation2);
>       if(!translation1.equals(translation2)) {
>         point1.set(translation1);
>         point2.set(translation2);
>         trans3.lookAt(point1, point2, up);
>         trans3.invert();
>         watchingTarget.setTransform(trans3);
>       }
>     }
>     else {
>       throw new RestrictedAccessException("first parameter needs to have =
> TransformGroup.ALLOW_TRANSFORM_WRITE and =
> TransformGroup.ALLOW_TRANSFORM_READ, second parameter needs =
> TransformGroup.ALLOW_TRANSFORM_READ");
>     }
>   }
>
>   public void initialize()
>   {
>     // set initial wakeup condition
>     wakeupCriterions[0] =3D criterion;
>     wakeupOr =3D new WakeupOr(wakeupCriterions);
>     this.wakeupOn(wakeupOr);
>   }
>
>   // called by Java 3D when appropriate stimulus occures
>   public void processStimulus(Enumeration criteria)
>   {
>     // setup watchingTarget to look at movingTarget
>     if(criterion.hasTriggered()) {
>       watchingTarget.getTransform(trans1);
>       movingTarget.getTransform(trans2);
>       trans1.get(translation1);
>       trans2.get(translation2);
>       if(!translation1.equals(translation2)) {
>         point1.set(translation1);
>         point2.set(translation2);
>         trans3.lookAt(point1, point2, up);
>         trans3.invert();
>         watchingTarget.setTransform(trans3);
>       }
>     }
>
>     this.wakeupOn(wakeupOr);
>   }
> }
> ------=_NextPart_000_0011_01BFA195.1B426B80
> Content-Type: application/octet-stream;
>         name="HelloUniverse.java"
> Content-Transfer-Encoding: quoted-printable
> Content-Disposition: attachment;
>         filename="HelloUniverse.java"
>
> import java.applet.Applet;=0A=
> import java.awt.BorderLayout;=0A=
> import java.awt.event.*;=0A=
> import java.awt.GraphicsConfiguration;=0A=
> import com.sun.j3d.utils.applet.MainFrame;=0A=
> import com.sun.j3d.utils.geometry.Sphere;=0A=
> import com.sun.j3d.utils.universe.*;=0A=
> import javax.media.j3d.*;=0A=
> import javax.vecmath.*;=0A=
> =0A=
> public class HelloUniverse extends Applet {=0A=
> Shape3D createLand(){=0A=
>         LineArray landGeom =3D new LineArray(44, =
> GeometryArray.COORDINATES=0A=
>                                             | GeometryArray.COLOR_3);=0A=
>         float l =3D -50.0f;=0A=
>         for(int c =3D 0; c < 44; c+=3D4){=0A=
> =0A=
>             landGeom.setCoordinate( c+0, new Point3f( -50.0f, 0.0f,  l =
> ));=0A=
>             landGeom.setCoordinate( c+1, new Point3f(  50.0f, 0.0f,  l =
> ));=0A=
>             landGeom.setCoordinate( c+2, new Point3f(   l   , 0.0f, =
> -50.0f ));=0A=
>             landGeom.setCoordinate( c+3, new Point3f(   l   , 0.0f,  =
> 50.0f ));=0A=
>             l +=3D 10.0f;=0A=
>         }=0A=
> =0A=
>         Color3f c =3D new Color3f(0.1f, 0.8f, 0.1f);=0A=
>         for(int i =3D 0; i < 44; i++) landGeom.setColor( i, c);=0A=
> =0A=
>         return new Shape3D(landGeom);=0A=
>     }=0A=
> =0A=
>     public void createSceneGraph() {=0A=
>   // Create the root of the branch graph=0A=
>   BranchGroup objRoot =3D new BranchGroup();=0A=
> =0A=
>   // Create the transform group node and initialize it to the=0A=
>   // identity.  Enable the TRANSFORM_WRITE capability so that=0A=
>   // our behavior code can modify it at runtime.  Add it to the=0A=
>   // root of the subgraph.=0A=
>   TransformGroup objTrans =3D new TransformGroup();=0A=
>   objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);=0A=
>   objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);=0A=
>   objRoot.addChild(objTrans);=0A=
> =0A=
>   objRoot.addChild(createLand());=0A=
>   =0A=
>   BoundingSphere bounds =3D=0A=
>       new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);=0A=
>     // Set up the global lights=0A=
>   Color3f lColor1 =3D new Color3f(0.7f, 0.7f, 0.7f);=0A=
>   Vector3f lDir1  =3D new Vector3f(-1.0f, -1.0f, -1.0f);=0A=
>   Color3f alColor =3D new Color3f(0.8f, 0.8f, 0.8f);=0A=
>   AmbientLight aLgt =3D new AmbientLight(alColor);=0A=
>   aLgt.setInfluencingBounds(bounds);=0A=
>   DirectionalLight lgt1 =3D new DirectionalLight(lColor1, lDir1);=0A=
>   lgt1.setInfluencingBounds(bounds);=0A=
>   objRoot.addChild(aLgt);=0A=
>   objRoot.addChild(lgt1);=0A=
> =0A=
>   // Create a simple shape leaf node, add it to the scene graph.=0A=
>   Appearance app =3D new Appearance();=0A=
>   app.setMaterial(new Material());=0A=
>   objTrans.addChild(new Sphere(2.0f, app));=0A=
> =0A=
>   Transform3D yAxis =3D new Transform3D();=0A=
>   Alpha alpha =3D new Alpha(-1, Alpha.INCREASING_ENABLE | =
> Alpha.DECREASING_ENABLE,=0A=
>           0, 0,=0A=
>           20000, 500, 200,=0A=
>           20000, 500, 200);=0A=
> =0A=
>   float knots[] =3D { 0.0f, 0.25f, 0.5f, 0.75f, 1.0f };=0A=
>   Point3f positions[] =3D { new Point3f(-20,0,0), new Point3f(0,10,0), =0A=
>     new Point3f(20f,0f,0f), new Point3f(0f,10f,20f), new =
> Point3f(0f,0f,20f) };=0A=
>           =0A=
>   PositionPathInterpolator interp =3D new PositionPathInterpolator(=0A=
>     alpha,=0A=
>     objTrans,=0A=
>     new Transform3D(),=0A=
>     knots,=0A=
>     positions);=0A=
>   interp.setSchedulingBounds(bounds);=0A=
>   objTrans.addChild(interp);=0A=
>   =0A=
>   =0A=
> =0A=
>         GraphicsConfiguration config =3D=0A=
>            SimpleUniverse.getPreferredConfiguration();=0A=
>   Canvas3D c =3D new Canvas3D(config);=0A=
>   add("Center", c);=0A=
>         =0A=
>         =0A=
>   // Create a simple scene and attach it to the virtual universe=0A=
>   SimpleUniverse u =3D new SimpleUniverse(c);=0A=
> =0A=
> =0A=
>   Transform3D trans =3D new Transform3D();=0A=
>   trans.set(new Vector3f(30,10,-10));=0A=
>   u.getViewingPlatform().getViewPlatformTransform().setTransform(trans);=0A=
>   =0A=
>   LookAtBehavior look =3D new =
> LookAtBehavior(u.getViewingPlatform().getViewPlatformTransform(),=0A=
>          objTrans,=0A=
>          bounds);=0A=
> =0A=
>       objRoot.addChild(look);=0A=
>         // Have Java 3D perform optimizations on this scene graph.=0A=
>         objRoot.compile();=0A=
>          u.addBranchGraph(objRoot);=0A=
> =0A=
>     }=0A=
> =0A=
>     public HelloUniverse() {=0A=
>   setLayout(new BorderLayout());=0A=
> =0A=
>   createSceneGraph();=0A=
> =0A=
>     }=0A=
> =0A=
>     //=0A=
>     // The following allows HelloUniverse to be run as an application=0A=
>     // as well as an applet=0A=
>     //=0A=
>     public static void main(String[] args) {=0A=
>   new MainFrame(new HelloUniverse(), 256, 256);=0A=
>     }=0A=
> }=0A=
>
> ------=_NextPart_000_0011_01BFA195.1B426B80--
>
> ===========================================================================
> To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
> of the message "signoff JAVA3D-INTEREST".  For general help, send email to
> [EMAIL PROTECTED] and include in the body of the message "help".
>
>   ------------------------------------------------------------------------
>
> Subject: Message from mail server
> Date: Mon, 26 Jun 2000 18:00:37 -0700 (PDT)
> From: Postmaster
>
> Delete.
> This is a system message.
>
> --END+PSEUDO--
>
> >From [EMAIL PROTECTED]  Mon Apr  3 18:55:08 2000
> X-Unix-From: [EMAIL PROTECTED]  Mon Apr  3 18:55:08 2000
> Return-Path: <[EMAIL PROTECTED]>
> Received: from engmail3.Eng.Sun.COM by ha3mpk.eng.sun.com (8.8.8+Sun/SMI-SVR4)
>         id SAA16210; Mon, 3 Apr 2000 18:55:07 -0700 (PDT)
> Received: from lukla.Sun.COM (lukla.Central.Sun.COM [129.147.5.31])
>         by engmail3.Eng.Sun.COM (8.9.1b+Sun/8.9.1/ENSMAIL,v1.6) with ESMTP id 
>SAA21037;
>         Mon, 3 Apr 2000 18:55:01 -0700 (PDT)
> Received: from mail2.javasoft.com (mail2.javasoft.com [204.160.241.38])
>         by lukla.Sun.COM (8.9.3+Sun/8.9.3) with ESMTP id TAA16629;
>         Mon, 3 Apr 2000 19:54:58 -0600 (MDT)
> Received: from mail (mail.javasoft.com [204.160.241.28])
>         by mail2.javasoft.com (8.10.0.Beta13+Sun/8.10.0.Beta13) with ESMTP id 
>e341mrS00893;
>         Mon, 3 Apr 2000 18:48:53 -0700 (PDT)
> Received: from JAVA.SUN.COM by JAVA.SUN.COM (LISTSERV-TCP/IP release 1.8d) with
>           spool id 7654023 for [EMAIL PROTECTED]; Mon, 3 Apr 2000
>           18:49:11 -0700
> Received: from smtp6.mindspring.com (smtp6.mindspring.com [207.69.200.110]) by
>           mail.java.sun.com (8.10.0.Beta13+Sun/8.10.0.Beta13) with ESMTP id
>           e341n8H14361 for <[EMAIL PROTECTED]>; Mon, 3 Apr 2000
>           18:49:08 -0700 (PDT)
> Received: from default (user-2ivebp1.dialup.mindspring.com [165.247.47.33]) by
>           smtp6.mindspring.com (8.9.3/8.8.5) with SMTP id VAA07600 for
>           <[EMAIL PROTECTED]>; Mon, 3 Apr 2000 21:48:07 -0400 (EDT)
> MIME-Version: 1.0
> Content-Type: text/plain; charset="iso-8859-1"
> Content-Transfer-Encoding: 7bit
> X-Priority: 3 (Normal)
> X-MSMail-Priority: Normal
> X-Mailer: Microsoft Outlook 8.5, Build 4.71.2173.0
> X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2314.1300
> Importance: Normal
> Message-ID:  <000301bf9dd6$e86ec940$151bf7a5@default>
> Date:         Mon, 3 Apr 2000 21:41:32 -0400
> Reply-To: Discussion list for Java 3D API <[EMAIL PROTECTED]>
> Sender: Discussion list for Java 3D API <[EMAIL PROTECTED]>
> From: Marvin Chase <[EMAIL PROTECTED]>
> Subject:      Re: [JAVA3D] View and Scene synchronization bug still in Beta2
> To: [EMAIL PROTECTED]
> In-Reply-To:  <[EMAIL PROTECTED]>
> Content-Length: 3907
> Status: RO
> X-Status: $$$$
> X-UID: 0000000001
>
> I agree,
>
> For the application I am writing It is very important that the influence of
> each behavior be merged into the subsequent animation frame, and unless
> everyone else is frantically creating new behavior objects for each
> different type of motion they need, the current API won't perform
> satisfactorily for anything but the simplest of applications.
>
> The use of a tree scene graph structure in J3D suggests that the influence
> of each transform above a specified node (regardless of how many behaviors
> are attached the parent transforms) will be merged to produce the resultant
> behavior.  If the influence of a behavior on any of the parent transforms is
> not realized in the next frame, why even have multiple transforms or
> behaviors in an application.  The animation will always be out of sync.
>
> I, like many other users I'm sure, assumed that issues related to behavior
> scheduling and influence would be cleared up eventually.  If they are not,
> J3D will not be a realistic tool for gaming nor for many other animation
> applications.
>
> -----Original Message-----
> From: Discussion list for Java 3D API
> [mailto:[EMAIL PROTECTED]]On Behalf Of Shawn Kendall
> Sent: Monday, April 03, 2000 1:38 PM
> To: [EMAIL PROTECTED]
> Subject: Re: [JAVA3D] View and Scene synchronization bug still in Beta2
>
> Kelvin Chung wrote:
>
> > Hi Shawn,
> >
> > >>    The synchronization bug 4313347 is fixed in FCS release.
> > >> However it is too late for us to make it into the upcoming v1.2beta2.
> > >>
> > >>    In FCS release, you will see that the view is
> > >> much less jitter than before. But there is still a little bit jitter
> > >> sometime, since Java 3D spec. don't gurantee the result of the update
> in
> > >> two different behaviors will reflect in the same frame at the same
> time.
> > >
> > >Ok, that's great to hear.  So, as long as ALL of a scene's updates happen
> in
> > >only ONE behavior, we can have true frame synchronization.  is that
> correct?
> > >
> >
> > Yes it is correct.
>
> This is a serious core problem with Java3D IMHO.  For many applications
> there
> must be a way to guarantee that all behaviors in a scene are updated before
> the
> scene is drawn.  For certain animations, camera motion, etc., the playback
> must
> be on a per frame basis.  At ANY frame rate, the savvy user will detect it
> if it
> is not.  The only  solution I can see is nothing short of replacing the
> entire
> Java3D behavior framework with our own!
>
> Also, what is to guarantee that ANY behavior is updated before the scene is
> drawn.  I mean if two different behaviors aren't, why would one Behavior
> work?
> I don't believe it would.  Is the only guaranteed way to create frame sync
> to
> inherit from Canvas3D and do updates in PreRender perhaps?
>
> Does this matter to anyone else out there?  I can't imagine this not being
> VERY
> important to many users... In gaming, we must have this to perform
> correctly.
> Some engines out there are time based, most are still frame based and will
> be
> for a long time.  It all depends on the game.
>
> --
> __________________________________________________________
>
> Shawn Kendall               Full Sail Real World Education
> Course Director             3300 University BLVD
> Real Time 3D for Gaming     Winter Park FL 32792
> [EMAIL PROTECTED]       http://www.fullsail.com
> __________________________________________________________
>
> ===========================================================================
> To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
> of the message "signoff JAVA3D-INTEREST".  For general help, send email to
> [EMAIL PROTECTED] and include in the body of the message "help".
>
> ===========================================================================
> To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
> of the message "signoff JAVA3D-INTEREST".  For general help, send email to
> [EMAIL PROTECTED] and include in the body of the message "help".
>
>   ------------------------------------------------------------------------
> import javax.vecmath.*;
> import javax.media.j3d.*;
> import java.util.*;
>
> /*
> This class is a behavior that is meant to be used for creating
> a "following" camera effect.
> Every update (elapsed frame 0) it copies and store the targets matrix
> in a buffer, then sets it own tranform from the end of the buffer.
> The effect is a view chasing or following of the target transform.
> However, if the buffer size is set to 1, then the offset is the only
> difference between the target transform and the output transfrom
> */
>
> public class CameraFollow extends Behavior
> {
>     WakeupCondition wake = new WakeupOnElapsedFrames(0);
>     public TransformGroup targetTG = null;
>     public TransformGroup cameraTG = null;
>     Transform3D tr3d = new Transform3D();
>     Matrix4d offsetMat = new Matrix4d();
>     final int MAX_BUFFER = 1;
>     Matrix4d[] mat = new Matrix4d[MAX_BUFFER];
>
>     int queueCount = 0;
>     int lagCount = 0;
>     Alpha alpha;
>     Transform3D axis = new Transform3D();
>     Transform3D axisInverse = new Transform3D();
>     TransformGroup target;
>     float minimumAngle ;
>     float maximumAngle ;
>
>     Transform3D rotation = new Transform3D();
>     Transform3D temp = new Transform3D();
>
>     public CameraFollow(TransformGroup objTrans) {
>         super();
>         target = objTrans;
>         alpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
>                                   0, 0,
>                                   4000, 0, 0,
>                                   0, 0, 0);
>         axisInverse.invert(axis);
>         minimumAngle = 0.0f;
>         maximumAngle = (float) (Math.PI*2.0f);
>
>     }
>
>     public void initialize()
>     {
>         for ( int i = 0; i<MAX_BUFFER ; i++ )
>         {
>             mat[i] = new Matrix4d();
>             mat[i].setIdentity();
>         }
>         offsetMat.setIdentity();
>         offsetMat.setTranslation( new Vector3d( 0.0f, 0.5f, 3.0f ) );
>         wakeupOn(wake);
>
>     }
>
>     public void processStimulus(Enumeration criteria)
>     {
>
>         // Perform the function of RotationInterpolator
>         if (alpha != null) {
>             float value = this.alpha.value();
>             double val = (1.0-value)*minimumAngle + value*maximumAngle;
>             /* construct a Transform3D from:  axis * rotation * axisInverse  */
>             rotation.rotY(val);
>
>             temp.mul(axis, rotation);
>             temp.mul(temp, axisInverse);
>
>             target.setTransform(temp);
>         }
>
>
>
>         // Transform the Camera view point
>         if ( cameraTG != null )
>         {
>             if ( targetTG != null )
>             {
>                 targetTG.getTransform(tr3d);
>
>                 // Copy the targets matrix to the buffer
>                 tr3d.get(mat[queueCount]);
>
>                 //lagCount = queueCount + 1;
>                 //if ( lagCount >= MAX_BUFFER )
>                 //    lagCount = 0;
>
>                 // Multiple in the view offset
>                 mat[lagCount].mul( offsetMat );
>
>                 tr3d.set(mat[lagCount]);
>
>                 // Finally, set the transfrom above the ViewPlatform
>                 cameraTG.setTransform( tr3d );
>
>                 //queueCount++;
>                 //if ( queueCount >= MAX_BUFFER )
>                 //    queueCount = 0;
>             }
>         }
>
>         wakeupOn(wake);
>     }
> }
>
>   ------------------------------------------------------------------------
> /*
>  *      @(#)HelloUniverse.java 1.47 99/09/15 13:36:59
>  *
>  * Copyright (c) 1996-1999 Sun Microsystems, Inc. All Rights Reserved.
>  *
>  * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
>  * modify and redistribute this software in source and binary code form,
>  * provided that i) this copyright notice and license appear on all copies of
>  * the software; and ii) Licensee does not utilize the software in a manner
>  * which is disparaging to Sun.
>  *
>  * This software is provided "AS IS," without a warranty of any kind. ALL
>  * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
>  * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
>  * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
>  * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
>  * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
>  * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
>  * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
>  * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
>  * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
>  * POSSIBILITY OF SUCH DAMAGES.
>  *
>  * This software is not designed or intended for use in on-line control of
>  * aircraft, air traffic, aircraft navigation or aircraft communications; or in
>  * the design, construction, operation or maintenance of any nuclear
>  * facility. Licensee represents and warrants that it will not use or
>  * redistribute the Software for such purposes.
>  */
>
> import java.applet.Applet;
> import java.awt.BorderLayout;
> import java.awt.event.*;
> import java.awt.GraphicsConfiguration;
> import com.sun.j3d.utils.applet.MainFrame;
> import com.sun.j3d.utils.geometry.ColorCube;
> import com.sun.j3d.utils.universe.*;
> import javax.media.j3d.*;
> import javax.vecmath.*;
>
> public class HelloUniverse extends Applet {
>                 CameraFollow cfb;
>
>     public BranchGroup createSceneGraph() {
>         // Create the root of the branch graph
>         BranchGroup objRoot = new BranchGroup();
>
>         // Create the transform group node and initialize it to the
>         // identity.  Enable the TRANSFORM_WRITE capability so that
>         // our behavior code can modify it at runtime.  Add it to the
>         // root of the subgraph.
>         TransformGroup objTrans = new TransformGroup();
>         objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
>         objRoot.addChild(objTrans);
>     objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
>
>         // Create a simple shape leaf node, add it to the scene graph.
>         objTrans.addChild(new ColorCube(0.4));
>
>         BoundingSphere bounds =
>             new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
>
>         // Create a new Behavior object that will perform the desired
>         // operation on the specified transform object and add it into
>         // the scene graph.
>         /*
>         Transform3D yAxis = new Transform3D();
>         Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
>                                         0, 0,
>                                         4000, 0, 0,
>                                         0, 0, 0);
>
>         RotationInterpolator rotator =
>             new RotationInterpolator(rotationAlpha, objTrans, yAxis,
>                                      0.0f, (float) Math.PI*2.0f);
>         rotator.setSchedulingBounds(bounds);
>         objTrans.addChild(rotator);
>         */
> // added by SFK
>                 cfb = new CameraFollow(objTrans);
>                 cfb.targetTG = objTrans;
> //              cfb.cameraTG = cameraTG;
>                 cfb.setSchedulingBounds(bounds);
>             objTrans.addChild(cfb);
> // end added by SFK
>
>         // Have Java 3D perform optimizations on this scene graph.
>         objRoot.compile();
>
>         return objRoot;
>     }
>
>     public HelloUniverse() {
>         setLayout(new BorderLayout());
>         GraphicsConfiguration config =
>            SimpleUniverse.getPreferredConfiguration();
>
>         Canvas3D c = new Canvas3D(config);
>         add("Center", c);
>
>         // Create a simple scene and attach it to the virtual universe
>         BranchGroup scene = createSceneGraph();
>         SimpleUniverse u = new SimpleUniverse(c);
>
>     // added by SFK
>         cfb.cameraTG = 
>u.getViewingPlatform().getMultiTransformGroup().getTransformGroup(0);
>     // end added by SFK
>
>     // This will move the ViewPlatform back a bit so the
>     // objects in the scene can be viewed.
>     u.getViewingPlatform().setNominalViewingTransform();
>
>         u.addBranchGraph(scene);
>     }
>
>     //
>     // The following allows HelloUniverse to be run as an application
>     // as well as an applet
>     //
>     public static void main(String[] args) {
>         new MainFrame(new HelloUniverse(), 256, 256);
>     }
> }

--
__________________________________________________________

Shawn Kendall               Full Sail Real World Education
Course Director             3300 University BLVD
Real Time 3D for Gaming     Winter Park FL 32792
[EMAIL PROTECTED]       http://www.fullsail.com
__________________________________________________________

===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA3D-INTEREST".  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".

Reply via email to