AnimatedModel.cpp 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440
  1. //
  2. // Copyright (c) 2008-2017 the Urho3D project.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #include "../Precompiled.h"
  23. #include "../Core/Context.h"
  24. #include "../Core/Profiler.h"
  25. #include "../Graphics/AnimatedModel.h"
  26. #include "../Graphics/Animation.h"
  27. #include "../Graphics/AnimationState.h"
  28. #include "../Graphics/Batch.h"
  29. #include "../Graphics/Camera.h"
  30. #include "../Graphics/DebugRenderer.h"
  31. #include "../Graphics/DrawableEvents.h"
  32. #include "../Graphics/Geometry.h"
  33. #include "../Graphics/Graphics.h"
  34. #include "../Graphics/IndexBuffer.h"
  35. #include "../Graphics/Material.h"
  36. #include "../Graphics/Octree.h"
  37. #include "../Graphics/VertexBuffer.h"
  38. #include "../IO/Log.h"
  39. #include "../Resource/ResourceCache.h"
  40. #include "../Resource/ResourceEvents.h"
  41. #include "../Scene/Scene.h"
  42. #include "../DebugNew.h"
  43. namespace Urho3D
  44. {
  45. extern const char* GEOMETRY_CATEGORY;
  46. static const StringVector animationStatesStructureElementNames =
  47. {
  48. "Anim State Count",
  49. " Animation",
  50. " Start Bone",
  51. " Is Looped",
  52. " Weight",
  53. " Time",
  54. " Layer"
  55. };
  56. static bool CompareAnimationOrder(const SharedPtr<AnimationState>& lhs, const SharedPtr<AnimationState>& rhs)
  57. {
  58. return lhs->GetLayer() < rhs->GetLayer();
  59. }
  60. static const unsigned MAX_ANIMATION_STATES = 256;
  61. AnimatedModel::AnimatedModel(Context* context) :
  62. StaticModel(context),
  63. animationLodFrameNumber_(0),
  64. morphElementMask_(0),
  65. animationLodBias_(1.0f),
  66. animationLodTimer_(-1.0f),
  67. animationLodDistance_(0.0f),
  68. updateInvisible_(false),
  69. animationDirty_(false),
  70. animationOrderDirty_(false),
  71. morphsDirty_(false),
  72. skinningDirty_(true),
  73. boneBoundingBoxDirty_(true),
  74. isMaster_(true),
  75. loading_(false),
  76. assignBonesPending_(false),
  77. forceAnimationUpdate_(false)
  78. {
  79. }
  80. AnimatedModel::~AnimatedModel()
  81. {
  82. // When being destroyed, remove the bone hierarchy if appropriate (last AnimatedModel in the node)
  83. Bone* rootBone = skeleton_.GetRootBone();
  84. if (rootBone && rootBone->node_)
  85. {
  86. Node* parent = rootBone->node_->GetParent();
  87. if (parent && !parent->GetComponent<AnimatedModel>())
  88. RemoveRootBone();
  89. }
  90. }
  91. void AnimatedModel::RegisterObject(Context* context)
  92. {
  93. context->RegisterFactory<AnimatedModel>(GEOMETRY_CATEGORY);
  94. URHO3D_ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
  95. URHO3D_MIXED_ACCESSOR_ATTRIBUTE("Model", GetModelAttr, SetModelAttr, ResourceRef, ResourceRef(Model::GetTypeStatic()), AM_DEFAULT);
  96. URHO3D_ACCESSOR_ATTRIBUTE("Material", GetMaterialsAttr, SetMaterialsAttr, ResourceRefList, ResourceRefList(Material::GetTypeStatic()),
  97. AM_DEFAULT);
  98. URHO3D_ATTRIBUTE("Is Occluder", bool, occluder_, false, AM_DEFAULT);
  99. URHO3D_ACCESSOR_ATTRIBUTE("Can Be Occluded", IsOccludee, SetOccludee, bool, true, AM_DEFAULT);
  100. URHO3D_ATTRIBUTE("Cast Shadows", bool, castShadows_, false, AM_DEFAULT);
  101. URHO3D_ACCESSOR_ATTRIBUTE("Update When Invisible", GetUpdateInvisible, SetUpdateInvisible, bool, false, AM_DEFAULT);
  102. URHO3D_ACCESSOR_ATTRIBUTE("Draw Distance", GetDrawDistance, SetDrawDistance, float, 0.0f, AM_DEFAULT);
  103. URHO3D_ACCESSOR_ATTRIBUTE("Shadow Distance", GetShadowDistance, SetShadowDistance, float, 0.0f, AM_DEFAULT);
  104. URHO3D_ACCESSOR_ATTRIBUTE("LOD Bias", GetLodBias, SetLodBias, float, 1.0f, AM_DEFAULT);
  105. URHO3D_ACCESSOR_ATTRIBUTE("Animation LOD Bias", GetAnimationLodBias, SetAnimationLodBias, float, 1.0f, AM_DEFAULT);
  106. URHO3D_COPY_BASE_ATTRIBUTES(Drawable);
  107. URHO3D_MIXED_ACCESSOR_ATTRIBUTE("Bone Animation Enabled", GetBonesEnabledAttr, SetBonesEnabledAttr, VariantVector,
  108. Variant::emptyVariantVector, AM_FILE | AM_NOEDIT);
  109. URHO3D_MIXED_ACCESSOR_ATTRIBUTE("Animation States", GetAnimationStatesAttr, SetAnimationStatesAttr,
  110. VariantVector, Variant::emptyVariantVector, AM_FILE)
  111. .SetMetadata(AttributeMetadata::P_VECTOR_STRUCT_ELEMENTS, animationStatesStructureElementNames);
  112. URHO3D_ACCESSOR_ATTRIBUTE("Morphs", GetMorphsAttr, SetMorphsAttr, PODVector<unsigned char>, Variant::emptyBuffer,
  113. AM_DEFAULT | AM_NOEDIT);
  114. }
  115. bool AnimatedModel::Load(Deserializer& source, bool setInstanceDefault)
  116. {
  117. loading_ = true;
  118. bool success = Component::Load(source, setInstanceDefault);
  119. loading_ = false;
  120. return success;
  121. }
  122. bool AnimatedModel::LoadXML(const XMLElement& source, bool setInstanceDefault)
  123. {
  124. loading_ = true;
  125. bool success = Component::LoadXML(source, setInstanceDefault);
  126. loading_ = false;
  127. return success;
  128. }
  129. bool AnimatedModel::LoadJSON(const JSONValue& source, bool setInstanceDefault)
  130. {
  131. loading_ = true;
  132. bool success = Component::LoadJSON(source, setInstanceDefault);
  133. loading_ = false;
  134. return success;
  135. }
  136. void AnimatedModel::ApplyAttributes()
  137. {
  138. if (assignBonesPending_)
  139. AssignBoneNodes();
  140. }
  141. void AnimatedModel::ProcessRayQuery(const RayOctreeQuery& query, PODVector<RayQueryResult>& results)
  142. {
  143. // If no bones or no bone-level testing, use the StaticModel test
  144. RayQueryLevel level = query.level_;
  145. if (level < RAY_TRIANGLE || !skeleton_.GetNumBones())
  146. {
  147. StaticModel::ProcessRayQuery(query, results);
  148. return;
  149. }
  150. // Check ray hit distance to AABB before proceeding with bone-level tests
  151. if (query.ray_.HitDistance(GetWorldBoundingBox()) >= query.maxDistance_)
  152. return;
  153. const Vector<Bone>& bones = skeleton_.GetBones();
  154. Sphere boneSphere;
  155. for (unsigned i = 0; i < bones.Size(); ++i)
  156. {
  157. const Bone& bone = bones[i];
  158. if (!bone.node_)
  159. continue;
  160. float distance;
  161. // Use hitbox if available
  162. if (bone.collisionMask_ & BONECOLLISION_BOX)
  163. {
  164. // Do an initial crude test using the bone's AABB
  165. const BoundingBox& box = bone.boundingBox_;
  166. const Matrix3x4& transform = bone.node_->GetWorldTransform();
  167. distance = query.ray_.HitDistance(box.Transformed(transform));
  168. if (distance >= query.maxDistance_)
  169. continue;
  170. if (level != RAY_AABB)
  171. {
  172. // Follow with an OBB test if required
  173. Matrix3x4 inverse = transform.Inverse();
  174. Ray localRay = query.ray_.Transformed(inverse);
  175. distance = localRay.HitDistance(box);
  176. if (distance >= query.maxDistance_)
  177. continue;
  178. }
  179. }
  180. else if (bone.collisionMask_ & BONECOLLISION_SPHERE)
  181. {
  182. boneSphere.center_ = bone.node_->GetWorldPosition();
  183. boneSphere.radius_ = bone.radius_;
  184. distance = query.ray_.HitDistance(boneSphere);
  185. if (distance >= query.maxDistance_)
  186. continue;
  187. }
  188. else
  189. continue;
  190. // If the code reaches here then we have a hit
  191. RayQueryResult result;
  192. result.position_ = query.ray_.origin_ + distance * query.ray_.direction_;
  193. result.normal_ = -query.ray_.direction_;
  194. result.distance_ = distance;
  195. result.drawable_ = this;
  196. result.node_ = node_;
  197. result.subObject_ = i;
  198. results.Push(result);
  199. }
  200. }
  201. void AnimatedModel::Update(const FrameInfo& frame)
  202. {
  203. // If node was invisible last frame, need to decide animation LOD distance here
  204. // If headless, retain the current animation distance (should be 0)
  205. if (frame.camera_ && abs((int)frame.frameNumber_ - (int)viewFrameNumber_) > 1)
  206. {
  207. // First check for no update at all when invisible. In that case reset LOD timer to ensure update
  208. // next time the model is in view
  209. if (!updateInvisible_)
  210. {
  211. if (animationDirty_)
  212. {
  213. animationLodTimer_ = -1.0f;
  214. forceAnimationUpdate_ = true;
  215. }
  216. return;
  217. }
  218. float distance = frame.camera_->GetDistance(node_->GetWorldPosition());
  219. // If distance is greater than draw distance, no need to update at all
  220. if (drawDistance_ > 0.0f && distance > drawDistance_)
  221. return;
  222. float scale = GetWorldBoundingBox().Size().DotProduct(DOT_SCALE);
  223. animationLodDistance_ = frame.camera_->GetLodDistance(distance, scale, lodBias_);
  224. }
  225. if (animationDirty_ || animationOrderDirty_)
  226. UpdateAnimation(frame);
  227. else if (boneBoundingBoxDirty_)
  228. UpdateBoneBoundingBox();
  229. }
  230. void AnimatedModel::UpdateBatches(const FrameInfo& frame)
  231. {
  232. const Matrix3x4& worldTransform = node_->GetWorldTransform();
  233. const BoundingBox& worldBoundingBox = GetWorldBoundingBox();
  234. distance_ = frame.camera_->GetDistance(worldBoundingBox.Center());
  235. // Note: per-geometry distances do not take skinning into account. Especially in case of a ragdoll they may be
  236. // much off base if the node's own transform is not updated
  237. if (batches_.Size() == 1)
  238. batches_[0].distance_ = distance_;
  239. else
  240. {
  241. for (unsigned i = 0; i < batches_.Size(); ++i)
  242. batches_[i].distance_ = frame.camera_->GetDistance(worldTransform * geometryData_[i].center_);
  243. }
  244. // Use a transformed version of the model's bounding box instead of world bounding box for LOD scale
  245. // determination so that animation does not change the scale
  246. BoundingBox transformedBoundingBox = boundingBox_.Transformed(worldTransform);
  247. float scale = transformedBoundingBox.Size().DotProduct(DOT_SCALE);
  248. float newLodDistance = frame.camera_->GetLodDistance(distance_, scale, lodBias_);
  249. // If model is rendered from several views, use the minimum LOD distance for animation LOD
  250. if (frame.frameNumber_ != animationLodFrameNumber_)
  251. {
  252. animationLodDistance_ = newLodDistance;
  253. animationLodFrameNumber_ = frame.frameNumber_;
  254. }
  255. else
  256. animationLodDistance_ = Min(animationLodDistance_, newLodDistance);
  257. if (newLodDistance != lodDistance_)
  258. {
  259. lodDistance_ = newLodDistance;
  260. CalculateLodLevels();
  261. }
  262. }
  263. void AnimatedModel::UpdateGeometry(const FrameInfo& frame)
  264. {
  265. // Late update in case the model came into view and animation was dirtied in the meanwhile
  266. if (forceAnimationUpdate_)
  267. {
  268. UpdateAnimation(frame);
  269. forceAnimationUpdate_ = false;
  270. }
  271. if (morphsDirty_)
  272. UpdateMorphs();
  273. if (skinningDirty_)
  274. UpdateSkinning();
  275. }
  276. UpdateGeometryType AnimatedModel::GetUpdateGeometryType()
  277. {
  278. if (morphsDirty_ || forceAnimationUpdate_)
  279. return UPDATE_MAIN_THREAD;
  280. else if (skinningDirty_)
  281. return UPDATE_WORKER_THREAD;
  282. else
  283. return UPDATE_NONE;
  284. }
  285. void AnimatedModel::DrawDebugGeometry(DebugRenderer* debug, bool depthTest)
  286. {
  287. if (debug && IsEnabledEffective())
  288. {
  289. debug->AddBoundingBox(GetWorldBoundingBox(), Color::GREEN, depthTest);
  290. debug->AddSkeleton(skeleton_, Color(0.75f, 0.75f, 0.75f), depthTest);
  291. }
  292. }
  293. void AnimatedModel::SetModel(Model* model, bool createBones)
  294. {
  295. if (model == model_)
  296. return;
  297. if (!node_)
  298. {
  299. URHO3D_LOGERROR("Can not set model while model component is not attached to a scene node");
  300. return;
  301. }
  302. // Unsubscribe from the reload event of previous model (if any), then subscribe to the new
  303. if (model_)
  304. UnsubscribeFromEvent(model_, E_RELOADFINISHED);
  305. model_ = model;
  306. if (model)
  307. {
  308. SubscribeToEvent(model, E_RELOADFINISHED, URHO3D_HANDLER(AnimatedModel, HandleModelReloadFinished));
  309. // Copy the subgeometry & LOD level structure
  310. SetNumGeometries(model->GetNumGeometries());
  311. const Vector<Vector<SharedPtr<Geometry> > >& geometries = model->GetGeometries();
  312. const PODVector<Vector3>& geometryCenters = model->GetGeometryCenters();
  313. for (unsigned i = 0; i < geometries.Size(); ++i)
  314. {
  315. geometries_[i] = geometries[i];
  316. geometryData_[i].center_ = geometryCenters[i];
  317. }
  318. // Copy geometry bone mappings
  319. const Vector<PODVector<unsigned> >& geometryBoneMappings = model->GetGeometryBoneMappings();
  320. geometryBoneMappings_.Clear();
  321. geometryBoneMappings_.Reserve(geometryBoneMappings.Size());
  322. for (unsigned i = 0; i < geometryBoneMappings.Size(); ++i)
  323. geometryBoneMappings_.Push(geometryBoneMappings[i]);
  324. // Copy morphs. Note: morph vertex buffers will be created later on-demand
  325. morphVertexBuffers_.Clear();
  326. morphs_.Clear();
  327. const Vector<ModelMorph>& morphs = model->GetMorphs();
  328. morphs_.Reserve(morphs.Size());
  329. morphElementMask_ = 0;
  330. for (unsigned i = 0; i < morphs.Size(); ++i)
  331. {
  332. ModelMorph newMorph;
  333. newMorph.name_ = morphs[i].name_;
  334. newMorph.nameHash_ = morphs[i].nameHash_;
  335. newMorph.weight_ = 0.0f;
  336. newMorph.buffers_ = morphs[i].buffers_;
  337. for (HashMap<unsigned, VertexBufferMorph>::ConstIterator j = morphs[i].buffers_.Begin();
  338. j != morphs[i].buffers_.End(); ++j)
  339. morphElementMask_ |= j->second_.elementMask_;
  340. morphs_.Push(newMorph);
  341. }
  342. // Copy bounding box & skeleton
  343. SetBoundingBox(model->GetBoundingBox());
  344. // Initial bone bounding box is just the one stored in the model
  345. boneBoundingBox_ = boundingBox_;
  346. boneBoundingBoxDirty_ = true;
  347. SetSkeleton(model->GetSkeleton(), createBones);
  348. ResetLodLevels();
  349. // Reserve space for skinning matrices
  350. skinMatrices_.Resize(skeleton_.GetNumBones());
  351. SetGeometryBoneMappings();
  352. // Enable skinning in batches
  353. for (unsigned i = 0; i < batches_.Size(); ++i)
  354. {
  355. if (skinMatrices_.Size())
  356. {
  357. batches_[i].geometryType_ = GEOM_SKINNED;
  358. // Check if model has per-geometry bone mappings
  359. if (geometrySkinMatrices_.Size() && geometrySkinMatrices_[i].Size())
  360. {
  361. batches_[i].worldTransform_ = &geometrySkinMatrices_[i][0];
  362. batches_[i].numWorldTransforms_ = geometrySkinMatrices_[i].Size();
  363. }
  364. // If not, use the global skin matrices
  365. else
  366. {
  367. batches_[i].worldTransform_ = &skinMatrices_[0];
  368. batches_[i].numWorldTransforms_ = skinMatrices_.Size();
  369. }
  370. }
  371. else
  372. {
  373. batches_[i].geometryType_ = GEOM_STATIC;
  374. batches_[i].worldTransform_ = &node_->GetWorldTransform();
  375. batches_[i].numWorldTransforms_ = 1;
  376. }
  377. }
  378. }
  379. else
  380. {
  381. RemoveRootBone(); // Remove existing root bone if any
  382. SetNumGeometries(0);
  383. geometryBoneMappings_.Clear();
  384. morphVertexBuffers_.Clear();
  385. morphs_.Clear();
  386. morphElementMask_ = 0;
  387. SetBoundingBox(BoundingBox());
  388. SetSkeleton(Skeleton(), false);
  389. }
  390. MarkNetworkUpdate();
  391. }
  392. AnimationState* AnimatedModel::AddAnimationState(Animation* animation)
  393. {
  394. if (!isMaster_)
  395. {
  396. URHO3D_LOGERROR("Can not add animation state to non-master model");
  397. return nullptr;
  398. }
  399. if (!animation || !skeleton_.GetNumBones())
  400. return nullptr;
  401. // Check for not adding twice
  402. AnimationState* existing = GetAnimationState(animation);
  403. if (existing)
  404. return existing;
  405. SharedPtr<AnimationState> newState(new AnimationState(this, animation));
  406. animationStates_.Push(newState);
  407. MarkAnimationOrderDirty();
  408. return newState;
  409. }
  410. void AnimatedModel::RemoveAnimationState(Animation* animation)
  411. {
  412. if (animation)
  413. RemoveAnimationState(animation->GetNameHash());
  414. else
  415. {
  416. for (Vector<SharedPtr<AnimationState> >::Iterator i = animationStates_.Begin(); i != animationStates_.End(); ++i)
  417. {
  418. AnimationState* state = *i;
  419. if (!state->GetAnimation())
  420. {
  421. animationStates_.Erase(i);
  422. MarkAnimationDirty();
  423. return;
  424. }
  425. }
  426. }
  427. }
  428. void AnimatedModel::RemoveAnimationState(const String& animationName)
  429. {
  430. RemoveAnimationState(StringHash(animationName));
  431. }
  432. void AnimatedModel::RemoveAnimationState(StringHash animationNameHash)
  433. {
  434. for (Vector<SharedPtr<AnimationState> >::Iterator i = animationStates_.Begin(); i != animationStates_.End(); ++i)
  435. {
  436. AnimationState* state = *i;
  437. Animation* animation = state->GetAnimation();
  438. if (animation)
  439. {
  440. // Check both the animation and the resource name
  441. if (animation->GetNameHash() == animationNameHash || animation->GetAnimationNameHash() == animationNameHash)
  442. {
  443. animationStates_.Erase(i);
  444. MarkAnimationDirty();
  445. return;
  446. }
  447. }
  448. }
  449. }
  450. void AnimatedModel::RemoveAnimationState(AnimationState* state)
  451. {
  452. for (Vector<SharedPtr<AnimationState> >::Iterator i = animationStates_.Begin(); i != animationStates_.End(); ++i)
  453. {
  454. if (*i == state)
  455. {
  456. animationStates_.Erase(i);
  457. MarkAnimationDirty();
  458. return;
  459. }
  460. }
  461. }
  462. void AnimatedModel::RemoveAnimationState(unsigned index)
  463. {
  464. if (index < animationStates_.Size())
  465. {
  466. animationStates_.Erase(index);
  467. MarkAnimationDirty();
  468. }
  469. }
  470. void AnimatedModel::RemoveAllAnimationStates()
  471. {
  472. if (animationStates_.Size())
  473. {
  474. animationStates_.Clear();
  475. MarkAnimationDirty();
  476. }
  477. }
  478. void AnimatedModel::SetAnimationLodBias(float bias)
  479. {
  480. animationLodBias_ = Max(bias, 0.0f);
  481. MarkNetworkUpdate();
  482. }
  483. void AnimatedModel::SetUpdateInvisible(bool enable)
  484. {
  485. updateInvisible_ = enable;
  486. MarkNetworkUpdate();
  487. }
  488. void AnimatedModel::SetMorphWeight(unsigned index, float weight)
  489. {
  490. if (index >= morphs_.Size())
  491. return;
  492. // If morph vertex buffers have not been created yet, create now
  493. if (weight != 0.0f && morphVertexBuffers_.Empty())
  494. CloneGeometries();
  495. if (weight != morphs_[index].weight_)
  496. {
  497. morphs_[index].weight_ = weight;
  498. // For a master model, set the same morph weight on non-master models
  499. if (isMaster_)
  500. {
  501. PODVector<AnimatedModel*> models;
  502. GetComponents<AnimatedModel>(models);
  503. // Indexing might not be the same, so use the name hash instead
  504. for (unsigned i = 1; i < models.Size(); ++i)
  505. {
  506. if (!models[i]->isMaster_)
  507. models[i]->SetMorphWeight(morphs_[index].nameHash_, weight);
  508. }
  509. }
  510. MarkMorphsDirty();
  511. MarkNetworkUpdate();
  512. }
  513. }
  514. void AnimatedModel::SetMorphWeight(const String& name, float weight)
  515. {
  516. for (unsigned i = 0; i < morphs_.Size(); ++i)
  517. {
  518. if (morphs_[i].name_ == name)
  519. {
  520. SetMorphWeight(i, weight);
  521. return;
  522. }
  523. }
  524. }
  525. void AnimatedModel::SetMorphWeight(StringHash nameHash, float weight)
  526. {
  527. for (unsigned i = 0; i < morphs_.Size(); ++i)
  528. {
  529. if (morphs_[i].nameHash_ == nameHash)
  530. {
  531. SetMorphWeight(i, weight);
  532. return;
  533. }
  534. }
  535. }
  536. void AnimatedModel::ResetMorphWeights()
  537. {
  538. for (Vector<ModelMorph>::Iterator i = morphs_.Begin(); i != morphs_.End(); ++i)
  539. i->weight_ = 0.0f;
  540. // For a master model, reset weights on non-master models
  541. if (isMaster_)
  542. {
  543. PODVector<AnimatedModel*> models;
  544. GetComponents<AnimatedModel>(models);
  545. for (unsigned i = 1; i < models.Size(); ++i)
  546. {
  547. if (!models[i]->isMaster_)
  548. models[i]->ResetMorphWeights();
  549. }
  550. }
  551. MarkMorphsDirty();
  552. MarkNetworkUpdate();
  553. }
  554. float AnimatedModel::GetMorphWeight(unsigned index) const
  555. {
  556. return index < morphs_.Size() ? morphs_[index].weight_ : 0.0f;
  557. }
  558. float AnimatedModel::GetMorphWeight(const String& name) const
  559. {
  560. for (Vector<ModelMorph>::ConstIterator i = morphs_.Begin(); i != morphs_.End(); ++i)
  561. {
  562. if (i->name_ == name)
  563. return i->weight_;
  564. }
  565. return 0.0f;
  566. }
  567. float AnimatedModel::GetMorphWeight(StringHash nameHash) const
  568. {
  569. for (Vector<ModelMorph>::ConstIterator i = morphs_.Begin(); i != morphs_.End(); ++i)
  570. {
  571. if (i->nameHash_ == nameHash)
  572. return i->weight_;
  573. }
  574. return 0.0f;
  575. }
  576. AnimationState* AnimatedModel::GetAnimationState(Animation* animation) const
  577. {
  578. for (Vector<SharedPtr<AnimationState> >::ConstIterator i = animationStates_.Begin(); i != animationStates_.End(); ++i)
  579. {
  580. if ((*i)->GetAnimation() == animation)
  581. return *i;
  582. }
  583. return nullptr;
  584. }
  585. AnimationState* AnimatedModel::GetAnimationState(const String& animationName) const
  586. {
  587. return GetAnimationState(StringHash(animationName));
  588. }
  589. AnimationState* AnimatedModel::GetAnimationState(StringHash animationNameHash) const
  590. {
  591. for (Vector<SharedPtr<AnimationState> >::ConstIterator i = animationStates_.Begin(); i != animationStates_.End(); ++i)
  592. {
  593. Animation* animation = (*i)->GetAnimation();
  594. if (animation)
  595. {
  596. // Check both the animation and the resource name
  597. if (animation->GetNameHash() == animationNameHash || animation->GetAnimationNameHash() == animationNameHash)
  598. return *i;
  599. }
  600. }
  601. return nullptr;
  602. }
  603. AnimationState* AnimatedModel::GetAnimationState(unsigned index) const
  604. {
  605. return index < animationStates_.Size() ? animationStates_[index].Get() : nullptr;
  606. }
  607. void AnimatedModel::SetSkeleton(const Skeleton& skeleton, bool createBones)
  608. {
  609. if (!node_ && createBones)
  610. {
  611. URHO3D_LOGERROR("AnimatedModel not attached to a scene node, can not create bone nodes");
  612. return;
  613. }
  614. if (isMaster_)
  615. {
  616. // Check if bone structure has stayed compatible (reloading the model.) In that case retain the old bones and animations
  617. if (skeleton_.GetNumBones() == skeleton.GetNumBones())
  618. {
  619. Vector<Bone>& destBones = skeleton_.GetModifiableBones();
  620. const Vector<Bone>& srcBones = skeleton.GetBones();
  621. bool compatible = true;
  622. for (unsigned i = 0; i < destBones.Size(); ++i)
  623. {
  624. if (destBones[i].node_ && destBones[i].name_ == srcBones[i].name_ && destBones[i].parentIndex_ ==
  625. srcBones[i].parentIndex_)
  626. {
  627. // If compatible, just copy the values and retain the old node and animated status
  628. Node* boneNode = destBones[i].node_;
  629. bool animated = destBones[i].animated_;
  630. destBones[i] = srcBones[i];
  631. destBones[i].node_ = boneNode;
  632. destBones[i].animated_ = animated;
  633. }
  634. else
  635. {
  636. compatible = false;
  637. break;
  638. }
  639. }
  640. if (compatible)
  641. return;
  642. }
  643. RemoveAllAnimationStates();
  644. // Detach the rootbone of the previous model if any
  645. if (createBones)
  646. RemoveRootBone();
  647. skeleton_.Define(skeleton);
  648. // Merge bounding boxes from non-master models
  649. FinalizeBoneBoundingBoxes();
  650. Vector<Bone>& bones = skeleton_.GetModifiableBones();
  651. // Create scene nodes for the bones
  652. if (createBones)
  653. {
  654. for (Vector<Bone>::Iterator i = bones.Begin(); i != bones.End(); ++i)
  655. {
  656. // Create bones as local, as they are never to be directly synchronized over the network
  657. Node* boneNode = node_->CreateChild(i->name_, LOCAL);
  658. boneNode->AddListener(this);
  659. boneNode->SetTransform(i->initialPosition_, i->initialRotation_, i->initialScale_);
  660. // Copy the model component's temporary status
  661. boneNode->SetTemporary(IsTemporary());
  662. i->node_ = boneNode;
  663. }
  664. for (unsigned i = 0; i < bones.Size(); ++i)
  665. {
  666. unsigned parentIndex = bones[i].parentIndex_;
  667. if (parentIndex != i && parentIndex < bones.Size())
  668. bones[parentIndex].node_->AddChild(bones[i].node_);
  669. }
  670. }
  671. using namespace BoneHierarchyCreated;
  672. VariantMap& eventData = GetEventDataMap();
  673. eventData[P_NODE] = node_;
  674. node_->SendEvent(E_BONEHIERARCHYCREATED, eventData);
  675. }
  676. else
  677. {
  678. // For non-master models: use the bone nodes of the master model
  679. skeleton_.Define(skeleton);
  680. // Instruct the master model to refresh (merge) its bone bounding boxes
  681. auto* master = node_->GetComponent<AnimatedModel>();
  682. if (master && master != this)
  683. master->FinalizeBoneBoundingBoxes();
  684. if (createBones)
  685. {
  686. Vector<Bone>& bones = skeleton_.GetModifiableBones();
  687. for (Vector<Bone>::Iterator i = bones.Begin(); i != bones.End(); ++i)
  688. {
  689. Node* boneNode = node_->GetChild(i->name_, true);
  690. if (boneNode)
  691. boneNode->AddListener(this);
  692. i->node_ = boneNode;
  693. }
  694. }
  695. }
  696. assignBonesPending_ = !createBones;
  697. }
  698. void AnimatedModel::SetModelAttr(const ResourceRef& value)
  699. {
  700. auto* cache = GetSubsystem<ResourceCache>();
  701. // When loading a scene, set model without creating the bone nodes (will be assigned later during post-load)
  702. SetModel(cache->GetResource<Model>(value.name_), !loading_);
  703. }
  704. void AnimatedModel::SetBonesEnabledAttr(const VariantVector& value)
  705. {
  706. Vector<Bone>& bones = skeleton_.GetModifiableBones();
  707. for (unsigned i = 0; i < bones.Size() && i < value.Size(); ++i)
  708. bones[i].animated_ = value[i].GetBool();
  709. }
  710. void AnimatedModel::SetAnimationStatesAttr(const VariantVector& value)
  711. {
  712. auto* cache = GetSubsystem<ResourceCache>();
  713. RemoveAllAnimationStates();
  714. unsigned index = 0;
  715. unsigned numStates = index < value.Size() ? value[index++].GetUInt() : 0;
  716. // Prevent negative or overly large value being assigned from the editor
  717. if (numStates > M_MAX_INT)
  718. numStates = 0;
  719. if (numStates > MAX_ANIMATION_STATES)
  720. numStates = MAX_ANIMATION_STATES;
  721. animationStates_.Reserve(numStates);
  722. while (numStates--)
  723. {
  724. if (index + 5 < value.Size())
  725. {
  726. // Note: null animation is allowed here for editing
  727. const ResourceRef& animRef = value[index++].GetResourceRef();
  728. SharedPtr<AnimationState> newState(new AnimationState(this, cache->GetResource<Animation>(animRef.name_)));
  729. animationStates_.Push(newState);
  730. newState->SetStartBone(skeleton_.GetBone(value[index++].GetString()));
  731. newState->SetLooped(value[index++].GetBool());
  732. newState->SetWeight(value[index++].GetFloat());
  733. newState->SetTime(value[index++].GetFloat());
  734. newState->SetLayer((unsigned char)value[index++].GetInt());
  735. }
  736. else
  737. {
  738. // If not enough data, just add an empty animation state
  739. SharedPtr<AnimationState> newState(new AnimationState(this, nullptr));
  740. animationStates_.Push(newState);
  741. }
  742. }
  743. if (animationStates_.Size())
  744. {
  745. MarkAnimationDirty();
  746. MarkAnimationOrderDirty();
  747. }
  748. }
  749. void AnimatedModel::SetMorphsAttr(const PODVector<unsigned char>& value)
  750. {
  751. for (unsigned index = 0; index < value.Size(); ++index)
  752. SetMorphWeight(index, (float)value[index] / 255.0f);
  753. }
  754. ResourceRef AnimatedModel::GetModelAttr() const
  755. {
  756. return GetResourceRef(model_, Model::GetTypeStatic());
  757. }
  758. VariantVector AnimatedModel::GetBonesEnabledAttr() const
  759. {
  760. VariantVector ret;
  761. const Vector<Bone>& bones = skeleton_.GetBones();
  762. ret.Reserve(bones.Size());
  763. for (Vector<Bone>::ConstIterator i = bones.Begin(); i != bones.End(); ++i)
  764. ret.Push(i->animated_);
  765. return ret;
  766. }
  767. VariantVector AnimatedModel::GetAnimationStatesAttr() const
  768. {
  769. VariantVector ret;
  770. ret.Reserve(animationStates_.Size() * 6 + 1);
  771. ret.Push(animationStates_.Size());
  772. for (Vector<SharedPtr<AnimationState> >::ConstIterator i = animationStates_.Begin(); i != animationStates_.End(); ++i)
  773. {
  774. AnimationState* state = *i;
  775. Animation* animation = state->GetAnimation();
  776. Bone* startBone = state->GetStartBone();
  777. ret.Push(GetResourceRef(animation, Animation::GetTypeStatic()));
  778. ret.Push(startBone ? startBone->name_ : String::EMPTY);
  779. ret.Push(state->IsLooped());
  780. ret.Push(state->GetWeight());
  781. ret.Push(state->GetTime());
  782. ret.Push((int)state->GetLayer());
  783. }
  784. return ret;
  785. }
  786. const PODVector<unsigned char>& AnimatedModel::GetMorphsAttr() const
  787. {
  788. attrBuffer_.Clear();
  789. for (Vector<ModelMorph>::ConstIterator i = morphs_.Begin(); i != morphs_.End(); ++i)
  790. attrBuffer_.WriteUByte((unsigned char)(i->weight_ * 255.0f));
  791. return attrBuffer_.GetBuffer();
  792. }
  793. void AnimatedModel::UpdateBoneBoundingBox()
  794. {
  795. if (skeleton_.GetNumBones())
  796. {
  797. // The bone bounding box is in local space, so need the node's inverse transform
  798. boneBoundingBox_.Clear();
  799. Matrix3x4 inverseNodeTransform = node_->GetWorldTransform().Inverse();
  800. const Vector<Bone>& bones = skeleton_.GetBones();
  801. for (Vector<Bone>::ConstIterator i = bones.Begin(); i != bones.End(); ++i)
  802. {
  803. Node* boneNode = i->node_;
  804. if (!boneNode)
  805. continue;
  806. // Use hitbox if available. If not, use only half of the sphere radius
  807. /// \todo The sphere radius should be multiplied with bone scale
  808. if (i->collisionMask_ & BONECOLLISION_BOX)
  809. boneBoundingBox_.Merge(i->boundingBox_.Transformed(inverseNodeTransform * boneNode->GetWorldTransform()));
  810. else if (i->collisionMask_ & BONECOLLISION_SPHERE)
  811. boneBoundingBox_.Merge(Sphere(inverseNodeTransform * boneNode->GetWorldPosition(), i->radius_ * 0.5f));
  812. }
  813. }
  814. boneBoundingBoxDirty_ = false;
  815. worldBoundingBoxDirty_ = true;
  816. }
  817. void AnimatedModel::OnNodeSet(Node* node)
  818. {
  819. Drawable::OnNodeSet(node);
  820. if (node)
  821. {
  822. // If this AnimatedModel is the first in the node, it is the master which controls animation & morphs
  823. isMaster_ = GetComponent<AnimatedModel>() == this;
  824. }
  825. }
  826. void AnimatedModel::OnMarkedDirty(Node* node)
  827. {
  828. Drawable::OnMarkedDirty(node);
  829. // If the scene node or any of the bone nodes move, mark skinning dirty
  830. if (skeleton_.GetNumBones())
  831. {
  832. skinningDirty_ = true;
  833. // Bone bounding box doesn't need to be marked dirty when only the base scene node moves
  834. if (node != node_)
  835. boneBoundingBoxDirty_ = true;
  836. }
  837. }
  838. void AnimatedModel::OnWorldBoundingBoxUpdate()
  839. {
  840. if (isMaster_)
  841. {
  842. // Note: do not update bone bounding box here, instead do it in either of the threaded updates
  843. worldBoundingBox_ = boneBoundingBox_.Transformed(node_->GetWorldTransform());
  844. }
  845. else
  846. {
  847. // Non-master animated models get the bounding box from the master
  848. /// \todo If it's a skinned attachment that does not cover the whole body, it will have unnecessarily large bounds
  849. auto* master = node_->GetComponent<AnimatedModel>();
  850. // Check if we've become the new master model in case the original was deleted
  851. if (master == this)
  852. isMaster_ = true;
  853. if (master)
  854. worldBoundingBox_ = master->GetWorldBoundingBox();
  855. }
  856. }
  857. void AnimatedModel::AssignBoneNodes()
  858. {
  859. assignBonesPending_ = false;
  860. if (!node_)
  861. return;
  862. // Find the bone nodes from the node hierarchy and add listeners
  863. Vector<Bone>& bones = skeleton_.GetModifiableBones();
  864. bool boneFound = false;
  865. for (Vector<Bone>::Iterator i = bones.Begin(); i != bones.End(); ++i)
  866. {
  867. Node* boneNode = node_->GetChild(i->name_, true);
  868. if (boneNode)
  869. {
  870. boneFound = true;
  871. boneNode->AddListener(this);
  872. }
  873. i->node_ = boneNode;
  874. }
  875. // If no bones found, this may be a prefab where the bone information was left out.
  876. // In that case reassign the skeleton now if possible
  877. if (!boneFound && model_)
  878. SetSkeleton(model_->GetSkeleton(), true);
  879. // Re-assign the same start bone to animations to get the proper bone node this time
  880. for (Vector<SharedPtr<AnimationState> >::Iterator i = animationStates_.Begin(); i != animationStates_.End(); ++i)
  881. {
  882. AnimationState* state = *i;
  883. state->SetStartBone(state->GetStartBone());
  884. }
  885. }
  886. void AnimatedModel::FinalizeBoneBoundingBoxes()
  887. {
  888. Vector<Bone>& bones = skeleton_.GetModifiableBones();
  889. PODVector<AnimatedModel*> models;
  890. GetComponents<AnimatedModel>(models);
  891. if (models.Size() > 1)
  892. {
  893. // Reset first to the model resource's original bone bounding information if available (should be)
  894. if (model_)
  895. {
  896. const Vector<Bone>& modelBones = model_->GetSkeleton().GetBones();
  897. for (unsigned i = 0; i < bones.Size() && i < modelBones.Size(); ++i)
  898. {
  899. bones[i].collisionMask_ = modelBones[i].collisionMask_;
  900. bones[i].radius_ = modelBones[i].radius_;
  901. bones[i].boundingBox_ = modelBones[i].boundingBox_;
  902. }
  903. }
  904. // Get matching bones from all non-master models and merge their bone bounding information
  905. // to prevent culling errors (master model may not have geometry in all bones, or the bounds are smaller)
  906. for (PODVector<AnimatedModel*>::Iterator i = models.Begin(); i != models.End(); ++i)
  907. {
  908. if ((*i) == this)
  909. continue;
  910. Skeleton& otherSkeleton = (*i)->GetSkeleton();
  911. for (Vector<Bone>::Iterator j = bones.Begin(); j != bones.End(); ++j)
  912. {
  913. Bone* otherBone = otherSkeleton.GetBone(j->nameHash_);
  914. if (otherBone)
  915. {
  916. if (otherBone->collisionMask_ & BONECOLLISION_SPHERE)
  917. {
  918. j->collisionMask_ |= BONECOLLISION_SPHERE;
  919. j->radius_ = Max(j->radius_, otherBone->radius_);
  920. }
  921. if (otherBone->collisionMask_ & BONECOLLISION_BOX)
  922. {
  923. j->collisionMask_ |= BONECOLLISION_BOX;
  924. if (j->boundingBox_.Defined())
  925. j->boundingBox_.Merge(otherBone->boundingBox_);
  926. else
  927. j->boundingBox_.Define(otherBone->boundingBox_);
  928. }
  929. }
  930. }
  931. }
  932. }
  933. // Remove collision information from dummy bones that do not affect skinning, to prevent them from being merged
  934. // to the bounding box and making it artificially large
  935. for (Vector<Bone>::Iterator i = bones.Begin(); i != bones.End(); ++i)
  936. {
  937. if (i->collisionMask_ & BONECOLLISION_BOX && i->boundingBox_.Size().Length() < M_EPSILON)
  938. i->collisionMask_ &= ~BONECOLLISION_BOX;
  939. if (i->collisionMask_ & BONECOLLISION_SPHERE && i->radius_ < M_EPSILON)
  940. i->collisionMask_ &= ~BONECOLLISION_SPHERE;
  941. }
  942. }
  943. void AnimatedModel::RemoveRootBone()
  944. {
  945. Bone* rootBone = skeleton_.GetRootBone();
  946. if (rootBone && rootBone->node_)
  947. rootBone->node_->Remove();
  948. }
  949. void AnimatedModel::MarkAnimationDirty()
  950. {
  951. if (isMaster_)
  952. {
  953. animationDirty_ = true;
  954. MarkForUpdate();
  955. }
  956. }
  957. void AnimatedModel::MarkAnimationOrderDirty()
  958. {
  959. if (isMaster_)
  960. {
  961. animationOrderDirty_ = true;
  962. MarkForUpdate();
  963. }
  964. }
  965. void AnimatedModel::MarkMorphsDirty()
  966. {
  967. morphsDirty_ = true;
  968. }
  969. void AnimatedModel::CloneGeometries()
  970. {
  971. const Vector<SharedPtr<VertexBuffer> >& originalVertexBuffers = model_->GetVertexBuffers();
  972. HashMap<VertexBuffer*, SharedPtr<VertexBuffer> > clonedVertexBuffers;
  973. morphVertexBuffers_.Resize(originalVertexBuffers.Size());
  974. for (unsigned i = 0; i < originalVertexBuffers.Size(); ++i)
  975. {
  976. VertexBuffer* original = originalVertexBuffers[i];
  977. if (model_->GetMorphRangeCount(i))
  978. {
  979. SharedPtr<VertexBuffer> clone(new VertexBuffer(context_));
  980. clone->SetShadowed(true);
  981. clone->SetSize(original->GetVertexCount(), morphElementMask_ & original->GetElementMask(), true);
  982. void* dest = clone->Lock(0, original->GetVertexCount());
  983. if (dest)
  984. {
  985. CopyMorphVertices(dest, original->GetShadowData(), original->GetVertexCount(), clone, original);
  986. clone->Unlock();
  987. }
  988. clonedVertexBuffers[original] = clone;
  989. morphVertexBuffers_[i] = clone;
  990. }
  991. else
  992. morphVertexBuffers_[i].Reset();
  993. }
  994. // Geometries will always be cloned fully. They contain only references to buffer, so they are relatively light
  995. for (unsigned i = 0; i < geometries_.Size(); ++i)
  996. {
  997. for (unsigned j = 0; j < geometries_[i].Size(); ++j)
  998. {
  999. SharedPtr<Geometry> original = geometries_[i][j];
  1000. SharedPtr<Geometry> clone(new Geometry(context_));
  1001. // Add an additional vertex stream into the clone, which supplies only the morphable vertex data, while the static
  1002. // data comes from the original vertex buffer(s)
  1003. const Vector<SharedPtr<VertexBuffer> >& originalBuffers = original->GetVertexBuffers();
  1004. unsigned totalBuf = originalBuffers.Size();
  1005. for (unsigned k = 0; k < originalBuffers.Size(); ++k)
  1006. {
  1007. VertexBuffer* originalBuffer = originalBuffers[k];
  1008. if (clonedVertexBuffers.Contains(originalBuffer))
  1009. ++totalBuf;
  1010. }
  1011. clone->SetNumVertexBuffers(totalBuf);
  1012. unsigned l = 0;
  1013. for (unsigned k = 0; k < originalBuffers.Size(); ++k)
  1014. {
  1015. VertexBuffer* originalBuffer = originalBuffers[k];
  1016. if (clonedVertexBuffers.Contains(originalBuffer))
  1017. {
  1018. VertexBuffer* clonedBuffer = clonedVertexBuffers[originalBuffer];
  1019. clone->SetVertexBuffer(l++, originalBuffer);
  1020. // Specify the morph buffer at a greater index to override the model's original positions/normals/tangents
  1021. clone->SetVertexBuffer(l++, clonedBuffer);
  1022. }
  1023. else
  1024. clone->SetVertexBuffer(l++, originalBuffer);
  1025. }
  1026. clone->SetIndexBuffer(original->GetIndexBuffer());
  1027. clone->SetDrawRange(original->GetPrimitiveType(), original->GetIndexStart(), original->GetIndexCount());
  1028. clone->SetLodDistance(original->GetLodDistance());
  1029. geometries_[i][j] = clone;
  1030. }
  1031. }
  1032. // Make sure the rendering batches use the new cloned geometries
  1033. ResetLodLevels();
  1034. MarkMorphsDirty();
  1035. }
  1036. void AnimatedModel::CopyMorphVertices(void* destVertexData, void* srcVertexData, unsigned vertexCount, VertexBuffer* destBuffer,
  1037. VertexBuffer* srcBuffer)
  1038. {
  1039. unsigned mask = destBuffer->GetElementMask() & srcBuffer->GetElementMask();
  1040. unsigned normalOffset = srcBuffer->GetElementOffset(SEM_NORMAL);
  1041. unsigned tangentOffset = srcBuffer->GetElementOffset(SEM_TANGENT);
  1042. unsigned vertexSize = srcBuffer->GetVertexSize();
  1043. auto* dest = (float*)destVertexData;
  1044. auto* src = (unsigned char*)srcVertexData;
  1045. while (vertexCount--)
  1046. {
  1047. if (mask & MASK_POSITION)
  1048. {
  1049. auto* posSrc = (float*)src;
  1050. dest[0] = posSrc[0];
  1051. dest[1] = posSrc[1];
  1052. dest[2] = posSrc[2];
  1053. dest += 3;
  1054. }
  1055. if (mask & MASK_NORMAL)
  1056. {
  1057. auto* normalSrc = (float*)(src + normalOffset);
  1058. dest[0] = normalSrc[0];
  1059. dest[1] = normalSrc[1];
  1060. dest[2] = normalSrc[2];
  1061. dest += 3;
  1062. }
  1063. if (mask & MASK_TANGENT)
  1064. {
  1065. auto* tangentSrc = (float*)(src + tangentOffset);
  1066. dest[0] = tangentSrc[0];
  1067. dest[1] = tangentSrc[1];
  1068. dest[2] = tangentSrc[2];
  1069. dest[3] = tangentSrc[3];
  1070. dest += 4;
  1071. }
  1072. src += vertexSize;
  1073. }
  1074. }
  1075. void AnimatedModel::SetGeometryBoneMappings()
  1076. {
  1077. geometrySkinMatrices_.Clear();
  1078. geometrySkinMatrixPtrs_.Clear();
  1079. if (!geometryBoneMappings_.Size())
  1080. return;
  1081. // Check if all mappings are empty, then we do not need to use mapped skinning
  1082. bool allEmpty = true;
  1083. for (unsigned i = 0; i < geometryBoneMappings_.Size(); ++i)
  1084. if (geometryBoneMappings_[i].Size())
  1085. allEmpty = false;
  1086. if (allEmpty)
  1087. return;
  1088. // Reserve space for per-geometry skinning matrices
  1089. geometrySkinMatrices_.Resize(geometryBoneMappings_.Size());
  1090. for (unsigned i = 0; i < geometryBoneMappings_.Size(); ++i)
  1091. geometrySkinMatrices_[i].Resize(geometryBoneMappings_[i].Size());
  1092. // Build original-to-skinindex matrix pointer mapping for fast copying
  1093. // Note: at this point layout of geometrySkinMatrices_ cannot be modified or pointers become invalid
  1094. geometrySkinMatrixPtrs_.Resize(skeleton_.GetNumBones());
  1095. for (unsigned i = 0; i < geometryBoneMappings_.Size(); ++i)
  1096. {
  1097. for (unsigned j = 0; j < geometryBoneMappings_[i].Size(); ++j)
  1098. geometrySkinMatrixPtrs_[geometryBoneMappings_[i][j]].Push(&geometrySkinMatrices_[i][j]);
  1099. }
  1100. }
  1101. void AnimatedModel::UpdateAnimation(const FrameInfo& frame)
  1102. {
  1103. // If using animation LOD, accumulate time and see if it is time to update
  1104. if (animationLodBias_ > 0.0f && animationLodDistance_ > 0.0f)
  1105. {
  1106. // Perform the first update always regardless of LOD timer
  1107. if (animationLodTimer_ >= 0.0f)
  1108. {
  1109. animationLodTimer_ += animationLodBias_ * frame.timeStep_ * ANIMATION_LOD_BASESCALE;
  1110. if (animationLodTimer_ >= animationLodDistance_)
  1111. animationLodTimer_ = fmodf(animationLodTimer_, animationLodDistance_);
  1112. else
  1113. return;
  1114. }
  1115. else
  1116. animationLodTimer_ = 0.0f;
  1117. }
  1118. ApplyAnimation();
  1119. }
  1120. void AnimatedModel::ApplyAnimation()
  1121. {
  1122. // Make sure animations are in ascending priority order
  1123. if (animationOrderDirty_)
  1124. {
  1125. Sort(animationStates_.Begin(), animationStates_.End(), CompareAnimationOrder);
  1126. animationOrderDirty_ = false;
  1127. }
  1128. // Reset skeleton, apply all animations, calculate bones' bounding box. Make sure this is only done for the master model
  1129. // (first AnimatedModel in a node)
  1130. if (isMaster_)
  1131. {
  1132. skeleton_.ResetSilent();
  1133. for (Vector<SharedPtr<AnimationState> >::Iterator i = animationStates_.Begin(); i != animationStates_.End(); ++i)
  1134. (*i)->Apply();
  1135. // Skeleton reset and animations apply the node transforms "silently" to avoid repeated marking dirty. Mark dirty now
  1136. node_->MarkDirty();
  1137. // Calculate new bone bounding box
  1138. UpdateBoneBoundingBox();
  1139. }
  1140. animationDirty_ = false;
  1141. }
  1142. void AnimatedModel::UpdateSkinning()
  1143. {
  1144. // Note: the model's world transform will be baked in the skin matrices
  1145. const Vector<Bone>& bones = skeleton_.GetBones();
  1146. // Use model's world transform in case a bone is missing
  1147. const Matrix3x4& worldTransform = node_->GetWorldTransform();
  1148. // Skinning with global matrices only
  1149. if (!geometrySkinMatrices_.Size())
  1150. {
  1151. for (unsigned i = 0; i < bones.Size(); ++i)
  1152. {
  1153. const Bone& bone = bones[i];
  1154. if (bone.node_)
  1155. skinMatrices_[i] = bone.node_->GetWorldTransform() * bone.offsetMatrix_;
  1156. else
  1157. skinMatrices_[i] = worldTransform;
  1158. }
  1159. }
  1160. // Skinning with per-geometry matrices
  1161. else
  1162. {
  1163. for (unsigned i = 0; i < bones.Size(); ++i)
  1164. {
  1165. const Bone& bone = bones[i];
  1166. if (bone.node_)
  1167. skinMatrices_[i] = bone.node_->GetWorldTransform() * bone.offsetMatrix_;
  1168. else
  1169. skinMatrices_[i] = worldTransform;
  1170. // Copy the skin matrix to per-geometry matrices as needed
  1171. for (unsigned j = 0; j < geometrySkinMatrixPtrs_[i].Size(); ++j)
  1172. *geometrySkinMatrixPtrs_[i][j] = skinMatrices_[i];
  1173. }
  1174. }
  1175. skinningDirty_ = false;
  1176. }
  1177. void AnimatedModel::UpdateMorphs()
  1178. {
  1179. auto* graphics = GetSubsystem<Graphics>();
  1180. if (!graphics)
  1181. return;
  1182. if (morphs_.Size())
  1183. {
  1184. // Reset the morph data range from all morphable vertex buffers, then apply morphs
  1185. for (unsigned i = 0; i < morphVertexBuffers_.Size(); ++i)
  1186. {
  1187. VertexBuffer* buffer = morphVertexBuffers_[i];
  1188. if (buffer)
  1189. {
  1190. VertexBuffer* originalBuffer = model_->GetVertexBuffers()[i];
  1191. unsigned morphStart = model_->GetMorphRangeStart(i);
  1192. unsigned morphCount = model_->GetMorphRangeCount(i);
  1193. void* dest = buffer->Lock(morphStart, morphCount);
  1194. if (dest)
  1195. {
  1196. // Reset morph range by copying data from the original vertex buffer
  1197. CopyMorphVertices(dest, originalBuffer->GetShadowData() + morphStart * originalBuffer->GetVertexSize(),
  1198. morphCount, buffer, originalBuffer);
  1199. for (unsigned j = 0; j < morphs_.Size(); ++j)
  1200. {
  1201. if (morphs_[j].weight_ != 0.0f)
  1202. {
  1203. HashMap<unsigned, VertexBufferMorph>::Iterator k = morphs_[j].buffers_.Find(i);
  1204. if (k != morphs_[j].buffers_.End())
  1205. ApplyMorph(buffer, dest, morphStart, k->second_, morphs_[j].weight_);
  1206. }
  1207. }
  1208. buffer->Unlock();
  1209. }
  1210. }
  1211. }
  1212. }
  1213. morphsDirty_ = false;
  1214. }
  1215. void AnimatedModel::ApplyMorph(VertexBuffer* buffer, void* destVertexData, unsigned morphRangeStart, const VertexBufferMorph& morph,
  1216. float weight)
  1217. {
  1218. unsigned elementMask = morph.elementMask_ & buffer->GetElementMask();
  1219. unsigned vertexCount = morph.vertexCount_;
  1220. unsigned normalOffset = buffer->GetElementOffset(SEM_NORMAL);
  1221. unsigned tangentOffset = buffer->GetElementOffset(SEM_TANGENT);
  1222. unsigned vertexSize = buffer->GetVertexSize();
  1223. unsigned char* srcData = morph.morphData_;
  1224. auto* destData = (unsigned char*)destVertexData;
  1225. while (vertexCount--)
  1226. {
  1227. unsigned vertexIndex = *((unsigned*)srcData) - morphRangeStart;
  1228. srcData += sizeof(unsigned);
  1229. if (elementMask & MASK_POSITION)
  1230. {
  1231. auto* dest = (float*)(destData + vertexIndex * vertexSize);
  1232. auto* src = (float*)srcData;
  1233. dest[0] += src[0] * weight;
  1234. dest[1] += src[1] * weight;
  1235. dest[2] += src[2] * weight;
  1236. srcData += 3 * sizeof(float);
  1237. }
  1238. if (elementMask & MASK_NORMAL)
  1239. {
  1240. auto* dest = (float*)(destData + vertexIndex * vertexSize + normalOffset);
  1241. auto* src = (float*)srcData;
  1242. dest[0] += src[0] * weight;
  1243. dest[1] += src[1] * weight;
  1244. dest[2] += src[2] * weight;
  1245. srcData += 3 * sizeof(float);
  1246. }
  1247. if (elementMask & MASK_TANGENT)
  1248. {
  1249. auto* dest = (float*)(destData + vertexIndex * vertexSize + tangentOffset);
  1250. auto* src = (float*)srcData;
  1251. dest[0] += src[0] * weight;
  1252. dest[1] += src[1] * weight;
  1253. dest[2] += src[2] * weight;
  1254. srcData += 3 * sizeof(float);
  1255. }
  1256. }
  1257. }
  1258. void AnimatedModel::HandleModelReloadFinished(StringHash eventType, VariantMap& eventData)
  1259. {
  1260. Model* currentModel = model_;
  1261. model_.Reset(); // Set null to allow to be re-set
  1262. SetModel(currentModel);
  1263. }
  1264. }