This commit is contained in:
2025-09-16 20:38:29 +03:00
parent 1aa002d8ba
commit 190318e5c4
20 changed files with 925 additions and 243 deletions

View File

@@ -97,7 +97,8 @@ CharacterModule::CharacterModule(flecs::world &ecs)
Ogre::ANIMBLEND_CUMULATIVE);
Ogre::String
animNames[AnimationControl::NUM_ANIMS] = {
"idle", "walking", "running"
"idle", "walking", "running",
"treading_water", "swimming"
};
for (i = 0; i < AnimationControl::NUM_ANIMS;
i++) {
@@ -165,11 +166,11 @@ CharacterModule::CharacterModule(flecs::world &ecs)
if (anim.currentAnim != anim.nextAnim)
setAnimation(anim);
});
ecs.system<EngineData, CharacterBase, AnimationControl>(
"HandleAnimations1")
ecs.system<const EngineData, const Input, CharacterBase,
AnimationControl>("HandleAnimations1")
.kind(flecs::OnUpdate)
.each([this](EngineData &eng, CharacterBase &ch,
AnimationControl &anim) {
.each([this](const EngineData &eng, const Input &input,
CharacterBase &ch, AnimationControl &anim) {
float delta = eng.delta;
Ogre::Real animSpeed = 1;
if (anim.currentAnim != AnimationControl::ANIM_NONE) {
@@ -177,6 +178,11 @@ CharacterModule::CharacterModule(flecs::world &ecs)
AnimationControl::ANIM_WALK)
anim.mAnims[anim.currentAnim]->addTime(
delta * 1.0f);
else if (anim.currentAnim ==
AnimationControl::ANIM_SWIMMING &&
input.fast)
anim.mAnims[anim.currentAnim]->addTime(
delta * 20.0f);
else
anim.mAnims[anim.currentAnim]->addTime(
delta * animSpeed);
@@ -186,6 +192,24 @@ CharacterModule::CharacterModule(flecs::world &ecs)
return;
ch.mBoneMotion = ch.mRootBone->getPosition();
});
ecs.system<CharacterBase>()
.kind(flecs::OnUpdate)
.with<TerrainReady>()
.with<WaterReady>()
.with<InWater>()
.each([this](flecs::entity e, CharacterBase &ch) {
float full_subm = 2.0f;
Ogre::Vector3 pos = ch.mBodyNode->getPosition();
float current_subm = -Ogre::Math::Clamp(
pos.y + Ogre::Math::Sin(ch.mTimer * 0.13f +
130.0f) *
0.07f,
-full_subm, 0.0f);
if (current_subm > 0.9f)
ch.is_submerged = true;
else if (current_subm < 0.8f)
ch.is_submerged = false;
});
ecs.system<const EngineData, const CharacterBase, CharacterVelocity>(
"HandleGravity")
.kind(flecs::OnUpdate)
@@ -222,6 +246,24 @@ CharacterModule::CharacterModule(flecs::world &ecs)
}
gr.gvelocity *= 0.99;
});
ecs.system<const EngineData, const AnimationControl,
const CharacterBase, CharacterVelocity>("HandleSwimming")
.kind(flecs::OnUpdate)
.with<TerrainReady>()
.with<WaterReady>()
.each([this](flecs::entity e, const EngineData &eng,
const AnimationControl &anim,
const CharacterBase &ch, CharacterVelocity &gr) {
if (anim.currentAnim ==
AnimationControl::ANIM_SWIMMING) {
float h = Ogre::Math::Clamp(
0.2f - ch.mBodyNode->getPosition().y,
0.0f, 2000.0f);
if (h > 0.2 && h < 2.0f)
gr.gvelocity.y += 1.2 * (h + 1.0f) * h *
eng.delta;
}
});
ecs.system<const EngineData, const CharacterBase, CharacterVelocity>(
"HandleRootMotionVelocity")
.kind(flecs::OnUpdate)
@@ -287,34 +329,72 @@ CharacterModule::CharacterModule(flecs::world &ecs)
}
}
});
ecs.system<const Input, AnimationControl>("HandlePlayerAnimations")
ecs.system<const Input, const CharacterBase, AnimationControl>(
"HandlePlayerAnimations")
.kind(flecs::OnUpdate)
.with<Character>()
.with<Player>()
.each([](const Input &input, AnimationControl &anim) {
.each([](flecs::entity e, const Input &input,
const CharacterBase &ch, AnimationControl &anim) {
if (!anim.configured)
return;
bool controls_idle = input.motion.zeroLength();
bool anim_is_idle = anim.currentAnim ==
AnimationControl::ANIM_IDLE;
bool anim_is_idle =
anim.currentAnim ==
AnimationControl::ANIM_IDLE ||
anim.currentAnim ==
AnimationControl::ANIM_TREADING_WATER;
bool anim_is_walking = anim.currentAnim ==
AnimationControl::ANIM_WALK;
bool anim_is_running = anim.currentAnim ==
AnimationControl::ANIM_RUN;
bool anim_is_swimming = anim.currentAnim ==
AnimationControl::ANIM_SWIMMING;
bool anim_is_motion = anim_is_walking ||
anim_is_running;
anim_is_running ||
anim_is_swimming;
if (controls_idle) {
if (anim.currentAnim ==
AnimationControl::ANIM_IDLE &&
ch.is_submerged)
anim.nextAnim = AnimationControl::
ANIM_TREADING_WATER;
else if (anim.currentAnim ==
AnimationControl::
ANIM_TREADING_WATER &&
!ch.is_submerged)
anim.nextAnim =
AnimationControl::ANIM_IDLE;
}
if (!controls_idle && anim_is_idle) {
anim.reset = true;
if (input.fast)
anim.nextAnim =
AnimationControl::ANIM_RUN;
else
anim.nextAnim =
AnimationControl::ANIM_WALK;
if (ch.is_submerged) {
if (input.fast)
anim.nextAnim =
AnimationControl::
ANIM_SWIMMING;
else
anim.nextAnim =
AnimationControl::
ANIM_SWIMMING;
} else {
if (input.fast)
anim.nextAnim =
AnimationControl::ANIM_RUN;
else
anim.nextAnim =
AnimationControl::
ANIM_WALK;
}
} else
anim.reset = false;
if (controls_idle && anim_is_motion)
anim.nextAnim = AnimationControl::ANIM_IDLE;
if (ch.is_submerged)
anim.nextAnim = AnimationControl::
ANIM_TREADING_WATER;
else
anim.nextAnim =
AnimationControl::ANIM_IDLE;
else if (!controls_idle && anim_is_motion) {
if (input.fast && anim_is_walking)
anim.nextAnim =
@@ -322,20 +402,42 @@ CharacterModule::CharacterModule(flecs::world &ecs)
else if (!input.fast && anim_is_running)
anim.nextAnim =
AnimationControl::ANIM_WALK;
if ((anim_is_walking || anim_is_running) &&
ch.is_submerged) {
if (input.fast)
anim.nextAnim =
AnimationControl::
ANIM_SWIMMING;
else
anim.nextAnim =
AnimationControl::
ANIM_SWIMMING;
} else if ((anim_is_swimming) &&
!ch.is_submerged) {
if (input.fast)
anim.nextAnim =
AnimationControl::ANIM_RUN;
else
anim.nextAnim =
AnimationControl::
ANIM_WALK;
}
}
});
ecs.system<const EngineData, CharacterBase, CharacterBody>(
"UpdateCharacterBase")
ecs.system<const EngineData, CharacterLocation, CharacterBase,
CharacterBody>("UpdateCharacterBase")
.kind(flecs::OnUpdate)
.with<Character>()
.each([](const EngineData &eng, CharacterBase &ch,
CharacterBody &body) {
.each([](const EngineData &eng, CharacterLocation &loc,
CharacterBase &ch, CharacterBody &body) {
if (!ch.mBodyNode) {
body.mController = nullptr;
ch.mBodyEnt = eng.mScnMgr->createEntity(
"normal-male.glb");
ch.mBodyNode = eng.mScnMgr->getRootSceneNode()
->createChildSceneNode();
ch.mBodyNode->setOrientation(loc.orientation);
ch.mBodyNode->setPosition(loc.position);
ch.mBodyNode->attachObject(ch.mBodyEnt);
ch.mSkeleton = ch.mBodyEnt->getSkeleton();
body.mGhostObject =
@@ -385,6 +487,11 @@ CharacterModule::CharacterModule(flecs::world &ecs)
"No root bone");
ch.mRootBone = ch.mSkeleton->getBone("Root");
OgreAssert(ch.mRootBone, "No root bone");
} else {
loc.orientation =
ch.mBodyNode->_getDerivedOrientation();
loc.position =
ch.mBodyNode->_getDerivedPosition();
}
});
ecs.system<const EngineData, CharacterBase, CharacterBody>(
@@ -592,16 +699,6 @@ CharacterModule::CharacterModule(flecs::world &ecs)
<< "\n";
});
#endif
/* Create player */
player = ecs.entity("player");
player.set<AnimationControl>({ AnimationControl::ANIM_NONE,
AnimationControl::ANIM_NONE, false,
false });
player.set<CharacterBase>(
{ "normal-male.glb", 0.0f, nullptr, nullptr, nullptr });
player.set<CharacterBody>({ nullptr, nullptr, nullptr, false, false });
player.add<Character>();
player.add<Player>();
}
void CharacterModule::setAnimation(AnimationControl &anim)