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

47
.vscode/settings.json vendored
View File

@@ -26,6 +26,51 @@
"initializer_list": "cpp",
"span": "cpp",
"chrono": "cpp",
"format": "cpp"
"format": "cpp",
"cctype": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"bit": "cpp",
"bitset": "cpp",
"charconv": "cpp",
"compare": "cpp",
"concepts": "cpp",
"condition_variable": "cpp",
"cstdint": "cpp",
"map": "cpp",
"set": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"iterator": "cpp",
"memory": "cpp",
"optional": "cpp",
"ratio": "cpp",
"system_error": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"fstream": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"limits": "cpp",
"mutex": "cpp",
"new": "cpp",
"numbers": "cpp",
"numeric": "cpp",
"ostream": "cpp",
"semaphore": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"thread": "cpp",
"typeinfo": "cpp"
}
}

BIN
assets/blender/vehicles/boat-gobbot.blend (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/blender/vehicles/boat.blend (Stored with Git LFS)

Binary file not shown.

BIN
assets/blender/vehicles/raft.blend (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/blender/vehicles/tiny-boat.blend (Stored with Git LFS) Normal file

Binary file not shown.

View File

@@ -228,8 +228,7 @@ function StartGameQuest()
quest.activate = function(this)
print('activate...')
local mc_is_free = function()
this.boat_id = ecs_vehicle_set("boat", 0, 0, -20, 1.75)
this.boat2_id = ecs_vehicle_set("boat", -10, 0, -20, 1.55)
this.boat_id = ecs_vehicle_set("raft", 0, 0, -20, 1.75)
this.npc_id = ecs_npc_set("normal-female.glb", 0, 2, -20, 1.75)
this.boat = true
-- ecs_set_slot(this.boat_id, this.npc_id, "captain_seat")
@@ -251,7 +250,7 @@ function StartGameQuest()
end
quests = {}
-- ecs_set_debug_drawing(true)
setup_handler(function(event)
setup_handler(function(event, entity)
print(event)
for k, v in pairs(quests) do
if v.active then
@@ -264,7 +263,7 @@ setup_handler(function(event)
print("narration progress!")
elseif event == "narration_answered" then
local answer = narration_get_answer()
story:choose(answer)
-- story:choose(answer)
print("answered:", answer)
elseif event == "new_game" then
ecs_character_params_set("player", "gravity", true)

View File

@@ -2,5 +2,5 @@ project(gamedata)
find_package(OGRE REQUIRED COMPONENTS Bites Bullet Paging Terrain Overlay CONFIG)
add_library(GameData STATIC GameData.cpp CharacterModule.cpp WaterModule.cpp SunModule.cpp TerrainModule.cpp GUIModule.cpp LuaData.cpp WorldMapModule.cpp
BoatModule.cpp EventTriggerModule.cpp CharacterAnimationModule.cpp)
target_link_libraries(GameData PUBLIC OgreMain OgreBites OgreBullet OgrePaging OgreTerrain OgreOverlay flecs::flecs_static lua sceneloader)
target_link_libraries(GameData PUBLIC OgreMain OgreBites OgreBullet OgrePaging OgreTerrain OgreOverlay flecs::flecs_static lua PRIVATE sceneloader)
target_include_directories(GameData PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

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);
}
});
}
}
}

View File

