New models; using raft

This commit is contained in:
2025-09-25 04:11:31 +03:00
parent 9e5d08bfc6
commit 7e06da700a
15 changed files with 355 additions and 390 deletions

View File

@@ -4,305 +4,6 @@
#include "CharacterAnimationModule.h"
namespace ECS
{
#if 0
struct AnimationSystem {
struct AnimationDataNode {
float weight;
};
int root_index;
struct AnimationSystemBuilder {
struct AnimationNode {
enum {
ANIMATION_NODE_OUTPUT,
ANIMATION_NODE_BLEND2,
ANIMATION_NODE_ANIMATION,
ANIMATION_NODE_STATEMACHINE,
ANIMATION_NODE_STATE,
ANIMATION_NODE_TRANSITION
};
AnimationNode *outputs[32];
int output_count;
int type;
std::string anchor;
};
AnimationNode *parent;
std::list<AnimationNode *> parent_stack;
std::vector<AnimationNode *> animation_nodes;
struct ANOutput : AnimationNode {};
struct ANBlend2 : AnimationNode {
float weight;
};
struct ANAnimation : AnimationNode {
std::string animation;
};
struct ANStateMachine : AnimationNode {};
struct ANState : AnimationNode {
std::string name;
bool start;
bool end;
};
struct ANStateMachineTransition : AnimationNode {
std::string from, to;
bool at_end;
};
AnimationSystemBuilder *output()
{
ANOutput *onode = new ANOutput;
onode->output_count = 0;
onode->type = AnimationNode::ANIMATION_NODE_OUTPUT;
onode->anchor = "";
animation_nodes.push_back(onode);
parent = onode;
return this;
}
AnimationSystemBuilder *blend2(float blend,
const std::string &anchor = "")
{
ANBlend2 *onode = new ANBlend2;
onode->output_count = 0;
onode->type = AnimationNode::ANIMATION_NODE_BLEND2;
onode->anchor = anchor;
onode->weight = blend;
animation_nodes.push_back(onode);
parent->outputs[parent->output_count++] = onode;
parent_stack.push_back(parent);
parent = onode;
return this;
}
AnimationSystemBuilder *
animation(const std::string &animation,
const std::string &anchor = "")
{
ANAnimation *onode = new ANAnimation;
onode->output_count = 0;
onode->type = AnimationNode::ANIMATION_NODE_ANIMATION;
onode->anchor = anchor;
onode->animation = animation;
animation_nodes.push_back(onode);
parent->outputs[parent->output_count++] = onode;
parent_stack.push_back(parent);
parent = onode;
return this;
}
AnimationSystemBuilder *end()
{
parent = parent_stack.back();
parent_stack.pop_back();
return this;
}
AnimationSystemBuilder *
state_machine(const std::string &anchor = "")
{
ANStateMachine *onode = new ANStateMachine;
onode->output_count = 0;
onode->type =
AnimationNode::ANIMATION_NODE_STATEMACHINE;
onode->anchor = anchor;
animation_nodes.push_back(onode);
parent->outputs[parent->output_count++] = onode;
parent_stack.push_back(parent);
parent = onode;
return this;
}
AnimationSystemBuilder *state(const std::string &name)
{
ANState *onode = new ANState;
onode->output_count = 0;
onode->type = AnimationNode::ANIMATION_NODE_STATE;
onode->anchor = "";
onode->name = name;
animation_nodes.push_back(onode);
parent->outputs[parent->output_count++] = onode;
parent_stack.push_back(parent);
parent = onode;
return this;
}
AnimationSystemBuilder *
transition(const std::string &from, const std::string &to,
bool at_end, const std::string &anchor = "")
{
ANStateMachineTransition *onode =
new ANStateMachineTransition;
onode->output_count = 0;
onode->type = AnimationNode::ANIMATION_NODE_TRANSITION;
onode->anchor = anchor;
onode->from = from;
onode->to = to;
onode->at_end = at_end;
animation_nodes.push_back(onode);
parent->outputs[parent->output_count++] = onode;
parent_stack.push_back(parent);
parent = onode;
return this;
}
void build()
{
}
};
AnimationSystemBuilder m_builder;
std::map<AnimationSystem::AnimationSystemBuilder::AnimationNode *,
AnimationDataNode>
mruntimeData;
AnimationSystemBuilder *builder()
{
m_builder.animation_nodes.reserve(8);
m_builder.parent = nullptr;
return &m_builder;
}
void update(float delta)
{
std::deque<AnimationSystemBuilder::AnimationNode *> queue;
root_index = -1;
if (mruntimeData.size() == 0) {
int i;
for (i = 0; i < m_builder.animation_nodes.size(); i++) {
AnimationDataNode data;
data.weight = 0;
mruntimeData[m_builder.animation_nodes[i]] =
data;
std::cout << "type: "
<< m_builder.animation_nodes[i]->type
<< std::endl;
}
for (i = 0; i < m_builder.animation_nodes.size(); i++) {
if (m_builder.animation_nodes[i]->type ==
AnimationSystemBuilder::AnimationNode::
ANIMATION_NODE_OUTPUT) {
root_index = i;
break;
}
}
}
std::cout << "root index: " << root_index << " "
<< m_builder.animation_nodes.size() << std::endl;
queue.push_back(m_builder.animation_nodes[root_index]);
int i;
while (queue.size() > 0) {
AnimationSystemBuilder::AnimationNode *item =
queue.front();
queue.pop_front();
switch (item->type) {
case AnimationSystemBuilder::AnimationNode::
ANIMATION_NODE_OUTPUT:
for (i = 0; i < item->output_count; i++) {
AnimationSystemBuilder::AnimationNode
*out = item->outputs[i];
mruntimeData[out].weight = 1.0f;
}
break;
case AnimationSystemBuilder::AnimationNode::
ANIMATION_NODE_BLEND2: {
float weight =
static_cast<AnimationSystemBuilder::
ANBlend2 *>(item)
->weight;
for (i = 0; i < item->output_count; i++) {
AnimationSystemBuilder::AnimationNode
*out = item->outputs[i];
if (i == 0)
mruntimeData[out].weight =
weight;
else if (i == 0)
mruntimeData[out].weight =
(1.0f - weight);
else
mruntimeData[out].weight = 0.0f;
}
} break;
case AnimationSystemBuilder::AnimationNode::
ANIMATION_NODE_ANIMATION: {
const std::string &animation =
static_cast<AnimationSystemBuilder::
ANAnimation *>(item)
->animation;
std::cout << "animation: " << animation << " "
<< mruntimeData[item].weight
<< std::endl;
} break;
case AnimationSystemBuilder::AnimationNode::
ANIMATION_NODE_STATEMACHINE:
break;
case AnimationSystemBuilder::AnimationNode::
ANIMATION_NODE_STATE:
break;
}
for (i = 0; i < item->output_count; i++) {
queue.push_back(item->outputs[i]);
}
}
#if 0
while (breadth) {
int i;
switch (breadth->type) {
case AnimationSystemBuilder::AnimationNode::
ANIMATION_NODE_OUTPUT:
for (i = 0; i < breadth->output_count; i++) {
AnimationSystemBuilder::AnimationNode
*out = breadth->outputs[i];
mruntimeData[out].weight = 1.0f;
}
break;
case AnimationSystemBuilder::AnimationNode::
ANIMATION_NODE_BLEND2: {
float weight =
static_cast<AnimationSystemBuilder::
ANBlend2 *>(breadth)
->weight;
for (i = 0; i < breadth->output_count; i++) {
AnimationSystemBuilder::AnimationNode
*out = breadth->outputs[i];
if (i == 0)
mruntimeData[out].weight =
weight;
else if (i == 0)
mruntimeData[out].weight =
(1.0f - weight);
else
mruntimeData[out].weight = 0.0f;
}
} break;
case AnimationSystemBuilder::AnimationNode::
ANIMATION_NODE_ANIMATION:
break;
case AnimationSystemBuilder::AnimationNode::
ANIMATION_NODE_STATEMACHINE:
break;
case AnimationSystemBuilder::AnimationNode::
ANIMATION_NODE_STATE:
break;
}
visited.insert(breadth);
AnimationSystemBuilder::AnimationNode *next = nullptr;
while (!next && parents.size() > 0) {
for (i = 0; i < breadth->output_count; i++) {
if (visited.find(breadth->outputs[i]) ==
visited.end()) {
next = breadth->outputs[i];
break;
}
}
if (next)
break;
else {
breadth = parents.back();
parents.pop_back();
}
}
if (next) {
parents.push_back(breadth);
breadth = next;
}
}
#endif
OgreAssert(false, "update");
}
};
struct AnimationTree {
AnimationSystem *manimationSystem;
};
#endif
CharacterAnimationModule::CharacterAnimationModule(flecs::world &ecs)
{
ecs.module<CharacterAnimationModule>();
@@ -321,7 +22,8 @@ CharacterAnimationModule::CharacterAnimationModule(flecs::world &ecs)
"swimming" };
int state_count = sizeof(animNames) /
sizeof(animNames[0]);
anim.mAnimationSystem = new AnimationSystem();
anim.mAnimationSystem =
new AnimationSystem(false);
for (i = 0; i < state_count; i++) {
Animation *animation = new Animation(
ch.mBodyEnt->getAnimationState(
@@ -330,6 +32,9 @@ CharacterAnimationModule::CharacterAnimationModule(flecs::world &ecs)
animNames[i])
);
std::cout
<< "animation: " << animNames[i]
<< std::endl;
animation->setLoop(true);
anim.mAnimationSystem->add_animation(
animNames[i], animation);
@@ -338,45 +43,51 @@ CharacterAnimationModule::CharacterAnimationModule(flecs::world &ecs)
->builder()
/* clang-format off */
->output()
->state_machine(ANIM_FADE_SPEED, "state")
->state("idle")
->animation("idle")
->end()
->state("walking")
->animation("walking")
->end()
->state("running")
->animation("running")
->end()
->state("treading_water")
->animation("treading_water")
->end()
->state("swimming")
->animation("swimming")
->end()
->state("swimming-fast")
->speed(20.0f)
->animation("swimming")
->state_machine(ANIM_FADE_SPEED, "main")
->state("locomotion")
->state_machine(ANIM_FADE_SPEED, "locomotion-state")
->state("idle")
->animation("idle")
->end()
->state("walking")
->animation("walking")
->end()
->state("running")
->animation("running")
->end()
->state("treading_water")
->animation("treading_water")
->end()
->state("swimming")
->animation("swimming")
->end()
->state("swimming-fast")
->speed(20.0f)
->animation("swimming")
->end()
->end()
->end()
->end()
->end()
->end();
/* clang-format on */
anim.mAnimationSystem
->get<AnimationNodeStateMachine>("main")
->setAnimation("locomotion");
anim.mAnimationSystem
->get<AnimationNodeStateMachine>(
"state")
"locomotion-state")
->setAnimation("idle");
anim.configured = true;
}
});
ecs.system<const EngineData, const Input, CharacterBase,
AnimationControl>("HandleAnimations1")
ecs.system<const EngineData, CharacterBase, AnimationControl>(
"HandleAnimations1")
.kind(flecs::OnUpdate)
.each([this](const EngineData &eng, const Input &input,
.each([this](flecs::entity e, const EngineData &eng,
CharacterBase &ch, AnimationControl &anim) {
float delta = eng.delta;
anim.mAnimationSystem->addTime(delta);
// fadeAnimations(anim, delta);
if (!ch.mRootBone)
return;
ch.mBoneMotion += ch.mRootBone->getPosition();
@@ -412,7 +123,8 @@ CharacterAnimationModule::CharacterAnimationModule(flecs::world &ecs)
const AnimationControl &anim,
const CharacterBase &ch, CharacterVelocity &gr) {
if (anim.mAnimationSystem
->get<AnimationNodeStateMachine>("state")
->get<AnimationNodeStateMachine>(
"locomotion-state")
->getCurrentState() == "swimming") {
float h = Ogre::Math::Clamp(
0.0f - ch.mBodyNode->getPosition().y,
@@ -468,6 +180,30 @@ CharacterAnimationModule::CharacterAnimationModule(flecs::world &ecs)
}
}
});
ecs.system<const Input, const CharacterBase, AnimationControl>(
"HandleNPCAnimations")
.kind(flecs::OnUpdate)
.with<Character>()
.without<Player>()
.each([](flecs::entity e, const Input &input,
const CharacterBase &ch, AnimationControl &anim) {
if (!anim.configured)
return;
AnimationNodeStateMachine *state_machine =
anim.mAnimationSystem
->get<AnimationNodeStateMachine>(
"locomotion-state");
Ogre::String current_state =
state_machine->getCurrentState();
Ogre::String next_state = "idle";
if (current_state != "treading_water" &&
ch.is_submerged)
next_state = "treading_water";
if (current_state != "idle" && !ch.is_submerged)
next_state = "idle";
state_machine->setAnimation(next_state);
});
ecs.system<const Input, const CharacterBase, AnimationControl>(
"HandlePlayerAnimations")
.kind(flecs::OnUpdate)
@@ -477,12 +213,10 @@ CharacterAnimationModule::CharacterAnimationModule(flecs::world &ecs)
const CharacterBase &ch, AnimationControl &anim) {
if (!anim.configured)
return;
if (input.fast)
std::cout << "fast!" << std::endl;
AnimationNodeStateMachine *state_machine =
anim.mAnimationSystem
->get<AnimationNodeStateMachine>(
"state");
"locomotion-state");
Ogre::String current_state =
state_machine->getCurrentState();
bool controls_idle = input.motion.zeroLength();
@@ -501,30 +235,28 @@ CharacterAnimationModule::CharacterAnimationModule(flecs::world &ecs)
anim_is_swimming;
bool start_motion = !controls_idle && anim_is_idle;
bool end_motion = controls_idle && !anim_is_idle;
Ogre::String next_state = current_state;
if (controls_idle && anim_is_idle) {
if (current_state != "treading_water" &&
ch.is_submerged)
state_machine->setAnimation(
"treading_water");
next_state = "treading_water";
else if (current_state != "idle" &&
!ch.is_submerged)
state_machine->setAnimation("idle");
next_state = "idle";
state_machine->setAnimation(next_state, true);
} else if (start_motion) {
if (ch.is_submerged) {
if (input.fast)
state_machine->setAnimation(
"swimming-fast", true);
next_state = "swimming-fast";
else
state_machine->setAnimation(
"swimming", true);
next_state = "swimming";
} else {
if (input.fast)
state_machine->setAnimation(
"running", true);
next_state = "running";
else
state_machine->setAnimation(
"walking", true);
next_state = "walking";
}
state_machine->setAnimation(next_state, true);
} else if (end_motion) {
if (ch.is_submerged)
state_machine->setAnimation(
@@ -535,23 +267,21 @@ CharacterAnimationModule::CharacterAnimationModule(flecs::world &ecs)
if (ch.is_submerged) {
if (input.fast &&
!anim_is_swimming_fast) {
state_machine->setAnimation(
"swimming-fast");
next_state = "swimming-fast";
} else if (!input.fast &&
!anim_is_swimming_slow) {
state_machine->setAnimation(
"swimming");
next_state = "swimming";
}
} else {
if (input.fast && !anim_is_running)
state_machine->setAnimation(
"running");
next_state = "running";
else if (!input.fast &&
!anim_is_walking)
state_machine->setAnimation(
"walking");
next_state = "walking";
}
if (current_state != next_state)
state_machine->setAnimation(next_state);
}
});
}
}
}