/*******************************************************************************
* Copyright 2011 See AUTHORS file.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package com.badlogic.gdx.tests.bullet;
import com.badlogic.gdx.graphics.g3d.Model;
import com.badlogic.gdx.graphics.g3d.ModelInstance;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.math.collision.BoundingBox;
import com.badlogic.gdx.physics.bullet.collision.btCollisionObject;
import com.badlogic.gdx.physics.bullet.dynamics.btRigidBody;
import com.badlogic.gdx.physics.bullet.dynamics.btRigidBody.btRigidBodyConstructionInfo;
import com.badlogic.gdx.physics.bullet.linearmath.btMotionState;
/** @author xoppa Renderable BaseEntity with a bullet physics body. */
public class BulletEntity extends BaseEntity {
private final static Matrix4 tmpM = new Matrix4();
public BulletEntity.MotionState motionState;
public btCollisionObject body;
public final BoundingBox boundingBox = new BoundingBox();
public final float boundingBoxRadius;
public BulletEntity (final Model model, final btRigidBodyConstructionInfo bodyInfo, final float x, final float y, final float z) {
this(model, bodyInfo == null ? null : new btRigidBody(bodyInfo), x, y, z);
}
public BulletEntity (final Model model, final btRigidBodyConstructionInfo bodyInfo, final Matrix4 transform) {
this(model, bodyInfo == null ? null : new btRigidBody(bodyInfo), transform);
}
public BulletEntity (final Model model, final btCollisionObject body, final float x, final float y, final float z) {
this(model, body, tmpM.setToTranslation(x, y, z));
}
public BulletEntity (final Model model, final btCollisionObject body, final Matrix4 transform) {
this(new ModelInstance(model, transform.cpy()), body);
}
public BulletEntity (final ModelInstance modelInstance, final btCollisionObject body) {
this.modelInstance = modelInstance;
this.transform = this.modelInstance.transform;
this.body = body;
modelInstance.calculateBoundingBox(boundingBox);
boundingBoxRadius = boundingBox.getDimensions(new Vector3()).len() * 0.5f;
if (body != null) {
body.userData = this;
if (body instanceof btRigidBody) {
this.motionState = new MotionState(this.modelInstance.transform);
((btRigidBody)this.body).setMotionState(motionState);
} else
body.setWorldTransform(transform);
}
}
@Override
public void dispose () {
// Don't rely on the GC
if (motionState != null) motionState.dispose();
if (body != null) body.dispose();
// And remove the reference
motionState = null;
body = null;
}
static class MotionState extends btMotionState {
private final Matrix4 transform;
public MotionState (final Matrix4 transform) {
this.transform = transform;
}
/** For dynamic and static bodies this method is called by bullet once to get the initial state of the body. For kinematic
* bodies this method is called on every update, unless the body is deactivated. */
@Override
public void getWorldTransform (final Matrix4 worldTrans) {
worldTrans.set(transform);
}
/** For dynamic bodies this method is called by bullet every update to inform about the new position and rotation. */
@Override
public void setWorldTransform (final Matrix4 worldTrans) {
transform.set(worldTrans);
}
}
}