add 2 new utility functions to the BGE mesh py api.
[blender.git] / source / gameengine / Rasterizer / RAS_MaterialBucket.h
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file RAS_MaterialBucket.h
29  *  \ingroup bgerast
30  */
31
32 #ifndef __RAS_MATERIALBUCKET_H__
33 #define __RAS_MATERIALBUCKET_H__
34
35 #include "RAS_TexVert.h"
36 #include "CTR_Map.h"
37 #include "STR_HashedString.h"
38 #include "SG_QList.h"
39
40 #include "MT_Transform.h"
41 #include "RAS_IPolygonMaterial.h"
42 #include "RAS_IRasterizer.h"
43 #include "RAS_Deformer.h"
44
45 #include <vector>
46 #include <set>
47 #include <list>
48 using namespace std;
49
50 /* Display List Slot */
51
52 class KX_ListSlot
53 {
54 protected:
55         int m_refcount;
56 public:
57         KX_ListSlot() { m_refcount = 1; }
58         virtual ~KX_ListSlot() {}
59         virtual int Release() { 
60                 if (--m_refcount > 0)
61                         return m_refcount;
62                 delete this;
63                 return 0;
64         }
65         virtual KX_ListSlot* AddRef() {
66                 m_refcount++;
67                 return this;
68         }
69         virtual void SetModified(bool mod)=0;
70 };
71
72 class RAS_DisplayArray;
73 class RAS_MeshSlot;
74 class RAS_MeshMaterial;
75 class RAS_MaterialBucket;
76 struct DerivedMesh;
77
78 /* An array with data used for OpenGL drawing */
79
80 class RAS_DisplayArray
81 {
82 public:
83         vector<RAS_TexVert> m_vertex;
84         vector<unsigned short> m_index;
85         /* LINE currently isn't used */
86         enum { LINE = 2, TRIANGLE = 3, QUAD = 4 } m_type;
87         //RAS_MeshSlot *m_origSlot;
88         
89         /* Number of RAS_MeshSlot using this array */
90         int m_users;
91
92         enum { BUCKET_MAX_INDEX = 65535 };
93         enum { BUCKET_MAX_VERTEX = 65535 };
94 };
95
96 /* Entry of a RAS_MeshObject into RAS_MaterialBucket */
97 typedef std::vector<RAS_DisplayArray*>  RAS_DisplayArrayList;
98
99 // The QList is used to link the mesh slots to the object
100 // The DList is used to link the visible mesh slots to the material bucket
101 class RAS_MeshSlot : public SG_QList
102 {
103         friend class RAS_ListRasterizer;
104 private:
105         //  indices into display arrays
106         int                                                     m_startarray;
107         int                                                     m_endarray;
108         int                                                     m_startindex;
109         int                                                     m_endindex;
110         int                                                     m_startvertex;
111         int                                                     m_endvertex;
112         RAS_DisplayArrayList            m_displayArrays;
113
114         // for construction only
115         RAS_DisplayArray*                       m_currentArray;
116
117 public:
118         // for rendering
119         RAS_MaterialBucket*             m_bucket;
120         RAS_MeshObject*                 m_mesh;
121         void*                                   m_clientObj;
122         RAS_Deformer*                   m_pDeformer;
123         DerivedMesh*                    m_pDerivedMesh;
124         double*                                 m_OpenGLMatrix;
125         // visibility
126         bool                                    m_bVisible;
127         bool                                    m_bCulled;
128         // object color
129         bool                                    m_bObjectColor;
130         MT_Vector4                              m_RGBAcolor;
131         // display lists
132         KX_ListSlot*                    m_DisplayList;
133         bool                                    m_bDisplayList;
134         // joined mesh slots
135         RAS_MeshSlot*                   m_joinSlot;
136         MT_Matrix4x4                    m_joinInvTransform;
137         list<RAS_MeshSlot*>             m_joinedSlots;
138
139         RAS_MeshSlot();
140         RAS_MeshSlot(const RAS_MeshSlot& slot);
141         virtual ~RAS_MeshSlot();
142         
143         void init(RAS_MaterialBucket *bucket, int numverts);
144
145         struct iterator {
146                 RAS_DisplayArray *array;
147                 RAS_TexVert *vertex;
148                 unsigned short *index;
149                 size_t startvertex;
150                 size_t endvertex;
151                 size_t totindex;
152                 size_t arraynum;
153         };
154
155         void begin(iterator& it);
156         void next(iterator& it);
157         bool end(iterator& it);
158
159         /* used during construction */
160         void SetDisplayArray(int numverts);
161         RAS_DisplayArray *CurrentDisplayArray();
162         void SetDeformer(RAS_Deformer* deformer);
163
164         void AddPolygon(int numverts);
165         int AddVertex(const RAS_TexVert& tv);
166         void AddPolygonVertex(int offset);
167
168         /* optimization */
169         bool Split(bool force=false);
170         bool Join(RAS_MeshSlot *target, MT_Scalar distance);
171         bool Equals(RAS_MeshSlot *target);
172 #ifdef USE_SPLIT
173         bool IsCulled();
174 #else
175         bool IsCulled() { return m_bCulled; }
176 #endif
177         void SetCulled(bool culled) { m_bCulled = culled; }
178
179
180 #ifdef WITH_CXX_GUARDEDALLOC
181         MEM_CXX_CLASS_ALLOC_FUNCS("GE:RAS_MeshSlot")
182 #endif
183 };
184
185 /* Used by RAS_MeshObject, to point to it's slots in a bucket */
186
187 class RAS_MeshMaterial
188 {
189 public:
190         RAS_MeshSlot *m_baseslot;
191         class RAS_MaterialBucket *m_bucket;
192
193         /* the KX_GameObject is used as a key here */
194         CTR_Map<CTR_HashedPtr,RAS_MeshSlot*> m_slots;
195
196
197 #ifdef WITH_CXX_GUARDEDALLOC
198         MEM_CXX_CLASS_ALLOC_FUNCS("GE:RAS_MeshMaterial")
199 #endif
200 };
201
202 /* Contains a list of display arrays with the same material,
203  * and a mesh slot for each mesh that uses display arrays in
204  * this bucket */
205
206 class RAS_MaterialBucket
207 {
208 public:
209         RAS_MaterialBucket(RAS_IPolyMaterial* mat);
210         virtual ~RAS_MaterialBucket();
211         
212         /* Bucket Sorting */
213         struct less;
214         typedef set<RAS_MaterialBucket*, less> Set;
215
216         /* Material Properties */
217         RAS_IPolyMaterial*              GetPolyMaterial() const;
218         bool                                    IsAlpha() const;
219         bool                                    IsZSort() const;
220                 
221         /* Rendering */
222         bool ActivateMaterial(const MT_Transform& cameratrans, RAS_IRasterizer* rasty,
223                 RAS_IRenderTools *rendertools);
224         void RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRasterizer* rasty,
225                 RAS_IRenderTools* rendertools, RAS_MeshSlot &ms);
226         
227         /* Mesh Slot Access */
228         list<RAS_MeshSlot>::iterator msBegin();
229         list<RAS_MeshSlot>::iterator msEnd();
230
231         class RAS_MeshSlot*     AddMesh(int numverts);
232         class RAS_MeshSlot* CopyMesh(class RAS_MeshSlot *ms);
233         void                            RemoveMesh(class RAS_MeshSlot* ms);
234         void                            Optimize(MT_Scalar distance);
235         void                            ActivateMesh(RAS_MeshSlot* slot)
236         {
237                 m_activeMeshSlotsHead.AddBack(slot);
238         }
239         SG_DList&                       GetActiveMeshSlots()
240         {
241                 return m_activeMeshSlotsHead;
242         }
243         RAS_MeshSlot*           GetNextActiveMeshSlot()
244         {
245                 return (RAS_MeshSlot*)m_activeMeshSlotsHead.Remove();
246         }
247
248 private:
249         list<RAS_MeshSlot>                      m_meshSlots;                    // all the mesh slots
250         RAS_IPolyMaterial*                      m_material;
251         SG_DList                                        m_activeMeshSlotsHead;  // only those which must be rendered
252         
253
254 #ifdef WITH_CXX_GUARDEDALLOC
255         MEM_CXX_CLASS_ALLOC_FUNCS("GE:RAS_MaterialBucket")
256 #endif
257 };
258
259 #endif  /* __RAS_MATERIAL_BUCKET */