diff --git a/.vscode/settings.json b/.vscode/settings.json index 70c0c20..68b0f60 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -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" } } \ No newline at end of file diff --git a/assets/blender/vehicles/boat-gobbot.blend b/assets/blender/vehicles/boat-gobbot.blend new file mode 100644 index 0000000..e853c24 --- /dev/null +++ b/assets/blender/vehicles/boat-gobbot.blend @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e16bc4a41e531a083eb876d6bf1c6deeec2a9f2764f2ed89d132fb3a6cc3fdc5 +size 691678 diff --git a/assets/blender/vehicles/boat.blend b/assets/blender/vehicles/boat.blend index 19771ae..90a7604 100644 --- a/assets/blender/vehicles/boat.blend +++ b/assets/blender/vehicles/boat.blend @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:64b6e1ece8f3b453151d64ecccb377efddf36606fa45f89788298f110db81b02 -size 378269 +oid sha256:ff559da43b9e80e50d7193b9635a683768678c45c1313f5e05183e56e3de0fd8 +size 549955 diff --git a/assets/blender/vehicles/raft.blend b/assets/blender/vehicles/raft.blend new file mode 100644 index 0000000..c84bf03 --- /dev/null +++ b/assets/blender/vehicles/raft.blend @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:10d57e0918b872573d77821178f305da327904cec61fe6a49c61ddd1e9afd7b4 +size 395684 diff --git a/assets/blender/vehicles/tiny-boat.blend b/assets/blender/vehicles/tiny-boat.blend new file mode 100644 index 0000000..3329bdd --- /dev/null +++ b/assets/blender/vehicles/tiny-boat.blend @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4b7393545407478397119ac4eb87fee07eee7af037f46bfa8935739c4687ac03 +size 538165 diff --git a/lua-scripts/data.lua b/lua-scripts/data.lua index b8af6dc..9b9247f 100644 --- a/lua-scripts/data.lua +++ b/lua-scripts/data.lua @@ -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) diff --git a/src/gamedata/CMakeLists.txt b/src/gamedata/CMakeLists.txt index 77e41d7..82ca32b 100644 --- a/src/gamedata/CMakeLists.txt +++ b/src/gamedata/CMakeLists.txt @@ -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}) diff --git a/src/gamedata/CharacterAnimationModule.cpp b/src/gamedata/CharacterAnimationModule.cpp index 64f37cf..9e06095 100644 --- a/src/gamedata/CharacterAnimationModule.cpp +++ b/src/gamedata/CharacterAnimationModule.cpp @@ -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 parent_stack; - std::vector 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 - mruntimeData; - AnimationSystemBuilder *builder() - { - m_builder.animation_nodes.reserve(8); - m_builder.parent = nullptr; - return &m_builder; - } - void update(float delta) - { - std::deque 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(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(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(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(); @@ -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("main") + ->setAnimation("locomotion"); anim.mAnimationSystem ->get( - "state") + "locomotion-state") ->setAnimation("idle"); anim.configured = true; } }); - ecs.system("HandleAnimations1") + ecs.system( + "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("state") + ->get( + "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( + "HandleNPCAnimations") + .kind(flecs::OnUpdate) + .with() + .without() + .each([](flecs::entity e, const Input &input, + const CharacterBase &ch, AnimationControl &anim) { + if (!anim.configured) + return; + AnimationNodeStateMachine *state_machine = + anim.mAnimationSystem + ->get( + "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( "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( - "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); } }); } -} \ No newline at end of file +} diff --git a/src/gamedata/CharacterAnimationModule.h b/src/gamedata/CharacterAnimationModule.h index a8597d6..4d61e92 100644 --- a/src/gamedata/CharacterAnimationModule.h +++ b/src/gamedata/CharacterAnimationModule.h @@ -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( 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( - 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 animation_list; @@ -347,8 +368,11 @@ struct AnimationSystem : AnimationNode { std::list parent_stack; std::unordered_map nodeMap; std::vector 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 mAnimations; - // AnimationNodeStateMachine *mStateMachine; AnimationSystem *mAnimationSystem; }; struct CharacterAnimationModule { CharacterAnimationModule(flecs::world &ecs); - // void setAnimation(AnimationControl &anim); - // void fadeAnimations(AnimationControl &anim, Ogre::Real deltaTime); }; } #endif diff --git a/src/gamedata/EventTriggerModule.cpp b/src/gamedata/EventTriggerModule.cpp index b41435e..cc6a017 100644 --- a/src/gamedata/EventTriggerModule.cpp +++ b/src/gamedata/EventTriggerModule.cpp @@ -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++; } diff --git a/src/gamedata/EventTriggerModule.h b/src/gamedata/EventTriggerModule.h index b2ae612..e1506d7 100644 --- a/src/gamedata/EventTriggerModule.h +++ b/src/gamedata/EventTriggerModule.h @@ -10,6 +10,7 @@ struct EventTrigger { float halfheight; float radius; Ogre::String event; + Ogre::SceneNode *node; }; struct EventTriggerExit { Ogre::String event; diff --git a/src/gamedata/LuaData.cpp b/src/gamedata/LuaData.cpp index 3197839..7f9172c 100644 --- a/src/gamedata/LuaData.cpp +++ b/src/gamedata/LuaData.cpp @@ -12,11 +12,17 @@ int luaopen_lpeg(lua_State *L); } namespace ECS { +struct LuaEcsEntity { + int id; + flecs::entity e; +}; struct idmap { std::unordered_map id2entity; + std::unordered_map 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( + { "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( + 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()); + 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()); + 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()); + 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()); + return 1; + }, + 1); + } else + lua_pushnil(L); + return 1; + }); + lua_settable(L, -3); } LuaData::~LuaData() diff --git a/src/gamedata/LuaData.h b/src/gamedata/LuaData.h index 135a381..6e2af3b 100644 --- a/src/gamedata/LuaData.h +++ b/src/gamedata/LuaData.h @@ -12,6 +12,7 @@ struct LuaData { std::vector 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(); diff --git a/src/sceneloader/CMakeLists.txt b/src/sceneloader/CMakeLists.txt index b81b29b..8ac4aca 100644 --- a/src/sceneloader/CMakeLists.txt +++ b/src/sceneloader/CMakeLists.txt @@ -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) diff --git a/src/sceneloader/loader.cpp b/src/sceneloader/loader.cpp index d2ce170..e8d71d8 100644 --- a/src/sceneloader/loader.cpp +++ b/src/sceneloader/loader.cpp @@ -560,7 +560,7 @@ void SceneLoader::processNode(pugi::xml_node &XMLNode, SceneNode *pParent) if (anyr.has_value()) r = Ogre::any_cast(anyr); e.set( - { pNode, Ogre::Vector3(0, 0, 0), h, r, event }); + { pNode, Ogre::Vector3(0, 0, 0), h, r, event, pNode }); } }