/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package automenta.spacenet.space.geom.physics; import automenta.spacenet.space.geom.Box; import automenta.spacenet.var.vector.Quat; import automenta.spacenet.var.vector.V3; import com.bulletphysics.collision.shapes.CollisionShape; import com.bulletphysics.dynamics.RigidBody; import com.bulletphysics.dynamics.RigidBodyConstructionInfo; import com.bulletphysics.linearmath.DefaultMotionState; import com.bulletphysics.linearmath.Transform; import javax.vecmath.Quat4f; import javax.vecmath.Vector3f; /** * * @author seh */ public class PhyBox extends Box { //TODO implement world bounds limiting private RigidBody body; private final Transform t = new Transform(); private final Vector3f v = new Vector3f(); private final Quat4f q = new Quat4f(); private float mass; private CollisionShape collShape; public PhyBox(double w, double h, double d, float mass) { this(new V3(), new V3(w, h, d), mass); } protected CollisionShape newCollisionShape() { return new com.bulletphysics.collision.shapes.BoxShape(new Vector3f(1, 1, 1)); } public class PhyBoxMotionState extends DefaultMotionState { public PhyBoxMotionState(Transform startTransform) { super(startTransform); } @Override public void setWorldTransform(Transform centerOfMassWorldTrans) { super.setWorldTransform(centerOfMassWorldTrans); bulletToArdor(); } } protected void bulletToArdor() { //if (!isPositionStatic()) { //Position getPosition().set(t.origin.x, t.origin.y, t.origin.z); //} //Orientation body.getWorldTransform(t); t.getRotation(q); PhyBox.this.getOrientation().set(q.x, q.y, q.z, q.w); //Size? } public void setVelocity(double vx, double vy, double vz) { body.setLinearVelocity(new Vector3f((float) vx, (float) vy, (float) vz)); } public RigidBody getBody() { return body; } public PhyBox(V3 position, V3 scale, float mass) { this(position, scale, mass, BoxShape.Cubic); } public PhyBox(Box b, float mass) { super(b.getPosition(), b.getSize(), b.getOrientation(), BoxShape.Empty); init(mass); } protected void init(float mass) { this.mass = mass; collShape = newCollisionShape(); Vector3f localInertia = new Vector3f(0, 0, 0); if (mass != 0) { collShape.calculateLocalInertia(mass, localInertia); } Transform startTransform = new Transform(); startTransform.setIdentity(); RigidBodyConstructionInfo rbInfo = new RigidBodyConstructionInfo(mass, new PhyBoxMotionState(startTransform), collShape, localInertia); body = new RigidBody(rbInfo); if (mass != 0) { body.setActivationState(RigidBody.DISABLE_DEACTIVATION); //body.setSleepingThresholds(0.1f, 0.1f); } positionChanged(); sizeChanged(); oriChanged(); setPhysicalOrientation(); rotate(0, 0, 0); } /** * * @param position * @param scale * @param mass set mass=0 for static (frozen, non-dynamic) object */ public PhyBox(V3 position, V3 scale, float mass, BoxShape shape) { super(position, scale, new Quat(), shape); init(mass); } @Override protected void sizeChanged() { super.sizeChanged(); //Scale v.set(getSize().getXf() / 2.0f, getSize().getYf() / 2.0f, getSize().getZf() / 2.0f); body.getCollisionShape().setLocalScaling(v); } @Override public Box rotate(double heading, double attitude, double bank) { Box b = super.rotate(heading, attitude, bank); setPhysicalOrientation(); return b; } protected void setPhysicalOrientation() { body.getWorldTransform(t); t.getRotation(q); q.set(getOrientation().getXf(), getOrientation().getYf(), getOrientation().getZf(), getOrientation().getWf()); System.out.println("node -> phy: " + q); t.setRotation(q); body.setWorldTransform(t); } @Override protected void oriChanged() { super.oriChanged(); } @Override protected void positionChanged() { super.positionChanged(); body.getWorldTransform(t); t.origin.set(getPosition().getXf(), getPosition().getYf(), getPosition().getZf()); body.setWorldTransform(t); } public boolean isPositionStatic() { return mass == 0; } }