2
0

AnimatedModel.cpp 36 KB

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