Divide Framework 0.1
A free and open-source 3D Framework under heavy development
Loading...
Searching...
No Matches
SceneAnimator.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2018 DIVIDE-Studio
3 Copyright (c) 2009 Ionut Cava
4
5 This file is part of DIVIDE Framework.
6
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software
9 and associated documentation files (the "Software"), to deal in the Software
10 without restriction,
11 including without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sublicense,
13 and/or sell copies of the Software, and to permit persons to whom the
14 Software is furnished to do so,
15 subject to the following conditions:
16
17 The above copyright notice and this permission notice shall be included in
18 all copies or substantial portions of the Software.
19
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 IMPLIED,
22 INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
23 PARTICULAR PURPOSE AND NONINFRINGEMENT.
24 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
25 DAMAGES OR OTHER LIABILITY,
26 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
27 IN CONNECTION WITH THE SOFTWARE
28 OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
30 */
31
32/*Code references:
33 http://nolimitsdesigns.com/game-design/open-asset-import-library-animation-loader/
34*/
35
36#pragma once
37#ifndef SCENE_ANIMATOR_H_
38#define SCENE_ANIMATOR_H_
39
40#include "AnimationEvaluator.h"
42
43struct aiMesh;
44struct aiNode;
45struct aiScene;
46
47namespace Divide {
48
49namespace Attorney {
50 class SceneAnimatorMeshImporter;
51};
52
54void CalculateBoneToWorldTransform(Bone* pInternalNode) noexcept;
55
56class Mesh;
57class ByteBuffer;
58class MeshImporter;
59class PlatformContext;
60
61class AnimEvaluator;
62
65 public:
67 // index = frameIndex; entry = vectorIndex;
69 // index = animationID;
71
74 bool init(PlatformContext& context, Bone* skeleton, const vector<Bone*>& bones);
76 void release(bool releaseAnimations);
77 void save(PlatformContext& context, ByteBuffer& dataOut) const;
78 void load(PlatformContext& context, ByteBuffer& dataIn);
80 bool hasSkeleton() const noexcept { return _skeleton != nullptr; }
85 inline void playAnimationForward(const U32 animationIndex)
86 {
87 assert(animationIndex < _animations.size());
88
89 _animations[animationIndex]->playAnimationForward(true);
90 }
91
92 void playAnimationBackward(const U32 animationIndex)
93 {
94 assert( animationIndex < _animations.size() );
95 _animations[animationIndex]->playAnimationForward(false);
96 }
100 inline void adjustAnimationSpeedBy(const U32 animationIndex, const D64 percent)
101 {
102 assert( animationIndex < _animations.size() );
103 _animations[animationIndex]->ticksPerSecond( animationSpeed(animationIndex) * (percent / 100.0));
104 }
106 inline void adjustAnimationSpeedTo(const U32 animationIndex, const D64 ticksPerSecond)
107 {
108 assert( animationIndex < _animations.size() );
109 _animations[animationIndex]->ticksPerSecond(ticksPerSecond);
110 }
111
113 inline D64 animationSpeed(const U32 animationIndex) const
114 {
115 assert( animationIndex < _animations.size() );
116 return _animations[animationIndex]->ticksPerSecond();
117 }
118
121 inline AnimEvaluator::FrameIndex frameIndexForTimeStamp(const U32 animationIndex, const D64 dt) const
122 {
123 assert( animationIndex < _animations.size() );
124 return _animations[animationIndex]->frameIndexAt(dt);
125 }
126
127 inline const BoneTransform& transforms(const U32 animationIndex, const U32 index) const
128 {
129 assert( animationIndex < _animations.size() );
130 return _animations[animationIndex]->transforms(index);
131 }
132
133 inline const AnimEvaluator& animationByIndex(const U32 animationIndex) const
134 {
135 assert( animationIndex < _animations.size() );
136
137 const AnimEvaluator* animation = _animations[animationIndex].get();
138 assert(animation != nullptr);
139 return *animation;
140 }
141
142 inline AnimEvaluator& animationByIndex(const U32 animationIndex)
143 {
144 assert( animationIndex < _animations.size() );
145
146 AnimEvaluator* animation = _animations[animationIndex].get();
147 assert(animation != nullptr);
148 return *animation;
149 }
150
151 inline U32 frameCount(const U32 animationIndex) const
152 {
153 assert( animationIndex < _animations.size() );
154 return _animations[animationIndex]->frameCount();
155 }
156
157 inline const vector<std::unique_ptr<AnimEvaluator>>& animations() const noexcept
158 {
159 return _animations;
160 }
161
162 inline const string& animationName(const U32 animationIndex) const
163 {
164 assert( animationIndex < _animations.size() );
165
166 return _animations[animationIndex]->name();
167 }
168
170 {
172 if (itr != std::end(_animationNameToID))
173 {
174 return itr->second;
175 }
176
177 return U32_MAX;
178 }
182 inline const mat4<F32>& boneTransform(const U32 animationIndex, const D64 dt, const string& bName)
183 {
184 const I32 boneID = boneIndex(bName);
185 if (boneID != -1)
186 {
187 return boneTransform(animationIndex, dt, boneID);
188 }
189
191 return _boneTransformCache;
192 }
193
195 inline const mat4<F32>& boneTransform(const U32 animationIndex, const D64 dt, const I32 bIndex)
196 {
197 if (bIndex != -1)
198 {
199 assert( animationIndex < _animations.size() );
200 return _animations[animationIndex]->transforms(dt).matrices()[bIndex];
201 }
202
204 return _boneTransformCache;
205 }
206
208 inline const mat4<F32>& boneOffsetTransform(const string& bName)
209 {
210 const Bone* bone = boneByName(bName);
211 if (bone != nullptr)
212 {
213 _boneTransformCache = bone->offsetMatrix();
214 }
215
216 return _boneTransformCache;
217 }
218
219 Bone* boneByName(const string& name) const;
223 I32 boneIndex(const string& bName) const;
224 const vector<Line>& skeletonLines(U32 animationIndex, D64 dt);
225
227 inline U32 getMaxAnimationFrames() const noexcept
228 {
230 }
231
232 inline U8 boneCount() const noexcept
233 {
235 }
236
237 private:
238 bool init(PlatformContext& context);
239 void buildBuffers(GFXDevice& gfxDevice);
240
242 void saveSkeleton(ByteBuffer& dataOut, Bone* parent) const;
244
245 static void UpdateTransforms(Bone* pNode);
246 void calculate(U32 animationIndex, D64 pTime);
247 static I32 CreateSkeleton(Bone* piNode,
248 const mat4<F32>& parent,
249 vector<Line>& lines);
250
251 private:
255 Bone* _skeleton = nullptr;
265};
266
267namespace Attorney {
270 static void registerAnimations(SceneAnimator& animator, const vector<AnimEvaluator*>& animations)
271 {
272 const size_t animationCount = animations.size();
273 animator._animations.reserve(animationCount);
274 for (size_t i = 0; i < animationCount; ++i)
275 {
276 animator._animations.emplace_back(animations[i]);
277 insert(animator._animationNameToID, _ID(animator._animations[i]->name().c_str()), to_U32(i));
278 }
279 }
280
281 static void buildBuffers(SceneAnimator& animator, GFXDevice& gfxDevice) {
282 animator.buildBuffers(gfxDevice);
283 }
284
285 friend class Divide::Mesh;
287 };
288};
289
290}; // namespace Divide
291
292#endif // SCENE_ANIMATOR_H_
static void buildBuffers(SceneAnimator &animator, GFXDevice &gfxDevice)
static void registerAnimations(SceneAnimator &animator, const vector< AnimEvaluator * > &animations)
PASS OWNERSHIP OF ANIMATIONS TO THE ANIMATOR!!!
Rough around the edges Adapter pattern abstracting the actual rendering API and access to the GPU.
Definition: GFXDevice.h:215
static void UpdateTransforms(Bone *pNode)
U32 frameCount(const U32 animationIndex) const
U8 boneCount() const noexcept
vector< std::unique_ptr< AnimEvaluator > > _animations
A vector that holds each animation.
static I32 CreateSkeleton(Bone *piNode, const mat4< F32 > &parent, vector< Line > &lines)
Create animation skeleton.
const mat4< F32 > & boneTransform(const U32 animationIndex, const D64 dt, const string &bName)
AnimEvaluator & animationByIndex(const U32 animationIndex)
const BoneTransform & transforms(const U32 animationIndex, const U32 index) const
bool init(PlatformContext &context, Bone *skeleton, const vector< Bone * > &bones)
This will build the skeleton based on the scene passed to it and CLEAR EVERYTHING.
void playAnimationBackward(const U32 animationIndex)
Definition: SceneAnimator.h:92
const AnimEvaluator & animationByIndex(const U32 animationIndex) const
vector< LineMap > LineCollection
Definition: SceneAnimator.h:70
U32 _maximumAnimationFrames
Frame count of the longest registered animation.
AnimEvaluator::FrameIndex frameIndexForTimeStamp(const U32 animationIndex, const D64 dt) const
void calculate(U32 animationIndex, D64 pTime)
void save(PlatformContext &context, ByteBuffer &dataOut) const
Bone * loadSkeleton(ByteBuffer &dataIn, Bone *parent)
vector< I32 > LineMap
Definition: SceneAnimator.h:68
const vector< std::unique_ptr< AnimEvaluator > > & animations() const noexcept
void release(bool releaseAnimations)
Frees all memory and initializes everything to a default state.
vector< vector< Line > > _skeletonLinesContainer
const mat4< F32 > & boneTransform(const U32 animationIndex, const D64 dt, const I32 bIndex)
Same as above, except takes the index.
LineCollection _skeletonLines
Bone * boneByName(const string &name) const
const vector< Line > & skeletonLines(U32 animationIndex, D64 dt)
Renders the current skeleton pose at time index dt.
vector< Bone * > _bones
hashMap< U64, U32 > _animationNameToID
find animations quickly
I32 boneIndex(const string &bName) const
void adjustAnimationSpeedTo(const U32 animationIndex, const D64 ticksPerSecond)
This will set the animation speed.
void buildBuffers(GFXDevice &gfxDevice)
void adjustAnimationSpeedBy(const U32 animationIndex, const D64 percent)
U32 animationID(const string &animationName)
void saveSkeleton(ByteBuffer &dataOut, Bone *parent) const
I/O operations.
void playAnimationForward(const U32 animationIndex)
Definition: SceneAnimator.h:85
bool hasSkeleton() const noexcept
Lets the caller know if there is a skeleton present.
Definition: SceneAnimator.h:80
const mat4< F32 > & boneOffsetTransform(const string &bName)
Get the bone's global transform.
Bone * _skeleton
Root node of the internal scene structure.
U32 getMaxAnimationFrames() const noexcept
Returns the frame count of the longest registered animation.
mat4< F32 > _boneTransformCache
const string & animationName(const U32 animationIndex) const
D64 animationSpeed(const U32 animationIndex) const
Get the animation speed... in ticks per second.
void identity() noexcept
Handle console commands that start with a forward slash.
Definition: AIProcessor.cpp:7
bool load() override
constexpr U32 to_U32(const T value)
void insert(eastl::vector< T, A1 > &target, const eastl::vector< T, A2 > &source)
Definition: Vector.h:97
int32_t I32
uint8_t U8
int16_t I16
void CalculateBoneToWorldTransform(Bone *pInternalNode) noexcept
Calculates the global transformation matrix for the given internal node.
eastl::vector< Type > vector
Definition: Vector.h:42
hashAlg::unordered_map< K, V, HashFun, Predicate > hashMap
Definition: HashMap.h:55
Project & parent
Definition: DefaultScene.h:41
constexpr U64 _ID(const char *const str, const U64 value=val_64_const) noexcept
constexpr U8 to_U8(const T value)
constexpr U32 U32_MAX
double D64
uint32_t U32
constexpr U8 U8_ZERO