Dalton has posted 1 posts at DZone. View Full User Profile

3D Model Interaction with Java 3D

01.26.2008
| 48583 views |
  • submit to reddit

Camera

If you want to view your scene on different angles, you will need a camera. Java 3D uses a view based model - there are no camera objects, but a ViewPlatform object. Whenever you want to change the view of your scene, all you have to do is to change parameters on the ViewPlatform object. If you are using SimpleUniverse to facilitate the view configuration of your program, you don't need to add any ViewPlatform instance to the root node because SimpleUniverse has already added that for you.

The ViewPlatform created by SimpleUniverse is inside a MultiTransformGroup, which you can obtain via ViewingPlatform. The following code demonstrates how to obtain this MultiTransformGroup and use it to change the view of the scene:

            import com.sun.j3d.utils.universe.ViewingPlatform;


/* You don't have to create a ViewingPlatform if you are using SimpleUniverse */
ViewingPlatform vp = universe.getViewingPlatform();

/* You don't need to add the VP to a TransformGroup because the VP is already added in a MultiTransformGroup;
0 is the topmost TransformGroup */
TransformGroup vpGroup = vp.getMultiTransformGroup().getTransformGroup(0);

/* You can transform the view platform as you do with other objects */
Transform3D vpTranslation = new Transform3D();
Vector3f translationVector = new Vector3f(1.9F, 1.2F, 6F);

vpTranslation.setTranslation(translationVector);
vpGroup.setTransform(vpTranslation);
Example: Translation vectors used on the ViewPlatorm
0.0, -1.2, 6.0 1.9, 1.2, 6.0
0.0, 1.2, 6.0 -1.9, 1.2, 6.0

Do not confuse ViewPlatform with ViewingPlatform - the latter is a convenience class used to "set up the view side of the graph" - it contains a ViewPlatform.

Recommended reading: ViewingPlatform javadoc, ViewPlatform javadoc

Background

Unless you want your background to be plain black, you should specify one. Just remember to always add the background to the root node of your scene; add it anywhere else and you will get an undesirable IllegalSharingException.

Color background

            import javax.media.j3d.Background;


/* A dull gray background */
Background background = new Background(new Color3f(Color.LIGHT_GRAY));

/* incluencRegion is a BoundingSphere. See the "Lights" section for details */
background.setApplicationBounds(influenceRegion);

/* root is a BranchGroup, root node of your Scene object */
root.addChild(background);

Image background

            TextureLoader t = new TextureLoader("leaves.jpg", canvas);

Background background = new Background(t.getImage());
background.setImageScaleMode(Background.SCALE_REPEAT); // Tiles the image
background.setApplicationBounds(influenceRegion);

root.addChild(background);

This static background is quite boring. If you are looking for something more interesting, such as a celestial sphere, you should use apply a geometry to a background. You can find examples on Java2S website.

Recommended reading: Background javadoc

Interacting with the model

Now it's time to use the TransformGroup references you've kept a while ago. You will use them to control the movement of the model. The cockroach will do a very silly movement: the left legs will move forward while the right legs stand still, then the right legs move forward while left legs stand still; the body will always move a little bit forward on every movement. It's far from realistic, but you can derive more complex movements if you learn this one. (If you're concerned, as far as my assignment, the movement was more complex than that...)

The class Behavior will be used to interact with the model. The Behavior class is like a listener - you have to implement it to achieve the desired reaction. It has to be activated every time it's used, or it won't react to the next stimulus. The stimulus used on this section will be a key press, but you can use many others - check WakeupCriterion's direct known subclasses to check for other options. After implementing your Behavior subclass, all you have to do is to add it on the node you want to animate.

Instance variables

            /** Groups that will be animated. */
TransformGroup[] groups;

/** Used to transform the groups you will animate. */
Transform3D[] transforms;

/** Used to translate the groups you will animate. */
Vector3f[] translations;

/** Type of event for which groups will react. */
WakeupOnAWTEvent wake;

/** Increments 1 every time the user hits a key. */
int hitCount;

/** Decides which group will be animated based on the hitCount. */
int bodyPartIndex;

Constructor

            SimpleTripodMovement(TransformGroup... groups) {
this.groups = groups; // You can add a groups count security check if you will

wake = new WakeupOnAWTEvent(KeyEvent.KEY_PRESSED); // You decide which key later

translations = new Vector3f[groups.length];
transforms = new Transform3D[groups.length];

for (int i = 0; i < groups.length; i++) {
translations[i] = new Vector3f(0F, 0F, 0F);
transforms[i] = new Transform3D();
}
}

