Package jinngine.rendering

Source Code of jinngine.rendering.Interaction

package jinngine.rendering;

import java.util.Iterator;

import jinngine.collision.RayCast;
import jinngine.geometry.Geometry;
import jinngine.geometry.SupportMap3;
import jinngine.math.InertiaMatrix;
import jinngine.math.Matrix3;
import jinngine.math.Vector3;
import jinngine.physics.Body;
import jinngine.physics.Scene;
import jinngine.physics.constraint.joint.BallInSocketJoint;


public class Interaction implements Rendering.EventCallback {
  private final Scene scene;
  private boolean interacting = false;
  private Body target = null;
  private final Body controller = new Body("InteractionController");
  private final Vector3 pickpoint = new Vector3();
  private BallInSocketJoint force;
  private Matrix3 inertia;
  private Matrix3 inverse;
  private final Vector3 planeNormal = new Vector3(0,1,0);
 
  public Interaction( Scene scene) {
    this.scene = scene;
    this.controller.state.anisotropicmass.assignScale(1); // hope to prevent bugs
    this.controller.setFixed(true);
  }
 
  @Override
  public void mouseDragged(double x, double y, Vector3 point, Vector3 direction) {
    // update body
 
    // intersect the pointer ray with the interaction plane to get a target point
    double u = planeNormal.dot(pickpoint.sub(point)) / planeNormal.dot(direction);

    // move controller body to target position
    controller.setPosition(point.add(direction.multiply(u)));
  }

  @Override
  public void mousePressed(double x, double y, Vector3 point, Vector3 direction) {
    target = null;
    interacting = false;
    double parameter = Double.POSITIVE_INFINITY;
    Iterator<Body> bodies = scene.getBodies();
    // go thru each body
    while (bodies.hasNext()) {
      Body bi = bodies.next();

      // only shoot at non-fixed bodies
      if ( !bi.isFixed()) {
        Iterator<Geometry> geometries = bi.getGeometries();
        Geometry gi = geometries.next();

        // if geometry is usable
        if ( gi instanceof SupportMap3) {

          RayCast raycast = new RayCast();
          Vector3 pb = new Vector3(), pc = new Vector3();
          double t = raycast.run((SupportMap3)gi, null, point, direction, pb, pc, 0, 0.05, 1e-7, true);

//          write out t for debugging
//          System.out.println("t="+t);
         
          if (t<parameter) {
            parameter = t;
            target = bi;
            pickpoint.assign(point.add(direction.multiply(t)));
//            pickpoint.print();
          }
        } // if support map
      } // body is unfixed
    }
   
    // clicked something?
    if (target != null) {
      interacting = true;
     
//      System.out.println("found " + target);
     
      // place controller body into the world at the centre of mass
      // of target body
      controller.setVelocity(new Vector3());
      controller.setPosition(pickpoint);
      controller.updateTransformations();
      target.updateTransformations();

      this.force = new BallInSocketJoint(target, controller, controller.getPosition(), new Vector3(0,1,0));
      this.force.setForceLimit(1.5*target.getMass());
      this.force.setCorrectionVelocityLimit(7);
     
      // copy angular mass properties
      inertia = new InertiaMatrix(target.state.inertia);
      inverse = new InertiaMatrix(target.state.inverseinertia);

      // mute angular movement
      target.state.inverseinertia.assignZero();
     
      // remove current movement
      target.setVelocity(0,0,0);
      target.setAngularVelocity(0,0,0);

      // insert the acting stuff into the physics world
      scene.addBody(this.controller);
      scene.addConstraint(this.force);
      scene.addLiveConstraint(this.force);
    }
  }

  @Override
  public void mouseReleased() {
    if (interacting) {           
      // remove controller body and force
      scene.removeConstraint(this.force);
      scene.removeBody(this.controller)
      scene.removeLiveConstraint(this.force);
         
      // restore angular inertia properties
      target.state.inertia.assign(inertia);
      target.state.inverseinertia.assign(inverse);

      // reset state
      target = null;
      interacting = false;     
    }
  }

  @Override
  public void spacePressed() {
    // set new plane normal and re-start pickpoint
    planeNormal.assign(0,0,1);
    pickpoint.assign(controller.getPosition());

  }

  @Override
  public void spaceReleased() {
    // set new plane normal and re-start pickpoint
    planeNormal.assign(0,1,0)
    pickpoint.assign(controller.getPosition());

  }

}
TOP

Related Classes of jinngine.rendering.Interaction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.