21 #include "private/phyjointprivate.h"
22 #include "private/phyobjectprivate.h"
23 #include "private/worldprivate.h"
28 #define isnan(x) _isnan(x)
30 #define isnan(x) std::isnan(x)
35 void PhyHinge::construct(
const wVector& axis,
const wVector& centre, real startAngle, PhyObject* parent, PhyObject* child,
bool cp ) {
36 dof =
new PhyDOF(
this, axis, centre,
false );
46 wVector end = child->matrix().w_pos;
48 start -= parent->matrix().w_pos;
50 wVector newx = (start-end).normalize();
51 if ( isnan(newx[0]) || isnan(newx[1]) || isnan(newx[2]) ) {
60 real angle = atan2( sinAngle, cosAngle );
61 wQuaternion ql( axis, angle );
79 wQuaternion q( axis, startAngle );
94 qWarning(
"Sanity Check Failed on localMatrixParent" );
97 qWarning(
"Sanity Check Failed on localMatrixChild" );
107 construct( axis, centre, startAngle, parent, child, cp );
112 construct( axis, centre, 0, parent, child, cp );
117 construct( axis,
wVector(0,0,0), startAngle, parent, child, cp );
122 construct( axis,
wVector(0,0,0), 0, parent, child, cp );
127 dof =
new PhyDOF(
this, axis, centre,
false );
157 qWarning(
"Sanity Check Failed on localMatrixParent" );
160 qWarning(
"Sanity Check Failed on localMatrixChild" );
182 #ifdef WORLDSIM_USE_NEWTON
183 priv->joint = NewtonConstraintCreateUserJoint( worldpriv->world, 6, PhyJointPrivate::userBilateralHandler, 0,
priv->child,
priv->parent );
184 NewtonJointSetUserData(
priv->joint,
this );
198 qWarning(
"Sanity Check Failed on globalMatrixParent" );
201 qWarning(
"Sanity Check Failed on globalMatrixChild" );
214 real angle = atan2( sinAngle, cosAngle );
224 wVector omegaParent, omegaChild;
225 #ifdef WORLDSIM_USE_NEWTON
227 NewtonBodyGetOmega(
priv->parent, &omegaParent[0] );
229 omegaParent =
wVector(0, 0, 0);
231 NewtonBodyGetOmega(
priv->child, &omegaChild[0] );
240 dof->setPosition( angle );
241 dof->setVelocity( vel );
244 void PhyHinge::updateJoint( real timestep ) {
253 const real angle = dof->position();
254 const real vel = dof->velocity();
256 #ifdef WORLDSIM_USE_NEWTON
259 NewtonUserJointSetRowStiffness(
priv->joint, 1.0 );
261 NewtonUserJointSetRowStiffness(
priv->joint, 1.0 );
263 NewtonUserJointSetRowStiffness(
priv->joint, 1.0 );
275 NewtonUserJointSetRowStiffness(
priv->joint, 1.0 );
277 NewtonUserJointSetRowStiffness(
priv->joint, 1.0 );
279 if ( dof->isLimited() ) {
282 dof->limits( lolimit, hilimit );
283 if ( angle < lolimit ) {
284 real relAngle = lolimit - angle;
288 NewtonUserJointSetRowStiffness(
priv->joint, dof->stiffness() );
289 NewtonUserJointSetRowSpringDamperAcceleration(
priv->joint, 50000.0, 100 );
291 NewtonUserJointSetRowMinimumFriction(
priv->joint, 0.0 );
293 }
else if ( angle > hilimit ) {
294 real relAngle = hilimit - angle;
298 NewtonUserJointSetRowStiffness(
priv->joint, dof->stiffness() );
299 NewtonUserJointSetRowSpringDamperAcceleration(
priv->joint, 50000.0, 100 );
301 NewtonUserJointSetRowMaximumFriction(
priv->joint, 0.0 );
308 real force, accel, wishangle, wishvel, sign;
309 switch( dof->motion() ) {
315 force = fabs( dof->appliedForce() );
316 accel = 2.0*dof->appliedForce();
318 NewtonUserJointSetRowMinimumFriction(
priv->joint, -force );
319 NewtonUserJointSetRowMaximumFriction(
priv->joint, +force );
320 NewtonUserJointSetRowAcceleration(
priv->joint, accel );
321 NewtonUserJointSetRowStiffness(
priv->joint, dof->stiffness() );
325 accel = 0.8*( dof->desiredVelocity() - vel ) / ( timestep );
326 wishangle = (dof->desiredVelocity()*timestep);
328 NewtonUserJointSetRowAcceleration(
priv->joint, accel );
329 NewtonUserJointSetRowStiffness(
priv->joint, dof->stiffness() );
332 wishangle = dof->desiredPosition() - angle;
333 wishvel = wishangle / timestep;
334 if ( fabs(wishvel) > dof->maxVelocity() ) {
335 sign = (wishvel<0) ? -1.0 : +1.0;
336 wishvel = sign*dof->maxVelocity();
338 accel = 0.8*( wishvel - vel ) / ( timestep );
340 NewtonUserJointSetRowAcceleration(
priv->joint, accel );
341 NewtonUserJointSetRowStiffness(
priv->joint, dof->stiffness() );