Action nodes work better now
This commit is contained in:
@@ -27,6 +27,7 @@ CharacterModule::CharacterModule(flecs::world &ecs)
|
||||
ecs.component<CharacterInActuator>();
|
||||
ecs.component<Male>();
|
||||
ecs.component<Female>();
|
||||
ecs.component<CharacterControlDisable>();
|
||||
ecs.import <CharacterAnimationModule>();
|
||||
ecs.import <TerrainModule>();
|
||||
ecs.import <WaterModule>();
|
||||
@@ -131,75 +132,14 @@ 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)
|
||||
.with<TerrainReady>()
|
||||
.with<WaterReady>()
|
||||
.with<InWater>()
|
||||
.without<CharacterDisablePhysics>()
|
||||
.without<CharacterUpdatePhysicsState>()
|
||||
.each([this](flecs::entity e, const EngineData &eng,
|
||||
const CharacterBase &ch, CharacterVelocity &gr) {
|
||||
Ogre::Vector3 gravity(0, -9.8f, 0);
|
||||
Ogre::Vector3 pos = ch.mBodyNode->getPosition();
|
||||
Ogre::Vector3 v(0, 0, 0);
|
||||
if (e.has<CharacterGravity>())
|
||||
v += gravity;
|
||||
if (e.has<CharacterBuoyancy>()) {
|
||||
float volume = 2.0f * 0.5f * 0.5f;
|
||||
float density = 900.0f;
|
||||
float full_subm = 2.0f;
|
||||
float mass = 80.0f;
|
||||
float multiplier = 0.25f;
|
||||
float current_subm = -Ogre::Math::Clamp(
|
||||
pos.y + Ogre::Math::Sin(ch.mTimer *
|
||||
0.13f +
|
||||
130.0f) *
|
||||
0.07f,
|
||||
-full_subm, 0.0f);
|
||||
|
||||
Ogre::Vector3 b = -gravity * density * volume *
|
||||
multiplier * current_subm /
|
||||
full_subm / mass;
|
||||
v += b;
|
||||
}
|
||||
gr.gvelocity += v * eng.delta;
|
||||
gr.gvelocity.y =
|
||||
Ogre::Math::Clamp(gr.gvelocity.y, -2.5f, 1.5f);
|
||||
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)
|
||||
.with<TerrainReady>()
|
||||
.with<WaterReady>()
|
||||
.without<InWater>()
|
||||
.with<CharacterGravity>()
|
||||
.without<CharacterDisablePhysics>()
|
||||
.each([this](flecs::entity e, const EngineData &eng,
|
||||
const CharacterBase &ch, CharacterVelocity &gr) {
|
||||
Ogre::Vector3 gravity(0, -9.8f, 0);
|
||||
Ogre::Vector3 pos = ch.mBodyNode->getPosition();
|
||||
gr.gvelocity += gravity * eng.delta;
|
||||
if (pos.y < -1.2) {
|
||||
gr.gvelocity.y = 0.0f;
|
||||
}
|
||||
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)
|
||||
.with<Character>()
|
||||
.with<Player>()
|
||||
.without<CharacterInActuator>()
|
||||
.each([](flecs::entity e, const Input &input,
|
||||
.without<CharacterControlDisable>()
|
||||
.each([](flecs::entity e, const Input &input,
|
||||
const Camera &camera, CharacterBase &ch) {
|
||||
ch.mGoalDirection = Ogre::Vector3::ZERO;
|
||||
float delta = e.world().delta_time();
|
||||
@@ -604,6 +544,92 @@ void CharacterModule::updateCameraGoal(Camera &camera, Ogre::Real deltaYaw,
|
||||
}
|
||||
}
|
||||
|
||||
void applyWeightBasedScale(Ogre::Entity *ent,
|
||||
const Ogre::String &targetBoneName,
|
||||
const Ogre::Vector3 &scale)
|
||||
{
|
||||
Ogre::MeshPtr mesh = ent->getMesh();
|
||||
Ogre::SkeletonInstance *skel = ent->getSkeleton();
|
||||
Ogre::Bone *targetBone = skel->getBone(targetBoneName);
|
||||
|
||||
// Create a non-uniform scale matrix relative to the bone's local space
|
||||
Ogre::Matrix4 scaleMatrix = Ogre::Matrix4::IDENTITY;
|
||||
scaleMatrix.setScale(scale);
|
||||
|
||||
for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) {
|
||||
Ogre::SubMesh *submesh = mesh->getSubMesh(i);
|
||||
Ogre::VertexData *vertexData = submesh->useSharedVertices ?
|
||||
mesh->sharedVertexData :
|
||||
submesh->vertexData;
|
||||
|
||||
// 1. Get Position Element
|
||||
const Ogre::VertexElement *posElem =
|
||||
vertexData->vertexDeclaration->findElementBySemantic(
|
||||
Ogre::VES_POSITION);
|
||||
Ogre::HardwareVertexBufferSharedPtr vbuf =
|
||||
vertexData->vertexBufferBinding->getBuffer(
|
||||
posElem->getSource());
|
||||
|
||||
// 2. Access Bone Assignments
|
||||
// This map tells us which bones influence which vertex and by how much
|
||||
const Ogre::Mesh::VertexBoneAssignmentList &vbal =
|
||||
submesh->getBoneAssignments();
|
||||
|
||||
// Lock buffer for reading and writing
|
||||
float *pVertices = static_cast<float *>(
|
||||
vbuf->lock(Ogre::HardwareBuffer::HBL_NORMAL));
|
||||
|
||||
for (size_t vIdx = 0; vIdx < vertexData->vertexCount; ++vIdx) {
|
||||
float totalWeight = 0.0f;
|
||||
|
||||
// Find assignments for this specific vertex
|
||||
for (auto const &[index, assignment] : vbal) {
|
||||
if (assignment.vertexIndex == vIdx &&
|
||||
assignment.boneIndex ==
|
||||
targetBone->getHandle()) {
|
||||
totalWeight = assignment.weight;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (totalWeight > 0.0f) {
|
||||
float *pPos;
|
||||
posElem->baseVertexPointerToElement(
|
||||
reinterpret_cast<unsigned char *>(
|
||||
pVertices) +
|
||||
vIdx * vbuf->getVertexSize(),
|
||||
&pPos);
|
||||
|
||||
Ogre::Vector3 vertexPos(pPos[0], pPos[1],
|
||||
pPos[2]);
|
||||
|
||||
// Transform vertex to bone local space, scale it, then move back
|
||||
// This ensures scaling happens along the bone's axis, not the world axis
|
||||
Ogre::Vector3 localPos =
|
||||
targetBone->_getDerivedOrientation()
|
||||
.Inverse() *
|
||||
(vertexPos -
|
||||
targetBone->_getDerivedPosition());
|
||||
Ogre::Vector3 scaledLocalPos =
|
||||
scaleMatrix * localPos;
|
||||
Ogre::Vector3 worldPos =
|
||||
(targetBone->_getDerivedOrientation() *
|
||||
scaledLocalPos) +
|
||||
targetBone->_getDerivedPosition();
|
||||
|
||||
// Interpolate based on weight (Lerp) to handle vertices shared with other bones
|
||||
Ogre::Vector3 finalPos = Ogre::Math::lerp(
|
||||
vertexPos, worldPos, totalWeight);
|
||||
|
||||
pPos[0] = finalPos.x;
|
||||
pPos[1] = finalPos.y;
|
||||
pPos[2] = finalPos.z;
|
||||
}
|
||||
}
|
||||
vbuf->unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void CharacterModule::createCharacter(flecs::entity e,
|
||||
const Ogre::Vector3 &position,
|
||||
const Ogre::Quaternion &rotation,
|
||||
|
||||
Reference in New Issue
Block a user