Changeset View
Changeset View
Standalone View
Standalone View
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
| Context not available. | |||||
| } | } | ||||
| #endif | #endif | ||||
| } | } | ||||
| void CcdPhysicsEnvironment::SetupObjectConstraints(KX_GameObject *obj_src, KX_GameObject *obj_dest, | |||||
| bRigidBodyJointConstraint *dat) | |||||
| { | |||||
| PHY_IPhysicsController *phy_src = obj_src->GetPhysicsController(); | |||||
| PHY_IPhysicsController *phy_dest = obj_dest->GetPhysicsController(); | |||||
| PHY_IPhysicsEnvironment *phys_env = obj_src->GetScene()->GetPhysicsEnvironment(); | |||||
| /* we need to pass a full constraint frame, not just axis */ | |||||
| MT_Matrix3x3 localCFrame(MT_Vector3(dat->axX,dat->axY,dat->axZ)); | |||||
| MT_Vector3 axis0 = localCFrame.getColumn(0); | |||||
| MT_Vector3 axis1 = localCFrame.getColumn(1); | |||||
| MT_Vector3 axis2 = localCFrame.getColumn(2); | |||||
| MT_Vector3 scale = obj_src->NodeGetWorldScaling(); | |||||
| /* apply not only the pivot and axis values, but also take scale into count | |||||
| * this is not working well, if only one or two axis are scaled, but works ok on | |||||
| * homogeneous scaling */ | |||||
| int constraintId = phys_env->CreateConstraint(phy_src, phy_dest, | |||||
| (PHY_ConstraintType)dat->type, | |||||
| (float)(dat->pivX * scale.x()), | |||||
| (float)(dat->pivY * scale.y()), | |||||
| (float)(dat->pivZ * scale.z()), | |||||
| (float)(axis0.x() * scale.x()), | |||||
| (float)(axis0.y() * scale.y()), | |||||
| (float)(axis0.z() * scale.z()), | |||||
| (float)(axis1.x() * scale.x()), | |||||
| (float)(axis1.y() * scale.y()), | |||||
| (float)(axis1.z() * scale.z()), | |||||
| (float)(axis2.x() * scale.x()), | |||||
| (float)(axis2.y() * scale.y()), | |||||
| (float)(axis2.z() * scale.z()), | |||||
| dat->flag); | |||||
| /* PHY_POINT2POINT_CONSTRAINT=1, | |||||
| * PHY_LINEHINGE_CONSTRAINT=2, | |||||
| * PHY_ANGULAR_CONSTRAINT = 3, | |||||
| * PHY_CONE_TWIST_CONSTRAINT = 4, | |||||
| * PHY_VEHICLE_CONSTRAINT=11, | |||||
| * PHY_GENERIC_6DOF_CONSTRAINT=12 */ | |||||
| if (constraintId) { | |||||
sybren: `if(!constraintId) return;` would also work here, and unindent a big chunk of code. It also… | |||||
| /* if it is a generic 6DOF constraint, set all the limits accordingly */ | |||||
| if (dat->type == PHY_GENERIC_6DOF_CONSTRAINT) { | |||||
sybrenUnsubmitted Not Done Inline ActionsThere is a lot of code duplication in these if-bodies. Possibly by re-ordering some code and pushing the ifs down, this can be avoided. sybren: There is a lot of code duplication in these `if`-bodies. Possibly by re-ordering some code and… | |||||
| int dof; | |||||
| int dofbit=1; | |||||
| for (dof=0;dof<6;dof++) { | |||||
| if (dat->flag & dofbit) { | |||||
| phys_env->SetConstraintParam(constraintId, dof, dat->minLimit[dof], dat->maxLimit[dof]); | |||||
| } | |||||
| else { | |||||
| /* minLimit > maxLimit means free(disabled limit) for this degree of freedom */ | |||||
sybrenUnsubmitted Not Done Inline Actions"disabled limit" seems a strange concept to me, as in this case there is no limit to disable in the first place. "no limit" makes more sense to me. The same condition is also described differently in different comments. Also see my note about code de-duplication. sybren: "disabled limit" seems a strange concept to me, as in this case there is no limit to disable in… | |||||
| phys_env->SetConstraintParam(constraintId, dof, 1 ,-1); | |||||
| } | |||||
| dofbit<<=1; | |||||
| } | |||||
| } | |||||
| else if (dat->type == PHY_CONE_TWIST_CONSTRAINT) { | |||||
| int dof; | |||||
| int dofbit = 1<<3; /* bit flag use_angular_limit_x */ | |||||
| for (dof=3;dof<6;dof++) { | |||||
| if(dat->flag & dofbit) { | |||||
| phys_env->SetConstraintParam(constraintId, dof, dat->minLimit[dof], dat->maxLimit[dof]); | |||||
| } | |||||
| else { | |||||
| /* maxLimit < 0 means free(disabled limit) for this degree of freedom */ | |||||
| phys_env->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; /* bit flag use_angular_limit_x */ | |||||
| if (dat->flag & dofbit) { | |||||
| phys_env->SetConstraintParam(constraintId, dof, dat->minLimit[dof], dat->maxLimit[dof]); | |||||
| } | |||||
| else { | |||||
| /* minLimit > maxLimit means free(disabled limit) for this degree of freedom */ | |||||
| phys_env->SetConstraintParam(constraintId,dof,1,-1); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| Context not available. | |||||
Not Done Inline ActionsWouldn't a switch statement be better here? sybren: Wouldn't a `switch` statement be better here? | |||||
if(!constraintId) return; would also work here, and unindent a big chunk of code. It also fits the semantics of the method; when there is no constraint, the process of setting it up is done.