2017-09-30 00:32:06 +02:00
|
|
|
package armory.trait.physics.bullet;
|
2015-11-26 22:30:19 +01:00
|
|
|
|
2017-09-30 02:15:21 +02:00
|
|
|
#if arm_bullet
|
|
|
|
|
2015-11-26 22:30:19 +01:00
|
|
|
import haxebullet.Bullet;
|
2016-07-10 00:51:39 +02:00
|
|
|
import iron.math.Vec4;
|
2018-08-28 13:50:52 +02:00
|
|
|
import iron.math.Quat;
|
2016-08-25 00:26:01 +02:00
|
|
|
import iron.object.Transform;
|
|
|
|
import iron.object.MeshObject;
|
2015-11-26 22:30:19 +01:00
|
|
|
|
2018-08-23 20:26:40 +02:00
|
|
|
/**
|
|
|
|
* RigidBody is used to allow objects to interact with Physics in your game including collisions and gravity.
|
|
|
|
* RigidBody can also be used with the getContacts method to detect collisions and run appropriate code.
|
|
|
|
* The Bullet physics engine is used for these calculations.
|
|
|
|
*/
|
2018-08-17 17:01:54 +02:00
|
|
|
@:access(armory.trait.physics.bullet.PhysicsWorld)
|
2018-07-24 21:28:03 +02:00
|
|
|
class RigidBody extends iron.Trait {
|
2015-11-26 22:30:19 +01:00
|
|
|
|
2016-07-19 19:42:46 +02:00
|
|
|
var shape:Shape;
|
2015-11-26 22:30:19 +01:00
|
|
|
public var physics:PhysicsWorld;
|
2016-10-09 16:06:18 +02:00
|
|
|
public var transform:Transform = null;
|
2015-11-26 22:30:19 +01:00
|
|
|
public var mass:Float;
|
|
|
|
public var friction:Float;
|
2017-05-14 11:59:12 +02:00
|
|
|
public var restitution:Float;
|
2016-05-06 23:46:04 +02:00
|
|
|
public var collisionMargin:Float;
|
2016-12-08 14:30:39 +01:00
|
|
|
public var linearDamping:Float;
|
|
|
|
public var angularDamping:Float;
|
2017-11-13 10:18:37 +01:00
|
|
|
public var animated:Bool;
|
2018-08-27 07:35:39 +02:00
|
|
|
public var destroyed = false;
|
2017-11-06 13:01:08 +01:00
|
|
|
var linearFactors:Array<Float>;
|
|
|
|
var angularFactors:Array<Float>;
|
|
|
|
var deactivationParams:Array<Float>;
|
2018-10-30 12:56:49 +01:00
|
|
|
var ccd = false; // Continuous collision detection
|
2017-10-29 19:34:10 +01:00
|
|
|
public var group = 1;
|
2017-12-12 20:07:31 +01:00
|
|
|
public var trigger = false;
|
2017-12-12 13:39:15 +01:00
|
|
|
var bodyScaleX:Float; // Transform scale at creation time
|
|
|
|
var bodyScaleY:Float;
|
|
|
|
var bodyScaleZ:Float;
|
|
|
|
var currentScaleX:Float;
|
|
|
|
var currentScaleY:Float;
|
|
|
|
var currentScaleZ:Float;
|
2015-11-26 22:30:19 +01:00
|
|
|
|
2016-01-21 02:37:36 +01:00
|
|
|
public var body:BtRigidBodyPointer = null;
|
2018-08-23 20:26:40 +02:00
|
|
|
public var motionState:BtMotionStatePointer;
|
|
|
|
public var btshape:BtCollisionShapePointer;
|
2016-12-07 02:01:42 +01:00
|
|
|
public var ready = false;
|
2015-11-26 22:30:19 +01:00
|
|
|
static var nextId = 0;
|
|
|
|
public var id = 0;
|
2016-10-02 19:52:40 +02:00
|
|
|
public var onReady:Void->Void = null;
|
2018-08-17 10:20:46 +02:00
|
|
|
public var onContact:Array<RigidBody->Void> = null;
|
2015-11-26 22:30:19 +01:00
|
|
|
|
2018-08-23 20:26:40 +02:00
|
|
|
static var nullvec = true;
|
|
|
|
static var vec1:BtVector3;
|
|
|
|
static var vec2:BtVector3;
|
|
|
|
static var vec3:BtVector3;
|
|
|
|
static var quat1:BtQuaternion;
|
|
|
|
static var trans1:BtTransform;
|
|
|
|
static var trans2:BtTransform;
|
2018-08-28 13:50:52 +02:00
|
|
|
static var quat = new Quat();
|
2018-08-23 20:26:40 +02:00
|
|
|
|
2017-05-14 11:59:12 +02:00
|
|
|
public function new(mass = 1.0, shape = Shape.Box, friction = 0.5, restitution = 0.0, collisionMargin = 0.0,
|
2017-11-13 10:18:37 +01:00
|
|
|
linearDamping = 0.04, angularDamping = 0.1, animated = false,
|
2017-11-06 13:01:08 +01:00
|
|
|
linearFactors:Array<Float> = null, angularFactors:Array<Float> = null,
|
2018-10-30 12:56:49 +01:00
|
|
|
group = 1, trigger = false, deactivationParams:Array<Float> = null, ccd = false) {
|
2015-11-26 22:30:19 +01:00
|
|
|
super();
|
|
|
|
|
2018-08-23 20:26:40 +02:00
|
|
|
if (nullvec) {
|
|
|
|
nullvec = false;
|
|
|
|
vec1 = BtVector3.create(0, 0, 0);
|
|
|
|
vec2 = BtVector3.create(0, 0, 0);
|
|
|
|
vec3 = BtVector3.create(0, 0, 0);
|
|
|
|
quat1 = BtQuaternion.create(0, 0, 0, 0);
|
|
|
|
trans1 = BtTransform.create();
|
|
|
|
trans2 = BtTransform.create();
|
|
|
|
}
|
|
|
|
|
2015-11-26 22:30:19 +01:00
|
|
|
this.mass = mass;
|
|
|
|
this.shape = shape;
|
|
|
|
this.friction = friction;
|
2017-05-14 11:59:12 +02:00
|
|
|
this.restitution = restitution;
|
2016-05-06 23:46:04 +02:00
|
|
|
this.collisionMargin = collisionMargin;
|
2016-12-08 14:30:39 +01:00
|
|
|
this.linearDamping = linearDamping;
|
|
|
|
this.angularDamping = angularDamping;
|
2017-11-13 10:18:37 +01:00
|
|
|
this.animated = animated;
|
2017-11-06 13:01:08 +01:00
|
|
|
this.linearFactors = linearFactors;
|
|
|
|
this.angularFactors = angularFactors;
|
2017-10-29 19:34:10 +01:00
|
|
|
this.group = group;
|
2017-12-12 20:07:31 +01:00
|
|
|
this.trigger = trigger;
|
2017-11-06 13:01:08 +01:00
|
|
|
this.deactivationParams = deactivationParams;
|
2018-10-30 12:56:49 +01:00
|
|
|
this.ccd = ccd;
|
2017-04-16 14:46:35 +02:00
|
|
|
|
|
|
|
notifyOnAdd(init);
|
2015-11-26 22:30:19 +01:00
|
|
|
}
|
2016-05-06 23:46:04 +02:00
|
|
|
|
|
|
|
inline function withMargin(f:Float) {
|
|
|
|
return f - f * collisionMargin;
|
|
|
|
}
|
2015-11-26 22:30:19 +01:00
|
|
|
|
2016-10-02 19:52:40 +02:00
|
|
|
public function notifyOnReady(f:Void->Void) {
|
|
|
|
onReady = f;
|
2017-04-20 11:13:33 +02:00
|
|
|
if (ready) onReady();
|
2016-10-02 19:52:40 +02:00
|
|
|
}
|
|
|
|
|
2015-11-26 22:30:19 +01:00
|
|
|
public function init() {
|
2016-12-07 02:01:42 +01:00
|
|
|
if (ready) return;
|
|
|
|
ready = true;
|
2018-02-04 22:57:12 +01:00
|
|
|
|
|
|
|
if (!Std.is(object, MeshObject)) return; // No mesh data
|
|
|
|
|
2017-04-02 13:13:43 +02:00
|
|
|
transform = object.transform;
|
2017-09-30 00:32:06 +02:00
|
|
|
physics = armory.trait.physics.PhysicsWorld.active;
|
2017-04-02 13:13:43 +02:00
|
|
|
|
2016-07-19 19:42:46 +02:00
|
|
|
if (shape == Shape.Box) {
|
2018-08-23 20:26:40 +02:00
|
|
|
vec1.setX(withMargin(transform.dim.x / 2));
|
|
|
|
vec1.setY(withMargin(transform.dim.y / 2));
|
|
|
|
vec1.setZ(withMargin(transform.dim.z / 2));
|
|
|
|
btshape = BtBoxShape.create(vec1);
|
2015-11-26 22:30:19 +01:00
|
|
|
}
|
2016-07-19 19:42:46 +02:00
|
|
|
else if (shape == Shape.Sphere) {
|
2018-08-23 20:26:40 +02:00
|
|
|
btshape = BtSphereShape.create(withMargin(transform.dim.x / 2));
|
2015-11-26 22:30:19 +01:00
|
|
|
}
|
2018-08-17 17:01:54 +02:00
|
|
|
else if (shape == Shape.ConvexHull) {
|
2018-08-23 20:26:40 +02:00
|
|
|
var shapeConvex = BtConvexHullShape.create();
|
|
|
|
fillConvexHull(shapeConvex, transform.scale, collisionMargin);
|
|
|
|
btshape = shapeConvex;
|
2015-11-26 22:30:19 +01:00
|
|
|
}
|
2016-07-19 19:42:46 +02:00
|
|
|
else if (shape == Shape.Cone) {
|
2018-08-23 20:26:40 +02:00
|
|
|
btshape = BtConeShapeZ.create(
|
2017-11-26 20:43:59 +01:00
|
|
|
withMargin(transform.dim.x / 2), // Radius
|
|
|
|
withMargin(transform.dim.z)); // Height
|
2015-11-26 22:30:19 +01:00
|
|
|
}
|
2016-07-19 19:42:46 +02:00
|
|
|
else if (shape == Shape.Cylinder) {
|
2018-08-23 20:26:40 +02:00
|
|
|
vec1.setX(withMargin(transform.dim.x / 2));
|
|
|
|
vec1.setY(withMargin(transform.dim.y / 2));
|
|
|
|
vec1.setZ(withMargin(transform.dim.z / 2));
|
|
|
|
btshape = BtCylinderShapeZ.create(vec1);
|
2015-11-26 22:30:19 +01:00
|
|
|
}
|
2016-07-19 19:42:46 +02:00
|
|
|
else if (shape == Shape.Capsule) {
|
2017-11-26 20:43:59 +01:00
|
|
|
var r = transform.dim.x / 2;
|
2018-08-23 20:26:40 +02:00
|
|
|
btshape = BtCapsuleShapeZ.create(
|
2016-12-08 14:30:39 +01:00
|
|
|
withMargin(r), // Radius
|
2017-11-26 20:43:59 +01:00
|
|
|
withMargin(transform.dim.z - r * 2)); // Height between 2 sphere centers
|
2015-11-26 22:30:19 +01:00
|
|
|
}
|
2018-08-17 17:01:54 +02:00
|
|
|
else if (shape == Shape.Mesh || shape == Shape.Terrain) {
|
2015-11-26 22:30:19 +01:00
|
|
|
var meshInterface = BtTriangleMesh.create(true, true);
|
2016-05-25 00:13:44 +02:00
|
|
|
fillTriangleMesh(meshInterface, transform.scale);
|
2018-08-17 17:01:54 +02:00
|
|
|
if (mass > 0) {
|
2018-08-23 20:26:40 +02:00
|
|
|
var shapeGImpact = BtGImpactMeshShape.create(meshInterface);
|
|
|
|
shapeGImpact.updateBound();
|
|
|
|
btshape = shapeGImpact;
|
2018-08-17 17:01:54 +02:00
|
|
|
if (!physics.gimpactRegistered) {
|
2018-08-21 13:08:19 +02:00
|
|
|
#if js
|
|
|
|
GImpactCollisionAlgorithm.create().registerAlgorithm(physics.dispatcher);
|
|
|
|
#else
|
2018-08-17 17:01:54 +02:00
|
|
|
BtGImpactCollisionAlgorithm.registerAlgorithm(physics.dispatcher);
|
2018-08-21 13:08:19 +02:00
|
|
|
#end
|
2018-08-17 17:01:54 +02:00
|
|
|
physics.gimpactRegistered = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2018-08-23 20:26:40 +02:00
|
|
|
btshape = BtBvhTriangleMeshShape.create(meshInterface, true, true);
|
2018-08-17 17:01:54 +02:00
|
|
|
}
|
2015-11-26 22:30:19 +01:00
|
|
|
}
|
2017-12-05 23:45:40 +01:00
|
|
|
//else if (shape == Shape.Terrain) {
|
2017-12-04 15:10:20 +01:00
|
|
|
// var data:Array<Dynamic> = [];
|
2018-08-23 20:26:40 +02:00
|
|
|
// btshape = BtHeightfieldTerrainShape.create(3, 3, data, 1, -10, 10, 2, 0, true);
|
2017-12-04 15:10:20 +01:00
|
|
|
//}
|
2015-11-26 22:30:19 +01:00
|
|
|
|
2018-08-23 20:26:40 +02:00
|
|
|
trans1.setIdentity();
|
|
|
|
vec1.setX(transform.worldx());
|
|
|
|
vec1.setY(transform.worldy());
|
|
|
|
vec1.setZ(transform.worldz());
|
|
|
|
trans1.setOrigin(vec1);
|
2018-08-28 13:50:52 +02:00
|
|
|
quat.fromMat(transform.world);
|
|
|
|
quat1.setX(quat.x);
|
|
|
|
quat1.setY(quat.y);
|
|
|
|
quat1.setZ(quat.z);
|
|
|
|
quat1.setW(quat.w);
|
2018-08-23 20:26:40 +02:00
|
|
|
trans1.setRotation(quat1);
|
|
|
|
|
|
|
|
var centerOfMassOffset = trans2;
|
|
|
|
centerOfMassOffset.setIdentity();
|
|
|
|
motionState = BtDefaultMotionState.create(trans1, centerOfMassOffset);
|
|
|
|
|
|
|
|
vec1.setX(0);
|
|
|
|
vec1.setY(0);
|
|
|
|
vec1.setZ(0);
|
|
|
|
var inertia = vec1;
|
|
|
|
if (mass > 0) btshape.calculateLocalInertia(mass, inertia);
|
|
|
|
var bodyCI = BtRigidBodyConstructionInfo.create(mass, motionState, btshape, inertia);
|
|
|
|
body = BtRigidBody.create(bodyCI);
|
2017-04-02 13:13:43 +02:00
|
|
|
body.setFriction(friction);
|
2018-11-12 10:44:15 +01:00
|
|
|
// body.setRollingFriction(friction); // This causes bodies to get stuck, apply angular damping instead
|
|
|
|
if (shape == Shape.Sphere || shape == Shape.Cylinder || shape == Shape.Cone || shape == Shape.Capsule) {
|
|
|
|
angularDamping += friction;
|
|
|
|
}
|
2017-05-14 11:59:12 +02:00
|
|
|
body.setRestitution(restitution);
|
2015-11-26 22:30:19 +01:00
|
|
|
|
2017-11-06 13:01:08 +01:00
|
|
|
if (deactivationParams != null) {
|
|
|
|
setDeactivationParams(deactivationParams[0], deactivationParams[1], deactivationParams[2]);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
setActivationState(ActivationState.NoDeactivation);
|
|
|
|
}
|
2015-11-26 22:30:19 +01:00
|
|
|
|
2016-12-08 14:30:39 +01:00
|
|
|
if (linearDamping != 0.04 || angularDamping != 0.1) {
|
2017-02-26 15:09:36 +01:00
|
|
|
body.setDamping(linearDamping, angularDamping);
|
2016-12-08 14:30:39 +01:00
|
|
|
}
|
|
|
|
|
2017-11-06 13:01:08 +01:00
|
|
|
if (linearFactors != null) {
|
|
|
|
setLinearFactor(linearFactors[0], linearFactors[1], linearFactors[2]);
|
2017-10-23 17:26:17 +02:00
|
|
|
}
|
|
|
|
|
2017-11-06 13:01:08 +01:00
|
|
|
if (angularFactors != null) {
|
|
|
|
setAngularFactor(angularFactors[0], angularFactors[1], angularFactors[2]);
|
2017-10-23 17:26:17 +02:00
|
|
|
}
|
|
|
|
|
2017-12-12 20:07:31 +01:00
|
|
|
if (trigger) body.setCollisionFlags(body.getCollisionFlags() | BtCollisionObject.CF_NO_CONTACT_RESPONSE);
|
2017-11-02 13:32:21 +01:00
|
|
|
|
2018-10-30 12:56:49 +01:00
|
|
|
if (ccd) setCcd(transform.radius);
|
|
|
|
|
2017-12-12 13:39:15 +01:00
|
|
|
bodyScaleX = currentScaleX = transform.scale.x;
|
|
|
|
bodyScaleY = currentScaleY = transform.scale.y;
|
|
|
|
bodyScaleZ = currentScaleZ = transform.scale.z;
|
|
|
|
|
2017-11-06 13:01:08 +01:00
|
|
|
id = nextId;
|
|
|
|
nextId++;
|
|
|
|
|
2015-11-26 22:30:19 +01:00
|
|
|
#if js
|
|
|
|
//body.setUserIndex(nextId);
|
|
|
|
untyped body.userIndex = id;
|
|
|
|
#elseif cpp
|
2017-02-26 15:09:36 +01:00
|
|
|
body.setUserIndex(id);
|
2015-11-26 22:30:19 +01:00
|
|
|
#end
|
|
|
|
|
|
|
|
physics.addRigidBody(this);
|
2018-09-13 14:49:34 +02:00
|
|
|
notifyOnRemove(removeFromWorld);
|
2015-11-26 22:30:19 +01:00
|
|
|
|
2016-10-02 19:52:40 +02:00
|
|
|
if (onReady != null) onReady();
|
2018-08-23 20:26:40 +02:00
|
|
|
|
|
|
|
#if js
|
|
|
|
Ammo.destroy(bodyCI);
|
|
|
|
#end
|
2015-11-26 22:30:19 +01:00
|
|
|
}
|
|
|
|
|
2018-09-13 14:49:34 +02:00
|
|
|
function physicsUpdate() {
|
2016-12-07 02:01:42 +01:00
|
|
|
if (!ready) return;
|
2017-11-13 10:18:37 +01:00
|
|
|
if (object.animation != null || animated) {
|
2016-10-09 16:06:18 +02:00
|
|
|
syncTransform();
|
|
|
|
}
|
|
|
|
else {
|
2017-02-26 15:09:36 +01:00
|
|
|
var trans = body.getWorldTransform();
|
2016-10-09 16:06:18 +02:00
|
|
|
var p = trans.getOrigin();
|
|
|
|
var q = trans.getRotation();
|
|
|
|
transform.loc.set(p.x(), p.y(), p.z());
|
|
|
|
transform.rot.set(q.x(), q.y(), q.z(), q.w());
|
2017-08-23 00:53:26 +02:00
|
|
|
if (object.parent != null) {
|
|
|
|
var ptransform = object.parent.transform;
|
|
|
|
transform.loc.x -= ptransform.worldx();
|
|
|
|
transform.loc.y -= ptransform.worldy();
|
|
|
|
transform.loc.z -= ptransform.worldz();
|
|
|
|
}
|
2017-03-12 17:29:22 +01:00
|
|
|
transform.buildMatrix();
|
2016-10-09 16:06:18 +02:00
|
|
|
}
|
2018-08-17 10:20:46 +02:00
|
|
|
|
|
|
|
if (onContact != null) {
|
|
|
|
var rbs = physics.getContacts(this);
|
|
|
|
if (rbs != null) for (rb in rbs) for (f in onContact) f(rb);
|
|
|
|
}
|
2015-11-26 22:30:19 +01:00
|
|
|
}
|
|
|
|
|
2016-04-27 10:29:32 +02:00
|
|
|
public function removeFromWorld() {
|
2016-09-14 11:49:32 +02:00
|
|
|
if (physics != null) physics.removeRigidBody(this);
|
2015-11-26 22:30:19 +01:00
|
|
|
}
|
|
|
|
|
2016-04-27 10:29:32 +02:00
|
|
|
public function activate() {
|
2017-02-26 15:09:36 +01:00
|
|
|
body.activate(false);
|
2015-11-26 22:30:19 +01:00
|
|
|
}
|
|
|
|
|
2016-04-27 10:29:32 +02:00
|
|
|
public function disableGravity() {
|
2018-08-23 20:26:40 +02:00
|
|
|
vec1.setX(0);
|
|
|
|
vec1.setY(0);
|
|
|
|
vec1.setZ(0);
|
|
|
|
body.setGravity(vec1);
|
2015-11-26 22:30:19 +01:00
|
|
|
}
|
|
|
|
|
2017-12-14 14:33:58 +01:00
|
|
|
public function enableGravity() {
|
|
|
|
body.setGravity(physics.world.getGravity());
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setGravity(v:Vec4) {
|
2018-08-23 20:26:40 +02:00
|
|
|
vec1.setX(v.x);
|
|
|
|
vec1.setY(v.y);
|
|
|
|
vec1.setZ(v.z);
|
|
|
|
body.setGravity(vec1);
|
2017-12-14 14:33:58 +01:00
|
|
|
}
|
2015-11-26 22:30:19 +01:00
|
|
|
|
2017-01-19 00:26:18 +01:00
|
|
|
public function setActivationState(newState:Int) {
|
2017-02-26 15:09:36 +01:00
|
|
|
body.setActivationState(newState);
|
2017-01-19 00:26:18 +01:00
|
|
|
}
|
2015-11-26 22:30:19 +01:00
|
|
|
|
2017-11-06 13:01:08 +01:00
|
|
|
public function setDeactivationParams(linearThreshold:Float, angularThreshold:Float, time:Float) {
|
|
|
|
body.setSleepingThresholds(linearThreshold, angularThreshold);
|
|
|
|
// body.setDeactivationTime(time); // not available in ammo
|
|
|
|
}
|
|
|
|
|
2018-04-18 02:26:33 +02:00
|
|
|
public function applyForce(force:Vec4, loc:Vec4 = null) {
|
|
|
|
activate();
|
2018-08-23 20:26:40 +02:00
|
|
|
vec1.setX(force.x);
|
|
|
|
vec1.setY(force.y);
|
|
|
|
vec1.setZ(force.z);
|
2018-04-18 02:26:33 +02:00
|
|
|
if (loc == null) {
|
2018-08-23 20:26:40 +02:00
|
|
|
body.applyCentralForce(vec1);
|
2018-04-18 02:26:33 +02:00
|
|
|
}
|
|
|
|
else {
|
2018-08-23 20:26:40 +02:00
|
|
|
vec2.setX(loc.x);
|
|
|
|
vec2.setY(loc.y);
|
|
|
|
vec2.setZ(loc.z);
|
|
|
|
body.applyForce(vec1, vec2);
|
2018-04-18 02:26:33 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-25 00:26:01 +02:00
|
|
|
public function applyImpulse(impulse:Vec4, loc:Vec4 = null) {
|
2017-08-07 10:47:29 +02:00
|
|
|
activate();
|
2018-08-23 20:26:40 +02:00
|
|
|
vec1.setX(impulse.x);
|
|
|
|
vec1.setY(impulse.y);
|
|
|
|
vec1.setZ(impulse.z);
|
2016-08-25 00:26:01 +02:00
|
|
|
if (loc == null) {
|
2018-08-23 20:26:40 +02:00
|
|
|
body.applyCentralImpulse(vec1);
|
2015-11-26 22:30:19 +01:00
|
|
|
}
|
|
|
|
else {
|
2018-08-23 20:26:40 +02:00
|
|
|
vec2.setX(loc.x);
|
|
|
|
vec2.setY(loc.y);
|
|
|
|
vec2.setZ(loc.z);
|
|
|
|
body.applyImpulse(vec1, vec2);
|
2015-11-26 22:30:19 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-12 21:06:12 +01:00
|
|
|
public function applyTorque(torque:Vec4) {
|
|
|
|
activate();
|
|
|
|
vec1.setX(torque.x);
|
|
|
|
vec1.setY(torque.y);
|
|
|
|
vec1.setZ(torque.z);
|
|
|
|
body.applyTorque(vec1);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function applyTorqueImpulse(torque:Vec4) {
|
|
|
|
activate();
|
|
|
|
vec1.setX(torque.x);
|
|
|
|
vec1.setY(torque.y);
|
|
|
|
vec1.setZ(torque.z);
|
|
|
|
body.applyTorqueImpulse(vec1);
|
|
|
|
}
|
|
|
|
|
2016-04-27 10:29:32 +02:00
|
|
|
public function setLinearFactor(x:Float, y:Float, z:Float) {
|
2018-08-23 20:26:40 +02:00
|
|
|
vec1.setX(x);
|
|
|
|
vec1.setY(y);
|
|
|
|
vec1.setZ(z);
|
|
|
|
body.setLinearFactor(vec1);
|
2015-11-26 22:30:19 +01:00
|
|
|
}
|
|
|
|
|
2016-04-27 10:29:32 +02:00
|
|
|
public function setAngularFactor(x:Float, y:Float, z:Float) {
|
2018-08-23 20:26:40 +02:00
|
|
|
vec1.setX(x);
|
|
|
|
vec1.setY(y);
|
|
|
|
vec1.setZ(z);
|
|
|
|
body.setAngularFactor(vec1);
|
2015-11-26 22:30:19 +01:00
|
|
|
}
|
|
|
|
|
2018-04-14 20:00:40 +02:00
|
|
|
public function getLinearVelocity():Vec4 {
|
|
|
|
var v = body.getLinearVelocity();
|
|
|
|
return new Vec4(v.x(), v.y(), v.z());
|
2016-05-05 19:50:03 +02:00
|
|
|
}
|
2015-11-26 22:30:19 +01:00
|
|
|
|
2016-04-27 10:29:32 +02:00
|
|
|
public function setLinearVelocity(x:Float, y:Float, z:Float) {
|
2018-08-23 20:26:40 +02:00
|
|
|
vec1.setX(x);
|
|
|
|
vec1.setY(y);
|
|
|
|
vec1.setZ(z);
|
|
|
|
body.setLinearVelocity(vec1);
|
2015-11-26 22:30:19 +01:00
|
|
|
}
|
|
|
|
|
2018-04-14 20:00:40 +02:00
|
|
|
public function getAngularVelocity():Vec4 {
|
|
|
|
var v = body.getAngularVelocity();
|
|
|
|
return new Vec4(v.x(), v.y(), v.z());
|
2018-04-13 05:21:36 +02:00
|
|
|
}
|
2015-11-26 22:30:19 +01:00
|
|
|
|
2016-04-27 10:29:32 +02:00
|
|
|
public function setAngularVelocity(x:Float, y:Float, z:Float) {
|
2018-08-23 20:26:40 +02:00
|
|
|
vec1.setX(x);
|
|
|
|
vec1.setY(y);
|
|
|
|
vec1.setZ(z);
|
|
|
|
body.setAngularVelocity(vec1);
|
2015-11-26 22:30:19 +01:00
|
|
|
}
|
|
|
|
|
2017-11-08 00:06:36 +01:00
|
|
|
public function setFriction(f:Float) {
|
|
|
|
body.setFriction(f);
|
|
|
|
body.setRollingFriction(f);
|
|
|
|
this.friction = f;
|
|
|
|
}
|
|
|
|
|
2018-08-17 10:20:46 +02:00
|
|
|
public function notifyOnContact(f:RigidBody->Void) {
|
|
|
|
if (onContact == null) onContact = [];
|
|
|
|
onContact.push(f);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function removeContact(f:RigidBody->Void) {
|
|
|
|
onContact.remove(f);
|
|
|
|
}
|
|
|
|
|
2015-11-26 22:30:19 +01:00
|
|
|
public function syncTransform() {
|
2017-12-12 13:39:15 +01:00
|
|
|
var t = transform;
|
|
|
|
t.buildMatrix();
|
2018-08-23 20:26:40 +02:00
|
|
|
vec1.setX(t.worldx());
|
|
|
|
vec1.setY(t.worldy());
|
|
|
|
vec1.setZ(t.worldz());
|
|
|
|
trans1.setOrigin(vec1);
|
2018-08-28 13:50:52 +02:00
|
|
|
quat.fromMat(t.world);
|
|
|
|
quat1.setX(quat.x);
|
|
|
|
quat1.setY(quat.y);
|
|
|
|
quat1.setZ(quat.z);
|
|
|
|
quat1.setW(quat.w);
|
2018-08-23 20:26:40 +02:00
|
|
|
trans1.setRotation(quat1);
|
|
|
|
body.setCenterOfMassTransform(trans1);
|
2017-12-12 13:39:15 +01:00
|
|
|
if (currentScaleX != t.scale.x || currentScaleY != t.scale.y || currentScaleZ != t.scale.z) setScale(t.scale);
|
2017-07-01 13:12:22 +02:00
|
|
|
activate();
|
2015-11-26 22:30:19 +01:00
|
|
|
}
|
|
|
|
|
2018-10-30 12:56:49 +01:00
|
|
|
// Continuous collision detection
|
|
|
|
public function setCcd(sphereRadius:Float, motionThreshold = 1e-7) {
|
|
|
|
body.setCcdSweptSphereRadius(sphereRadius);
|
|
|
|
body.setCcdMotionThreshold(motionThreshold);
|
|
|
|
}
|
|
|
|
|
2017-12-12 13:39:15 +01:00
|
|
|
function setScale(v:Vec4) {
|
|
|
|
currentScaleX = v.x;
|
|
|
|
currentScaleY = v.y;
|
|
|
|
currentScaleZ = v.z;
|
2018-08-23 20:26:40 +02:00
|
|
|
vec1.setX(bodyScaleX * v.x);
|
|
|
|
vec1.setY(bodyScaleY * v.y);
|
|
|
|
vec1.setZ(bodyScaleZ * v.z);
|
|
|
|
btshape.setLocalScaling(vec1);
|
2017-12-12 23:20:32 +01:00
|
|
|
physics.world.updateSingleAabb(body);
|
2017-12-12 13:39:15 +01:00
|
|
|
}
|
|
|
|
|
2018-08-06 21:56:53 +02:00
|
|
|
function fillConvexHull(shape:BtConvexHullShapePointer, scale:Vec4, margin:Float) {
|
2017-05-14 09:27:47 +02:00
|
|
|
var positions = cast(object, MeshObject).data.geom.positions;
|
2015-11-26 22:30:19 +01:00
|
|
|
|
2016-05-25 00:13:44 +02:00
|
|
|
var sx = scale.x * (1.0 - margin);
|
|
|
|
var sy = scale.y * (1.0 - margin);
|
|
|
|
var sz = scale.z * (1.0 - margin);
|
|
|
|
|
2015-11-26 22:30:19 +01:00
|
|
|
for (i in 0...Std.int(positions.length / 3)) {
|
2018-08-23 20:26:40 +02:00
|
|
|
vec1.setX(positions[i * 3] * sx);
|
|
|
|
vec1.setY(positions[i * 3 + 1] * sy);
|
|
|
|
vec1.setZ(positions[i * 3 + 2] * sz);
|
|
|
|
shape.addPoint(vec1, true);
|
2015-11-26 22:30:19 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-25 00:13:44 +02:00
|
|
|
function fillTriangleMesh(triangleMesh:BtTriangleMeshPointer, scale:Vec4) {
|
2017-05-14 09:27:47 +02:00
|
|
|
var positions = cast(object, MeshObject).data.geom.positions;
|
2017-06-02 16:41:36 +02:00
|
|
|
var indices = cast(object, MeshObject).data.geom.indices;
|
2015-11-26 22:30:19 +01:00
|
|
|
|
2018-01-10 21:10:08 +01:00
|
|
|
for (ar in indices) {
|
|
|
|
for (i in 0...Std.int(ar.length / 3)) {
|
2018-08-23 20:26:40 +02:00
|
|
|
vec1.setX(positions[ar[i * 3 + 0] * 3 + 0] * scale.x);
|
|
|
|
vec1.setY(positions[ar[i * 3 + 0] * 3 + 1] * scale.y);
|
|
|
|
vec1.setZ(positions[ar[i * 3 + 0] * 3 + 2] * scale.z);
|
|
|
|
vec2.setX(positions[ar[i * 3 + 1] * 3 + 0] * scale.x);
|
|
|
|
vec2.setY(positions[ar[i * 3 + 1] * 3 + 1] * scale.y);
|
|
|
|
vec2.setZ(positions[ar[i * 3 + 1] * 3 + 2] * scale.z);
|
|
|
|
vec3.setX(positions[ar[i * 3 + 2] * 3 + 0] * scale.x);
|
|
|
|
vec3.setY(positions[ar[i * 3 + 2] * 3 + 1] * scale.y);
|
|
|
|
vec3.setZ(positions[ar[i * 3 + 2] * 3 + 2] * scale.z);
|
|
|
|
triangleMesh.addTriangle(vec1, vec2, vec3);
|
2018-01-10 21:10:08 +01:00
|
|
|
}
|
2015-11-26 22:30:19 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-07-19 19:42:46 +02:00
|
|
|
|
2017-11-06 13:01:08 +01:00
|
|
|
@:enum abstract Shape(Int) from Int to Int {
|
2016-07-19 19:42:46 +02:00
|
|
|
var Box = 0;
|
|
|
|
var Sphere = 1;
|
|
|
|
var ConvexHull = 2;
|
|
|
|
var Mesh = 3;
|
|
|
|
var Cone = 4;
|
|
|
|
var Cylinder = 5;
|
|
|
|
var Capsule = 6;
|
|
|
|
var Terrain = 7;
|
|
|
|
}
|
2017-01-19 00:26:18 +01:00
|
|
|
|
2017-11-06 13:01:08 +01:00
|
|
|
@:enum abstract ActivationState(Int) from Int to Int {
|
2017-01-19 00:26:18 +01:00
|
|
|
var Active = 1;
|
|
|
|
var NoDeactivation = 4;
|
|
|
|
var NoSimulation = 5;
|
|
|
|
}
|
2017-09-30 02:15:21 +02:00
|
|
|
|
|
|
|
#end
|