fixed: auto_ptr -> unique_ptr
[opensg.git] / Source / System / FileIO / Collada / OSGColladaNode.cpp
blob70bd80f1e419eb043c2fb171481558cd6535c29e
1 /*---------------------------------------------------------------------------*\
2 * OpenSG *
3 * *
4 * *
5 * Copyright (C) 2009 by the OpenSG Forum *
6 * *
7 * www.opensg.org *
8 * *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
10 * *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
13 * License *
14 * *
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
18 * *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
23 * *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
27 * *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
30 * Changes *
31 * *
32 * *
33 * *
34 * *
35 * *
36 * *
37 \*---------------------------------------------------------------------------*/
39 #if __GNUC__ >= 4 || __GNUC_MINOR__ >=3
40 #pragma GCC diagnostic ignored "-Wold-style-cast"
41 #endif
43 #include "OSGColladaNode.h"
45 #if defined(OSG_WITH_COLLADA) || defined(OSG_DO_DOC)
47 #include "OSGColladaLog.h"
48 #include "OSGColladaGlobal.h"
49 #include "OSGColladaInstanceNode.h"
50 #include "OSGColladaInstanceLight.h"
51 #include "OSGColladaInstanceGeometry.h"
52 #include "OSGColladaInstanceController.h"
53 #include "OSGTransform.h"
54 #include "OSGSkeletonJoint.h"
55 #include "OSGNameAttachment.h"
57 #include <dom/domLookat.h>
58 #include <dom/domMatrix.h>
59 #include <dom/domRotate.h>
60 #include <dom/domScale.h>
61 #include <dom/domSkew.h>
62 #include <dom/domTranslate.h>
63 #include <dom/domInstance_node.h>
64 #include <dom/domNode.h>
66 OSG_BEGIN_NAMESPACE
68 // ===========================================================================
70 ColladaInstInfoTransitPtr
71 ColladaNode::ColladaNodeInstInfo::create(
72 ColladaElement *colInstParent, ColladaInstanceNode *colInst,
73 Node *parentN )
75 return ColladaInstInfoTransitPtr(
76 new ColladaNodeInstInfo(colInstParent, colInst,parentN));
79 void
80 ColladaNode::ColladaNodeInstInfo::process(void)
82 SFATAL << "ColladaNodeInstInfo::process called!" << std::endl;
85 ColladaNode::ColladaNodeInstInfo::ColladaNodeInstInfo(
86 ColladaElement *colInstParent, ColladaInstanceNode *colInst,
87 Node *parentN )
89 : Inherited (colInstParent, colInst)
90 , _colInstTarget(NULL )
91 , _parentN (parentN )
95 ColladaNode::ColladaNodeInstInfo::~ColladaNodeInstInfo(void)
99 // ===========================================================================
101 ColladaNode::NodeLoaderStateTransitPtr
102 ColladaNode::NodeLoaderState::create(void)
104 return NodeLoaderStateTransitPtr(new NodeLoaderState());
107 void
108 ColladaNode::NodeLoaderState::pushNodePath(const std::string &nodeId)
110 _nodePath.push_back(nodeId);
113 void
114 ColladaNode::NodeLoaderState::popNodePath(void)
116 OSG_ASSERT(_nodePath.empty() == false);
118 _nodePath.pop_back();
121 const ColladaNode::NodePath &
122 ColladaNode::NodeLoaderState::getNodePath(void) const
124 return _nodePath;
127 void
128 ColladaNode::NodeLoaderState::dumpNodePath(void) const
130 NodePathConstIt npIt = _nodePath.begin();
131 NodePathConstIt npEnd = _nodePath.end ();
133 OSG_COLLADA_LOG(("node path ["));
135 for(; npIt != npEnd; ++npIt)
137 OSG_COLLADA_PLOG((" '%s'", npIt->c_str()));
140 OSG_COLLADA_PLOG((" ]\n"));
143 void
144 ColladaNode::NodeLoaderState::pushMatrix(const Matrix &matrix)
146 _matrixStack.push_back(_worldMatrix);
147 _worldMatrix.mult(matrix);
150 void
151 ColladaNode::NodeLoaderState::popMatrix(void)
153 OSG_ASSERT(_matrixStack.empty() == false);
155 _worldMatrix = _matrixStack.back();
156 _matrixStack.pop_back();
159 const Matrix &
160 ColladaNode::NodeLoaderState::getWorldMatrix(void) const
162 return _worldMatrix;
165 Skeleton *
166 ColladaNode::NodeLoaderState::getSkeleton(void) const
168 return _skel;
171 void
172 ColladaNode::NodeLoaderState::setSkeleton(Skeleton *skel)
174 _skel = skel;
177 Int16
178 ColladaNode::NodeLoaderState::getJointId(void) const
180 return _jointId;
183 void
184 ColladaNode::NodeLoaderState::setJointId(Int16 jointId)
186 _jointId = jointId;
189 ColladaNode::NodeLoaderState::NodeLoaderState(void)
190 : Inherited ()
191 , _nodePath ()
192 , _skel ()
193 , _jointId (SkeletonJoint::INVALID_JOINT_ID)
194 , _worldMatrix()
195 , _matrixStack()
199 ColladaNode::NodeLoaderState::~NodeLoaderState(void)
203 // ===========================================================================
205 ColladaNode::InstData::InstData(void)
206 : _nodePath ()
207 , _localMatrix()
208 , _skel (NULL)
209 , _topN (NULL)
210 , _bottomN (NULL)
211 , _sidMap ()
215 ColladaNode::InstData::~InstData(void)
219 // ===========================================================================
221 ColladaElementRegistrationHelper ColladaNode::_regHelper(
222 &ColladaNode::create, "node");
224 const std::string ColladaNode::_loaderStateName("ColladaNode");
226 ColladaElementTransitPtr
227 ColladaNode::create(daeElement *elem, ColladaGlobal *global)
229 if(global->getLoaderState(_loaderStateName) == NULL)
231 NodeLoaderStateRefPtr state = NodeLoaderState::create();
233 global->addLoaderState(_loaderStateName, state);
236 return ColladaElementTransitPtr(new ColladaNode(elem, global));
239 void
240 ColladaNode::read(ColladaElement *colElemParent)
242 domNodeRef node = getDOMElementAs<domNode>();
244 OSG_COLLADA_LOG(("ColladaNode::read id [%s]\n", node->getId()));
246 // <node>
247 const domNode_Array &nodes = node->getNode_array();
248 for(UInt32 i = 0; i < nodes.getCount(); ++i)
249 readNode(nodes[i]);
251 // <instance_node>
252 const domInstance_node_Array &instNodes =
253 node->getInstance_node_array();
255 for(UInt32 i = 0; i < instNodes.getCount(); ++i)
256 readInstanceNode(instNodes[i]);
258 // <instance_light>
259 const domInstance_light_Array &instLights =
260 node->getInstance_light_array();
262 for(UInt32 i = 0; i < instLights.getCount(); ++i)
263 readInstanceLight(instLights[i]);
264 // <instance_geometry>
265 const domInstance_geometry_Array &instGeos =
266 node->getInstance_geometry_array();
268 for(UInt32 i = 0; i < instGeos.getCount(); ++i)
269 readInstanceGeometry(instGeos[i]);
271 // <instance_controller>
272 const domInstance_controller_Array &instControllers =
273 node->getInstance_controller_array();
275 for(UInt32 i = 0; i < instControllers.getCount(); ++i)
276 readInstanceController(instControllers[i]);
279 Node *
280 ColladaNode::createInstance(ColladaInstInfo *colInstInfo)
282 Node *retVal = NULL;
283 domNodeRef node = getDOMElementAs<domNode>();
285 #if 0 // old trunk patch
286 if(_topN->getParent() != NULL)
288 retVal = cloneTree(_topN);
290 #endif
292 if(node->getType() == NODETYPE_JOINT)
294 retVal = createInstanceJoint(colInstInfo, node);
296 else
298 retVal = createInstanceNode(colInstInfo, node);
301 return retVal;
304 bool
305 ColladaNode::isJoint(void) const
307 domNodeRef node = getDOMElementAs<domNode>();
309 return (node->getType() == NODETYPE_JOINT);
312 Skeleton *
313 ColladaNode::getSkeleton(void) const
315 OSG_ASSERT(_instDataStore.empty() == false);
317 if(_instDataStore.size() > 1)
319 domNodeRef node = getDOMElementAs<domNode>();
321 SWARNING << "ColladaNode::getSkeleton: id ["
322 << (node->getId() != NULL ? node->getId() : "")
323 << "] has multiple instances, skeleton is ambiguous."
324 << std::endl;
327 return _instDataStore[0]._skel;
330 Node *
331 ColladaNode::getTopNode(UInt32 instIdx) const
333 OSG_ASSERT(instIdx < _instDataStore.size());
335 return _instDataStore[instIdx]._topN;
338 Node *
339 ColladaNode::getBottomNode(UInt32 instIdx) const
341 OSG_ASSERT(instIdx < _instDataStore.size());
343 return _instDataStore[instIdx]._bottomN;
346 Node *
347 ColladaNode::getNodeBySid(UInt32 instIdx, const std::string &sid) const
349 OSG_ASSERT(instIdx < _instDataStore.size());
351 Node *retVal = NULL;
352 const InstData &instData = _instDataStore[instIdx];
353 SIdNodeMapConstIt sidIt = instData._sidMap.find(sid);
354 if(sidIt != instData._sidMap.end())
356 retVal = sidIt->second;
358 else
360 SWARNING << "ColladaNode::getNodeBySid: Could not find a node "
361 << "for sid [" << sid << "]." << std::endl;
364 return retVal;
368 ColladaNode::ColladaNode(daeElement *elem, ColladaGlobal *global)
369 : Inherited (elem, global)
370 , _instDataStore( )
374 ColladaNode::~ColladaNode(void)
378 Node *
379 ColladaNode::createInstanceNode(ColladaInstInfo *colInstInfo, domNode *node)
381 OSG_COLLADA_LOG(("ColladaNode::createInstanceNode id [%s]\n",
382 node->getId()));
384 NodeLoaderState *state =
385 getGlobal()->getLoaderStateAs<NodeLoaderState>(_loaderStateName);
386 OSG_ASSERT(state != NULL);
388 state->pushNodePath(node->getId() != NULL ? node->getId() : "");
389 state->dumpNodePath();
391 NodeUnrecPtr retVal = NULL;
392 InstData instData;
394 instData._nodePath = state->getNodePath();
395 const daeElementRefArray &contents = node->getContents();
397 // read "transform" child elements in the order
398 // they occur in the document
399 for(UInt32 i = 0; i < contents.getCount(); ++i)
401 if(contents[i]->typeID() == domLookat::ID())
403 handleLookAt(daeSafeCast<domLookat>(contents[i]), instData);
405 else if(contents[i]->typeID() == domMatrix::ID())
407 handleMatrix(daeSafeCast<domMatrix>(contents[i]), instData);
409 else if(contents[i]->typeID() == domRotate::ID())
411 handleRotate(daeSafeCast<domRotate>(contents[i]), instData);
413 else if(contents[i]->typeID() == domScale::ID())
415 handleScale(daeSafeCast<domScale>(contents[i]), instData);
417 else if(contents[i]->typeID() == domSkew::ID())
419 handleSkew(daeSafeCast<domSkew>(contents[i]), instData);
421 else if(contents[i]->typeID() == domTranslate::ID())
423 handleTranslate(daeSafeCast<domTranslate>(contents[i]), instData);
427 // assert top and bottom are both set or both unset
428 OSG_ASSERT((instData._topN != NULL && instData._bottomN != NULL) ||
429 (instData._topN == NULL && instData._bottomN == NULL) );
431 // if no xforms were created make a group for this <node>
432 if(instData._topN == NULL && instData._bottomN == NULL)
434 instData._topN = makeCoredNode<Group>();
435 instData._bottomN = instData._topN;
437 if(getGlobal()->getOptions()->getCreateNameAttachments() == true &&
438 node->getName() != NULL )
440 setName(instData._topN, node->getName());
444 // update world matrix before we instantiate child nodes, etc.
445 state->pushMatrix(instData._localMatrix);
447 // add <node> child elements
448 const domNode_Array &nodes = node->getNode_array();
450 for(UInt32 i = 0; i < nodes.getCount(); ++i)
451 handleNode(nodes[i], instData);
453 // add <instance_node> child elements
454 const domInstance_node_Array &instNodes =
455 node->getInstance_node_array();
457 for(UInt32 i = 0; i < instNodes.getCount(); ++i)
458 handleInstanceNode(instNodes[i], instData);
460 // add <instance_light> child elements
461 const domInstance_light_Array &instLights =
462 node->getInstance_light_array();
464 for(UInt32 i = 0; i < instLights.getCount(); ++i)
465 handleInstanceLight(instLights[i], instData);
467 // add <instance_geometry> child elements
468 const domInstance_geometry_Array &instGeos =
469 node->getInstance_geometry_array();
471 for(UInt32 i = 0; i < instGeos.getCount(); ++i)
472 handleInstanceGeometry(instGeos[i], instData);
474 // add <instance_controller> child elemnts
475 const domInstance_controller_Array &instControllers =
476 node->getInstance_controller_array();
478 for(UInt32 i = 0; i < instControllers.getCount(); ++i)
479 handleInstanceController(instControllers[i], instData);
481 editInstStore().push_back(instData._topN);
482 _instDataStore .push_back(instData );
483 retVal = instData._topN;
485 state->popMatrix ();
486 state->popNodePath();
488 return retVal;
491 Node *
492 ColladaNode::createInstanceJoint(ColladaInstInfo *colInstInfo, domNode *node)
494 NodeUnrecPtr retVal = NULL;
495 bool startSkel = false;
497 // if there is a ColladaInstanceElement someone tried to use <instance_node>
498 // with this joint as target - this is currently not supported
499 if(colInstInfo->getColInst() != NULL)
501 SWARNING << "ColladaNode::createInstanceJoint: <instance_node> with "
502 << "target <node> of type JOINT not supported." << std::endl;
503 return retVal;
506 NodeLoaderState *state =
507 getGlobal()->getLoaderStateAs<NodeLoaderState>(_loaderStateName);
508 OSG_ASSERT(state != NULL);
510 state->pushNodePath(node->getId() != NULL ? node->getId() : "");
511 state->dumpNodePath();
513 InstData instData;
514 instData._nodePath = state->getNodePath();
515 instData._skel = state->getSkeleton();
517 if(instData._skel == NULL)
519 startSkel = true;
520 instData._skel = Skeleton::create();
522 state->setSkeleton(instData._skel);
523 state->setJointId (0 );
525 OSG_COLLADA_LOG(("ColladaNode::createInstanceJoint: id [%s] "
526 "root joint\n", node->getId()));
528 else
530 state->setJointId(state->getJointId() + 1);
532 OSG_COLLADA_LOG(("ColladaNode::createInstanceJoint: id [%s] "
533 "joint [%d]\n", node->getId(), state->getJointId()));
536 const daeElementRefArray &contents = node->getContents();
538 for(UInt32 i = 0; i < contents.getCount(); ++i)
540 if(contents[i]->typeID() == domLookat::ID())
542 handleLookAt(daeSafeCast<domLookat>(contents[i]), instData);
544 else if(contents[i]->typeID() == domMatrix::ID())
546 handleMatrix(daeSafeCast<domMatrix>(contents[i]), instData);
548 else if(contents[i]->typeID() == domRotate::ID())
550 handleRotate(daeSafeCast<domRotate>(contents[i]), instData);
552 else if(contents[i]->typeID() == domScale::ID())
554 handleScale(daeSafeCast<domScale>(contents[i]), instData);
556 else if(contents[i]->typeID() == domSkew::ID())
558 handleSkew(daeSafeCast<domSkew>(contents[i]), instData);
560 else if(contents[i]->typeID() == domTranslate::ID())
562 handleTranslate(daeSafeCast<domTranslate>(contents[i]), instData);
566 // assert top and bottom are both set or both unset
567 OSG_ASSERT((instData._topN != NULL && instData._bottomN != NULL) ||
568 (instData._topN == NULL && instData._bottomN == NULL) );
570 if(instData._topN == NULL && instData._bottomN == NULL)
572 // no xforms were created, make a SkeletonJoint for this <node>
574 SkeletonJointUnrecPtr joint = SkeletonJoint::create();
576 joint->setJointId(state->getJointId());
578 instData._topN = makeNodeFor(joint);
579 instData._bottomN = instData._topN;
581 if(getGlobal()->getOptions()->getCreateNameAttachments() == true &&
582 node->getName() != NULL )
584 setName(instData._topN, node->getName());
587 else if(getGlobal()->getOptions()->getMergeTransforms() == false)
589 // when not merging transforms add SkeletonJoint core now
591 SkeletonJointUnrecPtr joint = SkeletonJoint::create();
592 NodeUnrecPtr jointN = makeNodeFor(joint);
594 joint->setJointId(state->getJointId());
596 instData._bottomN->addChild(jointN);
597 instData._bottomN = jointN;
600 if(startSkel == true)
602 // add a transform for the world matrix up to this node to put
603 // the Skeleton in the correct coordinate system
605 TransformUnrecPtr xform = Transform::create();
606 NodeUnrecPtr xformN = makeNodeFor(xform);
608 xform->setMatrix(state->getWorldMatrix());
610 xformN->addChild(instData._topN);
611 instData._topN = xformN;
613 if(getGlobal()->getOptions()->getCreateNameAttachments() == true)
614 setName(xformN, "SkeletonWorldMatrix");
617 // update world matrix before we instantiate child nodes, etc.
618 state->pushMatrix(instData._localMatrix);
620 // add <node> child elements
621 const domNode_Array &nodes = node->getNode_array();
623 for(UInt32 i = 0; i < nodes.getCount(); ++i)
624 handleNode(nodes[i], instData);
626 // add <instance_node> child elements
627 const domInstance_node_Array &instNodes =
628 node->getInstance_node_array();
630 for(UInt32 i = 0; i < instNodes.getCount(); ++i)
631 handleInstanceNode(instNodes[i], instData);
633 // we don't handle other <instance_*> tags here, it does not
634 // make sense to have them inside a skeleton
636 editInstStore().push_back(instData._topN);
637 _instDataStore .push_back(instData );
638 retVal = instData._topN;
640 if(startSkel == true)
642 instData._skel->pushToRoots(instData._topN);
644 state->setSkeleton(NULL);
645 state->setJointId (SkeletonJoint::INVALID_JOINT_ID);
648 state->popMatrix ();
649 state->popNodePath();
651 return retVal;
654 void
655 ColladaNode::handleLookAt(domLookat *lookat, InstData &instData)
657 if(lookat == NULL)
658 return;
660 SWARNING << "ColladaNode::handleLookAt: NIY" << std::endl;
663 void
664 ColladaNode::handleMatrix(domMatrix *matrix, InstData &instData)
666 if(matrix == NULL)
667 return;
669 Matrix m(matrix->getValue()[0], // rVal00
670 matrix->getValue()[1], // rVal10
671 matrix->getValue()[2], // rVal20
672 matrix->getValue()[3], // rVal30
673 matrix->getValue()[4], // rVal01
674 matrix->getValue()[5], // rVal11
675 matrix->getValue()[6], // rVal21
676 matrix->getValue()[7], // rVal31
677 matrix->getValue()[8], // rVal02
678 matrix->getValue()[9], // rVal12
679 matrix->getValue()[10], // rVal22
680 matrix->getValue()[11], // rVal32
681 matrix->getValue()[12], // rVal03
682 matrix->getValue()[13], // rVal13
683 matrix->getValue()[14], // rVal23
684 matrix->getValue()[15] ); // rVal33
686 std::string xformSID;
688 if(matrix->getSid() != NULL)
689 xformSID.assign(matrix->getSid());
691 appendXForm(m, xformSID, instData);
694 void
695 ColladaNode::handleRotate(domRotate *rotate, InstData &instData)
697 if(rotate == NULL)
698 return;
700 Matrix m;
701 Quaternion q;
702 q.setValueAsAxisDeg(rotate->getValue()[0],
703 rotate->getValue()[1],
704 rotate->getValue()[2],
705 rotate->getValue()[3] );
707 m.setRotate(q);
709 std::string xformSID;
711 if(rotate->getSid() != NULL)
712 xformSID.assign(rotate->getSid());
714 appendXForm(m, xformSID, instData);
717 void
718 ColladaNode::handleScale(domScale *scale, InstData &instData)
720 if(scale == NULL)
721 return;
723 Matrix m;
724 m.setScale(scale->getValue()[0],
725 scale->getValue()[1],
726 scale->getValue()[2] );
728 std::string xformSID;
730 if(scale->getSid() != NULL)
731 xformSID.assign(scale->getSid());
733 appendXForm(m, xformSID, instData);
736 void
737 ColladaNode::handleSkew(domSkew *skew, InstData &instData)
740 * Implemented in accordance with the RenderMan specification.
741 * See http://www.koders.com/cpp/fidA08C276050F880D11C2E49280DD9997478DC5BA1.aspx for
742 * the implementation that this was copied from.
743 * (If the url is invalid, this implementation was copied from the GNU GMAN project,
744 * in the gmanmatrix4.cpp file.)
747 if(skew == NULL)
748 return;
750 // SWARNING << "ColladaNode::handleSkew: NIY" << std::endl;
751 Real32 angle,an1,an2,rx,ry,alpha;
752 Matrix m;
753 Vec3f a1,a2,n1,n2;
755 domFloat7 elems = skew->getValue();
756 angle = elems[0];
757 Vec3f a(elems[1],elems[2],elems[3]), b(elems[4],elems[5],elems[6]);
758 b.normalize();
759 a1 = b * a.dot(b);
760 a2 = a - a1;
761 a2.normalize();
763 an1 = a.dot(a2);
764 an2 = a.dot(b);
766 angle = osgDegree2Rad(angle);
767 rx = an1*osgCos(angle) - an2*osgSin(angle);
768 ry = an1*osgSin(angle) + an2*osgCos(angle);
770 if(rx <= 0.0f)
771 { // skew angle too large, and we can't calculate the skew matrix
772 SWARNING << "ColladaNode::handleSkew: Skew Angle too large! ( rx = "
773 << rx << " )" << std::endl;
774 return;
777 // are A and B parallel?
778 if(OSG::osgAbs(an1) < 0.000001)
779 alpha = 0.0f;
780 else
781 alpha = ry/rx - an2/an1;
783 m[0][0] = a2.x() * b.x() * alpha + 1.0f;
784 m[1][0] = a2.y() * b.x() * alpha;
785 m[2][0] = a2.z() * b.x() * alpha;
787 m[0][1] = a2.x() * b.y() * alpha;
788 m[1][1] = a2.y() * b.y() * alpha + 1.0f;
789 m[2][1] = a2.z() * b.y() * alpha;
791 m[0][2] = a2.x() * b.z() * alpha;
792 m[1][2] = a2.y() * b.z() * alpha;
793 m[2][2] = a2.z() * b.z() * alpha + 1.0f;
795 std::string xformSID;
797 if(skew->getSid() != NULL)
798 xformSID.assign(skew->getSid());
800 appendXForm(m, xformSID, instData);
803 void
804 ColladaNode::handleTranslate(domTranslate *translate, InstData &instData)
806 if(translate == NULL)
807 return;
809 Matrix m;
810 m.setTranslate(translate->getValue()[0],
811 translate->getValue()[1],
812 translate->getValue()[2] );
814 std::string nameSuffix;
816 if(translate->getSid() != NULL)
818 nameSuffix.append("." );
819 nameSuffix.append(translate->getSid());
822 appendXForm(m, nameSuffix, instData);
825 void
826 ColladaNode::appendXForm(const Matrix &m,
827 const std::string &xformSID,
828 InstData &instData )
830 domNodeRef node = getDOMElementAs<domNode>();
831 NodeLoaderState *state =
832 getGlobal()->getLoaderStateAs<NodeLoaderState>(_loaderStateName);
833 OSG_ASSERT(state != NULL);
835 if(getGlobal()->getOptions()->getMergeTransforms() == true)
837 if(instData._bottomN == NULL)
839 if(node->getType() == NODETYPE_JOINT)
841 SkeletonJointUnrecPtr joint = SkeletonJoint::create();
842 instData._bottomN = makeNodeFor(joint);
844 joint->setMatrix(m);
845 joint->setJointId(state->getJointId());
847 else
849 TransformUnrecPtr xform = Transform::create();
850 instData._bottomN = makeNodeFor(xform);
852 xform->setMatrix(m);
855 instData._localMatrix = m;
857 else
859 if(node->getType() == NODETYPE_JOINT)
861 SkeletonJoint *joint =
862 dynamic_cast<SkeletonJoint *>(instData._bottomN->getCore());
863 OSG_ASSERT(joint != NULL);
865 joint->editMatrix().mult(m);
867 else
869 Transform *xform =
870 dynamic_cast<Transform *>(instData._bottomN->getCore());
871 OSG_ASSERT(xform != NULL);
873 xform->editMatrix().mult(m);
876 instData._localMatrix.mult(m);
879 if(instData._topN == NULL)
880 instData._topN = instData._bottomN;
882 if(xformSID.empty() == false)
883 instData._sidMap[xformSID] = instData._bottomN;
885 if(getGlobal()->getOptions()->getCreateNameAttachments() == true &&
886 node->getName() != NULL &&
887 getName(instData._bottomN) == NULL )
889 std::string nodeName = node->getName();
891 setName(instData._bottomN, nodeName);
894 else
896 TransformUnrecPtr xform = Transform::create();
897 NodeUnrecPtr xformN = makeNodeFor(xform);
899 if(instData._bottomN != NULL)
900 instData._bottomN->addChild(xformN);
902 xform->setMatrix(m);
903 instData._localMatrix.mult(m);
905 instData._bottomN = xformN;
907 if(instData._topN == NULL)
908 instData._topN = instData._bottomN;
910 if(xformSID.empty() == false)
911 instData._sidMap[xformSID] = xformN;
913 if(getGlobal()->getOptions()->getCreateNameAttachments() == true &&
914 node->getName() != NULL )
916 std::string nodeName = node->getName();
918 if(xformSID.empty() == false)
920 nodeName.append("." );
921 nodeName.append(xformSID);
924 setName(instData._bottomN, nodeName);
929 void
930 ColladaNode::appendChild(domNode *child,
931 Node *childN,
932 InstData &instData)
934 domNodeRef node = getDOMElementAs<domNode>();
936 // only add the child if it is not the first joint
937 // in a hierarchy
939 if(child->getType() != NODETYPE_JOINT ||
940 node ->getType() != NODETYPE_NODE )
942 OSG_ASSERT(instData._topN != NULL);
943 OSG_ASSERT(instData._bottomN != NULL);
945 instData._bottomN->addChild(childN);
949 void
950 ColladaNode::readNode(domNode *child)
952 ColladaNodeRefPtr colNodeChild = getUserDataAs<ColladaNode>(child);
954 if(colNodeChild == NULL)
956 colNodeChild = dynamic_pointer_cast<ColladaNode>(
957 ColladaElementFactory::the()->create(child, getGlobal()));
959 colNodeChild->read(this);
963 void
964 ColladaNode::handleNode(domNode *child,
965 InstData &instData)
967 ColladaNodeRefPtr colNodeChild = getUserDataAs<ColladaNode>(child);
968 ColladaInstInfoRefPtr colInstInfo =
969 ColladaNodeInstInfo::create(this, NULL, instData._bottomN);
971 Node *childN = colNodeChild->createInstance(colInstInfo);
973 appendChild(child, childN, instData);
976 void
977 ColladaNode::readInstanceNode(domInstance_node *instNode)
979 ColladaInstanceNodeRefPtr colInstNode =
980 getUserDataAs<ColladaInstanceNode>(instNode);
982 if(colInstNode == NULL)
984 colInstNode = dynamic_pointer_cast<ColladaInstanceNode>(
985 ColladaElementFactory::the()->create(instNode, getGlobal()));
987 colInstNode->read(this);
991 void
992 ColladaNode::handleInstanceNode(domInstance_node *instNode,
993 InstData &instData)
995 ColladaInstanceNodeRefPtr colInstNode =
996 getUserDataAs<ColladaInstanceNode>(instNode);
997 ColladaInstInfoRefPtr colInstInfo =
998 ColladaNodeInstInfo::create(this, colInstNode, instData._bottomN);
1000 Node *childN = colInstNode->getTargetElem()->createInstance(colInstInfo);
1002 appendChild(colInstNode->getTargetDOMElem(), childN, instData);
1005 void
1006 ColladaNode::readInstanceLight(domInstance_light *instLight)
1008 if(getGlobal()->getOptions()->getLoadLights() == false)
1009 return;
1011 ColladaInstanceLightRefPtr colInstLight =
1012 getUserDataAs<ColladaInstanceLight>(instLight);
1014 if(colInstLight == NULL)
1016 colInstLight = dynamic_pointer_cast<ColladaInstanceLight>(
1017 ColladaElementFactory::the()->create(instLight, getGlobal()));
1019 colInstLight->read(this);
1023 void
1024 ColladaNode::handleInstanceLight(domInstance_light *instLight,
1025 InstData &instData )
1027 if(getGlobal()->getOptions()->getLoadLights() == false)
1028 return;
1030 ColladaInstanceLightRefPtr colInstLight =
1031 getUserDataAs<ColladaInstanceLight>(instLight);
1033 ColladaInstInfoRefPtr lightInstInfo =
1034 ColladaLight::ColladaLightInstInfo::create(
1035 this, colInstLight, instData._bottomN);
1037 getGlobal()->editInstQueue().push_back(lightInstInfo);
1040 void
1041 ColladaNode::readInstanceGeometry(domInstance_geometry *instGeo)
1043 ColladaInstanceGeometryRefPtr colInstGeo =
1044 getUserDataAs<ColladaInstanceGeometry>(instGeo);
1046 if(colInstGeo == NULL)
1048 colInstGeo = dynamic_pointer_cast<ColladaInstanceGeometry>(
1049 ColladaElementFactory::the()->create(instGeo, getGlobal()));
1051 colInstGeo->read(this);
1055 void
1056 ColladaNode::handleInstanceGeometry(domInstance_geometry *instGeo,
1057 InstData &instData)
1059 ColladaInstanceGeometryRefPtr colInstGeo =
1060 getUserDataAs<ColladaInstanceGeometry>(instGeo);
1062 ColladaInstInfoRefPtr geoInstInfo =
1063 ColladaGeometry::ColladaGeometryInstInfo::create(
1064 this, colInstGeo, instData._bottomN);
1066 getGlobal()->editInstQueue().push_back(geoInstInfo);
1069 void
1070 ColladaNode::readInstanceController(domInstance_controller *instCtrl)
1072 ColladaInstanceControllerRefPtr colInstCtrl =
1073 getUserDataAs<ColladaInstanceController>(instCtrl);
1075 if(colInstCtrl == NULL)
1077 colInstCtrl = dynamic_pointer_cast<ColladaInstanceController>(
1078 ColladaElementFactory::the()->create(instCtrl, getGlobal()));
1080 colInstCtrl->read(this);
1084 void
1085 ColladaNode::handleInstanceController(
1086 domInstance_controller *instCtrl,
1087 InstData &instData )
1089 ColladaInstanceControllerRefPtr colInstCtrl =
1090 getUserDataAs<ColladaInstanceController>(instCtrl);
1092 ColladaInstInfoRefPtr ctrlInstInfo =
1093 ColladaController::ColladaControllerInstInfo::create(
1094 this, colInstCtrl, instData._bottomN);
1096 getGlobal()->editInstQueue().push_back(ctrlInstInfo);
1099 OSG_END_NAMESPACE
1101 #endif // OSG_WITH_COLLADA