/*
*
* (c)2010 Lein-Mathisen Digital
* http://lmdig.com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
package com.kristianlm.robotanks.box2dbridge.jnibox2d;
import org.jbox2d.collision.FilterData;
import org.jbox2d.common.Vec2;
import android.util.FloatMath;
import com.kristianlm.robotanks.box2dbridge.IBody;
import com.kristianlm.robotanks.box2dbridge.IShape;
public class JNIBox2DBody implements IBody {
int bodyID;
float angularVelocity = 0;
float angle = 0;
Vec2 position = new Vec2();
Vec2 velocity = new Vec2();
Object userData;
float linearDamping = 0;
float angularDamping = 0;
float inertiaInv;
public JNIBox2DBody(int id) {
this.bodyID = id;
System.out.println("associated " + this + " with " + id);
// let libbox2d know which java object stores the lib's body object
nAssociateJNIObject(id);
}
public void setUserData(Object userData) {
this.userData = userData;
}
/**
* key method!! this function is called by the JNIBox2D engine.
*
* upon every query with (update) set, this function is called for all
* bodies found.
*
* @param x
* @param y
* @param vx
* @param vy
* @param angle
* @param avel
* @param inertiaInv
*/
public void callbackSetData(float x, float y, float vx, float vy,
float angle, float avel, float inertiaInv) {
position.x = x;
position.y = y;
velocity.x = vx;
velocity.y = vy;
this.angle = angle;
this.angularVelocity = avel;
this.inertiaInv = inertiaInv;
}
@Override
public String toString() {
return super.toString() + "_ID<" + bodyID + ">";
}
@Override
public IShape createBox(float width, float height, float x, float y,
float density, float angle) {
int shapeID = nCreateBox(bodyID, width, height, x, y, density, angle);
// System.out.println("Created shape ID " + shapeID);
IShape s = new JNIBox2DShape(shapeID, this);
return s;
}
@Override
public void applyForce(Vec2 force, Vec2 point) {
nApplyForce(bodyID, force.x, force.y, point.x, point.y);
}
@Override
public void applyTorque(float t) {
nApplyTorque(bodyID, t);
}
@Override
public float getAngle() {
// updateData();
return angle;
}
@Override
public float getAngularVelocity() {
// updateData();
return angularVelocity;
}
@Override
public Vec2 getLinearVelocity() {
// updateData();
return velocity;
}
@Override
public Object getUserData() {
return userData;
}
@Override
public Vec2 getWorldCenter() {
// updateData();
return position;
}
@Override
public Vec2 getWorldDirection(Vec2 v) {
float sin = FloatMath.sin(angle);
float cos = FloatMath.cos(angle);
return new Vec2(cos * v.x + -sin * v.y, sin * v.x + cos * v.y);
}
@Override
public void getWorldLocationToOut(Vec2 p, Vec2 q) {
// TODO Auto-generated method stub
}
@Override
public boolean isSleeping() {
// TODO Auto-generated method stub
return false;
}
@Override
public float getInertiaInv() {
// updateData();
return inertiaInv;
}
@Override
public void setPosition(Vec2 pos) {
nSetPosition(bodyID, pos.x, pos.y);
}
@Override
public void setAngularDamping(float d) {
angularDamping = d;
nSetDamping(bodyID, linearDamping, angularDamping);
}
@Override
public void setLinearDamping(float d) {
linearDamping = d;
nSetDamping(bodyID, linearDamping, angularDamping);
}
@Override
public void setMassFromShapes() {
nSetMassFromShapes(bodyID);
}
@Override
public FilterData getFilterData() {
FilterData fd = new FilterData();
nGetFilterData(bodyID, fd);
return fd;
}
public void refilter(int categoryBits, int maskBits, int groupIndex) {
nRefilter(bodyID, categoryBits, maskBits, groupIndex);
}
public void refilter() {
nRefilter(bodyID, 0x01, 0xFF, 0);
}
@Override
public void destroyShape(IShape shape) {
if (!(shape instanceof JNIBox2DShape))
return;
JNIBox2DShape s = (JNIBox2DShape) shape;
nDestroyShape(bodyID, s.shapeID);
}
static {
System.loadLibrary("box2d");
}
native void nUpdateData(int ID);
native int nCreateBox(int ID, float width, float height, float x, float y,
float density, float angle);
native int nCreateShape(int ID, float density, float[] ordered_vlist);
native void nApplyForce(int ID, float fx, float fy, float px, float py);
native public void nApplyTorque(int ID, float t);
/*
* clumpsy, libbox2d stores this object as userData for each body. this way,
* when querying, body objects can be retrieved.
*/
native public void nAssociateJNIObject(int ID);
native public void nSetMassFromShapes(int ID);
native public void nSetDamping(int ID, float linearDamping,
float angularDamping);
native private void nRefilter(int ID, int categoryBits, int maskBits,
int groupIndex);
native private void nGetFilterData(int bodyID, FilterData fd);
native private void nDestroyShape(int bodyID, int shapeID);
native private void nSetPosition(int bodyID, float posx, float posy);
}