Skip to content

Commit

Permalink
UPBGE: Use one display array bucket per deformer.
Browse files Browse the repository at this point in the history
Previously the modifier deformers were allowed to share the same
display array bucket, but this behaviour was limiting because in
the display array bucket we didn't know which deformer we have to
get info from.

Now every deformer have it's unique display array bucket, in the
theorical side is much better because modifier deformers produce
different render so the display array is different even if we don't
create a real display array and simply let derived mesh draw.
On the practical side it's also benefical because we can now determine
if a display array bucket can use render nodes with display array
or not and do this choose at the instanciation of the diaplay array
bucket.
  • Loading branch information
panzergame committed May 19, 2017
1 parent 8ba5fef commit 1b30104
Show file tree
Hide file tree
Showing 9 changed files with 32 additions and 93 deletions.
4 changes: 0 additions & 4 deletions source/gameengine/Converter/BL_SkinDeformer.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,6 @@ class BL_SkinDeformer : public BL_MeshDeformer
{
m_lastArmaUpdate = -1.0;
}
virtual bool ShareVertexArray()
{
return false;
}

protected:
BL_ArmatureObject *m_armobj; // Our parent object
Expand Down
4 changes: 0 additions & 4 deletions source/gameengine/Converter/KX_SoftBodyDeformer.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,6 @@ class KX_SoftBodyDeformer : public RAS_Deformer
{
return true;
}
virtual bool ShareVertexArray()
{
return false;
}
};

#endif
Expand Down
2 changes: 1 addition & 1 deletion source/gameengine/Rasterizer/RAS_BatchGroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ bool RAS_BatchGroup::MergeMeshUser(RAS_MeshUser *meshUser, const MT_Matrix4x4& m
RAS_IDisplayArray *origarray = meshSlot->GetDisplayArray();
batch.m_displayArray = RAS_IBatchDisplayArray::ConstructArray(origarray->GetPrimitiveType(), origarray->GetFormat());
batch.m_displayArrayBucket = new RAS_DisplayArrayBucket(meshSlot->m_bucket, batch.m_displayArray,
meshSlot->m_mesh, meshSlot->m_meshMaterial);
meshSlot->m_mesh, meshSlot->m_meshMaterial, nullptr);
}

if (!MergeMeshSlot(batch, meshSlot, mat)) {
Expand Down
4 changes: 0 additions & 4 deletions source/gameengine/Rasterizer/RAS_Deformer.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,6 @@ class RAS_Deformer
{
return false;
}
virtual bool ShareVertexArray()
{
return true;
}
virtual bool UseVertexArray()
{
return true;
Expand Down
25 changes: 10 additions & 15 deletions source/gameengine/Rasterizer/RAS_DisplayArrayBucket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,13 @@
# include <windows.h>
#endif // WIN32

RAS_DisplayArrayBucket::RAS_DisplayArrayBucket(RAS_MaterialBucket *bucket, RAS_IDisplayArray *array, RAS_MeshObject *mesh, RAS_MeshMaterial *meshmat)
RAS_DisplayArrayBucket::RAS_DisplayArrayBucket(RAS_MaterialBucket *bucket, RAS_IDisplayArray *array,
RAS_MeshObject *mesh, RAS_MeshMaterial *meshmat, RAS_Deformer *deformer)
:m_bucket(bucket),
m_displayArray(array),
m_mesh(mesh),
m_meshMaterial(meshmat),
m_deformer(deformer),
m_useVao(true),
m_storageInfo(nullptr),
m_instancingBuffer(nullptr),
Expand Down Expand Up @@ -94,6 +96,7 @@ void RAS_DisplayArrayBucket::ProcessReplica()
m_displayArray = m_displayArray->GetReplica();
}

m_deformer = nullptr;
// Request to recreate storage info.
m_storageInfo = nullptr;

Expand Down Expand Up @@ -140,17 +143,9 @@ unsigned int RAS_DisplayArrayBucket::GetNumActiveMeshSlots() const
return m_activeMeshSlots.size();
}

void RAS_DisplayArrayBucket::AddDeformer(RAS_Deformer *deformer)
void RAS_DisplayArrayBucket::SetDeformer(RAS_Deformer *deformer)
{
m_deformerList.push_back(deformer);
}

