New models; using raft
This commit is contained in:
47
.vscode/settings.json
vendored
47
.vscode/settings.json
vendored
@@ -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
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)
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
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
BIN
assets/blender/vehicles/tiny-boat.blend
(Stored with Git LFS)
Normal file
Binary file not shown.
@@ -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)
|
||||
|
||||
@@ -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})
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ struct EventTrigger {
|
||||
float halfheight;
|
||||
float radius;
|
||||
Ogre::String event;
|
||||
Ogre::SceneNode *node;
|
||||
};
|
||||
struct EventTriggerExit {
|
||||
Ogre::String event;
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user