diff --git a/Sources/armory/trait/physics/bullet/PhysicsConstraint.hx b/Sources/armory/trait/physics/bullet/PhysicsConstraint.hx index 9c176b60..58d65c4c 100644 --- a/Sources/armory/trait/physics/bullet/PhysicsConstraint.hx +++ b/Sources/armory/trait/physics/bullet/PhysicsConstraint.hx @@ -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 = 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); diff --git a/blender/arm/exporter.py b/blender/arm/exporter.py index 6a8cd99e..dbe181cc 100755 --- a/blender/arm/exporter.py +++ b/blender/arm/exporter.py @@ -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):