/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ #include #include "config.h" #include "plane2d.h" #include "joint_internal.h" //**************************************************************************** // Plane2D /* This code is part of the Plane2D ODE joint by psero@gmx.de Wed Apr 23 18:53:43 CEST 2003 */ static const dReal Midentity[3][3] = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1, } }; dxJointPlane2D::dxJointPlane2D( dxWorld *w ) : dxJoint( w ) { motor_x.init( world ); motor_y.init( world ); motor_angle.init( world ); } void dxJointPlane2D::getSureMaxInfo( SureMaxInfo* info ) { info->max_m = 6; } void dxJointPlane2D::getInfo1( dxJoint::Info1 *info ) { info->nub = 3; info->m = 3; if ( motor_x.fmax > 0 ) row_motor_x = info->m++; else row_motor_x = 0; if ( motor_y.fmax > 0 ) row_motor_y = info->m++; else row_motor_y = 0; if ( motor_angle.fmax > 0 ) row_motor_angle = info->m++; else row_motor_angle = 0; } void dxJointPlane2D::getInfo2( dReal worldFPS, dReal worldERP, int rowskip, dReal *J1, dReal *J2, int pairskip, dReal *pairRhsCfm, dReal *pairLoHi, int *findex ) { dReal eps = worldFPS * worldERP; /* v = v1, w = omega1 (v2, omega2 not important (== static environment)) constraint equations: vz = 0 wx = 0 wy = 0 <=> ( 0 0 1 ) (vx) ( 0 0 0 ) (wx) ( 0 ) ( 0 0 0 ) (vy) + ( 1 0 0 ) (wy) = ( 0 ) ( 0 0 0 ) (vz) ( 0 1 0 ) (wz) ( 0 ) J1/J1l Omega1/J1a */ // fill in linear and angular coeff. for left hand side: J1[GI2_JLZ] = 1; J1[rowskip + GI2_JAX] = 1; J1[2 * rowskip + GI2_JAY] = 1; // error correction (against drift): // a) linear vz, so that z (== pos[2]) == 0 pairRhsCfm[GI2_RHS] = eps * -node[0].body->posr.pos[2]; # if 0 // b) angular correction? -> left to application !!! dReal *body_z_axis = &node[0].body->R[8]; pairRhsCfm[pairskip + GI2_RHS] = eps * + atan2( body_z_axis[1], body_z_axis[2] ); // wx error pairRhsCfm[2 * pairskip + GI2_RHS] = eps * -atan2( body_z_axis[0], body_z_axis[2] ); // wy error # endif // if the slider is powered, or has joint limits, add in the extra row: if ( row_motor_x > 0 ) { int currRowSkip = row_motor_x * rowskip, currPairSkip = row_motor_x * pairskip; motor_x.addLimot( this, worldFPS, J1 + currRowSkip, J2 + currRowSkip, pairRhsCfm + currPairSkip, pairLoHi + currPairSkip, Midentity[0], 0 ); } if ( row_motor_y > 0 ) { int currRowSkip = row_motor_y * rowskip, currPairSkip = row_motor_y * pairskip; motor_y.addLimot( this, worldFPS, J1 + currRowSkip, J2 + currRowSkip, pairRhsCfm + currPairSkip, pairLoHi + currPairSkip, Midentity[1], 0 ); } if ( row_motor_angle > 0 ) { int currRowSkip = row_motor_angle * rowskip, currPairSkip = row_motor_angle * pairskip; motor_angle.addLimot( this, worldFPS, J1 + currRowSkip, J2 + currRowSkip, pairRhsCfm + currPairSkip, pairLoHi + currPairSkip, Midentity[2], 1 ); } } dJointType dxJointPlane2D::type() const { return dJointTypePlane2D; } sizeint dxJointPlane2D::size() const { return sizeof( *this ); } void dJointSetPlane2DXParam( dxJoint *joint, int parameter, dReal value ) { dUASSERT( joint, "bad joint argument" ); checktype( joint, Plane2D ); dxJointPlane2D* joint2d = ( dxJointPlane2D* )( joint ); joint2d->motor_x.set( parameter, value ); } void dJointSetPlane2DYParam( dxJoint *joint, int parameter, dReal value ) { dUASSERT( joint, "bad joint argument" ); checktype( joint, Plane2D ); dxJointPlane2D* joint2d = ( dxJointPlane2D* )( joint ); joint2d->motor_y.set( parameter, value ); } void dJointSetPlane2DAngleParam( dxJoint *joint, int parameter, dReal value ) { dUASSERT( joint, "bad joint argument" ); checktype( joint, Plane2D ); dxJointPlane2D* joint2d = ( dxJointPlane2D* )( joint ); joint2d->motor_angle.set( parameter, value ); }