00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00098 #include "../include/IPSA/SoFrictionCone.h"
00099
00100 #include <Inventor/nodes/SoCone.h>
00101 #include <Inventor/nodes/SoMaterial.h>
00102 #include <Inventor/nodes/SoTransform.h>
00103 #include <Inventor/nodes/SoSeparator.h>
00104 #include <Inventor/nodes/SoResetTransform.h>
00105
00106 SO_KIT_SOURCE(SoFrictionCone);
00107
00108 std::string SoFrictionCone::FrictionConeSeparatorName = std::string("FrictionCones");
00109
00112 void SoFrictionCone::initClass()
00113 {
00114 SO_KIT_INIT_CLASS(SoFrictionCone, SoBaseKit, "BaseKit");
00115 }
00116
00117
00120 SoFrictionCone::SoFrictionCone()
00121 {
00122 SO_KIT_CONSTRUCTOR(SoFrictionCone);
00123 isBuiltIn = TRUE;
00124
00125 SO_KIT_ADD_CATALOG_ENTRY(resetTransform,SoResetTransform,FALSE,this,offsetTransform,TRUE);
00126 SO_KIT_ADD_CATALOG_ENTRY(offsetTransform,SoTransform,FALSE,this,transform,TRUE);
00127 SO_KIT_ADD_CATALOG_ENTRY(transform,SoTransform,FALSE,this,material,TRUE);
00128 SO_KIT_ADD_CATALOG_ENTRY(material,SoMaterial,FALSE,this,visualisation,TRUE);
00129 SO_KIT_ADD_CATALOG_ENTRY(visualisation,SoCone,FALSE,this,"",TRUE);
00130
00131 SO_KIT_ADD_FIELD(height, (1.0f));
00132 SO_KIT_ADD_FIELD(radius, (1.0f));
00133 SO_KIT_ADD_FIELD(scaling, (1.0f));
00134 SO_KIT_ADD_FIELD(transparency, (0.0f));
00135 SO_KIT_ADD_FIELD(color, (1.0f, 0.5f, 0.5f));
00136 SO_KIT_ADD_FIELD(contactPoint, (0.0f, 0.0f, 0.0f));
00137 SO_KIT_ADD_FIELD(contactNormal, (1.0f, 0.0f, 0.0f));
00138
00139 SO_KIT_INIT_INSTANCE();
00140
00141 updateParametersSensor.setFunction(SoFrictionCone::UpdateParametersCB);
00142 updateParametersSensor.setData(this);
00143
00144 updateParametersTrigger.appendConnection(&height);
00145 updateParametersTrigger.appendConnection(&radius);
00146 updateParametersTrigger.appendConnection(&scaling);
00147 updateParametersTrigger.appendConnection(&transparency);
00148 updateParametersTrigger.appendConnection(&color);
00149 updateParametersTrigger.appendConnection(&contactPoint);
00150 updateParametersTrigger.appendConnection(&contactNormal);
00151 setUpConnections(TRUE, TRUE);
00152 }
00153
00154
00158 SoBaseKit* SoFrictionCone::copy(SbBool copyConnections) const
00159 {
00160
00161
00162 SoFrictionCone *newSoFrictionCone = (SoFrictionCone *) SoBaseKit::copy(copyConnections);
00163 return newSoFrictionCone;
00164 }
00165
00166
00175 SbBool SoFrictionCone::setUpConnections(SbBool onOff, SbBool doItAlways)
00176 {
00177 if (!doItAlways && connectionsSetUp == onOff)
00178 return onOff;
00179 if (onOff)
00180 {
00181 SoBaseKit::setUpConnections(onOff, doItAlways);
00182
00183 SoFrictionCone::UpdateParametersCB(this, NULL);
00184
00185 if (&updateParametersTrigger != updateParametersSensor.getAttachedField())
00186 updateParametersSensor.attach(&updateParametersTrigger);
00187 }
00188 else
00189 {
00190 if (NULL != updateParametersSensor.getAttachedField())
00191 updateParametersSensor.detach();
00192 SoBaseKit::setUpConnections(onOff, doItAlways);
00193 }
00194
00195 connectionsSetUp = onOff;
00196 return !connectionsSetUp;
00197 }
00198
00199
00204 void SoFrictionCone::addToGraph(SoSeparator* root)
00205 {
00206 SoSeparator* frictionConeSep = GetFrictionConeSeparatorFromGraph(root);
00207 if (NULL == frictionConeSep)
00208 return;
00209 frictionConeSep->addChild(this);
00210 }
00211
00212
00217 void SoFrictionCone::RemoveAllFrictionConesFromGraph(SoSeparator* root)
00218 {
00219 SoSeparator* frictionConeSep = GetFrictionConeSeparatorFromGraph(root);
00220 if (NULL == frictionConeSep)
00221 return;
00222 frictionConeSep->removeAllChildren();
00223 }
00224
00225
00233 SoSeparator* SoFrictionCone::GetFrictionConeSeparatorFromGraph(SoSeparator* root)
00234 {
00235 if (NULL == root)
00236 return NULL;
00237 SoSeparator* frictionConeNode = static_cast<SoSeparator*> (root->getByName(SoFrictionCone::FrictionConeSeparatorName.c_str()));
00238 if (NULL == frictionConeNode)
00239 {
00240 frictionConeNode = new SoSeparator;
00241 frictionConeNode->setName(SoFrictionCone::FrictionConeSeparatorName.c_str());
00242
00243 dynamic_cast<SoSeparator*> (root)->addChild(frictionConeNode);
00244 }
00245 return frictionConeNode;
00246 }
00247
00248
00257 void SoFrictionCone::UpdateParametersCB(void* data, SoSensor*)
00258 {
00259 SoFrictionCone* currentCone = static_cast<SoFrictionCone*> (data);
00260 if (NULL == currentCone)
00261 return;
00262 SoCone* visualisationCone = dynamic_cast<SoCone*> (currentCone->getPart("visualisation", TRUE));
00263 if (NULL != visualisationCone)
00264 {
00265 visualisationCone->height.setValue(currentCone->height.getValue() * currentCone->scaling.getValue());
00266 visualisationCone->bottomRadius.setValue(currentCone->radius.getValue() * currentCone->scaling.getValue());
00267 }
00268
00269 SoMaterial* coneMaterial = dynamic_cast<SoMaterial*> (currentCone->getPart("material", TRUE));
00270 if (NULL != coneMaterial)
00271 {
00272 float coneTransparency = currentCone->transparency.getValue();
00273 if (coneTransparency < 0) coneTransparency = 0;
00274 else if (coneTransparency > 1) coneTransparency = 1;
00275
00276 currentCone->transparency.setValue(coneTransparency);
00277 coneMaterial->diffuseColor.setValue(currentCone->color.getValue());
00278 coneMaterial->transparency.setValue(currentCone->transparency.getValue());
00279 }
00280
00281 SoTransform* alignment = dynamic_cast<SoTransform*> (currentCone->getPart("offsetTransform", TRUE));
00282 if (NULL != alignment)
00283 {
00284
00285
00286
00287 SbVec3f offset( 0.0f, -(visualisationCone->height.getValue() / 2.0f), 0.0f);
00288 alignment->translation.setValue(offset);
00289 }
00290
00291 SoTransform* coneTransform = dynamic_cast<SoTransform*> (currentCone->getPart("transform", TRUE));
00292 if (NULL != coneTransform)
00293 {
00294
00295
00296 SbRotation rotation(SbVec3f(0.0f, 1.0f, 0.0f), currentCone->contactNormal.getValue());
00297 SbMatrix alignmentMatrix;
00298 alignmentMatrix.setTransform(currentCone->contactPoint.getValue(), rotation, SbVec3f(1, 1, 1));
00299 coneTransform->setMatrix(alignmentMatrix);
00300 }
00301 }