Fix physics
This commit is contained in:
+262
-248
@@ -3,22 +3,23 @@
|
||||
|
||||
class PhysicsBody {
|
||||
|
||||
// @:keep
|
||||
props = ["mass"];
|
||||
|
||||
mass = 0.0;
|
||||
_mass = 0.0;
|
||||
|
||||
// @:keep
|
||||
set mass(f: f32): f32 {
|
||||
if (ready) {
|
||||
get mass(): f32 {
|
||||
return this._mass;
|
||||
}
|
||||
|
||||
set mass(f: f32) {
|
||||
if (this.ready) {
|
||||
// remove();
|
||||
let t = new PhysicsBody();
|
||||
t.mass = f;
|
||||
t.init(object);
|
||||
object.addTrait(t);
|
||||
t._mass = f;
|
||||
t.init(this.object);
|
||||
this.object.addTrait(t);
|
||||
}
|
||||
else mass = f;
|
||||
return f;
|
||||
else this._mass = f;
|
||||
}
|
||||
|
||||
object: BaseObject;
|
||||
@@ -35,7 +36,7 @@ class PhysicsBody {
|
||||
trigger = false;
|
||||
group = 1;
|
||||
mask = 1;
|
||||
shape = ShapeBox;
|
||||
shape = ShapeType.ShapeBox;
|
||||
destroyed = false;
|
||||
bodyScaleX: f32; // Transform scale at creation time
|
||||
bodyScaleY: f32;
|
||||
@@ -44,9 +45,9 @@ class PhysicsBody {
|
||||
currentScaleY: f32;
|
||||
currentScaleZ: f32;
|
||||
|
||||
body: PhysicsBullet.RigidBody = null;
|
||||
motionState: PhysicsBullet.MotionState;
|
||||
btshape: PhysicsBullet.CollisionShape;
|
||||
body: Ammo.btRigidBody = null;
|
||||
motionState: Ammo.btMotionState;
|
||||
btshape: Ammo.btCollisionShape;
|
||||
ready = false;
|
||||
id = 0;
|
||||
heightData: Uint8Array = null;
|
||||
@@ -55,178 +56,178 @@ class PhysicsBody {
|
||||
static ammoArray: i32 = -1;
|
||||
static gimpactRegistered = false;
|
||||
static first = true;
|
||||
static vec1: PhysicsBullet.Vector3;
|
||||
static vec2: PhysicsBullet.Vector3;
|
||||
static vec3: PhysicsBullet.Vector3;
|
||||
static quat1: PhysicsBullet.Quaternion;
|
||||
static trans1: PhysicsBullet.Transform;
|
||||
static trans2: PhysicsBullet.Transform;
|
||||
static vec1: Ammo.btVector3;
|
||||
static vec2: Ammo.btVector3;
|
||||
static vec3: Ammo.btVector3;
|
||||
static quat1: Ammo.btQuaternion;
|
||||
static trans1: Ammo.btTransform;
|
||||
static trans2: Ammo.btTransform;
|
||||
static quat = new Quat();
|
||||
|
||||
static convexHullCache = new Map<MeshData, PhysicsBullet.ConvexHullShape>();
|
||||
static triangleMeshCache = new Map<MeshData, PhysicsBullet.TriangleMesh>();
|
||||
static convexHullCache = new Map<MeshData, Ammo.btConvexHullShape>();
|
||||
static triangleMeshCache = new Map<MeshData, Ammo.btTriangleMesh>();
|
||||
static usersCache = new Map<MeshData, i32>();
|
||||
|
||||
constructor() {
|
||||
if (first) {
|
||||
first = false;
|
||||
vec1 = new PhysicsBullet.Vector3(0, 0, 0);
|
||||
vec2 = new PhysicsBullet.Vector3(0, 0, 0);
|
||||
vec3 = new PhysicsBullet.Vector3(0, 0, 0);
|
||||
quat1 = new PhysicsBullet.Quaternion(0, 0, 0, 0);
|
||||
trans1 = new PhysicsBullet.Transform();
|
||||
trans2 = new PhysicsBullet.Transform();
|
||||
if (PhysicsBody.first) {
|
||||
PhysicsBody.first = false;
|
||||
PhysicsBody.vec1 = new Ammo.btVector3(0, 0, 0);
|
||||
PhysicsBody.vec2 = new Ammo.btVector3(0, 0, 0);
|
||||
PhysicsBody.vec3 = new Ammo.btVector3(0, 0, 0);
|
||||
PhysicsBody.quat1 = new Ammo.btQuaternion(0, 0, 0, 0);
|
||||
PhysicsBody.trans1 = new Ammo.btTransform();
|
||||
PhysicsBody.trans2 = new Ammo.btTransform();
|
||||
}
|
||||
}
|
||||
|
||||
withMargin(f: f32) {
|
||||
return f - f * collisionMargin;
|
||||
withMargin = (f: f32) => {
|
||||
return f - f * this.collisionMargin;
|
||||
}
|
||||
|
||||
init(o: BaseObject) {
|
||||
object = o;
|
||||
if (ready) return;
|
||||
ready = true;
|
||||
init = (o: BaseObject) => {
|
||||
this.object = o;
|
||||
if (this.ready) return;
|
||||
this.ready = true;
|
||||
|
||||
if (object.constructor != MeshObject) return; // No mesh data
|
||||
let transform = object.transform;
|
||||
if (this.object.constructor != MeshObject) return; // No mesh data
|
||||
let transform = o.transform;
|
||||
let physics = PhysicsWorld.active;
|
||||
|
||||
if (shape == ShapeBox) {
|
||||
vec1.setX(withMargin(transform.dim.x / 2));
|
||||
vec1.setY(withMargin(transform.dim.y / 2));
|
||||
vec1.setZ(withMargin(transform.dim.z / 2));
|
||||
btshape = new PhysicsBullet.BoxShape(vec1);
|
||||
if (this.shape == ShapeType.ShapeBox) {
|
||||
PhysicsWorld.vec1.setX(this.withMargin(transform.dim.x / 2));
|
||||
PhysicsWorld.vec1.setY(this.withMargin(transform.dim.y / 2));
|
||||
PhysicsWorld.vec1.setZ(this.withMargin(transform.dim.z / 2));
|
||||
this.btshape = new Ammo.btBoxShape(PhysicsWorld.vec1);
|
||||
}
|
||||
else if (shape == ShapeSphere) {
|
||||
btshape = new PhysicsBullet.SphereShape(withMargin(transform.dim.x / 2));
|
||||
else if (this.shape == ShapeType.ShapeSphere) {
|
||||
this.btshape = new Ammo.btSphereShape(this.withMargin(transform.dim.x / 2));
|
||||
}
|
||||
else if (shape == ShapeConvexHull) {
|
||||
let shapeConvex = fillConvexHull(transform.scale, collisionMargin);
|
||||
btshape = shapeConvex;
|
||||
else if (this.shape == ShapeType.ShapeConvexHull) {
|
||||
let shapeConvex = this.fillConvexHull(transform.scale, this.collisionMargin);
|
||||
this.btshape = shapeConvex;
|
||||
}
|
||||
else if (shape == ShapeCone) {
|
||||
let coneZ = new PhysicsBullet.ConeShapeZ(
|
||||
withMargin(transform.dim.x / 2), // Radius
|
||||
withMargin(transform.dim.z)); // Height
|
||||
let cone: PhysicsBullet.ConeShape = coneZ;
|
||||
btshape = cone;
|
||||
else if (this.shape == ShapeType.ShapeCone) {
|
||||
let coneZ = new Ammo.btConeShapeZ(
|
||||
this.withMargin(transform.dim.x / 2), // Radius
|
||||
this.withMargin(transform.dim.z)); // Height
|
||||
let cone: Ammo.btConeShape = coneZ;
|
||||
this.btshape = cone;
|
||||
}
|
||||
else if (shape == ShapeCylinder) {
|
||||
vec1.setX(withMargin(transform.dim.x / 2));
|
||||
vec1.setY(withMargin(transform.dim.y / 2));
|
||||
vec1.setZ(withMargin(transform.dim.z / 2));
|
||||
let cylZ = new PhysicsBullet.CylinderShapeZ(vec1);
|
||||
let cyl: PhysicsBullet.CylinderShape = cylZ;
|
||||
btshape = cyl;
|
||||
else if (this.shape == ShapeType.ShapeCylinder) {
|
||||
PhysicsWorld.vec1.setX(this.withMargin(transform.dim.x / 2));
|
||||
PhysicsWorld.vec1.setY(this.withMargin(transform.dim.y / 2));
|
||||
PhysicsWorld.vec1.setZ(this.withMargin(transform.dim.z / 2));
|
||||
let cylZ = new Ammo.btCylinderShapeZ(PhysicsWorld.vec1);
|
||||
let cyl: Ammo.btCylinderShape = cylZ;
|
||||
this.btshape = cyl;
|
||||
}
|
||||
else if (shape == ShapeCapsule) {
|
||||
else if (this.shape == ShapeType.ShapeCapsule) {
|
||||
let r = transform.dim.x / 2;
|
||||
let capsZ = new PhysicsBullet.CapsuleShapeZ(
|
||||
withMargin(r), // Radius
|
||||
withMargin(transform.dim.z - r * 2)); // Distance between 2 sphere centers
|
||||
let caps: PhysicsBullet.CapsuleShape = capsZ;
|
||||
btshape = caps;
|
||||
let capsZ = new Ammo.btCapsuleShapeZ(
|
||||
this.withMargin(r), // Radius
|
||||
this.withMargin(transform.dim.z - r * 2)); // Distance between 2 sphere centers
|
||||
let caps: Ammo.btCapsuleShape = capsZ;
|
||||
this.btshape = caps;
|
||||
}
|
||||
else if (shape == ShapeMesh) {
|
||||
let meshInterface = fillTriangleMesh(transform.scale);
|
||||
if (mass > 0) {
|
||||
let shapeGImpact = new PhysicsBullet.GImpactMeshShape(meshInterface);
|
||||
else if (this.shape == ShapeType.ShapeMesh) {
|
||||
let meshInterface = this.fillTriangleMesh(transform.scale);
|
||||
if (this.mass > 0) {
|
||||
let shapeGImpact = new Ammo.btGImpactMeshShape(meshInterface);
|
||||
shapeGImpact.updateBound();
|
||||
let shapeConcave: PhysicsBullet.ConcaveShape = shapeGImpact;
|
||||
btshape = shapeConcave;
|
||||
if (!gimpactRegistered) {
|
||||
gimpactRegistered = true;
|
||||
new PhysicsBullet.GImpactCollisionAlgorithm().registerAlgorithm(physics.dispatcher);
|
||||
let shapeConcave: Ammo.btConcaveShape = shapeGImpact;
|
||||
this.btshape = shapeConcave;
|
||||
if (!PhysicsBody.gimpactRegistered) {
|
||||
PhysicsBody.gimpactRegistered = true;
|
||||
new Ammo.GImpactCollisionAlgorithm().registerAlgorithm(physics.dispatcher);
|
||||
}
|
||||
}
|
||||
else {
|
||||
let shapeBvh = new PhysicsBullet.BvhTriangleMeshShape(meshInterface, true, true);
|
||||
let shapeTri: PhysicsBullet.TriangleMeshShape = shapeBvh;
|
||||
let shapeConcave: PhysicsBullet.ConcaveShape = shapeTri;
|
||||
btshape = shapeConcave;
|
||||
let shapeBvh = new Ammo.btBvhTriangleMeshShape(meshInterface, true, true);
|
||||
let shapeTri: Ammo.btTriangleMeshShape = shapeBvh;
|
||||
let shapeConcave: Ammo.btConcaveShape = shapeTri;
|
||||
this.btshape = shapeConcave;
|
||||
}
|
||||
}
|
||||
else if (shape == ShapeTerrain) {
|
||||
let length = heightData.length;
|
||||
if (ammoArray == -1) {
|
||||
ammoArray = PhysicsBullet.Ammo._malloc(length);
|
||||
else if (this.shape == ShapeType.ShapeTerrain) {
|
||||
let length = this.heightData.length;
|
||||
if (PhysicsBody.ammoArray == -1) {
|
||||
PhysicsBody.ammoArray = Ammo._malloc(length);
|
||||
}
|
||||
// From texture bytes
|
||||
for (let i = 0; i < length; ++i) {
|
||||
PhysicsBullet.Ammo.HEAPU8[ammoArray + i] = heightData[i];
|
||||
Ammo.HEAPU8[PhysicsBody.ammoArray + i] = this.heightData[i];
|
||||
}
|
||||
let slice = Math.floor(Math.sqrt(length)); // Assuming square terrain data
|
||||
let axis = 2; // z
|
||||
let dataType = 5; // u8
|
||||
btshape = new PhysicsBullet.HeightfieldTerrainShape(slice, slice, ammoArray, 1 / 255, 0, 1, axis, dataType, false);
|
||||
vec1.setX(transform.dim.x / slice);
|
||||
vec1.setY(transform.dim.y / slice);
|
||||
vec1.setZ(transform.dim.z);
|
||||
btshape.setLocalScaling(vec1);
|
||||
this.btshape = new Ammo.btHeightfieldTerrainShape(slice, slice, PhysicsBody.ammoArray, 1 / 255, 0, 1, axis, dataType, false);
|
||||
PhysicsBody.vec1.setX(transform.dim.x / slice);
|
||||
PhysicsBody.vec1.setY(transform.dim.y / slice);
|
||||
PhysicsBody.vec1.setZ(transform.dim.z);
|
||||
this.btshape.setLocalScaling(PhysicsBody.vec1);
|
||||
}
|
||||
|
||||
trans1.setIdentity();
|
||||
vec1.setX(transform.worldx());
|
||||
vec1.setY(transform.worldy());
|
||||
vec1.setZ(transform.worldz());
|
||||
trans1.setOrigin(vec1);
|
||||
quat.fromMat(transform.world);
|
||||
quat1.setValue(quat.x, quat.y, quat.z, quat.w);
|
||||
trans1.setRotation(quat1);
|
||||
trans2.setIdentity();
|
||||
motionState = new PhysicsBullet.DefaultMotionState(trans1, trans2); // Transform, center of mass offset
|
||||
PhysicsBody.trans1.setIdentity();
|
||||
PhysicsBody.vec1.setX(transform.worldx());
|
||||
PhysicsBody.vec1.setY(transform.worldy());
|
||||
PhysicsBody.vec1.setZ(transform.worldz());
|
||||
PhysicsBody.trans1.setOrigin(PhysicsBody.vec1);
|
||||
PhysicsBody.quat.fromMat(transform.world);
|
||||
PhysicsBody.quat1.setValue(PhysicsBody.quat.x, PhysicsBody.quat.y, PhysicsBody.quat.z, PhysicsBody.quat.w);
|
||||
PhysicsBody.trans1.setRotation(PhysicsBody.quat1);
|
||||
PhysicsBody.trans2.setIdentity();
|
||||
this.motionState = new Ammo.btDefaultMotionState(PhysicsBody.trans1, PhysicsBody.trans2); // Transform, center of mass offset
|
||||
|
||||
vec1.setX(0);
|
||||
vec1.setY(0);
|
||||
vec1.setZ(0);
|
||||
let inertia = vec1;
|
||||
PhysicsBody.vec1.setX(0);
|
||||
PhysicsBody.vec1.setY(0);
|
||||
PhysicsBody.vec1.setZ(0);
|
||||
let inertia = PhysicsBody.vec1;
|
||||
|
||||
if (mass > 0) btshape.calculateLocalInertia(mass, inertia);
|
||||
let bodyCI = new PhysicsBullet.RigidBodyConstructionInfo(mass, motionState, btshape, inertia);
|
||||
body = new PhysicsBullet.RigidBody(bodyCI);
|
||||
if (this.mass > 0) this.btshape.calculateLocalInertia(this.mass, inertia);
|
||||
let bodyCI = new Ammo.btRigidBodyConstructionInfo(this.mass, this.motionState, this.btshape, inertia);
|
||||
this.body = new Ammo.btRigidBody(bodyCI);
|
||||
|
||||
body.setFriction(friction);
|
||||
if (shape == ShapeSphere || shape == ShapeCylinder || shape == ShapeCone || shape == ShapeCapsule) {
|
||||
angularDamping += friction;
|
||||
this.body.setFriction(this.friction);
|
||||
if (this.shape == ShapeType.ShapeSphere || this.shape == ShapeType.ShapeCylinder || this.shape == ShapeType.ShapeCone || this.shape == ShapeType.ShapeCapsule) {
|
||||
this.angularDamping += this.friction;
|
||||
}
|
||||
body.setRestitution(restitution);
|
||||
// body.setSleepingThresholds(linearThreshold, angularThreshold);
|
||||
// body.setDeactivationTime(deactivationTime);
|
||||
body.setDamping(linearDamping, angularDamping);
|
||||
setLinearFactor(linearFactors[0], linearFactors[1], linearFactors[2]);
|
||||
setAngularFactor(angularFactors[0], angularFactors[1], angularFactors[2]);
|
||||
if (trigger) body.setCollisionFlags(body.getCollisionFlags() | PhysicsBullet.CollisionObject.CF_NO_CONTACT_RESPONSE);
|
||||
if (mass == 0.0) body.setCollisionFlags(body.getCollisionFlags() | PhysicsBullet.CollisionObject.CF_STATIC_OBJECT);
|
||||
if (ccd) setCcd(transform.radius);
|
||||
this.body.setRestitution(this.restitution);
|
||||
// this.body.setSleepingThresholds(linearThreshold, angularThreshold);
|
||||
// this.body.setDeactivationTime(deactivationTime);
|
||||
this.body.setDamping(this.linearDamping, this.angularDamping);
|
||||
this.setLinearFactor(this.linearFactors[0], this.linearFactors[1], this.linearFactors[2]);
|
||||
this.setAngularFactor(this.angularFactors[0], this.angularFactors[1], this.angularFactors[2]);
|
||||
if (this.trigger) this.body.setCollisionFlags(this.body.getCollisionFlags() | CollisionFlags.CF_NO_CONTACT_RESPONSE);
|
||||
if (this.mass == 0.0) this.body.setCollisionFlags(this.body.getCollisionFlags() | CollisionFlags.CF_STATIC_OBJECT);
|
||||
if (this.ccd) this.setCcd(transform.radius);
|
||||
|
||||
bodyScaleX = currentScaleX = transform.scale.x;
|
||||
bodyScaleY = currentScaleY = transform.scale.y;
|
||||
bodyScaleZ = currentScaleZ = transform.scale.z;
|
||||
this.bodyScaleX = this.currentScaleX = transform.scale.x;
|
||||
this.bodyScaleY = this.currentScaleY = transform.scale.y;
|
||||
this.bodyScaleZ = this.currentScaleZ = transform.scale.z;
|
||||
|
||||
id = nextId++;
|
||||
body.userIndex = id;
|
||||
this.id = PhysicsBody.nextId++;
|
||||
this.body.userIndex = this.id;
|
||||
|
||||
physics.addBody(this);
|
||||
|
||||
// notifyOnRemove(removeFromWorld);
|
||||
|
||||
PhysicsBullet.Ammo.destroy(bodyCI);
|
||||
Ammo.destroy(bodyCI);
|
||||
}
|
||||
|
||||
physicsUpdate() {
|
||||
if (!ready) return;
|
||||
let trans = body.getWorldTransform();
|
||||
physicsUpdate = () => {
|
||||
if (!this.ready) return;
|
||||
let trans = this.body.getWorldTransform();
|
||||
|
||||
let p = trans.getOrigin();
|
||||
let q = trans.getRotation();
|
||||
let qw: PhysicsBullet.QuadWord = q;
|
||||
let qw: Ammo.btQuadWord = q;
|
||||
|
||||
let transform = object.transform;
|
||||
let transform = this.object.transform;
|
||||
transform.loc.set(p.x(), p.y(), p.z());
|
||||
transform.rot.set(qw.x(), qw.y(), qw.z(), qw.w());
|
||||
if (object.parent != null) {
|
||||
let ptransform = object.parent.transform;
|
||||
if (this.object.parent != null) {
|
||||
let ptransform = this.object.parent.transform;
|
||||
transform.loc.x -= ptransform.worldx();
|
||||
transform.loc.y -= ptransform.worldy();
|
||||
transform.loc.z -= ptransform.worldz();
|
||||
@@ -234,133 +235,133 @@ class PhysicsBody {
|
||||
transform.buildMatrix();
|
||||
}
|
||||
|
||||
removeFromWorld() {
|
||||
removeFromWorld = () => {
|
||||
PhysicsWorld.active.removeBody(this);
|
||||
}
|
||||
|
||||
activate() {
|
||||
body.activate(false);
|
||||
activate = () => {
|
||||
this.body.activate(false);
|
||||
}
|
||||
|
||||
setGravity(v: Vec4) {
|
||||
vec1.setValue(v.x, v.y, v.z);
|
||||
body.setGravity(vec1);
|
||||
setGravity = (v: Vec4) => {
|
||||
PhysicsBody.vec1.setValue(v.x, v.y, v.z);
|
||||
this.body.setGravity(PhysicsBody.vec1);
|
||||
}
|
||||
|
||||
applyForce(force: Vec4, loc: Vec4 = null) {
|
||||
activate();
|
||||
vec1.setValue(force.x, force.y, force.z);
|
||||
applyForce = (force: Vec4, loc: Vec4 = null) => {
|
||||
this.activate();
|
||||
PhysicsBody.vec1.setValue(force.x, force.y, force.z);
|
||||
if (loc == null) {
|
||||
body.applyCentralForce(vec1);
|
||||
this.body.applyCentralForce(PhysicsBody.vec1);
|
||||
}
|
||||
else {
|
||||
vec2.setValue(loc.x, loc.y, loc.z);
|
||||
body.applyForce(vec1, vec2);
|
||||
PhysicsBody.vec2.setValue(loc.x, loc.y, loc.z);
|
||||
this.body.applyForce(PhysicsBody.vec1, PhysicsBody.vec2);
|
||||
}
|
||||
}
|
||||
|
||||
applyImpulse(impulse: Vec4, loc: Vec4 = null) {
|
||||
activate();
|
||||
vec1.setValue(impulse.x, impulse.y, impulse.z);
|
||||
applyImpulse = (impulse: Vec4, loc: Vec4 = null) => {
|
||||
this.activate();
|
||||
PhysicsBody.vec1.setValue(impulse.x, impulse.y, impulse.z);
|
||||
if (loc == null) {
|
||||
body.applyCentralImpulse(vec1);
|
||||
this.body.applyCentralImpulse(PhysicsBody.vec1);
|
||||
}
|
||||
else {
|
||||
vec2.setValue(loc.x, loc.y, loc.z);
|
||||
body.applyImpulse(vec1, vec2);
|
||||
PhysicsBody.vec2.setValue(loc.x, loc.y, loc.z);
|
||||
this.body.applyImpulse(PhysicsBody.vec1, PhysicsBody.vec2);
|
||||
}
|
||||
}
|
||||
|
||||
applyTorque(torque: Vec4) {
|
||||
activate();
|
||||
vec1.setValue(torque.x, torque.y, torque.z);
|
||||
body.applyTorque(vec1);
|
||||
applyTorque = (torque: Vec4) => {
|
||||
this.activate();
|
||||
PhysicsBody.vec1.setValue(torque.x, torque.y, torque.z);
|
||||
this.body.applyTorque(PhysicsBody.vec1);
|
||||
}
|
||||
|
||||
applyTorqueImpulse(torque: Vec4) {
|
||||
activate();
|
||||
vec1.setValue(torque.x, torque.y, torque.z);
|
||||
body.applyTorqueImpulse(vec1);
|
||||
applyTorqueImpulse = (torque: Vec4) => {
|
||||
this.activate();
|
||||
PhysicsBody.vec1.setValue(torque.x, torque.y, torque.z);
|
||||
this.body.applyTorqueImpulse(PhysicsBody.vec1);
|
||||
}
|
||||
|
||||
setLinearFactor(x: f32, y: f32, z: f32) {
|
||||
vec1.setValue(x, y, z);
|
||||
body.setLinearFactor(vec1);
|
||||
setLinearFactor = (x: f32, y: f32, z: f32) => {
|
||||
PhysicsBody.vec1.setValue(x, y, z);
|
||||
this.body.setLinearFactor(PhysicsBody.vec1);
|
||||
}
|
||||
|
||||
setAngularFactor(x: f32, y: f32, z: f32) {
|
||||
vec1.setValue(x, y, z);
|
||||
body.setAngularFactor(vec1);
|
||||
setAngularFactor = (x: f32, y: f32, z: f32) => {
|
||||
PhysicsBody.vec1.setValue(x, y, z);
|
||||
this.body.setAngularFactor(PhysicsBody.vec1);
|
||||
}
|
||||
|
||||
getLinearVelocity(): Vec4 {
|
||||
let v = body.getLinearVelocity();
|
||||
getLinearVelocity = (): Vec4 => {
|
||||
let v = this.body.getLinearVelocity();
|
||||
return new Vec4(v.x(), v.y(), v.z());
|
||||
}
|
||||
|
||||
setLinearVelocity(x: f32, y: f32, z: f32) {
|
||||
vec1.setValue(x, y, z);
|
||||
body.setLinearVelocity(vec1);
|
||||
setLinearVelocity = (x: f32, y: f32, z: f32) => {
|
||||
PhysicsBody.vec1.setValue(x, y, z);
|
||||
this.body.setLinearVelocity(PhysicsBody.vec1);
|
||||
}
|
||||
|
||||
getAngularVelocity(): Vec4 {
|
||||
let v = body.getAngularVelocity();
|
||||
getAngularVelocity = (): Vec4 => {
|
||||
let v = this.body.getAngularVelocity();
|
||||
return new Vec4(v.x(), v.y(), v.z());
|
||||
}
|
||||
|
||||
setAngularVelocity(x: f32, y: f32, z: f32) {
|
||||
vec1.setValue(x, y, z);
|
||||
body.setAngularVelocity(vec1);
|
||||
setAngularVelocity = (x: f32, y: f32, z: f32) => {
|
||||
PhysicsBody.vec1.setValue(x, y, z);
|
||||
this.body.setAngularVelocity(PhysicsBody.vec1);
|
||||
}
|
||||
|
||||
setFriction(f: f32) {
|
||||
body.setFriction(f);
|
||||
setFriction = (f: f32) => {
|
||||
this.body.setFriction(f);
|
||||
this.friction = f;
|
||||
}
|
||||
|
||||
setScale(v: Vec4) {
|
||||
currentScaleX = v.x;
|
||||
currentScaleY = v.y;
|
||||
currentScaleZ = v.z;
|
||||
vec1.setX(v.x / bodyScaleX);
|
||||
vec1.setY(v.y / bodyScaleY);
|
||||
vec1.setZ(v.z / bodyScaleZ);
|
||||
btshape.setLocalScaling(vec1);
|
||||
let worldDyn: PhysicsBullet.DynamicsWorld = PhysicsWorld.active.world;
|
||||
let worldCol: PhysicsBullet.CollisionWorld = worldDyn;
|
||||
worldCol.updateSingleAabb(body);
|
||||
setScale = (v: Vec4) => {
|
||||
this.currentScaleX = v.x;
|
||||
this.currentScaleY = v.y;
|
||||
this.currentScaleZ = v.z;
|
||||
PhysicsBody.vec1.setX(v.x / this.bodyScaleX);
|
||||
PhysicsBody.vec1.setY(v.y / this.bodyScaleY);
|
||||
PhysicsBody.vec1.setZ(v.z / this.bodyScaleZ);
|
||||
this.btshape.setLocalScaling(PhysicsBody.vec1);
|
||||
let worldDyn: Ammo.btDynamicsWorld = PhysicsWorld.active.world;
|
||||
let worldCol: Ammo.btCollisionWorld = worldDyn;
|
||||
worldCol.updateSingleAabb(this.body);
|
||||
}
|
||||
|
||||
syncTransform() {
|
||||
let t = object.transform;
|
||||
syncTransform = () => {
|
||||
let t = this.object.transform;
|
||||
t.buildMatrix();
|
||||
vec1.setValue(t.worldx(), t.worldy(), t.worldz());
|
||||
trans1.setOrigin(vec1);
|
||||
quat.fromMat(t.world);
|
||||
quat1.setValue(quat.x, quat.y, quat.z, quat.w);
|
||||
trans1.setRotation(quat1);
|
||||
body.setWorldTransform(trans1);
|
||||
if (currentScaleX != t.scale.x || currentScaleY != t.scale.y || currentScaleZ != t.scale.z) setScale(t.scale);
|
||||
activate();
|
||||
PhysicsBody.vec1.setValue(t.worldx(), t.worldy(), t.worldz());
|
||||
PhysicsBody.trans1.setOrigin(PhysicsBody.vec1);
|
||||
PhysicsBody.quat.fromMat(t.world);
|
||||
PhysicsBody.quat1.setValue(PhysicsBody.quat.x, PhysicsBody.quat.y, PhysicsBody.quat.z, PhysicsBody.quat.w);
|
||||
PhysicsBody.trans1.setRotation(PhysicsBody.quat1);
|
||||
this.body.setWorldTransform(PhysicsBody.trans1);
|
||||
if (this.currentScaleX != t.scale.x || this.currentScaleY != t.scale.y || this.currentScaleZ != t.scale.z) this.setScale(t.scale);
|
||||
this.activate();
|
||||
}
|
||||
|
||||
setCcd(sphereRadius: f32, motionThreshold = 1e-7) {
|
||||
body.setCcdSweptSphereRadius(sphereRadius);
|
||||
body.setCcdMotionThreshold(motionThreshold);
|
||||
setCcd = (sphereRadius: f32, motionThreshold = 1e-7) => {
|
||||
this.body.setCcdSweptSphereRadius(sphereRadius);
|
||||
this.body.setCcdMotionThreshold(motionThreshold);
|
||||
}
|
||||
|
||||
fillConvexHull(scale: Vec4, margin: f32): PhysicsBullet.ConvexHullShape {
|
||||
fillConvexHull = (scale: Vec4, margin: f32): Ammo.btConvexHullShape => {
|
||||
// Check whether shape already exists
|
||||
let data = cast(object, MeshObject).data;
|
||||
let shape = convexHullCache.get(data);
|
||||
let data = (this.object as MeshObject).data;
|
||||
let shape = PhysicsBody.convexHullCache.get(data);
|
||||
if (shape != null) {
|
||||
usersCache.set(data, usersCache.get(data) + 1);
|
||||
PhysicsBody.usersCache.set(data, PhysicsBody.usersCache.get(data) + 1);
|
||||
return shape;
|
||||
}
|
||||
|
||||
shape = new PhysicsBullet.ConvexHullShape();
|
||||
convexHullCache.set(data, shape);
|
||||
usersCache.set(data, 1);
|
||||
shape = new Ammo.btConvexHullShape();
|
||||
PhysicsBody.convexHullCache.set(data, shape);
|
||||
PhysicsBody.usersCache.set(data, 1);
|
||||
|
||||
let positions = data.positions.values;
|
||||
|
||||
@@ -375,26 +376,26 @@ class PhysicsBody {
|
||||
}
|
||||
|
||||
for (let i = 0; i < Math.floor(positions.length / 4); ++i) {
|
||||
vec1.setX(positions[i * 4 ] * sx);
|
||||
vec1.setY(positions[i * 4 + 1] * sy);
|
||||
vec1.setZ(positions[i * 4 + 2] * sz);
|
||||
shape.addPoint(vec1, true);
|
||||
PhysicsBody.vec1.setX(positions[i * 4 ] * sx);
|
||||
PhysicsBody.vec1.setY(positions[i * 4 + 1] * sy);
|
||||
PhysicsBody.vec1.setZ(positions[i * 4 + 2] * sz);
|
||||
shape.addPoint(PhysicsBody.vec1, true);
|
||||
}
|
||||
return shape;
|
||||
}
|
||||
|
||||
fillTriangleMesh(scale: Vec4): PhysicsBullet.TriangleMesh {
|
||||
fillTriangleMesh = (scale: Vec4): Ammo.btTriangleMesh => {
|
||||
// Check whether shape already exists
|
||||
let data = cast(object, MeshObject).data;
|
||||
let triangleMesh = triangleMeshCache.get(data);
|
||||
let data = (this.object as MeshObject).data;
|
||||
let triangleMesh = PhysicsBody.triangleMeshCache.get(data);
|
||||
if (triangleMesh != null) {
|
||||
usersCache.set(data, usersCache.get(data) + 1);
|
||||
PhysicsBody.usersCache.set(data, PhysicsBody.usersCache.get(data) + 1);
|
||||
return triangleMesh;
|
||||
}
|
||||
|
||||
triangleMesh = new PhysicsBullet.TriangleMesh(true, true);
|
||||
triangleMeshCache.set(data, triangleMesh);
|
||||
usersCache.set(data, 1);
|
||||
triangleMesh = new Ammo.btTriangleMesh(true, true);
|
||||
PhysicsBody.triangleMeshCache.set(data, triangleMesh);
|
||||
PhysicsBody.usersCache.set(data, 1);
|
||||
|
||||
let positions = data.positions.values;
|
||||
let indices = data.indices;
|
||||
@@ -411,50 +412,63 @@ class PhysicsBody {
|
||||
|
||||
for (let ar of indices) {
|
||||
for (let i = 0; i < Math.floor(ar.length / 3); ++i) {
|
||||
vec1.setX(positions[ar[i * 3 ] * 4 ] * sx);
|
||||
vec1.setY(positions[ar[i * 3 ] * 4 + 1] * sy);
|
||||
vec1.setZ(positions[ar[i * 3 ] * 4 + 2] * sz);
|
||||
vec2.setX(positions[ar[i * 3 + 1] * 4 ] * sx);
|
||||
vec2.setY(positions[ar[i * 3 + 1] * 4 + 1] * sy);
|
||||
vec2.setZ(positions[ar[i * 3 + 1] * 4 + 2] * sz);
|
||||
vec3.setX(positions[ar[i * 3 + 2] * 4 ] * sx);
|
||||
vec3.setY(positions[ar[i * 3 + 2] * 4 + 1] * sy);
|
||||
vec3.setZ(positions[ar[i * 3 + 2] * 4 + 2] * sz);
|
||||
triangleMesh.addTriangle(vec1, vec2, vec3);
|
||||
PhysicsBody.vec1.setX(positions[ar[i * 3 ] * 4 ] * sx);
|
||||
PhysicsBody.vec1.setY(positions[ar[i * 3 ] * 4 + 1] * sy);
|
||||
PhysicsBody.vec1.setZ(positions[ar[i * 3 ] * 4 + 2] * sz);
|
||||
PhysicsBody.vec2.setX(positions[ar[i * 3 + 1] * 4 ] * sx);
|
||||
PhysicsBody.vec2.setY(positions[ar[i * 3 + 1] * 4 + 1] * sy);
|
||||
PhysicsBody.vec2.setZ(positions[ar[i * 3 + 1] * 4 + 2] * sz);
|
||||
PhysicsBody.vec3.setX(positions[ar[i * 3 + 2] * 4 ] * sx);
|
||||
PhysicsBody.vec3.setY(positions[ar[i * 3 + 2] * 4 + 1] * sy);
|
||||
PhysicsBody.vec3.setZ(positions[ar[i * 3 + 2] * 4 + 2] * sz);
|
||||
triangleMesh.addTriangle(PhysicsBody.vec1, PhysicsBody.vec2, PhysicsBody.vec3);
|
||||
}
|
||||
}
|
||||
return triangleMesh;
|
||||
}
|
||||
|
||||
delete() {
|
||||
PhysicsBullet.Ammo.destroy(motionState);
|
||||
PhysicsBullet.Ammo.destroy(body);
|
||||
delete = () => {
|
||||
Ammo.destroy(this.motionState);
|
||||
Ammo.destroy(this.body);
|
||||
|
||||
// Delete shape if no other user is found
|
||||
if (shape == ShapeConvexHull || shape == ShapeMesh) {
|
||||
let data = cast(object, MeshObject).data;
|
||||
let i = usersCache.get(data) - 1;
|
||||
usersCache.set(data, i);
|
||||
if (this.shape == ShapeType.ShapeConvexHull || this.shape == ShapeType.ShapeMesh) {
|
||||
let data = (this.object as MeshObject).data;
|
||||
let i = PhysicsBody.usersCache.get(data) - 1;
|
||||
PhysicsBody.usersCache.set(data, i);
|
||||
if (i <= 0) {
|
||||
PhysicsBullet.Ammo.destroy(btshape);
|
||||
shape == ShapeConvexHull ?
|
||||
convexHullCache.remove(data) :
|
||||
triangleMeshCache.remove(data);
|
||||
Ammo.destroy(this.btshape);
|
||||
this.shape == ShapeType.ShapeConvexHull ?
|
||||
PhysicsBody.convexHullCache.delete(data) :
|
||||
PhysicsBody.triangleMeshCache.delete(data);
|
||||
}
|
||||
}
|
||||
else PhysicsBullet.Ammo.destroy(btshape);
|
||||
else Ammo.destroy(this.btshape);
|
||||
}
|
||||
}
|
||||
|
||||
enum ShapeType {
|
||||
ShapeBox = 0;
|
||||
ShapeSphere = 1;
|
||||
ShapeConvexHull = 2;
|
||||
ShapeMesh = 3;
|
||||
ShapeCone = 4;
|
||||
ShapeCylinder = 5;
|
||||
ShapeCapsule = 6;
|
||||
ShapeTerrain = 7;
|
||||
ShapeBox,
|
||||
ShapeSphere,
|
||||
ShapeConvexHull,
|
||||
ShapeMesh,
|
||||
ShapeCone,
|
||||
ShapeCylinder,
|
||||
ShapeCapsule,
|
||||
ShapeTerrain,
|
||||
}
|
||||
|
||||
enum CollisionFlags {
|
||||
CF_STATIC_OBJECT = 1,
|
||||
CF_KINEMATIC_OBJECT = 2,
|
||||
CF_NO_CONTACT_RESPONSE = 4,
|
||||
CF_CHARACTER_OBJECT = 16,
|
||||
}
|
||||
|
||||
// static ACTIVE_TAG = 1;
|
||||
// static ISLAND_SLEEPING = 2;
|
||||
// static WANTS_DEACTIVATION = 3;
|
||||
// static DISABLE_DEACTIVATION = 4;
|
||||
// static DISABLE_SIMULATION = 5;
|
||||
|
||||
///end
|
||||
|
||||
+606
-707
File diff suppressed because it is too large
Load Diff
@@ -4,119 +4,113 @@
|
||||
class PhysicsWorld {
|
||||
|
||||
static active: PhysicsWorld = null;
|
||||
static vec1: PhysicsBullet.Vector3 = null;
|
||||
static vec2: PhysicsBullet.Vector3 = null;
|
||||
static vec1: Ammo.btVector3 = null;
|
||||
static vec2: Ammo.btVector3 = null;
|
||||
static v1 = new Vec4();
|
||||
static v2 = new Vec4();
|
||||
|
||||
world: PhysicsBullet.DiscreteDynamicsWorld;
|
||||
dispatcher: PhysicsBullet.CollisionDispatcher;
|
||||
world: Ammo.btDiscreteDynamicsWorld;
|
||||
dispatcher: Ammo.btCollisionDispatcher;
|
||||
contacts: TPair[] = [];
|
||||
bodyMap = new Map<i32, PhysicsBody>();
|
||||
timeScale = 1.0;
|
||||
timeStep = 1 / 60;
|
||||
maxSteps = 1;
|
||||
|
||||
static load(done: ()=>void) {
|
||||
let b = Krom.loadBlob("data/plugins/ammo.wasm.js");
|
||||
static load = (done: ()=>void) => {
|
||||
let b = Krom.loadBlob("data/plugins/ammo.js");
|
||||
globalThis.eval(System.bufferToString(b));
|
||||
let print = (s: string) => { Krom.log(s); };
|
||||
(1, eval)(System.bufferToString(b));
|
||||
let instantiateWasm = (imports, successCallback) => {
|
||||
let wasmbin = Krom.loadBlob("data/plugins/ammo.wasm.wasm");
|
||||
let module = new webassembly.Module(wasmbin);
|
||||
let inst = new webassembly.Instance(module, imports);
|
||||
successCallback(inst);
|
||||
return inst.exports;
|
||||
};
|
||||
Ammo({print: print, instantiateWasm: instantiateWasm}).then(done);
|
||||
Ammo({print: print}).then(done);
|
||||
|
||||
}
|
||||
|
||||
constructor() {
|
||||
active = this;
|
||||
vec1 = new PhysicsBullet.Vector3(0, 0, 0);
|
||||
vec2 = new PhysicsBullet.Vector3(0, 0, 0);
|
||||
init();
|
||||
PhysicsWorld.active = this;
|
||||
PhysicsWorld.vec1 = new Ammo.btVector3(0, 0, 0);
|
||||
PhysicsWorld.vec2 = new Ammo.btVector3(0, 0, 0);
|
||||
this.init();
|
||||
}
|
||||
|
||||
reset() {
|
||||
for (let body of bodyMap) removeBody(body);
|
||||
reset = () => {
|
||||
for (let body of this.bodyMap.values()) this.removeBody(body);
|
||||
}
|
||||
|
||||
init() {
|
||||
let broadphase = new PhysicsBullet.DbvtBroadphase();
|
||||
let collisionConfiguration = new PhysicsBullet.DefaultCollisionConfiguration();
|
||||
dispatcher = new PhysicsBullet.CollisionDispatcher(collisionConfiguration);
|
||||
let solver = new PhysicsBullet.SequentialImpulseConstraintSolver();
|
||||
world = new PhysicsBullet.DiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);
|
||||
setGravity(new Vec4(0, 0, -9.81));
|
||||
init = () => {
|
||||
let broadphase = new Ammo.btDbvtBroadphase();
|
||||
let collisionConfiguration = new Ammo.btDefaultCollisionConfiguration();
|
||||
this.dispatcher = new Ammo.btCollisionDispatcher(collisionConfiguration);
|
||||
let solver = new Ammo.btSequentialImpulseConstraintSolver();
|
||||
this.world = new Ammo.btDiscreteDynamicsWorld(this.dispatcher, broadphase, solver, collisionConfiguration);
|
||||
this.setGravity(new Vec4(0, 0, -9.81));
|
||||
}
|
||||
|
||||
setGravity(v: Vec4) {
|
||||
vec1.setValue(v.x, v.y, v.z);
|
||||
world.setGravity(vec1);
|
||||
setGravity = (v: Vec4) => {
|
||||
PhysicsWorld.vec1.setValue(v.x, v.y, v.z);
|
||||
this.world.setGravity(PhysicsWorld.vec1);
|
||||
}
|
||||
|
||||
addBody(pb: PhysicsBody) {
|
||||
world.addRigidBodyToGroup(pb.body, pb.group, pb.mask);
|
||||
bodyMap.set(pb.id, pb);
|
||||
addBody = (pb: PhysicsBody) => {
|
||||
this.world.addRigidBody(pb.body, pb.group, pb.mask);
|
||||
this.bodyMap.set(pb.id, pb);
|
||||
}
|
||||
|
||||
removeBody(pb: PhysicsBody) {
|
||||
removeBody = (pb: PhysicsBody) => {
|
||||
if (pb.destroyed) return;
|
||||
pb.destroyed = true;
|
||||
if (world != null) world.removeRigidBody(pb.body);
|
||||
bodyMap.remove(pb.id);
|
||||
if (this.world != null) this.world.removeRigidBody(pb.body);
|
||||
this.bodyMap.delete(pb.id);
|
||||
pb.delete();
|
||||
}
|
||||
|
||||
getContacts(pb: PhysicsBody): PhysicsBody[] {
|
||||
if (contacts.length == 0) return null;
|
||||
getContacts = (pb: PhysicsBody): PhysicsBody[] => {
|
||||
if (this.contacts.length == 0) return null;
|
||||
let res: PhysicsBody[] = [];
|
||||
for (let i = 0; i < contacts.length; ++i) {
|
||||
let c = contacts[i];
|
||||
for (let i = 0; i < this.contacts.length; ++i) {
|
||||
let c = this.contacts[i];
|
||||
let pb: PhysicsBody = null;
|
||||
if (c.a == pb.body.userIndex) pb = bodyMap.get(c.b);
|
||||
else if (c.b == pb.body.userIndex) pb = bodyMap.get(c.a);
|
||||
if (c.a == pb.body.userIndex) pb = this.bodyMap.get(c.b);
|
||||
else if (c.b == pb.body.userIndex) pb = this.bodyMap.get(c.a);
|
||||
if (pb != null && res.indexOf(pb) == -1) res.push(pb);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
getContactPairs(pb: PhysicsBody): TPair[] {
|
||||
if (contacts.length == 0) return null;
|
||||
getContactPairs = (pb: PhysicsBody): TPair[] => {
|
||||
if (this.contacts.length == 0) return null;
|
||||
let res: TPair[] = [];
|
||||
for (let i = 0; i < contacts.length; ++i) {
|
||||
let c = contacts[i];
|
||||
for (let i = 0; i < this.contacts.length; ++i) {
|
||||
let c = this.contacts[i];
|
||||
if (c.a == pb.body.userIndex) res.push(c);
|
||||
else if (c.b == pb.body.userIndex) res.push(c);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
lateUpdate() {
|
||||
let t = Time.delta * timeScale;
|
||||
lateUpdate = () => {
|
||||
let t = Time.delta * this.timeScale;
|
||||
if (t == 0.0) return; // Simulation paused
|
||||
|
||||
world.stepSimulation(timeStep, maxSteps, t);
|
||||
updateContacts();
|
||||
for (let body of bodyMap) body.physicsUpdate();
|
||||
this.world.stepSimulation(this.timeStep, this.maxSteps, t);
|
||||
this.updateContacts();
|
||||
for (let body of this.bodyMap.values()) body.physicsUpdate();
|
||||
}
|
||||
|
||||
updateContacts() {
|
||||
contacts = [];
|
||||
let disp: PhysicsBullet.Dispatcher = dispatcher;
|
||||
updateContacts = () => {
|
||||
this.contacts = [];
|
||||
let disp: Ammo.btDispatcher = this.dispatcher;
|
||||
let numManifolds = disp.getNumManifolds();
|
||||
|
||||
for (let i = 0; i < numManifolds; ++i) {
|
||||
let contactManifold = disp.getManifoldByIndexInternal(i);
|
||||
let body0 = PhysicsBullet.Ammo.btRigidBody.prototype.upcast(contactManifold.getBody0());
|
||||
let body1 = PhysicsBullet.Ammo.btRigidBody.prototype.upcast(contactManifold.getBody1());
|
||||
let body0 = Ammo.btRigidBody.prototype.upcast(contactManifold.getBody0());
|
||||
let body1 = Ammo.btRigidBody.prototype.upcast(contactManifold.getBody1());
|
||||
|
||||
let numContacts = contactManifold.getNumContacts();
|
||||
let pt: PhysicsBullet.ManifoldPoint = null;
|
||||
let posA: PhysicsBullet.Vector3 = null;
|
||||
let posB: PhysicsBullet.Vector3 = null;
|
||||
let nor: PhysicsBullet.Vector3 = null;
|
||||
let pt: Ammo.btManifoldPoint = null;
|
||||
let posA: Ammo.btVector3 = null;
|
||||
let posB: Ammo.btVector3 = null;
|
||||
let nor: Ammo.btVector3 = null;
|
||||
for (let j = 0; j < numContacts; ++j) {
|
||||
pt = contactManifold.getContactPoint(j);
|
||||
posA = pt.get_m_positionWorldOnA();
|
||||
@@ -131,55 +125,55 @@ class PhysicsWorld {
|
||||
impulse: pt.getAppliedImpulse(),
|
||||
distance: pt.getDistance()
|
||||
};
|
||||
contacts.push(cp);
|
||||
this.contacts.push(cp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pickClosest(inputX: f32, inputY: f32): PhysicsBody {
|
||||
pickClosest = (inputX: f32, inputY: f32): PhysicsBody => {
|
||||
let camera = Scene.active.camera;
|
||||
let start = new Vec4();
|
||||
let end = new Vec4();
|
||||
RayCaster.getDirection(start, end, inputX, inputY, camera);
|
||||
let hit = rayCast(camera.transform.world.getLoc(), end);
|
||||
let hit = this.rayCast(camera.transform.world.getLoc(), end);
|
||||
let body = (hit != null) ? hit.body : null;
|
||||
return body;
|
||||
}
|
||||
|
||||
rayCast(from: Vec4, to: Vec4, group: i32 = 0x00000001, mask = 0xffffffff): THit {
|
||||
let rayFrom = vec1;
|
||||
let rayTo = vec2;
|
||||
rayCast = (from: Vec4, to: Vec4, group: i32 = 0x00000001, mask = 0xffffffff): THit => {
|
||||
let rayFrom = PhysicsWorld.vec1;
|
||||
let rayTo = PhysicsWorld.vec2;
|
||||
rayFrom.setValue(from.x, from.y, from.z);
|
||||
rayTo.setValue(to.x, to.y, to.z);
|
||||
|
||||
let rayCallback = new PhysicsBullet.ClosestRayResultCallback(rayFrom, rayTo);
|
||||
let rayCallback = new Ammo.ClosestRayResultCallback(rayFrom, rayTo);
|
||||
|
||||
rayCallback.set_m_collisionFilterGroup(group);
|
||||
rayCallback.set_m_collisionFilterMask(mask);
|
||||
|
||||
let worldDyn: PhysicsBullet.DynamicsWorld = world;
|
||||
let worldCol: PhysicsBullet.CollisionWorld = worldDyn;
|
||||
let worldDyn: Ammo.btDynamicsWorld = this.world;
|
||||
let worldCol: Ammo.btCollisionWorld = worldDyn;
|
||||
worldCol.rayTest(rayFrom, rayTo, rayCallback);
|
||||
let pb: PhysicsBody = null;
|
||||
let hitInfo: THit = null;
|
||||
|
||||
let rc: PhysicsBullet.RayResultCallback = rayCallback;
|
||||
let rc: Ammo.RayResultCallback = rayCallback;
|
||||
if (rc.hasHit()) {
|
||||
let co = rayCallback.get_m_collisionObject();
|
||||
let body = PhysicsBullet.Ammo.btRigidBody.prototype.upcast(co);
|
||||
let body = Ammo.btRigidBody.prototype.upcast(co);
|
||||
let hit = rayCallback.get_m_hitPointWorld();
|
||||
v1.set(hit.x(), hit.y(), hit.z());
|
||||
PhysicsWorld.v1.set(hit.x(), hit.y(), hit.z());
|
||||
let norm = rayCallback.get_m_hitNormalWorld();
|
||||
v2.set(norm.x(), norm.y(), norm.z());
|
||||
pb = bodyMap.get(body.userIndex);
|
||||
PhysicsWorld.v2.set(norm.x(), norm.y(), norm.z());
|
||||
pb = this.bodyMap.get(body.userIndex);
|
||||
hitInfo = {
|
||||
body: pb,
|
||||
pos: v1,
|
||||
normal: v2
|
||||
pos: PhysicsWorld.v1,
|
||||
normal: PhysicsWorld.v2
|
||||
};
|
||||
}
|
||||
|
||||
PhysicsBullet.Ammo.destroy(rayCallback);
|
||||
Ammo.destroy(rayCallback);
|
||||
return hitInfo;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user