4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; either version 2 of the License, or
7
* (at your option) any later version.
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.
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
16
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
/*********************************************************
20
* i_cal3d4p3.c : use Cal3D (http://cal3d.sourceforge.net)
21
* rocking animation lib with Soya
22
* Copyright (C) 2003 Jean-Baptiste 'Jiba' LAMY
23
*********************************************************/
25
//#include "../cal3d_wrapper.h" //#include <cal3d/cal3d_wrapper.h> // Buggous file ?
31
static int PyP3Cal3DShape_Traverse (P3_cal3d_shape* self, visitproc visit, void* arg) {
34
if (self->nb_materials > 0) {
35
for (i = 0; i < self->nb_materials; i++) {
36
err = visit ((PyObject*) self->materials[i], arg);
37
if (err) { return err; }
43
static int PyP3Cal3DShape_Clear (P3_cal3d_shape* self) {
45
if (self->nb_materials > 0) {
46
for( i = 0; i < self->nb_materials; i++) {
47
Py_DECREF (self->materials[i]);
49
self->nb_materials = 0;
50
free (self->materials);
55
static void PyP3Cal3DShape_Dealloc (P3_cal3d_shape* self) {
57
PyObject_GC_UnTrack ((PyObject*) self);
58
if (self->nb_materials > 0) {
59
for (i = 0; i < self->nb_materials; i++) {
60
Py_DECREF (self->materials[i]);
62
self->nb_materials = 0;
63
free (self->materials);
65
CalCoreModel_Destroy (self->core_model);
66
CalCoreModel_Delete (self->core_model);
67
self->ob_type->tp_free ((PyObject*) self);
70
static int PyP3Cal3DShape_Init (PyObject* self, PyObject* args, PyObject* kwds) {
71
P3_cal3d_shape_new ((P3_cal3d_shape*) self);
75
static PyObject* PyP3Cal3DShape_LoadSkeleton (P3_cal3d_shape* self, PyObject* arg) {
76
if (!CalCoreModel_LoadCoreSkeleton (self->core_model, PyString_AS_STRING (arg))) {
77
P3_error (CalError_GetLastErrorDescription());
78
P3_error ("CalCoreModel_LoadCoreSkeleton failed!");
79
return PyInt_FromLong (0);
81
return PyInt_FromLong (1);
84
static PyObject* PyP3Cal3DShape_LoadMesh (P3_cal3d_shape* self, PyObject* arg) {
85
int id = CalCoreModel_LoadCoreMesh (self->core_model, PyString_AS_STRING (arg));
87
P3_error (CalError_GetLastErrorDescription ());
88
P3_error ("CalCoreModel_LoadCoreMesh failed!");
90
return PyInt_FromLong (id);
93
static PyObject* PyP3Cal3DShape_LoadMaterial (P3_cal3d_shape* self, PyObject* arg) {
94
int id = CalCoreModel_LoadCoreMaterial (self->core_model, PyString_AS_STRING (arg));
96
P3_error (CalError_GetLastErrorDescription ());
97
P3_error ("CalCoreModel_LoadCoreMaterial failed!");
99
return PyInt_FromLong (id);
102
static PyObject* PyP3Cal3DShape_LoadAnimation (P3_cal3d_shape* self, PyObject* arg) {
103
int id = CalCoreModel_LoadCoreAnimation (self->core_model, PyString_AS_STRING (arg));
105
P3_error (CalError_GetLastErrorDescription());
106
P3_error ("CalCoreModel_LoadCoreAnimation failed!");
108
return PyInt_FromLong (id);
111
static PyObject* PyP3Cal3DShape_BuildMaterials (P3_cal3d_shape* shape) {
113
struct CalCoreMaterial* material;
115
if (shape->nb_materials > 0) {
116
for (i = 0; i < shape->nb_materials; i++) { Py_DECREF (shape->materials[i]); }
117
free (shape->materials);
119
if (shape->core_model == NULL) {
124
shape->nb_materials = CalCoreModel_GetCoreMaterialCount (shape->core_model);
125
shape->materials = (P3_material**) malloc (shape->nb_materials * sizeof (P3_material*));
126
for (i = 0; i < shape->nb_materials; i++) {
127
CalCoreModel_CreateCoreMaterialThread (shape->core_model, i);
128
CalCoreModel_SetCoreMaterialId (shape->core_model, i, 0, i);
130
material = CalCoreModel_GetCoreMaterial (shape->core_model, i);
131
CalCoreMaterial_SetUserData (material, (CalUserData) i);
133
shape->materials[i] = (P3_material*) PyObject_CallMethod
134
((PyObject*) shape, "_get_material_4_cal3d", "sfffffffff",
135
CalCoreMaterial_GetMapFilename (material, 0),
136
1.0, // It seems that the Cal3D C version
137
1.0, // does not support yet the
138
1.0, // CalCoreMaterial_Get*Color functions.
144
CalCoreMaterial_GetShininess (material));
145
Py_INCREF (shape->materials[i]);
152
static PyObject* PyP3Cal3DShape_SetCellShading (P3_cal3d_shape* a, PyObject* args) {
156
tuple = PySequence_Fast_GET_ITEM (args, 1);
157
PY_TUPLE_FLOAT_TO_ARRAY_4 (color, tuple);
158
shader = (P3_material*) PySequence_Fast_GET_ITEM (args, 0);
159
if ((PyObject*) shader == Py_None) { shader = NULL; }
160
P3_cal3d_shape_set_cell_shading (a, shader, color, (GLfloat) PyFloat_AS_DOUBLE (PySequence_Fast_GET_ITEM (args, 2)));
165
PY_GET_SET_ON_OPTION (Cal3DShape, P3_cal3d_shape*, ShadowCast, P3_CAL3D_SHADOW_CAST)
167
static PyGetSetDef PyP3Cal3DShape_GetSets[] = {
168
{ "shadow_cast", (getter) PyP3Cal3DShape_GetShadowCast, (setter) PyP3Cal3DShape_SetShadowCast, NULL },
172
static PyMethodDef PyP3Cal3DShape_Methods[] = {
173
{ "set_cell_shading", (PyCFunction) PyP3Cal3DShape_SetCellShading, METH_VARARGS },
174
{ "_load_skeleton", (PyCFunction) PyP3Cal3DShape_LoadSkeleton, METH_O },
175
{ "_load_mesh", (PyCFunction) PyP3Cal3DShape_LoadMesh, METH_O },
176
{ "_load_material", (PyCFunction) PyP3Cal3DShape_LoadMaterial, METH_O },
177
{ "_load_animation", (PyCFunction) PyP3Cal3DShape_LoadAnimation, METH_O },
178
{ "_build_materials", (PyCFunction) PyP3Cal3DShape_BuildMaterials, METH_NOARGS },
182
PyTypeObject PyP3Cal3DShape_Type = {
183
PyObject_HEAD_INIT(NULL)
186
sizeof(P3_cal3d_shape),
188
(destructor) PyP3Cal3DShape_Dealloc,/* tp_dealloc */
195
0,/* tp_as_sequence */
196
0,/* tp_as_mapping */
200
PYP3_GENERIC_GETATTR,/* tp_getattro */
203
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,/* tp_flags */
205
(traverseproc) PyP3Cal3DShape_Traverse,/* tp_traverse */
206
(inquiry) PyP3Cal3DShape_Clear,/* tp_clear */
207
0,/* tp_richcompare */
208
0,/* tp_weaklistoffset */
211
(PyMethodDef*) &PyP3Cal3DShape_Methods,/* tp_methods */
213
(PyGetSetDef*) &PyP3Cal3DShape_GetSets,/* tp_getset */
218
0,/* tp_dictoffset */
219
(initproc) PyP3Cal3DShape_Init,/* tp_init */
220
PYP3_GENERIC_ALLOC,/* tp_alloc */
221
(newfunc) PyP3Object_New,/* tp_new */
222
PYP3_GENERIC_GC_FREE,/* tp_free */
230
static int PyP3Cal3DVolume_Init (PyObject* self, PyObject* args, PyObject* kwds) {
231
P3_cal3d_volume_new ((P3_cal3d_volume*) self);
235
static int PyP3Cal3DVolume_Traverse (P3_cal3d_volume* w, visitproc visit, void* arg) {
237
if (w->shape != NULL) {
238
err = visit ((PyObject*) w->shape, arg);
239
if (err) { return err; }
241
if (w->parent != NULL) {
242
err = visit ((PyObject*) w->parent, arg);
243
if (err) { return err; }
245
if (w->attached_coordsys != NULL) {
246
err = visit ((PyObject*) w->attached_coordsys, arg);
247
if (err) { return err; }
252
static int PyP3Cal3DVolume_Clear (P3_cal3d_volume* self) {
253
Py_XDECREF (self->shape);
254
Py_XDECREF (self->parent);
255
Py_XDECREF (self->attached_coordsys);
258
self->attached_coordsys = NULL;
262
static void PyP3Cal3DVolume_Dealloc (P3_cal3d_volume* self) {
263
Py_XDECREF (self->shape);
264
Py_XDECREF (self->parent);
265
Py_XDECREF (self->attached_coordsys);
267
P3_cal3d_volume_dealloc (self);
269
PyObject_GC_UnTrack ((PyObject*) self);
270
self->ob_type->tp_free ((PyObject*) self);
273
static PyObject* PyP3Cal3DVolume_GetShape (P3_cal3d_volume* volume, void* context) {
274
if (volume->shape == NULL) {
278
Py_INCREF ((PyObject*) volume->shape);
279
return (PyObject*) volume->shape;
282
static PyObject* PyP3Cal3DVolume_SetShape (P3_cal3d_volume* volume, PyObject* arg) {
283
Py_XDECREF ((PyObject*) volume->shape);
284
if (arg == Py_None || arg == NULL) {
285
P3_cal3d_volume_set_shape (volume, NULL);
288
P3_cal3d_volume_set_shape (volume, (P3_cal3d_shape*) arg);
294
static PyObject* PyP3Cal3DVolume_Update (P3_cal3d_volume* volume, PyObject* arg) {
295
volume->delta_time += (float) PyFloat_AS_DOUBLE(arg);
300
static PyObject* PyP3Cal3DVolume_SetAttached (P3_cal3d_volume* volume, PyObject* args) {
301
P3_cal3d_volume_set_attached (volume,
302
(int) PyInt_AS_LONG (PySequence_Fast_GET_ITEM (args, 0)),
303
(int) PyInt_AS_LONG (PySequence_Fast_GET_ITEM (args, 1)));
308
static PyObject* PyP3Cal3DVolume_IsAttached (P3_cal3d_volume* volume, PyObject* arg) {
309
return PyInt_FromLong ((long) volume->attached_states[(int) PyInt_AS_LONG (arg)]);
312
static PyObject* PyP3Cal3DVolume_AttachAll (P3_cal3d_volume* volume) {
313
P3_cal3d_volume_attach_all (volume);
318
static PyObject* PyP3Cal3DVolume_SetLodLevel (P3_cal3d_volume* volume, PyObject* arg) {
319
if (volume->model != NULL) {
320
CalModel_SetLodLevel (volume->model, (float) PyFloat_AS_DOUBLE(arg));
326
static PyObject* PyP3Cal3DVolume_BuildSubshapes (P3_cal3d_volume* volume) {
327
P3_cal3d_volume_build_submeshes (volume);
332
static PyObject* PyP3Cal3DVolume_AnimateClearCycle (P3_cal3d_volume* volume, PyObject* args) {
333
CalMixer_ClearCycle (CalModel_GetMixer (volume->model),
334
(int) PyInt_AS_LONG (PySequence_Fast_GET_ITEM (args, 0)),
335
(float) PyFloat_AS_DOUBLE (PySequence_Fast_GET_ITEM (args, 1)));
340
static PyObject* PyP3Cal3DVolume_AnimateBlendCycle (P3_cal3d_volume* volume, PyObject* args) {
341
CalMixer_BlendCycle (CalModel_GetMixer (volume->model),
342
(int) PyInt_AS_LONG (PySequence_Fast_GET_ITEM (args, 0)),
343
(float) PyFloat_AS_DOUBLE (PySequence_Fast_GET_ITEM (args, 1)),
344
(float) PyFloat_AS_DOUBLE (PySequence_Fast_GET_ITEM (args, 2)));
349
static PyObject* PyP3Cal3DVolume_AnimateExecuteAction (P3_cal3d_volume* volume, PyObject* args) {
350
CalMixer_ExecuteAction (CalModel_GetMixer (volume->model),
351
(int) PyInt_AS_LONG (PySequence_Fast_GET_ITEM (args, 0)),
352
(float) PyFloat_AS_DOUBLE (PySequence_Fast_GET_ITEM (args, 1)),
353
(float) PyFloat_AS_DOUBLE (PySequence_Fast_GET_ITEM (args, 2)));
358
static PyObject* PyP3Cal3DVolume_GetState (P3_cal3d_volume* w) {
359
P3_chunk* chunk = P3_chunk_new ();
360
PyObject* attached_states;
363
P3_cal3d_volume_get_data (w, chunk);
364
tuple = PyTuple_New (4);
365
PyTuple_SET_ITEM (tuple, 0, PyString_FromStringAndSize ((char*) chunk->content, chunk->nb));
366
if (w->shape == NULL) {
368
PyTuple_SET_ITEM (tuple, 1, Py_None);
370
PyTuple_SET_ITEM (tuple, 2, Py_None);
372
Py_INCREF ((PyObject*) w->shape);
373
PyTuple_SET_ITEM (tuple, 1, (PyObject*) w->shape);
375
attached_states = PyTuple_New (w->nb_attached_states);
376
for (i = 0; i < w->nb_attached_states; i++) {
377
PyTuple_SET_ITEM (attached_states, i, PyInt_FromLong((long) w->attached_states[i]));
379
PyTuple_SET_ITEM (tuple, 2, attached_states);
382
Py_INCREF ((PyObject*) w->attached_coordsys);
383
PyTuple_SET_ITEM (tuple, 3, (PyObject*) w->attached_coordsys);
385
P3_chunk_dealloc (chunk);
389
static PyObject* PyP3Cal3DVolume_SetState (P3_cal3d_volume* w, PyObject* args) {
390
P3_chunk* chunk = P3_chunk_new ();
391
PyObject* attached_states;
394
s = PySequence_Fast_GET_ITEM (args, 0);
395
chunk->content = PyString_AS_STRING (s);
396
P3_cal3d_volume_set_data (w, chunk);
397
s = PySequence_Fast_GET_ITEM (args, 1);
401
w->shape = (P3_cal3d_shape*) s;
402
Py_INCREF ((PyObject*) w->shape);
403
w->model = CalModel_New ();
404
CalModel_Create (w->model, w->shape->core_model);
405
attached_states = PySequence_Fast_GET_ITEM (args, 2);
406
w->nb_attached_states = PySequence_Size (attached_states);
407
w->attached_states = malloc (w->nb_attached_states * sizeof(int));
408
for (i = 0; i < w->nb_attached_states; i++) {
409
w->attached_states[i] = (int) PyInt_AS_LONG (PySequence_Fast_GET_ITEM (attached_states, i));
410
if (w->attached_states[i] == 1) {
411
CalModel_AttachMesh (w->model, i);
414
P3_cal3d_volume_build_submeshes (w);
417
w->attached_coordsys = (P3_children) PySequence_Fast_GET_ITEM (args, 3);
418
Py_INCREF ((PyObject*) w->attached_coordsys);
425
static PyObject* PyP3Cal3DVolume_BoneId (P3_cal3d_volume* w, PyObject* arg) {
428
struct CalCoreSkeleton* core_skeleton;
429
struct CalCoreBone* core_bone;
431
name = PyString_AS_STRING(arg);
432
core_skeleton = CalSkeleton_GetCoreSkeleton(CalModel_GetSkeleton(w->model));
435
core_bone = CalCoreSkeleton_GetCoreBone(core_skeleton, i);
436
if (core_bone == NULL) {
437
PyErr_SetString(PyExc_ValueError, "No bone with this name.");
440
if (strcmp(name, CalCoreBone_GetName(core_bone)) == 0) {
441
return PyInt_FromLong((long) i);
447
static PyObject* PyP3Cal3DVolume_MoveToBone (P3_cal3d_volume* w, PyObject* args) {
448
struct CalBone* bone;
449
P3_instance* instance;
452
instance = ((P3_instance*) PySequence_Fast_GET_ITEM(args, 0));
454
bone = CalSkeleton_GetBone(CalModel_GetSkeleton(w->model), (int) PyInt_AS_LONG(PySequence_Fast_GET_ITEM(args, 1)));
456
P3_matrix_from_quaternion(instance->m, CalQuaternion_Get(CalBone_GetRotationAbsolute(bone)));
458
trans = CalVector_Get(CalBone_GetTranslationAbsolute(bone));
459
P3_matrix_translate(instance->m, trans[0], trans[1], trans[2]);
465
PY_GET_SET_ON_OBJECT (Cal3DVolume, P3_cal3d_volume*, AttachedCoordsys, attached_coordsys, PyObject*)
467
PY_GET_SET_ON_FLOAT_ARRAY (Cal3DVolume, P3_cal3d_volume*, Sphere, sphere, 4)
469
static PyGetSetDef PyP3Cal3DVolume_GetSets[] = {
470
PYP3_VISIBLE_GETSETS,
472
PYP3_COORDSYS_GETSETS,
473
{ "shape", (getter) PyP3Cal3DVolume_GetShape, 0, NULL },
474
{ "attached_coordsys", (getter) PyP3Cal3DVolume_GetAttachedCoordsys, (setter) PyP3Cal3DVolume_SetAttachedCoordsys, NULL },
475
{ "sphere", (getter) PyP3Cal3DVolume_GetSphere, (setter) PyP3Cal3DVolume_SetSphere, NULL },
479
static PyMethodDef PyP3Cal3DVolume_Methods[] = {
481
{ "_set_lod_level", (PyCFunction) PyP3Cal3DVolume_SetLodLevel, METH_O },
482
{ "set_shape", (PyCFunction) PyP3Cal3DVolume_SetShape, METH_O },
483
{ "_update", (PyCFunction) PyP3Cal3DVolume_Update, METH_O },
484
{ "_set_attached", (PyCFunction) PyP3Cal3DVolume_SetAttached, METH_VARARGS },
485
{ "_is_attached", (PyCFunction) PyP3Cal3DVolume_IsAttached, METH_O },
486
{ "attach_all", (PyCFunction) PyP3Cal3DVolume_AttachAll, METH_NOARGS },
487
{ "_build_subshapes", (PyCFunction) PyP3Cal3DVolume_BuildSubshapes, METH_NOARGS },
488
{ "_animate_clear_cycle", (PyCFunction) PyP3Cal3DVolume_AnimateClearCycle, METH_VARARGS },
489
{ "_animate_blend_cycle", (PyCFunction) PyP3Cal3DVolume_AnimateBlendCycle, METH_VARARGS },
490
{ "_animate_execute_action", (PyCFunction) PyP3Cal3DVolume_AnimateExecuteAction, METH_VARARGS },
491
{ "_getstate", (PyCFunction) PyP3Cal3DVolume_GetState, METH_NOARGS },
492
{ "_setstate", (PyCFunction) PyP3Cal3DVolume_SetState, METH_O },
493
{ "_bone_id", (PyCFunction) PyP3Cal3DVolume_BoneId, METH_O },
494
{ "_move_to_bone", (PyCFunction) PyP3Cal3DVolume_MoveToBone, METH_VARARGS },
498
PyTypeObject PyP3Cal3DVolume_Type = {
499
PyObject_HEAD_INIT(NULL)
501
"_soya._Cal3DVolume",
502
sizeof(P3_cal3d_volume),
504
(destructor) PyP3Cal3DVolume_Dealloc,/* tp_dealloc */
511
0,/* tp_as_sequence */
512
0,/* tp_as_mapping */
516
PYP3_GENERIC_GETATTR,/* tp_getattro */
519
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,/* tp_flags */
521
(traverseproc) PyP3Cal3DVolume_Traverse,/* tp_traverse */
522
(inquiry) PyP3Cal3DVolume_Clear,/* tp_clear */
523
0,/* tp_richcompare */
524
0,/* tp_weaklistoffset */
527
(PyMethodDef*) &PyP3Cal3DVolume_Methods,/* tp_methods */
529
(PyGetSetDef*) &PyP3Cal3DVolume_GetSets,/* tp_getset */
534
0,/* tp_dictoffset */
535
(initproc) PyP3Cal3DVolume_Init,/* tp_init */
536
PYP3_GENERIC_ALLOC,/* tp_alloc */
537
(newfunc) PyP3Object_New,/* tp_new */
538
PYP3_GENERIC_GC_FREE,/* tp_free */