Implemented Physics constraints: Generic, Generic-Spring, Slider, Piston and Hinge. Point constraint now uses Bullet Physics btPoint2Point constraint. Hinge constraint now obeys orientation inputs. Generic constraint can now be fully configured within Blender. Constraint behaviour matches that of Blender physics constraints.
This commit is contained in:
parent
00f5946bb4
commit
8beb8ef061
|
@ -1,10 +1,10 @@
|
|||
package armory.trait.physics.bullet;
|
||||
|
||||
#if arm_bullet
|
||||
|
||||
import Math;
|
||||
import iron.math.Quat;
|
||||
import armory.trait.physics.RigidBody;
|
||||
import armory.trait.physics.PhysicsWorld;
|
||||
|
||||
class PhysicsConstraint extends iron.Trait {
|
||||
|
||||
var body1:String;
|
||||
|
@ -21,6 +21,7 @@ class PhysicsConstraint extends iron.Trait {
|
|||
static var vec3:bullet.Bt.Vector3;
|
||||
static var trans1:bullet.Bt.Transform;
|
||||
static var trans2:bullet.Bt.Transform;
|
||||
static var transt:bullet.Bt.Transform;
|
||||
|
||||
public function new(body1:String, body2:String, type:String, disableCollisions:Bool, breakingThreshold:Float, limits:Array<Float> = null) {
|
||||
super();
|
||||
|
@ -32,6 +33,7 @@ class PhysicsConstraint extends iron.Trait {
|
|||
vec3 = new bullet.Bt.Vector3(0, 0, 0);
|
||||
trans1 = new bullet.Bt.Transform();
|
||||
trans2 = new bullet.Bt.Transform();
|
||||
|
||||
}
|
||||
|
||||
this.body1 = body1;
|
||||
|
@ -62,22 +64,19 @@ class PhysicsConstraint extends iron.Trait {
|
|||
vec1.setY(t.worldy() - t1.worldy());
|
||||
vec1.setZ(t.worldz() - t1.worldz());
|
||||
trans1.setOrigin(vec1);
|
||||
//trans1.setRotation(new bullet.Bt.Quaternion(t1.rot.x, t1.rot.y, t1.rot.z, t1.rot.w));
|
||||
trans2.setIdentity();
|
||||
vec2.setX(t.worldx() - t2.worldx());
|
||||
vec2.setY(t.worldy() - t2.worldy());
|
||||
vec2.setZ(t.worldz() - t2.worldz());
|
||||
trans2.setOrigin(vec2);
|
||||
//trans2.setRotation(new bullet.Bt.Quaternion(t2.rot.x, t2.rot.y, t2.rot.z, t2.rot.w));
|
||||
trans1.setRotation(new bullet.Bt.Quaternion(t.rot.x, t.rot.y, t.rot.z, t.rot.w));
|
||||
trans2.setRotation(new bullet.Bt.Quaternion(t.rot.x, t.rot.y, t.rot.z, t.rot.w));
|
||||
|
||||
if (type == "GENERIC" || type == "FIXED" || type == "POINT") {
|
||||
if (type == "GENERIC" || type == "FIXED") {
|
||||
var c = bullet.Bt.Generic6DofConstraint.new2(rb1.body, rb2.body, trans1, trans2, false);
|
||||
if (type == "POINT") {
|
||||
vec1.setX(0);
|
||||
vec1.setY(0);
|
||||
vec1.setZ(0);
|
||||
c.setLinearLowerLimit(vec1);
|
||||
c.setLinearUpperLimit(vec1);
|
||||
}
|
||||
else if (type == "FIXED") {
|
||||
if (type == "FIXED") {
|
||||
vec1.setX(0);
|
||||
vec1.setY(0);
|
||||
vec1.setZ(0);
|
||||
|
@ -86,8 +85,38 @@ class PhysicsConstraint extends iron.Trait {
|
|||
c.setAngularLowerLimit(vec1);
|
||||
c.setAngularUpperLimit(vec1);
|
||||
}
|
||||
else { // GENERIC
|
||||
// limit_x:Bool = limits[0] > 0.0;
|
||||
|
||||
else if(type == "GENERIC") {
|
||||
if(limits[0] == 0){
|
||||
limits[1] = 1.0;
|
||||
limits[2] = -1.0;
|
||||
|
||||
}
|
||||
if(limits[3] == 0){
|
||||
limits[4] = 1.0;
|
||||
limits[5] = -1.0;
|
||||
|
||||
}
|
||||
if(limits[6] == 0){
|
||||
limits[7] = 1.0;
|
||||
limits[8] = -1.0;
|
||||
|
||||
}
|
||||
if(limits[9] == 0){
|
||||
limits[10] = 1.0;
|
||||
limits[11] = -1.0;
|
||||
|
||||
}
|
||||
if(limits[12] == 0){
|
||||
limits[13] = 1.0;
|
||||
limits[14] = -1.0;
|
||||
|
||||
}
|
||||
if(limits[15] == 0){
|
||||
limits[16] = 1.0;
|
||||
limits[17] = -1.0;
|
||||
|
||||
}
|
||||
vec1.setX(limits[1]);
|
||||
vec1.setY(limits[4]);
|
||||
vec1.setZ(limits[7]);
|
||||
|
@ -107,16 +136,162 @@ class PhysicsConstraint extends iron.Trait {
|
|||
}
|
||||
con = cast c;
|
||||
}
|
||||
else if (type == "HINGE") {
|
||||
var axis = vec3;
|
||||
axis.setX(0);
|
||||
axis.setY(0);
|
||||
axis.setZ(1);
|
||||
var c = new bullet.Bt.HingeConstraint(rb1.body, rb2.body, vec2, vec1, axis, axis);
|
||||
|
||||
else if( type == "GENERIC_SPRING"){
|
||||
var c = new bullet.Bt.Generic6DofSpringConstraint(rb1.body, rb2.body, trans1, trans2, false);
|
||||
|
||||
if(limits[0] == 0){
|
||||
limits[1] = 1.0;
|
||||
limits[2] = -1.0;
|
||||
|
||||
}
|
||||
if(limits[3] == 0){
|
||||
limits[4] = 1.0;
|
||||
limits[5] = -1.0;
|
||||
|
||||
}
|
||||
if(limits[6] == 0){
|
||||
limits[7] = 1.0;
|
||||
limits[8] = -1.0;
|
||||
|
||||
}
|
||||
if(limits[9] == 0){
|
||||
limits[10] = 1.0;
|
||||
limits[11] = -1.0;
|
||||
|
||||
}
|
||||
if(limits[12] == 0){
|
||||
limits[13] = 1.0;
|
||||
limits[14] = -1.0;
|
||||
|
||||
}
|
||||
if(limits[15] == 0){
|
||||
limits[16] = 1.0;
|
||||
limits[17] = -1.0;
|
||||
|
||||
}
|
||||
vec1.setX(limits[1]);
|
||||
vec1.setY(limits[4]);
|
||||
vec1.setZ(limits[7]);
|
||||
c.setLinearLowerLimit(vec1);
|
||||
vec1.setX(limits[2]);
|
||||
vec1.setY(limits[5]);
|
||||
vec1.setZ(limits[8]);
|
||||
c.setLinearUpperLimit(vec1);
|
||||
vec1.setX(limits[10]);
|
||||
vec1.setY(limits[13]);
|
||||
vec1.setZ(limits[16]);
|
||||
c.setAngularLowerLimit(vec1);
|
||||
vec1.setX(limits[11]);
|
||||
vec1.setY(limits[14]);
|
||||
vec1.setZ(limits[17]);
|
||||
c.setAngularUpperLimit(vec1);
|
||||
if(limits[18] != 0)
|
||||
{
|
||||
c.enableSpring(0,true);
|
||||
c.setStiffness(0,limits[19]);
|
||||
c.setDamping(0,limits[20]);
|
||||
|
||||
}
|
||||
else{c.enableSpring(0,false);}
|
||||
if(limits[21] != 0)
|
||||
{
|
||||
c.enableSpring(1,true);
|
||||
c.setStiffness(1,limits[22]);
|
||||
c.setDamping(1,limits[23]);
|
||||
|
||||
}
|
||||
else{c.enableSpring(1,false);}
|
||||
if(limits[24] != 0)
|
||||
{
|
||||
c.enableSpring(2,true);
|
||||
c.setStiffness(2,limits[25]);
|
||||
c.setDamping(2,limits[26]);
|
||||
|
||||
}
|
||||
else{c.enableSpring(2,false);}
|
||||
if(limits[27] != 0)
|
||||
{
|
||||
c.enableSpring(3,true);
|
||||
c.setStiffness(3,limits[28]);
|
||||
c.setDamping(3,limits[29]);
|
||||
}
|
||||
else{c.enableSpring(3,false);}
|
||||
if(limits[30] != 0)
|
||||
{
|
||||
c.enableSpring(4,true);
|
||||
c.setStiffness(4,limits[31]);
|
||||
c.setDamping(4,limits[32]);
|
||||
}
|
||||
else{c.enableSpring(4,false);}
|
||||
if(limits[33] != 0)
|
||||
{
|
||||
c.enableSpring(5,true);
|
||||
c.setStiffness(5,limits[34]);
|
||||
c.setDamping(5,limits[35]);
|
||||
}
|
||||
else{c.enableSpring(5,false);}
|
||||
con = cast c;
|
||||
|
||||
}
|
||||
else if (type == "POINT"){
|
||||
var c = new bullet.Bt.Point2PointConstraint(rb1.body, rb2.body, vec1, vec2);
|
||||
con = cast c;
|
||||
}
|
||||
// else if (type == "SLIDER") {}
|
||||
// else if (type == "PISTON") {}
|
||||
|
||||
else if (type == "HINGE") {
|
||||
var axis = vec3;
|
||||
var _softness:Float = 0.9;
|
||||
var _biasFactor:Float = 0.3;
|
||||
var _relaxationFactor:Float = 1.0;
|
||||
|
||||
axis.setX(t.up().x);
|
||||
axis.setY(t.up().y);
|
||||
axis.setZ(t.up().z);
|
||||
|
||||
var c = new bullet.Bt.HingeConstraint(rb1.body, rb2.body, vec1, vec2, axis, axis);
|
||||
|
||||
if(limits[0] != 0){
|
||||
c.setLimit(limits[1],limits[2],_softness ,_biasFactor ,_relaxationFactor );
|
||||
}
|
||||
|
||||
con = cast c;
|
||||
}
|
||||
else if (type == "SLIDER") {
|
||||
var c = new bullet.Bt.SliderConstraint(rb1.body, rb2.body, trans1, trans2, true);
|
||||
|
||||
|
||||
|
||||
if(limits[0] != 0){
|
||||
c.setLowerLinLimit(limits[1]);
|
||||
c.setUpperLinLimit(limits[2]);
|
||||
}
|
||||
|
||||
con = cast c;
|
||||
|
||||
|
||||
}
|
||||
else if (type == "PISTON") {
|
||||
|
||||
var c = new bullet.Bt.SliderConstraint(rb1.body, rb2.body, trans1, trans2, true);
|
||||
|
||||
if(limits[0] != 0){
|
||||
c.setLowerLinLimit(limits[1]);
|
||||
c.setUpperLinLimit(limits[2]);
|
||||
}
|
||||
if(limits[3] != 0){
|
||||
c.setLowerAngLimit(limits[4]);
|
||||
c.setUpperAngLimit(limits[5]);
|
||||
}
|
||||
else{
|
||||
c.setLowerAngLimit(1);
|
||||
c.setUpperAngLimit(-1);
|
||||
|
||||
}
|
||||
con = cast c;
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (breakingThreshold > 0) con.setBreakingImpulseThreshold(breakingThreshold);
|
||||
|
||||
|
|
|
@ -1062,7 +1062,7 @@ class ArmoryExporter:
|
|||
cdata[i3 ] = col[0]
|
||||
cdata[i3 + 1] = col[1]
|
||||
cdata[i3 + 2] = col[2]
|
||||
|
||||
|
||||
mats = exportMesh.materials
|
||||
poly_map = []
|
||||
for i in range(max(len(mats), 1)):
|
||||
|
@ -1071,14 +1071,14 @@ class ArmoryExporter:
|
|||
poly_map[poly.material_index].append(poly)
|
||||
|
||||
o['index_arrays'] = []
|
||||
|
||||
|
||||
# map polygon indices to triangle loops
|
||||
tri_loops = {}
|
||||
for loop in exportMesh.loop_triangles:
|
||||
if loop.polygon_index not in tri_loops:
|
||||
tri_loops[loop.polygon_index] = []
|
||||
tri_loops[loop.polygon_index].append(loop)
|
||||
|
||||
|
||||
for index, polys in enumerate(poly_map):
|
||||
tris = 0
|
||||
for poly in polys:
|
||||
|
@ -1489,9 +1489,7 @@ class ArmoryExporter:
|
|||
mat.arm_particle_flag = True
|
||||
# Empty material roughness
|
||||
mat.use_nodes = True
|
||||
for node in mat.node_tree.nodes:
|
||||
if node.type == 'BSDF_PRINCIPLED':
|
||||
node.inputs[7].default_value = 0.25
|
||||
mat.node_tree.nodes['Principled BSDF'].inputs[7].default_value = 0.25
|
||||
o = {}
|
||||
o['name'] = mat.name
|
||||
o['contexts'] = []
|
||||
|
@ -2248,7 +2246,7 @@ class ArmoryExporter:
|
|||
col_mask = ''
|
||||
for b in bobject.arm_rb_collision_filter_mask:
|
||||
col_mask = ('1' if b else '0') + col_mask
|
||||
|
||||
|
||||
x['parameters'] = [str(shape), str(body_mass), str(rb.friction), str(rb.restitution), str(int(col_group, 2)), str(int(col_mask, 2)) ]
|
||||
lx = bobject.arm_rb_linear_factor[0]
|
||||
ly = bobject.arm_rb_linear_factor[1]
|
||||
|
@ -2425,7 +2423,7 @@ class ArmoryExporter:
|
|||
|
||||
bobject_eval = bobject.evaluated_get(self.depsgraph) if apply_modifiers else bobject
|
||||
exportMesh = bobject_eval.to_mesh()
|
||||
|
||||
|
||||
with open(nav_filepath, 'w') as f:
|
||||
for v in exportMesh.vertices:
|
||||
f.write("v %.4f " % (v.co[0] * bobject_eval.scale.x))
|
||||
|
@ -2531,6 +2529,66 @@ class ArmoryExporter:
|
|||
limits.append(rbc.limit_ang_z_lower)
|
||||
limits.append(rbc.limit_ang_z_upper)
|
||||
trait['parameters'].append(str(limits))
|
||||
if rbc.type == "GENERIC_SPRING":
|
||||
limits = []
|
||||
limits.append(1 if rbc.use_limit_lin_x else 0)
|
||||
limits.append(rbc.limit_lin_x_lower)
|
||||
limits.append(rbc.limit_lin_x_upper)
|
||||
limits.append(1 if rbc.use_limit_lin_y else 0)
|
||||
limits.append(rbc.limit_lin_y_lower)
|
||||
limits.append(rbc.limit_lin_y_upper)
|
||||
limits.append(1 if rbc.use_limit_lin_z else 0)
|
||||
limits.append(rbc.limit_lin_z_lower)
|
||||
limits.append(rbc.limit_lin_z_upper)
|
||||
limits.append(1 if rbc.use_limit_ang_x else 0)
|
||||
limits.append(rbc.limit_ang_x_lower)
|
||||
limits.append(rbc.limit_ang_x_upper)
|
||||
limits.append(1 if rbc.use_limit_ang_y else 0)
|
||||
limits.append(rbc.limit_ang_y_lower)
|
||||
limits.append(rbc.limit_ang_y_upper)
|
||||
limits.append(1 if rbc.use_limit_ang_z else 0)
|
||||
limits.append(rbc.limit_ang_z_lower)
|
||||
limits.append(rbc.limit_ang_z_upper)
|
||||
limits.append(1 if rbc.use_spring_x else 0)
|
||||
limits.append(rbc.spring_stiffness_x)
|
||||
limits.append(rbc.spring_damping_x)
|
||||
limits.append(1 if rbc.use_spring_y else 0)
|
||||
limits.append(rbc.spring_stiffness_y)
|
||||
limits.append(rbc.spring_damping_y)
|
||||
limits.append(1 if rbc.use_spring_z else 0)
|
||||
limits.append(rbc.spring_stiffness_z)
|
||||
limits.append(rbc.spring_damping_z)
|
||||
limits.append(1 if rbc.use_spring_ang_x else 0)
|
||||
limits.append(rbc.spring_stiffness_ang_x)
|
||||
limits.append(rbc.spring_damping_ang_x)
|
||||
limits.append(1 if rbc.use_spring_ang_y else 0)
|
||||
limits.append(rbc.spring_stiffness_ang_y)
|
||||
limits.append(rbc.spring_damping_ang_y)
|
||||
limits.append(1 if rbc.use_spring_ang_z else 0)
|
||||
limits.append(rbc.spring_stiffness_ang_z)
|
||||
limits.append(rbc.spring_damping_ang_z)
|
||||
trait['parameters'].append(str(limits))
|
||||
if rbc.type == "HINGE":
|
||||
limits = []
|
||||
limits.append(1 if rbc.use_limit_ang_z else 0)
|
||||
limits.append(rbc.limit_ang_z_lower)
|
||||
limits.append(rbc.limit_ang_z_upper)
|
||||
trait['parameters'].append(str(limits))
|
||||
if rbc.type == "SLIDER":
|
||||
limits = []
|
||||
limits.append(1 if rbc.use_limit_lin_x else 0)
|
||||
limits.append(rbc.limit_lin_x_lower)
|
||||
limits.append(rbc.limit_lin_x_upper)
|
||||
trait['parameters'].append(str(limits))
|
||||
if rbc.type == "PISTON":
|
||||
limits = []
|
||||
limits.append(1 if rbc.use_limit_lin_x else 0)
|
||||
limits.append(rbc.limit_lin_x_lower)
|
||||
limits.append(rbc.limit_lin_x_upper)
|
||||
limits.append(1 if rbc.use_limit_ang_x else 0)
|
||||
limits.append(rbc.limit_ang_x_lower)
|
||||
limits.append(rbc.limit_ang_x_upper)
|
||||
trait['parameters'].append(str(limits))
|
||||
o['traits'].append(trait)
|
||||
|
||||
def post_export_world(self, world, o):
|
||||
|
|
Loading…
Reference in a new issue