Merge pull request #1455 from QuantumCoderQC/master

Implemented Physics constraints: Generic, Generic-Spring, Slider...
This commit is contained in:
Lubos Lenco 2019-10-30 15:29:55 +01:00 committed by GitHub
commit dcb4b5fc6c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
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):