2. Hello Node

( Note: the starter tutorials in this wiki are not always up to date with the latest development version of jME. You can find up to date source files for the tutorials here: https://jme.dev.java.net/source/browse/jme/src/jmetest/TutorialGuide/ )

This program introduces Nodes, Bounding Volumes, Sphere, Colors, Translation and Scaling.

import com.jme.app.SimpleGame;
import com.jme.bounding.BoundingBox;
import com.jme.bounding.BoundingSphere;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.Node;
import com.jme.scene.shape.Box;
import com.jme.scene.shape.Sphere;
import com.jme.scene.state.LightState;
/**
 * Started Date: Jul 20, 2004<br><br>
 *
 * Simple Node object with a few Geometry manipulators.
 *
 * @author Jack Lindamood
 */
public class HelloNode extends SimpleGame {
 public static void main(String[] args) {
  HelloNode app = new HelloNode();
  app.start();
 }
 protected void simpleInitGame() {
  Box b=new Box("My Box",new Vector3f(0,0,0),new Vector3f(1,1,1));
  // Give the box a bounds object to allow it to be culled
  b.setModelBound(new BoundingSphere());
  // Calculate the best bounds for the object you gave it
  b.updateModelBound();
  // Move the box 2 in the y direction up
  b.setLocalTranslation(new Vector3f(0,2,0));
  // Give the box a solid color of blue.
  b.setSolidColor(ColorRGBA.blue);
  Sphere s=new Sphere("My sphere",10,10,1f);
  // Do bounds for the sphere, but we'll use a BoundingBox this time
  s.setModelBound(new BoundingBox());
  s.updateModelBound();
  // Give the sphere random colors
  s.setRandomColors();
  // Make a node and give it children
  Node n=new Node("My Node");
  n.attachChild(b);
  n.attachChild(s);
  // Make the node and all its children 5 times larger.
  n.setLocalScale(5);
  // Remove lighting for rootNode so that it will use our
  //basic colors.
  rootNode.setLightCombineMode(LightCombineMode.Off);
  rootNode.attachChild(n);
 }
}

The first new thing you see is:

// Give the box a bounds object to allow it to be culled
b.setModelBound(new BoundingSphere());

Bounding Volumes (such as BoundingSphere and BoundingBox) are the key to speed in jME. What happens is your object is surrounded by a bounds, and this bounds allows jME to do a quick, easy test to see if your object is even viewable. So in your game, you’ll make this really complex person and surround him with a sphere, for instance. A sphere is a really easy object mathematically, so jME can tell very fast if the sphere around your object is visible. If the sphere surrounding your guy isn’t visible (which is an easy test), then jME doesn’t even bother trying to draw your really large, very complex person. In this example, I surround my box with a sphere, but it makes more sense to surround it with a BoundingBox. Why? Well trying to draw a sphere around a box isn’t as tight a fit as a Box around a Box (obviously). I just use a sphere as an example:

// Calculate the best bounds for the object you gave it
b.updateModelBound();

When I start, I give my Box object bounds, but it’s an empty bounds. I now have to “update” the bounds so that it surrounds the object correctly. Now we’ll move it up:

// Move the box 2 in the y direction up
b.setLocalTranslation(new Vector3f(0,2,0));

Now we start moving our object. Vector3f has the format x, y, z, so this moves the object 2 units up. Remember how our Box looks above the Sphere? That’s because I moved it up some. If I had used Vector3f(0,-2,0) then it would have moved down two. Moving objects in jME is extremely simple. Now color it:

// Give the box a solid color of blue.
b.setSolidColor(ColorRGBA.blue);

Just looking at the function, you can tell I give my box a solid color. As you can guess by the color type, the color is blue. ColorRGBA.red would make it…. red! You can also use new ColorRGBA(0,1,0,1). These four numbers are: Red/Green/Blue/Alpha and are percentages from 0 to 1. Alpha is lingo for how opaque it is. (The opposite of opaque is transparent. Opaque would be a wall; not opaque would be a window.) So, an alpha of 0 would mean we couldn’t see it at all, while .5 would mean we see half way thru it. New ColorRGBA(0,1,1,1) would create a color that is green and blue. Now let’s make a sphere:

Sphere s=new Sphere("My sphere",10,10,1f);

jME can’t draw curves. It draws triangles. It’s very hard to draw a circle with triangles, isn’t it? Because of this, you have to get as close to a circle as you can. The first two numbers represent that closeness. If you change 10, 10 to 5,5 you’ll see a pretty bad looking sphere. If you make them 30, 30 you’ll see a very round looking sphere but the problem is that it’s made of a lot of triangles. More triangles mean slower FPS. The last number, 1, is the radius of the sphere. Just like my Node and my Box, Sphere needs a name which I give “My sphere”. For our sphere, let’s be a bit prettier with colors:

// Give the sphere random colors
s.setRandomColors();

This gives each vertex of the sphere a random color, which creates that psychodelic effect you saw. Now on to the node:

// Make a node and give it children
Node n=new Node("My Node");
n.attachChild(b);
n.attachChild(s);

Instead of attaching our box and sphere to the rootNode, we create a new node n to attach them too. I also wanted n (and all its children) to be five times bigger, so I did this:

// Make the node and all its children 5 times larger.
n.setLocalScale(5);

You’ll notice it’s similar to the function call setLocalTranslation in name. There’s also a setLocalRotation, which we’ll get into later. As the name suggests, this makes everything five times larger. Finally, you’ll notice a strange line at the end of my code:

// Remove lighting for rootNode so that it will use our
//basic colors.
rootNode.setLightCombineMode(LightCombineMode.Off);

You see, per vertex colors (which is what I’m doing here) isn’t really lighting. It’s a cheap, easy way to create colors. You’ll notice there’s no shading for these colors at all. If you don’t use this line, jME won’t try to use per vertex colors. The scene graph looks like this:

rootNode
“My Node” made 5x bigger
“My box” moved 2 up. “My sphere”

You’ll notice that because “My box” and “My sphere” are children of “My Node”, they are made five times bigger as well. If I move “My Node” down 10, then “My Box” and “My sphere” would move down 10, as well. This is the ease of making a game with a scene graph.

While you’re running the program, press “B” to see the bounding in action. It is a neat way to visualize the parent/child scene graph relationship. You can see the BoundingSphere around your box, the BoundingBox around your sphere, and the automatic BoundingSphere around “My node”:

 
Except where otherwise noted, content on this wiki is licensed under the following license:CC Attribution 3.0 Unported