As part of my University coursework I have to implement a simulation of a desert island with 2 sharks swimming around it in opposite directions and when a button (I have chosen the island) is clicked, the sharks should change their direction. As of now I have 2 sharks (cones) swimming in opposite directions around an island (sphere) but I cannot correctly implement the picking operation needed to detect clicks upon the island and act accordingly..
Below is my current code, I need help trying to make the picking operation work, right now nothing happens, not even when I click anywhere around the window.. thanks.
// TODO:
// 1: Allow clicking of a button to change direction of sharks
// 2: Get .obj models for shark and islands
// 3: find a better way of texturing the background i.e. tiling image etc
// 4: Change the viewpoint and maybe allow mouse/key nevigation
//
import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.GraphicsConfiguration;
//import java.awt.event.;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.Sphere;
import com.sun.j3d.utils.geometry.Cone;
import com.sun.j3d.utils.universe.SimpleUniverse;
import com.sun.j3d.utils.image.TextureLoader;
import com.sun.j3d.utils.geometry.Primitive;
import javax.media.j3d.Background;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.TransformGroup;
import javax.media.j3d.Transform3D;
import javax.media.j3d.Appearance;
import javax.media.j3d.ColoringAttributes;
import javax.media.j3d.Alpha;
import javax.media.j3d.RotationInterpolator;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.Texture;
import javax.media.j3d.TextureAttributes;
import javax.vecmath.Point3d;
import javax.vecmath.Color3f;
import javax.vecmath.Vector3d;
import javax.media.j3d.*;
import com.sun.j3d.utils.picking.PickCanvas;
import com.sun.j3d.utils.picking.PickResult;
import com.sun.j3d.utils.picking.behaviors.PickMouseBehavior;
import com.sun.j3d.loaders.Scene;
import com.microcrowd.loader.java3d.max3ds.Loader3DS;
public class DesertIsland extends Applet {
private Canvas3D canvas3D;
private SimpleUniverse simpleU;
private BoundingSphere bounds;
// Initialize transformgroup objects for the shark movement.
private TransformGroup tgShark1;// = new TransformGroup();
private TransformGroup shark1; // Shark object
private TransformGroup tgShark2;// = new TransformGroup();
private TransformGroup shark2; // Shark object
public BranchGroup createSceneGraph()
{
println("createSceneGraph() BEGIN; ");
/////////////////////////////////////////////////
///////////////// Create Shapes /////////////////
/////////////////////////////////////////////////
println("Creating Scene Graph object.");
// Create the root of the branch graph
BranchGroup objRoot = new BranchGroup();
println("Creating Bounding Sphere.");
// Set Application bounds
bounds = new BoundingSphere( new Point3d( 0.0 , 0.0 , 0.0 ) , 100.0 );
// Create background
/////////////////////////////////////////////////
println("Creating background.");
Background bg = new Background();
println("Setting background bounds.");
bg.setApplicationBounds(bounds);
BranchGroup backGeoBranch = new BranchGroup();
Sphere sphereObj = new Sphere(1.1f, Sphere.GENERATE_NORMALS | Sphere.GENERATE_NORMALS_INWARD | Sphere.GENERATE_TEXTURE_COORDS, 45);
Appearance backgroundApp = sphereObj.getAppearance();
println("Loading texture.");
TextureLoader bgTextureLoader = new TextureLoader("sea-texture.jpg", new String("RGB"), this);
if ( bgTextureLoader != null )
{
println("Set Background texture successfully.");
backgroundApp.setTexture( bgTextureLoader.getTexture() );
}
println("Setting background geometry.");
backGeoBranch.addChild(sphereObj);
bg.setGeometry(backGeoBranch);
println("Adding background to the scene graph");
objRoot.addChild( bg );
println("Creating Island");
// Create Green Circle for the island.
Appearance islandAppearance = new Appearance();
println("Loading Island Texture.");
TextureLoader ldr = new TextureLoader("island.GIF", this);
Texture texIsland = ldr.getTexture();
println("Setting Island texture.");
islandAppearance.setTexture( texIsland );
islandAppearance.setTextureAttributes( new TextureAttributes( ) );
println("Creating sphere with texture for island.");
//islandAppearance.setColoringAttributes( new ColoringAttributes( 1.0f , 1.0f , 0.0f , ColoringAttributes.SHADE_FLAT ) );
Sphere island = new Sphere( 0.3f , Primitive.GENERATE_TEXTURE_COORDS ,islandAppearance );
island.setUserData( new String( "Island" ) );
println("Adding Island to the scene graph");
objRoot.addChild( island );
// Create 2 grey cones for sharks.
// Appearance sharkAppearance = new Appearance();
// sharkAppearance.setColoringAttributes( new ColoringAttributes( 0.5f , 0.5f, 0.5f, ColoringAttributes.NICEST ) );
// Cone shark1 = new Cone( 0.05f , 0.1f , sharkAppearance );
// Cone shark2 = new Cone( 0.05f , 0.1f , sharkAppearance );
println("Creating Sharks.");
tgShark1 = new TransformGroup();
tgShark2 = new TransformGroup();
println("Instantiating Shark objects.");
shark1 = new TransformGroup();
shark2 = new TransformGroup();
// try
// {
// Loader3DS mlSh1 = new Loader3DS();
// Loader3DS mlSh2 = new Loader3DS();
// Scene sSh1 = mlSh1.load("models/Mezirozame0.3ds");
// Scene sSh2 = mlSh2.load("models/Mezirozame0.3ds");
// BranchGroup bSh1 = sSh1.getSceneGroup();
// BranchGroup bSh2 = sSh2.getSceneGroup();
// tgShark1.addChild( bSh1 );
// tgShark2.addChild( bSh2 );
// }
// catch( java.io.FileNotFoundException e )
// {
// System.out.println( e );
// System.out.println( "Using simple Cone objects as Sharks" );
println("Creating shark appearance.");
Appearance sharkAppearance = new Appearance();
sharkAppearance.setColoringAttributes( new ColoringAttributes( 0.5f , 0.5f, 0.5f, ColoringAttributes.NICEST ) );
println("Creating cone shapes for sharks.");
Cone cShark1 = new Cone( 0.05f , 0.1f , sharkAppearance );
cShark1.setUserData( new String("Shark 1") );
Cone cShark2 = new Cone( 0.05f , 0.1f , sharkAppearance );
cShark2.setUserData( new String("Shark 2") );
shark1.addChild( cShark1 );
shark2.addChild( cShark2 );
// }
println("Setting Shark1's read/write capabilities");
shark1.setCapability(
println("Setting Shark1's animation.");
println("Moving shark1 to the right.");
Transform3D right = new Transform3D();
Vector3d pos1 = new Vector3d( 0.4d , 0.0d , 0.0d );
right.set( pos1 );
TransformGroup tgMove1 = new TransformGroup( right );
println("Rotating Shark1 to upright position.");
Transform3D t3dRot1 = new Transform3D();
t3dRot1.rotX( ( Math.PI / 2.0 ) );
TransformGroup tgRot1 = new TransformGroup( t3dRot1 );
println("Setting Shark1 spinner.");
TransformGroup tgSpin1 = new TransformGroup();
tgSpin1.setCapability( TransformGroup.ALLOW_TRANSFORM_WRITE ) ;
// Set movement and direction etc
Alpha timeRamp1 = new Alpha( -1 , Alpha.DECREASING_ENABLE , 0, 0, 0, 0, 0, 10000, 0, 0);
RotationInterpolator rotator1 = new RotationInterpolator( timeRamp1, tgSpin1 );
rotator1.setSchedulingBounds( bounds );
println("Assembling Shark1 Animation.");
println("Adding Shark 1 to the scene graph.");
objRoot.addChild( tgShark1 );
tgShark1.addChild( tgRot1 );
tgRot1.addChild( tgSpin1 );
tgSpin1.addChild( tgMove1 );
tgMove1.addChild( rotator1 );
tgMove1.addChild( shark1 );
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
println("Setting Shark2's animation.");
println("Moving Shark2 to the left.");
Transform3D left = new Transform3D();
Vector3d pos2 = new Vector3d( -0.4d , 0.0d , 0.0d );
left.set( pos2 );
TransformGroup tgMove2 = new TransformGroup( left );
println("Rotationg Shark2 to the upright position.");
Transform3D t3dRot2 = new Transform3D();
t3dRot2.rotX( ( Math.PI / 2.0 ) );
TransformGroup tgRot2 = new TransformGroup( t3dRot2 );
println("Setting Shark2 spinner.");
TransformGroup tgSpin2 = new TransformGroup();
tgSpin2.setCapability( TransformGroup.ALLOW_TRANSFORM_WRITE ) ;
Alpha timeRamp2 = new Alpha( -1, 10000 ) ;
RotationInterpolator rotator2 = new RotationInterpolator( timeRamp2 , tgSpin2 );
rotator2.setSchedulingBounds( bounds );
println("Assembling Shark2.");
println("Adding Shark2 to the scene graph.");
objRoot.addChild( tgShark2 );
tgShark2.addChild( tgRot2 );
tgRot2.addChild( tgSpin2 );
tgSpin2.addChild( tgMove2 );
tgMove2.addChild( rotator2 );
tgMove2.addChild( shark2 );
// TransformGroup nav = new TransformGroup();
// KeyNavigatorBehaviour kn = new KeyNavigatorBehaviour( nav );
// kn.setSchedulingBounds( bounds );
// objRoot.addChild( kn );
println("Creating Picker object.");
Picker picker = new Picker( canvas3D , objRoot , bounds , island , shark1 , shark2 );
println("Adding Picker object to the scene graph");
objRoot.addChild( picker );
println("Compiling scene graph.");
objRoot.compile();
println("createSceneGraph() END;");
return objRoot;
}
private void println( String s )
{
System.out.println("@DESERTISLAND: " + s );
}
public DesertIsland()
{
println("Setting Layout.");
setLayout( new BorderLayout() );
GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
println("Creating Canvas.");
canvas3D = new Canvas3D(config);
add("Center", canvas3D);
println("Creating Scene Graph");
BranchGroup scene = createSceneGraph();
scene.compile();
println("Creating Simple Universe");
simpleU = new SimpleUniverse(canvas3D);
println("Setting the view platform");
simpleU.getViewingPlatform().setNominalViewingTransform();
println("Creating Scene..");
simpleU.addBranchGraph(scene);
}
// The following allows this to be run as an application
// as well as an applet
public static void main(String[] args) {
Frame frame = new MainFrame(new DesertIsland(), 512, 512);
}
}
class Picker extends PickMouseBehavior
{
private PickCanvas pickCanvas;
private Node trigger;
private Node shark1;
private Node shark2;
public Picker( Canvas3D canvas , BranchGroup root , Bounds bounds ,
Node triggerShape , Node sh1 , Node sh2 )
{
super( canvas , root , bounds );
pickCanvas = new PickCanvas( canvas , root );
trigger = triggerShape;
shark1 = sh1;
shark2 = sh2;
print("Created instance of Picker class.");
}
private void print( String s )
{
System.out.println("@PICKER: " + s );
}
public void updateScene(int xpos, int ypos)
{
print("updateScene() BEGIN;");
PickResult pickResult = null;
pickCanvas.setShapeLocation(xpos, ypos);
pickResult = pickCanvas.pickClosest();
Shape3D shape = null;
if (pickResult != null)
{
if ( pickResult != null )
{
Node pickedShape = (Primitive) pickResult.getNode(PickResult.PRIMITIVE);
String pickedData = (String) pickedShape.getUserData();
if ( pickedData.equals( trigger.getUserData() ) )
{
print("Triggering..");
}
else
{
print("Incorrect Shape");
}
}
}
else
{
print("No shape picked");
}
}
}