converted to Jolt physics
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
#include "loader.h"
|
||||
#include "Components.h"
|
||||
#include "GameData.h"
|
||||
#include "PhysicsModule.h"
|
||||
#include "BoatModule.h"
|
||||
|
||||
namespace ECS
|
||||
@@ -14,7 +15,107 @@ BoatModule::BoatModule(flecs::world &ecs)
|
||||
{
|
||||
ecs.module<BoatModule>();
|
||||
ecs.component<BoatBase>();
|
||||
ecs.component<BoatBody>();
|
||||
ecs.component<BoatType>();
|
||||
ecs.component<SpawnBoat>();
|
||||
ecs.observer<const EngineData, const BoatType>("CreateBoat")
|
||||
.event(flecs::OnSet)
|
||||
.without<BoatBase>()
|
||||
.without<SpawnBoat>()
|
||||
.each([&](flecs::entity e, const EngineData &eng,
|
||||
const BoatType &type) { e.add<SpawnBoat>(); });
|
||||
ecs.system<const EngineData, const BoatType>("CreateBoat")
|
||||
.kind(flecs::OnUpdate)
|
||||
.without<BoatBase>()
|
||||
.with<WaterReady>()
|
||||
.with<SpawnBoat>()
|
||||
.each([&](flecs::entity e, const EngineData &eng,
|
||||
const BoatType &type) {
|
||||
if (type.resourceName.find(".scene") !=
|
||||
std::string::npos) {
|
||||
BoatBase &boat = e.ensure<BoatBase>();
|
||||
int i;
|
||||
std::vector<Ogre::SceneNode *> colliderTarget;
|
||||
boat.mNode =
|
||||
ECS::get<EngineData>()
|
||||
.mScnMgr->getRootSceneNode()
|
||||
->createChildSceneNode(
|
||||
type.position,
|
||||
type.orientation);
|
||||
auto pnodes = boat.mNode->getChildren();
|
||||
for (i = 0; i < pnodes.size(); i++) {
|
||||
Ogre::SceneNode *pnode =
|
||||
static_cast<Ogre::SceneNode *>(
|
||||
pnodes[i]);
|
||||
Ogre::Any any =
|
||||
pnode->getUserObjectBindings()
|
||||
.getUserAny("type");
|
||||
if (!any.has_value())
|
||||
continue;
|
||||
Ogre::String obj_type =
|
||||
Ogre::any_cast<Ogre::String>(
|
||||
any);
|
||||
if (obj_type == "hull-collider") {
|
||||
/* FIXME */
|
||||
}
|
||||
}
|
||||
{
|
||||
Ogre::SceneNode *attachment =
|
||||
eng.mScnMgr->getRootSceneNode()
|
||||
->createChildSceneNode();
|
||||
Ogre::DataStreamPtr scene =
|
||||
Ogre::ResourceGroupManager::getSingleton()
|
||||
.openResource(
|
||||
type.resourceName,
|
||||
Ogre::ResourceGroupManager::
|
||||
AUTODETECT_RESOURCE_GROUP_NAME);
|
||||
SceneLoader loader;
|
||||
loader.load(scene, "General",
|
||||
attachment, e);
|
||||
// attachment->loadChildren(type.resourceName);
|
||||
std::vector<Ogre::Node *> v =
|
||||
attachment->getChildren();
|
||||
OgreAssert(v.size() == 1,
|
||||
"Bad root nodes count in " +
|
||||
type.resourceName);
|
||||
Ogre::Any any =
|
||||
static_cast<Ogre::SceneNode *>(
|
||||
v[0])
|
||||
->getUserObjectBindings()
|
||||
.getUserAny("type");
|
||||
OgreAssert(any.has_value(),
|
||||
"no \"type\" costom prop");
|
||||
Ogre::String obj_type =
|
||||
Ogre::any_cast<Ogre::String>(
|
||||
any);
|
||||
std::cout << "type: " << obj_type
|
||||
<< std::endl;
|
||||
OgreAssert(obj_type == "boat",
|
||||
"not a boat");
|
||||
boat.mNode =
|
||||
static_cast<Ogre::SceneNode *>(
|
||||
v[0]);
|
||||
boat.mNode->_setDerivedPosition(
|
||||
type.position);
|
||||
boat.mNode->_setDerivedOrientation(
|
||||
type.orientation);
|
||||
boat.mEnt = static_cast<Ogre::Entity *>(
|
||||
boat.mNode->getAttachedObject(
|
||||
std::to_string(
|
||||
(int)e.raw_id()) +
|
||||
"/boat"));
|
||||
loader.setupPhysicsBody(boat.mNode,
|
||||
boat.mEnt, e);
|
||||
e.remove<SpawnBoat>();
|
||||
e.modified<BoatBase>();
|
||||
}
|
||||
// BoatBody &body = e.ensure<BoatBody>();
|
||||
// e.modified<BoatBase>();
|
||||
}
|
||||
// ECS::get_mut<ECS::EngineData>().enableDbgDraw = true;
|
||||
// ECS::modified<ECS::EngineData>();
|
||||
// e.modified<BoatBody>();
|
||||
});
|
||||
#if 0
|
||||
ecs.system<const EngineData, BoatType, Body2Entity>("CreateBoat")
|
||||
.kind(flecs::OnUpdate)
|
||||
.without<BoatBase>()
|
||||
@@ -33,6 +134,7 @@ BoatModule::BoatModule(flecs::world &ecs)
|
||||
type.orientation);
|
||||
boat.mNode->attachObject(boat.mEnt);
|
||||
|
||||
#if 0
|
||||
BoatBody &body = e.ensure<BoatBody>();
|
||||
body.body =
|
||||
ECS::get<EngineData>()
|
||||
@@ -41,6 +143,7 @@ BoatModule::BoatModule(flecs::world &ecs)
|
||||
Ogre::Bullet::CT_TRIMESH,
|
||||
nullptr, 2, 0x7fffffff);
|
||||
b2e.entities[body.body] = e;
|
||||
#endif
|
||||
} else if (type.resourceName.find(".scene") !=
|
||||
std::string::npos) {
|
||||
int i;
|
||||
@@ -105,14 +208,27 @@ BoatModule::BoatModule(flecs::world &ecs)
|
||||
boat.mNode->getAttachedObject(
|
||||
std::to_string((int)e.raw_id()) +
|
||||
"/boat"));
|
||||
loader.setupPhysicsBody(boat.mNode, boat.mEnt);
|
||||
BoatBody &body = e.ensure<BoatBody>();
|
||||
#if 0
|
||||
Ogre::Any bodyA =
|
||||
boat.mNode->getUserObjectBindings()
|
||||
.getUserAny("bodyPointer");
|
||||
if (bodyA.has_value())
|
||||
body.body =
|
||||
Ogre::any_cast<btRigidBody *>(
|
||||
bodyA);
|
||||
#if 0
|
||||
body.body =
|
||||
ECS::get<EngineData>()
|
||||
.mWorld->addRigidBody(
|
||||
0, boat.mEnt,
|
||||
Ogre::Bullet::CT_TRIMESH,
|
||||
nullptr, 2, 0x7fffffff);
|
||||
#endif
|
||||
OgreAssert(body.body, "No body :()");
|
||||
b2e.entities[body.body] = e;
|
||||
#endif
|
||||
std::vector<Ogre::Node *> slots =
|
||||
boat.mNode->getChildren();
|
||||
for (i = 0; i < slots.size(); i++) {
|
||||
@@ -167,7 +283,10 @@ BoatModule::BoatModule(flecs::world &ecs)
|
||||
}
|
||||
}
|
||||
}
|
||||
// ECS::get_mut<ECS::EngineData>().enableDbgDraw = true;
|
||||
// ECS::modified<ECS::EngineData>();
|
||||
e.modified<BoatBody>();
|
||||
});
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,9 +18,7 @@ struct BoatBase {
|
||||
Ogre::Entity *mEnt;
|
||||
Ogre::SceneNode *mNode;
|
||||
};
|
||||
struct BoatBody {
|
||||
btRigidBody *body;
|
||||
};
|
||||
struct SpawnBoat {};
|
||||
struct BoatModule {
|
||||
BoatModule(flecs::world &ecs);
|
||||
};
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
project(gamedata)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
find_package(OGRE REQUIRED COMPONENTS Bites Bullet Paging Terrain Overlay CONFIG)
|
||||
find_package(Bullet REQUIRED)
|
||||
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 SmartObject.cpp goap.cpp)
|
||||
target_link_libraries(GameData PUBLIC OgreMain OgreBites OgreBullet
|
||||
OgrePaging OgreTerrain OgreOverlay flecs::flecs_static
|
||||
lua ${BULLET_LIBRARIES} PRIVATE sceneloader world-build)
|
||||
target_include_directories(GameData PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${BULLET_INCLUDE_DIR})
|
||||
BoatModule.cpp EventTriggerModule.cpp CharacterAnimationModule.cpp PhysicsModule.cpp SmartObject.cpp SlotsModule.cpp goap.cpp)
|
||||
target_link_libraries(GameData PUBLIC lua flecs::flecs_static OgreMain OgreBites
|
||||
OgrePaging OgreTerrain OgreOverlay
|
||||
PRIVATE sceneloader world-build physics)
|
||||
target_include_directories(GameData PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${BULLET_INCLUDE_DIR} ../luaaa)
|
||||
target_compile_definitions(GameData PRIVATE FLECS_CPP_NO_AUTO_REGISTRATION)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "Components.h"
|
||||
#include "EventTriggerModule.h"
|
||||
#include "CharacterModule.h"
|
||||
#include "PhysicsModule.h"
|
||||
#include "CharacterAnimationModule.h"
|
||||
#include "world-build.h"
|
||||
namespace ECS
|
||||
@@ -228,6 +229,7 @@ CharacterAnimationModule::CharacterAnimationModule(flecs::world &ecs)
|
||||
}
|
||||
#endif
|
||||
v.velocity = rot * boneMotion / safeDelta;
|
||||
#if 0
|
||||
if (!e.has<CharacterDisablePhysics>() &&
|
||||
!e.has<CharacterInActuator>()) {
|
||||
if (eng.startupDelay <= 0.0f)
|
||||
@@ -235,6 +237,7 @@ CharacterAnimationModule::CharacterAnimationModule(flecs::world &ecs)
|
||||
v.velocity.y = Ogre::Math::Clamp(v.velocity.y,
|
||||
-10.5f, 10.0f);
|
||||
}
|
||||
#endif
|
||||
// if (v.velocity.squaredLength() > 1.4f * 1.4f)
|
||||
// v.velocity = v.velocity.normalisedCopy() * 1.4f;
|
||||
// ch.mBoneMotion = Ogre::Vector3::ZERO;
|
||||
@@ -246,7 +249,11 @@ CharacterAnimationModule::CharacterAnimationModule(flecs::world &ecs)
|
||||
Ogre::Math::Clamp(v.velocity.z, -16.0f, 16.0f);
|
||||
v.velocity.y =
|
||||
Ogre::Math::Clamp(v.velocity.y, -10.5f, 10.0f);
|
||||
#if 0
|
||||
v.velocity.y = 0.0f;
|
||||
#endif
|
||||
});
|
||||
#if 0
|
||||
ecs.system<const EngineData, const AnimationControl,
|
||||
const CharacterBase, CharacterVelocity>("HandleSwimming")
|
||||
.kind(flecs::OnUpdate)
|
||||
@@ -271,12 +278,13 @@ CharacterAnimationModule::CharacterAnimationModule(flecs::world &ecs)
|
||||
h * eng.delta;
|
||||
}
|
||||
});
|
||||
ecs.system<const EngineData, CharacterBase, CharacterBody,
|
||||
AnimationControl, CharacterVelocity>("HandleRootMotion")
|
||||
#endif
|
||||
ecs.system<const EngineData, CharacterBase, AnimationControl,
|
||||
CharacterVelocity>("HandleRootMotion")
|
||||
.kind(flecs::OnUpdate)
|
||||
.each([this](flecs::entity e, const EngineData &eng,
|
||||
CharacterBase &ch, CharacterBody &body,
|
||||
AnimationControl &anim, CharacterVelocity &v) {
|
||||
CharacterBase &ch, AnimationControl &anim,
|
||||
CharacterVelocity &v) {
|
||||
if (!ch.mBodyNode)
|
||||
return;
|
||||
if (eng.delta < 0.0000001f)
|
||||
@@ -286,6 +294,7 @@ CharacterAnimationModule::CharacterAnimationModule(flecs::world &ecs)
|
||||
Ogre::Vector3 colNormal;
|
||||
bool is_on_floor = false;
|
||||
bool penetration = false;
|
||||
#if 0
|
||||
if (eng.startupDelay < 0.0f) {
|
||||
if (body.mController) {
|
||||
Ogre::Vector3 rotMotion =
|
||||
@@ -321,7 +330,9 @@ CharacterAnimationModule::CharacterAnimationModule(flecs::world &ecs)
|
||||
rotMotion);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
});
|
||||
#if 0
|
||||
ecs.system<CharacterVelocity, CharacterBase>("HandleRootMotionEnd")
|
||||
.kind(flecs::OnUpdate)
|
||||
.each([this](flecs::entity e, CharacterVelocity &v,
|
||||
@@ -330,6 +341,7 @@ CharacterAnimationModule::CharacterAnimationModule(flecs::world &ecs)
|
||||
// v.velocity = Ogre::Vector3::ZERO;
|
||||
// ch.mBoneMotion = Ogre::Vector3::ZERO;
|
||||
});
|
||||
#endif
|
||||
|
||||
ecs.system<const Input, const CharacterBase, AnimationControl>(
|
||||
"HandleNPCAnimations")
|
||||
@@ -576,6 +588,7 @@ CharacterAnimationModule::CharacterAnimationModule(flecs::world &ecs)
|
||||
<< std::endl;
|
||||
});
|
||||
#endif
|
||||
#if 0
|
||||
ecs.system<const EngineData, const CharacterBase, CharacterBody>(
|
||||
"UpdateBodyCast")
|
||||
.kind(flecs::OnUpdate)
|
||||
@@ -655,6 +668,7 @@ CharacterAnimationModule::CharacterAnimationModule(flecs::world &ecs)
|
||||
result.m_collisionObject)));
|
||||
}
|
||||
});
|
||||
#endif
|
||||
struct AnimationSetCommand : public GameWorld::Command {
|
||||
int operator()(const std::vector<GameWorld::Parameter *> &args)
|
||||
override
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#include <iostream>
|
||||
#include <Ogre.h>
|
||||
#include <OgreBullet.h>
|
||||
#include "GameData.h"
|
||||
#include "WaterModule.h"
|
||||
#include "TerrainModule.h"
|
||||
#include "Components.h"
|
||||
#include "PhysicsModule.h"
|
||||
#include "CharacterAnimationModule.h"
|
||||
#include "CharacterModule.h"
|
||||
#include "goap.h"
|
||||
@@ -17,8 +17,10 @@ CharacterModule::CharacterModule(flecs::world &ecs)
|
||||
ecs.component<Character>();
|
||||
ecs.component<Player>();
|
||||
ecs.component<CharacterBase>();
|
||||
ecs.component<CharacterVelocity>();
|
||||
ecs.component<CharacterBody>();
|
||||
ecs.component<CharacterGravity>();
|
||||
ecs.component<CharacterLocation>();
|
||||
ecs.component<CharacterBuoyancy>();
|
||||
ecs.component<CharacterConf>();
|
||||
ecs.component<CharacterDisablePhysics>();
|
||||
ecs.component<CharacterUpdatePhysicsState>();
|
||||
ecs.component<CharacterInActuator>();
|
||||
@@ -125,6 +127,7 @@ CharacterModule::CharacterModule(flecs::world &ecs)
|
||||
else if (current_subm < 0.8f)
|
||||
ch.is_submerged = false;
|
||||
});
|
||||
#if 0
|
||||
ecs.system<const EngineData, const CharacterBase, CharacterVelocity>(
|
||||
"HandleGravityBouyanceWater")
|
||||
.kind(flecs::OnUpdate)
|
||||
@@ -164,6 +167,8 @@ CharacterModule::CharacterModule(flecs::world &ecs)
|
||||
gr.gvelocity *= (1.0 - eng.delta);
|
||||
gr.velocity.y *= (1.0 - eng.delta);
|
||||
});
|
||||
#endif
|
||||
#if 0
|
||||
ecs.system<const EngineData, const CharacterBase, CharacterVelocity>(
|
||||
"HandleGravityNoWater")
|
||||
.kind(flecs::OnUpdate)
|
||||
@@ -183,6 +188,7 @@ CharacterModule::CharacterModule(flecs::world &ecs)
|
||||
gr.gvelocity *= (1.0 - eng.delta);
|
||||
gr.velocity.y *= (1.0 - eng.delta);
|
||||
});
|
||||
#endif
|
||||
#define TURN_SPEED 500.0f // character turning in degrees per second
|
||||
ecs.system<const Input, const Camera, CharacterBase>("UpdateBody")
|
||||
.kind(flecs::OnUpdate)
|
||||
@@ -235,6 +241,7 @@ CharacterModule::CharacterModule(flecs::world &ecs)
|
||||
ch.mBodyNode->yaw(Ogre::Degree(yawToGoal));
|
||||
}
|
||||
});
|
||||
#if 0
|
||||
ecs.system<const EngineData, CharacterLocation, CharacterBase,
|
||||
CharacterBody>("UpdateCharacterBase")
|
||||
.kind(flecs::OnUpdate)
|
||||
@@ -251,6 +258,40 @@ CharacterModule::CharacterModule(flecs::world &ecs)
|
||||
ch.mBodyNode->_getDerivedPosition();
|
||||
}
|
||||
});
|
||||
#endif
|
||||
ecs.observer<const EngineData, const CharacterLocation,
|
||||
const CharacterConf>("SetupCharacterM")
|
||||
.event(flecs::OnSet)
|
||||
.with<Character>()
|
||||
.without<CharacterBase>()
|
||||
.each([](flecs::entity e, const EngineData &eng,
|
||||
const CharacterLocation &loc,
|
||||
const CharacterConf &conf) {
|
||||
CharacterBase &ch = e.ensure<CharacterBase>();
|
||||
AnimationControl &anim = e.ensure<AnimationControl>();
|
||||
ch.mBodyEnt = eng.mScnMgr->createEntity(conf.type);
|
||||
ch.mBodyNode = eng.mScnMgr->getRootSceneNode()
|
||||
->createChildSceneNode();
|
||||
ch.mBodyNode->setOrientation(loc.orientation);
|
||||
ch.mBodyNode->setPosition(loc.position);
|
||||
ch.mBodyNode->attachObject(ch.mBodyEnt);
|
||||
ch.mSkeleton = ch.mBodyEnt->getSkeleton();
|
||||
OgreAssert(ch.mBodyEnt->getSkeleton()->hasBone("Root"),
|
||||
"No root bone");
|
||||
OgreAssert(ch.mSkeleton->hasBone("Root"),
|
||||
"No root bone");
|
||||
ch.mRootBone = ch.mSkeleton->getBone("Root");
|
||||
OgreAssert(ch.mRootBone, "No root bone");
|
||||
// body.mController = nullptr;
|
||||
ch.mBoneMotion = Ogre::Vector3::ZERO;
|
||||
ch.mBonePrevMotion = Ogre::Vector3::ZERO;
|
||||
e.set<CharacterVelocity>(
|
||||
{ { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } });
|
||||
e.add<CharacterGravity>();
|
||||
e.add<CharacterBuoyancy>();
|
||||
anim.configured = false;
|
||||
});
|
||||
#if 0
|
||||
ecs.system<const EngineData, const CharacterLocation,
|
||||
const CharacterConf, Body2Entity>("SetupCharacter")
|
||||
.kind(flecs::OnUpdate)
|
||||
@@ -276,13 +317,14 @@ CharacterModule::CharacterModule(flecs::world &ecs)
|
||||
"No root bone");
|
||||
ch.mRootBone = ch.mSkeleton->getBone("Root");
|
||||
OgreAssert(ch.mRootBone, "No root bone");
|
||||
body.mController = nullptr;
|
||||
// body.mController = nullptr;
|
||||
ch.mBoneMotion = Ogre::Vector3::ZERO;
|
||||
ch.mBonePrevMotion = Ogre::Vector3::ZERO;
|
||||
e.set<CharacterVelocity>(
|
||||
{ { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } });
|
||||
body.checkGround = false;
|
||||
body.checkGroundResult = false;
|
||||
#if 0
|
||||
body.mCollisionShape = nullptr;
|
||||
body.mGhostObject = nullptr;
|
||||
body.mController = nullptr;
|
||||
@@ -320,12 +362,15 @@ CharacterModule::CharacterModule(flecs::world &ecs)
|
||||
body.mGhostObject, ch.mBodyEnt, 1, 0x7FFFFFFF);
|
||||
OgreAssert(body.mGhostObject, "Need GhostObject");
|
||||
OgreAssert(body.mCollisionShape, "No collision shape");
|
||||
#endif
|
||||
e.add<CharacterGravity>();
|
||||
e.add<CharacterBuoyancy>();
|
||||
anim.configured = false;
|
||||
OgreAssert(body.mGhostObject->hasContactResponse(),
|
||||
"need contact response");
|
||||
// OgreAssert(body.mGhostObject->hasContactResponse(),
|
||||
// "need contact response");
|
||||
});
|
||||
#endif
|
||||
#if 0
|
||||
ecs.system<const EngineData, CharacterBase, CharacterBody>(
|
||||
"UpdateCharacterPhysics")
|
||||
.kind(flecs::OnUpdate)
|
||||
@@ -334,17 +379,21 @@ CharacterModule::CharacterModule(flecs::world &ecs)
|
||||
.with<WaterReady>()
|
||||
.each([](const EngineData &eng, CharacterBase &ch,
|
||||
CharacterBody &body) {
|
||||
#if 0
|
||||
if (ch.mBodyNode && !body.mController &&
|
||||
eng.startupDelay < 0.0f) {
|
||||
body.mController =
|
||||
new Ogre::Bullet::KinematicMotionSimple(
|
||||
body.mGhostObject,
|
||||
ch.mBodyNode);
|
||||
body.mController->enableManualNarrowPhase(true);
|
||||
eng.mWorld->getBtWorld()->addAction(
|
||||
body.mController);
|
||||
OgreAssert(body.mController, "Need controller");
|
||||
}
|
||||
#endif
|
||||
});
|
||||
#endif
|
||||
#define CAM_HEIGHT 1.6f // height of camera above character's center of mass
|
||||
ecs.system<const EngineData, Camera, const CharacterBase>(
|
||||
"UpdateCamera")
|
||||
@@ -394,6 +443,7 @@ CharacterModule::CharacterModule(flecs::world &ecs)
|
||||
Ogre::Node::TS_PARENT);
|
||||
}
|
||||
});
|
||||
#if 0
|
||||
class ClosestNotMeRayResultCallback
|
||||
: public btCollisionWorld::ClosestRayResultCallback {
|
||||
btCollisionObject *mMe;
|
||||
@@ -416,12 +466,14 @@ CharacterModule::CharacterModule(flecs::world &ecs)
|
||||
rayResult, normalInWorldSpace);
|
||||
}
|
||||
};
|
||||
ecs.system<const EngineData, CharacterBody>("CheckGround")
|
||||
#endif
|
||||
ecs.system<const EngineData, CharacterBase>("CheckGround")
|
||||
.kind(flecs::OnUpdate)
|
||||
.with<Character>()
|
||||
.with<Player>()
|
||||
.without<GroundCheckReady>()
|
||||
.each([](const EngineData &eng, CharacterBody &body) {
|
||||
.each([](const EngineData &eng, CharacterBase &ch) {
|
||||
#if 0
|
||||
if (body.mGhostObject) {
|
||||
btVector3 from =
|
||||
body.mGhostObject->getWorldTransform()
|
||||
@@ -437,7 +489,10 @@ CharacterModule::CharacterModule(flecs::world &ecs)
|
||||
if (resultCallback.hasHit())
|
||||
ECS::get().add<GroundCheckReady>();
|
||||
}
|
||||
#endif
|
||||
ECS::get().add<GroundCheckReady>();
|
||||
});
|
||||
#if 0
|
||||
ecs.system<const WaterBody, const CharacterBase, CharacterBody>(
|
||||
"CharacterWater1")
|
||||
.kind(flecs::OnUpdate)
|
||||
@@ -445,11 +500,13 @@ CharacterModule::CharacterModule(flecs::world &ecs)
|
||||
.without<InWater>()
|
||||
.each([](flecs::entity e, const WaterBody &waterb,
|
||||
const CharacterBase &ch, CharacterBody &body) {
|
||||
#if 0
|
||||
if (waterb.isInWater(body.mGhostObject) &&
|
||||
ch.mBodyNode->_getDerivedPosition().y < -0.05f) {
|
||||
e.add<InWater>();
|
||||
std::cout << "Big Splash\n";
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
if (waterb.mInWater.find(body.mGhostObject) ==
|
||||
waterb.mInWater.end())
|
||||
@@ -457,6 +514,8 @@ CharacterModule::CharacterModule(flecs::world &ecs)
|
||||
std::cout << waterb.mInWater.size() << " InWater\n";
|
||||
#endif
|
||||
});
|
||||
#endif
|
||||
#if 0
|
||||
ecs.system<const WaterBody, const CharacterBase, CharacterBody>(
|
||||
"CharacterWater2")
|
||||
.kind(flecs::OnUpdate)
|
||||
@@ -465,12 +524,15 @@ CharacterModule::CharacterModule(flecs::world &ecs)
|
||||
.each([](flecs::entity e, const WaterBody &waterb,
|
||||
const CharacterBase &ch, CharacterBody &body) {
|
||||
float h = ch.mBodyNode->_getDerivedPosition().y;
|
||||
#if 0
|
||||
if (waterb.isInWater(body.mGhostObject) && h > 0.05f)
|
||||
e.remove<InWater>();
|
||||
else if (!waterb.isInWater(body.mGhostObject) &&
|
||||
h > 0.05f)
|
||||
e.remove<InWater>();
|
||||
#endif
|
||||
});
|
||||
#endif
|
||||
#if 0
|
||||
ecs.system<const EngineData, CharacterBase, CharacterBody>(
|
||||
"DisplayPlayerPos")
|
||||
@@ -483,39 +545,14 @@ CharacterModule::CharacterModule(flecs::world &ecs)
|
||||
<< "\n";
|
||||
});
|
||||
#endif
|
||||
ecs.system<const EngineData, const CharacterBase, ParentSlot>(
|
||||
"UpdatePhysics2")
|
||||
.kind(flecs::OnUpdate)
|
||||
.with<CharacterDisablePhysics>()
|
||||
.each([](flecs::entity e, const EngineData &eng,
|
||||
const CharacterBase &ch, ParentSlot &slot) {
|
||||
if (slot.parent_e.has<ObjectSlots>()) {
|
||||
const ObjectSlots &slots =
|
||||
slot.parent_e.get<ObjectSlots>();
|
||||
if (slots.slots.find(slot.slot_name) ==
|
||||
slots.slots.end())
|
||||
// invalid setting
|
||||
e.remove<ParentSlot>();
|
||||
if (slot.activated)
|
||||
return;
|
||||
Ogre::SceneNode *slot_base =
|
||||
slots.slots.at(slot.slot_name).second;
|
||||
Ogre::Vector3 position =
|
||||
slot_base->_getDerivedPosition();
|
||||
Ogre::Quaternion orientation =
|
||||
slot_base->_getDerivedOrientation();
|
||||
ch.mBodyNode->_setDerivedPosition(position);
|
||||
ch.mBodyNode->_setDerivedOrientation(
|
||||
orientation);
|
||||
slot.activated = true;
|
||||
}
|
||||
});
|
||||
#if 0
|
||||
ecs.system<const EngineData, const CharacterBody>("UpdatePhysics")
|
||||
.kind(flecs::OnUpdate)
|
||||
.with<CharacterUpdatePhysicsState>()
|
||||
.write<CharacterUpdatePhysicsState>()
|
||||
.each([](flecs::entity e, const EngineData &eng,
|
||||
const CharacterBody &body) {
|
||||
#if 0
|
||||
if (e.has<CharacterDisablePhysics>()) {
|
||||
eng.mWorld->getBtWorld()->removeAction(
|
||||
body.mController);
|
||||
@@ -523,8 +560,10 @@ CharacterModule::CharacterModule(flecs::world &ecs)
|
||||
eng.mWorld->getBtWorld()->addAction(
|
||||
body.mController);
|
||||
}
|
||||
#endif
|
||||
e.remove<CharacterUpdatePhysicsState>();
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
void CharacterModule::updateCameraGoal(Camera &camera, Ogre::Real deltaYaw,
|
||||
@@ -726,4 +765,4 @@ CharacterAIModule::CharacterAIModule(flecs::world &ecs)
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef CHARACTER_MODULE_H_
|
||||
#define CHARACTER_MODULE_H_
|
||||
#include <flecs.h>
|
||||
#include <Ogre.h>
|
||||
#include "goap.h"
|
||||
namespace ECS
|
||||
{
|
||||
@@ -34,17 +35,6 @@ struct CharacterLocation {
|
||||
struct CharacterConf {
|
||||
Ogre::String type;
|
||||
};
|
||||
struct CharacterBody {
|
||||
btPairCachingGhostObject *mGhostObject;
|
||||
btCompoundShape *mCollisionShape;
|
||||
Ogre::Bullet::KinematicMotionSimple *mController;
|
||||
bool checkGround;
|
||||
bool checkGroundResult;
|
||||
};
|
||||
struct CharacterVelocity {
|
||||
Ogre::Vector3 gvelocity;
|
||||
Ogre::Vector3 velocity;
|
||||
};
|
||||
struct CharacterInActuator {
|
||||
Ogre::String animationState;
|
||||
Vector3 prevMotion;
|
||||
@@ -73,4 +63,4 @@ struct CharacterAIModule {
|
||||
CharacterAIModule(flecs::world &ecs);
|
||||
};
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#define COMPONENTS_H_
|
||||
#include <flecs.h>
|
||||
#include <Ogre.h>
|
||||
#include <OgreBullet.h>
|
||||
namespace Ogre
|
||||
{
|
||||
class ImGuiOverlay;
|
||||
@@ -20,7 +19,6 @@ struct GameData {
|
||||
};
|
||||
struct EngineData {
|
||||
Ogre::SceneManager *mScnMgr;
|
||||
Ogre::Bullet::DynamicsWorld *mWorld;
|
||||
float delta;
|
||||
float startupDelay;
|
||||
int width;
|
||||
@@ -75,24 +73,15 @@ struct App {
|
||||
std::vector<OgreBites::InputListener *> listeners;
|
||||
};
|
||||
struct CollisionShape {
|
||||
btCollisionShape *shape;
|
||||
void *shape;
|
||||
};
|
||||
struct InWater {};
|
||||
struct TerrainReady {};
|
||||
struct WaterAlmostReady {};
|
||||
struct WaterReady {};
|
||||
struct GroundCheckReady {};
|
||||
struct ParentSlot {
|
||||
flecs::entity parent_e;
|
||||
Ogre::String slot_name;
|
||||
bool activated;
|
||||
};
|
||||
struct ObjectSlots {
|
||||
std::unordered_map<Ogre::String,
|
||||
std::pair<Ogre::String, Ogre::SceneNode *> >
|
||||
slots;
|
||||
};
|
||||
struct Body2Entity {
|
||||
std::unordered_map<btCollisionObject *, flecs::entity> entities;
|
||||
/* std::unordered_map<btCollisionObject *, flecs::entity> entities; */
|
||||
};
|
||||
}
|
||||
#endif
|
||||
@@ -1,11 +1,14 @@
|
||||
#include <iostream>
|
||||
#include <OgreBullet.h>
|
||||
#include <OgreMeshManager.h>
|
||||
#include "Components.h"
|
||||
#include "GameData.h"
|
||||
#include "LuaData.h"
|
||||
#include "EventTriggerModule.h"
|
||||
|
||||
struct TriggerBody {
|
||||
void *data;
|
||||
};
|
||||
#if 0
|
||||
struct TriggerBody {
|
||||
btPairCachingGhostObject *mBody;
|
||||
btCylinderShape *shape;
|
||||
@@ -58,10 +61,22 @@ struct DeepPenetrationContactResultCallback : public btManifoldResult {
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
ECS::EventTriggerModule::EventTriggerModule(flecs::world &ecs)
|
||||
{
|
||||
ecs.module<EventTriggerModule>();
|
||||
ecs.component<EventTrigger>();
|
||||
ecs.component<EventTriggerData>();
|
||||
ecs.observer<const EngineData, const EventTrigger>("CreateTrigger")
|
||||
.event(flecs::OnSet)
|
||||
.each([](flecs::entity e, const EngineData &eng,
|
||||
const EventTrigger &trigger) {
|
||||
e.set<EventTriggerData>({});
|
||||
ECS::get<LuaBase>().mLua->call_handler(
|
||||
"actuator_created", e, e);
|
||||
});
|
||||
#if 0
|
||||
ecs.component<EventTriggerData>();
|
||||
ecs.component<TriggerBody>().on_add([](flecs::entity e,
|
||||
TriggerBody &body) {
|
||||
@@ -311,4 +326,5 @@ ECS::EventTriggerModule::EventTriggerModule(flecs::world &ecs)
|
||||
it++;
|
||||
}
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "BoatModule.h"
|
||||
#include "EventTriggerModule.h"
|
||||
#include "CharacterAnimationModule.h"
|
||||
#include "PhysicsModule.h"
|
||||
#include "world-build.h"
|
||||
|
||||
namespace ECS
|
||||
@@ -27,6 +28,7 @@ void setup_minimal()
|
||||
ecs.import <GameWorldModule>();
|
||||
ecs.component<InWater>();
|
||||
ecs.component<WaterReady>().add(flecs::Singleton);
|
||||
ecs.component<WaterAlmostReady>().add(flecs::Singleton);
|
||||
ecs.component<GroundCheckReady>().add(flecs::Singleton);
|
||||
ecs.component<App>()
|
||||
.on_add([](App &app) {
|
||||
@@ -37,26 +39,24 @@ void setup_minimal()
|
||||
.add(flecs::Singleton);
|
||||
/* lots of things depend on it */
|
||||
ecs.component<TerrainReady>().add(flecs::Singleton);
|
||||
ecs.component<ParentSlot>();
|
||||
ecs.component<ObjectSlots>();
|
||||
ecs.component<Body2Entity>().add(flecs::Singleton);
|
||||
}
|
||||
void setup(Ogre::SceneManager *scnMgr, Ogre::Bullet::DynamicsWorld *world,
|
||||
Ogre::SceneNode *cameraNode, Ogre::Camera *camera,
|
||||
Ogre::RenderWindow *window)
|
||||
void setup(Ogre::SceneManager *scnMgr, Ogre::SceneNode *cameraNode,
|
||||
Ogre::Camera *camera, Ogre::RenderWindow *window)
|
||||
{
|
||||
std::cout << "Setup GameData\n";
|
||||
setup_minimal();
|
||||
ecs.import <WaterModule>();
|
||||
ecs.component<RenderWindow>().add(flecs::Singleton);
|
||||
ecs.import <CharacterModule>();
|
||||
ecs.import <TerrainModule>();
|
||||
ecs.import <BoatModule>();
|
||||
ecs.import <PhysicsModule>();
|
||||
ecs.import <WaterModule>();
|
||||
ecs.import <SunModule>();
|
||||
ecs.import <TerrainModule>();
|
||||
ecs.import <GUIModule>();
|
||||
ecs.import <EventTriggerModule>();
|
||||
ecs.import <LuaModule>();
|
||||
ecs.import <WorldMapModule>();
|
||||
ecs.import <LuaModule>();
|
||||
ecs.import <BoatModule>();
|
||||
ecs.import <EventTriggerModule>();
|
||||
ecs.import <CharacterAnimationModule>();
|
||||
|
||||
ecs.system<EngineData>("UpdateDelta")
|
||||
@@ -89,9 +89,8 @@ void setup(Ogre::SceneManager *scnMgr, Ogre::Bullet::DynamicsWorld *world,
|
||||
std::cout << "ground check ready\n";
|
||||
#endif
|
||||
});
|
||||
ecs.set<EngineData>({ scnMgr, world, 0.0f, 5.0f,
|
||||
(int)window->getWidth(), (int)window->getHeight(),
|
||||
false });
|
||||
ecs.set<EngineData>({ scnMgr, 0.0f, 5.0f, (int)window->getWidth(),
|
||||
(int)window->getHeight(), false });
|
||||
ecs.set<Camera>({ cameraNode, camera, false });
|
||||
ecs.add<GameData>();
|
||||
ecs.add<Input>();
|
||||
@@ -105,7 +104,7 @@ void setup(Ogre::SceneManager *scnMgr, Ogre::Bullet::DynamicsWorld *world,
|
||||
nullptr,
|
||||
false,
|
||||
{ 0, 0, 0 } });
|
||||
ecs.set<Body2Entity>({});
|
||||
// ecs.set<Body2Entity>({});
|
||||
std::cout << "Setup GameData done\n";
|
||||
|
||||
/* Create player */
|
||||
@@ -129,4 +128,4 @@ bool Vector3::zeroLength() const
|
||||
float l = x * x + y * y + z * z;
|
||||
return (l < 1e-06 * 1e-06);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
#ifndef GAMEDATA_H
|
||||
#define GAMEDATA_H
|
||||
#include <OgreBullet.h>
|
||||
#include <flecs.h>
|
||||
namespace ECS
|
||||
{
|
||||
extern flecs::entity player;
|
||||
void setup_minimal();
|
||||
void setup(Ogre::SceneManager *scnMgr, Ogre::Bullet::DynamicsWorld *world,
|
||||
Ogre::SceneNode *cameraNode, Ogre::Camera *camera,
|
||||
Ogre::RenderWindow *window);
|
||||
void setup(Ogre::SceneManager *scnMgr, Ogre::SceneNode *cameraNode,
|
||||
Ogre::Camera *camera, Ogre::RenderWindow *window);
|
||||
void update(float delta);
|
||||
flecs::world get();
|
||||
template <class T> const T &get()
|
||||
|
||||
@@ -2,15 +2,67 @@
|
||||
#include "GameData.h"
|
||||
#include "Components.h"
|
||||
#include "GUIModule.h"
|
||||
#include "PhysicsModule.h"
|
||||
#include "CharacterModule.h"
|
||||
#include "CharacterAnimationModule.h"
|
||||
#include "BoatModule.h"
|
||||
#include "EventTriggerModule.h"
|
||||
#include "SlotsModule.h"
|
||||
#include "world-build.h"
|
||||
#include "LuaData.h"
|
||||
|
||||
#include "luaaa.hpp"
|
||||
extern "C" {
|
||||
int luaopen_lpeg(lua_State *L);
|
||||
}
|
||||
struct FooPosition {
|
||||
Ogre::Vector3 value;
|
||||
Ogre::Vector3 &get()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
};
|
||||
namespace luaaa
|
||||
{
|
||||
template <> struct LuaStack<FooPosition> {
|
||||
inline static FooPosition get(lua_State *L, int idx)
|
||||
{
|
||||
FooPosition result;
|
||||
if (lua_istable(L, idx)) {
|
||||
lua_pushnil(L);
|
||||
while (0 != lua_next(L, idx)) {
|
||||
const int top = lua_gettop(L);
|
||||
const char *name =
|
||||
LuaStack<const char *>::get(L, top - 1);
|
||||
if (strncmp(name, "x", 1) == 0)
|
||||
result.value.x =
|
||||
LuaStack<float>::get(L, top);
|
||||
else if (strncmp(name, "y", 1) == 0)
|
||||
result.value.y =
|
||||
LuaStack<float>::get(L, top);
|
||||
else if (strncmp(name, "z", 1) == 0)
|
||||
result.value.z =
|
||||
LuaStack<float>::get(L, top);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
lua_pop(L, 0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
inline static void put(lua_State *L, const FooPosition &v)
|
||||
{
|
||||
lua_newtable(L);
|
||||
LuaStack<const char *>::put(L, "x");
|
||||
LuaStack<float>::put(L, v.value.x);
|
||||
lua_rawset(L, -3);
|
||||
LuaStack<const char *>::put(L, "y");
|
||||
LuaStack<float>::put(L, v.value.y);
|
||||
lua_rawset(L, -3);
|
||||
LuaStack<const char *>::put(L, "z");
|
||||
LuaStack<float>::put(L, v.value.z);
|
||||
lua_rawset(L, -3);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
namespace ECS
|
||||
{
|
||||
@@ -194,6 +246,46 @@ LuaData::LuaData()
|
||||
#endif
|
||||
installLibraryLoader(L);
|
||||
lua_pop(L, 1);
|
||||
|
||||
#if 0
|
||||
luaaa::LuaClass<Ogre::Vector3> luaVector3(L, "Vector3");
|
||||
luaVector3.ctor<float, float, float>();
|
||||
luaVector3.get("x", [](Ogre::Vector3 &v) -> float { return v.x; });
|
||||
luaVector3.set("x", [](Ogre::Vector3 &v, float value) -> void {
|
||||
v.x = value;
|
||||
});
|
||||
luaVector3.get("y", [](Ogre::Vector3 &v) -> float { return v.y; });
|
||||
luaVector3.set("y", [](Ogre::Vector3 &v, float value) -> void {
|
||||
v.y = value;
|
||||
});
|
||||
luaVector3.get("z", [](Ogre::Vector3 &v) -> float { return v.z; });
|
||||
luaVector3.set("z", [](Ogre::Vector3 &v, float value) -> void {
|
||||
v.z = value;
|
||||
});
|
||||
luaVector3.fun("squaredLength", &Ogre::Vector3::squaredLength);
|
||||
luaVector3.fun("length", &Ogre::Vector3::length);
|
||||
luaVector3.fun("squaredDistance", &Ogre::Vector3::squaredDistance);
|
||||
luaVector3.fun("distance", &Ogre::Vector3::distance);
|
||||
#endif
|
||||
luaaa::LuaModule luaECS(L, "_ecs");
|
||||
luaECS.fun("position", [](int id) -> FooPosition {
|
||||
#if 0
|
||||
flecs::entity e = idmap.get_entity(id);
|
||||
if (e.has<CharacterBase>()) {
|
||||
const CharacterBase &cb = e.get<CharacterBase>();
|
||||
return cb.mBodyNode->_getDerivedPosition();
|
||||
} else if (e.has<BoatBase>()) {
|
||||
const BoatBase &boat = e.get<BoatBase>();
|
||||
return boat.mNode->_getDerivedPosition();
|
||||
} else if (e.has<EventTrigger>()) {
|
||||
const EventTrigger &trigger = e.get<EventTrigger>();
|
||||
return trigger.position;
|
||||
} else
|
||||
return Ogre::Vector3(0, 0, 0);
|
||||
#endif
|
||||
return FooPosition();
|
||||
});
|
||||
|
||||
lua_pushcfunction(L, [](lua_State *L) -> int {
|
||||
OgreAssert(false, "Crash function called");
|
||||
return 0;
|
||||
@@ -567,7 +659,9 @@ LuaData::LuaData()
|
||||
Ogre::String slot = lua_tostring(L, 3);
|
||||
flecs::entity parent_e = idmap.get_entity(parent);
|
||||
flecs::entity object_e = idmap.get_entity(object);
|
||||
object_e.set<ParentSlot>({ parent_e, slot, false });
|
||||
if (!object_e.has<CharacterDisablePhysics>())
|
||||
object_e.add<CharacterDisablePhysics>();
|
||||
object_e.set<ParentSlot>({ parent_e, slot });
|
||||
return 0;
|
||||
});
|
||||
lua_setglobal(L, "ecs_set_slot");
|
||||
@@ -737,6 +831,7 @@ void LuaData::lateSetup()
|
||||
LuaModule::LuaModule(flecs::world &ecs)
|
||||
{
|
||||
ecs.module<LuaModule>();
|
||||
ecs.import <SlotsModule>();
|
||||
ecs.component<LuaChildEventTrigger>();
|
||||
ecs.component<LuaBase>()
|
||||
.on_add([](LuaBase &lua) {
|
||||
|
||||
535
src/gamedata/PhysicsModule.cpp
Normal file
535
src/gamedata/PhysicsModule.cpp
Normal file
@@ -0,0 +1,535 @@
|
||||
#include <iostream>
|
||||
#include <Ogre.h>
|
||||
#include <Jolt/Jolt.h>
|
||||
#include <Jolt/Physics/Body/BodyID.h>
|
||||
#include <Jolt/Physics/Character/CharacterBase.h>
|
||||
#include <Jolt/Physics/Character/Character.h>
|
||||
#include <Jolt/Physics/Collision/BroadPhase/BroadPhase.h>
|
||||
#include <Jolt/Physics/Body/BodyLock.h>
|
||||
#include "Components.h"
|
||||
#include "GameData.h"
|
||||
#include "CharacterModule.h"
|
||||
#include "WaterModule.h"
|
||||
#include "BoatModule.h"
|
||||
#include "EventTriggerModule.h"
|
||||
#include "physics.h"
|
||||
#include "loader.h"
|
||||
#include "PhysicsModule.h"
|
||||
namespace ECS
|
||||
{
|
||||
struct PhysicsShape {
|
||||
JPH::ShapeRefC shape;
|
||||
};
|
||||
struct ConvexHull {};
|
||||
struct WaterBody {
|
||||
std::set<JPH::BodyID> inWater;
|
||||
bool isInWater(const JPH::BodyID &id) const;
|
||||
};
|
||||
struct TriggerBody {
|
||||
void *foo;
|
||||
};
|
||||
|
||||
PhysicsModule::PhysicsModule(flecs::world &ecs)
|
||||
{
|
||||
ecs.module<PhysicsModule>();
|
||||
ecs.import <EventTriggerModule>();
|
||||
ecs.import <BoatModule>();
|
||||
flecs::entity PhysicsPreUpdate =
|
||||
ecs.entity().add(flecs::Phase).depends_on(flecs::OnUpdate);
|
||||
flecs::entity PhysicsUpdate =
|
||||
ecs.entity().add(flecs::Phase).depends_on(PhysicsPreUpdate);
|
||||
flecs::entity PhysicsPostUpdate =
|
||||
ecs.entity().add(flecs::Phase).depends_on(PhysicsUpdate);
|
||||
ecs.component<Physics>().add(flecs::Singleton);
|
||||
ecs.component<JPH::BodyID>().member<uint32_t>("mID");
|
||||
/* for terrain */
|
||||
ecs.component<PhysicsBody>();
|
||||
ecs.component<PhysicsShape>();
|
||||
ecs.component<PhysicsNode>();
|
||||
ecs.component<PhysicsMeshName>();
|
||||
ecs.component<PhysicsMeshPtr>();
|
||||
ecs.component<PhysicsHeightfieldData>();
|
||||
|
||||
ecs.component<CharacterBody>();
|
||||
ecs.component<TriggerBody>();
|
||||
ecs.component<CharacterVelocity>();
|
||||
ecs.component<WaterBody>().add(flecs::Singleton);
|
||||
ecs.system<const EngineData, const Camera>("physics_init")
|
||||
.kind(PhysicsPreUpdate)
|
||||
.without<Physics>()
|
||||
.each([&](const EngineData &e, const Camera &c) {
|
||||
Physics &ph = ECS::get().ensure<Physics>();
|
||||
ph.physics = new JoltPhysicsWrapper(e.mScnMgr,
|
||||
c.mCameraNode);
|
||||
ECS::modified<Physics>();
|
||||
});
|
||||
#if 0
|
||||
ecs.system<PhysicsBody>("create_body")
|
||||
.kind(flecs::OnUpdate)
|
||||
.without<JPH::BodyID>()
|
||||
.each([&](flecs::entity e, PhysicsBody &rb) {
|
||||
JPH::BodyID id =
|
||||
JoltPhysicsWrapper::getSingleton().createBody(
|
||||
rb.shape.get(), rb.node,
|
||||
(JPH::EMotionType)rb.motion,
|
||||
(JPH::ObjectLayer)rb.layer);
|
||||
e.set<JPH::BodyID>(id);
|
||||
});
|
||||
#endif
|
||||
ecs.system<EngineData, Physics>("physics_update")
|
||||
.kind(PhysicsUpdate)
|
||||
.each([&](EngineData &e, Physics &ph) {
|
||||
ph.physics->update(e.delta);
|
||||
});
|
||||
ecs.observer<const EngineData, PhysicsMeshName>(
|
||||
"create_shape_mesh_name")
|
||||
.event(flecs::OnSet)
|
||||
.without<PhysicsShape>()
|
||||
.with<Physics>()
|
||||
.write<PhysicsShape>()
|
||||
.each([&](flecs::entity e, const EngineData &eng,
|
||||
PhysicsMeshName &name) {
|
||||
Ogre::DefaultHardwareBufferManagerBase dmgr;
|
||||
Ogre::MeshPtr mesh =
|
||||
Ogre::MeshManager::getSingleton().getByName(
|
||||
name.meshName);
|
||||
mesh->setHardwareBufferManager(&dmgr);
|
||||
mesh->load();
|
||||
JPH::ShapeRefC shape =
|
||||
JoltPhysicsWrapper::getSingleton()
|
||||
.createMeshShape(mesh);
|
||||
PhysicsShape &s = e.ensure<PhysicsShape>();
|
||||
s.shape = shape;
|
||||
e.modified<PhysicsShape>();
|
||||
});
|
||||
ecs.observer<const EngineData, PhysicsMeshPtr>("create_shape_mesh_ptr")
|
||||
.event(flecs::OnSet)
|
||||
.without<PhysicsShape>()
|
||||
.with<Physics>()
|
||||
.write<PhysicsShape>()
|
||||
.each([&](flecs::entity e, const EngineData &eng,
|
||||
PhysicsMeshPtr &meshPtr) {
|
||||
Ogre::DefaultHardwareBufferManager dmgr;
|
||||
Ogre::MeshPtr mesh = meshPtr.mesh;
|
||||
if (!mesh->isLoaded()) {
|
||||
mesh->setHardwareBufferManager(&dmgr);
|
||||
mesh->load();
|
||||
}
|
||||
JPH::ShapeRefC shape =
|
||||
JoltPhysicsWrapper::getSingleton()
|
||||
.createMeshShape(mesh);
|
||||
PhysicsShape &s = e.ensure<PhysicsShape>();
|
||||
s.shape = shape;
|
||||
e.modified<PhysicsShape>();
|
||||
});
|
||||
ecs.observer<const EngineData, PhysicsHeightfieldData>(
|
||||
"create_shape_heightfield")
|
||||
.event(flecs::OnSet)
|
||||
.without<PhysicsShape>()
|
||||
.with<Physics>()
|
||||
.write<PhysicsShape>()
|
||||
.each([&](flecs::entity e, const EngineData &eng,
|
||||
PhysicsHeightfieldData &hfd) {
|
||||
JPH::ShapeRefC shape =
|
||||
JoltPhysicsWrapper::getSingleton()
|
||||
.createHeightfieldShape(
|
||||
hfd.samples, hfd.offset,
|
||||
hfd.scale, hfd.sampleCount);
|
||||
PhysicsShape &s = e.ensure<PhysicsShape>();
|
||||
s.shape = shape;
|
||||
e.modified<PhysicsShape>();
|
||||
delete hfd.samples;
|
||||
e.remove<PhysicsHeightfieldData>();
|
||||
});
|
||||
#if 1
|
||||
ecs.observer<const EngineData, const PhysicsShape, const PhysicsNode,
|
||||
const PhysicsBody>("create_body_from_shape")
|
||||
.event(flecs::OnSet)
|
||||
.without<JPH::BodyID>()
|
||||
.with<Physics>()
|
||||
.write<PhysicsShape>()
|
||||
.write<JPH::BodyID>()
|
||||
.each([&](flecs::entity e, const EngineData &eng,
|
||||
const PhysicsShape &shape, const PhysicsNode &node,
|
||||
const PhysicsBody &body) {
|
||||
JPH::BodyID id =
|
||||
JoltPhysicsWrapper::getSingleton().createBody(
|
||||
shape.shape.GetPtr(), 0.0f, node.node,
|
||||
(JPH::EMotionType)body.motion,
|
||||
(JPH::ObjectLayer)body.layer);
|
||||
e.set<JPH::BodyID>(id);
|
||||
JoltPhysicsWrapper::getSingleton().addBody(
|
||||
id, JPH::EActivation::Activate);
|
||||
});
|
||||
#endif
|
||||
ecs.observer<const JPH::BodyID>("remove_body")
|
||||
.event(flecs::OnRemove)
|
||||
.each([&](flecs::entity e, const JPH::BodyID &id) {
|
||||
JoltPhysicsWrapper::getSingleton().removeBody(id);
|
||||
JoltPhysicsWrapper::getSingleton().destroyBody(id);
|
||||
std::cout << "body destroyed" << std::endl;
|
||||
});
|
||||
ecs.observer<const EngineData, const CharacterBase>("SetupCharacterPh")
|
||||
.event(flecs::OnSet)
|
||||
.with<Character>()
|
||||
.without<CharacterBody>()
|
||||
.write<CharacterBody>()
|
||||
.each([](flecs::entity e, const EngineData &eng,
|
||||
const CharacterBase &base) {
|
||||
CharacterBody &b = e.ensure<CharacterBody>();
|
||||
b.ch.reset(JoltPhysicsWrapper::getSingleton()
|
||||
.createCharacter(base.mBodyNode,
|
||||
1.75f, 0.23f));
|
||||
if (!e.has<CharacterDisablePhysics>())
|
||||
static_cast<JPH::Character *>(b.ch.get())
|
||||
->AddToPhysicsSystem(
|
||||
JPH::EActivation::Activate);
|
||||
e.modified<CharacterBody>();
|
||||
});
|
||||
ecs.observer<const EngineData, const EventTrigger>(
|
||||
"CreateTriggerPhysics")
|
||||
.event(flecs::OnSet)
|
||||
.without<JPH::BodyID>()
|
||||
.each([](flecs::entity e, const EngineData &eng,
|
||||
const EventTrigger &trigger) {
|
||||
JPH::ShapeRefC shape =
|
||||
JoltPhysicsWrapper::getSingleton()
|
||||
.createCylinderShape(trigger.halfheight,
|
||||
trigger.radius);
|
||||
JPH::BodyID id =
|
||||
JoltPhysicsWrapper::getSingleton().createSensor(
|
||||
shape.GetPtr(), trigger.node,
|
||||
JPH::EMotionType::Kinematic,
|
||||
Layers::MOVING);
|
||||
e.set<JPH::BodyID>(id);
|
||||
// JoltPhysicsWrapper::getSingleton().setDebugDraw(true);
|
||||
JoltPhysicsWrapper::getSingleton().addBody(
|
||||
id, JPH::EActivation::Activate);
|
||||
});
|
||||
#if 0
|
||||
ecs.system<const EngineData, const EventTrigger, const JPH::BodyID>(
|
||||
"UpdateTriggerPhysicsPre")
|
||||
.kind(PhysicsPreUpdate)
|
||||
.with<TerrainReady>()
|
||||
.with<WaterReady>()
|
||||
.with<WaterBody>()
|
||||
.each([](flecs::entity e, const EngineData &eng,
|
||||
const EventTrigger &trigger, const JPH::BodyID &id) {
|
||||
/* FIXME: update positions for triggers, probably need to move somewhere */
|
||||
JoltPhysicsWrapper::getSingleton()
|
||||
.setPositionAndRotation(
|
||||
id, trigger.node->_getDerivedPosition(),
|
||||
trigger.node->_getDerivedOrientation());
|
||||
#if 0
|
||||
std::cout << trigger.node->_getDerivedPosition() << " "
|
||||
<< trigger.node->getPosition() << " "
|
||||
<< trigger.node->getParent()->getName()
|
||||
<< ": " << trigger.node->getName()
|
||||
<< std::endl;
|
||||
// OgreAssert(false, "update triggers");
|
||||
#endif
|
||||
});
|
||||
ecs.system<const EngineData, const EventTrigger, const JPH::BodyID>(
|
||||
"UpdateTriggerPhysicsPost")
|
||||
.kind(PhysicsPostUpdate)
|
||||
.with<TerrainReady>()
|
||||
.with<WaterReady>()
|
||||
.with<WaterBody>()
|
||||
.each([](flecs::entity e, const EngineData &eng,
|
||||
const EventTrigger &trigger, const JPH::BodyID &id) {
|
||||
/* FIXME: update positions for triggers, probably need to move somewhere */
|
||||
Ogre::Vector3 position;
|
||||
Ogre::Quaternion rotation;
|
||||
JoltPhysicsWrapper::getSingleton()
|
||||
.getPositionAndRotation(id, position, rotation);
|
||||
trigger.node->_setDerivedPosition(position);
|
||||
trigger.node->_setDerivedOrientation(rotation);
|
||||
});
|
||||
#endif
|
||||
ecs.system<const EngineData>("init_water")
|
||||
.kind(PhysicsPreUpdate)
|
||||
.with<TerrainReady>()
|
||||
.with<WaterAlmostReady>()
|
||||
.without<WaterBody>()
|
||||
.each([this](const EngineData &eng) {
|
||||
ECS::get().set<WaterBody>({});
|
||||
});
|
||||
ecs.system<const EngineData, WaterBody>("update_water")
|
||||
.kind(PhysicsPostUpdate)
|
||||
.with<TerrainReady>()
|
||||
.with<WaterAlmostReady>()
|
||||
.each([this](const EngineData &eng, WaterBody &body) {
|
||||
const WaterSurface &water = ECS::get<WaterSurface>();
|
||||
JoltPhysicsWrapper::getSingleton().broadphaseQuery(
|
||||
eng.delta,
|
||||
water.mWaterNode->_getDerivedPosition(),
|
||||
body.inWater);
|
||||
#if 0
|
||||
for (JPH::BodyID inBodyID : body.inWater) {
|
||||
if (JoltPhysicsWrapper::getSingleton().isActive(
|
||||
inBodyID)) {
|
||||
float my =
|
||||
JoltPhysicsWrapper::getSingleton()
|
||||
.getPosition(inBodyID)
|
||||
.y;
|
||||
float myv =
|
||||
JoltPhysicsWrapper::getSingleton()
|
||||
.getLinearVelocity(
|
||||
inBodyID)
|
||||
.y;
|
||||
float b = 1.0f;
|
||||
float drag = 0.5f;
|
||||
float adrag = 0.05f;
|
||||
float level = -1.3f;
|
||||
float mdec = 1.0f;
|
||||
float minc = 1.0f;
|
||||
float h = -my + level;
|
||||
if (h < 0)
|
||||
h = 0;
|
||||
if (my < level - 0.1f)
|
||||
b *= 1.1f * (1.0f + 1.2f * h);
|
||||
else if (my > level + 0.1f) {
|
||||
b *= 0.8f;
|
||||
if (myv > 0.1f)
|
||||
b *= 0.9f;
|
||||
if (my > level + 0.4f)
|
||||
b *= 0.5f;
|
||||
}
|
||||
if (myv < 0.0f)
|
||||
drag = 0.7f;
|
||||
JoltPhysicsWrapper::getSingleton().applyBuoyancyImpulse(
|
||||
inBodyID,
|
||||
water.mWaterNode->_getDerivedPosition() -
|
||||
Ogre::Vector3(0, 0.1f,
|
||||
0),
|
||||
Ogre::Vector3::UNIT_Y, b, drag,
|
||||
adrag, Ogre::Vector3::ZERO,
|
||||
eng.delta);
|
||||
// std::cout << b << std::endl;
|
||||
#if 0
|
||||
std::cout << "addHit: "
|
||||
<< JoltPhysics::convert(
|
||||
body.GetPosition())
|
||||
<< std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
ECS::get().add<WaterReady>();
|
||||
});
|
||||
ecs.system<const JPH::BodyID, const WaterBody>("update_water_status1")
|
||||
.kind(PhysicsPostUpdate)
|
||||
.with<TerrainReady>()
|
||||
.with<WaterReady>()
|
||||
.with<InWater>()
|
||||
.each([this](flecs::entity e, const JPH::BodyID &id,
|
||||
const WaterBody &body) {
|
||||
if (!body.isInWater(id))
|
||||
e.remove<InWater>();
|
||||
});
|
||||
ecs.system<const JPH::BodyID, const WaterBody>("update_water_status2")
|
||||
.kind(PhysicsPostUpdate)
|
||||
.with<TerrainReady>()
|
||||
.with<WaterReady>()
|
||||
.without<InWater>()
|
||||
.each([this](flecs::entity e, const JPH::BodyID &id,
|
||||
const WaterBody &body) {
|
||||
if (body.isInWater(id))
|
||||
e.add<InWater>();
|
||||
});
|
||||
ecs.system<const CharacterBody, const WaterBody>(
|
||||
"update_water_character1")
|
||||
.kind(PhysicsPostUpdate)
|
||||
.with<TerrainReady>()
|
||||
.with<WaterReady>()
|
||||
.with<InWater>()
|
||||
.each([this](flecs::entity e, const CharacterBody &ch,
|
||||
const WaterBody &body) {
|
||||
JPH::Character *chptr =
|
||||
static_cast<JPH::Character *>(ch.ch.get());
|
||||
if (!body.isInWater(chptr->GetBodyID()))
|
||||
e.remove<InWater>();
|
||||
});
|
||||
ecs.system<const CharacterBody, const WaterBody>(
|
||||
"update_water_character2")
|
||||
.kind(PhysicsPostUpdate)
|
||||
.with<TerrainReady>()
|
||||
.with<WaterReady>()
|
||||
.without<InWater>()
|
||||
.each([this](flecs::entity e, const CharacterBody &ch,
|
||||
const WaterBody &body) {
|
||||
JPH::Character *chptr =
|
||||
static_cast<JPH::Character *>(ch.ch.get());
|
||||
if (body.isInWater(chptr->GetBodyID()))
|
||||
e.add<InWater>();
|
||||
});
|
||||
ecs.system<const EngineData, const BoatBase, const WaterBody,
|
||||
const JPH::BodyID>("update_water_boat_enable")
|
||||
.kind(PhysicsPreUpdate)
|
||||
.with<TerrainReady>()
|
||||
.with<WaterReady>()
|
||||
.each([this](flecs::entity e, const EngineData &eng,
|
||||
const BoatBase &boat, const WaterBody &body,
|
||||
const JPH::BodyID &id) {
|
||||
if (!JoltPhysicsWrapper::getSingleton().isAdded(id))
|
||||
JoltPhysicsWrapper::getSingleton().addBody(
|
||||
id, JPH::EActivation::Activate);
|
||||
});
|
||||
ecs.system<const EngineData, const BoatBase, const WaterBody,
|
||||
const JPH::BodyID>("update_water_boat_activation")
|
||||
.kind(PhysicsPreUpdate)
|
||||
.with<TerrainReady>()
|
||||
.with<WaterReady>()
|
||||
.with<InWater>()
|
||||
.each([this](flecs::entity e, const EngineData &eng,
|
||||
const BoatBase &boat, const WaterBody &body,
|
||||
const JPH::BodyID &id) {
|
||||
if (!JoltPhysicsWrapper::getSingleton().isActive(id))
|
||||
JoltPhysicsWrapper::getSingleton().activate(id);
|
||||
});
|
||||
ecs.system<const EngineData, const BoatBase, const WaterBody,
|
||||
const JPH::BodyID>("update_water_boat_buoyancy")
|
||||
.kind(PhysicsPreUpdate)
|
||||
.with<TerrainReady>()
|
||||
.with<WaterReady>()
|
||||
.with<InWater>()
|
||||
.each([this](flecs::entity e, const EngineData &eng,
|
||||
const BoatBase &boat, const WaterBody &body,
|
||||
const JPH::BodyID &id) {
|
||||
const WaterSurface &water = ECS::get<WaterSurface>();
|
||||
float b = 1.0f, drag = 0.5f, adrag = 0.5f;
|
||||
float level = 0.1f;
|
||||
float my = JoltPhysicsWrapper::getSingleton()
|
||||
.getPosition(id)
|
||||
.y;
|
||||
float myv = JoltPhysicsWrapper::getSingleton()
|
||||
.getLinearVelocity(id)
|
||||
.y;
|
||||
#if 0
|
||||
if (my < level && myv < 0)
|
||||
b = 10.0f;
|
||||
else if (my > level && myv > 0)
|
||||
b = 0.8f;
|
||||
#endif
|
||||
if (my < level)
|
||||
b = 1.7f;
|
||||
else if (my > level)
|
||||
b = 0.9f;
|
||||
// std::cout << my << std::endl;
|
||||
JoltPhysicsWrapper::getSingleton().applyBuoyancyImpulse(
|
||||
id, water.mWaterNode->_getDerivedPosition(),
|
||||
Ogre::Vector3::UNIT_Y, b, drag, adrag,
|
||||
Ogre::Vector3::ZERO, eng.delta);
|
||||
});
|
||||
ecs.system<const EngineData, const CharacterBody, const WaterBody>(
|
||||
"update_water_character_buoyancy")
|
||||
.kind(PhysicsPreUpdate)
|
||||
.with<TerrainReady>()
|
||||
.with<WaterReady>()
|
||||
.with<InWater>()
|
||||
.without<CharacterDisablePhysics>()
|
||||
.with<CharacterBuoyancy>()
|
||||
.each([this](flecs::entity e, const EngineData &eng,
|
||||
const CharacterBody &ch, const WaterBody &body) {
|
||||
JPH::Character *chptr =
|
||||
static_cast<JPH::Character *>(ch.ch.get());
|
||||
JPH::BodyID id = chptr->GetBodyID();
|
||||
if (JoltPhysicsWrapper::getSingleton().isActive(id)) {
|
||||
const WaterSurface &water =
|
||||
ECS::get<WaterSurface>();
|
||||
float my = JoltPhysicsWrapper::getSingleton()
|
||||
.getPosition(id)
|
||||
.y;
|
||||
float myv = JoltPhysicsWrapper::getSingleton()
|
||||
.getLinearVelocity(id)
|
||||
.y;
|
||||
float b = 1.0f;
|
||||
float drag = 0.5f;
|
||||
float adrag = 0.05f;
|
||||
float level = -1.3f;
|
||||
float mdec = 1.0f;
|
||||
float minc = 1.0f;
|
||||
float h = -my + level;
|
||||
if (h < 0)
|
||||
h = 0;
|
||||
if (my < level - 0.1f)
|
||||
b *= 1.1f * (1.0f + 1.2f * h);
|
||||
else if (my > level + 0.1f) {
|
||||
b *= 0.8f;
|
||||
if (myv > 0.1f)
|
||||
b *= 0.9f;
|
||||
if (my > level + 0.4f)
|
||||
b *= 0.5f;
|
||||
}
|
||||
if (myv < 0.0f)
|
||||
drag = 0.7f;
|
||||
JoltPhysicsWrapper::getSingleton()
|
||||
.applyBuoyancyImpulse(
|
||||
id,
|
||||
water.mWaterNode
|
||||
->_getDerivedPosition(),
|
||||
Ogre::Vector3::UNIT_Y, b, drag,
|
||||
adrag, Ogre::Vector3::ZERO,
|
||||
eng.delta);
|
||||
// std::cout << b << std::endl;
|
||||
#if 0
|
||||
std::cout << "addHit: "
|
||||
<< JoltPhysics::convert(
|
||||
body.GetPosition())
|
||||
<< std::endl;
|
||||
#endif
|
||||
}
|
||||
});
|
||||
ecs.system<const EngineData, const CharacterBody, CharacterVelocity>(
|
||||
"HandleVelocity")
|
||||
.kind(PhysicsPostUpdate)
|
||||
.with<TerrainReady>()
|
||||
.with<WaterReady>()
|
||||
.without<CharacterDisablePhysics>()
|
||||
.without<CharacterUpdatePhysicsState>()
|
||||
.each([this](flecs::entity e, const EngineData &eng,
|
||||
const CharacterBody &body, CharacterVelocity &gr) {
|
||||
Ogre::Vector3 v = gr.velocity;
|
||||
v.y = 0.0f;
|
||||
JPH::Character *ch =
|
||||
static_cast<JPH::Character *>(body.ch.get());
|
||||
if (!e.has<InWater>()) {
|
||||
if (ch->IsSupported()) {
|
||||
v.y = gr.velocity.y;
|
||||
gr.gvelocity.y = 0;
|
||||
} else {
|
||||
v.y = gr.velocity.y;
|
||||
v.y += gr.gvelocity.y;
|
||||
gr.gvelocity.y += -9.8f * eng.delta;
|
||||
}
|
||||
} else {
|
||||
v = JoltPhysics::convert(
|
||||
ch->GetLinearVelocity());
|
||||
v.x = gr.velocity.x;
|
||||
v.z = gr.velocity.z;
|
||||
}
|
||||
// gr.velocity.y = 0.0f;
|
||||
// v.y = 0.0f;
|
||||
ch->SetLinearVelocity(JoltPhysics::convert(v));
|
||||
gr.velocity = Ogre::Vector3::ZERO;
|
||||
});
|
||||
}
|
||||
flecs::entity PhysicsModule::createTerrainChunkBody(Ogre::SceneNode *node,
|
||||
float *samples,
|
||||
const Ogre::Vector3 &offset,
|
||||
const Ogre::Vector3 &scale,
|
||||
int sampleCount)
|
||||
{
|
||||
flecs::entity e = ECS::get().entity();
|
||||
e.set<PhysicsHeightfieldData>({ samples, offset, scale, sampleCount });
|
||||
e.set<PhysicsBody>({ (uint32_t)JPH::EMotionType::Static,
|
||||
(uint32_t)Layers::NON_MOVING });
|
||||
e.set<PhysicsNode>({ node });
|
||||
|
||||
return e;
|
||||
}
|
||||
bool WaterBody::isInWater(const JPH::BodyID &id) const
|
||||
{
|
||||
return inWater.find(id) != inWater.end();
|
||||
}
|
||||
}
|
||||
57
src/gamedata/PhysicsModule.h
Normal file
57
src/gamedata/PhysicsModule.h
Normal file
@@ -0,0 +1,57 @@
|
||||
#ifndef _PHYSICS_MODULE_H_
|
||||
#define _PHYSICS_MODULE_H_
|
||||
#include <flecs.h>
|
||||
class JoltPhysicsWrapper;
|
||||
namespace JPH
|
||||
{
|
||||
class Shape;
|
||||
class CharacterBase;
|
||||
}
|
||||
namespace Ogre
|
||||
{
|
||||
class TerrainGroup;
|
||||
}
|
||||
namespace ECS
|
||||
{
|
||||
struct Physics {
|
||||
JoltPhysicsWrapper *physics;
|
||||
};
|
||||
struct PhysicsNode {
|
||||
Ogre::SceneNode *node;
|
||||
};
|
||||
struct PhysicsMeshName {
|
||||
Ogre::String meshName;
|
||||
};
|
||||
struct PhysicsMeshPtr {
|
||||
Ogre::MeshPtr mesh;
|
||||
};
|
||||
struct PhysicsBody {
|
||||
uint32_t motion;
|
||||
uint32_t layer;
|
||||
};
|
||||
struct CharacterBody {
|
||||
std::shared_ptr<JPH::CharacterBase> ch;
|
||||
};
|
||||
struct BoatBody {
|
||||
void *tmp;
|
||||
};
|
||||
struct PhysicsHeightfieldData {
|
||||
const float *samples;
|
||||
Ogre::Vector3 offset;
|
||||
Ogre::Vector3 scale;
|
||||
int sampleCount;
|
||||
};
|
||||
struct CharacterVelocity {
|
||||
Ogre::Vector3 gvelocity;
|
||||
Ogre::Vector3 velocity;
|
||||
};
|
||||
struct PhysicsModule {
|
||||
PhysicsModule(flecs::world &ecs);
|
||||
static flecs::entity createTerrainChunkBody(Ogre::SceneNode *node,
|
||||
float *samples,
|
||||
const Ogre::Vector3 &offset,
|
||||
const Ogre::Vector3 &scale,
|
||||
int sampleCount);
|
||||
};
|
||||
}
|
||||
#endif
|
||||
153
src/gamedata/SlotsModule.cpp
Normal file
153
src/gamedata/SlotsModule.cpp
Normal file
@@ -0,0 +1,153 @@
|
||||
#include <iostream>
|
||||
#include "Components.h"
|
||||
#include "GameData.h"
|
||||
#include "CharacterModule.h"
|
||||
#include "BoatModule.h"
|
||||
#include "SlotsModule.h"
|
||||
namespace ECS
|
||||
{
|
||||
SlotsModule::SlotsModule(flecs::world &ecs)
|
||||
{
|
||||
ecs.module<SlotsModule>();
|
||||
ecs.import <CharacterModule>();
|
||||
ecs.component<ParentSlot>();
|
||||
ecs.component<ParentSlotData>();
|
||||
ecs.component<ObjectSlots>();
|
||||
ecs.observer<const EngineData, const BoatBase>("CreateBoatSlots")
|
||||
.event(flecs::OnSet)
|
||||
.each([](flecs::entity e, const EngineData &eng,
|
||||
const BoatBase &boat) {
|
||||
int i;
|
||||
std::vector<Ogre::Node *> slots =
|
||||
boat.mNode->getChildren();
|
||||
for (i = 0; i < slots.size(); i++) {
|
||||
Ogre::Any any =
|
||||
static_cast<Ogre::SceneNode *>(slots[i])
|
||||
->getUserObjectBindings()
|
||||
.getUserAny("type");
|
||||
if (!any.has_value())
|
||||
continue;
|
||||
Ogre::String obj_type =
|
||||
Ogre::any_cast<Ogre::String>(any);
|
||||
std::cout << "child type: " << obj_type
|
||||
<< std::endl;
|
||||
}
|
||||
if (slots.size() > 0) {
|
||||
ObjectSlots &vs = e.ensure<ObjectSlots>();
|
||||
for (i = 0; i < slots.size(); i++) {
|
||||
Ogre::Any any =
|
||||
static_cast<Ogre::SceneNode *>(
|
||||
slots[i])
|
||||
->getUserObjectBindings()
|
||||
.getUserAny("type");
|
||||
if (!any.has_value())
|
||||
continue;
|
||||
Ogre::String obj_type =
|
||||
Ogre::any_cast<Ogre::String>(
|
||||
any);
|
||||
any = static_cast<Ogre::SceneNode *>(
|
||||
slots[i])
|
||||
->getUserObjectBindings()
|
||||
.getUserAny("name");
|
||||
if (!any.has_value())
|
||||
continue;
|
||||
Ogre::String obj_name =
|
||||
Ogre::any_cast<Ogre::String>(
|
||||
any);
|
||||
vs.slots[obj_name] = {
|
||||
obj_type,
|
||||
static_cast<Ogre::SceneNode *>(
|
||||
slots[i])
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
ecs.system<const EngineData, const CharacterBase, ParentSlot,
|
||||
ParentSlotData>("UpdatePhysics2a")
|
||||
.kind(flecs::OnUpdate)
|
||||
.with<CharacterDisablePhysics>()
|
||||
.each([](flecs::entity e, const EngineData &eng,
|
||||
const CharacterBase &ch, ParentSlot &slot,
|
||||
ParentSlotData &psdata) {
|
||||
if (slot.slot_name == "") {
|
||||
e.remove<ParentSlot>();
|
||||
e.remove<ParentSlotData>();
|
||||
}
|
||||
|
||||
if (slot.parent_e.has<ObjectSlots>()) {
|
||||
const ObjectSlots &slots =
|
||||
slot.parent_e.get<ObjectSlots>();
|
||||
if (slots.slots.find(slot.slot_name) ==
|
||||
slots.slots.end()) {
|
||||
// invalid setting
|
||||
e.remove<ParentSlot>();
|
||||
return;
|
||||
}
|
||||
Ogre::SceneNode *slot_base =
|
||||
slots.slots.at(slot.slot_name).second;
|
||||
#if 0
|
||||
ch.mBodyNode->getParent()->removeChild(
|
||||
ch.mBodyNode);
|
||||
#endif
|
||||
slot_base->addChild(ch.mBodyNode);
|
||||
Ogre::Vector3 position =
|
||||
slot_base->_getDerivedPosition();
|
||||
Ogre::Quaternion orientation =
|
||||
slot_base->_getDerivedOrientation();
|
||||
ch.mBodyNode->_setDerivedPosition(position);
|
||||
ch.mBodyNode->_setDerivedOrientation(
|
||||
orientation);
|
||||
psdata.parent_e = slot.parent_e;
|
||||
psdata.parentNode = slot_base;
|
||||
psdata.slot_name = slot.slot_name;
|
||||
e.remove<ParentSlot>();
|
||||
e.modified<ParentSlotData>();
|
||||
std::cout << "base: " << slot_base->getName();
|
||||
}
|
||||
});
|
||||
ecs.system<const EngineData, const CharacterBase, ParentSlot>(
|
||||
"UpdatePhysics2")
|
||||
.kind(flecs::OnUpdate)
|
||||
.with<CharacterDisablePhysics>()
|
||||
.without<ParentSlotData>()
|
||||
.with<WaterReady>()
|
||||
.each([](flecs::entity e, const EngineData &eng,
|
||||
const CharacterBase &ch, ParentSlot &slot) {
|
||||
std::cout << e.name() << std::endl;
|
||||
if (!slot.parent_e.has<ObjectSlots>())
|
||||
return;
|
||||
OgreAssert(slot.parent_e.has<ObjectSlots>(),
|
||||
"parent has no slots");
|
||||
OgreAssert(e.has<Character>(), "not a character");
|
||||
if (slot.parent_e.has<ObjectSlots>()) {
|
||||
const ObjectSlots &slots =
|
||||
slot.parent_e.get<ObjectSlots>();
|
||||
if (slot.slot_name == "")
|
||||
return;
|
||||
if (slots.slots.find(slot.slot_name) ==
|
||||
slots.slots.end()) {
|
||||
// invalid setting
|
||||
e.remove<ParentSlot>();
|
||||
OgreAssert(false, "bad slot");
|
||||
return;
|
||||
}
|
||||
ParentSlotData &psdata =
|
||||
e.ensure<ParentSlotData>();
|
||||
Ogre::SceneNode *slot_base =
|
||||
slots.slots.at(slot.slot_name).second;
|
||||
Ogre::Vector3 position =
|
||||
slot_base->_getDerivedPosition();
|
||||
Ogre::Quaternion orientation =
|
||||
slot_base->_getDerivedOrientation();
|
||||
ch.mBodyNode->_setDerivedPosition(position);
|
||||
ch.mBodyNode->_setDerivedOrientation(
|
||||
orientation);
|
||||
psdata.parent_e = slot.parent_e;
|
||||
psdata.parentNode = slot_base;
|
||||
psdata.slot_name = slot.slot_name;
|
||||
e.remove<ParentSlot>();
|
||||
e.modified<ParentSlotData>();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
25
src/gamedata/SlotsModule.h
Normal file
25
src/gamedata/SlotsModule.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef _SLOTS_MODULE_H_
|
||||
#define _SLOTS_MODULE_H_
|
||||
#include <flecs.h>
|
||||
#include <Ogre.h>
|
||||
namespace ECS
|
||||
{
|
||||
struct ParentSlot {
|
||||
flecs::entity parent_e;
|
||||
Ogre::String slot_name;
|
||||
};
|
||||
struct ParentSlotData {
|
||||
Ogre::String slot_name;
|
||||
flecs::entity parent_e;
|
||||
Ogre::SceneNode *parentNode;
|
||||
};
|
||||
struct ObjectSlots {
|
||||
std::unordered_map<Ogre::String,
|
||||
std::pair<Ogre::String, Ogre::SceneNode *> >
|
||||
slots;
|
||||
};
|
||||
struct SlotsModule {
|
||||
SlotsModule(flecs::world &ecs);
|
||||
};
|
||||
}
|
||||
#endif
|
||||
@@ -1,7 +1,6 @@
|
||||
#include <unordered_set>
|
||||
#include <iostream>
|
||||
#include <Ogre.h>
|
||||
#include <OgreBullet.h>
|
||||
#include <BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h>
|
||||
#include <OgreTerrain.h>
|
||||
#include <OgreTerrainGroup.h>
|
||||
@@ -14,6 +13,7 @@
|
||||
#include "Components.h"
|
||||
#include "CharacterModule.h"
|
||||
#include "SunModule.h"
|
||||
#include "PhysicsModule.h"
|
||||
#include "TerrainModule.h"
|
||||
|
||||
#define TERRAIN_SIZE 129
|
||||
@@ -173,7 +173,7 @@ class FlatTerrainDefiner
|
||||
: public Ogre::TerrainPagedWorldSection::TerrainDefiner,
|
||||
public Ogre::FrameListener {
|
||||
Ogre::SceneManager *mScnMgr;
|
||||
Ogre::Bullet::DynamicsWorld *mWorld;
|
||||
// Ogre::Bullet::DynamicsWorld *mWorld;
|
||||
struct gen_collider {
|
||||
Ogre::TerrainGroup *group;
|
||||
long x;
|
||||
@@ -182,18 +182,44 @@ class FlatTerrainDefiner
|
||||
std::deque<struct gen_collider> collider_queue;
|
||||
|
||||
public:
|
||||
FlatTerrainDefiner(Ogre::SceneManager *scm,
|
||||
Ogre::Bullet::DynamicsWorld *world)
|
||||
FlatTerrainDefiner(Ogre::SceneManager *
|
||||
scm /*, Ogre::Bullet::DynamicsWorld *world */)
|
||||
: Ogre::TerrainPagedWorldSection::TerrainDefiner()
|
||||
, Ogre::FrameListener()
|
||||
, mScnMgr(scm)
|
||||
, mWorld(world)
|
||||
// , mWorld(world)
|
||||
{
|
||||
Ogre::Root::getSingleton().addFrameListener(this);
|
||||
}
|
||||
|
||||
private:
|
||||
public:
|
||||
void createTerrainChunk(Ogre::TerrainGroup *terrainGroup, long x,
|
||||
long y)
|
||||
{
|
||||
Ogre::Terrain *terrain = terrainGroup->getTerrain(x, y);
|
||||
float minH = terrain->getMinHeight();
|
||||
float maxH = terrain->getMaxHeight();
|
||||
uint16_t terrainSize = terrainGroup->getTerrainSize();
|
||||
OgreAssert(terrain && terrain->getHeightData() &&
|
||||
terrain->isLoaded(),
|
||||
"invalid terrain supplied");
|
||||
uint16_t size = terrain->getSize();
|
||||
float *heightData = terrain->getHeightData();
|
||||
Ogre::SceneNode *node = terrain->_getRootSceneNode();
|
||||
float worldSize = terrain->getWorldSize();
|
||||
float scaled = worldSize / (size - 1);
|
||||
Ogre::Vector3 bodyPosition = terrain->getPosition();
|
||||
bodyPosition.y += (maxH + minH) / 2.0f;
|
||||
bodyPosition.x += worldSize / 2.0f;
|
||||
bodyPosition.z += worldSize / 2.0f;
|
||||
Ogre::Vector3 offset =
|
||||
node->_getDerivedPosition() - bodyPosition;
|
||||
flecs::entity e = PhysicsModule::createTerrainChunkBody(
|
||||
node, heightData, offset,
|
||||
Ogre::Vector3(scaled, 1, scaled), size);
|
||||
node->getUserObjectBindings().setUserAny("_collider", e);
|
||||
}
|
||||
void define(Ogre::TerrainGroup *terrainGroup, long x, long y) override
|
||||
{
|
||||
uint16_t terrainSize = terrainGroup->getTerrainSize();
|
||||
@@ -258,6 +284,10 @@ public:
|
||||
float maxH = terrain->getMaxHeight();
|
||||
int size = terrain->getSize();
|
||||
float worldSize = terrain->getWorldSize();
|
||||
{
|
||||
createTerrainChunk(group, x, y);
|
||||
}
|
||||
#if 0
|
||||
if (true) {
|
||||
btRigidBody *body =
|
||||
mWorld->addTerrainRigidBody(
|
||||
@@ -297,6 +327,7 @@ public:
|
||||
y));
|
||||
created = true;
|
||||
}
|
||||
#endif
|
||||
collider_queue.pop_front();
|
||||
// FIXME: create entities and components instead
|
||||
Ogre::SceneNode *items =
|
||||
@@ -317,11 +348,6 @@ public:
|
||||
what->attachObject(ent);
|
||||
what->setOrientation(item.rotation);
|
||||
what->setPosition(item.position);
|
||||
ECS::get<EngineData>()
|
||||
.mWorld->addRigidBody(
|
||||
0, ent,
|
||||
Ogre::Bullet::CT_TRIMESH,
|
||||
nullptr, 2, 0x7fffffff);
|
||||
}
|
||||
} else {
|
||||
output.push_back(collider_queue.front());
|
||||
@@ -338,13 +364,10 @@ public:
|
||||
};
|
||||
class DummyPageProvider : public Ogre::PageProvider {
|
||||
public:
|
||||
DummyPageProvider(btDynamicsWorld *world)
|
||||
DummyPageProvider(/* btDynamicsWorld *world */)
|
||||
: Ogre::PageProvider()
|
||||
, mBtWorld(world)
|
||||
{
|
||||
}
|
||||
std::unordered_map<Ogre::PageID, btRigidBody *> body;
|
||||
btDynamicsWorld *mBtWorld;
|
||||
bool prepareProceduralPage(Ogre::Page *page,
|
||||
Ogre::PagedWorldSection *section)
|
||||
{
|
||||
@@ -377,6 +400,7 @@ TerrainModule::TerrainModule(flecs::world &ecs)
|
||||
ecs.component<CanSetPlayerPosition>().add(flecs::Singleton);
|
||||
ecs.component<Terrain>().add(flecs::Singleton);
|
||||
ecs.component<TerrainPrivate>().add(flecs::Singleton);
|
||||
ecs.component<PlacementObjects>();
|
||||
ecs.set<TerrainPrivate>({ nullptr, {} });
|
||||
ecs.system<const EngineData, const Camera, const Sun, Terrain,
|
||||
TerrainPrivate>("SetupUpdateTerrain")
|
||||
@@ -389,8 +413,8 @@ TerrainModule::TerrainModule(flecs::world &ecs)
|
||||
if (!priv.mDummyPageProvider)
|
||||
priv.mDummyPageProvider =
|
||||
new DummyPageProvider(
|
||||
eng.mWorld
|
||||
->getBtWorld());
|
||||
/* eng.mWorld
|
||||
->getBtWorld() */);
|
||||
terrain.mTerrainGlobals =
|
||||
OGRE_NEW Ogre::TerrainGlobalOptions();
|
||||
|
||||
@@ -477,7 +501,7 @@ TerrainModule::TerrainModule(flecs::world &ecs)
|
||||
|
||||
terrain.mTerrainPagedWorldSection->setDefiner(
|
||||
OGRE_NEW FlatTerrainDefiner(
|
||||
eng.mScnMgr, eng.mWorld));
|
||||
eng.mScnMgr /*, eng.mWorld */));
|
||||
|
||||
terrain.mTerrainGroup->freeTemporaryResources();
|
||||
std::cout << "Terrain setup done\n";
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "WaterModule.h"
|
||||
namespace ECS
|
||||
{
|
||||
#if 0
|
||||
class WaterPhysicsAction : public btActionInterface {
|
||||
btPairCachingGhostObject *mWaterBody;
|
||||
btManifoldArray mManifoldArray;
|
||||
@@ -53,13 +54,13 @@ public:
|
||||
return (mInWater.find(body) != mInWater.end());
|
||||
}
|
||||
};
|
||||
#endif
|
||||
static const uint32_t WATER_MASK = 0xF00;
|
||||
WaterModule::WaterModule(flecs::world &ecs)
|
||||
{
|
||||
ecs.module<WaterModule>();
|
||||
ecs.component<WaterSurface>()
|
||||
.on_add([](flecs::entity e, WaterSurface &water) {
|
||||
ECS::get().add<WaterBody>();
|
||||
water.mAbove = false;
|
||||
water.mDepthMaterial = nullptr;
|
||||
water.mDepthTech = nullptr;
|
||||
@@ -457,10 +458,14 @@ WaterModule::WaterModule(flecs::world &ecs)
|
||||
eng.mScnMgr->getRenderQueue()->setRenderableListener(
|
||||
&water.mRenderTargetListener);
|
||||
std::cout << "Water setup done\n";
|
||||
ECS::get().add<WaterAlmostReady>();
|
||||
})
|
||||
.add(flecs::Singleton);
|
||||
#if 0
|
||||
ecs.component<WaterBody>().add(flecs::Singleton);
|
||||
ecs.component<WaterBody>()
|
||||
.on_add([this](WaterBody &body) {
|
||||
#if 0
|
||||
body.mShapeAabbMax = btVector3(0, 0, 0);
|
||||
body.mShapeAabbMin = btVector3(0, 0, 0);
|
||||
body.mSurface.clear();
|
||||
@@ -489,9 +494,11 @@ WaterModule::WaterModule(flecs::world &ecs)
|
||||
.get<EngineData>()
|
||||
.mWorld->getBtWorld()
|
||||
->addAction(body.action);
|
||||
#endif
|
||||
ECS::get().add<WaterReady>();
|
||||
})
|
||||
.add(flecs::Singleton);
|
||||
#endif
|
||||
ecs.system<const EngineData, const Camera, WaterSurface>("UpdateWater")
|
||||
.kind(flecs::OnUpdate)
|
||||
.with<WaterReady>()
|
||||
@@ -520,6 +527,7 @@ WaterModule::WaterModule(flecs::world &ecs)
|
||||
// water.mRenderTargetListener.mInDepth = false;
|
||||
// water.mWaterEnt->setVisible(true);
|
||||
});
|
||||
#if 0
|
||||
ecs.system<const EngineData, const WaterSurface, WaterBody>(
|
||||
"UpdateWaterBody")
|
||||
.kind(flecs::OnUpdate)
|
||||
@@ -527,6 +535,7 @@ WaterModule::WaterModule(flecs::world &ecs)
|
||||
.each([this](const EngineData &eng, const WaterSurface &water,
|
||||
WaterBody &body) {
|
||||
int i;
|
||||
#if 0
|
||||
OgreAssert(body.mWaterBody, "Water not ready");
|
||||
std::set<btCollisionObject *> currentOverlaps;
|
||||
Ogre::Vector3 waterPos =
|
||||
@@ -542,6 +551,7 @@ WaterModule::WaterModule(flecs::world &ecs)
|
||||
body.mWaterBody->getWorldTransform().setOrigin(
|
||||
Ogre::Bullet::convert(waterBodyPos +
|
||||
d));
|
||||
#endif
|
||||
#if 0
|
||||
btCompoundShape *mshape =
|
||||
static_cast<btCompoundShape *>(
|
||||
@@ -646,6 +656,7 @@ WaterModule::WaterModule(flecs::world &ecs)
|
||||
}
|
||||
#endif
|
||||
});
|
||||
#endif
|
||||
}
|
||||
struct shapeParams {
|
||||
float offsetX, offsetY, offsetZ;
|
||||
@@ -654,6 +665,7 @@ struct shapeParams {
|
||||
static struct shapeParams childShapes[] = {
|
||||
{ 0.0f, 0.0f, 0.0f, 100.0f, 100.0f, 100.0f },
|
||||
};
|
||||
#if 0
|
||||
void WaterModule::createWaterShape(WaterBody *water)
|
||||
{
|
||||
int i = 0;
|
||||
@@ -684,6 +696,7 @@ void WaterModule::createWaterShape(WaterBody *water)
|
||||
shape->recalculateLocalAabb();
|
||||
water->mWaterShape = shape;
|
||||
}
|
||||
#endif
|
||||
void WaterSurface::RenderTextureListener::preRenderTargetUpdate(
|
||||
const Ogre::RenderTargetEvent &evt)
|
||||
{
|
||||
@@ -712,6 +725,7 @@ bool WaterSurface::RenderTextureListener::renderableQueued(
|
||||
*ppTech = mSurface->mDepthTech;
|
||||
return true;
|
||||
}
|
||||
#if 0
|
||||
struct DeepPenetrationContactResultCallback : public btManifoldResult {
|
||||
DeepPenetrationContactResultCallback(
|
||||
const btCollisionObjectWrapper *body0Wrap,
|
||||
@@ -954,8 +968,11 @@ void WaterPhysicsAction::debugDraw(btIDebugDraw *debugDrawer)
|
||||
void WaterPhysicsAction::setupBody()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
bool WaterBody::isInWater(const btCollisionObject *body) const
|
||||
{
|
||||
return static_cast<WaterPhysicsAction *>(action)->isInWater(body);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -37,20 +37,10 @@ struct WaterSurface {
|
||||
mRefractionClipPlaneBelow;
|
||||
Ogre::Viewport *mViewports[4];
|
||||
};
|
||||
struct WaterBody {
|
||||
std::vector<btCollisionShape *> mChildShapes;
|
||||
btCollisionShape *mWaterShape;
|
||||
btPairCachingGhostObject *mWaterBody;
|
||||
std::unordered_map<btCollisionObject *, float> mSurface;
|
||||
btVector3 mShapeAabbMin, mShapeAabbMax;
|
||||
int count;
|
||||
btActionInterface *action;
|
||||
bool isInWater(const btCollisionObject *body) const;
|
||||
};
|
||||
struct WaterModule {
|
||||
btPairCachingGhostObject *mGhostObject;
|
||||
// btPairCachingGhostObject *mGhostObject;
|
||||
WaterModule(flecs::world &ecs);
|
||||
void createWaterShape(WaterBody *water);
|
||||
// void createWaterShape(WaterBody *water);
|
||||
};
|
||||
}
|
||||
#endif
|
||||
@@ -2,6 +2,7 @@
|
||||
#define H_GOAP_H_
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <flecs.h>
|
||||
namespace ECS
|
||||
{
|
||||
@@ -346,4 +347,4 @@ template <class RunnerType> struct DeclareAction : public BaseAction {
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user