00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00269 #include "../include/IPSA/SoJoint.h"
00270 #include "../include/IPSA/SoPhysics.h"
00271
00272 #include <Inventor/nodes/SoTransform.h>
00273
00274
00275 SO_KIT_SOURCE(SoJoint);
00276
00279 void SoJoint::initClass()
00280 {
00281 SO_KIT_INIT_CLASS(SoJoint, SoBaseKit, "BaseKit");
00282 }
00283
00284
00293 SoJoint::SoJoint(const SbString& BodyOne, const SbString& BodyTwo, const SbString& nodeName)
00294 : INIT_CFM(1e-8f),
00295 INIT_ERP(0.2f),
00296 isInitialised(FALSE)
00297 {
00298 SO_KIT_CONSTRUCTOR(SoJoint);
00299 isBuiltIn = TRUE;
00300
00301 SO_KIT_ADD_CATALOG_ENTRY(visualisationShape, SoSeparator, FALSE, this, "", TRUE);
00302
00303 SO_KIT_ADD_FIELD(Bodyname1, (""));
00304 SO_KIT_ADD_FIELD(Bodyname2, (""));
00305 SO_KIT_ADD_FIELD(VisualisationScale, (1.0f));
00306 SO_KIT_ADD_FIELD(drawVisualisationShape, (FALSE));
00307
00308 SO_KIT_INIT_INSTANCE();
00309
00310 soJointFeedback = new dJointFeedback;
00311 soJointGroupId = dJointGroupCreate(0);
00312
00313 drawVisualisationShapeSensor.setFunction(SoJoint::IPSAJointDrawVisualisationChangedCB);
00314 drawVisualisationShapeSensor.setData(this);
00315 updateOdeParametersSensor.setFunction(SoJoint::IPSAUpdateOdeParametersCB);
00316 updateOdeParametersSensor.setData(this);
00317
00318
00319
00320
00321
00322
00323
00324 Bodyname1.setValue(BodyOne);
00325 Bodyname2.setValue(BodyTwo);
00326
00327 this->setName(nodeName);
00328 }
00329
00330
00334 SoBaseKit* SoJoint::copy(SbBool copyConnections) const
00335 {
00336 SoJoint* newJoint = static_cast<SoJoint*> (SoBaseKit::copy(copyConnections));
00337
00338 newJoint->soJointFeedback = soJointFeedback;
00339 newJoint->soJointGroupId = soJointGroupId;
00340 newJoint->soJointId = soJointId;
00341 newJoint->isInitialised = isInitialised;
00342 newJoint->setUpConnections(TRUE, TRUE);
00343
00344 return newJoint;
00345 }
00346
00347
00359 SbBool SoJoint::setUpConnections(SbBool onOff, SbBool doItAlways)
00360 {
00361 if (!doItAlways && connectionsSetUp == onOff)
00362 return onOff;
00363 if (onOff)
00364 {
00365 SoBaseKit::setUpConnections(onOff, doItAlways);
00366
00367 SoJoint::IPSAJointDrawVisualisationChangedCB(this, NULL);
00368
00369 if (&drawVisualisationShape != drawVisualisationShapeSensor.getAttachedField())
00370 drawVisualisationShapeSensor.attach(&drawVisualisationShape);
00371 if (&updateOdeParametersTrigger != updateOdeParametersSensor.getAttachedField())
00372 updateOdeParametersSensor.attach(&updateOdeParametersTrigger);
00373 }
00374 else
00375 {
00376 if (NULL != drawVisualisationShapeSensor.getAttachedField())
00377 drawVisualisationShapeSensor.detach();
00378 if (NULL != updateOdeParametersSensor.getAttachedField())
00379 updateOdeParametersSensor.detach();
00380 SoBaseKit::setUpConnections(onOff, doItAlways);
00381 }
00382
00383 connectionsSetUp = onOff;
00384 return !connectionsSetUp;
00385 }
00386
00387
00390 SoJoint::~SoJoint()
00391 {
00392 delete soJointFeedback;
00393 soJointFeedback = NULL;
00394 destroyJoint();
00395 }
00396
00397
00405 void SoJoint::destroyJoint()
00406 {
00407 if (NULL != soJointGroupId)
00408 {
00409 dJointGroupDestroy(soJointGroupId);
00410 soJointGroupId = NULL;
00411 }
00412 }
00413
00414
00418 dJointID SoJoint::getJointID()
00419 {
00420 return this->soJointId;
00421 }
00422
00423
00439 SoCallbackAction::Response SoJoint::InitOdeJointsCB(void* userdata, SoCallbackAction* action, const SoNode* node)
00440 {
00441 SoJoint* joint = dynamic_cast<SoJoint*> (const_cast<SoNode*> (node));
00442 if (NULL == joint)
00443 return SoCallbackAction::CONTINUE;
00444
00445 if (!joint->isInitialised)
00446 {
00447 joint->setUpConnections(TRUE, TRUE);
00448 printf("creating %s (%s) ", joint->getTypeId().getName().getString(), joint->getName().getString());
00449
00450
00451 SoPhysics* p1 = joint->getPhysicsBody1();
00452 SoPhysics* p2 = joint->getPhysicsBody2();
00453 assert (p1 != NULL);
00454
00455 printf("linking (%s)<->(%s)\n\r", p1->getName().getString(), (p2 != NULL ? p2->getName().getString():("")) );
00456
00457 dWorldID soWorldId = p1->getWorld();
00458 assert (soWorldId != NULL && "SoJoint::InitOdeJointsCB() soWorldID must not be NULL");
00459
00460
00461
00462 dBodyID body2 = NULL;
00463 if (p2 != NULL)
00464 {
00465 assert (soWorldId == p2->getWorld() && "SoJoint::InitOdeJointsCB() bodies connected to the joint don't exist in the same world");
00466 body2 = p2->getBody();
00467 }
00468
00469 joint->createOdeJoint(soWorldId);
00470 dJointID odeJointId = joint->soJointId;
00471
00472 if (NULL != odeJointId)
00473 {
00474
00475 dJointAttach(odeJointId, p1->getBody(), body2);
00476 dJointSetFeedback(odeJointId, joint->soJointFeedback);
00477 }
00478 else
00479 printf("SoJoint::InitOdeJointsCB() no joint created");
00480
00481 joint->isInitialised = TRUE;
00482 }
00483
00484 joint->updateOdeJointProperties(action->getModelMatrix());
00485
00486 joint->setParams();
00487
00488 return SoCallbackAction::CONTINUE;
00489 }
00490
00491
00498 void SoJoint::createOdeJoint(const dWorldID soWorldId)
00499 {
00500 soJointId = NULL;
00501 }
00502
00503
00509 void SoJoint::updateOdeJointProperties(const SbMatrix& modelMatrix)
00510 {
00511
00512 }
00513
00514
00520 SoPhysics* SoJoint::getPhysicsBody(const SbName& bodyName)
00521 {
00522 if (0 >= bodyName.getLength())
00523 return NULL;
00524
00525 SoNode* bodyNode = SoNode::getByName(bodyName.getString());
00526
00527 SoPhysics* physics = dynamic_cast<SoPhysics*>(bodyNode);
00528
00529 return physics;
00530 }
00531
00532
00538 SoPhysics* SoJoint::getPhysicsBody1()
00539 {
00540 return getPhysicsBody(Bodyname1.getValue());
00541 }
00542
00543
00549 SoPhysics* SoJoint::getPhysicsBody2()
00550 {
00551 return getPhysicsBody(Bodyname2.getValue());
00552 }
00553
00554
00563 void SoJoint::setTorque(dReal torque1 , dReal torque2 , dReal torque3 )
00564 {
00565 printf("This method is not implemented by this joint\n");
00566 }
00567
00568
00575 void SoJoint::setForce(dReal force1 )
00576 {
00577 printf("This method is not implemented by this joint\n");
00578 }
00579
00580
00589 SoSFVec3f SoJoint::getTorque(int idx)
00590 {
00591 SoSFVec3f ret;
00592
00593 assert(soJointId != NULL);
00594 soJointFeedback = dJointGetFeedback(soJointId);
00595
00596 switch (idx)
00597 {
00598 case 1:
00599 ret.setValue(soJointFeedback->t1[0],soJointFeedback->t1[1],soJointFeedback->t1[2]);
00600 break;
00601 case 2:
00602 ret.setValue(soJointFeedback->t2[0],soJointFeedback->t2[1],soJointFeedback->t2[2]);
00603 break;
00604 default:
00605 ret.setValue(soJointFeedback->t1[0],soJointFeedback->t1[1],soJointFeedback->t1[2]);
00606 break;
00607 }
00608 return ret;
00609 }
00610
00611
00620 SoSFVec3f SoJoint::getForce(int idx)
00621 {
00622 SoSFVec3f ret;
00623
00624 assert(soJointId != NULL);
00625 soJointFeedback = dJointGetFeedback(soJointId);
00626
00627 switch (idx)
00628 {
00629 case 1:
00630 ret.setValue(soJointFeedback->f1[0],soJointFeedback->f1[1],soJointFeedback->f1[2]);
00631 break;
00632 case 2:
00633 ret.setValue(soJointFeedback->f2[0],soJointFeedback->f2[1],soJointFeedback->f2[2]);
00634 break;
00635 default:
00636 ret.setValue(soJointFeedback->f1[0],soJointFeedback->f1[1],soJointFeedback->f1[2]);
00637 break;
00638 }
00639 return ret;
00640 }
00641
00642
00650 void SoJoint::IPSAJointDrawVisualisationChangedCB(void* data, SoSensor*)
00651 {
00652 SoJoint* currentJoint = static_cast<SoJoint*> (data);
00653 if (NULL == currentJoint)
00654 return;
00655
00656 SoSeparator* currentVisualisation = dynamic_cast<SoSeparator*> (currentJoint->visualisationShape.getValue());
00657 if (FALSE == currentJoint->drawVisualisationShape.getValue())
00658 currentVisualisation->removeAllChildren();
00659 else
00660 {
00661 SoNode* visualisation = currentJoint->createVisualisation();
00662 if (NULL != visualisation)
00663 currentVisualisation->addChild(visualisation);
00664 }
00665 }
00666
00667
00673 void SoJoint::IPSAUpdateOdeParametersCB(void* data, SoSensor*)
00674 {
00675 SoJoint* currentJoint = static_cast<SoJoint*>(data);
00676 if(!currentJoint)
00677 return;
00678
00679 currentJoint->setParams();
00680 }
00681
00682
00690 void SoJoint::GenerateCylinderAlignmentRotation(const SbVec3f& axis, SoTransform& transform)
00691 {
00692 SbVec3f rotation;
00693 rotation[0] = axis.dot(SbVec3f(0, 0, 1));
00694 rotation[1] = axis.dot(SbVec3f(0, 1, 0));
00695 rotation[2] = axis.dot(SbVec3f(1, 0, 0));
00696
00697 transform.rotation.setValue(rotation, -1.57f);
00698 }