allow removing animation components and dont stash initial joint transforms when creating bone animations
This commit is contained in:
@@ -71,7 +71,6 @@ namespace flutter_filament
|
|||||||
struct BoneAnimation : AnimationStatus
|
struct BoneAnimation : AnimationStatus
|
||||||
{
|
{
|
||||||
size_t boneIndex;
|
size_t boneIndex;
|
||||||
std::vector<utils::Entity> meshTargets;
|
|
||||||
size_t skinIndex = 0;
|
size_t skinIndex = 0;
|
||||||
int lengthInFrames;
|
int lengthInFrames;
|
||||||
float frameLengthInMs = 0;
|
float frameLengthInMs = 0;
|
||||||
@@ -113,15 +112,15 @@ namespace flutter_filament
|
|||||||
if (std::holds_alternative<FilamentInstance *>(target))
|
if (std::holds_alternative<FilamentInstance *>(target))
|
||||||
{
|
{
|
||||||
auto instance = std::get<FilamentInstance *>(target);
|
auto instance = std::get<FilamentInstance *>(target);
|
||||||
const auto joints = instance->getJointsAt(0);
|
// const auto joints = instance->getJointsAt(0);
|
||||||
|
|
||||||
for (int i = 0; i < instance->getJointCountAt(0); i++)
|
// for (int i = 0; i < instance->getJointCountAt(0); i++)
|
||||||
{
|
// {
|
||||||
const auto joint = joints[i];
|
// const auto joint = joints[i];
|
||||||
const auto &jointTransformInstance = _transformManager.getInstance(joint);
|
// const auto &jointTransformInstance = _transformManager.getInstance(joint);
|
||||||
const auto &jointTransform = _transformManager.getTransform(jointTransformInstance);
|
// const auto &jointTransform = _transformManager.getTransform(jointTransformInstance);
|
||||||
animationComponent.initialJointTransforms.push_back(jointTransform);
|
// animationComponent.initialJointTransforms.push_back(jointTransform);
|
||||||
}
|
// }
|
||||||
componentInstance = addComponent(instance->getRoot());
|
componentInstance = addComponent(instance->getRoot());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -132,6 +131,26 @@ namespace flutter_filament
|
|||||||
this->elementAt<0>(componentInstance) = animationComponent;
|
this->elementAt<0>(componentInstance) = animationComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void removeAnimationComponent(std::variant<FilamentInstance *, Entity> target)
|
||||||
|
{
|
||||||
|
AnimationComponent animationComponent;
|
||||||
|
animationComponent.target = target;
|
||||||
|
EntityInstanceBase::Type componentInstance;
|
||||||
|
if (std::holds_alternative<FilamentInstance *>(target))
|
||||||
|
{
|
||||||
|
auto instance = std::get<FilamentInstance *>(target);
|
||||||
|
if(hasComponent(instance->getRoot())) {
|
||||||
|
removeComponent(instance->getRoot());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
auto entity = std::get<Entity>(target);
|
||||||
|
if(hasComponent(entity)) {
|
||||||
|
removeComponent(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void update()
|
void update()
|
||||||
{
|
{
|
||||||
auto now = high_resolution_clock::now();
|
auto now = high_resolution_clock::now();
|
||||||
@@ -152,34 +171,36 @@ namespace flutter_filament
|
|||||||
auto &gltfAnimations = animationComponent.gltfAnimations;
|
auto &gltfAnimations = animationComponent.gltfAnimations;
|
||||||
auto &boneAnimations = animationComponent.boneAnimations;
|
auto &boneAnimations = animationComponent.boneAnimations;
|
||||||
|
|
||||||
for (int i = ((int)gltfAnimations.size()) - 1; i >= 0; i--)
|
if(gltfAnimations.size() > 0) {
|
||||||
{
|
for (int i = ((int)gltfAnimations.size()) - 1; i >= 0; i--)
|
||||||
|
|
||||||
auto animationStatus = animationComponent.gltfAnimations[i];
|
|
||||||
|
|
||||||
auto elapsedInSecs = float(std::chrono::duration_cast<std::chrono::milliseconds>(now - animationStatus.start).count()) / 1000.0f;
|
|
||||||
|
|
||||||
if (!animationStatus.loop && elapsedInSecs >= animationStatus.durationInSecs)
|
|
||||||
{
|
{
|
||||||
animator->applyAnimation(animationStatus.index, animationStatus.durationInSecs - 0.001);
|
|
||||||
animator->updateBoneMatrices();
|
|
||||||
gltfAnimations.erase(gltfAnimations.begin() + i);
|
|
||||||
animationComponent.fadeGltfAnimationIndex = -1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
animator->applyAnimation(animationStatus.index, elapsedInSecs);
|
|
||||||
|
|
||||||
if (animationComponent.fadeGltfAnimationIndex != -1 && elapsedInSecs < animationComponent.fadeDuration)
|
auto animationStatus = animationComponent.gltfAnimations[i];
|
||||||
{
|
|
||||||
// cross-fade
|
auto elapsedInSecs = float(std::chrono::duration_cast<std::chrono::milliseconds>(now - animationStatus.start).count()) / 1000.0f;
|
||||||
auto fadeFromTime = animationComponent.fadeOutAnimationStart + elapsedInSecs;
|
|
||||||
auto alpha = elapsedInSecs / animationComponent.fadeDuration;
|
if (!animationStatus.loop && elapsedInSecs >= animationStatus.durationInSecs)
|
||||||
animator->applyCrossFade(animationComponent.fadeGltfAnimationIndex, fadeFromTime, alpha);
|
{
|
||||||
|
animator->applyAnimation(animationStatus.index, animationStatus.durationInSecs - 0.001);
|
||||||
|
animator->updateBoneMatrices();
|
||||||
|
gltfAnimations.erase(gltfAnimations.begin() + i);
|
||||||
|
animationComponent.fadeGltfAnimationIndex = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
animator->applyAnimation(animationStatus.index, elapsedInSecs);
|
||||||
|
|
||||||
|
if (animationComponent.fadeGltfAnimationIndex != -1 && elapsedInSecs < animationComponent.fadeDuration)
|
||||||
|
{
|
||||||
|
// cross-fade
|
||||||
|
auto fadeFromTime = animationComponent.fadeOutAnimationStart + elapsedInSecs;
|
||||||
|
auto alpha = elapsedInSecs / animationComponent.fadeDuration;
|
||||||
|
animator->applyCrossFade(animationComponent.fadeGltfAnimationIndex, fadeFromTime, alpha);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
animator->updateBoneMatrices();
|
||||||
}
|
}
|
||||||
|
|
||||||
animator->updateBoneMatrices();
|
|
||||||
|
|
||||||
for (int i = (int)boneAnimations.size() - 1; i >= 0; i--)
|
for (int i = (int)boneAnimations.size() - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
auto animationStatus = boneAnimations[i];
|
auto animationStatus = boneAnimations[i];
|
||||||
@@ -188,6 +209,7 @@ namespace flutter_filament
|
|||||||
|
|
||||||
if (!animationStatus.loop && elapsedInSecs >= animationStatus.durationInSecs)
|
if (!animationStatus.loop && elapsedInSecs >= animationStatus.durationInSecs)
|
||||||
{
|
{
|
||||||
|
Log("Bone animation %d finished", i);
|
||||||
boneAnimations.erase(boneAnimations.begin() + i);
|
boneAnimations.erase(boneAnimations.begin() + i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -197,7 +219,6 @@ namespace flutter_filament
|
|||||||
int currFrame = static_cast<int>(elapsedFrames) % animationStatus.lengthInFrames;
|
int currFrame = static_cast<int>(elapsedFrames) % animationStatus.lengthInFrames;
|
||||||
float delta = elapsedFrames - currFrame;
|
float delta = elapsedFrames - currFrame;
|
||||||
int nextFrame = currFrame;
|
int nextFrame = currFrame;
|
||||||
auto restLocalTransform = animationComponent.initialJointTransforms[animationStatus.boneIndex];
|
|
||||||
|
|
||||||
// offset from the end if reverse
|
// offset from the end if reverse
|
||||||
if (animationStatus.reverse)
|
if (animationStatus.reverse)
|
||||||
@@ -225,8 +246,8 @@ namespace flutter_filament
|
|||||||
}
|
}
|
||||||
|
|
||||||
// simple linear interpolation
|
// simple linear interpolation
|
||||||
math::mat4f curr = (1 - delta) * (restLocalTransform * animationStatus.frameData[currFrame]);
|
math::mat4f curr = (1 - delta) * animationStatus.frameData[currFrame];
|
||||||
math::mat4f next = delta * (restLocalTransform * animationStatus.frameData[nextFrame]);
|
math::mat4f next = delta * animationStatus.frameData[nextFrame];
|
||||||
math::mat4f localTransform = curr + next;
|
math::mat4f localTransform = curr + next;
|
||||||
|
|
||||||
const Entity joint = target->getJointsAt(animationStatus.skinIndex)[animationStatus.boneIndex];
|
const Entity joint = target->getJointsAt(animationStatus.skinIndex)[animationStatus.boneIndex];
|
||||||
|
|||||||
Reference in New Issue
Block a user