Merge from trunk 16122-16307
[blender.git] / source / gameengine / Ketsji / KX_VertexProxy.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_VertexProxy.h"
34 #include "KX_MeshProxy.h"
35 #include "RAS_TexVert.h"
36
37 #include "KX_PyMath.h"
38
39 PyTypeObject KX_VertexProxy::Type = {
40         PyObject_HEAD_INIT(&PyType_Type)
41         0,
42         "KX_VertexProxy",
43         sizeof(KX_VertexProxy),
44         0,
45         PyDestructor,
46         0,
47         __getattr,
48         __setattr,
49         0, //&MyPyCompare,
50         __repr,
51         0, //&cvalue_as_number,
52         0,
53         0,
54         0,
55         0
56 };
57
58 PyParentObject KX_VertexProxy::Parents[] = {
59         &KX_VertexProxy::Type,
60         &SCA_IObject::Type,
61         &CValue::Type,
62         NULL
63 };
64
65 PyMethodDef KX_VertexProxy::Methods[] = {
66 {"getXYZ", (PyCFunction)KX_VertexProxy::sPyGetXYZ,METH_VARARGS},
67 {"setXYZ", (PyCFunction)KX_VertexProxy::sPySetXYZ,METH_VARARGS},
68 {"getUV", (PyCFunction)KX_VertexProxy::sPyGetUV,METH_VARARGS},
69 {"setUV", (PyCFunction)KX_VertexProxy::sPySetUV,METH_VARARGS},
70
71 {"getUV2", (PyCFunction)KX_VertexProxy::sPyGetUV2,METH_VARARGS},
72 {"setUV2", (PyCFunction)KX_VertexProxy::sPySetUV2,METH_VARARGS},
73
74 {"getRGBA", (PyCFunction)KX_VertexProxy::sPyGetRGBA,METH_VARARGS},
75 {"setRGBA", (PyCFunction)KX_VertexProxy::sPySetRGBA,METH_VARARGS},
76 {"getNormal", (PyCFunction)KX_VertexProxy::sPyGetNormal,METH_VARARGS},
77 {"setNormal", (PyCFunction)KX_VertexProxy::sPySetNormal,METH_VARARGS},
78   {NULL,NULL} //Sentinel
79 };
80
81 PyObject*
82 KX_VertexProxy::_getattr(const STR_String& attr)
83 {
84   if (attr == "XYZ")
85         return PyObjectFrom(MT_Vector3(m_vertex->getLocalXYZ()));
86
87   if (attr == "UV")
88         return PyObjectFrom(MT_Point2(m_vertex->getUV1()));
89
90   if (attr == "colour" || attr == "color")
91   {
92         const unsigned char *colp = m_vertex->getRGBA();
93         MT_Vector4 color(colp[0], colp[1], colp[2], colp[3]);
94         color /= 255.0;
95         return PyObjectFrom(color);
96   }
97   
98   if (attr == "normal")
99   {
100         return PyObjectFrom(MT_Vector3(m_vertex->getNormal()));
101   }
102
103   // pos
104   if (attr == "x")
105         return PyFloat_FromDouble(m_vertex->getLocalXYZ()[0]);
106   if (attr == "y")
107         return PyFloat_FromDouble(m_vertex->getLocalXYZ()[1]);
108   if (attr == "z")
109         return PyFloat_FromDouble(m_vertex->getLocalXYZ()[2]);
110
111   // Col
112   if (attr == "r")
113         return PyFloat_FromDouble(m_vertex->getRGBA()[0]/255.0);
114   if (attr == "g")
115         return PyFloat_FromDouble(m_vertex->getRGBA()[1]/255.0);
116   if (attr == "b")
117         return PyFloat_FromDouble(m_vertex->getRGBA()[2]/255.0);
118   if (attr == "a")
119         return PyFloat_FromDouble(m_vertex->getRGBA()[3]/255.0);
120
121   // UV
122   if (attr == "u")
123         return PyFloat_FromDouble(m_vertex->getUV1()[0]);
124   if (attr == "v")
125         return PyFloat_FromDouble(m_vertex->getUV1()[1]);
126
127   _getattr_up(SCA_IObject);
128 }
129
130 int    KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue)
131 {
132   if (PySequence_Check(pyvalue))
133   {
134         if (attr == "XYZ")
135         {
136                 MT_Point3 vec;
137                 if (PyVecTo(pyvalue, vec))
138                 {
139                         m_vertex->SetXYZ(vec);
140                         m_mesh->SetMeshModified(true);
141                         return 0;
142                 }
143                 return 1;
144         }
145         
146         if (attr == "UV")
147         {
148                 MT_Point2 vec;
149                 if (PyVecTo(pyvalue, vec))
150                 {
151                         m_vertex->SetUV(vec);
152                         m_mesh->SetMeshModified(true);
153                         return 0;
154                 }
155                 return 1;
156         }
157         
158         if (attr == "colour" || attr == "color")
159         {
160                 MT_Vector4 vec;
161                 if (PyVecTo(pyvalue, vec))
162                 {
163                         m_vertex->SetRGBA(vec);
164                         m_mesh->SetMeshModified(true);
165                         return 0;
166                 }
167                 return 1;
168         }
169         
170         if (attr == "normal")
171         {
172                 MT_Vector3 vec;
173                 if (PyVecTo(pyvalue, vec))
174                 {
175                         m_vertex->SetNormal(vec);
176                         m_mesh->SetMeshModified(true);
177                         return 0;
178                 }
179                 return 1;
180         }
181   }
182   
183   if (PyFloat_Check(pyvalue))
184   {
185         float val = PyFloat_AsDouble(pyvalue);
186         // pos
187         MT_Point3 pos(m_vertex->getLocalXYZ());
188         if (attr == "x")
189         {
190                 pos.x() = val;
191                 m_vertex->SetXYZ(pos);
192                 m_mesh->SetMeshModified(true);
193                 return 0;
194         }
195         
196         if (attr == "y")
197         {
198                 pos.y() = val;
199                 m_vertex->SetXYZ(pos);
200                 m_mesh->SetMeshModified(true);
201                 return 0;
202         }
203         
204         if (attr == "z")
205         {
206                 pos.z() = val;
207                 m_vertex->SetXYZ(pos);
208                 m_mesh->SetMeshModified(true);
209                 return 0;
210         }
211         
212         // uv
213         MT_Point2 uv = m_vertex->getUV1();
214         if (attr == "u")
215         {
216                 uv[0] = val;
217                 m_vertex->SetUV(uv);
218                 m_mesh->SetMeshModified(true);
219                 return 0;
220         }
221
222         if (attr == "v")
223         {
224                 uv[1] = val;
225                 m_vertex->SetUV(uv);
226                 m_mesh->SetMeshModified(true);
227                 return 0;
228         }
229
230         // uv
231         MT_Point2 uv2 = m_vertex->getUV2();
232         if (attr == "u2")
233         {
234                 uv[0] = val;
235                 m_vertex->SetUV2(uv);
236                 m_mesh->SetMeshModified(true);
237                 return 0;
238         }
239
240         if (attr == "v2")
241         {
242                 uv[1] = val;
243                 m_vertex->SetUV2(uv);
244                 m_mesh->SetMeshModified(true);
245                 return 0;
246         }
247         
248         // col
249         unsigned int icol = *((const unsigned int *)m_vertex->getRGBA());
250         unsigned char *cp = (unsigned char*) &icol;
251         val *= 255.0;
252         if (attr == "r")
253         {
254                 cp[0] = (unsigned char) val;
255                 m_vertex->SetRGBA(icol);
256                 m_mesh->SetMeshModified(true);
257                 return 0;
258         }
259         if (attr == "g")
260         {
261                 cp[1] = (unsigned char) val;
262                 m_vertex->SetRGBA(icol);
263                 m_mesh->SetMeshModified(true);
264                 return 0;
265         }
266         if (attr == "b")
267         {
268                 cp[2] = (unsigned char) val;
269                 m_vertex->SetRGBA(icol);
270                 m_mesh->SetMeshModified(true);
271                 return 0;
272         }
273         if (attr == "a")
274         {
275                 cp[3] = (unsigned char) val;
276                 m_vertex->SetRGBA(icol);
277                 m_mesh->SetMeshModified(true);
278                 return 0;
279         }
280   }
281   
282   return SCA_IObject::_setattr(attr, pyvalue);
283 }
284
285 KX_VertexProxy::KX_VertexProxy(KX_MeshProxy*mesh, RAS_TexVert* vertex)
286 :       m_vertex(vertex),
287         m_mesh(mesh)
288 {
289 }
290
291 KX_VertexProxy::~KX_VertexProxy()
292 {
293 }
294
295
296
297 // stuff for cvalue related things
298 CValue*         KX_VertexProxy::Calc(VALUE_OPERATOR, CValue *) { return NULL;}
299 CValue*         KX_VertexProxy::CalcFinal(VALUE_DATA_TYPE, VALUE_OPERATOR, CValue *) { return NULL;}    
300 STR_String      sVertexName="vertex";
301 const STR_String &      KX_VertexProxy::GetText() {return sVertexName;};
302 float           KX_VertexProxy::GetNumber() { return -1;}
303 STR_String      KX_VertexProxy::GetName() { return sVertexName;}
304 void            KX_VertexProxy::SetName(STR_String) { };
305 CValue*         KX_VertexProxy::GetReplica() { return NULL;}
306 void            KX_VertexProxy::ReplicaSetName(STR_String) {};
307
308
309 // stuff for python integration
310         
311 PyObject* KX_VertexProxy::PyGetXYZ(PyObject*, 
312                                PyObject*, 
313                                PyObject*)
314 {
315         return PyObjectFrom(MT_Point3(m_vertex->getLocalXYZ()));
316 }
317
318 PyObject* KX_VertexProxy::PySetXYZ(PyObject*, 
319                                PyObject* args, 
320                                PyObject*)
321 {
322         MT_Point3 vec;
323         if (PyVecArgTo(args, vec))
324         {
325                 m_vertex->SetXYZ(vec);
326                 m_mesh->SetMeshModified(true);
327                 Py_Return;
328         }
329         
330         return NULL;
331 }
332
333 PyObject* KX_VertexProxy::PyGetNormal(PyObject*, 
334                                PyObject*, 
335                                PyObject*)
336 {
337         return PyObjectFrom(MT_Vector3(m_vertex->getNormal()));
338 }
339
340 PyObject* KX_VertexProxy::PySetNormal(PyObject*, 
341                                PyObject* args, 
342                                PyObject*)
343 {
344         MT_Vector3 vec;
345         if (PyVecArgTo(args, vec))
346         {
347                 m_vertex->SetNormal(vec);
348                 m_mesh->SetMeshModified(true);
349                 Py_Return;
350         }
351         
352         return NULL;
353 }
354
355
356 PyObject* KX_VertexProxy::PyGetRGBA(PyObject*,
357                                PyObject*, 
358                                PyObject*)
359 {
360         int *rgba = (int *) m_vertex->getRGBA();
361         return PyInt_FromLong(*rgba);
362 }
363
364 PyObject* KX_VertexProxy::PySetRGBA(PyObject*, 
365                                PyObject* args, 
366                                PyObject*)
367 {
368         float r, g, b, a;
369         if (PyArg_ParseTuple(args, "(ffff)", &r, &g, &b, &a))
370         {
371                 m_vertex->SetRGBA(MT_Vector4(r, g, b, a));
372                 m_mesh->SetMeshModified(true);
373                 Py_Return;
374         }
375         PyErr_Clear();
376         
377         int rgba;
378         if (PyArg_ParseTuple(args,"i",&rgba))
379         {
380                 m_vertex->SetRGBA(rgba);
381                 m_mesh->SetMeshModified(true);
382                 Py_Return;
383         }
384         
385         return NULL;
386 }
387
388
389 PyObject* KX_VertexProxy::PyGetUV(PyObject*, 
390                                PyObject*, 
391                                PyObject*)
392 {
393         return PyObjectFrom(MT_Vector2(m_vertex->getUV1()));
394 }
395
396 PyObject* KX_VertexProxy::PySetUV(PyObject*, 
397                                PyObject* args, 
398                                PyObject*)
399 {
400         MT_Point2 vec;
401         if (PyVecArgTo(args, vec))
402         {
403                 m_vertex->SetUV(vec);
404                 m_mesh->SetMeshModified(true);
405                 Py_Return;
406         }
407         
408         return NULL;
409 }
410
411 PyObject* KX_VertexProxy::PyGetUV2(PyObject*, 
412                                PyObject*, 
413                                PyObject*)
414 {
415         return PyObjectFrom(MT_Vector2(m_vertex->getUV2()));
416 }
417
418 PyObject* KX_VertexProxy::PySetUV2(PyObject*, 
419                                PyObject* args, 
420                                PyObject*)
421 {
422         MT_Point2 vec;
423         unsigned int unit=0;
424         PyObject* list=0;
425         if(PyArg_ParseTuple(args, "Oi", &list, &unit))
426         {
427                 if (PyVecTo(list, vec))
428                 {
429                         m_vertex->SetFlag((m_vertex->getFlag()|TV_2NDUV));
430                         m_vertex->SetUnit(unit);
431                         m_vertex->SetUV2(vec);
432                         m_mesh->SetMeshModified(true);
433                         Py_Return;
434                 }
435         }
436         return NULL;
437 }