# Java3d in Eclipse einbinden



## N0__ESCAPE (27. Sep 2016)

Hey! 
Ich hab schon das ganze Internet durchsucht, und finde einfach nix!
(Ihr seid meine letzte Rettung )
Ich habe mir Java 3D runtergeladen und installiert.
Habs natürlich auch mit Build Path ins projekt eingebunden.
Dann hab ich den Code reingepackt

```
import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.Enumeration;

import javax.media.j3d.Alpha;
import javax.media.j3d.AmbientLight;
import javax.media.j3d.Appearance;
import javax.media.j3d.Behavior;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.Bounds;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.DirectionalLight;
import javax.media.j3d.Locale;
import javax.media.j3d.Material;
import javax.media.j3d.Node;
import javax.media.j3d.PhysicalBody;
import javax.media.j3d.PhysicalEnvironment;
import javax.media.j3d.PositionInterpolator;
import javax.media.j3d.Switch;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.media.j3d.View;
import javax.media.j3d.ViewPlatform;
import javax.media.j3d.VirtualUniverse;
import javax.media.j3d.WakeupCriterion;
import javax.media.j3d.WakeupOnAWTEvent;
import javax.media.j3d.WakeupOnCollisionEntry;
import javax.media.j3d.WakeupOnElapsedTime;
import javax.media.j3d.WakeupOr;
import javax.vecmath.Color3f;
import javax.vecmath.Matrix3d;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;
import javax.vecmath.Vector3f;

import com.sun.j3d.loaders.Scene;
import com.sun.j3d.loaders.objectfile.ObjectFile;
import com.sun.j3d.utils.geometry.Box;
import com.sun.j3d.utils.geometry.Cylinder;
import com.sun.j3d.utils.geometry.Sphere;

/**
* This application demonstrates a number of things in the implementation of a
* simple shooting game. The object of the the game is to shoot a duck that
* repeatedly moves across the screen from left to right. There are two duck
* models, one for the 'live' duck and one for the 'dead' one. These are loaded
* from 'duck.obj' and 'deadduck.obj' files. The 'gun' is built from primitives.
* The duck and the ball that is used to shoot the duck use interpolators for
* their animation. The gun uses key board input to aim and fire it, and
* collision detection is used to 'kill' the duck.
*
* @author I.J.Palmer
* @version 1.0
*/
public class SimpleGame extends Frame implements ActionListener {
  protected Canvas3D myCanvas3D = new Canvas3D(null);

  protected Button exitButton = new Button("Exit");

  protected BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0,
      0.0), 100.0);

  /** Switch that is used to swap the duck models */
  Switch duckSwitch;

  /** Alpha used to drive the duck animation */
  Alpha duckAlpha;

  /** Used to drive the ball animation */
  Alpha ballAlpha;

  /** Used to move the ball */
  PositionInterpolator moveBall;

  /** Used to rotate the gun */
  TransformGroup gunXfmGrp = new TransformGroup();

  /**
   * This builds the view branch of the scene graph.
   *
   * @return BranchGroup with viewing objects attached.
   */
  protected BranchGroup buildViewBranch(Canvas3D c) {
    BranchGroup viewBranch = new BranchGroup();
    Transform3D viewXfm = new Transform3D();
    Matrix3d viewTilt = new Matrix3d();
    viewTilt.rotX(Math.PI / -6);
    viewXfm.set(viewTilt, new Vector3d(0.0, 10.0, 10.0), 1.0);
    TransformGroup viewXfmGroup = new TransformGroup(viewXfm);
    ViewPlatform myViewPlatform = new ViewPlatform();
    PhysicalBody myBody = new PhysicalBody();
    PhysicalEnvironment myEnvironment = new PhysicalEnvironment();
    viewXfmGroup.addChild(myViewPlatform);
    viewBranch.addChild(viewXfmGroup);
    View myView = new View();
    myView.addCanvas3D(c);
    myView.attachViewPlatform(myViewPlatform);
    myView.setPhysicalBody(myBody);
    myView.setPhysicalEnvironment(myEnvironment);
    return viewBranch;
  }

  /**
   * This adds some lights to the content branch of the scene graph.
   *
   * @param b
   *            The BranchGroup to add the lights to.
   */
  protected void addLights(BranchGroup b) {
    Color3f ambLightColour = new Color3f(0.5f, 0.5f, 0.5f);
    AmbientLight ambLight = new AmbientLight(ambLightColour);
    ambLight.setInfluencingBounds(bounds);
    Color3f dirLightColour = new Color3f(1.0f, 1.0f, 1.0f);
    Vector3f dirLightDir = new Vector3f(-1.0f, -1.0f, -1.0f);
    DirectionalLight dirLight = new DirectionalLight(dirLightColour,
        dirLightDir);
    dirLight.setInfluencingBounds(bounds);
    b.addChild(ambLight);
    b.addChild(dirLight);
  }

  /**
   * This builds the gun geometry. It uses box and cylinder primitives and
   * sets up a transform group so that we can rotate the gun.
   */
  protected BranchGroup buildGun() {
    BranchGroup theGun = new BranchGroup();
    Appearance gunApp = new Appearance();
    Color3f ambientColour = new Color3f(0.5f, 0.5f, 0.5f);
    Color3f emissiveColour = new Color3f(0.0f, 0.0f, 0.0f);
    Color3f specularColour = new Color3f(1.0f, 1.0f, 1.0f);
    Color3f diffuseColour = new Color3f(0.5f, 0.5f, 0.5f);
    float shininess = 20.0f;
    gunApp.setMaterial(new Material(ambientColour, emissiveColour,
        diffuseColour, specularColour, shininess));
    TransformGroup init = new TransformGroup();
    TransformGroup barrel = new TransformGroup();
    Transform3D gunXfm = new Transform3D();
    Transform3D barrelXfm = new Transform3D();
    barrelXfm.set(new Vector3d(0.0, -2.0, 0.0));
    barrel.setTransform(barrelXfm);
    Matrix3d gunXfmMat = new Matrix3d();
    gunXfmMat.rotX(Math.PI / 2);
    gunXfm.set(gunXfmMat, new Vector3d(0.0, 0.0, 0.0), 1.0);
    init.setTransform(gunXfm);
    gunXfmGrp.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    gunXfmGrp.addChild(new Box(1.0f, 1.0f, 0.5f, gunApp));
    barrel.addChild(new Cylinder(0.3f, 4.0f, gunApp));
    gunXfmGrp.addChild(barrel);
    theGun.addChild(init);
    init.addChild(gunXfmGrp);
    return theGun;
  }

  /**
   * Creates the duck. This loads the two duck geometries from the files
   * 'duck.obj' and 'deadduck.obj' and loads these into a switch. The access
   * rights to the switch are then set so we can write to this switch to swap
   * between the two duck models. It also creates a transform group and an
   * interpolator to move the duck.
   *
   * @return BranchGroup with content attached.
   */
  protected BranchGroup buildDuck() {
    BranchGroup theDuck = new BranchGroup();
    duckSwitch = new Switch(0);
    duckSwitch.setCapability(Switch.ALLOW_SWITCH_WRITE);

    ObjectFile f1 = new ObjectFile();
    ObjectFile f2 = new ObjectFile();
    Scene s1 = null;
    Scene s2 = null;
    try {
      s1 = f1.load("duck.obj");
      s2 = f2.load("deadduck.obj");
    } catch (Exception e) {
      System.exit(1);
    }

    TransformGroup duckRotXfmGrp = new TransformGroup();
    Transform3D duckRotXfm = new Transform3D();
    Matrix3d duckRotMat = new Matrix3d();
    duckRotMat.rotY(Math.PI / 2);
    duckRotXfm.set(duckRotMat, new Vector3d(0.0, 0.0, -30.0), 1.0);
    duckRotXfmGrp.setTransform(duckRotXfm);
    duckRotXfmGrp.addChild(duckSwitch);

    duckSwitch.addChild(s1.getSceneGroup());
    duckSwitch.addChild(s2.getSceneGroup());

    TransformGroup duckMovXfmGrp = new TransformGroup();
    duckMovXfmGrp.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
    duckMovXfmGrp.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    duckMovXfmGrp.addChild(duckRotXfmGrp);

    duckAlpha = new Alpha(-1, 0, 0, 3000, 0, 0);
    Transform3D axis = new Transform3D();
    PositionInterpolator moveDuck = new PositionInterpolator(duckAlpha,
        duckMovXfmGrp, axis, -30.0f, 30.0f);
    moveDuck.setSchedulingBounds(bounds);
    theDuck.addChild(moveDuck);
    theDuck.addChild(duckMovXfmGrp);
    return theDuck;
  }

  /**
   * This builds the ball that acts as the bullet for our gun. The ball is
   * created from a sphere primitive, and a transform group and interpolator
   * are added so that we can 'fire' the bullet.
   *
   * @return BranchGroup that is the root of the ball branch.
   */
  protected BranchGroup buildBall() {
    BranchGroup theBall = new BranchGroup();

    Appearance ballApp = new Appearance();
    Color3f ambientColour = new Color3f(1.0f, 0.0f, 0.0f);
    Color3f emissiveColour = new Color3f(0.0f, 0.0f, 0.0f);
    Color3f specularColour = new Color3f(1.0f, 1.0f, 1.0f);
    Color3f diffuseColour = new Color3f(1.0f, 0.0f, 0.0f);
    float shininess = 20.0f;
    ballApp.setMaterial(new Material(ambientColour, emissiveColour,
        diffuseColour, specularColour, shininess));

    Sphere ball = new Sphere(0.2f, ballApp);

    TransformGroup ballMovXfmGrp = new TransformGroup();
    ballMovXfmGrp.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
    ballMovXfmGrp.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    ballMovXfmGrp.addChild(ball);
    theBall.addChild(ballMovXfmGrp);

    ballAlpha = new Alpha(1, 0, 0, 500, 0, 0);
    Transform3D axis = new Transform3D();
    axis.rotY(Math.PI / 2);
    moveBall = new PositionInterpolator(ballAlpha, ballMovXfmGrp, axis,
        0.0f, 50.0f);
    moveBall.setSchedulingBounds(bounds);
    theBall.addChild(moveBall);

    return theBall;

  }

  /**
   * This puts all the content togther. It used the three 'build' functions to
   * create the duck, the gun and the ball. It also creates the two behaviours
   * from the DuckBehaviour and GunBehaviour classes. It then puts all this
   * together.
   *
   * @return BranchGroup that is the root of the content.
   */
  protected BranchGroup buildContentBranch() {
    BranchGroup contentBranch = new BranchGroup();
    Node theDuck = buildDuck();
    contentBranch.addChild(theDuck);
    Node theBall = buildBall();
    contentBranch.addChild(theBall);
    DuckBehaviour hitTheDuck = new DuckBehaviour(theDuck, duckSwitch,
        duckAlpha, bounds);
    GunBehaviour shootTheGun = new GunBehaviour(ballAlpha, moveBall,
        gunXfmGrp, bounds);
    contentBranch.addChild(hitTheDuck);
    contentBranch.addChild(shootTheGun);
    contentBranch.addChild(buildGun());
    addLights(contentBranch);
    return contentBranch;
  }

  /** Exit the application */
  public void actionPerformed(ActionEvent e) {
    dispose();
    System.exit(0);
  }

  public SimpleGame() {
    VirtualUniverse myUniverse = new VirtualUniverse();
    Locale myLocale = new Locale(myUniverse);
    myLocale.addBranchGraph(buildViewBranch(myCanvas3D));
    myLocale.addBranchGraph(buildContentBranch());
    setTitle("Duck Shoot!");
    setSize(400, 400);
    setLayout(new BorderLayout());
    add("Center", myCanvas3D);
    exitButton.addActionListener(this);
    add("South", exitButton);
    setVisible(true);

  }

  public static void main(String[] args) {
    SimpleGame sg = new SimpleGame();
  }

}
/**
* This is used in the SimpleGame application. It defines the behaviour for the
* duck, which is the target in the shooting game. If something collides with
* the duck, it swaps a switch value to 'kill' the duck The duck is revived when
* it's alpha value passes through zero.
*
* @author I.J.Palmer
* @version 1.0
*/

class DuckBehaviour extends Behavior {
  /** The shape that is being watched for collisions. */
  protected Node collidingShape;

  /** The separate criteria that trigger this behaviour */
  protected WakeupCriterion[] theCriteria;

  /** The result of the 'OR' of the separate criteria */
  protected WakeupOr oredCriteria;

  /** The switch that is used to swap the duck shapes */
  protected Switch theSwitch;

  /** The alpha generator that drives the animation */
  protected Alpha theTargetAlpha;

  /** Defines whether the duck is dead or alive */
  protected boolean dead = false;

  /**
   * This sets up the data for the behaviour.
   *
   * @param theShape
   *            Node that is to be watched for collisions.
   * @param sw
   *            Switch that is used to swap shapes.
   * @param a1
   *            Alpha that drives the duck's animation.
   * @param theBounds
   *            Bounds that define the active region for this behaviour.
   */
  public DuckBehaviour(Node theShape, Switch sw, Alpha a1, Bounds theBounds) {
    collidingShape = theShape;
    theSwitch = sw;
    theTargetAlpha = a1;
    setSchedulingBounds(theBounds);
  }

  /**
   * This sets up the criteria for triggering the behaviour. It creates an
   * collision crtiterion and a time elapsed criterion, OR's these together
   * and then sets the OR'ed criterion as the wake up condition.
   */
  public void initialize() {
    theCriteria = new WakeupCriterion[2];
    theCriteria[0] = new WakeupOnCollisionEntry(collidingShape);
    theCriteria[1] = new WakeupOnElapsedTime(1);
    oredCriteria = new WakeupOr(theCriteria);
    wakeupOn(oredCriteria);
  }

  /**
   * This is where the work is done. If there is a collision, then if the duck
   * is alive we switch to the dead duck. If the duck was already dead then we
   * take no action. The other case we need to check for is when the alpha
   * value is zero, when we need to set the duck back to the live one for its
   * next traversal of the screen. Finally, the wake up condition is set to be
   * the OR'ed criterion again.
   */
  public void processStimulus(Enumeration criteria) {
    while (criteria.hasMoreElements()) {
      WakeupCriterion theCriterion = (WakeupCriterion) criteria
          .nextElement();
      if (theCriterion instanceof WakeupOnCollisionEntry) {
        //There'sa collision so if the duck is alive swap
        //it to the dead one
        if (dead == false) {
          theSwitch.setWhichChild(1);
          dead = true;
        }
      } else if (theCriterion instanceof WakeupOnElapsedTime) {
        //If there isn't a collision, then check the alpha
        //value and if it's zero, revive the duck
        if (theTargetAlpha.value() < 0.1) {
          theSwitch.setWhichChild(0);
          dead = false;
        }
      }

    }
    wakeupOn(oredCriteria);
  }
}

/**
* This is used in the SimpleGame application. It defines a behaviour that
* allows a 'gun' to be rotated when left and right cursor keys are pressed and
* then a ball is 'fired' when the space bar is pressed. The 'firing' is
* achieved by setting the start time of an interpolator to the current time.
*
* @author I.J.Palmer
* @version 1.0
*/

class GunBehaviour extends Behavior {
  /** The separate criteria that trigger this behaviour */
  protected WakeupCriterion theCriterion;

  /** The alpha that is used to 'fire' the ball */
  protected Alpha theGunAlpha;

  /** Used to animate the ball */
  protected PositionInterpolator theInterpolator;

  /** Used to calculate the current direction of the gun */
  protected int aim = 0;

  /** This is used to rotate the gun */
  protected TransformGroup aimXfmGrp;

  /** Used to aim the ball */
  protected Matrix3d aimShotMat = new Matrix3d();

  /** Used to aim the gun */
  protected Matrix3d aimGunMat = new Matrix3d();

  /** Used to define the ball's direction */
  protected Transform3D aimShotXfm = new Transform3D();

  /** Used to define the gun's direction */
  protected Transform3D aimGunXfm = new Transform3D();

  /**
   * Set up the data for the behaviour.
   *
   * @param a1
   *            Alpha that drives the ball's animation.
   * @param pi
   *            PositionInterpolator used for the ball.
   * @param gunRotGrp
   *            TransformGroup that is used to rotate the gun.
   * @param theBounds
   *            Bounds that define the active region for this behaviour.
   */
  public GunBehaviour(Alpha a1, PositionInterpolator pi,
      TransformGroup gunRotGrp, Bounds theBounds) {
    theGunAlpha = a1;
    theInterpolator = pi;
    setSchedulingBounds(theBounds);
    aimXfmGrp = gunRotGrp;
  }

  /**
   * This sets up the criteria for triggering the behaviour. We simple want to
   * wait for a key to be pressed.
   */
  public void initialize() {
    theCriterion = new WakeupOnAWTEvent(KeyEvent.KEY_PRESSED);
    wakeupOn(theCriterion);
  }

  /**
   * This is where the work is done. This identifies which key has been
   * pressed and acts accordingly: left key cursor rotate left, right cursor
   * key rotate right, spacebar fire.
   *
   * @criteria Enumeration that represents the trigger conditions.
   */
  public void processStimulus(Enumeration criteria) {
    while (criteria.hasMoreElements()) {
      WakeupCriterion theCriterion = (WakeupCriterion) criteria
          .nextElement();
      if (theCriterion instanceof WakeupOnAWTEvent) {
        AWTEvent[] triggers = ((WakeupOnAWTEvent) theCriterion)
            .getAWTEvent();
        //Check if it's a keyboard event
        if (triggers[0] instanceof KeyEvent) {
          int keyPressed = ((KeyEvent) triggers[0]).getKeyCode();
          if (keyPressed == KeyEvent.VK_LEFT) {
            //It's a left key so move the turret
            //and the aim of the gun left unless
            //we're at our maximum angle
            if (aim < 8)
              aim += 1;
            System.out.println("Left " + aim);
            aimShotMat.rotY(((aim / 32.0) + 0.5) * Math.PI);
            aimGunMat.rotZ(((aim / -32.0)) * Math.PI);
            aimShotXfm.setRotation(aimShotMat);
            aimGunXfm.setRotation(aimGunMat);
            aimXfmGrp.setTransform(aimGunXfm);
            theInterpolator.setAxisOfTranslation(aimShotXfm);
          } else if (keyPressed == KeyEvent.VK_RIGHT) {
            //It's the right key so do the same but rotate right
            if (aim > -8)
              aim -= 1;
            System.out.println("Right " + aim);
            aimShotMat.rotY(((aim / 32.0) + 0.5) * Math.PI);
            aimGunMat.rotZ(((aim / -32.0)) * Math.PI);
            aimGunXfm.setRotation(aimGunMat);
            aimShotXfm.setRotation(aimShotMat);
            aimXfmGrp.setTransform(aimGunXfm);
            theInterpolator.setAxisOfTranslation(aimShotXfm);
          } else if (keyPressed == KeyEvent.VK_SPACE) {
            //It's the spacebar so reset the start time
            //of the ball's animation
            theGunAlpha.setStartTime(System.currentTimeMillis());
          }
        }
      }
    }
    wakeupOn(theCriterion);
  }
}
```

