00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00279 #include "../include/IPSA/SoCollisionShape.h"
00280 #include "../include/IPSA/SoWorldPhysics.h"
00281 #include <Inventor/SbBox.h>
00282 #include <Inventor/nodes/SoCube.h>
00283 #include <Inventor/nodes/SoSeparator.h>
00284 #include <Inventor/nodes/SoDrawStyle.h>
00285
00286 SO_KIT_SOURCE(SoCollisionShape);
00287
00288
00291 void SoCollisionShape::initClass()
00292 {
00293 SO_KIT_INIT_CLASS(SoCollisionShape, SoBaseKit, "BaseKit");
00294 }
00295
00296
00308 SoCallbackAction::Response SoCollisionShape::InitCollisionShapesCB(void* userdata, SoCallbackAction* action, const SoNode* node)
00309 {
00310 SoWorldPhysics* world = static_cast<SoWorldPhysics*> (userdata);
00311 SoCollisionShape* collisionShape = dynamic_cast<SoCollisionShape*> (const_cast<SoNode*> (node));
00312
00313 if (NULL != world && NULL != collisionShape)
00314 {
00315 collisionShape->setUpConnections(TRUE, TRUE);
00316 collisionShape->setSpace(world->ownspace);
00317 collisionShape->createGeom(action->getModelMatrix());
00318 collisionShape->updateGeomPosition(action->getModelMatrix());
00319 if (collisionShape->autoinitialise.getValue())
00320 collisionShape->updateVisualisationAndOdeProperties();
00321 }
00322 return SoCallbackAction::CONTINUE;
00323 }
00324
00325
00330 SoCollisionShape::SoCollisionShape(const SbString& nodeName )
00331 : CoinRefTransform(SbMatrix::identity()),
00332 space(NULL),
00333 geometry(NULL),
00334 COG(SbVec3f(0.0f, 0.0f, 0.0f))
00335 {
00336 SO_KIT_CONSTRUCTOR(SoCollisionShape);
00337
00338 SO_KIT_ADD_CATALOG_ENTRY(separator,SoSeparator,FALSE,this,"",TRUE);
00339 SO_KIT_ADD_CATALOG_ENTRY(visDrawStyle,SoDrawStyle,TRUE,separator,ODETransform,TRUE);
00340 SO_KIT_ADD_CATALOG_ENTRY(ODETransform,SoMatrixTransform,FALSE,separator,visualisation,TRUE);
00341 SO_KIT_ADD_CATALOG_ABSTRACT_ENTRY(visualisation,SoNode,SoCube,TRUE,separator,"",TRUE);
00342
00343 SO_KIT_ADD_FIELD(alignment,(SoCollisionShape::STANDARD));
00344 SO_KIT_DEFINE_ENUM_VALUE(eAlignment, STANDARD);
00345 SO_KIT_DEFINE_ENUM_VALUE(eAlignment, CENTERED);
00346 SO_KIT_SET_SF_ENUM_TYPE(alignment, eAlignment);
00347
00348 SO_KIT_ADD_FIELD(surfaceMaterial, (SoCollisionShape::GREASY));
00349 SO_KIT_DEFINE_ENUM_VALUE(eSurfaceMaterial, CLEAN);
00350 SO_KIT_DEFINE_ENUM_VALUE(eSurfaceMaterial, GREASY);
00351 SO_KIT_DEFINE_ENUM_VALUE(eSurfaceMaterial, WOOD);
00352 SO_KIT_DEFINE_ENUM_VALUE(eSurfaceMaterial, GLASS);
00353 SO_KIT_DEFINE_ENUM_VALUE(eSurfaceMaterial, STEEL);
00354 SO_KIT_DEFINE_ENUM_VALUE(eSurfaceMaterial, RUBBER);
00355 SO_KIT_SET_SF_ENUM_TYPE(surfaceMaterial, eSurfaceMaterial);
00356
00357 SO_KIT_ADD_FIELD(category,(1));
00358 SO_KIT_ADD_FIELD(collisionmask,(1));
00359 SO_KIT_ADD_FIELD(autoinitialise,(TRUE));
00360
00361 SO_KIT_INIT_INSTANCE();
00362
00363
00364 SoDrawStyle* dstyle = dynamic_cast<SoDrawStyle*> (getPart("visDrawStyle", TRUE));
00365 dstyle->style = SoDrawStyle::INVISIBLE;
00366
00367
00368 transform = dynamic_cast<SoMatrixTransform*> (getPart("ODETransform", FALSE));
00369
00370 this->setName(nodeName);
00371
00372 updateOdePropertiesSensor.setFunction(SoCollisionShape::UpdateVisualisationAndOdePropertiesCB);
00373 updateOdePropertiesSensor.setData(this);
00374
00375
00376
00377
00378
00379
00380 }
00381
00382
00386 SoBaseKit* SoCollisionShape::copy(SbBool copyConnections) const
00387 {
00388
00389
00390 SoCollisionShape* newSoCollisionShape = dynamic_cast<SoCollisionShape*> (SoBaseKit::copy(copyConnections));
00391 assert(geometry == NULL && "Can not copy initialised SoCollisionshapes!\n");
00392
00393 newSoCollisionShape->space = space;
00394 newSoCollisionShape->geometry = geometry;
00395 newSoCollisionShape->COG = COG;
00396 newSoCollisionShape->transform = transform;
00397 newSoCollisionShape->CoinRefTransform = CoinRefTransform;
00398 newSoCollisionShape->setUpConnections(TRUE, TRUE);
00399
00400 return newSoCollisionShape;
00401 }
00402
00403
00410 SbBool SoCollisionShape::setUpConnections(SbBool onOff, SbBool doItAlways )
00411 {
00412 if (!doItAlways && onOff == connectionsSetUp)
00413 return onOff;
00414 if (onOff)
00415 {
00416 SoBaseKit::setUpConnections(onOff, doItAlways);
00417
00418 SoCollisionShape::UpdateVisualisationAndOdePropertiesCB(this, NULL);
00419
00420 if (&updateOdePropertiesTrigger != updateOdePropertiesSensor.getAttachedField())
00421 updateOdePropertiesSensor.attach(&updateOdePropertiesTrigger);
00422 }
00423 else
00424 {
00425 if (NULL != updateOdePropertiesSensor.getAttachedField())
00426 updateOdePropertiesSensor.detach();
00427 SoBaseKit::setUpConnections(onOff, doItAlways);
00428 }
00429
00430 connectionsSetUp = onOff;
00431 return !connectionsSetUp;
00432 }
00433
00434
00437 SoCollisionShape::~SoCollisionShape()
00438 {
00439 if (geometry != NULL)
00440 {
00441 dGeomDestroy(geometry);
00442 geometry = NULL;
00443 }
00444 }
00445
00446
00450 void SoCollisionShape::updateVisualisationAndOdeProperties()
00451 {
00452 SoCube* vis = dynamic_cast<SoCube*> (getPart("visualisation", TRUE));
00453 if(NULL != vis)
00454 {
00455 vis->width.setValue(1);
00456 vis->height.setValue(1);
00457 vis->depth.setValue(1);
00458 }
00459 }
00460
00461
00465 dGeomID SoCollisionShape::getGeom()
00466 {
00467 return geometry;
00468 }
00469
00470
00485 dGeomID SoCollisionShape::createGeom(const SbMatrix& mm)
00486 {
00487 if(geometry == NULL)
00488 {
00489 geometry = this->cGeom(mm);
00490 dGeomSetBody(geometry, NULL);
00491 dGeomSetData(geometry, this);
00492 }
00493
00494 updateVisualisationAndOdeProperties();
00495
00496
00497 dGeomSetCategoryBits(geometry, category.getValue());
00498 dGeomSetCollideBits(geometry, collisionmask.getValue());
00499 return geometry;
00500 }
00501
00502
00509 void SoCollisionShape::setSpace(dSpaceID spaceID)
00510 {
00511 if (NULL == space)
00512 space = spaceID;
00513 else if (spaceID == space)
00514 {
00515
00516 }
00517 else
00518 {
00519 printf("SoCollisionShape::setSpace() -> the space has already been set!");
00520 printf(" Changing the collision space is not allowed/supported currently.\n");
00521 }
00522 }
00523
00524
00532 dGeomID SoCollisionShape::cGeom(const SbMatrix& mm)
00533 {
00534 assert(space != NULL);
00535
00536 return dCreateBox(space, 1, 1, 1);
00537 }
00538
00539
00544 SbBool SoCollisionShape::getVisualisationStatus()
00545 {
00546 SoDrawStyle* dstyle = dynamic_cast<SoDrawStyle*> (getPart("visDrawStyle", FALSE));
00547 if(dstyle->style.getValue() == SoDrawStyle::INVISIBLE)
00548 return FALSE;
00549 else
00550 return TRUE;
00551 }
00552
00553
00558 void SoCollisionShape::setVisualisationStatus(SbBool onOff)
00559 {
00560 SoDrawStyle* dstyle = dynamic_cast<SoDrawStyle*> (getPart("visDrawStyle", FALSE));
00561 if(onOff)
00562 dstyle->style = SoDrawStyle::FILLED;
00563 else
00564 dstyle->style = SoDrawStyle::INVISIBLE;
00565 }
00566
00570 void SoCollisionShape::getCOG(SbVec3f& COM)
00571 {
00572 COM = COG;
00573 }
00574
00582 void SoCollisionShape::UpdateVisualisationAndOdePropertiesCB(void* data, SoSensor* sensor)
00583 {
00584 SoCollisionShape* collisionShape = static_cast<SoCollisionShape*> (data);
00585 if (NULL == collisionShape)
00586 return;
00587
00588 collisionShape->updateVisualisationAndOdeProperties();
00589 }
00590
00598 void SoCollisionShape::updateGeomPosition(const SbMatrix& mm)
00599 {
00600 SbVec3f translation;
00601 SbRotation rotation,so;
00602 SbVec3f scaling;
00603 CoinRefTransform.getTransform(translation, rotation, scaling, so);
00604 CoinRefTransform.setTransform(-COG, rotation, scaling);
00605
00606 SbMatrix modelMatrix;
00607 if (alignment.getValue() == SoCollisionShape::STANDARD)
00608 modelMatrix.setTranslate(COG);
00609 else if (alignment.getValue() == SoCollisionShape::CENTERED)
00610 modelMatrix.setTranslate(SbVec3f(0.0,0.0,0.0));
00611
00612 modelMatrix = modelMatrix.multRight(mm);
00613 modelMatrix.getTransform(translation, rotation, scaling, so);
00614
00615
00616 SbVec3f axis;
00617 float radians;
00618 rotation.getValue(axis, radians);
00619 const float* AXIS_VALUES = axis.getValue();
00620 dMatrix3 rot;
00621
00622 dRFromAxisAndAngle(rot, AXIS_VALUES[0], AXIS_VALUES[1], AXIS_VALUES[2], radians);
00623
00624
00625 dGeomSetPosition(geometry, translation[0], translation[1], translation[2]);
00626 dGeomSetRotation(geometry, rot);
00627
00628
00629 }
00630
00636 void SoCollisionShape::updateOIPosition()
00637 {
00638 const dReal* TRANSLATION = dGeomGetPosition (geometry);
00639 dQuaternion rot;
00640 dGeomGetQuaternion (geometry, rot);
00641
00642 SbMatrix ftrans = CoinRefTransform;
00643 SbMatrix odet = SbMatrix::identity();
00644 odet.setTransform(SbVec3f(TRANSLATION[0],TRANSLATION[1],TRANSLATION[2]),
00645 SbRotation(rot[1],rot[2],rot[3],rot[0]),
00646 SbVec3f(1,1,1));
00647 ftrans.multRight(odet);
00648 printf("cshape: oi/ode at: [%f %f %f]\n", TRANSLATION[0], TRANSLATION[1], TRANSLATION[2]);
00649
00650 assert(transform != NULL);
00651 transform->matrix.setValue(ftrans);
00652 }