Intagrated Tracy, debugged animations

This commit is contained in:
2026-02-12 14:00:05 +03:00
parent 7947690e80
commit 74a1adfb27
25 changed files with 1553 additions and 2109 deletions

View File

@@ -10,6 +10,7 @@
#include "GameData.h"
#include "Components.h"
#include "WaterModule.h"
#include <tracy/Tracy.hpp>
namespace ECS
{
#if 0
@@ -112,12 +113,6 @@ WaterModule::WaterModule(flecs::world &ecs)
Ogre::Plane(Ogre::Vector3(0.0, -1.0, 0.0), h);
water.mRefractionClipPlaneBelow =
Ogre::Plane(Ogre::Vector3(0.0, 1.0, 0.0), -h);
#if 0
if (Ogre::TextureManager::getSingleton()
.resourceExists(renderTargetName))
Ogre::TextureManager::getSingleton()
.remove(renderTargetName);
#endif
Ogre::TexturePtr reflectionTexture =
Ogre::TextureManager::getSingleton().createManual(
renderTargetName,
@@ -201,64 +196,6 @@ WaterModule::WaterModule(flecs::world &ecs)
Ogre::MANUAL_CULL_NONE);
pass->setVertexProgram("Water/water_vp");
pass->setFragmentProgram("Water/water_fp");
#if 0
Ogre::GpuProgramPtr water_vp =
Ogre::GpuProgramManager::getSingleton()
.getByName(
"Water/water_vp",
Ogre::RGN_AUTODETECT);
OgreAssert(water_vp != nullptr,
"VP failed");
pass->setGpuProgram(
Ogre::GPT_VERTEX_PROGRAM,
water_vp);
OgreAssert(water_vp->isSupported(),
"VP not supported");
Ogre::GpuProgramPtr water_fp =
Ogre::GpuProgramManager::getSingleton()
.getByName(
"Water/water_fp",
Ogre::RGN_AUTODETECT);
OgreAssert(water_vp != nullptr,
"FP failed");
pass->setGpuProgram(
Ogre::GPT_FRAGMENT_PROGRAM,
water_fp);
OgreAssert(water_fp->isSupported(),
"FP not supported");
Ogre::GpuProgramParametersSharedPtr paramsVP =
water_vp->getDefaultParameters();
paramsVP->setNamedAutoConstant(
"world",
Ogre::GpuProgramParameters::
ACT_WORLD_MATRIX);
paramsVP->setNamedAutoConstant(
"worldViewProj",
Ogre::GpuProgramParameters::
ACT_WORLDVIEWPROJ_MATRIX);
paramsVP->setNamedAutoConstant(
"textureProjMatrix",
Ogre::GpuProgramParameters::
ACT_TEXTURE_WORLDVIEWPROJ_MATRIX);
paramsVP->setNamedAutoConstant(
"eyePosition",
Ogre::GpuProgramParameters::
ACT_CAMERA_POSITION_OBJECT_SPACE);
paramsVP->setNamedAutoConstant(
"normalMatrix",
Ogre::GpuProgramParameters::
ACT_NORMAL_MATRIX);
paramsVP->setNamedAutoConstant(
"worldView",
Ogre::GpuProgramParameters::
ACT_WORLDVIEW_MATRIX);
paramsVP->setNamedAutoConstant(
"viewProj",
Ogre::GpuProgramParameters::
ACT_VIEWPROJ_MATRIX);
Ogre::GpuProgramParametersSharedPtr paramsFP =
water_fp->getDefaultParameters();
#endif
Ogre::TextureUnitState *texture_unit =
pass->createTextureUnitState();
texture_unit->setTextureName(
@@ -284,38 +221,7 @@ WaterModule::WaterModule(flecs::world &ecs)
Ogre::FT_MAG, Ogre::FO_LINEAR);
texture_unit2->setTextureFiltering(
Ogre::FT_MIP, Ogre::FO_LINEAR);
#if 0
bool success =
Ogre::RTShader::ShaderGenerator::getSingletonPtr()
->createShaderBasedTechnique(
*mat,
Ogre::MSN_DEFAULT,
Ogre::MSN_SHADERGEN);
OgreAssert(
success,
"createShaderBasedTechnique");
Ogre::RTShader::RenderState *renderState =
Ogre::RTShader::ShaderGenerator::
getSingletonPtr()
->getRenderState(
Ogre::MSN_SHADERGEN,
*mat,
0);
Ogre::RTShader::SubRenderState *perPixelLightModel =
Ogre::RTShader::ShaderGenerator::getSingletonPtr()
->createSubRenderState(
Ogre::RTShader::
SRS_PER_PIXEL_LIGHTING);
renderState->addTemplateSubRenderState(
perPixelLightModel);
#endif
}
#if 0
mat = Ogre::MaterialManager::getSingleton()
.getByName("Water/Above");
mat->load();
#endif
mat->load();
mat->setReceiveShadows(false);
/*
@@ -494,202 +400,37 @@ WaterModule::WaterModule(flecs::world &ecs)
"Water/Above");
})
.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();
body.mWaterBody = OGRE_NEW btPairCachingGhostObject();
createWaterShape(&body);
body.mWaterBody->setCollisionShape(body.mWaterShape);
btTransform bodyTransform;
bodyTransform.setIdentity();
body.mWaterBody->setWorldTransform(bodyTransform);
body.mWaterBody->setCollisionFlags(
body.mWaterBody->getCollisionFlags() |
btCollisionObject::CF_KINEMATIC_OBJECT |
btCollisionObject::CF_NO_CONTACT_RESPONSE);
body.mWaterBody->setActivationState(
DISABLE_DEACTIVATION);
const EngineData &eng = ECS::get<EngineData>();
const WaterSurface &water = ECS::get<WaterSurface>();
eng.mWorld->attachCollisionObject(body.mWaterBody,
water.mWaterEnt, 16,
0x7fffffff & ~2);
WaterPhysicsAction *action =
OGRE_NEW WaterPhysicsAction(body.mWaterBody);
body.action = action;
ECS::get()
.get<EngineData>()
.mWorld->getBtWorld()
->addAction(body.action);
#endif
ECS::get().add<WaterReady>();
})
.add(flecs::Singleton);
#endif
ecs.system<const EngineData, const Camera, WaterSurface>("UpdateWater")
ecs.system<const EngineData, const Camera, WaterSurface>(
"UpdateWaterPosition")
.kind(flecs::OnUpdate)
.with<WaterReady>()
.interval(0.3f)
.each([](const EngineData &eng, const Camera &camera,
WaterSurface &water) {
float delta = eng.delta;
Ogre::Vector3 mCameraPos =
camera.mCameraNode->_getDerivedPosition();
Ogre::Vector3 waterPos =
water.mWaterNode->_getDerivedPosition();
mCameraPos.y = 0;
waterPos.y = 0;
Ogre::Vector3 d = mCameraPos - waterPos;
// Ogre::Vector3 waterPosition = mCameraPos;
// mWaterNode->setPosition(waterPosition);
if (d.squaredLength() < 100.0f * 100.0f)
water.mWaterNode->translate(d * 3.0f * delta);
else
water.mWaterNode->translate(d);
// water.mWaterEnt->setVisible(false);
water.mViewports[0]->update();
water.mViewports[1]->update();
// water.mRenderTargetListener.mInDepth = true;
// water.mViewports[2]->update();
// water.mViewports[3]->update();
// water.mRenderTargetListener.mInDepth = false;
// water.mWaterEnt->setVisible(true);
ZoneScopedN("UpdateWaterPosition");
float delta = eng.delta;
Ogre::Vector3 mCameraPos =
camera.mCameraNode->_getDerivedPosition();
Ogre::Vector3 waterPos =
water.mWaterNode->_getDerivedPosition();
mCameraPos.y = 0;
waterPos.y = 0;
Ogre::Vector3 d = mCameraPos - waterPos;
if (d.squaredLength() < 100.0f * 100.0f)
water.mWaterNode->translate(d * 3.0f * delta);
else
water.mWaterNode->translate(d);
});
ecs.system<WaterSurface>("UpdateWater")
.kind(flecs::OnUpdate)
.with<WaterReady>()
.each([](WaterSurface &water) {
static int updateViewport = 0;
ZoneScopedN("UpdateWaterRender");
water.mViewports[updateViewport++]->update();
if (updateViewport > 1)
updateViewport = 0;
});
#if 0
ecs.system<const EngineData, const WaterSurface, WaterBody>(
"UpdateWaterBody")
.kind(flecs::OnUpdate)
.with<WaterReady>()
.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 =
water.mWaterNode->_getDerivedPosition();
Ogre::Vector3 waterBodyPos = Ogre::Bullet::convert(
body.mWaterBody->getWorldTransform()
.getOrigin());
waterPos.y = 0;
waterBodyPos.y = 0;
Ogre::Vector3 d = waterPos - waterBodyPos;
d.y = 0;
if (d.squaredLength() > 10.0f * 10.0f)
body.mWaterBody->getWorldTransform().setOrigin(
Ogre::Bullet::convert(waterBodyPos +
d));
#endif
#if 0
btCompoundShape *mshape =
static_cast<btCompoundShape *>(
body.mWaterBody->getCollisionShape());
btDispatcher *dispatch =
eng.mWorld->getBtWorld()->getDispatcher();
btHashedOverlappingPairCache *cache =
body.mWaterBody->getOverlappingPairCache();
btBroadphasePairArray &collisionPairs =
cache->getOverlappingPairArray();
const int numObjects = collisionPairs.size();
std::cout << "numObjects: " << numObjects << "\n";
std::cout
<< "numObjects: "
<< body.mWaterBody->getOverlappingPairs().size()
<< "\n";
for (int i = 0; i < numObjects; i++) {
const btBroadphasePair &collisionPair =
collisionPairs[i];
}
#endif
#if 0
body.mShapeAabbMin =
body.mWaterBody->getWorldTransform()
.getOrigin() +
btVector3(-100, -100, -100);
body.mShapeAabbMax =
body.mWaterBody->getWorldTransform()
.getOrigin() +
btVector3(100, 100, 100);
#if 0
body.mWaterShape->getAabb(
body.mWaterBody->getWorldTransform(),
body.mShapeAabbMin, body.mShapeAabbMax);
#endif
std::cout << "manifolds: "
<< static_cast<WaterPhysicsAction *>(
body.action)
->mManifoldArray.size()
<< "\n";
for (int j = 0;
j < static_cast<WaterPhysicsAction *>(body.action)
->mManifoldArray.size();
j++) {
btPersistentManifold *manifold =
static_cast<WaterPhysicsAction *>(
body.action)
->mManifoldArray[j];
std::cout << "contacts: "
<< manifold->getNumContacts() << "\n";
if (manifold->getNumContacts() == 0)
continue;
const btCollisionObject *obj =
(manifold->getBody0() ==
body.mWaterBody) ?
manifold->getBody1() :
manifold->getBody0();
btCollisionObject *nobj =
const_cast<btCollisionObject *>(obj);
#if 0
if (obj->getCollisionFlags() &
btCollisionObject::CF_STATIC_OBJECT)
continue;
#endif
bool ok = false;
Ogre::Vector3 contactPosA, contactPosB;
float minDist = 0.0f;
for (int p = 0; p < manifold->getNumContacts();
p++) {
const btManifoldPoint &pt =
manifold->getContactPoint(p);
float dist = pt.getDistance();
if (dist < minDist) {
minDist = dist;
ok = true;
}
}
if (ok) {
currentOverlaps.insert(nobj);
if (body.mInWater.find(nobj) ==
body.mInWater.end()) {
/* new body */
body.mInWater.insert(nobj);
/* calculate proj surface */
body.mSurface[nobj] = 100.0f;
body.count++;
}
}
}
for (std::set<btCollisionObject *>::iterator it =
body.mInWater.begin();
it != body.mInWater.end();) {
btCollisionObject *obj = *it;
if (currentOverlaps.find(obj) ==
currentOverlaps.end()) {
/* remove body */
it = body.mInWater.erase(it);
body.mSurface.erase(obj);
body.count--;
} else
it++;
}
#endif
});
#endif
}
struct shapeParams {
float offsetX, offsetY, offsetZ;
@@ -698,38 +439,6 @@ 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;
btCompoundShape *shape = OGRE_NEW btCompoundShape();
shape->setMargin(0.2f);
{
btVector3 inertia(0, 0, 0);
std::vector<btScalar> masses;
btTransform principal;
principal.setIdentity();
for (i = 0; i < sizeof(childShapes) / sizeof(childShapes[0]);
i++) {
btTransform xform;
xform.setIdentity();
xform.setOrigin(btVector3(childShapes[i].offsetX,
childShapes[i].offsetY,
childShapes[i].offsetZ));
btBoxShape *box = OGRE_NEW btBoxShape(btVector3(
childShapes[i].boxX, childShapes[i].boxY,
childShapes[i].boxZ));
water->mChildShapes.push_back(box);
shape->addChildShape(xform, box);
masses.push_back(0);
}
shape->calculatePrincipalAxisTransform(masses.data(), principal,
inertia);
}
shape->recalculateLocalAabb();
water->mWaterShape = shape;
}
#endif
void WaterSurface::RenderTextureListener::preRenderTargetUpdate(
const Ogre::RenderTargetEvent &evt)
{
@@ -758,254 +467,4 @@ bool WaterSurface::RenderTextureListener::renderableQueued(
*ppTech = mSurface->mDepthTech;
return true;
}
#if 0
struct DeepPenetrationContactResultCallback : public btManifoldResult {
DeepPenetrationContactResultCallback(
const btCollisionObjectWrapper *body0Wrap,
const btCollisionObjectWrapper *body1Wrap)
: btManifoldResult(body0Wrap, body1Wrap)
, mPenetrationDistance(0)
, mOtherIndex(0)
{
}
float mPenetrationDistance;
int mOtherIndex;
btVector3 mNormal, mPoint;
void reset()
{
mPenetrationDistance = 0.0f;
}
bool hasHit()
{
return mPenetrationDistance < 0.0f;
}
virtual void addContactPoint(const btVector3 &normalOnBInWorld,
const btVector3 &pointInWorldOnB,
btScalar depth)
{
#ifdef VDEBUG
std::cout
<< "contact: " << Ogre::Bullet::convert(pointInWorldOnB)
<< " " << Ogre::Bullet::convert(normalOnBInWorld)
<< "\n";
#endif
if (mPenetrationDistance > depth) { // Has penetration?
const bool isSwapped =
m_manifoldPtr->getBody0() !=
m_body0Wrap->getCollisionObject();
mPenetrationDistance = depth;
mOtherIndex = isSwapped ? m_index0 : m_index1;
mPoint = isSwapped ? (pointInWorldOnB +
(normalOnBInWorld * depth)) :
pointInWorldOnB;
mNormal = isSwapped ? normalOnBInWorld * -1 :
normalOnBInWorld;
}
}
};
void WaterPhysicsAction::updateAction(btCollisionWorld *collisionWorld,
btScalar deltaTimeStep)
{
collisionWorld->updateSingleAabb(mWaterBody);
mWaterBody->getCollisionShape()->getAabb(
mWaterBody->getWorldTransform(), mShapeAabbMin, mShapeAabbMax);
btDispatcher *dispatch = collisionWorld->getDispatcher();
btHashedOverlappingPairCache *cache =
mWaterBody->getOverlappingPairCache();
btBroadphasePairArray &collisionPairs =
cache->getOverlappingPairArray();
btVector3 a, b;
collisionWorld->getBroadphase()->getAabb(
mWaterBody->getBroadphaseHandle(), a, b);
collisionWorld->getBroadphase()->setAabb(
mWaterBody->getBroadphaseHandle(), mShapeAabbMin, mShapeAabbMax,
dispatch);
btDispatcherInfo &dispatchInfo = collisionWorld->getDispatchInfo();
dispatch->dispatchAllCollisionPairs(cache, dispatchInfo, dispatch);
std::set<btCollisionObject *> currentOverlaps;
std::set<btCollisionObject *>::iterator it;
const int numObjects = collisionPairs.size();
#ifdef VDEBUG
std::cout << "collision pairs: " << numObjects << "\n";
std::cout << "MIN: " << Ogre::Bullet::convert(mShapeAabbMin) << "\n";
std::cout << "MAX: " << Ogre::Bullet::convert(mShapeAabbMax) << "\n";
std::cout << "MIN: " << Ogre::Bullet::convert(a) << "\n";
std::cout << "MAX: " << Ogre::Bullet::convert(b) << "\n";
#endif
std::set<const btCollisionObject *> mCurrentInWater;
/* perform narrow phase */
for (int i = 0; i < numObjects; i++) {
int j;
const btBroadphasePair *collisionPairPtr =
collisionWorld->getBroadphase()
->getOverlappingPairCache()
->findPair(collisionPairs[i].m_pProxy0,
collisionPairs[i].m_pProxy1);
if (!collisionPairPtr)
continue;
#ifndef USE_MANIFOLD
const btBroadphasePair &collisionPair = *collisionPairPtr;
const btCollisionObject *objA =
static_cast<btCollisionObject *>(
collisionPair.m_pProxy0->m_clientObject);
const btCollisionObject *objB =
static_cast<btCollisionObject *>(
collisionPair.m_pProxy1->m_clientObject);
#ifdef VDEBUG
std::cout << "bodies: " << objA << " " << objB << "\n";
std::cout << "bodies: " << objA->getCollisionShape()->getName()
<< " " << objB->getCollisionShape()->getName()
<< "\n";
std::cout << "pair: " << i << " " << collisionPair.m_algorithm
<< "\n";
#endif
const btCollisionObject *me, *other;
if (objA == static_cast<btCollisionObject *>(mWaterBody)) {
me = objA;
other = objB;
} else {
me = objB;
other = objA;
}
const btCollisionShape *my_shape = me->getCollisionShape();
const btCollisionShape *other_shape =
other->getCollisionShape();
btCollisionObjectWrapper obA(NULL, my_shape, mWaterBody,
mWaterBody->getWorldTransform(),
-1, j);
btCollisionObjectWrapper obB(NULL, other_shape, other,
other->getWorldTransform(), -1, 0);
btCollisionAlgorithm *algorithm = dispatch->findAlgorithm(
&obA, &obB, NULL, BT_CONTACT_POINT_ALGORITHMS);
#else
btCollisionAlgorithm *algorithm = collisionPairPtr->m_algorithm;
OgreAssert(algorithm, "No algorithm found");
#endif
#ifdef VDEBUG
std::cout << "algorithm: " << algorithm << "\n";
#endif
#ifndef USE_MANIFOLD
DeepPenetrationContactResultCallback contactPointResult(&obA,
&obB);
#ifdef VDEBUG
std::cout << "process collision\n";
#endif
algorithm->processCollision(&obA, &obB,
collisionWorld->getDispatchInfo(),
&contactPointResult);
algorithm->~btCollisionAlgorithm();
dispatch->freeCollisionAlgorithm(algorithm);
if (contactPointResult.hasHit()) {
mCurrentInWater.insert(other);
mInWater.insert(other);
}
#ifdef VDEBUG
std::cout << "process collision done\n";
#endif
#else
if (collisionPairPtr->m_algorithm)
collisionPairPtr->m_algorithm->getAllContactManifolds(
mManifoldArray);
std::cout << "action: manifold: " << mManifoldArray.size()
<< "\n";
#endif
#if 0
std::cout << " "
<< Ogre::Bullet::convert(
collisionPair.m_pProxy0->m_aabbMin)
<< " -> "
<< Ogre::Bullet::convert(
collisionPair.m_pProxy0->m_aabbMax)
<< " VS "
<< Ogre::Bullet::convert(
collisionPair.m_pProxy1->m_aabbMin)
<< " -> "
<< Ogre::Bullet::convert(
collisionPair.m_pProxy1->m_aabbMax)
<< "\n";
std::cout << "group: 0 " << std::dec
<< collisionPair.m_pProxy0->m_collisionFilterGroup
<< "mask: " << std::hex
<< collisionPair.m_pProxy0->m_collisionFilterMask
<< "\n";
std::cout << "group: 1 " << std::dec
<< collisionPair.m_pProxy1->m_collisionFilterGroup
<< "mask: " << std::hex
<< collisionPair.m_pProxy1->m_collisionFilterMask
<< std::dec << "\n";
if (collisionPair.m_algorithm)
collisionPair.m_algorithm->getAllContactManifolds(
mManifoldArray);
std::cout << "action: manifold: " << mManifoldArray.size()
<< "\n";
#endif
#ifdef USE_MANIFOLD
for (int j = 0; j < mManifoldArray.size(); j++) {
btPersistentManifold *manifold = mManifoldArray[j];
std::cout << "contacts: " << manifold->getNumContacts()
<< "\n";
if (manifold->getNumContacts() == 0)
continue;
const btCollisionObject *obj =
(manifold->getBody0() == mWaterBody) ?
manifold->getBody1() :
manifold->getBody0();
btCollisionObject *nobj =
const_cast<btCollisionObject *>(obj);
#if 1
if (obj->getCollisionFlags() &
btCollisionObject::CF_STATIC_OBJECT)
continue;
#endif
bool ok = false;
Ogre::Vector3 contactPosA, contactPosB;
float minDist = 0.0f;
for (int p = 0; p < manifold->getNumContacts(); p++) {
const btManifoldPoint &pt =
manifold->getContactPoint(p);
float dist = pt.getDistance();
if (dist < minDist) {
minDist = dist;
ok = true;
}
}
if (ok) {
currentOverlaps.insert(nobj);
if (mInWater.find(nobj) == mInWater.end()) {
/* new body */
mInWater.insert(nobj);
}
}
}
#endif
}
for (std::set<const btCollisionObject *>::iterator it =
mInWater.begin();
it != mInWater.end();) {
const btCollisionObject *obj = *it;
if (mCurrentInWater.find(obj) == mCurrentInWater.end()) {
/* remove body */
it = mInWater.erase(it);
} else
it++;
}
#ifdef VDEBUG
std::cout << "water count: " << mInWater.size() << "\n";
#endif
}
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
}