Start behaviors before scene is visible

Sorry about the two posts in a row :slight_smile:

Does anyone know if it’s possible to start 3D behaviors (javax.media.j3d.Behavior) before the Canvas3D becomes visible?

Here’s what I’m trying to do:

I’m using a Swing application to manipulate a 3D scene. However, none of the Behaviors will run unless I previously viewed the Canvas3D. That is, if I start my Swing application (cannot initially see Canvas3D) and just start interacting with the GUI (contains JButtons, JTextField, etc) that causes transforms in the 3D scene, none of the behaviors connected to these tranforms will have their processStimulus() invoked, however the transforms do take place! Is there a way around this?

i simply don’t understand…

first you ask if it’s possible to start 3D behaviors before the Canvas3D becomes visible. Then you ask how to avoid it?!

Moreover, if you say the code to transform the scene is in behaviors and the scene is transformed, it means the ‘processStimulus()’ is called!
On the opposite, if you’re sure ‘processStimulus()’ is never called, it means you transform the scene elsewhere!

It’s not clear at all…

maybe myBehavior.setEnable(true/false) helps.

Sorry about the confusion, I’ll try to explain:

[quote]you say the code to transform the scene is in behaviors
[/quote]
I never said that the behaviors transform the scene, I said that the behaviors are “connected” to these transforms (TransformGroups) like this:



// Constructor
public My3DBehavior(TransformGroup aTransformGroup)
{
   transformGroup = aTransformGroup;
   wakeupCondition = new WakeupOnTransformChange(transformGroup);
}

// Initialize the behavior to wake up on a transform 
// change.
public void initialize()
{
   wakeupOn(wakeupCondition);
}

// TransformGroup has been modified!
public void processStimulus(Enumeration e)
{
   System.out.println("TransformGroup has been modified!");
   doWork();
   // Reset the wake up condition.
   wakeupOn(wakeupCondition);
}

So the problem again is that if the Canvas3D is not made visible, the ‘processStimulus()’ of ‘My3DBehavior’ will not be called, even though the TransformGroup is modified. As soon as the Canvas3D is made visible, all further transforms on the TransformGroup is caught by the behavior.

Please let me know if there is need for further explaination. Thank-you.

P.S. I was already using setEnabed(true).

oh, sorry, my fault… It’s very clear now.
…and sorry again for having no solution. :-X

It sounds as though the transform change is only registered when the scene is visible.

Could you perhaps register the change from the controls buttons rather than from the scene? Or disable the controls until the scene is visible?

Breakfast,

I’ve already tried what you proposed, and it works fine. However, in a situation where the user will only be interacting and viewing the swing GUI, he/she will not receive any visual indications of any tranformations that took place in the 3D scene. This is very misleading to the user since the transformations did in fact take place, but no behavior was run.

So, just to recap, it is possible to perform tranformations on a scene before it is rendered, but it is not possible to have any behavior respond to those tranformations. Is there some way to “jump start” the BehaviorScheduler before the scene is rendered? Or is the problem related to some rule that the ViewingPlatform’s bounds aren’t valid until the Canvas3D is shown?

Hi
As i understand it, there is no way to have behaviours automatically run before at least one frame is rendered, you can call processStimuli on the behaviour yourself if you know which on it is, but I don’t know what effect this will have as I have never tried it, especially if that behaviour effects the scenegraph.

Cheers

Endolf

endolf,

calling processStimulus from the Swing thread causes a java.lang.IllegalStateException at runtime. This is thrown by the wakupOn call that I have in the processStimulus. Excerpt from wakupOn javadoc: “Throws:
java.lang.IllegalStateException - if this method is called by a method other than initialize or processStimulus”
I guess what they really mean is that the wakeupOn should only be called from a J3D thread (probably the BehaviorScheduler).

So, the only workaround that I found was to create another public method in my behavior which would do the same work as my processStimulus minus the setting of the wakeupOn:


.
.
.
public MyBehavior(TransformGroup aTransformGroup)
{
     transformGroup = aTransformGroup;
     wakeupCondition = new WakeupOnTransformChange(transformGroup);
}

public void initialize()
{
     wakeupOn(wakeupCondition);
}

public void processStimulus(Enumeration e)
{
     doWork();
     wakeupOn(wakeupCondition);
}

public void doWork()
{
     // doing something here
}
.
.
.

This works fine, but I now need to call doWork() everytime the user is interacting with one of the swing controls insted of just letting the behavior worry about it :frowning:

We are doing something very similar in our game – that’s basically the only way to get Swing and Java3D to interact via behaviors, AFAIK

You could also try playing around with the WakeupOnAWTEvent (? don’t have javadocs handy), which is how some of the sun interpolators work.