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