/src/ogre/OgreMain/src/OgreSkeletonInstance.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | ----------------------------------------------------------------------------- |
3 | | This source file is part of OGRE |
4 | | (Object-oriented Graphics Rendering Engine) |
5 | | For the latest info, see http://www.ogre3d.org/ |
6 | | |
7 | | Copyright (c) 2000-2014 Torus Knot Software Ltd |
8 | | |
9 | | Permission is hereby granted, free of charge, to any person obtaining a copy |
10 | | of this software and associated documentation files (the "Software"), to deal |
11 | | in the Software without restriction, including without limitation the rights |
12 | | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
13 | | copies of the Software, and to permit persons to whom the Software is |
14 | | furnished to do so, subject to the following conditions: |
15 | | |
16 | | The above copyright notice and this permission notice shall be included in |
17 | | all copies or substantial portions of the Software. |
18 | | |
19 | | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
20 | | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
21 | | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
22 | | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
23 | | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
24 | | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
25 | | THE SOFTWARE. |
26 | | ----------------------------------------------------------------------------- |
27 | | */ |
28 | | #include "OgreStableHeaders.h" |
29 | | #include "OgreSkeletonInstance.h" |
30 | | #include "OgreTagPoint.h" |
31 | | |
32 | | |
33 | | namespace Ogre { |
34 | | //------------------------------------------------------------------------- |
35 | | SkeletonInstance::SkeletonInstance(const SkeletonPtr& masterCopy) |
36 | 0 | : Skeleton() |
37 | 0 | , mSkeleton(masterCopy) |
38 | 0 | { |
39 | 0 | } |
40 | | //------------------------------------------------------------------------- |
41 | | SkeletonInstance::~SkeletonInstance() |
42 | 0 | { |
43 | | // have to call this here rather than in Resource destructor |
44 | | // since calling virtual methods in base destructors causes crash |
45 | | // ...and calling it in Skeleton destructor does not unload |
46 | | // SkeletonInstance since it has seized to be by then. |
47 | 0 | unload(); |
48 | 0 | } |
49 | | //------------------------------------------------------------------------- |
50 | | unsigned short SkeletonInstance::getNumAnimations(void) const |
51 | 0 | { |
52 | 0 | return mSkeleton->getNumAnimations(); |
53 | 0 | } |
54 | | //------------------------------------------------------------------------- |
55 | | Animation* SkeletonInstance::getAnimation(unsigned short index) const |
56 | 0 | { |
57 | 0 | return mSkeleton->getAnimation(index); |
58 | 0 | } |
59 | | //------------------------------------------------------------------------- |
60 | | Animation* SkeletonInstance::createAnimation(const String& name, Real length) |
61 | 0 | { |
62 | 0 | return mSkeleton->createAnimation(name, length); |
63 | 0 | } |
64 | | //------------------------------------------------------------------------- |
65 | | Animation* SkeletonInstance::getAnimation(const String& name, |
66 | | const LinkedSkeletonAnimationSource** linker) const |
67 | 0 | { |
68 | 0 | return mSkeleton->getAnimation(name, linker); |
69 | 0 | } |
70 | | //------------------------------------------------------------------------- |
71 | | Animation* SkeletonInstance::_getAnimationImpl(const String& name, |
72 | | const LinkedSkeletonAnimationSource** linker) const |
73 | 0 | { |
74 | 0 | return mSkeleton->_getAnimationImpl(name, linker); |
75 | 0 | } |
76 | | //------------------------------------------------------------------------- |
77 | | void SkeletonInstance::removeAnimation(const String& name) |
78 | 0 | { |
79 | 0 | mSkeleton->removeAnimation(name); |
80 | 0 | } |
81 | | //------------------------------------------------------------------------- |
82 | | void SkeletonInstance::addLinkedSkeletonAnimationSource(const String& skelName, |
83 | | Real scale) |
84 | 0 | { |
85 | 0 | mSkeleton->addLinkedSkeletonAnimationSource(skelName, scale); |
86 | 0 | } |
87 | | //------------------------------------------------------------------------- |
88 | | void SkeletonInstance::removeAllLinkedSkeletonAnimationSources(void) |
89 | 0 | { |
90 | 0 | mSkeleton->removeAllLinkedSkeletonAnimationSources(); |
91 | 0 | } |
92 | | //------------------------------------------------------------------------- |
93 | | const Skeleton::LinkedSkeletonAnimSourceList& |
94 | | SkeletonInstance::getLinkedSkeletonAnimationSources() const |
95 | 0 | { |
96 | 0 | return mSkeleton->getLinkedSkeletonAnimationSources(); |
97 | 0 | } |
98 | | Skeleton::LinkedSkeletonAnimSourceIterator |
99 | | SkeletonInstance::getLinkedSkeletonAnimationSourceIterator(void) const |
100 | 0 | { |
101 | 0 | return Skeleton::LinkedSkeletonAnimSourceIterator( |
102 | 0 | mSkeleton->getLinkedSkeletonAnimationSources().begin(), |
103 | 0 | mSkeleton->getLinkedSkeletonAnimationSources().end()); |
104 | 0 | } |
105 | | //------------------------------------------------------------------------- |
106 | | void SkeletonInstance::_initAnimationState(AnimationStateSet* animSet) |
107 | 0 | { |
108 | 0 | mSkeleton->_initAnimationState(animSet); |
109 | 0 | } |
110 | | //------------------------------------------------------------------------- |
111 | | void SkeletonInstance::_refreshAnimationState(AnimationStateSet* animSet) |
112 | 0 | { |
113 | 0 | mSkeleton->_refreshAnimationState(animSet); |
114 | 0 | } |
115 | | //------------------------------------------------------------------------- |
116 | | void SkeletonInstance::cloneBoneAndChildren(Bone* source, Bone* parent) |
117 | 0 | { |
118 | 0 | Bone* newBone; |
119 | 0 | if (source->getName().empty()) |
120 | 0 | { |
121 | 0 | newBone = createBone(source->getHandle()); |
122 | 0 | } |
123 | 0 | else |
124 | 0 | { |
125 | 0 | newBone = createBone(source->getName(), source->getHandle()); |
126 | 0 | } |
127 | 0 | if (parent == NULL) |
128 | 0 | { |
129 | 0 | mRootBones.push_back(newBone); |
130 | 0 | } |
131 | 0 | else |
132 | 0 | { |
133 | 0 | parent->addChild(newBone); |
134 | 0 | } |
135 | 0 | newBone->setOrientation(source->getOrientation()); |
136 | 0 | newBone->setPosition(source->getPosition()); |
137 | 0 | newBone->setScale(source->getScale()); |
138 | | |
139 | | // Process children |
140 | 0 | for (auto c : source->getChildren()) |
141 | 0 | { |
142 | 0 | cloneBoneAndChildren(static_cast<Bone*>(c), newBone); |
143 | 0 | } |
144 | 0 | } |
145 | | //------------------------------------------------------------------------- |
146 | | void SkeletonInstance::prepareImpl(void) |
147 | 0 | { |
148 | | // construct self from master |
149 | 0 | mBlendState = mSkeleton->mBlendState; |
150 | | // Copy bones |
151 | 0 | BoneList::const_iterator i; |
152 | 0 | for (i = mSkeleton->getRootBones().begin(); i != mSkeleton->getRootBones().end(); ++i) |
153 | 0 | { |
154 | 0 | Bone* b = *i; |
155 | 0 | cloneBoneAndChildren(b, 0); |
156 | 0 | b->_update(true, false); |
157 | 0 | } |
158 | 0 | setBindingPose(); |
159 | 0 | } |
160 | | //------------------------------------------------------------------------- |
161 | | void SkeletonInstance::unprepareImpl(void) |
162 | 0 | { |
163 | 0 | Skeleton::unprepareImpl(); |
164 | | |
165 | | // destroy TagPoints |
166 | 0 | for (auto& t : mActiveTagPoints) |
167 | 0 | { |
168 | | // Woohoo! The child object all the same attaching this skeleton instance, but is ok we can just |
169 | | // ignore it: |
170 | | // 1. The parent node of the tagPoint already deleted by Skeleton::unload(), nothing need to do now |
171 | | // 2. And the child object relationship already detached by Entity::~Entity() |
172 | 0 | OGRE_DELETE t; |
173 | 0 | } |
174 | 0 | mActiveTagPoints.clear(); |
175 | 0 | for (auto& t : mFreeTagPoints) |
176 | 0 | { |
177 | 0 | OGRE_DELETE t; |
178 | 0 | } |
179 | 0 | mFreeTagPoints.clear(); |
180 | 0 | } |
181 | | |
182 | | //------------------------------------------------------------------------- |
183 | | TagPoint* SkeletonInstance::createTagPointOnBone(Bone* bone, |
184 | | const Quaternion &offsetOrientation, |
185 | | const Vector3 &offsetPosition) |
186 | 0 | { |
187 | 0 | TagPoint* ret; |
188 | 0 | if (mFreeTagPoints.empty()) { |
189 | 0 | ret = OGRE_NEW TagPoint(uint16(-1), this); |
190 | 0 | mActiveTagPoints.push_back(ret); |
191 | 0 | } else { |
192 | 0 | ret = mFreeTagPoints.front(); |
193 | 0 | mActiveTagPoints.splice( |
194 | 0 | mActiveTagPoints.end(), mFreeTagPoints, mFreeTagPoints.begin()); |
195 | | // Initial some members ensure identically behavior, avoiding potential bug. |
196 | 0 | ret->setParentEntity(0); |
197 | 0 | ret->setChildObject(0); |
198 | 0 | ret->setInheritOrientation(true); |
199 | 0 | ret->setInheritScale(true); |
200 | 0 | ret->setInheritParentEntityOrientation(true); |
201 | 0 | ret->setInheritParentEntityScale(true); |
202 | 0 | } |
203 | |
|
204 | 0 | ret->setPosition(offsetPosition); |
205 | 0 | ret->setOrientation(offsetOrientation); |
206 | 0 | ret->setScale(Vector3::UNIT_SCALE); |
207 | 0 | ret->setBindingPose(); |
208 | 0 | bone->addChild(ret); |
209 | |
|
210 | 0 | return ret; |
211 | 0 | } |
212 | | //------------------------------------------------------------------------- |
213 | | void SkeletonInstance::freeTagPoint(TagPoint* tagPoint) |
214 | 0 | { |
215 | 0 | TagPointList::iterator it = |
216 | 0 | std::find(mActiveTagPoints.begin(), mActiveTagPoints.end(), tagPoint); |
217 | 0 | assert(it != mActiveTagPoints.end()); |
218 | 0 | if (it != mActiveTagPoints.end()) |
219 | 0 | { |
220 | 0 | if (tagPoint->getParent()) |
221 | 0 | tagPoint->getParent()->removeChild(tagPoint); |
222 | |
|
223 | 0 | mFreeTagPoints.splice(mFreeTagPoints.end(), mActiveTagPoints, it); |
224 | 0 | } |
225 | 0 | } |
226 | | //------------------------------------------------------------------------- |
227 | | const String& SkeletonInstance::getName(void) const |
228 | 0 | { |
229 | | // delegate |
230 | 0 | return mSkeleton->getName(); |
231 | 0 | } |
232 | | //------------------------------------------------------------------------- |
233 | | ResourceHandle SkeletonInstance::getHandle(void) const |
234 | 0 | { |
235 | | // delegate |
236 | 0 | return mSkeleton->getHandle(); |
237 | 0 | } |
238 | | //------------------------------------------------------------------------- |
239 | | const String& SkeletonInstance::getGroup(void) const |
240 | 0 | { |
241 | | // delegate |
242 | 0 | return mSkeleton->getGroup(); |
243 | 0 | } |
244 | | |
245 | | } |
246 | | |