BGE patch: [#26223] Some RigidBody joints fixes (ui angles, conetwist/hinge limits...
authorDalai Felinto <dfelinto@gmail.com>
Sun, 27 Feb 2011 09:21:13 +0000 (09:21 +0000)
committerDalai Felinto <dfelinto@gmail.com>
Sun, 27 Feb 2011 09:21:13 +0000 (09:21 +0000)
From the tracker:::
Issues fixed:
- ConeTwist-constraint's params weren't making it to the CcdPhysicsEnvironment, also added Hinge's params.
- UI wasn't using angles where applicable.
- btHingeConstraint's constructor can create frame-matrices which don't align so the hinge doesn's start at 0 degree tilt.
This is an issue when setting limits.

Changes:
- UI: Hinge limits can be set (and disabled).
- UI: ConeTwist only has max-limits and only the twistX can be disabled
- PyApi via rna_constraint.c: added the functions limit_xyz_min, limit_xyz_max (for 6dof), limit_angle_xyz_min,
limit_angle_xyz_max (for 6dof), limit_angle_x_min, limit_angle_x_max (for hinge).
- PyApi: dropped python-function limit_cone_min.

.:. Extra:
UI Changes:
- renamed "RigidBody Joint" to "Rigid Boidy Joint"
- reorganized UI to conform with other parameters (e.g. Limit Rot)
- added dis/active all over the place :)

release/scripts/ui/properties_object_constraint.py
source/blender/blenkernel/intern/constraint.c
source/blender/makesrna/intern/rna_constraint.c
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp

index ad6c0630289ff61ac911116722906bb50b6cfb40..6034fb9e51e2b88d5509a3deddd76d63ab05daa4 100644 (file)
@@ -535,32 +535,86 @@ class ConstraintButtonsPanel():
             layout.label(text="Limits:")
             split = layout.split()
 
-            col = split.column(align=True)
-            col.prop(con, "use_angular_limit_x", text="Angular X")
-            col.prop(con, "use_angular_limit_y", text="Angular Y")
-            col.prop(con, "use_angular_limit_z", text="Angular Z")
+            col = split.column()
+            col.prop(con, "use_angular_limit_x", text="Angle X")
+            subcol = col.column()
+            subcol.active  =con.use_angular_limit_x
+            subcol.prop(con, "limit_angle_max_x", text="")
 
             col = split.column()
-            col.prop(con, "limit_cone_min", text="")
+            col.prop(con, "use_angular_limit_y", text="Angle Y")
+            subcol = col.column()
+            subcol.active  =con.use_angular_limit_y
+            subcol.prop(con, "limit_angle_max_y", text="")
+
             col = split.column()
-            col.prop(con, "limit_cone_max", text="")
+            col.prop(con, "use_angular_limit_z", text="Angle Z")
+            subcol = col.column()
+            subcol.active  =con.use_angular_limit_z
+            subcol.prop(con, "limit_angle_max_z", text="")
 
         elif con.pivot_type == 'GENERIC_6_DOF':
             layout.label(text="Limits:")
             split = layout.split()
-
+    
             col = split.column(align=True)
             col.prop(con, "use_limit_x", text="X")
+            sub = col.column()
+            sub.active = con.use_limit_x
+            sub.prop(con, "limit_min_x", text="Min")
+            sub.prop(con, "limit_max_x", text="Max")
+            
+            col = split.column(align=True)
             col.prop(con, "use_limit_y", text="Y")
+            sub = col.column()
+            sub.active = con.use_limit_y
+            sub.prop(con, "limit_min_y", text="Min")
+            sub.prop(con, "limit_max_y", text="Max")
+            
+            col = split.column(align=True)
             col.prop(con, "use_limit_z", text="Z")
-            col.prop(con, "use_angular_limit_x", text="Angular X")
-            col.prop(con, "use_angular_limit_y", text="Angular Y")
-            col.prop(con, "use_angular_limit_z", text="Angular Z")
+            sub = col.column()
+            sub.active = con.use_limit_z
+            sub.prop(con, "limit_min_z", text="Min")
+            sub.prop(con, "limit_max_z", text="Max")
+    
+            split = layout.split()
+    
+            col = split.column(align=True)
+            col.prop(con, "use_angular_limit_x", text="Angle X")
+            sub = col.column()
+            sub.active = con.use_angular_limit_x
+            sub.prop(con, "limit_angle_min_x", text="Min")
+            sub.prop(con, "limit_angle_max_x", text="Max")
+    
+            col = split.column(align=True)
+            col.prop(con, "use_angular_limit_y", text="Angle Y")
+            sub = col.column()
+            sub.active = con.use_angular_limit_y
+            sub.prop(con, "limit_angle_min_y", text="Min")
+            sub.prop(con, "limit_angle_max_y", text="Max")
+    
+            col = split.column(align=True)
+            col.prop(con, "use_angular_limit_z", text="Angle Z")
+            sub = col.column()
+            sub.active = con.use_angular_limit_z
+            sub.prop(con, "limit_angle_min_z", text="Min")
+            sub.prop(con, "limit_angle_max_z", text="Max")
 
