From f03fa79d28a112c39fcbab5d71b952333dc66fac Mon Sep 17 00:00:00 2001 From: Kester Maddock Date: Tue, 4 May 2004 09:34:02 +0000 Subject: [PATCH] Fix for bug #945 getVertexArrayLength(x) returns different values on different runs of the game engine. http://projects.blender.org/tracker/index.php?func=detail&aid=945&group_id=9&atid=125 The material buckets were being sorted by pointer (ie their location in memory.) Also fixed find shared verticies. --- .../Converter/BL_SkinMeshObject.cpp | 2 +- .../Rasterizer/RAS_IPolygonMaterial.cpp | 15 ++++++++++- .../Rasterizer/RAS_IPolygonMaterial.h | 9 +++++++ .../Rasterizer/RAS_MaterialBucket.cpp | 4 +-- .../Rasterizer/RAS_MaterialBucket.h | 26 +++++++++++++++---- .../gameengine/Rasterizer/RAS_MeshObject.cpp | 12 ++++----- source/gameengine/Rasterizer/RAS_MeshObject.h | 19 +++++++++++--- 7 files changed, 68 insertions(+), 19 deletions(-) diff --git a/source/gameengine/Converter/BL_SkinMeshObject.cpp b/source/gameengine/Converter/BL_SkinMeshObject.cpp index be85300dd71..364fd76776f 100644 --- a/source/gameengine/Converter/BL_SkinMeshObject.cpp +++ b/source/gameengine/Converter/BL_SkinMeshObject.cpp @@ -142,7 +142,7 @@ void BL_SkinMeshObject::Bucketize(double* oglmatrix,void* clientobj,bool useObje ms.m_RGBAcolor = rgbavec; ms.m_pDeformer = ((BL_DeformableGameObject*)clientobj)->m_pDeformer; - for (BucketMaterialSet::iterator it = m_materials.begin();it!=m_materials.end();it++) + for (RAS_MaterialBucket::Set::iterator it = m_materials.begin();it!=m_materials.end();it++) { RAS_MaterialBucket* materialbucket = (*it); diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp index 88fb5349764..33cdc43afd8 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp @@ -79,7 +79,20 @@ bool RAS_IPolyMaterial::Equals(const RAS_IPolyMaterial& lhs) const ); } - +bool RAS_IPolyMaterial::Less(const RAS_IPolyMaterial& rhs) const +{ + return ( + this->m_materialname < rhs.m_materialname || + this->m_texturename < rhs.m_texturename || + this->m_lightlayer < rhs.m_lightlayer || + this->m_tile < rhs.m_tile || + this->m_tilexrep < rhs.m_tilexrep || + this->m_tileyrep < rhs.m_tileyrep || + this->m_transparant < rhs.m_transparant || + this->m_drawingmode < rhs.m_drawingmode || + this->m_bIsTriangle < rhs.m_bIsTriangle + ); +} int RAS_IPolyMaterial::GetLightLayer() { diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h index 01c3e80c055..7d10f23068b 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h @@ -43,6 +43,9 @@ class RAS_IRasterizer; +/** + * Material properties. + */ class RAS_IPolyMaterial { //todo: remove these variables from this interface/protocol class @@ -104,6 +107,7 @@ public: virtual void Activate(RAS_IRasterizer* rasty, TCachingInfo& cachingInfo) const {} bool Equals(const RAS_IPolyMaterial& lhs) const; + bool Less(const RAS_IPolyMaterial& rhs) const; int GetLightLayer(); bool IsTransparant(); bool UsesTriangles(); @@ -118,5 +122,10 @@ inline bool operator ==( const RAS_IPolyMaterial & rhs,const RAS_IPolyMaterial return ( rhs.Equals(lhs)); } +inline bool operator < ( const RAS_IPolyMaterial & lhs, const RAS_IPolyMaterial & rhs) +{ + return lhs.Less(rhs); +} + #endif //__RAS_IPOLYGONMATERIAL diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp index 39de3a400aa..5f1766be0e4 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp @@ -97,7 +97,7 @@ void RAS_MaterialBucket::ClearScheduledPolygons() -RAS_IPolyMaterial* RAS_MaterialBucket::GetPolyMaterial() +RAS_IPolyMaterial* RAS_MaterialBucket::GetPolyMaterial() const { return m_material; } @@ -137,7 +137,7 @@ void RAS_MaterialBucket::MarkVisibleMeshSlot(KX_MeshSlot& ms, -bool RAS_MaterialBucket::IsTransparant() +bool RAS_MaterialBucket::IsTransparant() const { return (m_material->IsTransparant()); } diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.h b/source/gameengine/Rasterizer/RAS_MaterialBucket.h index e43273e9dcc..51174c12335 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.h +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.h @@ -51,7 +51,9 @@ typedef vector< KX_IndexArray* > vecIndexArrays; typedef vector KX_VertexArray; - +/** + * KX_VertexIndex + */ struct KX_VertexIndex { public: KX_VertexIndex(int size); @@ -62,7 +64,9 @@ public: }; - +/** + * KX_MeshSlot. + */ class KX_MeshSlot { public: @@ -86,7 +90,9 @@ inline bool operator <( const KX_MeshSlot& rhs,const KX_MeshSlot& lhs) return ( rhs.Less(lhs)); } - +/** + * Contains a list of meshs with the same material properties. + */ class RAS_MaterialBucket { typedef std::set T_MeshSlotList; @@ -108,8 +114,8 @@ public: void SchedulePolygons(int drawingmode); void ClearScheduledPolygons(); - RAS_IPolyMaterial* GetPolyMaterial(); - bool IsTransparant(); + RAS_IPolyMaterial* GetPolyMaterial() const; + bool IsTransparant() const; static void StartFrame(); static void EndFrame(); @@ -120,6 +126,16 @@ public: bool visible, bool color, const MT_Vector4& rgbavec); + + struct less + { + bool operator()(const RAS_MaterialBucket* x, const RAS_MaterialBucket* y) const + { + return *x->GetPolyMaterial() < *y->GetPolyMaterial(); + } + }; + + typedef set Set; }; #endif //__KX_BUCKET diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp index 79ec632ce73..4f5833df50b 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.cpp +++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp @@ -108,7 +108,7 @@ RAS_MaterialBucket* RAS_MeshObject::GetMaterialBucket(unsigned int matid) { if (m_materials.size() > 0 && (matid < m_materials.size())) { - BucketMaterialSet::const_iterator it = m_materials.begin(); + RAS_MaterialBucket::Set::const_iterator it = m_materials.begin(); while (matid--) ++it; return *it; } @@ -270,7 +270,7 @@ int RAS_MeshObject::FindOrAddVertex(int vtxarray, { if ((*it).m_arrayindex1 == ao->m_index1 && ((*it).m_array == vtxarray) && - (RAS_IPolyMaterial*) (*it).m_matid == mat + (*(RAS_IPolyMaterial*) (*it).m_matid) == *mat ) { return (*it).m_index; @@ -396,7 +396,7 @@ void RAS_MeshObject::Bucketize(double* oglmatrix, ms.m_bObjectColor = useObjectColor; ms.m_RGBAcolor = rgbavec; - for (BucketMaterialSet::iterator it = m_materials.begin();it!=m_materials.end();++it) + for (RAS_MaterialBucket::Set::iterator it = m_materials.begin();it!=m_materials.end();++it) { RAS_MaterialBucket* bucket = *it; bucket->SchedulePolygons(0); @@ -421,7 +421,7 @@ void RAS_MeshObject::MarkVisible(double* oglmatrix, ms.m_RGBAcolor = rgbavec; ms.m_bObjectColor= useObjectColor; - for (BucketMaterialSet::iterator it = m_materials.begin();it!=m_materials.end();++it) + for (RAS_MaterialBucket::Set::iterator it = m_materials.begin();it!=m_materials.end();++it) { RAS_MaterialBucket* bucket = *it; bucket->SchedulePolygons(0); @@ -440,7 +440,7 @@ void RAS_MeshObject::RemoveFromBuckets(double* oglmatrix, ms.m_mesh = this; ms.m_OpenGLMatrix = oglmatrix; - for (BucketMaterialSet::iterator it = m_materials.begin();it!=m_materials.end();++it) + for (RAS_MaterialBucket::Set::iterator it = m_materials.begin();it!=m_materials.end();++it) { RAS_MaterialBucket* bucket = *it; // RAS_IPolyMaterial* polymat = bucket->GetPolyMaterial(); @@ -562,7 +562,7 @@ void RAS_MeshObject::SchedulePolygons(int drawingmode,RAS_IRasterizer* rasty) if (m_bModified) { - for (BucketMaterialSet::iterator it = m_materials.begin();it!=m_materials.end();++it) + for (RAS_MaterialBucket::Set::iterator it = m_materials.begin();it!=m_materials.end();++it) { RAS_MaterialBucket* bucket = *it; diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.h b/source/gameengine/Rasterizer/RAS_MeshObject.h index 87a5e6be77c..78e142fda8a 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.h +++ b/source/gameengine/Rasterizer/RAS_MeshObject.h @@ -41,10 +41,14 @@ #include #include "RAS_Polygon.h" +#include "RAS_MaterialBucket.h" #include "MT_Transform.h" #include "GEN_HashedPtr.h" +/** + * This class holds an array of vertices and indicies. + */ class KX_ArrayOptimizer { public: @@ -63,6 +67,9 @@ public: int m_index1; }; +/** + * This struct holds a triangle. + */ struct RAS_TriangleIndex { public: @@ -72,6 +79,11 @@ public: bool m_collider; }; +/** + * This class looks horribly broken. Only m_matid is used, and + * m_matid is a (int) RAS_IPolyMaterial*. + * --> m_matid == lhs.m_matid should be *m_matid == *lhs.m_matid + */ class RAS_MatArrayIndex { public: @@ -124,9 +136,8 @@ class RAS_MeshObject protected: GEN_Map m_matVertexArrayS; - typedef set BucketMaterialSet; - BucketMaterialSet m_materials; + RAS_MaterialBucket::Set m_materials; public: // for now, meshes need to be in a certain layer (to avoid sorting on lights in realtime) RAS_MeshObject(int lightlayer); @@ -178,8 +189,8 @@ public: void ClearArrayData(); - BucketMaterialSet::iterator GetFirstMaterial(); - BucketMaterialSet::iterator GetLastMaterial(); + RAS_MaterialBucket::Set::iterator GetFirstMaterial(); + RAS_MaterialBucket::Set::iterator GetLastMaterial(); virtual RAS_TexVert* GetVertex( short array,