implement culling for InstanceDrawable

This commit is contained in:
Adam Jensen 2023-06-19 02:14:07 +01:00
parent 3087c2aa5a
commit 5af34c4a5a
8 changed files with 73 additions and 4 deletions

View File

@ -13,7 +13,7 @@ class TransformComponent : public InstanceComponent {
public:
// Instance *m_instance = nullptr; // 4
Vector3 m_scale {1.0f, 1.0f, 1.0f, 1.0f}; // 10
Matrix *m_matrix = nullptr; // 20
Matrix *m_matrix = nullptr; // 20, read by UpdateInstances, written by G2Instance_SetTransformsToIdentity
int8_t m_rootMatrix = 0; // 31
uint8_t m_flags = 0; // C3, read by MeshComponent::SetModel
public:

View File

@ -10,6 +10,8 @@ public:
// 15 methods
virtual void GetBoundingVolume(BasicCullingVolume*) = 0; // 4
virtual void draw(Matrix *, float) = 0; // 1C
virtual bool GetBoundingSphere(Vector *pCenter, float *pRadius) { return false; } // 2C
virtual bool GetBoundingBox(Vector *pMin, Vector *pMax) { return false; } // 30
};
}

View File

@ -1,4 +1,5 @@
#pragma once
#include <cstdint>
#include "cdcMath/Math.h"
namespace cdc {
@ -8,7 +9,17 @@ class ISceneCellGroup;
class ISceneEntity {
public:
struct UpdateState {
uint32_t updateFlags;
bool enabled;
IDrawable *drawable;
SceneCellGroup *cellGroup;
Matrix matrix;
uint32_t moveState;
};
// 25 methods
virtual void ApplyUpdateState(UpdateState*) = 0; // 0
virtual void setMatrix(Matrix&) = 0; // 4
virtual Matrix& getMatrix() = 0; // 8
virtual void setDrawable(IDrawable *) = 0; // C

View File

@ -10,6 +10,16 @@ SceneEntity::SceneEntity(Scene *scene) : scene(scene) {
scene->AddEntity(this);
}
void SceneEntity::ApplyUpdateState(UpdateState *updateState) {
// called from UpdateInstances
// without this, the object might still render in the correct position
// but QueryVolumeFromDrawable can't move the culling volume away from origin
// HACK
if (updateState && (updateState->updateFlags & 8))
setMatrix(updateState->matrix);
}
void SceneEntity::setMatrix(Matrix& newMatrix) {
matrix = newMatrix;
QueryVolumeFromDrawable();

View File

@ -27,6 +27,7 @@ public:
SceneEntity(Scene *scene);
// 25 methods
void ApplyUpdateState(UpdateState*) override;
void setMatrix(Matrix&) override;
Matrix& getMatrix() override;
void setDrawable(IDrawable *) override;

View File

@ -4,7 +4,9 @@
#include "cdcWorld/Instance.h"
#include "rendering/CommonRenderDevice.h"
#include "rendering/Culling/BasicPrimitives.h"
#include "rendering/Culling/BasicPrimitives_inlines.h" // for SetFromMinMax
#include "rendering/PCDX11MatrixState.h"
#include "rendering/RenderMesh.h"
namespace cdc {
@ -82,9 +84,28 @@ InstanceDrawable::InstanceDrawable(Instance *instance) :
}
void InstanceDrawable::GetBoundingVolume(BasicCullingVolume *volume) {
// HACK
BasicCullingVolume everything;
*volume = everything;
Vector center, min, max;
float radius;
if (GetBoundingSphere(&center, &radius)) {
CullingSphere sphere {center};
const float minimumRadius = 1.0f / 0x4000;
if (radius < minimumRadius)
radius = minimumRadius;
sphere.m_sphereEq.w = radius;
volume->m_data.sphere = sphere;
volume->m_type = kVolumeSphere;
} else if (GetBoundingBox(&min, &max)) {
CullingBox box;
box.SetFromMinMax({min}, {max});
volume->m_data.box = box;
volume->m_type = kVolumeBox;
} else {
volume->m_type = kVolumeEverything;
}
}
void InstanceDrawable::draw(Matrix *, float) {
@ -115,6 +136,19 @@ void InstanceDrawable::draw(Matrix *, float) {
}
}
bool InstanceDrawable::GetBoundingSphere(Vector *pCenter, float *pRadius) {
// TODO
return false;
}
bool InstanceDrawable::GetBoundingBox(Vector *pMin, Vector *pMax) {
// HACK
MeshComponent& meshComponent = m_instance->GetMeshComponent();
cdc::RenderModelInstance *rmi = m_renderModelInstances[meshComponent.GetCurrentRenderModelIndex()];
cdc::RenderMesh const *rm = rmi->GetRenderMesh();
return rm->getBoundingBox(*(Vector3*)pMin, *(Vector3*)pMax);
}
void InstanceDrawable::AddToDirtyList() { // 2038
// dirty list is processed by SceneLayer::Update/UpdateInstances
m_pPrevDirty = s_pLastDirty;

View File

@ -55,6 +55,8 @@ public:
void GetBoundingVolume(cdc::BasicCullingVolume*) override;
void draw(cdc::Matrix *, float) override;
bool GetBoundingSphere(Vector *pCenter, float *pRadius) override;
bool GetBoundingBox(Vector *pMin, Vector *pMax) override;
void AddToDirtyList();
void RemoveFromDirtyList();

View File

@ -74,7 +74,16 @@ static void UpdateInstances() { // 2052
// TODO
if (i->sceneEntity)
SceneLayer::AddInstance(i);
// TODO
if (i->sceneEntity) {
SceneEntity::UpdateState us;
us.updateFlags = 8; // update the matrix
us.matrix = *i->GetTransformComponent().m_matrix;
i->sceneEntity->ApplyUpdateState(&us);
}
id->RemoveFromDirtyList(); // via ValidateAll
}
}