!!ist nur ein bespiels code!!
dann start ich das ganze und bekomme folgende fehlermeldung:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no j3dcore-ogl in java.library.path
    at java.lang.ClassLoader.loadLibrary(Unknown Source)
    at java.lang.Runtime.loadLibrary0(Unknown Source)
    at java.lang.System.loadLibrary(Unknown Source)
    at javax.media.j3d.NativePipeline$1.run(NativePipeline.java:231)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.media.j3d.NativePipeline.loadLibrary(NativePipeline.java:200)
    at javax.media.j3d.NativePipeline.loadLibraries(NativePipeline.java:157)
    at javax.media.j3d.MasterControl.loadLibraries(MasterControl.java:987)
    at javax.media.j3d.VirtualUniverse.<clinit>(VirtualUniverse.java:299)
    at javax.media.j3d.Canvas3D.<clinit>(Canvas3D.java:3881)
    at SimpleGame.<init>(SimpleGame.java:62)
    at SimpleGame.main(SimpleGame.java:298)

weiß jemand die lösung? wie gesagt der code ist nur zur veranschaulichung, das hauptaugenmerk liegt auf der fehlermeldung 
VG
N0__ESCAPE


----------



## Cromewell (27. Sep 2016)

Vielleicht hilft das: http://stackoverflow.com/questions/4098161/problems-with-java3d-lib-configuration


----------



## Viktim (28. Sep 2016)

Hi, ich hatte damit auch Probleme, und hab dann auch die Anleitung aus der ersten Antwort durchgemacht, die ist echt hilfreich  Erstmal denkt man, dass eteht doch überall so, aber ein paar Schritte werden sonst nicht erklährt 

(Nur nochmal zur Bestätigung von @Cromewell )


----------



## XyMorgan (28. Sep 2016)

Setze in deine Startkonfiguration in Eclipse im Tab -> Arguments den Pfad auf die Fehlenden dlls ->

-Djava.library.path=DEIN PFAD mit den dlls

Hab nicht geschaut was im link steht.


----------



## N0__ESCAPE (28. Sep 2016)

danke an euch drei, habs hinbekommen!


----------

