separate Gltf/Morph/BoneAnimationComponentManager definitions
move gltf animation instantiation to GltfAnimationComponentManager (this helps ensure we are creating the component on the correct entity)
This commit is contained in:
@@ -31,49 +31,93 @@ extern "C"
|
||||
EMSCRIPTEN_KEEPALIVE bool AnimationManager_addGltfAnimationComponent(TAnimationManager *tAnimationManager, TSceneAsset *tSceneAsset)
|
||||
{
|
||||
auto sceneAsset = reinterpret_cast<SceneAsset *>(tSceneAsset);
|
||||
if(sceneAsset->getType() != SceneAsset::SceneAssetType::Gltf || !sceneAsset->isInstance()) {
|
||||
if(sceneAsset->getType() != SceneAsset::SceneAssetType::Gltf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GltfSceneAssetInstance *instance;
|
||||
|
||||
if (sceneAsset->isInstance())
|
||||
{
|
||||
instance = reinterpret_cast<GltfSceneAssetInstance *>(sceneAsset);
|
||||
} else {
|
||||
instance = reinterpret_cast<GltfSceneAssetInstance *>(sceneAsset->getInstanceAt(0));
|
||||
}
|
||||
|
||||
auto animationManager = reinterpret_cast<AnimationManager *>(tAnimationManager);
|
||||
|
||||
animationManager->addGltfAnimationComponent(reinterpret_cast<GltfSceneAssetInstance *>(sceneAsset));
|
||||
animationManager->addGltfAnimationComponent(instance);
|
||||
return true;
|
||||
}
|
||||
EMSCRIPTEN_KEEPALIVE bool AnimationManager_removeGltfAnimationComponent(TAnimationManager *tAnimationManager, TSceneAsset *tSceneAsset)
|
||||
{
|
||||
auto sceneAsset = reinterpret_cast<SceneAsset *>(tSceneAsset);
|
||||
if(sceneAsset->getType() != SceneAsset::SceneAssetType::Gltf || !sceneAsset->isInstance()) {
|
||||
|
||||
if(sceneAsset->getType() != SceneAsset::SceneAssetType::Gltf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GltfSceneAssetInstance *instance;
|
||||
|
||||
if (sceneAsset->isInstance())
|
||||
{
|
||||
instance = reinterpret_cast<GltfSceneAssetInstance *>(sceneAsset);
|
||||
} else {
|
||||
instance = reinterpret_cast<GltfSceneAssetInstance *>(sceneAsset->getInstanceAt(0));
|
||||
}
|
||||
|
||||
|
||||
auto animationManager = reinterpret_cast<AnimationManager *>(tAnimationManager);
|
||||
animationManager->removeGltfAnimationComponent(reinterpret_cast<GltfSceneAssetInstance *>(sceneAsset));
|
||||
animationManager->removeGltfAnimationComponent(instance);
|
||||
return true;
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE bool AnimationManager_addBoneAnimationComponent(TAnimationManager *tAnimationManager, TSceneAsset *tSceneAsset)
|
||||
{
|
||||
auto sceneAsset = reinterpret_cast<SceneAsset *>(tSceneAsset);
|
||||
if(sceneAsset->getType() != SceneAsset::SceneAssetType::Gltf || !sceneAsset->isInstance()) {
|
||||
|
||||
if(sceneAsset->getType() != SceneAsset::SceneAssetType::Gltf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GltfSceneAssetInstance *instance;
|
||||
|
||||
if (sceneAsset->isInstance())
|
||||
{
|
||||
instance = reinterpret_cast<GltfSceneAssetInstance *>(sceneAsset);
|
||||
} else {
|
||||
instance = reinterpret_cast<GltfSceneAssetInstance *>(sceneAsset->getInstanceAt(0));
|
||||
}
|
||||
|
||||
auto animationManager = reinterpret_cast<AnimationManager *>(tAnimationManager);
|
||||
|
||||
animationManager->addBoneAnimationComponent(reinterpret_cast<GltfSceneAssetInstance *>(sceneAsset));
|
||||
animationManager->addBoneAnimationComponent(instance);
|
||||
return true;
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE bool AnimationManager_removeBoneAnimationComponent(TAnimationManager *tAnimationManager, TSceneAsset *tSceneAsset)
|
||||
{
|
||||
auto sceneAsset = reinterpret_cast<SceneAsset *>(tSceneAsset);
|
||||
if(sceneAsset->getType() != SceneAsset::SceneAssetType::Gltf || !sceneAsset->isInstance()) {
|
||||
if(sceneAsset->getType() != SceneAsset::SceneAssetType::Gltf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if(sceneAsset->getType() != SceneAsset::SceneAssetType::Gltf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GltfSceneAssetInstance *instance;
|
||||
|
||||
if (sceneAsset->isInstance())
|
||||
{
|
||||
instance = reinterpret_cast<GltfSceneAssetInstance *>(sceneAsset);
|
||||
} else {
|
||||
instance = reinterpret_cast<GltfSceneAssetInstance *>(sceneAsset->getInstanceAt(0));
|
||||
}
|
||||
|
||||
auto animationManager = reinterpret_cast<AnimationManager *>(tAnimationManager);
|
||||
animationManager->removeBoneAnimationComponent(reinterpret_cast<GltfSceneAssetInstance *>(sceneAsset));
|
||||
animationManager->removeBoneAnimationComponent(instance);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -124,15 +168,27 @@ extern "C"
|
||||
return true;
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void AnimationManager_resetToRestPose(TAnimationManager *tAnimationManager, TSceneAsset *sceneAsset)
|
||||
EMSCRIPTEN_KEEPALIVE void AnimationManager_resetToRestPose(TAnimationManager *tAnimationManager, TSceneAsset *tSceneAsset)
|
||||
{
|
||||
auto *animationManager = reinterpret_cast<AnimationManager *>(tAnimationManager);
|
||||
auto asset = reinterpret_cast<SceneAsset *>(sceneAsset);
|
||||
if (asset->getType() == SceneAsset::SceneAssetType::Gltf && asset->isInstance())
|
||||
{
|
||||
auto *instance = reinterpret_cast<GltfSceneAssetInstance *>(asset);
|
||||
animationManager->resetToRestPose(instance);
|
||||
auto sceneAsset = reinterpret_cast<SceneAsset *>(tSceneAsset);
|
||||
if (sceneAsset->getType() != SceneAsset::SceneAssetType::Gltf) {
|
||||
Log("Error - incorrect asset type, cannot reset to reset pose");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
GltfSceneAssetInstance *instance;
|
||||
|
||||
if (sceneAsset->isInstance())
|
||||
{
|
||||
instance = reinterpret_cast<GltfSceneAssetInstance *>(sceneAsset);
|
||||
} else {
|
||||
instance = reinterpret_cast<GltfSceneAssetInstance *>(sceneAsset->getInstanceAt(0));
|
||||
}
|
||||
|
||||
animationManager->resetToRestPose(instance);
|
||||
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE bool AnimationManager_addBoneAnimation(
|
||||
@@ -297,19 +353,31 @@ extern "C"
|
||||
return true;
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void AnimationManager_setGltfAnimationFrame(
|
||||
EMSCRIPTEN_KEEPALIVE bool AnimationManager_setGltfAnimationFrame(
|
||||
TAnimationManager *tAnimationManager,
|
||||
TSceneAsset *tSceneAsset,
|
||||
int animationIndex,
|
||||
int frame)
|
||||
{
|
||||
auto *animationManager = reinterpret_cast<AnimationManager *>(tAnimationManager);
|
||||
auto asset = reinterpret_cast<SceneAsset *>(tSceneAsset);
|
||||
if (asset->getType() == SceneAsset::SceneAssetType::Gltf && asset->isInstance())
|
||||
{
|
||||
auto *instance = reinterpret_cast<GltfSceneAssetInstance *>(asset);
|
||||
animationManager->setGltfAnimationFrame(instance, animationIndex, frame);
|
||||
auto sceneAsset = reinterpret_cast<SceneAsset *>(tSceneAsset);
|
||||
if (sceneAsset->getType() != SceneAsset::SceneAssetType::Gltf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GltfSceneAssetInstance *instance;
|
||||
|
||||
if (sceneAsset->isInstance())
|
||||
{
|
||||
instance = reinterpret_cast<GltfSceneAssetInstance *>(sceneAsset);
|
||||
} else {
|
||||
instance = reinterpret_cast<GltfSceneAssetInstance *>(sceneAsset->getInstanceAt(0));
|
||||
}
|
||||
|
||||
animationManager->setGltfAnimationFrame(instance, animationIndex, frame);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE float AnimationManager_getGltfAnimationDuration(
|
||||
@@ -320,7 +388,7 @@ extern "C"
|
||||
auto sceneAsset = reinterpret_cast<SceneAsset *>(tSceneAsset);
|
||||
|
||||
if(sceneAsset->getType() != SceneAsset::SceneAssetType::Gltf) {
|
||||
return false;
|
||||
return -1.0;
|
||||
}
|
||||
|
||||
auto animationManager = reinterpret_cast<AnimationManager *>(tAnimationManager);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <chrono>
|
||||
#include <variant>
|
||||
|
||||
#include "components/AnimationComponentManager.hpp"
|
||||
#include "components/BoneAnimationComponentManager.hpp"
|
||||
|
||||
#include "Log.hpp"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <chrono>
|
||||
#include <variant>
|
||||
|
||||
#include "components/AnimationComponentManager.hpp"
|
||||
#include "components/GltfAnimationComponentManager.hpp"
|
||||
|
||||
#include "Log.hpp"
|
||||
|
||||
@@ -15,9 +15,75 @@ namespace thermion
|
||||
}
|
||||
}
|
||||
|
||||
bool GltfAnimationComponentManager::addGltfAnimation(FilamentInstance *target, int index, bool loop, bool reverse, bool replaceActive, float crossfade, float startOffset) {
|
||||
|
||||
EntityInstanceBase::Type componentInstance = getInstance(target->getRoot());
|
||||
|
||||
auto &animationComponent = this->elementAt<0>(componentInstance);
|
||||
|
||||
animationComponent.target = target;
|
||||
|
||||
if (replaceActive)
|
||||
{
|
||||
if (animationComponent.animations.size() > 0)
|
||||
{
|
||||
auto &last = animationComponent.animations.back();
|
||||
animationComponent.fadeGltfAnimationIndex = last.index;
|
||||
animationComponent.fadeDuration = crossfade;
|
||||
auto now = high_resolution_clock::now();
|
||||
auto elapsedInSecs = float(std::chrono::duration_cast<std::chrono::milliseconds>(now - last.start).count()) / 1000.0f;
|
||||
animationComponent.fadeOutAnimationStart = elapsedInSecs;
|
||||
animationComponent.animations.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
animationComponent.fadeGltfAnimationIndex = -1;
|
||||
animationComponent.fadeDuration = 0.0f;
|
||||
}
|
||||
}
|
||||
else if (crossfade > 0)
|
||||
{
|
||||
Log("ERROR: crossfade only supported when replaceActive is true.");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
animationComponent.fadeGltfAnimationIndex = -1;
|
||||
animationComponent.fadeDuration = 0.0f;
|
||||
}
|
||||
|
||||
GltfAnimation animation;
|
||||
animation.startOffset = startOffset;
|
||||
animation.index = index;
|
||||
animation.start = std::chrono::high_resolution_clock::now();
|
||||
animation.loop = loop;
|
||||
animation.reverse = reverse;
|
||||
animation.durationInSecs = target->getAnimator()->getAnimationDuration(index);
|
||||
|
||||
bool found = false;
|
||||
|
||||
// don't play the animation if it's already running
|
||||
for (int i = 0; i < animationComponent.animations.size(); i++)
|
||||
{
|
||||
if (animationComponent.animations[i].index == index)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
animationComponent.animations.push_back(animation);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void GltfAnimationComponentManager::removeAnimationComponent(FilamentInstance *target) {
|
||||
if(hasComponent(target->getRoot())) {
|
||||
removeComponent(target->getRoot());
|
||||
TRACE("Found component, component removed");
|
||||
} else {
|
||||
TRACE("Component not found, skipping removal");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <chrono>
|
||||
#include <variant>
|
||||
|
||||
#include "components/AnimationComponentManager.hpp"
|
||||
#include "components/MorphAnimationComponentManager.hpp"
|
||||
|
||||
#include "Log.hpp"
|
||||
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
|
||||
#include "Log.hpp"
|
||||
|
||||
#include "components/AnimationComponentManager.hpp"
|
||||
#include "components/AnimationComponentManager.hpp"
|
||||
#include "scene/AnimationManager.hpp"
|
||||
#include "scene/SceneAsset.hpp"
|
||||
#include "scene/GltfSceneAssetInstance.hpp"
|
||||
@@ -334,71 +332,7 @@ namespace thermion
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_gltfAnimationComponentManager->hasComponent(instance->getEntity()))
|
||||
{
|
||||
_gltfAnimationComponentManager->addComponent(instance->getEntity());
|
||||
Log("ERROR: specified entity is not animatable (has no animation component attached).");
|
||||
return;
|
||||
}
|
||||
|
||||
auto animationComponentInstance = _gltfAnimationComponentManager->getInstance(instance->getEntity());
|
||||
|
||||
auto &animationComponent = _gltfAnimationComponentManager->elementAt<0>(animationComponentInstance);
|
||||
|
||||
animationComponent.target = instance->getInstance();
|
||||
|
||||
if (replaceActive)
|
||||
{
|
||||
if (animationComponent.animations.size() > 0)
|
||||
{
|
||||
auto &last = animationComponent.animations.back();
|
||||
animationComponent.fadeGltfAnimationIndex = last.index;
|
||||
animationComponent.fadeDuration = crossfade;
|
||||
auto now = high_resolution_clock::now();
|
||||
auto elapsedInSecs = float(std::chrono::duration_cast<std::chrono::milliseconds>(now - last.start).count()) / 1000.0f;
|
||||
animationComponent.fadeOutAnimationStart = elapsedInSecs;
|
||||
animationComponent.animations.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
animationComponent.fadeGltfAnimationIndex = -1;
|
||||
animationComponent.fadeDuration = 0.0f;
|
||||
}
|
||||
}
|
||||
else if (crossfade > 0)
|
||||
{
|
||||
Log("ERROR: crossfade only supported when replaceActive is true.");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
animationComponent.fadeGltfAnimationIndex = -1;
|
||||
animationComponent.fadeDuration = 0.0f;
|
||||
}
|
||||
|
||||
GltfAnimation animation;
|
||||
animation.startOffset = startOffset;
|
||||
animation.index = index;
|
||||
animation.start = std::chrono::high_resolution_clock::now();
|
||||
animation.loop = loop;
|
||||
animation.reverse = reverse;
|
||||
animation.durationInSecs = instance->getInstance()->getAnimator()->getAnimationDuration(index);
|
||||
|
||||
bool found = false;
|
||||
|
||||
// don't play the animation if it's already running
|
||||
for (int i = 0; i < animationComponent.animations.size(); i++)
|
||||
{
|
||||
if (animationComponent.animations[i].index == index)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
animationComponent.animations.push_back(animation);
|
||||
}
|
||||
_gltfAnimationComponentManager->addGltfAnimation(instance->getInstance(), index, loop, reverse, replaceActive, crossfade, startOffset);
|
||||
}
|
||||
|
||||
void AnimationManager::stopGltfAnimation(GltfSceneAssetInstance *instance, int index)
|
||||
@@ -515,35 +449,47 @@ namespace thermion
|
||||
|
||||
bool AnimationManager::addGltfAnimationComponent(GltfSceneAssetInstance *instance)
|
||||
{
|
||||
std::lock_guard lock(_mutex);
|
||||
_gltfAnimationComponentManager->addAnimationComponent(instance->getInstance());
|
||||
TRACE("Added glTF animation component");
|
||||
return true;
|
||||
}
|
||||
|
||||
void AnimationManager::removeGltfAnimationComponent(GltfSceneAssetInstance *instance)
|
||||
{
|
||||
std::lock_guard lock(_mutex);
|
||||
_gltfAnimationComponentManager->removeAnimationComponent(instance->getInstance());
|
||||
TRACE("Removed glTF animation component");
|
||||
}
|
||||
|
||||
bool AnimationManager::addBoneAnimationComponent(GltfSceneAssetInstance *instance)
|
||||
{
|
||||
std::lock_guard lock(_mutex);
|
||||
_boneAnimationComponentManager->addAnimationComponent(instance->getInstance());
|
||||
TRACE("Added bone animation component");
|
||||
return true;
|
||||
}
|
||||
|
||||
void AnimationManager::removeBoneAnimationComponent(GltfSceneAssetInstance *instance)
|
||||
{
|
||||
std::lock_guard lock(_mutex);
|
||||
_boneAnimationComponentManager->removeAnimationComponent(instance->getInstance());
|
||||
TRACE("Removed bone animation component");
|
||||
}
|
||||
|
||||
bool AnimationManager::addMorphAnimationComponent(utils::Entity entity)
|
||||
{
|
||||
std::lock_guard lock(_mutex);
|
||||
_morphAnimationComponentManager->addAnimationComponent(entity);
|
||||
TRACE("Added morph animation component");
|
||||
return true;
|
||||
}
|
||||
|
||||
void AnimationManager::removeMorphAnimationComponent(utils::Entity entity)
|
||||
{
|
||||
std::lock_guard lock(_mutex);
|
||||
_morphAnimationComponentManager->removeAnimationComponent(entity);
|
||||
TRACE("Removed morph animation component");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,19 +12,18 @@
|
||||
#include <filament/VertexBuffer.h>
|
||||
#include <filament/IndexBuffer.h>
|
||||
#include <gltfio/AssetLoader.h>
|
||||
#include <gltfio/Animator.h>
|
||||
#include <gltfio/FilamentAsset.h>
|
||||
#include <gltfio/FilamentInstance.h>
|
||||
#include <gltfio/MaterialProvider.h>
|
||||
|
||||
#include <utils/NameComponentManager.h>
|
||||
|
||||
#include "scene/GltfSceneAssetInstance.hpp"
|
||||
#include "components/AnimationComponentManager.hpp"
|
||||
#include "components/CollisionComponentManager.hpp"
|
||||
|
||||
#include "scene/SceneAsset.hpp"
|
||||
|
||||
|
||||
|
||||
namespace thermion
|
||||
{
|
||||
|
||||
|
||||
Reference in New Issue
Block a user