mirror of
https://github.com/rrika/cdcEngineDXHR.git
synced 2024-11-23 05:29:57 +00:00
implement culling for InstanceDrawable
This commit is contained in:
parent
3087c2aa5a
commit
5af34c4a5a
@ -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:
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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(¢er, &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;
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user