1 /* Copyright (C) 2022 Wildfire Games.
2 * This file is part of 0 A.D.
4 * 0 A.D. is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
9 * 0 A.D. is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
19 * Owner of all skeleton animations
22 #include "precompiled.h"
24 #include "SkeletonAnimManager.h"
26 #include "graphics/ColladaManager.h"
27 #include "graphics/Model.h"
28 #include "graphics/SkeletonAnim.h"
29 #include "graphics/SkeletonAnimDef.h"
30 #include "ps/CLogger.h"
32 #include "ps/FileIo.h"
34 ///////////////////////////////////////////////////////////////////////////////
35 // CSkeletonAnimManager constructor
36 CSkeletonAnimManager::CSkeletonAnimManager(CColladaManager
& colladaManager
)
37 : m_ColladaManager(colladaManager
)
41 ///////////////////////////////////////////////////////////////////////////////
42 // CSkeletonAnimManager destructor
43 CSkeletonAnimManager::~CSkeletonAnimManager()
47 ///////////////////////////////////////////////////////////////////////////////
48 // GetAnimation: return a given animation by filename; return null if filename
49 // doesn't refer to valid animation file
50 CSkeletonAnimDef
* CSkeletonAnimManager::GetAnimation(const VfsPath
& pathname
)
52 VfsPath name
= pathname
.ChangeExtension(L
"");
54 // Find if it's already been loaded
55 std::unordered_map
<VfsPath
, std::unique_ptr
<CSkeletonAnimDef
>>::iterator iter
= m_Animations
.find(name
);
56 if (iter
!= m_Animations
.end())
57 return iter
->second
.get();
59 std::unique_ptr
<CSkeletonAnimDef
> def
;
61 // Find the file to load
62 VfsPath psaFilename
= m_ColladaManager
.GetLoadablePath(name
, CColladaManager::PSA
);
64 if (psaFilename
.empty())
65 LOGERROR("Could not load animation '%s'", pathname
.string8());
69 def
= CSkeletonAnimDef::Load(psaFilename
);
73 LOGERROR("Could not load animation '%s'", psaFilename
.string8());
77 LOGMESSAGE("CSkeletonAnimManager::GetAnimation(%s): Loaded successfully", pathname
.string8());
79 LOGERROR("CSkeletonAnimManager::GetAnimation(%s): Failed loading, marked file as bad", pathname
.string8());
81 // Add to map, NULL if failed to load - we won't try loading it again
82 return m_Animations
.insert_or_assign(name
, std::move(def
)).first
->second
.get();
86 * BuildAnimation: load raw animation frame animation from given file, and build a
87 * animation specific to this model
89 std::unique_ptr
<CSkeletonAnim
> CSkeletonAnimManager::BuildAnimation(const VfsPath
& pathname
, const CStr8
& name
, const CStr8
& ID
, int frequency
, float speed
, float actionpos
, float actionpos2
, float soundpos
)
91 CSkeletonAnimDef
* def
= GetAnimation(pathname
);
95 std::unique_ptr
<CSkeletonAnim
> anim
= std::make_unique
<CSkeletonAnim
>();
98 anim
->m_Frequency
= frequency
;
99 anim
->m_AnimDef
= def
;
100 anim
->m_Speed
= speed
;
102 if (actionpos
== -1.f
)
103 anim
->m_ActionPos
= -1.f
;
105 anim
->m_ActionPos
= actionpos
* anim
->m_AnimDef
->GetDuration();
107 if (actionpos2
== -1.f
)
108 anim
->m_ActionPos2
= -1.f
;
110 anim
->m_ActionPos2
= actionpos2
* anim
->m_AnimDef
->GetDuration();
112 if (soundpos
== -1.f
)
113 anim
->m_SoundPos
= -1.f
;
115 anim
->m_SoundPos
= soundpos
* anim
->m_AnimDef
->GetDuration();
117 anim
->m_ObjectBounds
.SetEmpty();