OSGTransformPushGraphOp.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "OSGTransformPushGraphOp.h"
00040 #include "OSGGraphOpFactory.h"
00041 #include "OSGAction.h"
00042
00043 #include <set>
00044
00045 #include <boost/bind.hpp>
00046
00063 OSG_BEGIN_NAMESPACE
00064
00065 namespace
00066 {
00067 static bool registerOp(void)
00068 {
00069 GraphOpRefPtr newOp = TransformPushGraphOp::create();
00070
00071 GraphOpFactory::the()->registerOp(newOp);
00072 return true;
00073 }
00074
00075 static OSG::StaticInitFuncWrapper registerOpWrapper(registerOp);
00076 }
00077
00078 const char *TransformPushGraphOp::getClassname(void)
00079 {
00080 return "TransformPushGraphOp";
00081 }
00082
00083 TransformPushGraphOp::TransformPushGraphOp(const char* name)
00084 : Inherited(name)
00085 {
00086
00087 }
00088
00089 TransformPushGraphOpTransitPtr
00090 TransformPushGraphOp::create(void)
00091 {
00092 return TransformPushGraphOpTransitPtr(new TransformPushGraphOp);
00093 }
00094
00095 GraphOpTransitPtr TransformPushGraphOp::clone(void)
00096 {
00097 return GraphOpTransitPtr(new TransformPushGraphOp);
00098 }
00099
00100 void TransformPushGraphOp::setParams(const std::string params)
00101 {
00102 ParamSet ps(params);
00103
00104 std::string out = ps.getUnusedParams();
00105 if(out.length())
00106 {
00107 FWARNING(("TransformPushGraphOp doesn't have parameters '%s'.\n",
00108 out.c_str()));
00109 }
00110 }
00111
00112 std::string TransformPushGraphOp::usage(void)
00113 {
00114 return "TransformPush: Move Transform towards leafs of the scene.\n";
00115 }
00116
00117
00118 TransformPushGraphOp::~TransformPushGraphOp(void)
00119 {
00120
00121 }
00122
00123
00124 Action::ResultE TransformPushGraphOp::traverseEnter(Node * const node)
00125 {
00126 if(isInExcludeList(node))
00127 return Action::Skip;
00128
00129 return Action::Continue;
00130 }
00131
00132 Action::ResultE TransformPushGraphOp::traverseLeave(
00133 Node * const node, Action::ResultE res)
00134 {
00135 if(isInExcludeList(node))
00136 return Action::Skip;
00137
00138 if(isInPreserveList(node))
00139 return Action::Continue;
00140
00141 Transform *trans = dynamic_cast<Transform *>(node->getCore());
00142
00143 if(trans == NULL)
00144 return Action::Continue;
00145
00146
00147 if(!node->getMFChildren()->empty())
00148 {
00149 _pushPossible = true;
00150 _pushTargets.clear();
00151
00152 OSG::traverse(
00153 *(node->getMFChildren()),
00154 boost::bind(&TransformPushGraphOp::traverseTargetsEnter, this, _1));
00155
00156 if(_pushPossible == true)
00157 {
00158
00159 pushTransform(trans);
00160
00161
00162 GroupUnrecPtr replaceCore = Group::create();
00163 node->setCore(replaceCore);
00164 }
00165 }
00166
00167 return Action::Continue;
00168 }
00169
00172 Action::ResultE TransformPushGraphOp::traverseTargetsEnter(Node * const node)
00173 {
00174 NodeCore *core = node->getCore();
00175
00176 if(core == NULL)
00177 {
00178
00179 FWARNING(("TransformPushGraphOp::traverseTargetsEnter: "
00180 "Found node without core!\n"));
00181 return Action::Skip;
00182 }
00183
00184 if(isInExcludeList(node) || isInPreserveList(node))
00185 {
00186
00187 _pushPossible = false;
00188
00189 return Action::Quit;
00190 }
00191
00192 if(core->getType().isDerivedFrom(Transform::getClassType()))
00193 {
00194 _pushTargets.push_back(node);
00195
00196 return Action::Skip;
00197 }
00198
00199 if(core->getType().isDerivedFrom(Geometry ::getClassType()))
00200 {
00201 Geometry *geo = dynamic_cast<Geometry *>(core);
00202
00203 if(geo != NULL && validTargetGeo(geo))
00204 {
00205
00206 _pushTargets.push_back(node);
00207
00208 return Action::Skip;
00209 }
00210 else
00211 {
00212
00213 _pushPossible = false;
00214
00215 return Action::Quit;
00216 }
00217 }
00218
00219 if(core->getType().isDerivedFrom(Group::getClassType()))
00220 {
00221
00222 return Action::Continue;
00223 }
00224
00225
00226 _pushPossible = false;
00227
00228 return Action::Quit;
00229 }
00230
00233 bool TransformPushGraphOp::validTargetGeo(const Geometry *geo)
00234 {
00235 bool returnValue = true;
00236
00237 const Geometry::MFPropertiesType *mfProp =
00238 geo->getMFProperties ();
00239 Geometry::MFPropertiesType::const_iterator propIt = mfProp->begin();
00240 Geometry::MFPropertiesType::const_iterator propEnd = mfProp->end ();
00241
00242 for(; propIt != propEnd; ++propIt)
00243 {
00244 if(*propIt != NULL && (*propIt)->getMFParents()->size() > 1)
00245 {
00246 returnValue = false;
00247 break;
00248 }
00249 }
00250
00251 return returnValue;
00252 }
00253
00254 void TransformPushGraphOp::pushTransform(const Transform *srcTrans)
00255 {
00256 PushTargetStore::iterator ptIt = _pushTargets.begin();
00257 PushTargetStore::iterator ptEnd = _pushTargets.end ();
00258
00259 for(; ptIt != ptEnd; ++ptIt)
00260 {
00261 Transform *dstTrans = dynamic_cast<Transform *>((*ptIt)->getCore());
00262 if(dstTrans != NULL)
00263 {
00264 pushToTransform(srcTrans, dstTrans);
00265 continue;
00266 }
00267
00268 Geometry *dstGeo = dynamic_cast<Geometry *>((*ptIt)->getCore());
00269 if(dstGeo != NULL)
00270 {
00271 pushToGeometry(srcTrans, dstGeo);
00272 continue;
00273 }
00274
00275
00276 FWARNING(("TransformPushGraphOp::pushTransform: Unhandled push target"
00277 " type [%s]\n", (*ptIt)->getType().getCName()));
00278 }
00279 }
00280
00283 void TransformPushGraphOp::pushToTransform(
00284 const Transform *srcTrans, Transform *dstTrans)
00285 {
00286 dstTrans->editMatrix().multLeft(srcTrans->getMatrix());
00287 }
00288
00291 void TransformPushGraphOp::pushToGeometry(
00292 const Transform *srcTrans, Geometry *dstGeo)
00293 {
00294 typedef Vec4f VecType;
00295 typedef Pnt3f PntType;
00296
00297 Matrix mat = srcTrans->getMatrix();
00298 Matrix invMat;
00299 invMat.invertFrom(mat);
00300
00301 const Geometry::SFLengthsType *sfLen = dstGeo->getSFLengths ();
00302 Geometry::MFPropertiesType *mfProp = dstGeo->editMFProperties ();
00303 Geometry::MFPropIndicesType *mfInd = dstGeo->editMFPropIndices();
00304
00305 Geometry::MFPropertiesType::const_iterator propIt = mfProp->begin();
00306 Geometry::MFPropertiesType::const_iterator propEnd = mfProp->end ();
00307
00308 Geometry::MFPropIndicesType::const_iterator indIt = mfInd ->begin();
00309 Geometry::MFPropIndicesType::const_iterator indEnd = mfInd ->end ();
00310
00311 UInt32 propUsed = 0;
00312 for(UInt32 i = 0; i < sfLen->getValue()->size(); ++i)
00313 propUsed += sfLen->getValue()->getValue<UInt32>(i);
00314
00315 for(; propIt != propEnd && indIt != indEnd; ++propIt, ++indIt)
00316 {
00317 GeoVectorProperty *prop = *propIt;
00318 const GeoIntegralProperty *ind = *indIt;
00319
00320 if(prop == NULL)
00321 continue;
00322
00323 if(ind == NULL)
00324 {
00325
00326 if((prop->getUsage() & GeoProperty::UsageObjectSpace) != 0x0000)
00327 {
00328
00329 for(UInt32 i = 0; i < propUsed; ++i)
00330 {
00331 PntType pnt = prop->getValue<PntType>(i);
00332 mat.multFull(pnt, pnt);
00333 prop->setValue(pnt, i);
00334 }
00335 }
00336 else if((prop->getUsage() & GeoProperty::UsageTangentSpace) != 0x0000)
00337 {
00338
00339 for(UInt32 i = 0; i < propUsed; ++i)
00340 {
00341 VecType vec = prop->getValue<VecType>(i);
00342 invMat.mult(vec, vec);
00343 prop->setValue(vec, i);
00344 }
00345 }
00346 }
00347 else
00348 {
00349 std::set<UInt32> transInd;
00350
00351 if((prop->getUsage() & GeoProperty::UsageObjectSpace) != 0x0000)
00352 {
00353
00354 for(UInt32 i = 0; i < propUsed; ++i)
00355 {
00356 UInt32 j = ind->getValue(i);
00357
00358 if(transInd.find(j) == transInd.end())
00359 {
00360 PntType pnt = prop->getValue<PntType>(j);
00361 mat.multFull(pnt, pnt);
00362 prop->setValue(pnt, j);
00363
00364 transInd.insert(j);
00365 }
00366 }
00367 }
00368 else if((prop->getUsage() & GeoProperty::UsageTangentSpace) != 0x0000)
00369 {
00370
00371 for(UInt32 i = 0; i < propUsed; ++i)
00372 {
00373 UInt32 j = ind->getValue(i);
00374
00375 if(transInd.find(j) == transInd.end())
00376 {
00377 VecType vec = prop->getValue<VecType>(j);
00378 invMat.mult(vec, vec);
00379 prop->setValue(vec, j);
00380
00381 transInd.insert(j);
00382 }
00383 }
00384 }
00385 }
00386 }
00387 }
00388
00389
00390 OSG_END_NAMESPACE