1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2009 by the OpenSG Forum *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
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. *
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. *
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. *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
37 \*---------------------------------------------------------------------------*/
39 #if __GNUC__ >= 4 || __GNUC_MINOR__ >=3
40 #pragma GCC diagnostic ignored "-Wold-style-cast"
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>
68 // ===========================================================================
70 ColladaInstInfoTransitPtr
71 ColladaNode::ColladaNodeInstInfo::create(
72 ColladaElement
*colInstParent
, ColladaInstanceNode
*colInst
,
75 return ColladaInstInfoTransitPtr(
76 new ColladaNodeInstInfo(colInstParent
, colInst
,parentN
));
80 ColladaNode::ColladaNodeInstInfo::process(void)
82 SFATAL
<< "ColladaNodeInstInfo::process called!" << std::endl
;
85 ColladaNode::ColladaNodeInstInfo::ColladaNodeInstInfo(
86 ColladaElement
*colInstParent
, ColladaInstanceNode
*colInst
,
89 : Inherited (colInstParent
, colInst
)
90 , _colInstTarget(NULL
)
95 ColladaNode::ColladaNodeInstInfo::~ColladaNodeInstInfo(void)
99 // ===========================================================================
101 ColladaNode::NodeLoaderStateTransitPtr
102 ColladaNode::NodeLoaderState::create(void)
104 return NodeLoaderStateTransitPtr(new NodeLoaderState());
108 ColladaNode::NodeLoaderState::pushNodePath(const std::string
&nodeId
)
110 _nodePath
.push_back(nodeId
);
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
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"));
144 ColladaNode::NodeLoaderState::pushMatrix(const Matrix
&matrix
)
146 _matrixStack
.push_back(_worldMatrix
);
147 _worldMatrix
.mult(matrix
);
151 ColladaNode::NodeLoaderState::popMatrix(void)
153 OSG_ASSERT(_matrixStack
.empty() == false);
155 _worldMatrix
= _matrixStack
.back();
156 _matrixStack
.pop_back();
160 ColladaNode::NodeLoaderState::getWorldMatrix(void) const
166 ColladaNode::NodeLoaderState::getSkeleton(void) const
172 ColladaNode::NodeLoaderState::setSkeleton(Skeleton
*skel
)
178 ColladaNode::NodeLoaderState::getJointId(void) const
184 ColladaNode::NodeLoaderState::setJointId(Int16 jointId
)
189 ColladaNode::NodeLoaderState::NodeLoaderState(void)
193 , _jointId (SkeletonJoint::INVALID_JOINT_ID
)
199 ColladaNode::NodeLoaderState::~NodeLoaderState(void)
203 // ===========================================================================
205 ColladaNode::InstData::InstData(void)
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
));
240 ColladaNode::read(ColladaElement
*colElemParent
)
242 domNodeRef node
= getDOMElementAs
<domNode
>();
244 OSG_COLLADA_LOG(("ColladaNode::read id [%s]\n", node
->getId()));
247 const domNode_Array
&nodes
= node
->getNode_array();
248 for(UInt32 i
= 0; i
< nodes
.getCount(); ++i
)
252 const domInstance_node_Array
&instNodes
=
253 node
->getInstance_node_array();
255 for(UInt32 i
= 0; i
< instNodes
.getCount(); ++i
)
256 readInstanceNode(instNodes
[i
]);
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
]);
280 ColladaNode::createInstance(ColladaInstInfo
*colInstInfo
)
283 domNodeRef node
= getDOMElementAs
<domNode
>();
285 #if 0 // old trunk patch
286 if(_topN
->getParent() != NULL
)
288 retVal
= cloneTree(_topN
);
292 if(node
->getType() == NODETYPE_JOINT
)
294 retVal
= createInstanceJoint(colInstInfo
, node
);
298 retVal
= createInstanceNode(colInstInfo
, node
);
305 ColladaNode::isJoint(void) const
307 domNodeRef node
= getDOMElementAs
<domNode
>();
309 return (node
->getType() == NODETYPE_JOINT
);
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."
327 return _instDataStore
[0]._skel
;
331 ColladaNode::getTopNode(UInt32 instIdx
) const
333 OSG_ASSERT(instIdx
< _instDataStore
.size());
335 return _instDataStore
[instIdx
]._topN
;
339 ColladaNode::getBottomNode(UInt32 instIdx
) const
341 OSG_ASSERT(instIdx
< _instDataStore
.size());
343 return _instDataStore
[instIdx
]._bottomN
;
347 ColladaNode::getNodeBySid(UInt32 instIdx
, const std::string
&sid
) const
349 OSG_ASSERT(instIdx
< _instDataStore
.size());
352 const InstData
&instData
= _instDataStore
[instIdx
];
353 SIdNodeMapConstIt sidIt
= instData
._sidMap
.find(sid
);
354 if(sidIt
!= instData
._sidMap
.end())
356 retVal
= sidIt
->second
;
360 SWARNING
<< "ColladaNode::getNodeBySid: Could not find a node "
361 << "for sid [" << sid
<< "]." << std::endl
;
368 ColladaNode::ColladaNode(daeElement
*elem
, ColladaGlobal
*global
)
369 : Inherited (elem
, global
)
374 ColladaNode::~ColladaNode(void)
379 ColladaNode::createInstanceNode(ColladaInstInfo
*colInstInfo
, domNode
*node
)
381 OSG_COLLADA_LOG(("ColladaNode::createInstanceNode id [%s]\n",
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
;
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
;
486 state
->popNodePath();
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
;
506 NodeLoaderState
*state
=
507 getGlobal()->getLoaderStateAs
<NodeLoaderState
>(_loaderStateName
);
508 OSG_ASSERT(state
!= NULL
);
510 state
->pushNodePath(node
->getId() != NULL
? node
->getId() : "");
511 state
->dumpNodePath();
514 instData
._nodePath
= state
->getNodePath();
515 instData
._skel
= state
->getSkeleton();
517 if(instData
._skel
== NULL
)
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()));
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
);
649 state
->popNodePath();
655 ColladaNode::handleLookAt(domLookat
*lookat
, InstData
&instData
)
660 SWARNING
<< "ColladaNode::handleLookAt: NIY" << std::endl
;
664 ColladaNode::handleMatrix(domMatrix
*matrix
, InstData
&instData
)
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
);
695 ColladaNode::handleRotate(domRotate
*rotate
, InstData
&instData
)
702 q
.setValueAsAxisDeg(rotate
->getValue()[0],
703 rotate
->getValue()[1],
704 rotate
->getValue()[2],
705 rotate
->getValue()[3] );
709 std::string xformSID
;
711 if(rotate
->getSid() != NULL
)
712 xformSID
.assign(rotate
->getSid());
714 appendXForm(m
, xformSID
, instData
);
718 ColladaNode::handleScale(domScale
*scale
, InstData
&instData
)
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
);
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.)
750 // SWARNING << "ColladaNode::handleSkew: NIY" << std::endl;
751 Real32 angle
,an1
,an2
,rx
,ry
,alpha
;
755 domFloat7 elems
= skew
->getValue();
757 Vec3f
a(elems
[1],elems
[2],elems
[3]), b(elems
[4],elems
[5],elems
[6]);
766 angle
= osgDegree2Rad(angle
);
767 rx
= an1
*osgCos(angle
) - an2
*osgSin(angle
);
768 ry
= an1
*osgSin(angle
) + an2
*osgCos(angle
);
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
;
777 // are A and B parallel?
778 if(OSG::osgAbs(an1
) < 0.000001)
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
);
804 ColladaNode::handleTranslate(domTranslate
*translate
, InstData
&instData
)
806 if(translate
== NULL
)
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
);
826 ColladaNode::appendXForm(const Matrix
&m
,
827 const std::string
&xformSID
,
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
);
845 joint
->setJointId(state
->getJointId());
849 TransformUnrecPtr xform
= Transform::create();
850 instData
._bottomN
= makeNodeFor(xform
);
855 instData
._localMatrix
= m
;
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
);
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
);
896 TransformUnrecPtr xform
= Transform::create();
897 NodeUnrecPtr xformN
= makeNodeFor(xform
);
899 if(instData
._bottomN
!= NULL
)
900 instData
._bottomN
->addChild(xformN
);
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
);
930 ColladaNode::appendChild(domNode
*child
,
934 domNodeRef node
= getDOMElementAs
<domNode
>();
936 // only add the child if it is not the first joint
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
);
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);
964 ColladaNode::handleNode(domNode
*child
,
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
);
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);
992 ColladaNode::handleInstanceNode(domInstance_node
*instNode
,
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
);
1006 ColladaNode::readInstanceLight(domInstance_light
*instLight
)
1008 if(getGlobal()->getOptions()->getLoadLights() == false)
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);
1024 ColladaNode::handleInstanceLight(domInstance_light
*instLight
,
1025 InstData
&instData
)
1027 if(getGlobal()->getOptions()->getLoadLights() == false)
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
);
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);
1056 ColladaNode::handleInstanceGeometry(domInstance_geometry
*instGeo
,
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
);
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);
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
);
1101 #endif // OSG_WITH_COLLADA