21 #include "private/phyjointprivate.h"
22 #include "private/phyobjectprivate.h"
23 #include "private/worldprivate.h"
28 #define isnan(x) _isnan(x)
33 void PhyHinge::construct(
const wVector& axis,
const wVector& centre, real startAngle, PhyObject* parent, PhyObject* child,
bool cp ) {
34 dof =
new PhyDOF(
this, axis, centre,
false );
42 wVector end = child->matrix().w_pos;
44 start -= parent->matrix().w_pos;
46 wVector newx = (start-end).normalize();
47 if ( isnan(newx[0]) || isnan(newx[1]) || isnan(newx[2]) ) {
56 real angle = atan2( sinAngle, cosAngle );
57 wQuaternion ql( axis, angle );
75 wQuaternion q( axis, startAngle );
90 qWarning(
"Sanity Check Failed on localMatrixParent" );
93 qWarning(
"Sanity Check Failed on localMatrixChild" );
103 construct( axis, centre, startAngle, parent, child, cp );
108 construct( axis, centre, 0, parent, child, cp );
113 construct( axis,
wVector(0,0,0), startAngle, parent, child, cp );
118 construct( axis,
wVector(0,0,0), 0, parent, child, cp );
123 dof =
new PhyDOF(
this, axis, centre,
false );
153 qWarning(
"Sanity Check Failed on localMatrixParent" );
156 qWarning(
"Sanity Check Failed on localMatrixChild" );
173 #ifdef WORLDSIM_USE_NEWTON
174 priv->joint = NewtonConstraintCreateUserJoint( worldpriv->world, 6, PhyJointPrivate::userBilateralHandler, 0,
priv->child,
priv->parent );
175 NewtonJointSetUserData(
priv->joint,
this );
189 qWarning(
"Sanity Check Failed on globalMatrixParent" );
192 qWarning(
"Sanity Check Failed on globalMatrixChild" );
205 real angle = atan2( sinAngle, cosAngle );
215 wVector omegaParent, omegaChild;
216 #ifdef WORLDSIM_USE_NEWTON
218 NewtonBodyGetOmega(
priv->parent, &omegaParent[0] );
220 omegaParent =
wVector(0, 0, 0);
222 NewtonBodyGetOmega(
priv->child, &omegaChild[0] );
231 dof->setPosition( angle );
232 dof->setVelocity( vel );
235 void PhyHinge::updateJoint( real timestep ) {
244 const real angle = dof->position();
245 const real vel = dof->velocity();
247 #ifdef WORLDSIM_USE_NEWTON
250 NewtonUserJointSetRowStiffness(
priv->joint, 1.0 );
252 NewtonUserJointSetRowStiffness(
priv->joint, 1.0 );
254 NewtonUserJointSetRowStiffness(
priv->joint, 1.0 );
266 NewtonUserJointSetRowStiffness(
priv->joint, 1.0 );
268 NewtonUserJointSetRowStiffness(
priv->joint, 1.0 );
270 if ( dof->isLimited() ) {
273 dof->limits( lolimit, hilimit );
274 if ( angle < lolimit ) {
275 real relAngle = lolimit - angle;
279 NewtonUserJointSetRowStiffness(
priv->joint, dof->stiffness() );
280 NewtonUserJointSetRowSpringDamperAcceleration(
priv->joint, 50000.0, 100 );
282 NewtonUserJointSetRowMinimumFriction(
priv->joint, 0.0 );
284 }
else if ( angle > hilimit ) {
285 real relAngle = hilimit - angle;
289 NewtonUserJointSetRowStiffness(
priv->joint, dof->stiffness() );
290 NewtonUserJointSetRowSpringDamperAcceleration(
priv->joint, 50000.0, 100 );
292 NewtonUserJointSetRowMaximumFriction(
priv->joint, 0.0 );
299 real force, accel, wishangle, wishvel, sign;
300 switch( dof->motion() ) {
306 force = fabs( dof->appliedForce() );
307 accel = 2.0*dof->appliedForce();
309 NewtonUserJointSetRowMinimumFriction(
priv->joint, -force );
310 NewtonUserJointSetRowMaximumFriction(
priv->joint, +force );
311 NewtonUserJointSetRowAcceleration(
priv->joint, accel );
312 NewtonUserJointSetRowStiffness(
priv->joint, dof->stiffness() );
316 accel = 0.8*( dof->desiredVelocity() - vel ) / ( timestep );
317 wishangle = (dof->desiredVelocity()*timestep);
319 NewtonUserJointSetRowAcceleration(
priv->joint, accel );
320 NewtonUserJointSetRowStiffness(
priv->joint, dof->stiffness() );
324 wishangle = dof->desiredPosition() - angle;
325 wishvel = wishangle / timestep;
326 if ( fabs(wishvel) > dof->maxVelocity() ) {
327 sign = (wishvel<0) ? -1.0 : +1.0;
328 wishvel = sign*dof->maxVelocity();
330 accel = 0.8*( wishvel - vel ) / ( timestep );
332 NewtonUserJointSetRowAcceleration(
priv->joint, accel );
333 NewtonUserJointSetRowStiffness(
priv->joint, dof->stiffness() );