72 lines
3.2 KiB
C++
72 lines
3.2 KiB
C++
#include "MetaCoreAnimation/MetaCoreAnimation.h"
|
|
#include "MetaCoreScene/MetaCoreScene.h"
|
|
|
|
#include <algorithm>
|
|
#include <chrono>
|
|
#include <cstdlib>
|
|
#include <iostream>
|
|
#include <vector>
|
|
|
|
int main() {
|
|
using namespace MetaCore;
|
|
const auto clipGuid = MetaCoreBuildDeterministicAnimationGuid("benchmark/clip");
|
|
const auto controllerGuid = MetaCoreBuildDeterministicAnimationGuid("benchmark/controller");
|
|
|
|
MetaCoreAnimationClipDocument clip;
|
|
clip.AssetGuid = clipGuid;
|
|
clip.Duration = 1.0F;
|
|
for (int bone = 0; bone < 100; ++bone) {
|
|
MetaCoreAnimationChannelDocument channel;
|
|
channel.NodePath = "Root/Bone_" + std::to_string(bone);
|
|
channel.Target = MetaCoreAnimationChannelTarget::Translation;
|
|
channel.Vec3Keys = {{0.0F, {0, 0, 0}}, {1.0F, {static_cast<float>(bone) * 0.001F, 0, 0}}};
|
|
clip.Channels.push_back(std::move(channel));
|
|
}
|
|
|
|
MetaCoreAnimatorControllerDocument controller;
|
|
controller.AssetGuid = controllerGuid;
|
|
controller.Parameters.push_back({"Speed", MetaCoreAnimatorParameterType::Float, false, 0, 0.5F});
|
|
for (int layerIndex = 0; layerIndex < 2; ++layerIndex) {
|
|
MetaCoreAnimatorStateDocument state;
|
|
state.Id = "Move";
|
|
state.Motion.Type = MetaCoreAnimatorMotionType::BlendTree1D;
|
|
state.Motion.ParameterX = "Speed";
|
|
state.Motion.Samples = {{"slow", clipGuid, 0.0F}, {"fast", clipGuid, 1.0F}};
|
|
MetaCoreAnimatorLayerDocument layer;
|
|
layer.Id = "Layer_" + std::to_string(layerIndex);
|
|
layer.DefaultStateId = state.Id;
|
|
layer.BlendMode = layerIndex == 0 ? MetaCoreAnimatorLayerBlendMode::Override : MetaCoreAnimatorLayerBlendMode::Additive;
|
|
layer.States.push_back(std::move(state));
|
|
controller.Layers.push_back(std::move(layer));
|
|
}
|
|
|
|
MetaCoreScene scene;
|
|
for (int index = 0; index < 100; ++index) {
|
|
auto object = scene.CreateGameObject("Animated_" + std::to_string(index));
|
|
MetaCoreAnimatorComponent animator;
|
|
animator.ControllerAssetGuid = controllerGuid;
|
|
object.AddComponent<MetaCoreAnimatorComponent>(animator);
|
|
}
|
|
MetaCoreAnimationRuntime runtime(scene,
|
|
[&](MetaCoreAssetGuid guid) -> std::optional<MetaCoreAnimationClipDocument> { return guid == clipGuid ? std::optional(clip) : std::nullopt; },
|
|
[&](MetaCoreAssetGuid guid) -> std::optional<MetaCoreAnimatorControllerDocument> { return guid == controllerGuid ? std::optional(controller) : std::nullopt; });
|
|
runtime.Start();
|
|
for (int warmup = 0; warmup < 30; ++warmup) runtime.Update(1.0 / 60.0);
|
|
|
|
std::vector<double> samples;
|
|
samples.reserve(180);
|
|
for (int frame = 0; frame < 180; ++frame) {
|
|
const auto begin = std::chrono::steady_clock::now();
|
|
runtime.Update(1.0 / 60.0);
|
|
samples.push_back(std::chrono::duration<double, std::milli>(std::chrono::steady_clock::now() - begin).count());
|
|
}
|
|
std::sort(samples.begin(), samples.end());
|
|
const double p95 = samples[static_cast<std::size_t>(samples.size() * 0.95)];
|
|
std::cout << "AnimationBenchmark instances=100 bones=100 layers=2 p95_ms=" << p95 << '\n';
|
|
if (p95 > 4.0) {
|
|
std::cerr << "Animation CPU p95 exceeds the Linux x86_64 4 ms gate\n";
|
|
return EXIT_FAILURE;
|
|
}
|
|
return EXIT_SUCCESS;
|
|
}
|