1 /******************************************************************************* 2 * Copyright 2011 See AUTHORS file. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 ******************************************************************************/ 16 17 package com.badlogic.gdx.tests.bullet; 18 19 import com.badlogic.gdx.graphics.g3d.Model; 20 import com.badlogic.gdx.graphics.g3d.ModelInstance; 21 import com.badlogic.gdx.math.Matrix4; 22 import com.badlogic.gdx.math.Vector3; 23 import com.badlogic.gdx.math.collision.BoundingBox; 24 import com.badlogic.gdx.physics.bullet.collision.btCollisionObject; 25 import com.badlogic.gdx.physics.bullet.dynamics.btRigidBody; 26 import com.badlogic.gdx.physics.bullet.dynamics.btRigidBody.btRigidBodyConstructionInfo; 27 import com.badlogic.gdx.physics.bullet.linearmath.btMotionState; 28 29 /** @author xoppa Renderable BaseEntity with a bullet physics body. */ 30 public class BulletEntity extends BaseEntity { 31 private final static Matrix4 tmpM = new Matrix4(); 32 public BulletEntity.MotionState motionState; 33 public btCollisionObject body; 34 35 public final BoundingBox boundingBox = new BoundingBox(); 36 public final float boundingBoxRadius; 37 BulletEntity(final Model model, final btRigidBodyConstructionInfo bodyInfo, final float x, final float y, final float z)38 public BulletEntity (final Model model, final btRigidBodyConstructionInfo bodyInfo, final float x, final float y, final float z) { 39 this(model, bodyInfo == null ? null : new btRigidBody(bodyInfo), x, y, z); 40 } 41 BulletEntity(final Model model, final btRigidBodyConstructionInfo bodyInfo, final Matrix4 transform)42 public BulletEntity (final Model model, final btRigidBodyConstructionInfo bodyInfo, final Matrix4 transform) { 43 this(model, bodyInfo == null ? null : new btRigidBody(bodyInfo), transform); 44 } 45 BulletEntity(final Model model, final btCollisionObject body, final float x, final float y, final float z)46 public BulletEntity (final Model model, final btCollisionObject body, final float x, final float y, final float z) { 47 this(model, body, tmpM.setToTranslation(x, y, z)); 48 } 49 BulletEntity(final Model model, final btCollisionObject body, final Matrix4 transform)50 public BulletEntity (final Model model, final btCollisionObject body, final Matrix4 transform) { 51 this(new ModelInstance(model, transform.cpy()), body); 52 } 53 BulletEntity(final ModelInstance modelInstance, final btCollisionObject body)54 public BulletEntity (final ModelInstance modelInstance, final btCollisionObject body) { 55 this.modelInstance = modelInstance; 56 this.transform = this.modelInstance.transform; 57 this.body = body; 58 59 modelInstance.calculateBoundingBox(boundingBox); 60 boundingBoxRadius = boundingBox.getDimensions(new Vector3()).len() * 0.5f; 61 62 if (body != null) { 63 body.userData = this; 64 if (body instanceof btRigidBody) { 65 this.motionState = new MotionState(this.modelInstance.transform); 66 ((btRigidBody)this.body).setMotionState(motionState); 67 } else 68 body.setWorldTransform(transform); 69 } 70 } 71 72 @Override dispose()73 public void dispose () { 74 // Don't rely on the GC 75 if (motionState != null) motionState.dispose(); 76 if (body != null) body.dispose(); 77 // And remove the reference 78 motionState = null; 79 body = null; 80 } 81 82 static class MotionState extends btMotionState { 83 private final Matrix4 transform; 84 MotionState(final Matrix4 transform)85 public MotionState (final Matrix4 transform) { 86 this.transform = transform; 87 } 88 89 /** For dynamic and static bodies this method is called by bullet once to get the initial state of the body. For kinematic 90 * bodies this method is called on every update, unless the body is deactivated. */ 91 @Override getWorldTransform(final Matrix4 worldTrans)92 public void getWorldTransform (final Matrix4 worldTrans) { 93 worldTrans.set(transform); 94 } 95 96 /** For dynamic bodies this method is called by bullet every update to inform about the new position and rotation. */ 97 @Override setWorldTransform(final Matrix4 worldTrans)98 public void setWorldTransform (final Matrix4 worldTrans) { 99 transform.set(worldTrans); 100 } 101 } 102 } 103