Implementation of initialize

            public void initialize() { // Overriden method
wakeupOn(wake); // Inherited method
}

Implementation of processStimulus

            public void processStimulus(Enumeration enumeration) {
KeyEvent k = (KeyEvent) wake.getAWTEvent()[0];

/* Moves only if the key pressed is the right directional key and
if the hit count is a multiple of 4 */
if ((k.getKeyCode() == KeyEvent.VK_RIGHT) && (hitCount++ % 4 == 0)) {

/* Selects the body part to be moved */
bodyPartIndex = (bodyPartIndex + 1) % 3;

/* Moves 0.1 on Z axis */
translations[bodyPartIndex].set(translations[bodyPartIndex].x,
translations[bodyPartIndex].y,
translations[bodyPartIndex].z + 0.1F);

transforms[bodyPartIndex].setTranslation(translations[bodyPartIndex]);
groups[bodyPartIndex].setTransform(transforms[bodyPartIndex]);
}


/* If you don't put it here, it won't respond the next time you press a key */
wakeupOn(wake);
}

Applying the behavior

            /**
* Adds a simple tripod movement to the given roach.
*
* @param parts parts that will be animated
* @param roach supernode of parts * @param bounds world bounds, the smae used for lighting */ void addBehavior(TransformGroup[] parts, TransformGroup roach, Bounds bounds) { Behavior behavior = new CockroachBehavior(parts); /* Behavior will not work if you don't set the scheduling bounds! */ behavior.setSchedulingBounds(bounds); roach.addChild(behavior); }

As you have probably noticed, this class is tightly coupled with the objects it animates, but that is predictable; from Behavior's javadoc: 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.

Recommended reading: Behavior javadoc

Resources

References

References
Published at DZone with permission of its author, Dalton Filho. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Rick Ross replied on Sat, 2008/01/26 - 2:39pm

Wow, Dalton! I am truly impressed, and you are a rock star! This is super neat, so thank you for being part of the DZone/Javalobby community!

Rick

Steven Devijver replied on Sat, 2008/01/26 - 2:44pm

I can't stop thinking "Groovy Builder" ... :-)

Andres Almiray replied on Sat, 2008/01/26 - 3:15pm in response to: Steven Devijver

hehe me too =) I hope some takes on the the task of creating one.

Bob Spuckwood replied on Sun, 2008/01/27 - 12:37pm

Uh, so where, exactly is the viewable demo?

Rick Ross replied on Sun, 2008/01/27 - 5:07pm in response to: Bob Spuckwood

[quote=jonjonz]Uh, so where, exactly is the viewable demo?[/quote]

The rhetorical value of starting with "Uh" is lost on me. Be kind to this man, please. If you'd like to see a demo, then I imagine he'd be happy to oblige if you just ask nicely. Your comment seemed to carry more an overtone of criticism than of request. Dalton worked hard and put much effort into this article, so let's give him some acknowledgement.

"This looks interesting, Dalton. Would it be possible to provide a link to a viewable demo? Thanks."

Cheers,
Rick

Dalton Filho replied on Mon, 2008/01/28 - 11:31am

jonjonz,

I have now included a binary download that includes the 3D model. Note that you must have Java3D installed for it to work. Check https://java3d.dev.java.net/binary-builds.html

 

Dalton

Trent Creekmore replied on Thu, 2009/04/02 - 7:16pm

So where is the example code?

Trent Creekmore replied on Tue, 2009/04/07 - 6:51pm

s

deepak singh replied on Wed, 2009/06/03 - 2:03am


I was  testing 3D Model Interaction with Java 3D throught this example .
 During testing following error is coming


Exception in thread "main" java.lang.UnsatisfiedLinkError: no j3dcore-ogl in java.library.path
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1709)
        at java.lang.Runtime.loadLibrary0(Runtime.java:823)
        at java.lang.System.loadLibrary(System.java:1030)
        at javax.media.j3d.MasterControl$6.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.media.j3d.MasterControl.loadLibraries(Unknown Source)
        at javax.media.j3d.VirtualUniverse.<clinit>(Unknown Source)
        at javax.media.j3d.Canvas3D.<clinit>(Unknown Source)

        at com.daltonfilho.tutorials.java3d.SceneControl.initCanvas(SceneControl.java:68)
        at com.daltonfilho.tutorials.java3d.SceneControl.<init>(SceneControl.java:54)
        at com.daltonfilho.tutorials.java3d.Program.main(Program.java:31)



can you  help me i am using netbean +j2re1.4.1+jdk1.6.0_10+Java3D.1.4

I will very thank full for you help

deepak

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.