-            col = split.column()
-            col.prop(con, "limit_generic_min", text="")
-            col = split.column()
-            col.prop(con, "limit_generic_max", text="")
+        elif con.pivot_type == 'HINGE':
+            layout.label(text="Limits:")
+            split = layout.split()
+
+            row = split.row(align=True)
+            col = row.column()
+            col.prop(con, "use_angular_limit_x", text="Angle X")
+
+            col = row.column()
+            col.active = con.use_angular_limit_x
+            col.prop(con, "limit_angle_min_x", text="Min")
+            col = row.column()
+            col.active = con.use_angular_limit_x
+            col.prop(con, "limit_angle_max_x", text="Max")
 
     def CLAMP_TO(self, context, layout, con):
         self.target_template(layout, con)
@@ -736,4 +790,4 @@ def unregister():
     bpy.utils.unregister_module(__name__)
 
 if __name__ == "__main__":
-    register()
+    register()
\ No newline at end of file
index 827dddf34d342290c57d9c9324ef6b46e9bceea4..2bbed3ba9f09fc58d46c037aa67e783b48951c70 100644 (file)
@@ -3069,7 +3069,7 @@ static void rbj_flush_tars (bConstraint *con, ListBase *list, short nocopy)
 static bConstraintTypeInfo CTI_RIGIDBODYJOINT = {
        CONSTRAINT_TYPE_RIGIDBODYJOINT, /* type */
        sizeof(bRigidBodyJointConstraint), /* size */
-       "RigidBody Joint", /* name */
+       "Rigid Body Joint", /* name */
        "bRigidBodyJointConstraint", /* struct name */
        NULL, /* free data */
        NULL, /* relink data */
index 3d5164407312eb976a2f66523b122880f926e14b..92637e1577c12eb84e63626492ad48caab170634 100644 (file)
@@ -322,47 +322,6 @@ static void rna_SplineIKConstraint_joint_bindings_set(PointerRNA *ptr, const flo
        memcpy(ikData->points, values, ikData->numpoints * sizeof(float));
 }
 
-/* Array Get/Set Functions for RigidBodyJointConstraint Min/Max Cone Limits */
-void rna_RigidBodyJointConstraint_limit_cone_min_get(PointerRNA *ptr, float values[3])
-{
-       bRigidBodyJointConstraint *data= (bRigidBodyJointConstraint*)(((bConstraint*)ptr->data)->data);
-       float *limit = data->minLimit;
-       
-       values[0]= limit[3];
-       values[1]= limit[4];
-       values[2]= limit[5];
-}
-
-static void rna_RigidBodyJointConstraint_limit_cone_min_set(PointerRNA *ptr, const float values[3])
-{
-       bRigidBodyJointConstraint *data= (bRigidBodyJointConstraint*)(((bConstraint*)ptr->data)->data);
-       float *limit = data->minLimit;
-       
-       limit[3]= values[0];
-       limit[4]= values[1];
-       limit[5]= values[2];
-}
-
-void rna_RigidBodyJointConstraint_limit_cone_max_get(PointerRNA *ptr, float values[3])
-{
-       bRigidBodyJointConstraint *data= (bRigidBodyJointConstraint*)(((bConstraint*)ptr->data)->data);
-       float *limit = data->maxLimit;
-       
-       values[0]= limit[3];
-       values[1]= limit[4];
-       values[2]= limit[5];
-}
-
-static void rna_RigidBodyJointConstraint_limit_cone_max_set(PointerRNA *ptr, const float values[3])
-{
-       bRigidBodyJointConstraint *data= (bRigidBodyJointConstraint*)(((bConstraint*)ptr->data)->data);
-       float *limit = data->maxLimit;
-       
-       limit[3]= values[0];
-       limit[4]= values[1];
-       limit[5]= values[2];
-}
-
 #else
 
 EnumPropertyItem constraint_distance_items[] = {
@@ -1293,62 +1252,92 @@ static void rna_def_constraint_rigid_body_joint(BlenderRNA *brna)
        RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
        
        
-       /* Limit */
-    
-    /* Limit Min/Max for genereic 6 DoF */
-       prop= RNA_def_property(srna, "limit_generic_min", PROP_FLOAT, PROP_NONE);
-       RNA_def_property_float_sdna(prop, NULL, "minLimit");
-       RNA_def_property_array(prop, 6);
-       RNA_def_property_ui_text(prop, "Minimum Limit", "");
-
-       prop= RNA_def_property(srna, "limit_generic_max", PROP_FLOAT, PROP_NONE);
-       RNA_def_property_float_sdna(prop, NULL, "maxLimit");
-       RNA_def_property_array(prop, 6);
-       RNA_def_property_ui_text(prop, "Maximum Limit", "");
-    
-    /* Limit Min/Max for Cone Twist */
-       prop= RNA_def_property(srna, "limit_cone_min", PROP_FLOAT, PROP_NONE);
-       RNA_def_property_float_sdna(prop, NULL, "minLimit");
-       RNA_def_property_float_funcs(prop, "rna_RigidBodyJointConstraint_limit_cone_min_get", "rna_RigidBodyJointConstraint_limit_cone_min_set", NULL);
-       RNA_def_property_array(prop, 3);
-       RNA_def_property_ui_text(prop, "Minimum Limit", "");
-
-       prop= RNA_def_property(srna, "limit_cone_max", PROP_FLOAT, PROP_NONE);
-       RNA_def_property_float_sdna(prop, NULL, "maxLimit");
-       RNA_def_property_float_funcs(prop, "rna_RigidBodyJointConstraint_limit_cone_max_get", "rna_RigidBodyJointConstraint_limit_cone_max_set", NULL);
-       RNA_def_property_array(prop, 3);
-       RNA_def_property_ui_text(prop, "Maximum Limit", "");
+       /* Limits */
+       /* Limit Min/Max */
+       prop= RNA_def_property(srna, "limit_min_x", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "minLimit[0]");
+       RNA_def_property_ui_text(prop, "Minimum Limit X", "");
+
+       prop= RNA_def_property(srna, "limit_min_y", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "minLimit[1]");
+       RNA_def_property_ui_text(prop, "Minimum Limit Y", "");
+
+       prop= RNA_def_property(srna, "limit_min_z", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "minLimit[2]");
+       RNA_def_property_ui_text(prop, "Minimum Limit Z", "");
+
+       prop= RNA_def_property(srna, "limit_max_x", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "maxLimit[0]");
+       RNA_def_property_ui_text(prop, "Maximum Limit X", "");
+
+       prop= RNA_def_property(srna, "limit_max_y", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "maxLimit[1]");
+       RNA_def_property_ui_text(prop, "Maximum Limit Y", "");
+
+       prop= RNA_def_property(srna, "limit_max_z", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "maxLimit[2]");
+       RNA_def_property_ui_text(prop, "Maximum Limit Z", "");
+
+       /* Limit Min/Max for angle */
+       prop= RNA_def_property(srna, "limit_angle_min_x", PROP_FLOAT, PROP_ANGLE);
+       RNA_def_property_float_sdna(prop, NULL, "minLimit[3]");
+       RNA_def_property_range(prop, -M_PI*2, M_PI*2);
+       RNA_def_property_ui_text(prop, "Minimum Angular Limit X", "");
 
-    
-    /* Limit Booleans */
+       prop= RNA_def_property(srna, "limit_angle_min_y", PROP_FLOAT, PROP_ANGLE);
+       RNA_def_property_float_sdna(prop, NULL, "minLimit[4]");
+       RNA_def_property_range(prop, -M_PI*2, M_PI*2);
+       RNA_def_property_ui_text(prop, "Minimum Angular Limit Y", "");
+
+       prop= RNA_def_property(srna, "limit_angle_min_z", PROP_FLOAT, PROP_ANGLE);
+       RNA_def_property_float_sdna(prop, NULL, "minLimit[5]");
+       RNA_def_property_range(prop, -M_PI*2, M_PI*2);
+       RNA_def_property_ui_text(prop, "Minimum Angular Limit Z", "");
+
+       prop= RNA_def_property(srna, "limit_angle_max_x", PROP_FLOAT, PROP_ANGLE);
+       RNA_def_property_float_sdna(prop, NULL, "maxLimit[3]");
+       RNA_def_property_range(prop, -M_PI*2, M_PI*2);
+       RNA_def_property_ui_text(prop, "Maximum Angular Limit X", "");
+       
+       prop= RNA_def_property(srna, "limit_angle_max_y", PROP_FLOAT, PROP_ANGLE);
+       RNA_def_property_float_sdna(prop, NULL, "maxLimit[4]");
+       RNA_def_property_range(prop, -M_PI*2, M_PI*2);
+       RNA_def_property_ui_text(prop, "Maximum Angular Limit Y", "");
+
+       prop= RNA_def_property(srna, "limit_angle_max_z", PROP_FLOAT, PROP_ANGLE);
+       RNA_def_property_float_sdna(prop, NULL, "maxLimit[5]");
+       RNA_def_property_range(prop, -M_PI*2, M_PI*2);
+       RNA_def_property_ui_text(prop, "Maximum Angular Limit Z", "");
+
+       /* Limit Booleans */
        prop= RNA_def_property(srna, "use_limit_x", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", 1);
-       RNA_def_property_ui_text(prop, "Use X Limit", "Use minimum/maximum x limit");
+       RNA_def_property_ui_text(prop, "Limit X", "Use minimum/maximum x limit");
        RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
        
        prop= RNA_def_property(srna, "use_limit_y", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", 2);
-       RNA_def_property_ui_text(prop, "Use Y Limit", "Use minimum/maximum y limit");
+       RNA_def_property_ui_text(prop, "Limit Y", "Use minimum/maximum y limit");
        RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
        
        prop= RNA_def_property(srna, "use_limit_z", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", 4);
-       RNA_def_property_ui_text(prop, "Use Z Limit", "Use minimum/maximum z limit");
+       RNA_def_property_ui_text(prop, "Limit Z", "Use minimum/maximum z limit");
        RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
     
        prop= RNA_def_property(srna, "use_angular_limit_x", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", 8);
-       RNA_def_property_ui_text(prop, "Use Angular X Limit", "Use minimum/maximum x angular limit");
+       RNA_def_property_ui_text(prop, "Angular X Limit", "Use minimum/maximum x angular limit");
        RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
        
        prop= RNA_def_property(srna, "use_angular_limit_y", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", 16);
-       RNA_def_property_ui_text(prop, "Use Angular Y Limit", "Use minimum/maximum y angular limit");
+       RNA_def_property_ui_text(prop, "Angular Y Limit", "Use minimum/maximum y angular limit");
        RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
        
        prop= RNA_def_property(srna, "use_angular_limit_z", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", 32);
-       RNA_def_property_ui_text(prop, "Use Angular Z Limit", "Use minimum/maximum z angular limit");
+       RNA_def_property_ui_text(prop, "Angular Z Limit", "Use minimum/maximum z angular limit");
        RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
     
 }
index d69ae6b1821c42733385ba990af5e453c7fc0de4..35cd4edf945c3007fd67e35dc0edb940ee446765 100644 (file)
@@ -2651,6 +2651,41 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
                                                                                dofbit<<=1;
                                                                        }
                                                                }
+                                                               else if(dat->type == PHY_CONE_TWIST_CONSTRAINT)
+                                                               {
+                                                                       int dof;
+                                                                       int dofbit = 1<<3; // bitflag use_angular_limit_x
+                                                                       
+                                                                       for (dof=3;dof<6;dof++)
+                                                                       {
+                                                                               // flag only applies to angular limit x
+                                                                               if(dof != 3 || dat->flag & dofbit)
+                                                                               {
+                                                                                       kxscene->GetPhysicsEnvironment()->setConstraintParam(constraintId,dof,dat->minLimit[dof],dat->maxLimit[dof]);
+                                                                               }
+                                                                               else
+                                                                               {
+                                                                                       //maxLimit < 0 means free(disabled limit) for this degree of freedom
+                                                                                       kxscene->GetPhysicsEnvironment()->setConstraintParam(constraintId,dof,1,-1);
+                                                                               }
+                                                                               dofbit<<=1;
+                                                                       }                                                               
+                                                               }
+                                                               else if (dat->type == PHY_LINEHINGE_CONSTRAINT)
+                                                               {
+                                                                       int dof = 3; // dof for angular x
+                                                                       int dofbit = 1<<3; // bitflag use_angular_limit_x
+                                                                       
+                                                                       if (dat->flag & dofbit)
+                                                                       {
+                                                                               kxscene->GetPhysicsEnvironment()->setConstraintParam(constraintId,dof,
+                                                                                               dat->minLimit[dof],dat->maxLimit[dof]);
+                                                                       } else
+                                                                       {
+                                                                               //minLimit > maxLimit means free(disabled limit) for this degree of freedom
+                                                                               kxscene->GetPhysicsEnvironment()->setConstraintParam(constraintId,dof,1,-1);
+                                                                       }
+                                                               }
                                                        }
                                                }
                                        }
index 93f1d0962d71f6461e8586f987974fe3493cae72..937c70ede5e606700e6fa448ad33326c28555fa4 100644 (file)
@@ -1987,6 +1987,41 @@ void     CcdPhysicsEnvironment::setConstraintParam(int constraintId,int param,float
                                        break;
                        }
 
+                       default:
+                               {
+                               }
+                       };
+                       break;
+               };
+       case PHY_CONE_TWIST_CONSTRAINT:
+               {
+                       switch (param)
+                       {
+                       case 3: case 4: case 5:
+                               {
+                                       //param = 3,4,5 are constraint limits, high limit values
+                                       btConeTwistConstraint* coneTwist = (btConeTwistConstraint*)typedConstraint;
+                                       coneTwist->setLimit(param,value1);
+                                       break;
+                               }
+                       default:
+                               {
+                               }
+                       };
+                       break;
+               };
+       case PHY_ANGULAR_CONSTRAINT:
+       case PHY_LINEHINGE_CONSTRAINT:
+               {
+                       switch (param)
+                       {
+                       case 3:
+                               {
+                                       //param = 3 is a constraint limit, with low/high limit value
+                                       btHingeConstraint* hingeCons = (btHingeConstraint*)typedConstraint;
+                                       hingeCons->setLimit(value0,value1);
+                                       break;
+                               }
                        default:
                                {
                                }
@@ -2623,20 +2658,54 @@ int                     CcdPhysicsEnvironment::createConstraint(class PHY_IPhysicsController* ctrl
 
                        if (rb1)
                        {
-                               btVector3 axisInB = rb1 ? 
-                               (rb1->getCenterOfMassTransform().getBasis().inverse()*(rb0->getCenterOfMassTransform().getBasis() * axisInA)) : 
-                               rb0->getCenterOfMassTransform().getBasis() * axisInA;
+                               // We know the orientations so we should use them instead of
+                               // having btHingeConstraint fill in the blanks any way it wants to.
+                               btTransform frameInA;
+                               btTransform frameInB;
+                               
+                               btVector3 axis1(axis1X,axis1Y,axis1Z), axis2(axis2X,axis2Y,axis2Z);
+                               if (axis1.length() == 0.0)
+                               {
+                                       btPlaneSpace1( axisInA, axis1, axis2 );
+                               }
+                               
+                               // Internally btHingeConstraint's hinge-axis is z
+                               frameInA.getBasis().setValue( axis1.x(), axis2.x(), axisInA.x(),
+                                                                                       axis1.y(), axis2.y(), axisInA.y(),
+                                                                                       axis1.z(), axis2.z(), axisInA.z() );
+                                                                                       
+                               frameInA.setOrigin( pivotInA );
+
+                               btTransform inv = rb1->getCenterOfMassTransform().inverse();
 
-                               hinge = new btHingeConstraint(
-                                       *rb0,
-                                       *rb1,pivotInA,pivotInB,axisInA,axisInB);
+                               btTransform globalFrameA = rb0->getCenterOfMassTransform() * frameInA;
+                               
+                               frameInB = inv  * globalFrameA;
+                               
+                               hinge = new btHingeConstraint(*rb0,*rb1,frameInA,frameInB);
 
 
                        } else
                        {
-                               hinge = new btHingeConstraint(*rb0,
-                                       pivotInA,axisInA);
+                               static btRigidBody s_fixedObject2( 0,0,0);
+
+                               btTransform frameInA;
+                               btTransform frameInB;
+                               
+                               btVector3 axis1(axis1X,axis1Y,axis1Z), axis2(axis2X,axis2Y,axis2Z);
+                               if (axis1.length() == 0.0)
+                               {
+                                       btPlaneSpace1( axisInA, axis1, axis2 );
+                               }
+
+                               // Internally btHingeConstraint's hinge-axis is z
+                               frameInA.getBasis().setValue( axis1.x(), axis2.x(), axisInA.x(),
+                                                                                       axis1.y(), axis2.y(), axisInA.y(),
+                                                                                       axis1.z(), axis2.z(), axisInA.z() );
+                               frameInA.setOrigin( pivotInA );
+                               frameInB = rb0->getCenterOfMassTransform() * frameInA;
 
+                               hinge = new btHingeConstraint(*rb0, s_fixedObject2, frameInA, frameInB);
                        }
                        hinge->setAngularOnly(angularOnly);