@@ -195,13 +195,15 @@ struct AnimationNodeStateMachine : AnimationNode {
float fade_speed;
Ogre::String mCurrentStateName;
bool configured;
AnimationNodeStateMachine(float fade_speed)
bool debug;
AnimationNodeStateMachine(float fade_speed, bool debug = false)
: AnimationNode()
, currentAnim(nullptr)
, nextAnim(nullptr)
, fade_speed(fade_speed)
, mCurrentStateName("")
, configured(false)
, debug(debug)
{
m_weight = 1.0f;
}
@@ -212,21 +214,33 @@ struct AnimationNodeStateMachine : AnimationNode {
configure();
configured = true;
}
if (debug) {
std::cout<< "state machine addTime" << std::endl;
std::cout << "state machine children: " << children.size() << std::endl;
}
for (i = 0; i < children.size(); i++) {
if (debug)
std::cout << "child weight: " << i << " "
<< children[i]->getWeight()
<< std::endl;
AnimationNode *child = children[i];
if (fade_in.find(child) != fade_in.end()) {
Ogre::Real newWeight =
child->getWeight() + time * fade_speed;
child->setWeight(Ogre::Math::Clamp<Ogre::Real>(
newWeight * m_weight, 0, m_weight));
if (newWeight >= m_weight)
if (debug) {
std::cout << "fade in: " << newWeight << std::endl;
std::cout << "m_weight: " << m_weight << std::endl;
}
if (newWeight >= 1)
fade_in.erase(child);
}
if (fade_out.find(child) != fade_out.end()) {
Ogre::Real newWeight =
child->getWeight() - time * fade_speed;
child->setWeight(Ogre::Math::Clamp<Ogre::Real>(
newWeight * m_weight, 0, m_weight));
newWeight * m_weight, 0, 1));
if (newWeight <= 0)
fade_out.erase(child);
}
@@ -237,6 +251,11 @@ struct AnimationNodeStateMachine : AnimationNode {
}
void setWeight(float weight)
{
int i;
if (weight > m_weight && currentAnim)
fade_in.insert(currentAnim);
if (weight < m_weight && currentAnim && currentAnim->getWeight() > weight)
currentAnim->setWeight(weight);
m_weight = weight;
bool enabled = weight > 0.001f;
/* do not update child state yet */
@@ -253,17 +272,18 @@ struct AnimationNodeStateMachine : AnimationNode {
void configure()
{
int i;
std::cout << "children: " << children.size() << std::endl;
if (debug)
std::cout << "children: " << children.size() << std::endl;
for (i = 0; i < children.size(); i++)
addState(children[i]);
std::cout << "configure called" << std::endl;
if (debug)
std::cout << "configure called" << std::endl;
}
void reset()
{
int i;
for (i = 0; i < children.size(); i++) {
for (i = 0; i < children.size(); i++)
children[i]->reset();
}
}
void setAnimation(const Ogre::String &anim_state, bool reset = false)
{
@@ -273,7 +293,6 @@ struct AnimationNodeStateMachine : AnimationNode {
}
OgreAssert(stateMap.find(anim_state) != stateMap.end(),
"Bad animation state: " + anim_state);
std::cout << "STATE: " << anim_state << std::endl;
nextAnim = stateMap[anim_state];
if (nextAnim == currentAnim)
return;
@@ -324,8 +343,10 @@ struct AnimationNodeOutput : AnimationNode {
};
struct AnimationSystem : AnimationNode {
AnimationSystem()
: m_builder(this)
bool debug;
AnimationSystem(bool debug = false)
: debug(debug)
, m_builder(this, debug)
{
}
std::unordered_map<Ogre::String, Animation *> animation_list;
@@ -347,8 +368,11 @@ struct AnimationSystem : AnimationNode {
std::list<AnimationNode *> parent_stack;
std::unordered_map<Ogre::String, AnimationNode *> nodeMap;
std::vector<AnimationNodeAnimation *> animationNodeList;
AnimationSystemBuilder(AnimationSystem *animationSystem)
bool debug;
AnimationSystemBuilder(AnimationSystem *animationSystem,
bool debug = false)
: mAnimationSystem(animationSystem)
, debug(debug)
{
}
AnimationSystemBuilder *output()
@@ -391,7 +415,7 @@ struct AnimationSystem : AnimationNode {
{
OgreAssert(parent, "bad parent");
AnimationNodeStateMachine *onode =
new AnimationNodeStateMachine(fade_time);
new AnimationNodeStateMachine(fade_time, debug);
animation_nodes.push_back(onode);
parent->children.push_back(onode);
parent_stack.push_back(parent);
@@ -429,14 +453,23 @@ struct AnimationSystem : AnimationNode {
m_builder.animationNodeList[i];
float weight = anim->getWeight();
anim->mAnimation->increaseAccWeight(weight);
std::cout << i << " weight: " << weight << std::endl;
#ifdef VDEBUG
if (debug)
std::cout << i << " node: "
<< anim->mAnimation->getName() << " "
<< weight << std::endl;
#endif
}
for (i = 0; i < vanimation_list.size(); i++) {
float weight = vanimation_list[i]->getAccWeight();
vanimation_list[i]->setWeight(weight);
vanimation_list[i]->resetAccWeight();
std::cout << i << vanimation_list[i]->getName()
<< " acc weight: " << weight << std::endl;
#ifdef VDEBUG
if (debug)
std::cout << i << " animation: "
<< vanimation_list[i]->getName()
<< " " << weight << std::endl;
#endif
}
}
void setWeight(float weight)
@@ -460,24 +493,11 @@ struct AnimationSystem : AnimationNode {
};
struct AnimationControl {
// AnimID currentAnim;
// AnimID nextAnim;
// bool reset;
bool configured;
// Ogre::AnimationState *mAnims[NUM_ANIMS]; // master animation list
// Ogre::Animation *mSkelAnimations[NUM_ANIMS];
// bool mFadingIn[NUM_ANIMS]; // which animations are fading in
// bool mFadingOut[NUM_ANIMS]; // which animations are fading out
// Ogre::NodeAnimationTrack *mHipsTracks[NUM_ANIMS];
// Ogre::NodeAnimationTrack *mRootTracks[NUM_ANIMS];
// std::vector<AnimationNode *> mAnimations;
// AnimationNodeStateMachine *mStateMachine;
AnimationSystem *mAnimationSystem;
};
struct CharacterAnimationModule {
CharacterAnimationModule(flecs::world &ecs);
// void setAnimation(AnimationControl &anim);
// void fadeAnimations(AnimationControl &anim, Ogre::Real deltaTime);
};
}
#endif

View File

@@ -259,7 +259,8 @@ ECS::EventTriggerModule::EventTriggerModule(flecs::world &ecs)
LuaBase>()
.mLua
->call_handler(
evt.event);
evt.event,
e);
}
}
}
@@ -283,7 +284,9 @@ ECS::EventTriggerModule::EventTriggerModule(flecs::world &ecs)
std::cout << "body exited"
<< std::endl;
}
body.contactBodies.erase(*it);
it = body.contactBodies.erase(it);
if (it == body.contactBodies.end())
break;
}
it++;
}

