Py BGE API
[blender.git] / source / gameengine / Ketsji / KX_PolyProxy.cpp
1 /**
2  * $Id$
3  * ***** BEGIN GPL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software Foundation,
17  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18  *
19  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
20  * All rights reserved.
21  *
22  * The Original Code is: all of this file.
23  *
24  * Contributor(s): none yet.
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 #ifdef HAVE_CONFIG_H
30 #include <config.h>
31 #endif
32
33 #include "KX_PolyProxy.h"
34 #include "KX_MeshProxy.h"
35 #include "RAS_MeshObject.h"
36 #include "KX_BlenderMaterial.h"
37 #include "KX_PolygonMaterial.h"
38
39 #include "KX_PyMath.h"
40
41 PyTypeObject KX_PolyProxy::Type = {
42         PyObject_HEAD_INIT(&PyType_Type)
43         0,
44         "KX_PolyProxy",
45         sizeof(KX_PolyProxy),
46         0,
47         PyDestructor,
48         0,
49         __getattr,
50         __setattr,
51         0, //&MyPyCompare,
52         __repr,
53         0, //&cvalue_as_number,
54         0,
55         0,
56         0,
57         0
58 };
59
60 PyParentObject KX_PolyProxy::Parents[] = {
61         &KX_PolyProxy::Type,
62         &SCA_IObject::Type,
63         &CValue::Type,
64         NULL
65 };
66
67 PyMethodDef KX_PolyProxy::Methods[] = {
68         KX_PYMETHODTABLE_NOARGS(KX_PolyProxy,getMaterialIndex),
69         KX_PYMETHODTABLE_NOARGS(KX_PolyProxy,getNumVertex),
70         KX_PYMETHODTABLE_NOARGS(KX_PolyProxy,isVisible),
71         KX_PYMETHODTABLE_NOARGS(KX_PolyProxy,isCollider),
72         KX_PYMETHODTABLE_NOARGS(KX_PolyProxy,getMaterialName),
73         KX_PYMETHODTABLE_NOARGS(KX_PolyProxy,getTextureName),
74         KX_PYMETHODTABLE(KX_PolyProxy,getVertexIndex),
75         KX_PYMETHODTABLE_NOARGS(KX_PolyProxy,getMesh),
76         KX_PYMETHODTABLE_NOARGS(KX_PolyProxy,getMaterial),
77         {NULL,NULL} //Sentinel
78 };
79
80 PyAttributeDef KX_PolyProxy::Attributes[] = {
81         { NULL }        //Sentinel
82 };
83
84 PyObject* KX_PolyProxy::_getattr(const char *attr)
85 {
86         if (!strcmp(attr, "matname"))
87         {
88                 return PyString_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetMaterialName());
89         }
90         if (!strcmp(attr, "texture"))
91         {
92                 return PyString_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetTextureName());
93         }
94         if (!strcmp(attr, "material"))
95         {
96                 RAS_IPolyMaterial *polymat = m_polygon->GetMaterial()->GetPolyMaterial();
97                 if(polymat->GetFlag() & RAS_BLENDERMAT)
98                 {
99                         KX_BlenderMaterial* mat = static_cast<KX_BlenderMaterial*>(polymat);
100                         Py_INCREF(mat);
101                         return mat;
102                 }
103                 else
104                 {
105                         KX_PolygonMaterial* mat = static_cast<KX_PolygonMaterial*>(polymat);
106                         Py_INCREF(mat);
107                         return mat;
108                 }
109         }
110         if (!strcmp(attr, "matid"))
111         {
112                 // we'll have to scan through the material bucket of the mes and compare with 
113                 // the one of the polygon
114                 RAS_MaterialBucket* polyBucket = m_polygon->GetMaterial();
115                 unsigned int matid;
116                 for (matid=0; matid<m_mesh->NumMaterials(); matid++)
117                 {
118                         RAS_MeshMaterial* meshMat = m_mesh->GetMeshMaterial(matid);
119                         if (meshMat->m_bucket == polyBucket)
120                                 // found it
121                                 break;
122                 }
123                 return PyInt_FromLong(matid);
124         }
125         if (!strcmp(attr, "v1"))
126         {
127                 return PyInt_FromLong(m_polygon->GetVertexOffset(0));
128         }
129         if (!strcmp(attr, "v2"))
130         {
131                 return PyInt_FromLong(m_polygon->GetVertexOffset(1));
132         }
133         if (!strcmp(attr, "v3"))
134         {
135                 return PyInt_FromLong(m_polygon->GetVertexOffset(2));
136         }
137         if (!strcmp(attr, "v4"))
138         {
139                 return PyInt_FromLong(((m_polygon->VertexCount()>3)?m_polygon->GetVertexOffset(3):0));
140         }
141         if (!strcmp(attr, "visible"))
142         {
143                 return PyInt_FromLong(m_polygon->IsVisible());
144         }
145         if (!strcmp(attr, "collide"))
146         {
147                 return PyInt_FromLong(m_polygon->IsCollider());
148         }
149         _getattr_up(SCA_IObject);
150 }
151
152 KX_PolyProxy::KX_PolyProxy(const RAS_MeshObject*mesh, RAS_Polygon* polygon)
153 :       m_polygon(polygon),
154         m_mesh((RAS_MeshObject*)mesh)
155 {
156 }
157
158 KX_PolyProxy::~KX_PolyProxy()
159 {
160 }
161
162
163 // stuff for cvalue related things
164 CValue*         KX_PolyProxy::Calc(VALUE_OPERATOR, CValue *) { return NULL;}
165 CValue*         KX_PolyProxy::CalcFinal(VALUE_DATA_TYPE, VALUE_OPERATOR, CValue *) { return NULL;}      
166 STR_String      sPolyName="polygone";
167 const STR_String &      KX_PolyProxy::GetText() {return sPolyName;};
168 float           KX_PolyProxy::GetNumber() { return -1;}
169 STR_String      KX_PolyProxy::GetName() { return sPolyName;}
170 void            KX_PolyProxy::SetName(STR_String) { };
171 CValue*         KX_PolyProxy::GetReplica() { return NULL;}
172 void            KX_PolyProxy::ReplicaSetName(STR_String) {};
173
174
175 // stuff for python integration
176
177 KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getMaterialIndex, 
178 "getMaterialIndex() : return the material index of the polygon in the mesh\n")
179 {
180         RAS_MaterialBucket* polyBucket = m_polygon->GetMaterial();
181         unsigned int matid;
182         for (matid=0; matid<m_mesh->NumMaterials(); matid++)
183         {
184                 RAS_MeshMaterial* meshMat = m_mesh->GetMeshMaterial(matid);
185                 if (meshMat->m_bucket == polyBucket)
186                         // found it
187                         break;
188         }
189         return PyInt_FromLong(matid);
190 }
191
192 KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getNumVertex,
193 "getNumVertex() : returns the number of vertex of the polygon, 3 or 4\n")
194 {
195         return PyInt_FromLong(m_polygon->VertexCount());
196 }
197
198 KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, isVisible,
199 "isVisible() : returns whether the polygon is visible or not\n")
200 {
201         return PyInt_FromLong(m_polygon->IsVisible());
202 }
203
204 KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, isCollider,
205 "isCollider() : returns whether the polygon is receives collision or not\n")
206 {
207         return PyInt_FromLong(m_polygon->IsCollider());
208 }
209
210 KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getMaterialName,
211 "getMaterialName() : returns the polygon material name, \"NoMaterial\" if no material\n")
212 {
213         return PyString_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetMaterialName());
214 }
215
216 KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getTextureName,
217 "getTexturelName() : returns the polygon texture name, \"NULL\" if no texture\n")
218 {
219         return PyString_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetTextureName());
220 }
221
222 KX_PYMETHODDEF_DOC(KX_PolyProxy, getVertexIndex,
223 "getVertexIndex(vertex) : returns the mesh vertex index of a polygon vertex\n"
224 "vertex: index of the vertex in the polygon: 0->3\n"
225 "return value can be used to retrieve the vertex details through mesh proxy\n"
226 "Note: getVertexIndex(3) on a triangle polygon returns 0\n")
227 {
228         int index;
229         if (!PyArg_ParseTuple(args,"i",&index))
230         {
231                 return NULL;
232         }
233         if (index < 0 || index > 3)
234         {
235                 PyErr_SetString(PyExc_AttributeError, "Valid range for index is 0-3");
236                 return NULL;
237         }
238         if (index < m_polygon->VertexCount())
239         {
240                 return PyInt_FromLong(m_polygon->GetVertexOffset(index));
241         }
242         return PyInt_FromLong(0);
243 }
244
245 KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getMesh,
246 "getMesh() : returns a mesh proxy\n")
247 {
248         KX_MeshProxy* meshproxy = new KX_MeshProxy((RAS_MeshObject*)m_mesh);
249         return meshproxy;
250 }
251
252 KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getMaterial,
253 "getMaterial() : returns a material\n")
254 {
255         RAS_IPolyMaterial *polymat = m_polygon->GetMaterial()->GetPolyMaterial();
256         if(polymat->GetFlag() & RAS_BLENDERMAT)
257         {
258                 KX_BlenderMaterial* mat = static_cast<KX_BlenderMaterial*>(polymat);
259                 Py_INCREF(mat);
260                 return mat;
261         }
262         else
263         {
264                 KX_PolygonMaterial* mat = static_cast<KX_PolygonMaterial*>(polymat);
265                 Py_INCREF(mat);
266                 return mat;
267         }
268 }