AnimatedModel.cpp 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026
  1. //
  2. // Urho3D Engine
  3. // Copyright (c) 2008-2011 Lasse Öörni
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. //
  23. #include "Precompiled.h"
  24. #include "AnimatedModel.h"
  25. #include "Animation.h"
  26. #include "AnimationState.h"
  27. #include "Batch.h"
  28. #include "Camera.h"
  29. #include "Context.h"
  30. #include "DebugRenderer.h"
  31. #include "Geometry.h"
  32. #include "Graphics.h"
  33. #include "IndexBuffer.h"
  34. #include "Log.h"
  35. #include "Material.h"
  36. #include "MemoryBuffer.h"
  37. #include "Octree.h"
  38. #include "OctreeQuery.h"
  39. #include "Profiler.h"
  40. #include "ResourceCache.h"
  41. #include "ResourceEvents.h"
  42. #include "Scene.h"
  43. #include "Sort.h"
  44. #include "VertexBuffer.h"
  45. #include "DebugNew.h"
  46. static const Vector3 dotScale(1 / 3.0f, 1 / 3.0f, 1 / 3.0f);
  47. static bool CompareAnimationOrder(const SharedPtr<AnimationState>& lhs, const SharedPtr<AnimationState>& rhs)
  48. {
  49. return lhs->GetLayer() < rhs->GetLayer();
  50. }
  51. OBJECTTYPESTATIC(AnimatedModel);
  52. AnimatedModel::AnimatedModel(Context* context) :
  53. StaticModel(context),
  54. animationLodFrameNumber_(0),
  55. animationLodBias_(1.0f),
  56. animationLodTimer_(-1.0f),
  57. animationLodDistance_(0.0f),
  58. invisibleLodFactor_(0.0f),
  59. animationDirty_(true),
  60. animationOrderDirty_(true),
  61. morphsDirty_(true),
  62. skinningDirty_(true),
  63. isMaster_(true),
  64. assignBonesPending_(false)
  65. {
  66. }
  67. AnimatedModel::~AnimatedModel()
  68. {
  69. }
  70. void AnimatedModel::RegisterObject(Context* context)
  71. {
  72. context->RegisterFactory<AnimatedModel>();
  73. context->CopyBaseAttributes<Drawable, AnimatedModel>();
  74. ACCESSOR_ATTRIBUTE(AnimatedModel, VAR_RESOURCEREF, "Model", GetModelAttr, SetModelAttr, ResourceRef, ResourceRef(Model::GetTypeStatic()), AM_DEFAULT);
  75. ACCESSOR_ATTRIBUTE(AnimatedModel, VAR_RESOURCEREFLIST, "Materials", GetMaterialsAttr, SetMaterialsAttr, ResourceRefList, ResourceRefList(Material::GetTypeStatic()), AM_DEFAULT);
  76. ATTRIBUTE(AnimatedModel, VAR_FLOAT, "Animation LOD Bias", animationLodBias_, 1.0f, AM_DEFAULT);
  77. ATTRIBUTE(AnimatedModel, VAR_INT, "Raycast/Occlusion LOD Level", softwareLodLevel_, M_MAX_UNSIGNED, AM_DEFAULT);
  78. ACCESSOR_ATTRIBUTE(AnimatedModel, VAR_BUFFER, "Bone Animation Enabled", GetBonesEnabledAttr, SetBonesEnabledAttr, PODVector<unsigned char>, PODVector<unsigned char>(), AM_FILE | AM_NOEDIT);
  79. ACCESSOR_ATTRIBUTE(AnimatedModel, VAR_BUFFER, "Animation States", GetAnimationStatesAttr, SetAnimationStatesAttr, PODVector<unsigned char>, PODVector<unsigned char>(), AM_FILE | AM_NOEDIT);
  80. }
  81. void AnimatedModel::FinishUpdate()
  82. {
  83. if (assignBonesPending_)
  84. {
  85. AssignBoneNodes();
  86. assignBonesPending_ = false;
  87. }
  88. }
  89. void AnimatedModel::ProcessRayQuery(RayOctreeQuery& query, float initialDistance)
  90. {
  91. // If no bones or no bone-level testing, use the Drawable test
  92. if (!skeleton_.GetNumBones() || query.level_ < RAY_AABB)
  93. {
  94. Drawable::ProcessRayQuery(query, initialDistance);
  95. return;
  96. }
  97. PROFILE(RaycastAnimatedModel);
  98. const Vector<Bone>& bones = skeleton_.GetBones();
  99. Sphere boneSphere;
  100. RayQueryLevel level = query.level_;
  101. for (unsigned i = 0; i < bones.Size(); ++i)
  102. {
  103. const Bone& bone = bones[i];
  104. if (!bone.node_)
  105. continue;
  106. // Use hitbox if available
  107. if (bone.collisionMask_ & BONECOLLISION_BOX)
  108. {
  109. // Do an initial crude test using the bone's AABB
  110. const BoundingBox& box = bone.boundingBox_;
  111. const Matrix3x4& transform = bone.node_->GetWorldTransform();
  112. float distance = box.Transformed(transform).Distance(query.ray_);
  113. if (distance < query.maxDistance_)
  114. {
  115. if (level == RAY_AABB)
  116. {
  117. RayQueryResult result;
  118. result.drawable_ = this;
  119. result.node_ = GetNode();
  120. result.distance_ = distance;
  121. result.subObject_ = i;
  122. query.result_.Push(result);
  123. }
  124. else
  125. {
  126. // Follow with an OBB test if required
  127. Matrix3x4 inverse = transform.Inverse();
  128. Ray localRay(inverse * query.ray_.origin_, inverse * Vector4(query.ray_.direction_, 0.0f));
  129. distance = box.Distance(localRay);
  130. if (distance < query.maxDistance_)
  131. {
  132. RayQueryResult result;
  133. result.drawable_ = this;
  134. result.node_ = GetNode();
  135. result.distance_ = distance;
  136. result.subObject_ = i;
  137. query.result_.Push(result);
  138. }
  139. }
  140. }
  141. }
  142. else if (bone.collisionMask_ & BONECOLLISION_SPHERE)
  143. {
  144. boneSphere.center_ = bone.node_->GetWorldPosition();
  145. boneSphere.radius_ = bone.radius_;
  146. float distance = boneSphere.Distance(query.ray_);
  147. if (distance < query.maxDistance_)
  148. {
  149. RayQueryResult result;
  150. result.drawable_ = this;
  151. result.node_ = GetNode();
  152. result.subObject_ = i;
  153. result.distance_ = distance;
  154. query.result_.Push(result);
  155. }
  156. }
  157. }
  158. }
  159. void AnimatedModel::Update(const FrameInfo& frame)
  160. {
  161. // Update animation here
  162. if (!animationDirty_ && !animationOrderDirty_)
  163. return;
  164. // If node was invisible last frame, need to decide animation LOD distance here
  165. // If headless, retain the current animation distance (should be 0)
  166. if (frame.camera_ && abs((int)frame.frameNumber_ - (int)viewFrameNumber_) > 1)
  167. {
  168. if (invisibleLodFactor_ == 0.0f)
  169. return;
  170. float distance = frame.camera_->GetDistance(GetWorldPosition());
  171. // If distance is greater than draw distance, no need to update at all
  172. if (drawDistance_ > 0.0f && distance > drawDistance_)
  173. return;
  174. // Multiply the distance by a constant so that invisible nodes don't update that often
  175. float scale = GetWorldBoundingBox().Size().DotProduct(dotScale);
  176. animationLodDistance_ = frame.camera_->GetLodDistance(distance, scale, lodBias_) * invisibleLodFactor_;
  177. }
  178. UpdateAnimation(frame);
  179. }
  180. void AnimatedModel::UpdateDistance(const FrameInfo& frame)
  181. {
  182. distance_ = frame.camera_->GetDistance(GetWorldPosition());
  183. float scale = GetWorldBoundingBox().Size().DotProduct(dotScale);
  184. float newLodDistance = frame.camera_->GetLodDistance(distance_, scale, lodBias_);
  185. // If model is rendered from several views, use the minimum LOD distance for animation LOD
  186. if (frame.frameNumber_ != animationLodFrameNumber_)
  187. {
  188. animationLodDistance_ = newLodDistance;
  189. animationLodFrameNumber_ = frame.frameNumber_;
  190. }
  191. else
  192. animationLodDistance_ = Min(animationLodDistance_, newLodDistance);
  193. if (newLodDistance != lodDistance_)
  194. {
  195. lodDistance_ = newLodDistance;
  196. lodLevelsDirty_ = true;
  197. }
  198. }
  199. void AnimatedModel::UpdateGeometry(const FrameInfo& frame)
  200. {
  201. if (lodLevelsDirty_)
  202. CalculateLodLevels();
  203. if (morphsDirty_ && morphs_.Size())
  204. UpdateMorphs();
  205. if (skinningDirty_)
  206. UpdateSkinning();
  207. }
  208. void AnimatedModel::GetBatch(const FrameInfo& frame, unsigned batchIndex, Batch& batch)
  209. {
  210. batch.geometry_ = geometries_[batchIndex][lodLevels_[batchIndex]];
  211. batch.geometryType_ = GEOM_SKINNED;
  212. batch.worldTransform_ = &GetWorldTransform();
  213. batch.material_ = materials_[batchIndex];
  214. if (skinMatrices_.Size())
  215. {
  216. // Check if model has per-geometry bone mappings
  217. if (geometrySkinMatrices_.Size() && geometrySkinMatrices_[batchIndex].Size())
  218. {
  219. batch.shaderData_ = geometrySkinMatrices_[batchIndex][0].GetData();
  220. batch.shaderDataSize_ = geometrySkinMatrices_[batchIndex].Size() * 12;
  221. }
  222. // If not, use the global skin matrices
  223. else
  224. {
  225. batch.shaderData_ = skinMatrices_[0].GetData();
  226. batch.shaderDataSize_ = skinMatrices_.Size() * 12;
  227. }
  228. }
  229. }
  230. void AnimatedModel::DrawDebugGeometry(DebugRenderer* debug, bool depthTest)
  231. {
  232. debug->AddBoundingBox(GetWorldBoundingBox(), Color(0.0f, 1.0f, 0.0f), depthTest);
  233. debug->AddSkeleton(skeleton_, Color(0.75f, 0.75f, 0.75f), depthTest);
  234. }
  235. void AnimatedModel::SetModel(Model* model, bool createBones)
  236. {
  237. if (!model || model == model_)
  238. return;
  239. // Unsubscribe from the reload event of previous model (if any), then subscribe to the new
  240. if (model_)
  241. UnsubscribeFromEvent(model_, E_RELOADFINISHED);
  242. if (model)
  243. SubscribeToEvent(model, E_RELOADFINISHED, HANDLER(AnimatedModel, HandleModelReloadFinished));
  244. model_ = model;
  245. // Copy the subgeometry & LOD level structure
  246. SetNumGeometries(model->GetNumGeometries());
  247. const Vector<Vector<SharedPtr<Geometry> > >& geometries = model->GetGeometries();
  248. for (unsigned i = 0; i < geometries.Size(); ++i)
  249. geometries_[i] = geometries[i];
  250. // Copy geometry bone mappings
  251. const Vector<PODVector<unsigned> >& geometryBoneMappings = model->GetGeometryBoneMappings();
  252. geometryBoneMappings_.Clear();
  253. for (unsigned i = 0; i < geometryBoneMappings.Size(); ++i)
  254. geometryBoneMappings_.Push(geometryBoneMappings[i]);
  255. // Copy morphs
  256. morphVertexBuffers_.Clear();
  257. morphs_.Clear();
  258. const Vector<ModelMorph>& morphs = model->GetMorphs();
  259. for (unsigned i = 0; i < morphs.Size(); ++i)
  260. {
  261. ModelMorph newMorph;
  262. newMorph.name_ = morphs[i].name_;
  263. newMorph.nameHash_ = morphs[i].nameHash_;
  264. newMorph.weight_ = 0.0f;
  265. newMorph.buffers_ = morphs[i].buffers_;
  266. morphs_.Push(newMorph);
  267. }
  268. // If model has morphs, must clone all geometries & vertex buffers that refer to morphable vertex data
  269. if (morphs.Size())
  270. {
  271. cloneGeometries();
  272. MarkMorphsDirty();
  273. }
  274. // Copy bounding box & skeleton
  275. SetBoundingBox(model->GetBoundingBox());
  276. SetSkeleton(model->GetSkeleton(), createBones);
  277. }
  278. AnimationState* AnimatedModel::AddAnimationState(Animation* animation)
  279. {
  280. if (!isMaster_)
  281. {
  282. LOGERROR("Can not add animation state to non-master model");
  283. return 0;
  284. }
  285. if (!animation || !skeleton_.GetNumBones())
  286. return 0;
  287. // Check for not adding twice
  288. AnimationState* existing = GetAnimationState(animation);
  289. if (existing)
  290. return existing;
  291. SharedPtr<AnimationState> newState(new AnimationState(this, animation));
  292. animationStates_.Push(newState);
  293. MarkAnimationOrderDirty();
  294. return newState;
  295. }
  296. void AnimatedModel::RemoveAnimationState(Animation* animation)
  297. {
  298. if (animation)
  299. RemoveAnimationState(animation->GetNameHash());
  300. }
  301. void AnimatedModel::RemoveAnimationState(const String& animationName)
  302. {
  303. RemoveAnimationState(StringHash(animationName));
  304. }
  305. void AnimatedModel::RemoveAnimationState(StringHash animationNameHash)
  306. {
  307. for (Vector<SharedPtr<AnimationState> >::Iterator i = animationStates_.Begin(); i != animationStates_.End(); ++i)
  308. {
  309. AnimationState* state = *i;
  310. Animation* animation = state->GetAnimation();
  311. // Check both the animation and the resource name
  312. if (animation->GetNameHash() == animationNameHash || animation->GetAnimationNameHash() == animationNameHash)
  313. {
  314. animationStates_.Erase(i);
  315. MarkAnimationDirty();
  316. }
  317. }
  318. }
  319. void AnimatedModel::RemoveAnimationState(AnimationState* state)
  320. {
  321. for (Vector<SharedPtr<AnimationState> >::Iterator i = animationStates_.Begin(); i != animationStates_.End(); ++i)
  322. {
  323. if (*i == state)
  324. {
  325. animationStates_.Erase(i);
  326. MarkAnimationDirty();
  327. return;
  328. }
  329. }
  330. }
  331. void AnimatedModel::RemoveAllAnimationStates()
  332. {
  333. animationStates_.Clear();
  334. MarkAnimationDirty();
  335. }
  336. void AnimatedModel::SetAnimationLodBias(float bias)
  337. {
  338. animationLodBias_ = Max(bias, 0.0f);
  339. }
  340. void AnimatedModel::SetInvisibleLodFactor(float factor)
  341. {
  342. if (factor < 0.0f)
  343. factor = 0.0f;
  344. else if (factor != 0.0f && factor < 1.0f)
  345. factor = 1.0f;
  346. invisibleLodFactor_ = factor;
  347. }
  348. void AnimatedModel::SetMorphWeight(unsigned index, float weight)
  349. {
  350. if (index >= morphs_.Size())
  351. return;
  352. weight = Clamp(weight, 0.0f, 1.0f);
  353. if (weight != morphs_[index].weight_)
  354. {
  355. morphs_[index].weight_ = weight;
  356. MarkMorphsDirty();
  357. // For a master model, set the same morph weight on non-master models
  358. if (isMaster_)
  359. {
  360. PODVector<AnimatedModel*> models;
  361. GetComponents<AnimatedModel>(models);
  362. // Indexing might not be the same, so use the name hash instead
  363. for (unsigned i = 1; i < models.Size(); ++i)
  364. models[i]->SetMorphWeight(morphs_[index].nameHash_, weight);
  365. }
  366. }
  367. }
  368. void AnimatedModel::SetMorphWeight(const String& name, float weight)
  369. {
  370. for (unsigned i = 0; i < morphs_.Size(); ++i)
  371. {
  372. if (morphs_[i].name_ == name)
  373. {
  374. SetMorphWeight(i, weight);
  375. return;
  376. }
  377. }
  378. }
  379. void AnimatedModel::SetMorphWeight(StringHash nameHash, float weight)
  380. {
  381. for (unsigned i = 0; i < morphs_.Size(); ++i)
  382. {
  383. if (morphs_[i].nameHash_ == nameHash)
  384. {
  385. SetMorphWeight(i, weight);
  386. return;
  387. }
  388. }
  389. }
  390. void AnimatedModel::ResetMorphWeights()
  391. {
  392. for (Vector<ModelMorph>::Iterator i = morphs_.Begin(); i != morphs_.End(); ++i)
  393. i->weight_ = 0.0f;
  394. MarkMorphsDirty();
  395. // For a master model, reset weights on non-master models
  396. if (isMaster_)
  397. {
  398. PODVector<AnimatedModel*> models;
  399. GetComponents<AnimatedModel>(models);
  400. // Indexing might not be the same, so use the name hash instead
  401. for (unsigned i = 1; i < models.Size(); ++i)
  402. models[i]->ResetMorphWeights();
  403. }
  404. }
  405. float AnimatedModel::GetMorphWeight(unsigned index) const
  406. {
  407. return index < morphs_.Size() ? morphs_[index].weight_ : 0.0f;
  408. }
  409. float AnimatedModel::GetMorphWeight(const String& name) const
  410. {
  411. for (Vector<ModelMorph>::ConstIterator i = morphs_.Begin(); i != morphs_.End(); ++i)
  412. {
  413. if (i->name_ == name)
  414. return i->weight_;
  415. }
  416. return 0.0f;
  417. }
  418. float AnimatedModel::GetMorphWeight(StringHash nameHash) const
  419. {
  420. for (Vector<ModelMorph>::ConstIterator i = morphs_.Begin(); i != morphs_.End(); ++i)
  421. {
  422. if (i->nameHash_ == nameHash)
  423. return i->weight_;
  424. }
  425. return 0.0f;
  426. }
  427. AnimationState* AnimatedModel::GetAnimationState(Animation* animation) const
  428. {
  429. for (Vector<SharedPtr<AnimationState> >::ConstIterator i = animationStates_.Begin(); i != animationStates_.End(); ++i)
  430. {
  431. if ((*i)->GetAnimation() == animation)
  432. return *i;
  433. }
  434. return 0;
  435. }
  436. AnimationState* AnimatedModel::GetAnimationState(const String& animationName) const
  437. {
  438. for (Vector<SharedPtr<AnimationState> >::ConstIterator i = animationStates_.Begin(); i != animationStates_.End(); ++i)
  439. {
  440. Animation* animation = (*i)->GetAnimation();
  441. // Check both the animation and the resource name
  442. if (animation->GetName() == animationName || animation->GetAnimationName() == animationName)
  443. return *i;
  444. }
  445. return 0;
  446. }
  447. AnimationState* AnimatedModel::GetAnimationState(StringHash animationNameHash) const
  448. {
  449. for (Vector<SharedPtr<AnimationState> >::ConstIterator i = animationStates_.Begin(); i != animationStates_.End(); ++i)
  450. {
  451. Animation* animation = (*i)->GetAnimation();
  452. // Check both the animation and the resource name
  453. if (animation->GetNameHash() == animationNameHash || animation->GetAnimationNameHash() == animationNameHash)
  454. return *i;
  455. }
  456. return 0;
  457. }
  458. AnimationState* AnimatedModel::GetAnimationState(unsigned index) const
  459. {
  460. return index < animationStates_.Size() ? animationStates_[index].RawPtr() : 0;
  461. }
  462. void AnimatedModel::SetSkeleton(const Skeleton& skeleton, bool createBones)
  463. {
  464. if (!node_ && createBones)
  465. {
  466. LOGWARNING("AnimatedModel not attached to a scene node, can not create bone nodes");
  467. return;
  468. }
  469. if (isMaster_)
  470. {
  471. // Detach the rootbone of the previous model if any
  472. if (createBones)
  473. {
  474. Bone* rootBone = skeleton_.GetRootBone();
  475. if (rootBone)
  476. node_->RemoveChild(rootBone->node_);
  477. }
  478. RemoveAllAnimationStates();
  479. skeleton_.Define(skeleton);
  480. // Create scene nodes for the bones, or get from the master model if not master
  481. if (createBones)
  482. {
  483. Vector<Bone>& bones = skeleton_.GetModifiableBones();
  484. for (Vector<Bone>::Iterator i = bones.Begin(); i != bones.End(); ++i)
  485. {
  486. // Create bones as local, as they are never to be directly synchronized over the network
  487. Node* boneNode = node_->CreateChild(i->name_, LOCAL);
  488. boneNode->AddListener(this);
  489. boneNode->SetTransform(i->initialPosition_, i->initialRotation_, i->initialScale_);
  490. i->node_ = boneNode;
  491. }
  492. for (unsigned i = 0; i < bones.Size(); ++i)
  493. {
  494. unsigned parentIndex = bones[i].parentIndex_;
  495. if (parentIndex != i && parentIndex < bones.Size())
  496. bones[parentIndex].node_->AddChild(bones[i].node_);
  497. }
  498. }
  499. }
  500. else
  501. {
  502. // For non-master models: use the bone nodes of the master model
  503. skeleton_.Define(skeleton);
  504. if (createBones)
  505. {
  506. Vector<Bone>& bones = skeleton_.GetModifiableBones();
  507. for (Vector<Bone>::Iterator i = bones.Begin(); i != bones.End(); ++i)
  508. {
  509. Node* boneNode = node_->GetChild(i->name_, true);
  510. if (boneNode)
  511. boneNode->AddListener(this);
  512. i->node_ = boneNode;
  513. }
  514. }
  515. }
  516. // Reserve space for skinning matrices
  517. skinMatrices_.Resize(skeleton_.GetNumBones());
  518. RefreshGeometryBoneMappings();
  519. assignBonesPending_ = !createBones;
  520. }
  521. void AnimatedModel::SetModelAttr(ResourceRef value)
  522. {
  523. ResourceCache* cache = GetSubsystem<ResourceCache>();
  524. // When loading a scene, set model without creating the bone nodes (will be assigned later during post-load)
  525. SetModel(cache->GetResource<Model>(value.id_), !IsLoading());
  526. }
  527. void AnimatedModel::SetBonesEnabledAttr(PODVector<unsigned char> value)
  528. {
  529. MemoryBuffer buf(value);
  530. Vector<Bone>& bones = skeleton_.GetModifiableBones();
  531. unsigned numBones = buf.ReadVLE();
  532. for (unsigned i = 0; i < numBones && i < bones.Size(); ++i)
  533. bones[i].animated_ = buf.ReadBool();
  534. }
  535. void AnimatedModel::SetAnimationStatesAttr(PODVector<unsigned char> value)
  536. {
  537. ResourceCache* cache = GetSubsystem<ResourceCache>();
  538. // The animation states will at first be created without bone node references
  539. RemoveAllAnimationStates();
  540. MemoryBuffer buf(value);
  541. unsigned numAnimations = buf.ReadVLE();
  542. for (unsigned i = 0; i < numAnimations; ++i)
  543. {
  544. AnimationState* state = AddAnimationState(cache->GetResource<Animation>(buf.ReadStringHash()));
  545. if (state)
  546. {
  547. state->SetStartBone(skeleton_.GetBone(buf.ReadStringHash()));
  548. state->SetLooped(buf.ReadBool());
  549. state->SetWeight(buf.ReadFloat());
  550. state->SetTime(buf.ReadFloat());
  551. state->SetLayer(buf.ReadUByte());
  552. state->SetUseNlerp(buf.ReadBool());
  553. }
  554. else
  555. buf.Seek(sizeof(StringHash) + 1 + sizeof(float) + sizeof(float) + sizeof(int) + 1);
  556. }
  557. }
  558. ResourceRef AnimatedModel::GetModelAttr() const
  559. {
  560. return GetResourceRef(model_, Model::GetTypeStatic());
  561. }
  562. PODVector<unsigned char> AnimatedModel::GetBonesEnabledAttr() const
  563. {
  564. VectorBuffer buf;
  565. const Vector<Bone>& bones = skeleton_.GetBones();
  566. buf.WriteVLE(bones.Size());
  567. for (Vector<Bone>::ConstIterator i = bones.Begin(); i != bones.End(); ++i)
  568. buf.WriteBool(i->animated_);
  569. return buf.GetBuffer();
  570. }
  571. PODVector<unsigned char> AnimatedModel::GetAnimationStatesAttr() const
  572. {
  573. VectorBuffer buf;
  574. buf.WriteVLE(animationStates_.Size());
  575. for (Vector<SharedPtr<AnimationState> >::ConstIterator i = animationStates_.Begin(); i != animationStates_.End(); ++i)
  576. {
  577. AnimationState* state = *i;
  578. Bone* startBone = state->GetStartBone();
  579. buf.WriteStringHash(state->GetAnimation()->GetNameHash());
  580. buf.WriteStringHash(startBone ? startBone->nameHash_ : StringHash());
  581. buf.WriteBool(state->IsLooped());
  582. buf.WriteFloat(state->GetWeight());
  583. buf.WriteFloat(state->GetTime());
  584. buf.WriteInt(state->GetLayer());
  585. buf.WriteBool(state->GetUseNlerp());
  586. }
  587. return buf.GetBuffer();
  588. }
  589. void AnimatedModel::OnNodeSet(Node* node)
  590. {
  591. Drawable::OnNodeSet(node);
  592. // If this AnimatedModel is the first in the node, it is the master which controls animation & morphs
  593. isMaster_ = GetComponent<AnimatedModel>(0) == this;
  594. }
  595. void AnimatedModel::OnMarkedDirty(Node* node)
  596. {
  597. // If the scene node or any of the bone nodes move, mark skinning dirty
  598. skinningDirty_ = true;
  599. if (node == node_)
  600. {
  601. worldBoundingBoxDirty_ = true;
  602. if (octant_)
  603. octant_->GetRoot()->QueueReinsertion(this);
  604. }
  605. }
  606. void AnimatedModel::OnWorldBoundingBoxUpdate()
  607. {
  608. if (!skeleton_.GetNumBones())
  609. worldBoundingBox_ = boundingBox_.Transformed(GetWorldTransform());
  610. else
  611. {
  612. // If has bones, update world bounding box based on them
  613. worldBoundingBox_.defined_ = false;
  614. const Vector<Bone>& bones = skeleton_.GetBones();
  615. for (Vector<Bone>::ConstIterator i = bones.Begin(); i != bones.End(); ++i)
  616. {
  617. Node* boneNode = i->node_;
  618. if (!boneNode)
  619. continue;
  620. // Use hitbox if available. If not, use only half of the sphere radius
  621. if (i->collisionMask_ & BONECOLLISION_BOX)
  622. worldBoundingBox_.Merge(i->boundingBox_.Transformed(boneNode->GetWorldTransform()));
  623. else if (i->collisionMask_ & BONECOLLISION_SPHERE)
  624. worldBoundingBox_.Merge(Sphere(boneNode->GetWorldPosition(), i->radius_ * 0.5f));
  625. }
  626. }
  627. }
  628. void AnimatedModel::AssignBoneNodes()
  629. {
  630. if (!node_)
  631. return;
  632. // Find the bone nodes from the node hierarchy and add listeners
  633. Vector<Bone>& bones = skeleton_.GetModifiableBones();
  634. for (Vector<Bone>::Iterator i = bones.Begin(); i != bones.End(); ++i)
  635. {
  636. Node* boneNode = node_->GetChild(i->name_, true);
  637. if (boneNode)
  638. boneNode->AddListener(this);
  639. i->node_ = boneNode;
  640. }
  641. // Re-assign the same start bone to get the proper bone node this time
  642. for (Vector<SharedPtr<AnimationState> >::Iterator i = animationStates_.Begin(); i != animationStates_.End(); ++i)
  643. {
  644. AnimationState* state = *i;
  645. state->SetStartBone(state->GetStartBone());
  646. }
  647. }
  648. void AnimatedModel::MarkAnimationDirty()
  649. {
  650. if (!isMaster_)
  651. return;
  652. animationDirty_ = true;
  653. // Mark for octree update, as animation is updated before octree reinsertion
  654. MarkForUpdate();
  655. }
  656. void AnimatedModel::MarkAnimationOrderDirty()
  657. {
  658. if (!isMaster_)
  659. return;
  660. animationOrderDirty_ = true;
  661. // Mark for octree update, as animation is updated before octree reinsertion
  662. MarkForUpdate();
  663. }
  664. void AnimatedModel::MarkMorphsDirty()
  665. {
  666. morphsDirty_ = true;
  667. }
  668. void AnimatedModel::cloneGeometries()
  669. {
  670. // Clone vertex buffers as necessary
  671. const Vector<SharedPtr<VertexBuffer> >& originalVertexBuffers = model_->GetVertexBuffers();
  672. Map<VertexBuffer*, SharedPtr<VertexBuffer> > clonedVertexBuffers;
  673. morphVertexBuffers_.Resize(originalVertexBuffers.Size());
  674. for (unsigned i = 0; i < originalVertexBuffers.Size(); ++i)
  675. {
  676. VertexBuffer* original = originalVertexBuffers[i];
  677. if (original->HasMorphRange())
  678. {
  679. SharedPtr<VertexBuffer> clone(new VertexBuffer(context_));
  680. clone->SetSize(original->GetVertexCount(), original->GetElementMask(), true);
  681. void* originalData = original->Lock(0, original->GetVertexCount(), LOCK_NORMAL);
  682. if (originalData)
  683. {
  684. clone->SetData(originalData);
  685. original->Unlock();
  686. }
  687. clone->SetMorphRange(original->GetMorphRangeStart(), original->GetMorphRangeCount());
  688. clone->SetMorphRangeResetData(original->GetMorphRangeResetData());
  689. clonedVertexBuffers[original] = clone;
  690. morphVertexBuffers_[i] = clone;
  691. }
  692. }
  693. // Geometries will always be cloned fully. They contain only references to buffer, so they are relatively light
  694. for (unsigned i = 0; i < geometries_.Size(); ++i)
  695. {
  696. for (unsigned j = 0; j < geometries_[i].Size(); ++j)
  697. {
  698. SharedPtr<Geometry> original = geometries_[i][j];
  699. const Vector<SharedPtr<VertexBuffer> >& originalBuffers = original->GetVertexBuffers();
  700. SharedPtr<Geometry> clone(new Geometry(context_));
  701. clone->SetNumVertexBuffers(originalVertexBuffers.Size());
  702. for (unsigned k = 0; k < originalVertexBuffers.Size(); ++k)
  703. {
  704. VertexBuffer* originalBuffer = originalBuffers[k];
  705. if (clonedVertexBuffers.Find(originalBuffer) != clonedVertexBuffers.End())
  706. clone->SetVertexBuffer(k, clonedVertexBuffers[originalBuffer], original->GetVertexElementMask(k));
  707. else
  708. clone->SetVertexBuffer(k, originalBuffers[k], original->GetVertexElementMask(k));
  709. }
  710. clone->SetIndexBuffer(original->GetIndexBuffer());
  711. clone->SetDrawRange(original->GetPrimitiveType(), original->GetIndexStart(), original->GetIndexCount());
  712. clone->SetLodDistance(original->GetLodDistance());
  713. geometries_[i][j] = clone;
  714. }
  715. }
  716. }
  717. void AnimatedModel::RefreshGeometryBoneMappings()
  718. {
  719. geometrySkinMatrices_.Clear();
  720. geometrySkinMatrixPtrs_.Clear();
  721. if (!geometryBoneMappings_.Size())
  722. return;
  723. // Check if all mappings are empty, then we do not need to use mapped skinning
  724. bool allEmpty = true;
  725. for (unsigned i = 0; i < geometryBoneMappings_.Size(); ++i)
  726. if (geometryBoneMappings_[i].Size())
  727. allEmpty = false;
  728. if (allEmpty)
  729. return;
  730. // Reserve space for per-geometry skinning matrices
  731. geometrySkinMatrices_.Resize(geometryBoneMappings_.Size());
  732. for (unsigned i = 0; i < geometryBoneMappings_.Size(); ++i)
  733. geometrySkinMatrices_[i].Resize(geometryBoneMappings_[i].Size());
  734. // Build original-to-skinindex matrix pointer mapping for fast copying
  735. // Note: at this point layout of geometrySkinMatrices_ cannot be modified or pointers become invalid
  736. geometrySkinMatrixPtrs_.Resize(skeleton_.GetNumBones());
  737. for (unsigned i = 0; i < geometryBoneMappings_.Size(); ++i)
  738. {
  739. for (unsigned j = 0; j < geometryBoneMappings_[i].Size(); ++j)
  740. geometrySkinMatrixPtrs_[geometryBoneMappings_[i][j]].Push(&geometrySkinMatrices_[i][j]);
  741. }
  742. }
  743. void AnimatedModel::UpdateAnimation(const FrameInfo& frame)
  744. {
  745. // If using animation LOD, accumulate time and see if it is time to update
  746. if (animationLodBias_ > 0.0f && animationLodDistance_ > 0.0f)
  747. {
  748. // Check for first time update
  749. if (animationLodTimer_ >= 0.0f)
  750. {
  751. animationLodTimer_ += animationLodBias_ * frame.timeStep_ * frame.viewSize_.y_ * ANIMATION_LOD_BASESCALE;
  752. if (animationLodTimer_ >= animationLodDistance_)
  753. animationLodTimer_ = fmodf(animationLodTimer_, animationLodDistance_);
  754. else
  755. return;
  756. }
  757. else
  758. animationLodTimer_ = 0.0f;
  759. }
  760. PROFILE(UpdateAnimation);
  761. // Make sure animations are in ascending priority order
  762. if (animationOrderDirty_)
  763. {
  764. Sort(animationStates_.Begin(), animationStates_.End(), CompareAnimationOrder);
  765. animationOrderDirty_ = false;
  766. }
  767. // Reset skeleton, then apply all animations
  768. skeleton_.Reset();
  769. for (Vector<SharedPtr<AnimationState> >::Iterator i = animationStates_.Begin(); i != animationStates_.End(); ++i)
  770. (*i)->Apply();
  771. // Animation has changed the bounding box: mark node for octree reinsertion
  772. Drawable::OnMarkedDirty(node_);
  773. animationDirty_ = false;
  774. }
  775. void AnimatedModel::UpdateSkinning()
  776. {
  777. PROFILE(UpdateSkinning);
  778. // Note: the model's world transform will be baked in the skin matrices
  779. const Vector<Bone>& bones = skeleton_.GetBones();
  780. // Use model's world transform in case a bone is missing
  781. const Matrix3x4& worldTransform = node_->GetWorldTransform();
  782. // Skinning with global matrices only
  783. if (!geometrySkinMatrices_.Size())
  784. {
  785. for (unsigned i = 0; i < bones.Size(); ++i)
  786. {
  787. const Bone& bone = bones[i];
  788. if (bone.node_)
  789. skinMatrices_[i] = bone.node_->GetWorldTransform() * bone.offsetMatrix_;
  790. else
  791. skinMatrices_[i] = worldTransform;
  792. }
  793. }
  794. // Skinning with per-geometry matrices
  795. else
  796. {
  797. for (unsigned i = 0; i < bones.Size(); ++i)
  798. {
  799. const Bone& bone = bones[i];
  800. if (bone.node_)
  801. skinMatrices_[i] = bone.node_->GetWorldTransform() * bone.offsetMatrix_;
  802. else
  803. skinMatrices_[i] = worldTransform;
  804. // Copy the skin matrix to per-geometry matrices as needed
  805. for (unsigned j = 0; j < geometrySkinMatrixPtrs_[i].Size(); ++j)
  806. *geometrySkinMatrixPtrs_[i][j] = skinMatrices_[i];
  807. }
  808. }
  809. skinningDirty_ = false;
  810. }
  811. void AnimatedModel::UpdateMorphs()
  812. {
  813. if (morphs_.Size())
  814. {
  815. PROFILE(UpdateMorphs);
  816. // Reset the morph data range from all morphable vertex buffers, then apply morphs
  817. for (unsigned i = 0; i < morphVertexBuffers_.Size(); ++i)
  818. {
  819. VertexBuffer* buffer = morphVertexBuffers_[i];
  820. if (buffer)
  821. {
  822. void* lockedMorphRange = buffer->LockMorphRange();
  823. if (!lockedMorphRange)
  824. continue;
  825. buffer->ResetMorphRange(lockedMorphRange);
  826. for (unsigned j = 0; j < morphs_.Size(); ++j)
  827. {
  828. if (morphs_[j].weight_ > 0.0f)
  829. {
  830. Map<unsigned, VertexBufferMorph>::Iterator k = morphs_[j].buffers_.Find(i);
  831. if (k != morphs_[j].buffers_.End())
  832. ApplyMorph(buffer, lockedMorphRange, k->second_, morphs_[j].weight_);
  833. }
  834. }
  835. buffer->Unlock();
  836. }
  837. }
  838. }
  839. morphsDirty_ = false;
  840. }
  841. void AnimatedModel::ApplyMorph(VertexBuffer* buffer, void* lockedMorphRange, const VertexBufferMorph& morph, float weight)
  842. {
  843. unsigned elementMask = morph.elementMask_;
  844. unsigned vertexCount = morph.vertexCount_;
  845. unsigned normalOffset = buffer->GetElementOffset(ELEMENT_NORMAL);
  846. unsigned tangentOffset = buffer->GetElementOffset(ELEMENT_TANGENT);
  847. unsigned morphRangeStart = buffer->GetMorphRangeStart();
  848. unsigned vertexSize = buffer->GetVertexSize();
  849. unsigned char* srcData = morph.morphData_;
  850. unsigned char* destData = (unsigned char*)lockedMorphRange;
  851. while (vertexCount--)
  852. {
  853. unsigned vertexIndex = *((unsigned*)srcData) - morphRangeStart;
  854. srcData += sizeof(unsigned);
  855. if (elementMask & MASK_POSITION)
  856. {
  857. float* dest = (float*)(destData + vertexIndex * vertexSize);
  858. float* src = (float*)srcData;
  859. dest[0] += src[0] * weight;
  860. dest[1] += src[1] * weight;
  861. dest[2] += src[2] * weight;
  862. srcData += 3 * sizeof(float);
  863. }
  864. if (elementMask & MASK_NORMAL)
  865. {
  866. float* dest = (float*)(destData + vertexIndex * vertexSize + normalOffset);
  867. float* src = (float*)srcData;
  868. dest[0] += src[0] * weight;
  869. dest[1] += src[1] * weight;
  870. dest[2] += src[2] * weight;
  871. srcData += 3 * sizeof(float);
  872. }
  873. if (elementMask & MASK_TANGENT)
  874. {
  875. float* dest = (float*)(destData + vertexIndex * vertexSize + tangentOffset);
  876. float* src = (float*)srcData;
  877. dest[0] += src[0] * weight;
  878. dest[1] += src[1] * weight;
  879. dest[2] += src[2] * weight;
  880. srcData += 3 * sizeof(float);
  881. }
  882. }
  883. }
  884. void AnimatedModel::HandleModelReloadFinished(StringHash eventType, VariantMap& eventData)
  885. {
  886. Model* currentModel = model_;
  887. model_ = 0; // Set null to allow to be re-set
  888. SetModel(currentModel);
  889. }