armory/Sources/armory/trait/internal/PhysicsHook.hx
Lubos Lenco f24324a903 Fix DCE
2017-08-10 14:10:37 +02:00

128 lines
3.7 KiB
Haxe

package armory.trait.internal;
import iron.math.Vec4;
import iron.math.Mat4;
import iron.Trait;
import iron.object.MeshObject;
import iron.data.MeshData;
import iron.data.SceneFormat;
#if arm_physics
import armory.trait.internal.RigidBody;
import armory.trait.internal.PhysicsWorld;
import haxebullet.Bullet;
#end
class PhysicsHook extends Trait {
#if (!arm_physics)
public function new() { super(); }
#else
var targetName:String;
var verts:Array<Float>;
public function new(targetName:String, verts:Array<Float>) {
super();
this.targetName = targetName;
this.verts = verts;
Scene.active.notifyOnInit(function() {
notifyOnInit(init);
});
}
function init() {
// Hook to empty axes
var target = targetName != "" ? iron.Scene.active.getChild(targetName) : null;
var targetTransform = target != null ? target.transform : object.transform;
var physics = PhysicsWorld.active;
// Soft body hook
#if arm_physics_soft
var sb:SoftBody = object.getTrait(SoftBody);
if (sb != null && sb.ready) {
// Place static rigid body at target location
var _inertia = BtVector3.create(0, 0, 0);
var _shape = BtSphereShape.create(0.01);
var _transform = BtTransform.create();
_transform.setIdentity();
// _transform.setOrigin(BtVector3.create(
// targetTransform.loc.x,
// targetTransform.loc.y,
// targetTransform.loc.z));
// _transform.setRotation(BtQuaternion.create(
// targetTransform.rot.x,
// targetTransform.rot.y,
// targetTransform.rot.z,
// targetTransform.rot.w));
var _centerOfMassOffset = BtTransform.create();
_centerOfMassOffset.setIdentity();
var _motionState = BtDefaultMotionState.create(_transform, _centerOfMassOffset);
var mass = 0.0;
_shape.calculateLocalInertia(mass, _inertia);
var _bodyCI = BtRigidBodyConstructionInfo.create(mass, _motionState, _shape, _inertia);
var rb = BtRigidBody.create(_bodyCI);
#if js
var nodes = sb.body.get_m_nodes();
#elseif cpp
var nodes = sb.body.m_nodes;
#end
var geom = cast(object, MeshObject).data.geom;
var numNodes = Std.int(geom.positions.length / 3);
for (i in 0...numNodes) {
var node = nodes.at(i);
#if js
var nodePos = node.get_m_x();
#elseif cpp
var nodePos = node.m_x;
#end
// Find nodes at marked vertex group locations
var numVerts = Std.int(verts.length / 3);
for (j in 0...numVerts) {
var x = verts[j * 3] + sb.vertOffsetX;
var y = verts[j * 3 + 1] + sb.vertOffsetY;
var z = verts[j * 3 + 2] + sb.vertOffsetZ;
// Anchor node to rigid body
if (Math.abs(nodePos.x() - x) < 0.01 && Math.abs(nodePos.y() - y) < 0.01 && Math.abs(nodePos.z() - z) < 0.01) {
sb.body.appendAnchor(i, rb, false, 1.0 / numVerts);
}
}
}
return;
}
#end
// Rigid body hook
var rb1:RigidBody = object.getTrait(RigidBody);
if (rb1 != null && rb1.ready) {
#if js // TODO
var btrans = BtTransform.create();
btrans.setIdentity();
var dx = targetTransform.worldx() - object.transform.worldx();
var dy = targetTransform.worldy() - object.transform.worldy();
var dz = targetTransform.worldz() - object.transform.worldz();
btrans.setOrigin(BtVector3.create(dx, dy, dz));
var constraint = BtGeneric6DofConstraint.create(rb1.body, btrans, false); // cpp - fix rb1.body pass
constraint.setLinearLowerLimit(BtVector3.create(0, 0, 0));
constraint.setLinearUpperLimit(BtVector3.create(0, 0, 0));
constraint.setAngularLowerLimit(BtVector3.create(-10, -10, -10));
constraint.setAngularUpperLimit(BtVector3.create(10, 10, 10));
physics.world.addConstraint(constraint, false);
#end
return;
}
// Rigid body or soft body not initialized yet
notifyOnInit(init);
}
#end
}