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:
QuantumCoderQC 2019-10-29 23:12:40 +01:00
parent 00f5946bb4
commit 8beb8ef061
2 changed files with 262 additions and 29 deletions

View file

@ -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);

View file

@ -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):