void RAS_DisplayArrayBucket::RemoveDeformer(RAS_Deformer *deformer)
{
RAS_DeformerList::iterator it = std::find(m_deformerList.begin(), m_deformerList.end(), deformer);
if (it != m_deformerList.end()) {
m_deformerList.erase(it);
}
m_deformer = deformer;
}

bool RAS_DisplayArrayBucket::UseVao() const
Expand All @@ -175,11 +170,11 @@ void RAS_DisplayArrayBucket::UpdateActiveMeshSlots(RAS_Rasterizer *rasty)
m_useVao = false;
}

for (RAS_Deformer *deformer : m_deformerList) {
deformer->Apply(material, m_meshMaterial);
if (m_deformer) {
m_deformer->Apply(material, m_meshMaterial);

// Test if one of deformers is dynamic.
if (deformer->IsDynamic()) {
// Test if deformer is dynamic.
if (m_deformer->IsDynamic()) {
arrayModified = true;
}
}
Expand Down
12 changes: 4 additions & 8 deletions source/gameengine/Rasterizer/RAS_DisplayArrayBucket.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@ class RAS_Deformer;
class RAS_IStorageInfo;
class RAS_InstancingBuffer;

typedef std::vector<RAS_Deformer *> RAS_DeformerList;

class RAS_DisplayArrayBucket : public CM_RefCount<RAS_DisplayArrayBucket>
{
private:
Expand All @@ -65,7 +63,7 @@ class RAS_DisplayArrayBucket : public CM_RefCount<RAS_DisplayArrayBucket>
/// The list fo all visible mesh slots to render this frame.
RAS_MeshSlotList m_activeMeshSlots;
/// The list of all deformer usign this display array.
RAS_DeformerList m_deformerList;
RAS_Deformer *m_deformer;

/// As m_useDisplayList but without rasterizer value.
bool m_useVao;
Expand All @@ -92,7 +90,8 @@ class RAS_DisplayArrayBucket : public CM_RefCount<RAS_DisplayArrayBucket>
RAS_DisplayArrayDownwardNode m_batchingNode;

public:
RAS_DisplayArrayBucket(RAS_MaterialBucket *bucket, RAS_IDisplayArray *array, RAS_MeshObject *mesh, RAS_MeshMaterial *meshmat);
RAS_DisplayArrayBucket(RAS_MaterialBucket *bucket, RAS_IDisplayArray *array,
RAS_MeshObject *mesh, RAS_MeshMaterial *meshmat, RAS_Deformer *deformer);
~RAS_DisplayArrayBucket();

/// \section Replication
Expand All @@ -112,10 +111,7 @@ class RAS_DisplayArrayBucket : public CM_RefCount<RAS_DisplayArrayBucket>
void RemoveActiveMeshSlots();

/// \section Deformer
/// Add a deformer user.
void AddDeformer(RAS_Deformer *deformer);
/// Remove the given deformer.
void RemoveDeformer(RAS_Deformer *deformer);
void SetDeformer(RAS_Deformer *deformer);

/// \section Render Infos
bool UseVao() const;
Expand Down
10 changes: 0 additions & 10 deletions source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,16 +214,6 @@ void RAS_MaterialBucket::SetDisplayArrayUnmodified()
}
}

RAS_DisplayArrayBucket *RAS_MaterialBucket::FindDisplayArrayBucket(RAS_IDisplayArray *array, RAS_MeshObject *mesh)
{
for (RAS_DisplayArrayBucket *displayArrayBucket : m_displayArrayBucketList) {
if (displayArrayBucket->GetDisplayArray() == array && displayArrayBucket->GetMesh() == mesh) {
return displayArrayBucket;
}
}
return nullptr;
}

void RAS_MaterialBucket::AddDisplayArrayBucket(RAS_DisplayArrayBucket *bucket)
{
m_displayArrayBucketList.push_back(bucket);
Expand Down
2 changes: 0 additions & 2 deletions source/gameengine/Rasterizer/RAS_MaterialBucket.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,6 @@ class RAS_MaterialBucket
void RemoveActiveMeshSlots();
unsigned int GetNumActiveMeshSlots();

/// Find a display array bucket for the given display array.
RAS_DisplayArrayBucket *FindDisplayArrayBucket(RAS_IDisplayArray *array, RAS_MeshObject *mesh);
void AddDisplayArrayBucket(RAS_DisplayArrayBucket *bucket);
void RemoveDisplayArrayBucket(RAS_DisplayArrayBucket *bucket);

Expand Down
62 changes: 17 additions & 45 deletions source/gameengine/Rasterizer/RAS_MeshSlot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,6 @@ RAS_MeshSlot::RAS_MeshSlot()

RAS_MeshSlot::~RAS_MeshSlot()
{
if (m_pDeformer) {
// Remove the deformer user in the display array bucket.
m_displayArrayBucket->RemoveDeformer(m_pDeformer);
}

if (m_displayArrayBucket) {
m_displayArrayBucket->Release();
}
Expand Down Expand Up @@ -103,7 +98,7 @@ void RAS_MeshSlot::init(RAS_MaterialBucket *bucket, RAS_MeshObject *mesh,
m_displayArray = RAS_IDisplayArray::ConstructArray(type, format);
}

m_displayArrayBucket = new RAS_DisplayArrayBucket(bucket, m_displayArray, m_mesh, meshmat);
m_displayArrayBucket = new RAS_DisplayArrayBucket(bucket, m_displayArray, m_mesh, meshmat, m_pDeformer);
}

RAS_IDisplayArray *RAS_MeshSlot::GetDisplayArray()
Expand All @@ -114,50 +109,27 @@ RAS_IDisplayArray *RAS_MeshSlot::GetDisplayArray()
void RAS_MeshSlot::SetDeformer(RAS_Deformer *deformer)
{
if (deformer && m_pDeformer != deformer) {
if (deformer->ShareVertexArray()) {
// this deformer uses the base vertex array, first release the current ones
m_displayArrayBucket->Release();
m_displayArrayBucket = nullptr;
// then hook to the base ones
if (m_meshMaterial && m_meshMaterial->m_baseslot) {
m_displayArrayBucket = m_meshMaterial->m_baseslot->m_displayArrayBucket->AddRef();
}
}
else {
// no sharing
// we create local copy of RAS_DisplayArray when we have a deformer:
// this way we can avoid conflict between the vertex cache of duplicates
if (deformer->UseVertexArray()) {
// the deformer makes use of vertex array, make sure we have our local copy
if (m_displayArrayBucket->GetRefCount() > 1) {
// only need to copy if there are other users
// note that this is the usual case as vertex arrays are held by the material base slot
m_displayArrayBucket->Release();
m_displayArrayBucket = m_displayArrayBucket->GetReplica();
}
}
else {
// the deformer is not using vertex array (Modifier), release them
// no sharing
// we create local copy of RAS_DisplayArray when we have a deformer:
// this way we can avoid conflict between the vertex cache of duplicates
if (deformer->UseVertexArray()) {
// the deformer makes use of vertex array, make sure we have our local copy
if (m_displayArrayBucket->GetRefCount() > 1) {
// only need to copy if there are other users
// note that this is the usual case as vertex arrays are held by the material base slot
m_displayArrayBucket->Release();
m_displayArrayBucket = m_bucket->FindDisplayArrayBucket(nullptr, m_mesh);
if (m_displayArrayBucket) {
m_displayArrayBucket->AddRef();
}
else {
m_displayArrayBucket = new RAS_DisplayArrayBucket(m_bucket, nullptr, m_mesh, m_meshMaterial);
}
m_displayArrayBucket = m_displayArrayBucket->GetReplica();
}
}

if (m_displayArrayBucket) {
// Add the deformer user in the display array bucket.
m_displayArrayBucket->AddDeformer(deformer);
// Update m_displayArray to the display array bucket.
m_displayArray = m_displayArrayBucket->GetDisplayArray();
m_displayArrayBucket->SetDeformer(deformer);
}
else {
m_displayArray = nullptr;
// the deformer is not using vertex array (Modifier), release them
m_displayArrayBucket->Release();
m_displayArrayBucket = new RAS_DisplayArrayBucket(m_bucket, nullptr, m_mesh, m_meshMaterial, deformer);
}

// Update m_displayArray to the display array bucket.
m_displayArray = m_displayArrayBucket->GetDisplayArray();
}
m_pDeformer = deformer;
}
Expand Down

0 comments on commit 1b30104

Please sign in to comment.