Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2008-09-05 00:51:28 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2008-09-05 00:51:28 +0400
commitcb89decfdcf5e6b2f26376d416633f4ccf0c532d (patch)
treea299a5c8729dd0cb4359d57501fd9e6970141e5d /source/gameengine/Rasterizer/RAS_MeshObject.cpp
parent2167e5c341f656b2f664b1052d181e8aa32fe698 (diff)
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with scons, make, but not cmake, that seems to have an issue not related to these changes. The changes include: * GLSL support in the viewport and game engine, enable in the game menu in textured draw mode. * Synced and merged part of the duplicated blender and gameengine/ gameplayer drawing code. * Further refactoring of game engine drawing code, especially mesh storage changed a lot. * Optimizations in game engine armatures to avoid recomputations. * A python function to get the framerate estimate in game. * An option take object color into account in materials. * An option to restrict shadow casters to a lamp's layers. * Increase from 10 to 18 texture slots for materials, lamps, word. An extra texture slot shows up once the last slot is used. * Memory limit for undo, not enabled by default yet because it needs the .B.blend to be changed. * Multiple undo for image painting. * An offset for dupligroups, so not all objects in a group have to be at the origin.
Diffstat (limited to 'source/gameengine/Rasterizer/RAS_MeshObject.cpp')
-rw-r--r--source/gameengine/Rasterizer/RAS_MeshObject.cpp723
1 files changed, 253 insertions, 470 deletions
diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp
index a4f7f3f01dd..a907994bf57 100644
--- a/source/gameengine/Rasterizer/RAS_MeshObject.cpp
+++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp
@@ -26,10 +26,6 @@
* ***** END GPL LICENSE BLOCK *****
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
#include "RAS_MeshObject.h"
#include "RAS_IRasterizer.h"
#include "MT_MinMax.h"
@@ -37,62 +33,84 @@
#include <algorithm>
+/* polygon sorting */
-STR_String RAS_MeshObject::s_emptyname = "";
+struct RAS_MeshObject::polygonSlot
+{
+ float m_z;
+ int m_index[4];
+
+ polygonSlot() {}
+ /* pnorm is the normal from the plane equation that the distance from is
+ * used to sort again. */
+ void get(const RAS_TexVert *vertexarray, const unsigned short *indexarray,
+ int offset, int nvert, const MT_Vector3& pnorm)
+ {
+ MT_Vector3 center(0, 0, 0);
+ int i;
+ for(i=0; i<nvert; i++) {
+ m_index[i] = indexarray[offset+i];
+ center += vertexarray[m_index[i]].getXYZ();
+ }
-KX_ArrayOptimizer::~KX_ArrayOptimizer()
-{
- for (vector<KX_VertexArray*>::iterator itv = m_VertexArrayCache1.begin();
- !(itv == m_VertexArrayCache1.end());++itv)
- {
- delete (*itv);
+ /* note we don't divide center by the number of vertices, since all
+ * polygons have the same number of vertices, and that we leave out
+ * the 4-th component of the plane equation since it is constant. */
+ m_z = MT_dot(pnorm, center);
}
- for (vector<KX_IndexArray*>::iterator iti = m_IndexArrayCache1.begin();
- !(iti == m_IndexArrayCache1.end());++iti)
+ void set(unsigned short *indexarray, int offset, int nvert)
{
- delete (*iti);
+ int i;
+
+ for(i=0; i<nvert; i++)
+ indexarray[offset+i] = m_index[i];
}
+};
- m_TriangleArrayCount.clear();
- m_VertexArrayCache1.clear();
- m_IndexArrayCache1.clear();
-
+struct RAS_MeshObject::backtofront
+{
+ bool operator()(const polygonSlot &a, const polygonSlot &b) const
+ {
+ return a.m_z < b.m_z;
+ }
+};
-}
+struct RAS_MeshObject::fronttoback
+{
+ bool operator()(const polygonSlot &a, const polygonSlot &b) const
+ {
+ return a.m_z > b.m_z;
+ }
+};
+/* mesh object */
+STR_String RAS_MeshObject::s_emptyname = "";
RAS_MeshObject::RAS_MeshObject(Mesh* mesh, int lightlayer)
- : m_bModified(true),
- m_lightlayer(lightlayer),
- m_zsort(false),
- m_MeshMod(true),
+ : m_lightlayer(lightlayer),
+ m_bModified(true),
+ m_bMeshModified(true),
m_mesh(mesh),
- m_class(0)
+ m_bDeformed(false)
{
}
-
-bool RAS_MeshObject::MeshModified()
-{
- return m_MeshMod;
-}
-
-
RAS_MeshObject::~RAS_MeshObject()
{
- for (vector<RAS_Polygon*>::iterator it=m_Polygons.begin();!(it==m_Polygons.end());it++)
- {
- delete (*it);
- }
+ vector<RAS_Polygon*>::iterator it;
- ClearArrayData();
+ for(it=m_Polygons.begin(); it!=m_Polygons.end(); it++)
+ delete (*it);
}
-
+bool RAS_MeshObject::MeshModified()
+{
+ return m_bMeshModified;
+}
unsigned int RAS_MeshObject::GetLightLayer()
{
@@ -108,18 +126,21 @@ int RAS_MeshObject::NumMaterials()
const STR_String& RAS_MeshObject::GetMaterialName(unsigned int matid)
{
- RAS_MaterialBucket* bucket = GetMaterialBucket(matid);
+ RAS_MeshMaterial* mmat = GetMeshMaterial(matid);
+
+ if(mmat)
+ return mmat->m_bucket->GetPolyMaterial()->GetMaterialName();
- return bucket?bucket->GetPolyMaterial()->GetMaterialName():s_emptyname;
+ return s_emptyname;
}
-RAS_MaterialBucket* RAS_MeshObject::GetMaterialBucket(unsigned int matid)
+RAS_MeshMaterial* RAS_MeshObject::GetMeshMaterial(unsigned int matid)
{
if (m_materials.size() > 0 && (matid < m_materials.size()))
{
- RAS_MaterialBucket::Set::const_iterator it = m_materials.begin();
+ list<RAS_MeshMaterial>::iterator it = m_materials.begin();
while (matid--) ++it;
- return *it;
+ return &*it;
}
return NULL;
@@ -141,14 +162,17 @@ RAS_Polygon* RAS_MeshObject::GetPolygon(int num) const
-RAS_MaterialBucket::Set::iterator RAS_MeshObject::GetFirstMaterial()
+
+ list<RAS_MeshMaterial>::iterator GetFirstMaterial();
+ list<RAS_MeshMaterial>::iterator GetLastMaterial();
+list<RAS_MeshMaterial>::iterator RAS_MeshObject::GetFirstMaterial()
{
return m_materials.begin();
}
-RAS_MaterialBucket::Set::iterator RAS_MeshObject::GetLastMaterial()
+list<RAS_MeshMaterial>::iterator RAS_MeshObject::GetLastMaterial()
{
return m_materials.end();
}
@@ -171,377 +195,238 @@ const STR_String& RAS_MeshObject::GetName()
const STR_String& RAS_MeshObject::GetTextureName(unsigned int matid)
{
- RAS_MaterialBucket* bucket = GetMaterialBucket(matid);
+ RAS_MeshMaterial* mmat = GetMeshMaterial(matid);
- return bucket?bucket->GetPolyMaterial()->GetTextureName():s_emptyname;
+ if(mmat)
+ return mmat->m_bucket->GetPolyMaterial()->GetTextureName();
+
+ return s_emptyname;
}
+RAS_MeshMaterial *RAS_MeshObject::GetMeshMaterial(RAS_IPolyMaterial *mat)
+{
+ list<RAS_MeshMaterial>::iterator mit;
+ /* find a mesh material */
+ for(mit = m_materials.begin(); mit != m_materials.end(); mit++)
+ if(mit->m_bucket->GetPolyMaterial() == mat)
+ return &*mit;
-void RAS_MeshObject::AddPolygon(RAS_Polygon* poly)
-{
- m_Polygons.push_back(poly);
+ return NULL;
}
+RAS_Polygon* RAS_MeshObject::AddPolygon(RAS_MaterialBucket *bucket, int numverts)
+{
+ RAS_MeshMaterial *mmat;
+ RAS_Polygon *poly;
+ RAS_MeshSlot *slot;
+ /* find a mesh material */
+ mmat = GetMeshMaterial(bucket->GetPolyMaterial());
+
+ /* none found, create a new one */
+ if(!mmat) {
+ RAS_MeshMaterial meshmat;
+ meshmat.m_bucket = bucket;
+ meshmat.m_baseslot = meshmat.m_bucket->AddMesh(numverts);
+ m_materials.push_back(meshmat);
+ mmat = &m_materials.back();
+ }
+
+ /* add it to the bucket, this also adds new display arrays */
+ slot = mmat->m_baseslot;
+ slot->AddPolygon(numverts);
+
+ /* create a new polygon */
+ RAS_DisplayArray *darray = slot->CurrentDisplayArray();
+ poly = new RAS_Polygon(bucket, darray, numverts);
+ m_Polygons.push_back(poly);
+
+ return poly;
+}
void RAS_MeshObject::DebugColor(unsigned int abgr)
{
-/*
- int numpolys = NumPolygons();
- for (int i=0;i<numpolys;i++)
- {
+ /*int numpolys = NumPolygons();
+
+ for (int i=0;i<numpolys;i++) {
RAS_Polygon* poly = m_polygons[i];
for (int v=0;v<poly->VertexCount();v++)
- {
- RAS_TexVert* vtx = poly->GetVertex(v);
- vtx->setDebugRGBA(abgr);
- }
+ RAS_TexVert* vtx = poly->GetVertex(v)->setDebugRGBA(abgr);
}
*/
- m_debugcolor = abgr;
+ /* m_debugcolor = abgr; */
}
void RAS_MeshObject::SetVertexColor(RAS_IPolyMaterial* mat,MT_Vector4 rgba)
{
- const vecVertexArray & vertexvec = GetVertexCache(mat);
-
- for (vector<KX_VertexArray*>::const_iterator it = vertexvec.begin(); it != vertexvec.end(); ++it)
- {
- KX_VertexArray::iterator vit;
- for (vit=(*it)->begin(); vit != (*it)->end(); vit++)
- {
- vit->SetRGBA(rgba);
- }
- }
-}
-
-void RAS_MeshObject::SchedulePoly(const KX_VertexIndex& idx,
- int numverts,
- RAS_IPolyMaterial* mat)
-{
- KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);
-
- ao->m_IndexArrayCache1[idx.m_vtxarray]->push_back(idx.m_indexarray[0]);
- ao->m_IndexArrayCache1[idx.m_vtxarray]->push_back(idx.m_indexarray[1]);
- ao->m_IndexArrayCache1[idx.m_vtxarray]->push_back(idx.m_indexarray[2]);
-
- if (!mat->UsesTriangles())
- ao->m_IndexArrayCache1[idx.m_vtxarray]->push_back(idx.m_indexarray[3]);
-}
+ RAS_MeshMaterial *mmat = GetMeshMaterial(mat);
+ RAS_MeshSlot *slot = mmat->m_baseslot;
+ RAS_MeshSlot::iterator it;
+ size_t i;
+
+ for(slot->begin(it); !slot->end(it); slot->next(it))
+ for(i=it.startvertex; i<it.endvertex; i++)
+ it.vertex[i].SetRGBA(rgba);
+}
+
+void RAS_MeshObject::AddVertex(RAS_Polygon *poly, int i,
+ const MT_Point3& xyz,
+ const MT_Point2& uv,
+ const MT_Point2& uv2,
+ const MT_Vector4& tangent,
+ const unsigned int rgba,
+ const MT_Vector3& normal,
+ bool flat,
+ int origindex)
+{
+ RAS_TexVert texvert(xyz, uv, uv2, tangent, rgba, normal, flat, origindex);
+ RAS_MeshMaterial *mmat;
+ RAS_DisplayArray *darray;
+ RAS_MeshSlot *slot;
+ int offset;
+
+ mmat = GetMeshMaterial(poly->GetMaterial()->GetPolyMaterial());
+ slot = mmat->m_baseslot;
+ darray = slot->CurrentDisplayArray();
+ if(!flat) {
+ /* find vertices shared between faces, with the restriction
+ * that they exist in the same display array, and have the
+ * same uv coordinate etc */
+ vector<SharedVertex>& sharedmap = m_sharedvertex_map[origindex];
+ vector<SharedVertex>::iterator it;
-void RAS_MeshObject::ScheduleWireframePoly(const KX_VertexIndex& idx,
- int numverts,
- int edgecode,
- RAS_IPolyMaterial* mat)
-{
- //int indexpos = m_IndexArrayCount[idx.m_vtxarray];
- int edgetrace = 1<<(numverts-1);
- bool drawedge = (edgecode & edgetrace)!=0;
- edgetrace = 1;
- int prevvert = idx.m_indexarray[numverts-1];
- KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);
-
- for (int v = 0; v < numverts; v++)
- {
- unsigned int curvert = idx.m_indexarray[v];
- if (drawedge)
+ for(it = sharedmap.begin(); it != sharedmap.end(); it++)
{
- ao->m_IndexArrayCache1[idx.m_vtxarray]->push_back(prevvert);
- ao->m_IndexArrayCache1[idx.m_vtxarray]->push_back(curvert);
+ if(it->m_darray != darray)
+ continue;
+ if(!it->m_darray->m_vertex[it->m_offset].closeTo(&texvert))
+ continue;
+
+ /* found one, add it and we're done */
+ if(poly->IsVisible())
+ slot->AddPolygonVertex(it->m_offset);
+ poly->SetVertexOffset(i, it->m_offset);
+ return;
}
- prevvert = curvert;
- drawedge = (edgecode & edgetrace)!=0;
- edgetrace*=2;
}
- //m_IndexArrayCount[idx.m_vtxarray] = indexpos;
-}
-int RAS_MeshObject::FindOrAddVertex(int vtxarray,
- const MT_Point3& xyz,
- const MT_Point2& uv,
- const MT_Point2& uv2,
- const MT_Vector4& tangent,
- const unsigned int rgbacolor,
- const MT_Vector3& normal,
- bool flat,
- RAS_IPolyMaterial* mat,
- int origindex)
-{
- KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);
-
- int numverts = ao->m_VertexArrayCache1[vtxarray]->size();//m_VertexArrayCount[vtxarray];
- RAS_TexVert newvert(xyz,uv,uv2,tangent,rgbacolor,normal, flat? TV_CALCFACENORMAL: 0,origindex);
+ /* no shared vertex found, add a new one */
+ offset = slot->AddVertex(texvert);
+ if(poly->IsVisible())
+ slot->AddPolygonVertex(offset);
+ poly->SetVertexOffset(i, offset);
-#define KX_FIND_SHARED_VERTICES
-#ifdef KX_FIND_SHARED_VERTICES
if(!flat) {
- for (std::vector<RAS_MatArrayIndex>::iterator it = m_xyz_index_to_vertex_index_mapping[origindex].begin();
- it != m_xyz_index_to_vertex_index_mapping[origindex].end();
- it++)
- {
- if ((*it).m_arrayindex1 == ao->m_index1 &&
- (*it).m_array == vtxarray &&
- *(*it).m_matid == *mat &&
- (*ao->m_VertexArrayCache1[vtxarray])[(*it).m_index].closeTo(&newvert)
- )
- {
- return (*it).m_index;
- }
- }
+ SharedVertex shared;
+ shared.m_darray = darray;
+ shared.m_offset = offset;
+ m_sharedvertex_map[origindex].push_back(shared);
}
-#endif // KX_FIND_SHARED_VERTICES
-
- // no vertex found, add one
- ao->m_VertexArrayCache1[vtxarray]->push_back(newvert);
- // printf("(%f,%f,%f) ",xyz[0],xyz[1],xyz[2]);
- RAS_MatArrayIndex idx;
- idx.m_arrayindex1 = ao->m_index1;
- idx.m_array = vtxarray;
- idx.m_index = numverts;
- idx.m_matid = mat;
- m_xyz_index_to_vertex_index_mapping[origindex].push_back(idx);
-
- return numverts;
}
-vecVertexArray& RAS_MeshObject::GetVertexCache (RAS_IPolyMaterial* mat)
+int RAS_MeshObject::NumVertices(RAS_IPolyMaterial* mat)
{
- KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);
-
- return ao->m_VertexArrayCache1;
-}
+ RAS_MeshMaterial *mmat;
+ RAS_MeshSlot *slot;
+ RAS_MeshSlot::iterator it;
+ size_t len = 0;
-int RAS_MeshObject::GetVertexArrayLength(RAS_IPolyMaterial* mat)
-{
- int len = 0;
-
- const vecVertexArray & vertexvec = GetVertexCache(mat);
- vector<KX_VertexArray*>::const_iterator it = vertexvec.begin();
+ mmat = GetMeshMaterial(mat);
+ slot = mmat->m_baseslot;
+ for(slot->begin(it); !slot->end(it); slot->next(it))
+ len += it.endvertex - it.startvertex;
- for (; it != vertexvec.end(); ++it)
- {
- len += (*it)->size();
- }
-
return len;
}
-
RAS_TexVert* RAS_MeshObject::GetVertex(unsigned int matid,
unsigned int index)
{
- RAS_TexVert* vertex = NULL;
-
- RAS_MaterialBucket* bucket = GetMaterialBucket(matid);
- if (bucket)
- {
- RAS_IPolyMaterial* mat = bucket->GetPolyMaterial();
- if (mat)
- {
- const vecVertexArray & vertexvec = GetVertexCache(mat);
- vector<KX_VertexArray*>::const_iterator it = vertexvec.begin();
-
- for (unsigned int len = 0; it != vertexvec.end(); ++it)
- {
- if (index < len + (*it)->size())
- {
- vertex = &(*(*it))[index-len];
- break;
- }
- else
- {
- len += (*it)->size();
- }
- }
- }
- }
-
- return vertex;
-}
-
-
+ RAS_MeshMaterial *mmat;
+ RAS_MeshSlot *slot;
+ RAS_MeshSlot::iterator it;
+ size_t len;
-const vecIndexArrays& RAS_MeshObject::GetIndexCache (RAS_IPolyMaterial* mat)
-{
- KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);
-
- return ao->m_IndexArrayCache1;
-}
+ mmat = GetMeshMaterial(matid);
-
-
-KX_ArrayOptimizer* RAS_MeshObject::GetArrayOptimizer(RAS_IPolyMaterial* polymat)
-{
- KX_ArrayOptimizer** aop = m_matVertexArrayS[polymat];
-
- if(aop)
- return *aop;
+ if(!mmat)
+ return NULL;
- // didn't find array, but an array might already exist
- // for a material equal to this one
- for(int i=0;i<m_matVertexArrayS.size();i++) {
- RAS_IPolyMaterial *mat = (RAS_IPolyMaterial*)(m_matVertexArrayS.getKey(i)->getValue());
- if(*mat == *polymat) {
- m_matVertexArrayS.insert(polymat, *m_matVertexArrayS.at(i));
- return *m_matVertexArrayS.at(i);
- }
+ slot = mmat->m_baseslot;
+ len = 0;
+ for(slot->begin(it); !slot->end(it); slot->next(it)) {
+ if(index >= len + it.endvertex - it.startvertex)
+ len += it.endvertex - it.startvertex;
+ else
+ return &it.vertex[index - len];
}
-
- // create new array
- int numelements = m_matVertexArrayS.size();
- m_sortedMaterials.push_back(polymat);
-
- KX_ArrayOptimizer* ao = new KX_ArrayOptimizer(numelements);
- m_matVertexArrayS.insert(polymat, ao);
- return ao;
+ return NULL;
}
-
-
-void RAS_MeshObject::Bucketize(double* oglmatrix,
- void* clientobj,
- bool useObjectColor,
- const MT_Vector4& rgbavec)
+void RAS_MeshObject::AddMeshUser(void *clientobj)
{
- KX_MeshSlot ms;
- ms.m_clientObj = clientobj;
- ms.m_mesh = this;
- ms.m_OpenGLMatrix = oglmatrix;
- ms.m_bObjectColor = useObjectColor;
- ms.m_RGBAcolor = rgbavec;
-
- for (RAS_MaterialBucket::Set::iterator it = m_materials.begin();it!=m_materials.end();++it)
- {
- RAS_MaterialBucket* bucket = *it;
-// KX_ArrayOptimizer* oa = GetArrayOptimizer(bucket->GetPolyMaterial());
- bucket->SetMeshSlot(ms);
- }
+ list<RAS_MeshMaterial>::iterator it;
-}
-
-
-
-void RAS_MeshObject::MarkVisible(double* oglmatrix,
- void* clientobj,
- bool visible,
- bool useObjectColor,
- const MT_Vector4& rgbavec)
-{
- KX_MeshSlot ms;
- ms.m_clientObj = clientobj;
- ms.m_mesh = this;
- ms.m_OpenGLMatrix = oglmatrix;
- ms.m_RGBAcolor = rgbavec;
- ms.m_bObjectColor= useObjectColor;
-
- for (RAS_MaterialBucket::Set::iterator it = m_materials.begin();it!=m_materials.end();++it)
- {
- RAS_MaterialBucket* bucket = *it;
-// KX_ArrayOptimizer* oa = GetArrayOptimizer(bucket->GetPolyMaterial());
- bucket->MarkVisibleMeshSlot(ms,visible,useObjectColor,rgbavec);
+ for(it = m_materials.begin();it!=m_materials.end();++it) {
+ /* always copy from the base slot, which is never removed
+ * since new objects can be created with the same mesh data */
+ RAS_MeshSlot *ms = it->m_bucket->CopyMesh(it->m_baseslot);
+ ms->m_clientObj = clientobj;
+ it->m_slots.insert(clientobj, ms);
}
}
-
-void RAS_MeshObject::RemoveFromBuckets(double* oglmatrix,
- void* clientobj)
+void RAS_MeshObject::UpdateBuckets(void* clientobj,
+ double* oglmatrix,
+ bool useObjectColor,
+ const MT_Vector4& rgbavec,
+ bool visible,
+ bool culled)
{
- KX_MeshSlot ms;
- ms.m_clientObj = clientobj;
- ms.m_mesh = this;
- ms.m_OpenGLMatrix = oglmatrix;
-
- for (RAS_MaterialBucket::Set::iterator it = m_materials.begin();it!=m_materials.end();++it)
- {
- RAS_MaterialBucket* bucket = *it;
-// RAS_IPolyMaterial* polymat = bucket->GetPolyMaterial();
- //KX_ArrayOptimizer* oa = GetArrayOptimizer(polymat);
- bucket->RemoveMeshSlot(ms);
- }
-
-}
-
-
+ list<RAS_MeshMaterial>::iterator it;
-/*
- * RAS_MeshObject::GetVertex returns the vertex located somewhere in the vertexpool
- * it is the clients responsibility to make sure the array and index are valid
- */
-RAS_TexVert* RAS_MeshObject::GetVertex(short array,
- unsigned int index,
- RAS_IPolyMaterial* polymat)
-{
- KX_ArrayOptimizer* ao = GetArrayOptimizer(polymat);
- return &((*(ao->m_VertexArrayCache1)[array])[index]);
-}
+ for(it = m_materials.begin();it!=m_materials.end();++it) {
+ RAS_MeshSlot **msp = it->m_slots[clientobj];
+ if(!msp)
+ continue;
+ RAS_MeshSlot *ms = *msp;
-void RAS_MeshObject::ClearArrayData()
-{
- for (int i=0;i<m_matVertexArrayS.size();i++) {
- KX_ArrayOptimizer** ao = m_matVertexArrayS.at(i);
-
- // we have duplicate entries, only free once
- for(int j=i+1;j<m_matVertexArrayS.size();j++) {
- if(ao == m_matVertexArrayS.at(j)) {
- ao = NULL;
- break;
- }
- }
+ ms->m_mesh = this;
+ ms->m_OpenGLMatrix = oglmatrix;
+ ms->m_bObjectColor = useObjectColor;
+ ms->m_RGBAcolor = rgbavec;
+ ms->m_bVisible = visible;
+ ms->m_bCulled = culled || !visible;
- if (ao)
- delete *ao;
+ /* split if necessary */
+ ms->Split();
}
}
-
-
-/**
- * RAS_MeshObject::CreateNewVertices creates vertices within sorted pools of vertices that share same material
-*/
-int RAS_MeshObject::FindVertexArray(int numverts,
- RAS_IPolyMaterial* polymat)
+void RAS_MeshObject::RemoveFromBuckets(void *clientobj)
{
-// bool found=false;
- int array=-1;
+ list<RAS_MeshMaterial>::iterator it;
- KX_ArrayOptimizer* ao = GetArrayOptimizer(polymat);
+ for(it = m_materials.begin();it!=m_materials.end();++it) {
+ RAS_MeshSlot **msp = it->m_slots[clientobj];
- for (unsigned int i=0;i<ao->m_VertexArrayCache1.size();i++)
- {
- if ( (ao->m_TriangleArrayCount[i] + (numverts-2)) < BUCKET_MAX_TRIANGLES)
- {
- if((ao->m_VertexArrayCache1[i]->size()+numverts < BUCKET_MAX_INDICES))
- {
- array = i;
- ao->m_TriangleArrayCount[array]+=numverts-2;
- break;
- }
- }
- }
+ if(!msp)
+ continue;
- if (array == -1)
- {
- array = ao->m_VertexArrayCache1.size();
- vector<RAS_TexVert>* va = new vector<RAS_TexVert>;
- ao->m_VertexArrayCache1.push_back(va);
- KX_IndexArray *ia = new KX_IndexArray();
- ao->m_IndexArrayCache1.push_back(ia);
- ao->m_TriangleArrayCount.push_back(numverts-2);
- }
+ RAS_MeshSlot *ms = *msp;
- return array;
+ it->m_bucket->RemoveMesh(ms);
+ it->m_slots.remove(clientobj);
+ }
}
-
-
-
//void RAS_MeshObject::Transform(const MT_Transform& trans)
//{
//m_trans.translate(MT_Vector3(0,0,1));//.operator *=(trans);
@@ -563,71 +448,7 @@ void RAS_MeshObject::RelativeTransform(const MT_Vector3& vec)
}
*/
-
-
-void RAS_MeshObject::UpdateMaterialList()
-{
- m_materials.clear();
- unsigned int numpolys = m_Polygons.size();
- // for all polygons, find out which material they use, and add it to the set of materials
- for (unsigned int i=0;i<numpolys;i++)
- {
- m_materials.insert(m_Polygons[i]->GetMaterial());
- }
-}
-
-struct RAS_MeshObject::polygonSlot
-{
- float m_z;
- int m_index[4];
-
- polygonSlot() {}
-
- /* pnorm is the normal from the plane equation that the distance from is
- * used to sort again. */
- void get(const KX_VertexArray& vertexarray, const KX_IndexArray& indexarray,
- int offset, int nvert, const MT_Vector3& pnorm)
- {
- MT_Vector3 center(0, 0, 0);
- int i;
-
- for(i=0; i<nvert; i++) {
- m_index[i] = indexarray[offset+i];
- center += vertexarray[m_index[i]].getLocalXYZ();
- }
-
- /* note we don't divide center by the number of vertices, since all
- * polygons have the same number of vertices, and that we leave out
- * the 4-th component of the plane equation since it is constant. */
- m_z = MT_dot(pnorm, center);
- }
-
- void set(KX_IndexArray& indexarray, int offset, int nvert)
- {
- int i;
-
- for(i=0; i<nvert; i++)
- indexarray[offset+i] = m_index[i];
- }
-};
-
-struct RAS_MeshObject::backtofront
-{
- bool operator()(const polygonSlot &a, const polygonSlot &b) const
- {
- return a.m_z < b.m_z;
- }
-};
-
-struct RAS_MeshObject::fronttoback
-{
- bool operator()(const polygonSlot &a, const polygonSlot &b) const
- {
- return a.m_z > b.m_z;
- }
-};
-
-void RAS_MeshObject::SortPolygons(const MT_Transform &transform)
+void RAS_MeshObject::SortPolygons(RAS_MeshSlot& ms, const MT_Transform &transform)
{
// Limitations: sorting is quite simple, and handles many
// cases wrong, partially due to polygons being sorted per
@@ -645,43 +466,34 @@ void RAS_MeshObject::SortPolygons(const MT_Transform &transform)
// to avoid excessive state changes while drawing. e) would
// require splitting polygons.
- if (!m_zsort)
- return;
+ RAS_MeshSlot::iterator it;
+ size_t j;
- // Extract camera Z plane...
- const MT_Vector3 pnorm(transform.getBasis()[2]);
- // unneeded: const MT_Scalar pval = transform.getOrigin()[2];
+ for(ms.begin(it); !ms.end(it); ms.next(it)) {
+ unsigned int nvert = (int)it.array->m_type;
+ unsigned int totpoly = it.totindex/nvert;
- for (RAS_MaterialBucket::Set::iterator it = m_materials.begin();it!=m_materials.end();++it)
- {
- if(!(*it)->IsZSort())
+ if(totpoly <= 1)
+ continue;
+ if(it.array->m_type == RAS_DisplayArray::LINE)
continue;
- RAS_IPolyMaterial *mat = (*it)->GetPolyMaterial();
- KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);
-
- vecIndexArrays& indexarrays = ao->m_IndexArrayCache1;
- vecVertexArray& vertexarrays = ao->m_VertexArrayCache1;
- unsigned int i, j, nvert = (mat->UsesTriangles())? 3: 4;
-
- for(i=0; i<indexarrays.size(); i++) {
- KX_IndexArray& indexarray = *indexarrays[i];
- KX_VertexArray& vertexarray = *vertexarrays[i];
+ // Extract camera Z plane...
+ const MT_Vector3 pnorm(transform.getBasis()[2]);
+ // unneeded: const MT_Scalar pval = transform.getOrigin()[2];
- unsigned int totpoly = indexarray.size()/nvert;
- vector<polygonSlot> slots(totpoly);
+ vector<polygonSlot> slots(totpoly);
- /* get indices and z into temporary array */
- for(j=0; j<totpoly; j++)
- slots[j].get(vertexarray, indexarray, j*nvert, nvert, pnorm);
+ /* get indices and z into temporary array */
+ for(j=0; j<totpoly; j++)
+ slots[j].get(it.vertex, it.index, j*nvert, nvert, pnorm);
- /* sort (stable_sort might be better, if flickering happens?) */
- std::sort(slots.begin(), slots.end(), backtofront());
+ /* sort (stable_sort might be better, if flickering happens?) */
+ std::sort(slots.begin(), slots.end(), backtofront());
- /* get indices from temporary array again */
- for(j=0; j<totpoly; j++)
- slots[j].set(indexarray, j*nvert, nvert);
- }
+ /* get indices from temporary array again */
+ for(j=0; j<totpoly; j++)
+ slots[j].set(it.index, j*nvert, nvert);
}
}
@@ -690,37 +502,8 @@ void RAS_MeshObject::SchedulePolygons(int drawingmode)
{
if (m_bModified)
{
- int i, numpolys = m_Polygons.size();
-
- for (RAS_MaterialBucket::Set::iterator it = m_materials.begin();it!=m_materials.end();++it)
- if ((*it)->IsZSort())
- m_zsort = true;
-
- if (drawingmode == RAS_IRasterizer::KX_WIREFRAME)
- {
- for (i=0;i<numpolys;i++)
- {
- RAS_Polygon* poly = m_Polygons[i];
- if (poly->IsVisible())
- ScheduleWireframePoly(poly->GetVertexIndexBase(),poly->VertexCount(),poly->GetEdgeCode(),
- poly->GetMaterial()->GetPolyMaterial());
-
- }
- m_zsort = false;
- }
- else
- {
- for (i=0;i<numpolys;i++)
- {
- RAS_Polygon* poly = m_Polygons[i];
- if (poly->IsVisible())
- SchedulePoly(poly->GetVertexIndexBase(),poly->VertexCount(),
- poly->GetMaterial()->GetPolyMaterial());
- }
- }
-
m_bModified = false;
- m_MeshMod = true;
+ m_bMeshModified = true;
}
}