1 /*************************************************************************
3 * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
4 * All rights reserved. Email: russ@q12.org Web: www.q12.org *
6 * This library is free software; you can redistribute it and/or *
7 * modify it under the terms of EITHER: *
8 * (1) The GNU Lesser General Public License as published by the Free *
9 * Software Foundation; either version 2.1 of the License, or (at *
10 * your option) any later version. The text of the GNU Lesser *
11 * General Public License is included with this library in the *
13 * (2) The BSD-style license that is included with this library in *
14 * the file LICENSE-BSD.TXT. *
16 * This library is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
19 * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
21 *************************************************************************/
26 #include "joint_internal.h"
29 //****************************************************************************
30 // Prismatic and Universal
32 dxJointPU::dxJointPU( dxWorld
*w
) :
40 // | / Body 2 | / Body 1
41 // | / +---------+ | / +-----------+
43 // | / / / + _/ - / / +
44 // | / / /-/--------(_)----|--- /-----------/-------> AxisP
45 // | / +---------+ / - +-----------+ /
47 // | / +---------+ +-----------+
49 // .-----------------------------------------> X
50 // |----------------->
51 // Anchor2 <--------------|
55 // Setting member variables which are w.r.t body2
59 // Setting member variables which are w.r.t body2
60 dSetZero( anchor2
, 4 );
64 dSetZero( axisP1
, 4 );
77 dReal
dJointGetPUPosition( dJointID j
)
79 dxJointPU
* joint
= ( dxJointPU
* ) j
;
80 dUASSERT( joint
, "bad joint argument" );
81 checktype( joint
, PU
);
84 // get the offset in global coordinates
85 dMultiply0_331( q
, joint
->node
[0].body
->posr
.R
, joint
->anchor1
);
87 if ( joint
->node
[1].body
)
91 // get the anchor2 in global coordinates
92 dMultiply0_331( anchor2
, joint
->node
[1].body
->posr
.R
, joint
->anchor2
);
94 q
[0] = (( joint
->node
[0].body
->posr
.pos
[0] + q
[0] ) -
95 ( joint
->node
[1].body
->posr
.pos
[0] + anchor2
[0] ) );
96 q
[1] = (( joint
->node
[0].body
->posr
.pos
[1] + q
[1] ) -
97 ( joint
->node
[1].body
->posr
.pos
[1] + anchor2
[1] ) );
98 q
[2] = (( joint
->node
[0].body
->posr
.pos
[2] + q
[2] ) -
99 ( joint
->node
[1].body
->posr
.pos
[2] + anchor2
[2] ) );
103 //N.B. When there is no body 2 the joint->anchor2 is already in
104 // global coordinates
106 q
[0] = (( joint
->node
[0].body
->posr
.pos
[0] + q
[0] ) -
107 ( joint
->anchor2
[0] ) );
108 q
[1] = (( joint
->node
[0].body
->posr
.pos
[1] + q
[1] ) -
109 ( joint
->anchor2
[1] ) );
110 q
[2] = (( joint
->node
[0].body
->posr
.pos
[2] + q
[2] ) -
111 ( joint
->anchor2
[2] ) );
113 if ( joint
->flags
& dJOINT_REVERSE
)
122 // get prismatic axis in global coordinates
123 dMultiply0_331( axP
, joint
->node
[0].body
->posr
.R
, joint
->axisP1
);
125 return dCalcVectorDot3( axP
, q
);
129 dReal
dJointGetPUPositionRate( dJointID j
)
131 dxJointPU
* joint
= ( dxJointPU
* ) j
;
132 dUASSERT( joint
, "bad joint argument" );
133 checktype( joint
, PU
);
135 if ( joint
->node
[0].body
)
137 // We want to find the rate of change of the prismatic part of the joint
138 // We can find it by looking at the speed difference between body1 and the
141 // r will be used to find the distance between body1 and the anchor point
143 dVector3 anchor2
= {0,0,0};
144 if ( joint
->node
[1].body
)
146 // Find joint->anchor2 in global coordinates
147 dMultiply0_331( anchor2
, joint
->node
[1].body
->posr
.R
, joint
->anchor2
);
149 r
[0] = ( joint
->node
[0].body
->posr
.pos
[0] -
150 ( anchor2
[0] + joint
->node
[1].body
->posr
.pos
[0] ) );
151 r
[1] = ( joint
->node
[0].body
->posr
.pos
[1] -
152 ( anchor2
[1] + joint
->node
[1].body
->posr
.pos
[1] ) );
153 r
[2] = ( joint
->node
[0].body
->posr
.pos
[2] -
154 ( anchor2
[2] + joint
->node
[1].body
->posr
.pos
[2] ) );
158 //N.B. When there is no body 2 the joint->anchor2 is already in
159 // global coordinates
160 // r = joint->node[0].body->posr.pos - joint->anchor2;
161 dSubtractVectors3( r
, joint
->node
[0].body
->posr
.pos
, joint
->anchor2
);
164 // The body1 can have velocity coming from the rotation of
165 // the rotoide axis. We need to remove this.
167 // N.B. We do vel = r X w instead of vel = w x r to have vel negative
168 // since we want to remove it from the linear velocity of the body
170 dCalcVectorCross3( lvel1
, r
, joint
->node
[0].body
->avel
);
172 // lvel1 += joint->node[0].body->lvel;
173 dAddVectors3( lvel1
, lvel1
, joint
->node
[0].body
->lvel
);
175 // Since we want rate of change along the prismatic axis
176 // get axisP1 in global coordinates and get the component
177 // along this axis only
179 dMultiply0_331( axP1
, joint
->node
[0].body
->posr
.R
, joint
->axisP1
);
181 if ( joint
->node
[1].body
)
183 // Find the contribution of the angular rotation to the linear speed
184 // N.B. We do vel = r X w instead of vel = w x r to have vel negative
185 // since we want to remove it from the linear velocity of the body
187 dCalcVectorCross3( lvel2
, anchor2
, joint
->node
[1].body
->avel
);
189 // lvel1 -= lvel2 + joint->node[1].body->lvel;
191 dAddVectors3( tmp
, lvel2
, joint
->node
[1].body
->lvel
);
192 dSubtractVectors3( lvel1
, lvel1
, tmp
);
194 return dCalcVectorDot3( axP1
, lvel1
);
198 dReal rate
= dCalcVectorDot3( axP1
, lvel1
);
199 return ( (joint
->flags
& dJOINT_REVERSE
) ? -rate
: rate
);
209 dxJointPU::getSureMaxInfo( SureMaxInfo
* info
)
217 dxJointPU::getInfo1( dxJoint::Info1
*info
)
222 // powered needs an extra constraint row
224 // see if we're at a joint limit.
226 if (( limotP
.lostop
> -dInfinity
|| limotP
.histop
< dInfinity
) &&
227 limotP
.lostop
<= limotP
.histop
)
229 // measure joint position
230 dReal pos
= dJointGetPUPosition( this );
231 limotP
.testRotationalLimit( pos
); // N.B. The function is ill named
234 if ( limotP
.limit
|| limotP
.fmax
> 0 ) info
->m
++;
237 bool limiting1
= ( limot1
.lostop
>= -M_PI
|| limot1
.histop
<= M_PI
) &&
238 limot1
.lostop
<= limot1
.histop
;
239 bool limiting2
= ( limot2
.lostop
>= -M_PI
|| limot2
.histop
<= M_PI
) &&
240 limot2
.lostop
<= limot2
.histop
;
242 // We need to call testRotationLimit() even if we're motored, since it
243 // records the result.
246 if ( limiting1
|| limiting2
)
248 dReal angle1
, angle2
;
249 getAngles( &angle1
, &angle2
);
251 limot1
.testRotationalLimit( angle1
);
253 limot2
.testRotationalLimit( angle2
);
256 if ( limot1
.limit
|| limot1
.fmax
> 0 ) info
->m
++;
257 if ( limot2
.limit
|| limot2
.fmax
> 0 ) info
->m
++;
263 dxJointPU::getInfo2( dxJoint::Info2
*info
)
266 const int s1
= info
->rowskip
;
267 const int s2
= 2 * s1
;
269 const dReal k
= info
->fps
* info
->erp
;
271 // pull out pos and R for both bodies. also get the `connection'
274 dReal
*pos1
, *pos2
= 0, *R1
, *R2
= 0;
275 pos1
= node
[0].body
->posr
.pos
;
276 R1
= node
[0].body
->posr
.R
;
279 pos2
= node
[1].body
->posr
.pos
;
280 R2
= node
[1].body
->posr
.R
;
283 dVector3 axP
; // Axis of the prismatic joint in global frame
284 dMultiply0_331( axP
, R1
, axisP1
);
286 // distance between the body1 and the anchor2 in global frame
287 // Calculated in the same way as the offset
289 dVector3 wanchor2
= {0,0,0};
292 dMultiply0_331( wanchor2
, R2
, anchor2
);
293 dist
[0] = wanchor2
[0] + pos2
[0] - pos1
[0];
294 dist
[1] = wanchor2
[1] + pos2
[1] - pos1
[1];
295 dist
[2] = wanchor2
[2] + pos2
[2] - pos1
[2];
299 if (flags
& dJOINT_REVERSE
)
301 // Invert the sign of dist
302 dist
[0] = pos1
[0] - anchor2
[0];
303 dist
[1] = pos1
[1] - anchor2
[1];
304 dist
[2] = pos1
[2] - anchor2
[2];
308 dist
[0] = anchor2
[0] - pos1
[0];
309 dist
[1] = anchor2
[1] - pos1
[1];
310 dist
[2] = anchor2
[2] - pos1
[2];
314 dVector3 q
; // Temporary axis vector
315 // Will be used at 2 places with 2 different meaning
317 // ======================================================================
318 // Work on the angular part (i.e. row 0)
321 // The axis perpendicular to both axis1 and axis2 should be the only unconstrained
322 // rotational axis, the angular velocity of the two bodies perpendicular to
323 // the rotoide axes should be equal. Thus the constraint equations are
325 // where p is a unit vector perpendicular to both axis1 and axis2
326 // and w1 and w2 are the angular velocity vectors of the two bodies.
329 dReal val
= dCalcVectorDot3( ax1
, ax2
);
330 q
[0] = ax2
[0] - val
* ax1
[0];
331 q
[1] = ax2
[1] - val
* ax1
[1];
332 q
[2] = ax2
[2] - val
* ax1
[2];
335 dCalcVectorCross3( p
, ax1
, q
);
338 // info->J1a[s0+i] = p[i];
339 dCopyVector3(( info
->J1a
) + s0
, p
);
343 // info->J2a[s0+i] = -p[i];
344 dCopyNegatedVector3(( info
->J2a
) + s0
, p
);
347 // compute the right hand side of the constraint equation. Set relative
348 // body velocities along p to bring the axes back to perpendicular.
349 // If ax1, ax2 are unit length joint axes as computed from body1 and
350 // body2, we need to rotate both bodies along the axis p. If theta
351 // is the angle between ax1 and ax2, we need an angular velocity
352 // along p to cover the angle erp * (theta - Pi/2) in one step:
354 // |angular_velocity| = angle/time = erp*(theta - Pi/2) / stepsize
355 // = (erp*fps) * (theta - Pi/2)
357 // if theta is close to Pi/2,
358 // theta - Pi/2 ~= cos(theta), so
359 // |angular_velocity| ~= (erp*fps) * (ax1 dot ax2)
361 info
->c
[0] = k
* - val
;
365 // ==========================================================================
366 // Work on the linear part (i.e rows 1 and 2)
368 // We want: vel2 = vel1 + w1 x c ... but this would
369 // result in three equations, so we project along the planespace vectors
370 // so that sliding along the axisP is disregarded.
372 // p1 + R1 dist' = p2 + R2 anchor2'
373 // v1 + w1 x R1 dist' + v_p = v2 + w2 x R2 anchor2'
374 // v_p is speed of prismatic joint (i.e. elongation rate)
375 // Since the constraints are perpendicular to v_p we have:
376 // e1 dot v_p = 0 and e2 dot v_p = 0
377 // e1 dot ( v1 + w1 x dist = v2 + w2 x anchor2 )
378 // e2 dot ( v1 + w1 x dist = v2 + w2 x anchor2 )
380 // e1 . v1 + e1 . w1 x dist = e1 . v2 + e1 . w2 x anchor2
381 // since a . (b x c) = - b . (a x c) = - (a x c) . b
382 // and a x b = - b x a
383 // e1 . v1 - e1 x dist . w1 - e1 . v2 - (- e1 x anchor2 . w2) = 0
384 // e1 . v1 + dist x e1 . w1 - e1 . v2 - anchor2 x e1 . w2 = 0
385 // Coeff for 1er line of: J1l => e1, J2l => -e1
386 // Coeff for 2er line of: J1l => e2, J2l => -ax2
387 // Coeff for 1er line of: J1a => dist x e1, J2a => - anchor2 x e1
388 // Coeff for 2er line of: J1a => dist x e2, J2a => - anchor2 x e2
389 // e1 and e2 are perpendicular to axP
390 // so e1 = ax1 and e2 = ax1 x axP
391 // N.B. ax2 is not always perpendicular to axP since it is attached to body 2
392 dCalcVectorCross3( q
, ax1
, axP
);
394 dMultiply0_331( axP
, R1
, axisP1
);
396 dCalcVectorCross3(( info
->J1a
) + s1
, dist
, ax1
);
397 dCalcVectorCross3(( info
->J1a
) + s2
, dist
, q
);
399 // info->J1l[s1+i] = ax[i];
400 dCopyVector3(( info
->J1l
) + s1
, ax1
);
402 // info->J1l[s2+i] = q[i];
403 dCopyVector3(( info
->J1l
) + s2
, q
);
407 // Calculate anchor2 in world coordinate
409 // q x anchor2 instead of anchor2 x q since we want the negative value
410 dCalcVectorCross3(( info
->J2a
) + s1
, ax1
, wanchor2
);
411 // The cross product is in reverse order since we want the negative value
412 dCalcVectorCross3(( info
->J2a
) + s2
, q
, wanchor2
);
415 // info->J2l[s1+i] = -ax1[i];
416 dCopyNegatedVector3(( info
->J2l
) + s1
, ax1
);
417 // info->J2l[s2+i] = -ax1[i];
418 dCopyNegatedVector3(( info
->J2l
) + s2
, q
);
423 // We want to make correction for motion not in the line of the axisP
424 // We calculate the displacement w.r.t. the anchor pt.
426 // compute the elements 1 and 2 of right hand side.
427 // We want to align the offset point (in body 2's frame) with the center of body 1.
428 // The position should be the same when we are not along the prismatic axis
430 dMultiply0_331( err
, R1
, anchor1
);
431 // err[i] = dist[i] - err[i];
432 dSubtractVectors3( err
, dist
, err
);
433 info
->c
[1] = k
* dCalcVectorDot3( ax1
, err
);
434 info
->c
[2] = k
* dCalcVectorDot3( q
, err
);
436 int row
= 3 + limot1
.addLimot( this, info
, 3, ax1
, 1 );
437 row
+= limot2
.addLimot( this, info
, row
, ax2
, 1 );
439 if ( node
[1].body
|| !(flags
& dJOINT_REVERSE
) )
440 limotP
.addLimot( this, info
, row
, axP
, 0 );
446 limotP
.addLimot ( this, info
, row
, axP
, 0 );
450 void dJointSetPUAnchor( dJointID j
, dReal x
, dReal y
, dReal z
)
452 dxJointPU
* joint
= ( dxJointPU
* ) j
;
453 dUASSERT( joint
, "bad joint argument" );
454 checktype( joint
, PU
);
455 setAnchors( joint
, x
, y
, z
, joint
->anchor1
, joint
->anchor2
);
456 joint
->computeInitialRelativeRotations();
460 * This function initialize the anchor and the relative position of each body
461 * as if body2 was at its current position + [dx,dy,dy].
466 * dJointGetPUAxis3(jId, dir);
467 * dJointSetPUAnchor(jId, 0, 0, 0);
468 * // If you request the position you will have: dJointGetPUPosition(jId) == 0
469 * dJointSetPUAnchorDelta(jId, 0, 0, 0, dir[X]*offset, dir[Y]*offset, dir[Z]*offset);
470 * // If you request the position you will have: dJointGetPUPosition(jId) == -offset
473 * @param j The PU joint for which the anchor point will be set
474 * @param x The X position of the anchor point in world frame
475 * @param y The Y position of the anchor point in world frame
476 * @param z The Z position of the anchor point in world frame
477 * @param dx A delta to be added to the X position as if the anchor was set
478 * when body1 was at current_position[X] + dx
479 * @param dx A delta to be added to the Y position as if the anchor was set
480 * when body1 was at current_position[Y] + dy
481 * @param dx A delta to be added to the Z position as if the anchor was set
482 * when body1 was at current_position[Z] + dz
483 * @note Should have the same meaning as dJointSetSliderAxisDelta
485 void dJointSetPUAnchorDelta( dJointID j
, dReal x
, dReal y
, dReal z
,
486 dReal dx
, dReal dy
, dReal dz
)
488 dxJointPU
* joint
= ( dxJointPU
* ) j
;
489 dUASSERT( joint
, "bad joint argument" );
490 checktype( joint
, PU
);
492 if ( joint
->node
[0].body
)
494 joint
->node
[0].body
->posr
.pos
[0] += dx
;
495 joint
->node
[0].body
->posr
.pos
[1] += dy
;
496 joint
->node
[0].body
->posr
.pos
[2] += dz
;
499 setAnchors( joint
, x
, y
, z
, joint
->anchor1
, joint
->anchor2
);
501 if ( joint
->node
[0].body
)
503 joint
->node
[0].body
->posr
.pos
[0] -= dx
;
504 joint
->node
[0].body
->posr
.pos
[1] -= dy
;
505 joint
->node
[0].body
->posr
.pos
[2] -= dz
;
508 joint
->computeInitialRelativeRotations();
512 * \brief This function initialize the anchor and the relative position of each body
513 * such that dJointGetPUPosition will return the dot product of axis and [dx,dy,dy].
515 * The body 1 is moved to [-dx, -dy, -dx] then the anchor is set. This will be the
516 * position 0 for the prismatic part of the joint. Then the body 1 is moved to its
523 * dJointGetPUAxis3(jId, dir);
524 * dJointSetPUAnchor(jId, 0, 0, 0);
525 * // If you request the position you will have: dJointGetPUPosition(jId) == 0
526 * dJointSetPUAnchorDelta(jId, 0, 0, 0, dir[X]*offset, dir[Y]*offset, dir[Z]*offset);
527 * // If you request the position you will have: dJointGetPUPosition(jId) == offset
530 * @param j The PU joint for which the anchor point will be set
531 * @param x The X position of the anchor point in world frame
532 * @param y The Y position of the anchor point in world frame
533 * @param z The Z position of the anchor point in world frame
534 * @param dx A delta to be added to the X position as if the anchor was set
535 * when body1 was at current_position[X] + dx
536 * @param dx A delta to be added to the Y position as if the anchor was set
537 * when body1 was at current_position[Y] + dy
538 * @param dx A delta to be added to the Z position as if the anchor was set
539 * when body1 was at current_position[Z] + dz
540 * @note Should have the same meaning as dJointSetSliderAxisDelta
542 void dJointSetPUAnchorOffset( dJointID j
, dReal x
, dReal y
, dReal z
,
543 dReal dx
, dReal dy
, dReal dz
)
545 dxJointPU
* joint
= ( dxJointPU
* ) j
;
546 dUASSERT( joint
, "bad joint argument" );
547 checktype( joint
, PU
);
549 if (joint
->flags
& dJOINT_REVERSE
)
556 if ( joint
->node
[0].body
)
558 joint
->node
[0].body
->posr
.pos
[0] -= dx
;
559 joint
->node
[0].body
->posr
.pos
[1] -= dy
;
560 joint
->node
[0].body
->posr
.pos
[2] -= dz
;
563 setAnchors( joint
, x
, y
, z
, joint
->anchor1
, joint
->anchor2
);
565 if ( joint
->node
[0].body
)
567 joint
->node
[0].body
->posr
.pos
[0] += dx
;
568 joint
->node
[0].body
->posr
.pos
[1] += dy
;
569 joint
->node
[0].body
->posr
.pos
[2] += dz
;
572 joint
->computeInitialRelativeRotations();
579 void dJointSetPUAxis1( dJointID j
, dReal x
, dReal y
, dReal z
)
581 dxJointPU
* joint
= ( dxJointPU
* ) j
;
582 dUASSERT( joint
, "bad joint argument" );
583 checktype( joint
, PU
);
584 if ( joint
->flags
& dJOINT_REVERSE
)
585 setAxes( joint
, x
, y
, z
, NULL
, joint
->axis2
);
587 setAxes( joint
, x
, y
, z
, joint
->axis1
, NULL
);
588 joint
->computeInitialRelativeRotations();
591 void dJointSetPUAxis2( dJointID j
, dReal x
, dReal y
, dReal z
)
593 dxJointPU
* joint
= ( dxJointPU
* ) j
;
594 dUASSERT( joint
, "bad joint argument" );
595 checktype( joint
, PU
);
596 if ( joint
->flags
& dJOINT_REVERSE
)
597 setAxes( joint
, x
, y
, z
, joint
->axis1
, NULL
);
599 setAxes( joint
, x
, y
, z
, NULL
, joint
->axis2
);
600 joint
->computeInitialRelativeRotations();
604 void dJointSetPUAxisP( dJointID id
, dReal x
, dReal y
, dReal z
)
606 dJointSetPUAxis3( id
, x
, y
, z
);
611 void dJointSetPUAxis3( dJointID j
, dReal x
, dReal y
, dReal z
)
613 dxJointPU
* joint
= ( dxJointPU
* ) j
;
614 dUASSERT( joint
, "bad joint argument" );
615 checktype( joint
, PU
);
617 setAxes( joint
, x
, y
, z
, joint
->axisP1
, 0 );
619 joint
->computeInitialRelativeRotations();
625 void dJointGetPUAngles( dJointID j
, dReal
*angle1
, dReal
*angle2
)
627 dxJointUniversal
* joint
= ( dxJointUniversal
* ) j
;
628 dUASSERT( joint
, "bad joint argument" );
629 checktype( joint
, PU
);
630 if ( joint
->flags
& dJOINT_REVERSE
)
631 joint
->getAngles( angle2
, angle1
);
633 joint
->getAngles( angle1
, angle2
);
637 dReal
dJointGetPUAngle1( dJointID j
)
639 dxJointUniversal
* joint
= ( dxJointUniversal
* ) j
;
640 dUASSERT( joint
, "bad joint argument" );
641 checktype( joint
, PU
);
642 if ( joint
->flags
& dJOINT_REVERSE
)
643 return joint
->getAngle2();
645 return joint
->getAngle1();
649 dReal
dJointGetPUAngle2( dJointID j
)
651 dxJointUniversal
* joint
= ( dxJointUniversal
* ) j
;
652 dUASSERT( joint
, "bad joint argument" );
653 checktype( joint
, PU
);
654 if ( joint
->flags
& dJOINT_REVERSE
)
655 return joint
->getAngle1();
657 return joint
->getAngle2();
661 dReal
dJointGetPUAngle1Rate( dJointID j
)
663 dxJointPU
* joint
= ( dxJointPU
* ) j
;
664 dUASSERT( joint
, "bad joint argument" );
665 checktype( joint
, PU
);
667 if ( joint
->node
[0].body
)
671 if ( joint
->flags
& dJOINT_REVERSE
)
672 getAxis2( joint
, axis
, joint
->axis2
);
674 getAxis( joint
, axis
, joint
->axis1
);
676 dReal rate
= dCalcVectorDot3( axis
, joint
->node
[0].body
->avel
);
677 if ( joint
->node
[1].body
) rate
-= dCalcVectorDot3( axis
, joint
->node
[1].body
->avel
);
684 dReal
dJointGetPUAngle2Rate( dJointID j
)
686 dxJointPU
* joint
= ( dxJointPU
* ) j
;
687 dUASSERT( joint
, "bad joint argument" );
688 checktype( joint
, PU
);
690 if ( joint
->node
[0].body
)
694 if ( joint
->flags
& dJOINT_REVERSE
)
695 getAxis( joint
, axis
, joint
->axis1
);
697 getAxis2( joint
, axis
, joint
->axis2
);
699 dReal rate
= dCalcVectorDot3( axis
, joint
->node
[0].body
->avel
);
700 if ( joint
->node
[1].body
) rate
-= dCalcVectorDot3( axis
, joint
->node
[1].body
->avel
);
707 void dJointSetPUParam( dJointID j
, int parameter
, dReal value
)
709 dxJointPU
* joint
= ( dxJointPU
* ) j
;
710 dUASSERT( joint
, "bad joint argument" );
711 checktype( joint
, PU
);
713 switch ( parameter
& 0xff00 )
716 joint
->limot1
.set( parameter
, value
);
719 joint
->limot2
.set( parameter
& 0xff, value
);
722 joint
->limotP
.set( parameter
& 0xff, value
);
727 void dJointGetPUAnchor( dJointID j
, dVector3 result
)
729 dxJointPU
* joint
= ( dxJointPU
* ) j
;
730 dUASSERT( joint
, "bad joint argument" );
731 dUASSERT( result
, "bad result argument" );
732 checktype( joint
, PU
);
734 if ( joint
->node
[1].body
)
735 getAnchor2( joint
, result
, joint
->anchor2
);
738 // result[i] = joint->anchor2[i];
739 dCopyVector3( result
, joint
->anchor2
);
743 void dJointGetPUAxis1( dJointID j
, dVector3 result
)
745 dxJointPU
* joint
= ( dxJointPU
* ) j
;
746 dUASSERT( joint
, "bad joint argument" );
747 dUASSERT( result
, "bad result argument" );
748 checktype( joint
, PU
);
749 if ( joint
->flags
& dJOINT_REVERSE
)
750 getAxis2( joint
, result
, joint
->axis2
);
752 getAxis( joint
, result
, joint
->axis1
);
755 void dJointGetPUAxis2( dJointID j
, dVector3 result
)
757 dxJointPU
* joint
= ( dxJointPU
* ) j
;
758 dUASSERT( joint
, "bad joint argument" );
759 dUASSERT( result
, "bad result argument" );
760 checktype( joint
, PU
);
761 if ( joint
->flags
& dJOINT_REVERSE
)
762 getAxis( joint
, result
, joint
->axis1
);
764 getAxis2( joint
, result
, joint
->axis2
);
768 * @brief Get the prismatic axis
771 * @note This function was added for convenience it is the same as
774 void dJointGetPUAxisP( dJointID id
, dVector3 result
)
776 dJointGetPUAxis3( id
, result
);
780 void dJointGetPUAxis3( dJointID j
, dVector3 result
)
782 dxJointPU
* joint
= ( dxJointPU
* ) j
;
783 dUASSERT( joint
, "bad joint argument" );
784 dUASSERT( result
, "bad result argument" );
785 checktype( joint
, PU
);
786 getAxis( joint
, result
, joint
->axisP1
);
789 dReal
dJointGetPUParam( dJointID j
, int parameter
)
791 dxJointPU
* joint
= ( dxJointPU
* ) j
;
792 dUASSERT( joint
, "bad joint argument" );
793 checktype( joint
, PU
);
795 switch ( parameter
& 0xff00 )
798 return joint
->limot1
.get( parameter
);
801 return joint
->limot2
.get( parameter
& 0xff );
804 return joint
->limotP
.get( parameter
& 0xff );
813 dxJointPU::type() const
820 dxJointPU::size() const
822 return sizeof( *this );
827 dxJointPU::setRelativeValues()
830 dJointGetPUAnchor(this, anchor
);
831 setAnchors( this, anchor
[0], anchor
[1], anchor
[2], anchor1
, anchor2
);
833 dVector3 ax1
, ax2
, ax3
;
834 dJointGetPUAxis1(this, ax1
);
835 dJointGetPUAxis2(this, ax2
);
836 dJointGetPUAxis3(this, ax3
);
838 if ( flags
& dJOINT_REVERSE
)
840 setAxes( this, ax1
[0], ax1
[1], ax1
[2], NULL
, axis2
);
841 setAxes( this, ax2
[0], ax2
[1], ax2
[2], axis1
, NULL
);
845 setAxes( this, ax1
[0], ax1
[1], ax1
[2], axis1
, NULL
);
846 setAxes( this, ax2
[0], ax2
[1], ax2
[2], NULL
, axis2
);
850 setAxes( this, ax3
[0], ax3
[1], ax3
[2], NULL
, axisP1
);
852 computeInitialRelativeRotations();