package components; import gl.scenegraph.MeshComponent; import util.Log; import util.Vec; import worldData.Entity; import worldData.Obj; import worldData.Updateable; import worldData.Visitor; /** * currently only for testing! not functional jet * * @author Spobo * */ public class PhysicsComponent implements Entity { public static final float FRICTION = 1; // TODO make world dependant public static final Vec GRAVITY = new Vec(0, 0, 0); private static final String LOG_TAG = "PhysicsComponent"; Boolean physicsActive = true; public Vec force = new Vec(); private Vec velocity = new Vec(); private Vec accel = new Vec(); private float mass = 1; private Updateable myParent; @Override public boolean accept(Visitor visitor) { return visitor.default_visit(this); } @Override public Updateable getMyParent() { Log.e(LOG_TAG, "Get parent called which is not " + "implemented for this component!"); return null; } @Override public void setMyParent(Updateable parent) { // can't have children so the parent does not have to be stored Log.e(LOG_TAG, "Set parent called which is not " + "implemented for this component!"); } @Override public boolean update(float timeDelta, Updateable parent) { if (physicsActive) { Obj obj = (Obj) parent; final MeshComponent v = obj.getGraphicsComponent(); updateAccel(timeDelta); velocityVerletIntegration(timeDelta, v.getPosition()); updateSpeed(timeDelta); iterateCollisions(timeDelta, obj); } return true; } private void updateSpeed(float td) { velocity.mult(1 / FRICTION); // TODO correct with dt this way? } private void updateAccel(float timeDelta) { accel.setToZero(); accel.add(GRAVITY); } /** * velocity verlet integration, should be by rigid body simulation.. <a * href="http://en.wikipedia.org/wiki/Verlet_integration">Wiki text * * @param dt * * @param x */ private void velocityVerletIntegration(float dt, Vec x) { // step 1: x.add(Vec.mult(dt, velocity).add(Vec.mult(0.5f * dt * dt, accel))); // step 2: Vec velocHalf = Vec.add(velocity, Vec.mult(0.5f * dt, accel)); // step 3: addForceToAcceleration(dt); // step 4: velocity.setToVec(Vec.add(velocHalf, Vec.mult(0.5f * dt, accel))); } private void addForceToAcceleration(float dt) { if (!force.isNullVector()) { accel.add(Vec.mult(1 / mass, force)); } force.setToZero(); } private void iterateCollisions(float timeDelta, Obj obj) { // check for collisions and solve them. do this several times to avoid // clipping bugs etc } }