13 #include <ThirdParty/glm/glm/gtc/matrix_transform.hpp> 21 if (scene->HasAnimations()) {
27 boneData.resize(0xff, { glm::mat4() });
36 for (
unsigned int i = 0; i < scene->mNumAnimations; ++i) {
38 animation->
name = eastl::string(scene->mAnimations[i]->mName.C_Str());
39 animation->
duration =
static_cast<float>(scene->mAnimations[i]->mDuration);
40 animation->
ticksPerSecond =
static_cast<float>(scene->mAnimations[i]->mTicksPerSecond);
48 for (
unsigned int j = 0; j < scene->mAnimations[i]->mNumChannels; ++j) {
50 aiNodeAnim* node = scene->mAnimations[i]->mChannels[j];
52 eastl::map<eastl::string, Bone_t*>::iterator it =
boneMap.find(eastl::string(node->mNodeName.C_Str()));
55 animationNode.
bone = it->second;
58 std::cout <<
"[ERROR] Animation using bones not contained in skeleton" << std::endl;
62 animationNode.
positionKeys.resize(node->mNumPositionKeys);
63 animationNode.
rotationKeys.resize(node->mNumRotationKeys);
64 animationNode.
scalingKeys.resize(node->mNumScalingKeys);
66 for (
unsigned int k = 0; k < node->mNumPositionKeys; ++k) {
68 key.
time =
static_cast<float>(node->mPositionKeys[k].mTime);
69 key.
position = glm::vec3(node->mPositionKeys[k].mValue.x,
70 node->mPositionKeys[k].mValue.y,
71 node->mPositionKeys[k].mValue.z);
76 for (
unsigned int k = 0; k < node->mNumRotationKeys; ++k) {
78 key.
time =
static_cast<float>(node->mRotationKeys[k].mTime);
80 key.
rotation.x = node->mRotationKeys[k].mValue.x;
81 key.
rotation.y = node->mRotationKeys[k].mValue.y;
82 key.
rotation.z = node->mRotationKeys[k].mValue.z;
83 key.
rotation.w = node->mRotationKeys[k].mValue.w;
88 for (
unsigned int k = 0; k < node->mNumScalingKeys; ++k) {
90 key.
time =
static_cast<float>(node->mScalingKeys[k].mTime);
91 key.
scale = glm::vec3(node->mScalingKeys[k].mValue.x,
92 node->mScalingKeys[k].mValue.y,
93 node->mScalingKeys[k].mValue.z);
101 animation->
nodes.push_back(animationNode);
105 eastl::vector<float> animationBuffer;
111 animationBuffer.resize(static_cast<size_t>(animation->
duration) * 3 * 256 * 4);
113 size_t currentRow = 0;
122 for (
size_t j = 0, size =
boneData.size(); j < size; ++j) {
123 glm::mat4 transform =
boneData[j].transform;
125 glm::vec4 translate = transform[3];
126 transform[3] = glm::vec4(0.f, 0.f, 0.f, 1.f);
128 glm::vec3 scale = glm::vec3(
129 glm::length(glm::vec3(transform[0][0], transform[0][1], transform[0][2])),
130 glm::length(glm::vec3(transform[1][0], transform[1][1], transform[1][2])),
131 glm::length(glm::vec3(transform[2][0], transform[2][1], transform[2][2]))
134 transform[0][0] /= scale.x;
135 transform[0][1] /= scale.x;
136 transform[0][2] /= scale.x;
137 transform[1][0] /= scale.y;
138 transform[1][1] /= scale.y;
139 transform[1][2] /= scale.y;
140 transform[2][0] /= scale.z;
141 transform[2][1] /= scale.z;
142 transform[2][2] /= scale.z;
144 glm::quat rotation = glm::quat_cast(transform);
146 animationBuffer[(currentRow * 256 * 4) + j * 4] = translate.x;
147 animationBuffer[(currentRow * 256 * 4) + j * 4 + 1] = translate.y;
148 animationBuffer[(currentRow * 256 * 4) + j * 4 + 2] = translate.z;
149 animationBuffer[(currentRow * 256 * 4) + j * 4 + 3] = translate.w;
151 animationBuffer[((currentRow + 1) * 256 * 4) + j * 4] = scale.x;
152 animationBuffer[((currentRow + 1) * 256 * 4) + j * 4 + 1] = scale.y;
153 animationBuffer[((currentRow + 1) * 256 * 4) + j * 4 + 2] = scale.z;
155 animationBuffer[((currentRow + 2) * 256 * 4) + j * 4] = rotation.x;
156 animationBuffer[((currentRow + 2) * 256 * 4) + j * 4 + 1] = rotation.y;
157 animationBuffer[((currentRow + 2) * 256 * 4) + j * 4 + 2] = rotation.z;
158 animationBuffer[((currentRow + 2) * 256 * 4) + j * 4 + 3] = rotation.w;
166 animation->
texture = eastl::shared_ptr<VulkanTexture>(
new VulkanTexture(256, static_cast<int>(animation->
duration * 3.f)));
169 VkSamplerCreateInfo samplerInfo = {};
170 samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
171 samplerInfo.magFilter = VK_FILTER_NEAREST;
172 samplerInfo.minFilter = VK_FILTER_NEAREST;
173 samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
174 samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
175 samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
176 samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
177 samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
178 samplerInfo.anisotropyEnable = VK_FALSE;
179 samplerInfo.compareEnable = VK_FALSE;
180 samplerInfo.unnormalizedCoordinates = VK_TRUE;
182 eastl::static_pointer_cast<VulkanTexture,
Texture>(animation->
texture)->SetSampler(samplerInfo);
185 animation->
texture = eastl::shared_ptr<OpenGLTexture>(
new OpenGLTexture(256, static_cast<int>(animation->
duration * 3.f)));
198 if (scene->HasAnimations()) {
200 for (
unsigned int i = 0; i < scene->mNumAnimations; ++i) {
202 if (names.size() > i) {
203 animation->
name = names[i];
204 if(animation->
name==
"")
205 animation->
name = eastl::string(scene->mAnimations[i]->mName.C_Str());
208 animation->
name = eastl::string(scene->mAnimations[i]->mName.C_Str());
210 animation->
duration =
static_cast<float>(scene->mAnimations[i]->mDuration);
211 animation->
ticksPerSecond =
static_cast<float>(scene->mAnimations[i]->mTicksPerSecond);
219 for (
unsigned int j = 0; j < scene->mAnimations[i]->mNumChannels; ++j) {
221 aiNodeAnim* node = scene->mAnimations[i]->mChannels[j];
223 eastl::map<eastl::string, Bone_t*>::iterator it =
boneMap.find(eastl::string(node->mNodeName.C_Str()));
226 animationNode.
bone = it->second;
229 std::cout <<
"[ERROR] Animation using bones not contained in skeleton" << std::endl;
233 animationNode.
positionKeys.resize(node->mNumPositionKeys);
234 animationNode.
rotationKeys.resize(node->mNumRotationKeys);
235 animationNode.
scalingKeys.resize(node->mNumScalingKeys);
237 for (
unsigned int k = 0; k < node->mNumPositionKeys; ++k) {
239 key.
time =
static_cast<float>(node->mPositionKeys[k].mTime);
240 key.
position = glm::vec3(node->mPositionKeys[k].mValue.x,
241 node->mPositionKeys[k].mValue.y,
242 node->mPositionKeys[k].mValue.z);
247 for (
unsigned int k = 0; k < node->mNumRotationKeys; ++k) {
249 key.
time =
static_cast<float>(node->mRotationKeys[k].mTime);
251 key.
rotation.x = node->mRotationKeys[k].mValue.x;
252 key.
rotation.y = node->mRotationKeys[k].mValue.y;
253 key.
rotation.z = node->mRotationKeys[k].mValue.z;
254 key.
rotation.w = node->mRotationKeys[k].mValue.w;
259 for (
unsigned int k = 0; k < node->mNumScalingKeys; ++k) {
261 key.
time =
static_cast<float>(node->mScalingKeys[k].mTime);
262 key.
scale = glm::vec3(node->mScalingKeys[k].mValue.x,
263 node->mScalingKeys[k].mValue.y,
264 node->mScalingKeys[k].mValue.z);
272 animation->
nodes.push_back(animationNode);
276 eastl::vector<float> animationBuffer;
282 animationBuffer.resize(static_cast<size_t>(animation->
duration) * 3 * 256 * 4);
284 size_t currentRow = 0;
293 for (
size_t i = 0, size =
boneData.size(); i < size; ++i) {
294 glm::mat4 transform =
boneData[i].transform;
296 glm::vec4 translate = transform[3];
297 transform[3] = glm::vec4(0.f, 0.f, 0.f, 1.f);
299 glm::vec3 scale = glm::vec3(
300 glm::length(glm::vec3(transform[0][0], transform[0][1], transform[0][2])),
301 glm::length(glm::vec3(transform[1][0], transform[1][1], transform[1][2])),
302 glm::length(glm::vec3(transform[2][0], transform[2][1], transform[2][2]))
305 transform[0][0] /= scale.x;
306 transform[0][1] /= scale.x;
307 transform[0][2] /= scale.x;
308 transform[1][0] /= scale.y;
309 transform[1][1] /= scale.y;
310 transform[1][2] /= scale.y;
311 transform[2][0] /= scale.z;
312 transform[2][1] /= scale.z;
313 transform[2][2] /= scale.z;
315 glm::quat rotation = glm::quat_cast(transform);
317 animationBuffer[(currentRow * 256 * 4) + i * 4] = translate.x;
318 animationBuffer[(currentRow * 256 * 4) + i * 4 + 1] = translate.y;
319 animationBuffer[(currentRow * 256 * 4) + i * 4 + 2] = translate.z;
320 animationBuffer[(currentRow * 256 * 4) + i * 4 + 3] = translate.w;
322 animationBuffer[((currentRow + 1) * 256 * 4) + i * 4] = scale.x;
323 animationBuffer[((currentRow + 1) * 256 * 4) + i * 4 + 1] = scale.y;
324 animationBuffer[((currentRow + 1) * 256 * 4) + i * 4 + 2] = scale.z;
326 animationBuffer[((currentRow + 2) * 256 * 4) + i * 4] = rotation.x;
327 animationBuffer[((currentRow + 2) * 256 * 4) + i * 4 + 1] = rotation.y;
328 animationBuffer[((currentRow + 2) * 256 * 4) + i * 4 + 2] = rotation.z;
329 animationBuffer[((currentRow + 2) * 256 * 4) + i * 4 + 3] = rotation.w;
337 animation->
texture = eastl::shared_ptr<VulkanTexture>(
new VulkanTexture(256, static_cast<int>(animation->
duration * 3.f)));
340 VkSamplerCreateInfo samplerInfo = {};
341 samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
342 samplerInfo.magFilter = VK_FILTER_NEAREST;
343 samplerInfo.minFilter = VK_FILTER_NEAREST;
344 samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
345 samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
346 samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
347 samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
348 samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
349 samplerInfo.anisotropyEnable = VK_FALSE;
350 samplerInfo.compareEnable = VK_FALSE;
351 samplerInfo.unnormalizedCoordinates = VK_TRUE;
353 eastl::static_pointer_cast<VulkanTexture,
Texture>(animation->
texture)->SetSampler(samplerInfo);
356 animation->
texture = eastl::shared_ptr<OpenGLTexture>(
new OpenGLTexture(256, static_cast<int>(animation->
duration * 3.f)));
364 std::cout <<
"[WARNING] No animations detected in file" << std::endl;
371 for each (eastl::pair<eastl::string, Bone_t*> bone
in boneMap)
375 for (
size_t i = 0, size =
animations.size(); i < size; ++i) {
383 eastl::vector<eastl::string> names;
384 for each (eastl::pair<eastl::string, size_t> animation
in animationMap)
386 names.push_back(animation.first);
393 eastl::map<eastl::string, size_t>::iterator it =
animationMap.find(animation);
426 size_t frameIndex = 0;
427 for (
size_t i = 0, size = node.
scalingKeys.size(); i < size - 1; ++i) {
443 float delta = (time - currFrame.
time) / (nextFrame.
time - currFrame.
time);
445 delta = fmaxf(0.f, fminf(delta, 1.f));
447 scale = glm::mix(currFrame.
scale, nextFrame.
scale, delta);
449 return glm::scale(glm::mat4(), scale);
462 size_t frameIndex = 0;
463 for (
size_t i = 0, size = node.
rotationKeys.size(); i < size - 1; ++i) {
479 float delta = (time - currFrame.
time) / (nextFrame.
time - currFrame.
time);
481 delta = fmaxf(0.f, fminf(delta, 1.f));
487 return glm::mat4_cast(rotation);
500 size_t frameIndex = 0;
501 for (
size_t i = 0, size = node.
positionKeys.size(); i < size - 1; ++i) {
517 float delta = (time - currFrame.
time) / (nextFrame.
time - currFrame.
time);
519 delta = fmaxf(0.f, fminf(delta, 1.f));
523 return glm::translate(glm::mat4(), position);
559 for each (eastl::pair<eastl::string, Bone_t*> bone
in boneMap)
561 bone.second->transform = bone.second->defaultTransform;
585 eastl::map<eastl::string, size_t>::iterator it =
animationMap.find(animation);
627 bone->
childBones.resize(static_cast<size_t>(node->mNumChildren));
629 bone->
name = eastl::string(node->mName.C_Str());
642 for (
size_t i = 0, size = bone->
childBones.size(); i < size; ++i) {
652 for (
size_t i = 0, size = bone->
childBones.size(); i < size; ++i) {
660 eastl::map<eastl::string, Bone_t*>::iterator it =
boneMap.find(bone);
673 if (bone->
parent !=
nullptr) {
680 for (
size_t i = 0, size = bone->
childBones.size(); i < size; ++i) {
686 return glm::mat4(transform.a1, transform.b1, transform.c1, transform.d1,
687 transform.a2, transform.b2, transform.c2, transform.d2,
688 transform.a3, transform.b3, transform.c3, transform.d3,
689 transform.a4, transform.b4, transform.c4, transform.d4);
This object is used to store information regarding a texture. NOTE: Only the resource manager is allo...
Texture * GetAnimationData(size_t animation)
Returns a texture containing the animation snapshots for the current animation.
size_t GetAnimationIndex(eastl::string animation)
Returns a texture containing the animation snapshots for the current animation.
eastl::vector< struct Bone * > childBones
eastl::vector< AnimationScalingKey_t > scalingKeys
glm::mat4 TransformToMat4(aiMatrix4x4 transform)
eastl::vector< BoneData_t > boneData
Bone_t * GetRootBone()
Returns the root bone of the skeleton.
void UpdateBoneTreeTransformData()
size_t currentAnimationIndex
eastl::map< eastl::string, Bone_t * > boneMap
void SetAnimation(eastl::string animation, bool resetTime)
Sets the current animation of the mesh.
eastl::vector< Animation_t * > animations
void UpdateBoneTransformData(Bone_t *bone)
eastl::vector< AnimationPositionKey_t > positionKeys
glm::mat4 defaultTransform
glm::mat4 InterpolateRotation(float time, AnimationNode_t node)
bool HasAnimations()
Whether or not any animations have been loaded.
void DestroyBone(Bone_t *bone)
float GetAnimationDuration(size_t animation)
Returns the duration of a single loop of the animation.
void SetName(eastl::string name)
Sets the name of the skeleton.
float GetAnimationTicksPerSecond(size_t animation)
Returns the number of animation ticks per second. This is equal to the number of animation snapshots ...
void SetBoneTransform(eastl::string bone, glm::mat4 transform)
Skeleton(const aiScene *scene)
Creates a new animation data object, loading in the animation data from the provided scene...
eastl::shared_ptr< Texture > texture
eastl::string GetName()
Returns the name of the skeleton (normally the path).
eastl::map< eastl::string, size_t > animationMap
void ReadBones(Bone_t *bone, aiNode *node)
struct Engine::Skeleton::Animation Animation_t
A structure containing information a bone.
struct Engine::Skeleton::Bone Bone_t
A structure containing information a bone.
virtual void UpdateBoneBuffers()
aiAnimBehaviour preAnimBehaviour
eastl::vector< AnimationRotationKey_t > rotationKeys
glm::mat4 InterpolateScale(float time, AnimationNode_t node)
void LoadAnimationSet(const aiScene *scene, eastl::vector< eastl::string > names={})
Loads in animation data form the provided scene. If the animation data does not match the skeleton of...
Animation_t * currentAnimation
eastl::vector< struct AnimationNode > nodes
virtual ~Skeleton()
Destroys the Data, cleaning up the bone tree.
glm::mat4 InterpolatePosition(float time, AnimationNode_t node)
aiAnimBehaviour postAnimBehaviour
eastl::map< eastl::string, Bone_t * > GetBoneMap()
Returns a map that uses the name of a bone as key to return the corresponding bone.
eastl::vector< eastl::string > GetAnimations()
Returns a list of the loaded animations as a vector of names. Use these names to load a specific anim...
void Update(float deltaTime)