View File

@@ -10,6 +10,7 @@ struct EventTrigger {
float halfheight;
float radius;
Ogre::String event;
Ogre::SceneNode *node;
};
struct EventTriggerExit {
Ogre::String event;

View File

@@ -12,11 +12,17 @@ int luaopen_lpeg(lua_State *L);
}
namespace ECS
{
struct LuaEcsEntity {
int id;
flecs::entity e;
};
struct idmap {
std::unordered_map<int, flecs::entity> id2entity;
std::unordered_map<flecs::entity_t, int> entity2id;
int next_id;
idmap()
: id2entity({})
, entity2id({})
, next_id(0)
{
}
@@ -27,8 +33,11 @@ struct idmap {
}
int add_entity(flecs::entity e)
{
if (entity2id.find(e.id()) != entity2id.end())
return entity2id[e.id()];
int id = get_next_id();
id2entity[id] = e;
entity2id[e.id()] = id;
return id;
}
flecs::entity get_entity(int id)
@@ -53,7 +62,28 @@ int LuaData::call_handler(const Ogre::String &event)
for (i = 0; i < setup_handlers.size(); i++) {
lua_rawgeti(L, LUA_REGISTRYINDEX, setup_handlers[i]);
lua_pushstring(L, event.c_str());
lua_pcall(L, 1, 0, 0);
lua_pushinteger(L, -1);
if (lua_pcall(L, 2, 0, 0)) {
Ogre::LogManager::getSingleton().stream()
<< lua_tostring(L, -1);
OgreAssert(false, "Lua error");
}
}
return 0;
}
int LuaData::call_handler(const Ogre::String &event, flecs::entity e)
{
int i;
for (i = 0; i < setup_handlers.size(); i++) {
lua_rawgeti(L, LUA_REGISTRYINDEX, setup_handlers[i]);
lua_pushstring(L, event.c_str());
lua_pushinteger(L, idmap.add_entity(e));
if (lua_pcall(L, 2, 0, 0)) {
Ogre::LogManager::getSingleton().stream()
<< lua_tostring(L, -1);
OgreAssert(false, "Lua error");
}
}
return 0;
}
@@ -276,6 +306,21 @@ LuaData::LuaData()
lua_pushinteger(L, ret);
std::cout << "boat created: " << ret << std::endl;
return 1;
} else if (what == "raft") {
float yaw = lua_tonumber(L, 5);
float x = lua_tonumber(L, 2);
float y = lua_tonumber(L, 3);
float z = lua_tonumber(L, 4);
flecs::entity e = ECS::get().entity();
Ogre::Quaternion orientation(Ogre::Radian(yaw),
Ogre::Vector3(0, 1, 0));
Ogre::Vector3 position(x, y, z);
e.set<BoatType>(
{ "raft.scene", position, orientation });
int ret = idmap.add_entity(e);
lua_pushinteger(L, ret);
std::cout << "raft created: " << ret << std::endl;
return 1;
}
lua_pushinteger(L, -1);
return 1;
@@ -413,6 +458,118 @@ LuaData::LuaData()
return 0;
});
lua_setglobal(L, "ecs_set_slot");
lua_pushcfunction(L, [](lua_State *L) -> int {
luaL_checktype(L, 1, LUA_TNUMBER); // entity id
int id = lua_tointeger(L, 1);
flecs::entity e = idmap.get_entity(id);
LuaEcsEntity *edata = static_cast<LuaEcsEntity *>(
lua_newuserdata(L, sizeof(LuaEcsEntity)));
new (edata) LuaEcsEntity();
edata->e = e;
edata->id = e;
luaL_getmetatable(L, "FlecsEntityMetaTable");
lua_setmetatable(L, -2);
return 1;
});
lua_setglobal(L, "ecs_get_entity");
luaL_newmetatable(L, "FlecsEntityMetaTable");
lua_pushstring(L, "__index");
lua_pushcfunction(L, [](lua_State *L) -> int {
luaL_checktype(L, 1, LUA_TUSERDATA); //metatable
luaL_checktype(L, 2, LUA_TSTRING); //function
Ogre::String component = lua_tostring(L, 2);
if (component == "components") {
lua_pushvalue(L, 1);
lua_pushcclosure(
L,
[](lua_State *L) -> int {
luaL_checktype(L, lua_upvalueindex(1),
LUA_TUSERDATA);
LuaEcsEntity *ent = static_cast<
LuaEcsEntity *>(lua_touserdata(
L, lua_upvalueindex(1)));
std::cout << ent->id << " called!!!\n";
ent->e.each([&](flecs::id id) {
flecs::entity cmp =
ECS::get().entity(id);
if (cmp.is_alive()) {
const char *name =
cmp.name();
if (name)
std::cout
<< "component: "
<< name
<< std::endl;
}
});
return 0;
},
1);
} else if (component == "is_trigger") {
lua_pushvalue(L, 1);
lua_pushcclosure(
L,
[](lua_State *L) -> int {
luaL_checktype(L, lua_upvalueindex(1),
LUA_TUSERDATA);
LuaEcsEntity *ent = static_cast<
LuaEcsEntity *>(lua_touserdata(
L, lua_upvalueindex(1)));
lua_pushboolean(
L, ent->e.has<EventTrigger>());
return 1;
},
1);
} else if (component == "is_character") {
lua_pushvalue(L, 1);
lua_pushcclosure(
L,
[](lua_State *L) -> int {
luaL_checktype(L, lua_upvalueindex(1),
LUA_TUSERDATA);
LuaEcsEntity *ent = static_cast<
LuaEcsEntity *>(lua_touserdata(
L, lua_upvalueindex(1)));
lua_pushboolean(
L, ent->e.has<Character>());
return 1;
},
1);
} else if (component == "is_boat") {
lua_pushvalue(L, 1);
lua_pushcclosure(
L,
[](lua_State *L) -> int {
luaL_checktype(L, lua_upvalueindex(1),
LUA_TUSERDATA);
LuaEcsEntity *ent = static_cast<
LuaEcsEntity *>(lua_touserdata(
L, lua_upvalueindex(1)));
lua_pushboolean(L,
ent->e.has<BoatBase>());
return 1;
},
1);
} else if (component == "is_player") {
lua_pushvalue(L, 1);
lua_pushcclosure(
L,
[](lua_State *L) -> int {
luaL_checktype(L, lua_upvalueindex(1),
LUA_TUSERDATA);
LuaEcsEntity *ent = static_cast<
LuaEcsEntity *>(lua_touserdata(
L, lua_upvalueindex(1)));
lua_pushboolean(L,
ent->e.has<Player>());
return 1;
},
1);
} else
lua_pushnil(L);
return 1;
});
lua_settable(L, -3);
}
LuaData::~LuaData()

View File

@@ -12,6 +12,7 @@ struct LuaData {
std::vector<int> setup_handlers;
int setup_handler();
int call_handler(const Ogre::String &event);
int call_handler(const Ogre::String &event, flecs::entity e);
LuaData();
virtual ~LuaData();

View File

@@ -1,5 +1,5 @@
project(sceneloader)
add_library(sceneloader loader.cpp)
add_library(sceneloader STATIC loader.cpp)
target_include_directories(sceneloader PUBLIC .)
target_link_libraries(sceneloader PUBLIC OgreMain PRIVATE pugixml GameData)
target_link_libraries(sceneloader PUBLIC OgreTerrain)

View File

@@ -560,7 +560,7 @@ void SceneLoader::processNode(pugi::xml_node &XMLNode, SceneNode *pParent)
if (anyr.has_value())
r = Ogre::any_cast<float>(anyr);
e.set<ECS::EventTrigger>(
{ pNode, Ogre::Vector3(0, 0, 0), h, r, event });
{ pNode, Ogre::Vector3(0, 0, 0), h, r, event, pNode });
}
}