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:
Diffstat (limited to 'source/gameengine/Rasterizer/RAS_MeshObject.cpp')
-rw-r--r--source/gameengine/Rasterizer/RAS_MeshObject.cpp635
1 files changed, 635 insertions, 0 deletions
diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp
new file mode 100644
index 00000000000..3c78b7cf991
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp
@@ -0,0 +1,635 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "RAS_MeshObject.h"
+
+#include "RAS_IRasterizer.h"
+#include "MT_MinMax.h"
+
+STR_String RAS_MeshObject::s_emptyname = "";
+
+
+
+KX_ArrayOptimizer::~KX_ArrayOptimizer()
+{
+ int i = 0;
+
+ for (vector<KX_VertexArray*>::iterator itv = m_VertexArrayCache1.begin();
+ !(itv == m_VertexArrayCache1.end());itv++)
+ {
+ delete (*itv);
+ }
+
+ for (vector<KX_IndexArray*>::iterator iti = m_IndexArrayCache1.begin();
+ !(iti == m_IndexArrayCache1.end());iti++)
+ {
+ delete (*iti);
+ }
+
+ m_TriangleArrayCount.clear();
+ m_VertexArrayCache1.clear();
+ m_IndexArrayCache1.clear();
+
+
+}
+
+
+
+RAS_MeshObject::RAS_MeshObject(int lightlayer)
+ : m_bModified(true),
+ m_lightlayer(lightlayer)
+{
+}
+
+
+
+RAS_MeshObject::~RAS_MeshObject()
+{
+ for (vector<RAS_Polygon*>::iterator it=m_Polygons.begin();!(it==m_Polygons.end());it++)
+ {
+ delete (*it);
+ }
+
+ ClearArrayData();
+}
+
+
+
+int RAS_MeshObject::GetLightLayer()
+{
+ return m_lightlayer;
+}
+
+
+
+int RAS_MeshObject::NumMaterials()
+{
+ return m_materials.size();
+}
+
+
+
+const STR_String& RAS_MeshObject::GetMaterialName(int matid)
+{
+ if (m_materials.size() > 0 && (matid < m_materials.size()))
+ {
+ BucketMaterialSet::iterator it = m_materials.begin();
+
+ for (int i = 1; i < m_materials.size(); i++)
+ {
+ it++;
+ }
+ return (*it)->GetPolyMaterial()->GetMaterialName();
+ }
+
+ return s_emptyname;
+}
+
+
+
+RAS_MaterialBucket* RAS_MeshObject::GetMaterialBucket(int matid)
+{
+ RAS_MaterialBucket* bucket = NULL;
+
+ if (m_materials.size() > 0 && (matid < m_materials.size()))
+ {
+ BucketMaterialSet::iterator it = m_materials.begin();
+ int i = matid;
+ while (i > 0)
+ {
+ i--;
+ it++;
+ }
+ bucket = *it;
+ }
+
+ return bucket;
+}
+
+
+
+int RAS_MeshObject::NumPolygons()
+{
+ return m_Polygons.size();
+}
+
+
+
+RAS_Polygon* RAS_MeshObject::GetPolygon(int num)
+{
+ return m_Polygons[num];
+}
+
+
+
+set<RAS_MaterialBucket*>::iterator RAS_MeshObject::GetFirstMaterial()
+{
+ return m_materials.begin();
+}
+
+
+
+set<RAS_MaterialBucket*>::iterator RAS_MeshObject::GetLastMaterial()
+{
+ return m_materials.end();
+}
+
+
+
+void RAS_MeshObject::SetName(STR_String name)
+{
+ m_name = name;
+}
+
+
+
+const STR_String& RAS_MeshObject::GetName()
+{
+ return m_name;
+}
+
+
+
+const STR_String& RAS_MeshObject::GetTextureName(int matid)
+{
+ if (m_materials.size() > 0 && (matid < m_materials.size()))
+ {
+ BucketMaterialSet::iterator it = m_materials.begin();
+ for (int i = 1; i < m_materials.size(); i++)
+ {
+ it++;
+ }
+
+ return (*it)->GetPolyMaterial()->GetTextureName();
+ }
+
+ return s_emptyname;
+}
+
+
+
+void RAS_MeshObject::AddPolygon(RAS_Polygon* poly)
+{
+ m_Polygons.push_back(poly);
+}
+
+
+
+void RAS_MeshObject::DebugColor(unsigned int abgr)
+{
+/*
+ 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);
+ }
+ }
+ */
+
+ m_debugcolor = abgr;
+}
+
+
+
+void RAS_MeshObject::SchedulePoly(const KX_VertexIndex& idx,
+ int numverts,
+ RAS_IPolyMaterial* mat)
+{
+ //int indexpos = m_IndexArrayCount[idx.m_vtxarray];
+ int indexidx = 0;
+ //m_IndexArrayCount[idx.m_vtxarray] = indexpos + 3;
+
+ 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()) //if (!m_bUseTriangles)
+ {
+ //m_IndexArrayCount[idx.m_vtxarray] = indexpos+4;
+ ao->m_IndexArrayCache1[idx.m_vtxarray]->push_back(idx.m_indexarray[3]);
+ }
+}
+
+
+
+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)
+ {
+ ao->m_IndexArrayCache1[idx.m_vtxarray]->push_back(prevvert);
+ ao->m_IndexArrayCache1[idx.m_vtxarray]->push_back(curvert);
+ }
+ 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 unsigned int rgbacolor,
+ const MT_Vector3& normal,
+ RAS_IPolyMaterial* mat,
+ int orgindex)
+{
+ short newnormal[3];
+
+ newnormal[0]=(short)((normal[0])*32767.0);
+ newnormal[1]=(short)((normal[1])*32767.0);
+ newnormal[2]=(short)((normal[2])*32767.0);
+
+ KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]);
+
+ int numverts = ao->m_VertexArrayCache1[vtxarray]->size();//m_VertexArrayCount[vtxarray];
+
+#define KX_FIND_SHARED_VERTICES
+#ifdef KX_FIND_SHARED_VERTICES
+
+ std::vector<RAS_MatArrayIndex>::iterator it = m_xyz_index_to_vertex_index_mapping[orgindex].begin();
+ int index=-1;
+ while (index < 0 && !(it == m_xyz_index_to_vertex_index_mapping[orgindex].end()))
+ {
+ if ((*it).m_arrayindex1 == ao->m_index1 &&
+ ((*it).m_array == vtxarray) &&
+ (RAS_IPolyMaterial*) (*it).m_matid == mat
+ )
+ {
+ return (*it).m_index;
+ }
+ it++;
+ }
+
+ if (index >= 0)
+ return index;
+#endif // KX_FIND_SHARED_VERTICES
+
+ // no vertex found, add one
+ ao->m_VertexArrayCache1[vtxarray]->push_back(RAS_TexVert (xyz,uv,rgbacolor,newnormal, 0));
+ // 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 = (int) mat;
+ m_xyz_index_to_vertex_index_mapping[orgindex].push_back(idx);
+
+ return numverts;
+}
+
+
+
+const vecVertexArray& RAS_MeshObject::GetVertexCache (RAS_IPolyMaterial* mat)
+{
+ KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]);
+
+ return ao->m_VertexArrayCache1;
+}
+
+
+
+int RAS_MeshObject::GetVertexArrayLength(RAS_IPolyMaterial* mat)
+{
+ int len = 0;
+
+ const vecVertexArray & vertexvec = GetVertexCache(mat);
+ vector<KX_VertexArray*>::const_iterator it = vertexvec.begin();
+
+ for (; it != vertexvec.end(); it++)
+ {
+ len += (*it)->size();
+ }
+
+ return len;
+}
+
+
+
+RAS_TexVert* RAS_MeshObject::GetVertex(int matid,
+ 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 (int len = 0; it != vertexvec.end(); it++)
+ {
+ if (index < len + (*it)->size())
+ {
+ vertex = &(*(*it))[index-len];
+ break;
+ }
+ else
+ {
+ len += (*it)->size();
+ }
+ }
+ }
+ }
+
+ return vertex;
+}
+
+
+
+const vecIndexArrays& RAS_MeshObject::GetIndexCache (RAS_IPolyMaterial* mat)
+{
+ KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]);
+
+ return ao->m_IndexArrayCache1;
+}
+
+
+
+KX_ArrayOptimizer* RAS_MeshObject::GetArrayOptimizer(RAS_IPolyMaterial* polymat)
+{
+ KX_ArrayOptimizer** aop = (m_matVertexArrayS[*polymat]);
+
+ if (aop)
+ return *aop;
+
+ int numelements = m_matVertexArrayS.size();
+ m_sortedMaterials.push_back(polymat);
+
+ KX_ArrayOptimizer* ao = new KX_ArrayOptimizer(numelements);
+ m_matVertexArrayS.insert(*polymat,ao);
+
+ return ao;
+}
+
+
+
+void RAS_MeshObject::Bucketize(double* oglmatrix,
+ void* clientobj,
+ bool useObjectColor,
+ const MT_Vector4& rgbavec)
+{
+ KX_MeshSlot ms;
+ ms.m_clientObj = clientobj;
+ ms.m_mesh = this;
+ ms.m_OpenGLMatrix = oglmatrix;
+ ms.m_bObjectColor = useObjectColor;
+ ms.m_RGBAcolor = rgbavec;
+
+ int i=0;
+ for (BucketMaterialSet::iterator it = m_materials.begin();it!=m_materials.end();it++)
+ {
+ RAS_MaterialBucket* bucket = *it;
+ bucket->SchedulePolygons(0);
+ KX_ArrayOptimizer* oa = GetArrayOptimizer(bucket->GetPolyMaterial());
+ bucket->SetMeshSlot(ms);
+ }
+
+}
+
+
+
+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 (BucketMaterialSet::iterator it = m_materials.begin();it!=m_materials.end();it++)
+ {
+ RAS_MaterialBucket* bucket = *it;
+ bucket->SchedulePolygons(0);
+ KX_ArrayOptimizer* oa = GetArrayOptimizer(bucket->GetPolyMaterial());
+ bucket->MarkVisibleMeshSlot(ms,visible,useObjectColor,rgbavec);
+ }
+}
+
+
+
+void RAS_MeshObject::RemoveFromBuckets(double* oglmatrix,
+ void* clientobj)
+{
+ KX_MeshSlot ms;
+ ms.m_clientObj = clientobj;
+ ms.m_mesh = this;
+ ms.m_OpenGLMatrix = oglmatrix;
+
+ for (BucketMaterialSet::iterator it = m_materials.begin();it!=m_materials.end();it++)
+ {
+ RAS_MaterialBucket* bucket = *it;
+ RAS_IPolyMaterial* polymat = bucket->GetPolyMaterial();
+ bucket->SchedulePolygons(0);
+ //KX_ArrayOptimizer* oa = GetArrayOptimizer(polymat);
+ bucket->RemoveMeshSlot(ms);
+ }
+
+}
+
+
+
+/*
+ * 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,
+ short index,
+ RAS_IPolyMaterial* polymat)
+{
+ KX_ArrayOptimizer* ao = GetArrayOptimizer(polymat);//*(m_matVertexArrays[*polymat]);
+ return &((*(ao->m_VertexArrayCache1)[array])[index]);
+}
+
+
+
+void RAS_MeshObject::ClearArrayData()
+{
+ for (int i=0;i<m_matVertexArrayS.size();i++)
+ { KX_ArrayOptimizer** ao = m_matVertexArrayS.at(i);
+ if (ao)
+ delete *ao;
+ }
+}
+
+
+
+/**
+ * RAS_MeshObject::CreateNewVertices creates vertices within sorted pools of vertices that share same material
+*/
+int RAS_MeshObject::FindVertexArray(int numverts,
+ RAS_IPolyMaterial* polymat)
+{
+ bool found=false;
+ int array=-1;
+
+ KX_ArrayOptimizer* ao = GetArrayOptimizer(polymat);
+
+ for (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;
+ }
+ }
+ else
+ {
+ int i=0;
+ }
+ }
+
+ 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);
+ }
+
+ return array;
+}
+
+
+
+
+//void RAS_MeshObject::Transform(const MT_Transform& trans)
+//{
+ //m_trans.translate(MT_Vector3(0,0,1));//.operator *=(trans);
+
+// for (int i=0;i<m_Polygons.size();i++)
+// {
+// m_Polygons[i]->Transform(trans);
+// }
+//}
+
+
+/*
+void RAS_MeshObject::RelativeTransform(const MT_Vector3& vec)
+{
+ for (int i=0;i<m_Polygons.size();i++)
+ {
+ m_Polygons[i]->RelativeTransform(vec);
+ }
+}
+*/
+
+
+
+void RAS_MeshObject::UpdateMaterialList()
+{
+ m_materials.clear();
+ int numpolys = m_Polygons.size();
+ // for all polygons, find out which material they use, and add it to the set of materials
+ for (int i=0;i<numpolys;i++)
+ {
+ m_materials.insert(m_Polygons[i]->GetMaterial());
+ }
+ int nummaterials = m_materials.size();
+
+}
+
+
+
+void RAS_MeshObject::SchedulePolygons(int drawingmode,RAS_IRasterizer* rasty)
+{
+ int nummaterials = m_materials.size();
+ int i;
+
+ if (m_bModified)
+ {
+ for (BucketMaterialSet::iterator it = m_materials.begin();it!=m_materials.end();it++)
+ {
+ RAS_MaterialBucket* bucket = *it;
+
+ bucket->SchedulePolygons(drawingmode);
+ }
+
+ int numpolys = m_Polygons.size();
+
+ if ((rasty->GetDrawingMode() > RAS_IRasterizer::KX_BOUNDINGBOX) &&
+ (rasty->GetDrawingMode() < RAS_IRasterizer::KX_SOLID))
+ {
+ 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());
+
+ }
+ }
+ 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;
+ }
+ // }
+}