c03d585395cf40fc328d018d96da4d0a4d0c2516
[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(NULL)
43         0,
44         "KX_PolyProxy",
45         sizeof(KX_PolyProxy),
46         0,
47         PyDestructor,
48         0,
49         0,
50         0,
51         0,
52         py_base_repr,
53         0,0,0,0,0,0,
54         py_base_getattro,
55         py_base_setattro,
56         0,0,0,0,0,0,0,0,0,
57         Methods
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         /* All dummy's so they come up in a dir() */
82         KX_PYATTRIBUTE_DUMMY("matname"),
83         KX_PYATTRIBUTE_DUMMY("texture"),
84         KX_PYATTRIBUTE_DUMMY("material"),
85         KX_PYATTRIBUTE_DUMMY("matid"),
86         KX_PYATTRIBUTE_DUMMY("v1"),
87         KX_PYATTRIBUTE_DUMMY("v2"),
88         KX_PYATTRIBUTE_DUMMY("v3"),
89         KX_PYATTRIBUTE_DUMMY("v4"),
90         KX_PYATTRIBUTE_DUMMY("visible"),
91         KX_PYATTRIBUTE_DUMMY("collide"),
92         { NULL }        //Sentinel
93 };
94
95 PyObject* KX_PolyProxy::py_getattro(PyObject *attr)
96 {
97         char *attr_str= PyString_AsString(attr);
98         if (!strcmp(attr_str, "matname"))
99         {
100                 return PyString_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetMaterialName());
101         }
102         if (!strcmp(attr_str, "texture"))
103         {
104                 return PyString_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetTextureName());
105         }
106         if (!strcmp(attr_str, "material"))
107         {
108                 RAS_IPolyMaterial *polymat = m_polygon->GetMaterial()->GetPolyMaterial();
109                 if(polymat->GetFlag() & RAS_BLENDERMAT)
110                 {
111                         KX_BlenderMaterial* mat = static_cast<KX_BlenderMaterial*>(polymat);
112                         return mat->GetProxy();
113                 }
114                 else
115                 {
116                         KX_PolygonMaterial* mat = static_cast<KX_PolygonMaterial*>(polymat);
117                         return mat->GetProxy();
118                 }
119         }
120         if (!strcmp(attr_str, "matid"))
121         {
122                 // we'll have to scan through the material bucket of the mes and compare with 
123                 // the one of the polygon
124                 RAS_MaterialBucket* polyBucket = m_polygon->GetMaterial();
125                 unsigned int matid;
126                 for (matid=0; matid<m_mesh->NumMaterials(); matid++)
127                 {
128                         RAS_MeshMaterial* meshMat = m_mesh->GetMeshMaterial(matid);
129                         if (meshMat->m_bucket == polyBucket)
130                                 // found it
131                                 break;
132                 }
133                 return PyInt_FromLong(matid);
134         }
135         if (!strcmp(attr_str, "v1"))
136         {
137                 return PyInt_FromLong(m_polygon->GetVertexOffset(0));
138         }
139         if (!strcmp(attr_str, "v2"))
140         {
141                 return PyInt_FromLong(m_polygon->GetVertexOffset(1));
142         }
143         if (!strcmp(attr_str, "v3"))
144         {
145                 return PyInt_FromLong(m_polygon->GetVertexOffset(2));
146         }
147         if (!strcmp(attr_str, "v4"))
148         {
149                 return PyInt_FromLong(((m_polygon->VertexCount()>3)?m_polygon->GetVertexOffset(3):0));
150         }
151         if (!strcmp(attr_str, "visible"))
152         {
153                 return PyInt_FromLong(m_polygon->IsVisible());
154         }
155         if (!strcmp(attr_str, "collide"))
156         {
157                 return PyInt_FromLong(m_polygon->IsCollider());
158         }
159         py_getattro_up(SCA_IObject);
160 }
161
162 KX_PolyProxy::KX_PolyProxy(const RAS_MeshObject*mesh, RAS_Polygon* polygon)
163 :       m_polygon(polygon),
164         m_mesh((RAS_MeshObject*)mesh)
165 {
166 }
167
168 KX_PolyProxy::~KX_PolyProxy()
169 {
170 }
171
172
173 // stuff for cvalue related things
174 CValue*         KX_PolyProxy::Calc(VALUE_OPERATOR, CValue *) { return NULL;}
175 CValue*         KX_PolyProxy::CalcFinal(VALUE_DATA_TYPE, VALUE_OPERATOR, CValue *) { return NULL;}      
176 STR_String      sPolyName="polygone";
177 const STR_String &      KX_PolyProxy::GetText() {return sPolyName;};
178 double          KX_PolyProxy::GetNumber() { return -1;}
179 STR_String      KX_PolyProxy::GetName() { return sPolyName;}
180 void            KX_PolyProxy::SetName(STR_String) { };
181 CValue*         KX_PolyProxy::GetReplica() { return NULL;}
182 void            KX_PolyProxy::ReplicaSetName(STR_String) {};
183
184
185 // stuff for python integration
186
187 KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getMaterialIndex, 
188 "getMaterialIndex() : return the material index of the polygon in the mesh\n")
189 {
190         RAS_MaterialBucket* polyBucket = m_polygon->GetMaterial();
191         unsigned int matid;
192         for (matid=0; matid<m_mesh->NumMaterials(); matid++)
193         {
194                 RAS_MeshMaterial* meshMat = m_mesh->GetMeshMaterial(matid);
195                 if (meshMat->m_bucket == polyBucket)
196                         // found it
197                         break;
198         }
199         return PyInt_FromLong(matid);
200 }
201
202 KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getNumVertex,
203 "getNumVertex() : returns the number of vertex of the polygon, 3 or 4\n")
204 {
205         return PyInt_FromLong(m_polygon->VertexCount());
206 }
207
208 KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, isVisible,
209 "isVisible() : returns whether the polygon is visible or not\n")
210 {
211         return PyInt_FromLong(m_polygon->IsVisible());
212 }
213
214 KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, isCollider,
215 "isCollider() : returns whether the polygon is receives collision or not\n")
216 {
217         return PyInt_FromLong(m_polygon->IsCollider());
218 }
219
220 KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getMaterialName,
221 "getMaterialName() : returns the polygon material name, \"NoMaterial\" if no material\n")
222 {
223         return PyString_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetMaterialName());
224 }
225
226 KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getTextureName,
227 "getTexturelName() : returns the polygon texture name, \"NULL\" if no texture\n")
228 {
229         return PyString_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetTextureName());
230 }
231
232 KX_PYMETHODDEF_DOC(KX_PolyProxy, getVertexIndex,
233 "getVertexIndex(vertex) : returns the mesh vertex index of a polygon vertex\n"
234 "vertex: index of the vertex in the polygon: 0->3\n"
235 "return value can be used to retrieve the vertex details through mesh proxy\n"
236 "Note: getVertexIndex(3) on a triangle polygon returns 0\n")
237 {
238         int index;
239         if (!PyArg_ParseTuple(args,"i:getVertexIndex",&index))
240         {
241                 return NULL;
242         }
243         if (index < 0 || index > 3)
244         {
245                 PyErr_SetString(PyExc_AttributeError, "Valid range for index is 0-3");
246                 return NULL;
247         }
248         if (index < m_polygon->VertexCount())
249         {
250                 return PyInt_FromLong(m_polygon->GetVertexOffset(index));
251         }
252         return PyInt_FromLong(0);
253 }
254
255 KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getMesh,
256 "getMesh() : returns a mesh proxy\n")
257 {
258         KX_MeshProxy* meshproxy = new KX_MeshProxy((RAS_MeshObject*)m_mesh);
259         return meshproxy->NewProxy(true);
260 }
261
262 KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getMaterial,
263 "getMaterial() : returns a material\n")
264 {
265         RAS_IPolyMaterial *polymat = m_polygon->GetMaterial()->GetPolyMaterial();
266         if(polymat->GetFlag() & RAS_BLENDERMAT)
267         {
268                 KX_BlenderMaterial* mat = static_cast<KX_BlenderMaterial*>(polymat);
269                 return mat->GetProxy();
270         }
271         else
272         {
273                 KX_PolygonMaterial* mat = static_cast<KX_PolygonMaterial*>(polymat);
274                 return mat->GetProxy();
275         }
276 }