diff options
author | Joshua Leung <aligorith@gmail.com> | 2009-07-02 06:53:18 +0400 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2009-07-02 06:53:18 +0400 |
commit | 78939898c735d6f2048e9fc2aa64a3188ff5732f (patch) | |
tree | ecf5e891e2fffcf421c07243bfd9fab1d887bcff /source | |
parent | 1588de008a7c9c80d193034c0f8b4dc766620a38 (diff) |
NLA SoC: Adding some files that seem to have been missed during some merges. Hopefully all of these should really be in the repositry...
Diffstat (limited to 'source')
-rw-r--r-- | source/gameengine/Converter/BL_ModifierDeformer.cpp | 183 | ||||
-rw-r--r-- | source/gameengine/Converter/BL_ModifierDeformer.h | 107 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_PythonSeq.cpp | 382 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_PythonSeq.h | 60 | ||||
-rw-r--r-- | source/gameengine/PyDoc/API_intro.py | 103 | ||||
-rw-r--r-- | source/gameengine/SceneGraph/SG_DList.h | 161 | ||||
-rw-r--r-- | source/gameengine/SceneGraph/SG_QList.h | 157 |
7 files changed, 1153 insertions, 0 deletions
diff --git a/source/gameengine/Converter/BL_ModifierDeformer.cpp b/source/gameengine/Converter/BL_ModifierDeformer.cpp new file mode 100644 index 00000000000..eb27820c92f --- /dev/null +++ b/source/gameengine/Converter/BL_ModifierDeformer.cpp @@ -0,0 +1,183 @@ +/** + * $Id: BL_ModifierDeformer.cpp 20741 2009-06-08 20:08:19Z blendix $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifdef WIN32 +#pragma warning (disable : 4786) +#endif //WIN32 + +#include "MEM_guardedalloc.h" +#include "BL_ModifierDeformer.h" +#include "GEN_Map.h" +#include "STR_HashedString.h" +#include "RAS_IPolygonMaterial.h" +#include "BL_SkinMeshObject.h" +#include "PHY_IGraphicController.h" + +//#include "BL_ArmatureController.h" +#include "DNA_armature_types.h" +#include "DNA_action_types.h" +#include "DNA_key_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_ipo_types.h" +#include "DNA_curve_types.h" +#include "DNA_modifier_types.h" +#include "DNA_scene_types.h" +#include "BKE_armature.h" +#include "BKE_action.h" +#include "BKE_key.h" +#include "BKE_ipo.h" +#include "MT_Point3.h" + +extern "C"{ + #include "BKE_customdata.h" + #include "BKE_DerivedMesh.h" + #include "BKE_lattice.h" + #include "BKE_modifier.h" +} + #include "BKE_utildefines.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" + +#define __NLA_DEFNORMALS +//#undef __NLA_DEFNORMALS + + +BL_ModifierDeformer::~BL_ModifierDeformer() +{ + if (m_dm) { + // deformedOnly is used as a user counter + if (--m_dm->deformedOnly == 0) { + m_dm->needsFree = 1; + m_dm->release(m_dm); + } + } +}; + +RAS_Deformer *BL_ModifierDeformer::GetReplica() +{ + BL_ModifierDeformer *result; + + result = new BL_ModifierDeformer(*this); + result->ProcessReplica(); + return result; +} + +void BL_ModifierDeformer::ProcessReplica() +{ + /* Note! - This is not inherited from PyObjectPlus */ + BL_ShapeDeformer::ProcessReplica(); + if (m_dm) + // by default try to reuse mesh, deformedOnly is used as a user count + m_dm->deformedOnly++; + // this will force an update and if the mesh cannot be reused, a new one will be created + m_lastModifierUpdate = -1; +} + +bool BL_ModifierDeformer::HasCompatibleDeformer(Object *ob) +{ + if (!ob->modifiers.first) + return false; + // soft body cannot use mesh modifiers + if ((ob->gameflag & OB_SOFT_BODY) != 0) + return false; + ModifierData* md; + for (md = (ModifierData*)ob->modifiers.first; md; md = (ModifierData*)md->next) { + if (modifier_dependsOnTime(md)) + continue; + if (!(md->mode & eModifierMode_Realtime)) + continue; + return true; + } + return false; +} + +bool BL_ModifierDeformer::Update(void) +{ + bool bShapeUpdate = BL_ShapeDeformer::Update(); + + if (bShapeUpdate || m_lastModifierUpdate != m_gameobj->GetLastFrame()) { + // static derived mesh are not updated + if (m_dm == NULL || m_bDynamic) { + /* execute the modifiers */ + Object* blendobj = m_gameobj->GetBlendObject(); + /* hack: the modifiers require that the mesh is attached to the object + It may not be the case here because of replace mesh actuator */ + Mesh *oldmesh = (Mesh*)blendobj->data; + blendobj->data = m_bmesh; + /* execute the modifiers */ + DerivedMesh *dm = mesh_create_derived_no_virtual(m_scene, blendobj, m_transverts, CD_MASK_MESH); + /* restore object data */ + blendobj->data = oldmesh; + /* free the current derived mesh and replace, (dm should never be NULL) */ + if (m_dm != NULL) { + // HACK! use deformedOnly as a user counter + if (--m_dm->deformedOnly == 0) { + m_dm->needsFree = 1; + m_dm->release(m_dm); + } + } + m_dm = dm; + // get rid of temporary data + m_dm->needsFree = 0; + m_dm->release(m_dm); + // HACK! use deformedOnly as a user counter + m_dm->deformedOnly = 1; + /* update the graphic controller */ + PHY_IGraphicController *ctrl = m_gameobj->GetGraphicController(); + if (ctrl) { + float min_r[3], max_r[3]; + INIT_MINMAX(min_r, max_r); + m_dm->getMinMax(m_dm, min_r, max_r); + ctrl->setLocalAabb(min_r, max_r); + } + } + m_lastModifierUpdate=m_gameobj->GetLastFrame(); + bShapeUpdate = true; + } + return bShapeUpdate; +} + +bool BL_ModifierDeformer::Apply(RAS_IPolyMaterial *mat) +{ + if (!Update()) + return false; + + // drawing is based on derived mesh, must set it in the mesh slots + int nmat = m_pMeshObject->NumMaterials(); + for (int imat=0; imat<nmat; imat++) { + RAS_MeshMaterial *mmat = m_pMeshObject->GetMeshMaterial(imat); + RAS_MeshSlot **slot = mmat->m_slots[(void*)m_gameobj]; + if(!slot || !*slot) + continue; + (*slot)->m_pDerivedMesh = m_dm; + } + return true; +} diff --git a/source/gameengine/Converter/BL_ModifierDeformer.h b/source/gameengine/Converter/BL_ModifierDeformer.h new file mode 100644 index 00000000000..74de54152eb --- /dev/null +++ b/source/gameengine/Converter/BL_ModifierDeformer.h @@ -0,0 +1,107 @@ +/** + * $Id: BL_ModifierDeformer.h 20741 2009-06-08 20:08:19Z blendix $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef BL_MODIFIERDEFORMER +#define BL_MODIFIERDEFORMER + +#ifdef WIN32 +#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning +#endif //WIN32 + +#include "BL_ShapeDeformer.h" +#include "BL_DeformableGameObject.h" +#include <vector> + +struct DerivedMesh; +struct Object; + +class BL_ModifierDeformer : public BL_ShapeDeformer +{ +public: + static bool HasCompatibleDeformer(Object *ob); + + + BL_ModifierDeformer(BL_DeformableGameObject *gameobj, + Scene *scene, + Object *bmeshobj, + BL_SkinMeshObject *mesh) + : + BL_ShapeDeformer(gameobj,bmeshobj, mesh), + m_lastModifierUpdate(-1), + m_scene(scene), + m_dm(NULL) + { + m_recalcNormal = false; + }; + + /* this second constructor is needed for making a mesh deformable on the fly. */ + BL_ModifierDeformer(BL_DeformableGameObject *gameobj, + struct Scene *scene, + struct Object *bmeshobj_old, + struct Object *bmeshobj_new, + class BL_SkinMeshObject *mesh, + bool release_object, + BL_ArmatureObject* arma = NULL) + : + BL_ShapeDeformer(gameobj, bmeshobj_old, bmeshobj_new, mesh, release_object, false, arma), + m_lastModifierUpdate(-1), + m_scene(scene), + m_dm(NULL) + { + }; + + virtual void ProcessReplica(); + virtual RAS_Deformer *GetReplica(); + virtual ~BL_ModifierDeformer(); + virtual bool UseVertexArray() + { + return false; + } + + bool Update (void); + bool Apply(RAS_IPolyMaterial *mat); + void ForceUpdate() + { + m_lastModifierUpdate = -1.0; + }; + virtual struct DerivedMesh* GetFinalMesh() + { + return m_dm; + } + + +protected: + double m_lastModifierUpdate; + Scene *m_scene; + DerivedMesh *m_dm; + +}; + +#endif + diff --git a/source/gameengine/Ketsji/KX_PythonSeq.cpp b/source/gameengine/Ketsji/KX_PythonSeq.cpp new file mode 100644 index 00000000000..cc8021fc2e4 --- /dev/null +++ b/source/gameengine/Ketsji/KX_PythonSeq.cpp @@ -0,0 +1,382 @@ +/** + * $Id: + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: none of this file. + * + * Contributor(s): Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + * Readonly sequence wrapper for lookups on logic bricks + */ + + +#include "KX_PythonSeq.h" +#include "KX_GameObject.h" +#include "SCA_ISensor.h" +#include "SCA_IController.h" +#include "SCA_IActuator.h" + + +PyObject *KX_PythonSeq_CreatePyObject( PyObject *base, short type ) +{ + KX_PythonSeq *seq = PyObject_NEW( KX_PythonSeq, &KX_PythonSeq_Type); + seq->base = base; + Py_INCREF(base); /* so we can always access to check if its valid */ + seq->type = type; + seq->iter = -1; /* init */ + return (PyObject *)seq; + } + + static void KX_PythonSeq_dealloc( KX_PythonSeq * self ) +{ + Py_DECREF(self->base); + PyObject_DEL( self ); +} + +static Py_ssize_t KX_PythonSeq_len( PyObject * self ) +{ + PyObjectPlus *self_plus= BGE_PROXY_REF(((KX_PythonSeq *)self)->base); + + if(self_plus==NULL) { + PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); + return -1; + } + + switch(((KX_PythonSeq *)self)->type) { + case KX_PYGENSEQ_CONT_TYPE_SENSORS: + return ((SCA_IController *)self_plus)->GetLinkedSensors().size(); + case KX_PYGENSEQ_CONT_TYPE_ACTUATORS: + return ((SCA_IController *)self_plus)->GetLinkedActuators().size(); + case KX_PYGENSEQ_OB_TYPE_SENSORS: + return ((KX_GameObject *)self_plus)->GetSensors().size(); + case KX_PYGENSEQ_OB_TYPE_CONTROLLERS: + return ((KX_GameObject *)self_plus)->GetControllers().size(); + case KX_PYGENSEQ_OB_TYPE_ACTUATORS: + return ((KX_GameObject *)self_plus)->GetActuators().size(); + default: + /* Should never happen */ + PyErr_SetString(PyExc_SystemError, "invalid type, internal error"); + return -1; + } +} + +static PyObject *KX_PythonSeq_getIndex(PyObject* self, int index) +{ + PyObjectPlus *self_plus= BGE_PROXY_REF(((KX_PythonSeq *)self)->base); + + if(self_plus==NULL) { + PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); + return NULL; + } + + switch(((KX_PythonSeq *)self)->type) { + case KX_PYGENSEQ_CONT_TYPE_SENSORS: + { + vector<SCA_ISensor*>& linkedsensors = ((SCA_IController *)self_plus)->GetLinkedSensors(); + if(index<0) index += linkedsensors.size(); + if(index<0 || index>= linkedsensors.size()) { + PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range"); + return NULL; + } + return linkedsensors[index]->GetProxy(); + } + case KX_PYGENSEQ_CONT_TYPE_ACTUATORS: + { + vector<SCA_IActuator*>& linkedactuators = ((SCA_IController *)self_plus)->GetLinkedActuators(); + if(index<0) index += linkedactuators.size(); + if(index<0 || index>= linkedactuators.size()) { + PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range"); + return NULL; + } + return linkedactuators[index]->GetProxy(); + } + case KX_PYGENSEQ_OB_TYPE_SENSORS: + { + SCA_SensorList& linkedsensors= ((KX_GameObject *)self_plus)->GetSensors(); + if(index<0) index += linkedsensors.size(); + if(index<0 || index>= linkedsensors.size()) { + PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range"); + return NULL; + } + return linkedsensors[index]->GetProxy(); + } + case KX_PYGENSEQ_OB_TYPE_CONTROLLERS: + { + SCA_ControllerList& linkedcontrollers= ((KX_GameObject *)self_plus)->GetControllers(); + if(index<0) index += linkedcontrollers.size(); + if(index<0 || index>= linkedcontrollers.size()) { + PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range"); + return NULL; + } + return linkedcontrollers[index]->GetProxy(); + } + case KX_PYGENSEQ_OB_TYPE_ACTUATORS: + { + SCA_ActuatorList& linkedactuators= ((KX_GameObject *)self_plus)->GetActuators(); + if(index<0) index += linkedactuators.size(); + if(index<0 || index>= linkedactuators.size()) { + PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range"); + return NULL; + } + return linkedactuators[index]->GetProxy(); + } + } + + PyErr_SetString(PyExc_SystemError, "invalid sequence type, this is a bug"); + return NULL; +} + + +static PyObject * KX_PythonSeq_subscript(PyObject * self, PyObject *key) +{ + PyObjectPlus *self_plus= BGE_PROXY_REF(((KX_PythonSeq *)self)->base); + char *name = NULL; + + if(self_plus==NULL) { + PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); + return NULL; + } + + if (PyInt_Check(key)) { + return KX_PythonSeq_getIndex(self, PyInt_AS_LONG( key )); + } else if ( PyString_Check(key) ) { + name = PyString_AsString( key ); + } else { + PyErr_SetString( PyExc_TypeError, "expected a string or an index" ); + return NULL; + } + + switch(((KX_PythonSeq *)self)->type) { + case KX_PYGENSEQ_CONT_TYPE_SENSORS: + { + vector<SCA_ISensor*>& linkedsensors = ((SCA_IController *)self_plus)->GetLinkedSensors(); + SCA_ISensor* sensor; + for (unsigned int index=0;index<linkedsensors.size();index++) { + sensor = linkedsensors[index]; + if (sensor->GetName() == name) + return sensor->GetProxy(); + } + break; + } + case KX_PYGENSEQ_CONT_TYPE_ACTUATORS: + { + vector<SCA_IActuator*>& linkedactuators = ((SCA_IController *)self_plus)->GetLinkedActuators(); + SCA_IActuator* actuator; + for (unsigned int index=0;index<linkedactuators.size();index++) { + actuator = linkedactuators[index]; + if (actuator->GetName() == name) + return actuator->GetProxy(); + } + break; + } + case KX_PYGENSEQ_OB_TYPE_SENSORS: + { + SCA_SensorList& linkedsensors= ((KX_GameObject *)self_plus)->GetSensors(); + SCA_ISensor *sensor; + for (unsigned int index=0;index<linkedsensors.size();index++) { + sensor= linkedsensors[index]; + if (sensor->GetName() == name) + return sensor->GetProxy(); + } + break; + } + case KX_PYGENSEQ_OB_TYPE_CONTROLLERS: + { + SCA_ControllerList& linkedcontrollers= ((KX_GameObject *)self_plus)->GetControllers(); + SCA_IController *controller; + for (unsigned int index=0;index<linkedcontrollers.size();index++) { + controller= linkedcontrollers[index]; + if (controller->GetName() == name) + return controller->GetProxy(); + } + break; + } + case KX_PYGENSEQ_OB_TYPE_ACTUATORS: + { + SCA_ActuatorList& linkedactuators= ((KX_GameObject *)self_plus)->GetActuators(); + SCA_IActuator *actuator; + for (unsigned int index=0;index<linkedactuators.size();index++) { + actuator= linkedactuators[index]; + if (actuator->GetName() == name) + return actuator->GetProxy(); + } + break; + } + } + + PyErr_Format( PyExc_KeyError, "requested item \"%s\" does not exist", name); + return NULL; +} + +static PyMappingMethods KX_PythonSeq_as_mapping = { + KX_PythonSeq_len, /* mp_length */ + KX_PythonSeq_subscript, /* mp_subscript */ + 0, /* mp_ass_subscript */ +}; + + +/* + * Initialize the interator index + */ + +static PyObject *KX_PythonSeq_getIter(KX_PythonSeq *self) +{ + if(BGE_PROXY_REF(self->base)==NULL) { + PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); + return NULL; + } + + /* create a new iterator if were alredy using this one */ + if (self->iter == -1) { + self->iter = 0; + Py_INCREF(self); + return (PyObject *)self; + } else { + return KX_PythonSeq_CreatePyObject(self->base, self->type); + } + } + + +/* + * Return next KX_PythonSeq iter. + */ + +static PyObject *KX_PythonSeq_nextIter(KX_PythonSeq *self) +{ + PyObject *object = KX_PythonSeq_getIndex((PyObject *)self, self->iter); + + self->iter++; + if( object==NULL ) { + self->iter= -1; /* for reuse */ + PyErr_SetString(PyExc_StopIteration, "iterator at end"); + } + return object; /* can be NULL for end of iterator */ +} + + +static int KX_PythonSeq_compare( KX_PythonSeq * a, KX_PythonSeq * b ) /* TODO - python3.x wants richcmp */ +{ + return ( a->type == b->type && a->base == b->base) ? 0 : -1; +} + +/* + * repr function + * convert to a list and get its string value + */ +static PyObject *KX_PythonSeq_repr( KX_PythonSeq * self ) +{ + PyObject *list = PySequence_List((PyObject *)self); + PyObject *repr = PyObject_Repr(list); + Py_DECREF(list); + return repr; +} + + +/*****************************************************************************/ +/* Python KX_PythonSeq_Type structure definition: */ +/*****************************************************************************/ +PyTypeObject KX_PythonSeq_Type = { +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif + /* For printing, in format "<module>.<name>" */ + "KX_PythonSeq", /* char *tp_name; */ + sizeof( KX_PythonSeq ), /* int tp_basicsize; */ + 0, /* tp_itemsize; For allocation */ + + /* Methods to implement standard operations */ + + ( destructor ) KX_PythonSeq_dealloc, /* destructor tp_dealloc; */ + NULL, /* printfunc tp_print; */ + NULL, /* getattrfunc tp_getattr; */ + NULL, /* setattrfunc tp_setattr; */ + ( cmpfunc ) KX_PythonSeq_compare, /* cmpfunc tp_compare; */ + ( reprfunc ) KX_PythonSeq_repr, /* reprfunc tp_repr; */ + + /* Method suites for standard classes */ + + NULL, /* PyNumberMethods *tp_as_number; */ + NULL, /* PySequenceMethods *tp_as_sequence; */ + &KX_PythonSeq_as_mapping, /* PyMappingMethods *tp_as_mapping; */ + + /* More standard operations (here for binary compatibility) */ + + NULL, /* hashfunc tp_hash; */ + NULL, /* ternaryfunc tp_call; */ + NULL, /* reprfunc tp_str; */ + NULL, /* getattrofunc tp_getattro; */ + NULL, /* setattrofunc tp_setattro; */ + + /* Functions to access object as input/output buffer */ + NULL, /* PyBufferProcs *tp_as_buffer; */ + + /*** Flags to define presence of optional/expanded features ***/ + Py_TPFLAGS_DEFAULT, /* long tp_flags; */ + + NULL, /* char *tp_doc; Documentation string */ + /*** Assigned meaning in release 2.0 ***/ + /* call function for all accessible objects */ + NULL, /* traverseproc tp_traverse; */ + + /* delete references to contained objects */ + NULL, /* inquiry tp_clear; */ + + /*** Assigned meaning in release 2.1 ***/ + /*** rich comparisons ***/ + NULL, /* richcmpfunc tp_richcompare; */ + + /*** weak reference enabler ***/ + 0, /* long tp_weaklistoffset; */ + + /*** Added in release 2.2 ***/ + /* Iterators */ + ( getiterfunc) KX_PythonSeq_getIter, /* getiterfunc tp_iter; */ + ( iternextfunc ) KX_PythonSeq_nextIter, /* iternextfunc tp_iternext; */ + + /*** Attribute descriptor and subclassing stuff ***/ + NULL, /* struct PyMethodDef *tp_methods; */ + NULL, /* struct PyMemberDef *tp_members; */ + NULL, /* struct PyGetSetDef *tp_getset; */ + NULL, /* struct _typeobject *tp_base; */ + NULL, /* PyObject *tp_dict; */ + NULL, /* descrgetfunc tp_descr_get; */ + NULL, /* descrsetfunc tp_descr_set; */ + 0, /* long tp_dictoffset; */ + NULL, /* initproc tp_init; */ + NULL, /* allocfunc tp_alloc; */ + NULL, /* newfunc tp_new; */ + /* Low-level free-memory routine */ + NULL, /* freefunc tp_free; */ + /* For PyObject_IS_GC */ + NULL, /* inquiry tp_is_gc; */ + NULL, /* PyObject *tp_bases; */ + /* method resolution order */ + NULL, /* PyObject *tp_mro; */ + NULL, /* PyObject *tp_cache; */ + NULL, /* PyObject *tp_subclasses; */ + NULL, /* PyObject *tp_weaklist; */ + NULL +}; diff --git a/source/gameengine/Ketsji/KX_PythonSeq.h b/source/gameengine/Ketsji/KX_PythonSeq.h new file mode 100644 index 00000000000..15a016224a9 --- /dev/null +++ b/source/gameengine/Ketsji/KX_PythonSeq.h @@ -0,0 +1,60 @@ +/** + * $Id: + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + * Readonly sequence wrapper for lookups on logic bricks + */ + +#ifndef _adr_py_seq_h_ // only process once, +#define _adr_py_seq_h_ // even if multiply included + +#include "PyObjectPlus.h" + +// ------------------------- +enum KX_PYGENSEQ_TYPE { + KX_PYGENSEQ_CONT_TYPE_SENSORS, + KX_PYGENSEQ_CONT_TYPE_ACTUATORS, + KX_PYGENSEQ_OB_TYPE_SENSORS, + KX_PYGENSEQ_OB_TYPE_CONTROLLERS, + KX_PYGENSEQ_OB_TYPE_ACTUATORS +}; + +/* The Main PyType Object defined in Main.c */ +extern PyTypeObject KX_PythonSeq_Type; + +#define BPy_KX_PythonSeq_Check(v) \ + ((v)->ob_type == &KX_PythonSeq_Type) + +typedef struct { + PyObject_VAR_HEAD + PyObject *base; + short type; + short iter; +} KX_PythonSeq; + +PyObject *KX_PythonSeq_CreatePyObject(PyObject *base, short type); + +#endif // _adr_py_seq_h_ diff --git a/source/gameengine/PyDoc/API_intro.py b/source/gameengine/PyDoc/API_intro.py new file mode 100644 index 00000000000..ad37e34fbac --- /dev/null +++ b/source/gameengine/PyDoc/API_intro.py @@ -0,0 +1,103 @@ +# This is not a real module, it's simply an introductory text. + +""" +The Blender Game Engine Python API Reference +============================================ + + See U{release notes<http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.49/Game_Engine>} for updates, changes and new functionality in the Game Engine Python API. + + Top Module: + ----------- + + - L{GameLogic} + - L{GameKeys} + - L{GameTypes} + - L{Mathutils} + - L{Geometry} + - L{BGL} + + Undocumented modules: + --------------------- + - VideoTexture + - CValue + - Expression + - PhysicsConstraints + + +Introduction: +============= + + This reference documents the Blender Python API, a growing collection of + Python modules (libraries) that give access to part of the program's internal + data and functions. + + Through scripting Blender can be extended in real-time via + U{Python <www.python.org>}, an impressive high level, multi-paradigm, open + source language. Newcomers are recommended to start with the tutorial that + comes with it. + + This opens many interesting possibilities not available with logic bricks. + + Game Engine API Stability: + -------------------------- + + When writing python scripts there are a number of situations you should avoid to prevent crashes or unstable behavior. + While the API tries to prevent problems there are some situations where error checking would be too time consuming. + + Known cases: + - Memory Limits. + + There is nothing stopping you from filling a list or making a string so big that that causes blender to run out of memory, in this case python should rasie a MemoryError, but its likely blender will crash before this point. + + - Accessing any data that has been freed. + + For instance accessing a KX_GameObject after its End Object actuator runs. + This will cause a SystemError, however for L{KX_MeshProxy}, L{KX_VertexProxy} and L{KX_VertexProxy} it will crash the blender game engine. + + See: L{GameTypes.PyObjectPlus.invalid} which many types inherit. + + - Mixing L{KX_GameObject} between scenes. + + For instance tracking/parenting an L{KX_GameObject} object to an object from other scene. + + External Modules: + ----------------- + + Since 2.49 support for importing modules has been added. + + This allows you to import any blender textblock with a .py extension. + + External python scripts may be imported as modules when the script is in the same directory as the blend file. + + The current blend files path is included in the sys.path for loading modules. + All linked libraries will also be included so you can be sure when linking in assets from another blend file the scripts will load too. + + A note to newbie script writers: + -------------------------------- + + Interpreted languages are known to be much slower than compiled code, but for + many applications the difference is negligible or acceptable. Also, with + profiling (or even simple direct timing with L{Blender.sys.time<Sys.time>}) to + identify slow areas and well thought optimizations, the speed can be + I{considerably} improved in many cases. Try some of the best BPython scripts + to get an idea of what can be done, you may be surprised. + +@author: The Blender Python Team +@requires: Blender 2.49 or newer. +@version: 2.49 +@see: U{www.blender.org<http://www.blender.org>}: documentation and forum +@see: U{blenderartists.org<http://blenderartists.org>}: user forum +@see: U{projects.blender.org<http://projects.blender.org>} +@see: U{www.python.org<http://www.python.org>} +@see: U{www.python.org/doc<http://www.python.org/doc>} +@see: U{Blending into Python<en.wikibooks.org/wiki/Blender_3D:_Blending_Into_Python>}: User contributed documentation, featuring a blender/python cookbook with many examples. + +@note: the official version of this reference guide is only updated for each + new Blender release. But you can build the current SVN + version yourself: install epydoc, grab all files in the + source/gameengine/PyDoc/ folder of Blender's SVN and use the + epy_docgen.sh script also found there to generate the html docs. + Naturally you will also need a recent Blender binary to try the new + features. If you prefer not to compile it yourself, there is a testing + builds forum at U{blender.org<http://www.blender.org>}. +""" diff --git a/source/gameengine/SceneGraph/SG_DList.h b/source/gameengine/SceneGraph/SG_DList.h new file mode 100644 index 00000000000..eea19a85c7a --- /dev/null +++ b/source/gameengine/SceneGraph/SG_DList.h @@ -0,0 +1,161 @@ +/** + * $Id: SG_DList.h 20741 2009-06-08 20:08:19Z blendix $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#ifndef __SG_DLIST +#define __SG_DLIST + +#include <stdlib.h> + +/** + * Double circular linked list + */ +class SG_DList +{ +protected : + SG_DList* m_flink; + SG_DList* m_blink; + +public: + template<typename T> class iterator + { + private: + SG_DList& m_head; + T* m_current; + public: + typedef iterator<T> _myT; + iterator(SG_DList& head) : m_head(head), m_current(NULL) {} + ~iterator() {} + + void begin() + { + m_current = (T*)m_head.Peek(); + } + void back() + { + m_current = (T*)m_head.Back(); + } + bool end() + { + return (m_current == (T*)m_head.Self()); + } + bool add_back(T* item) + { + return m_current->AddBack(item); + } + T* operator*() + { + return m_current; + } + _myT& operator++() + { + // no check of NULL! make sure you don't try to increment beyond end + m_current = (T*)m_current->Peek(); + return *this; + } + _myT& operator--() + { + // no check of NULL! make sure you don't try to increment beyond end + m_current = (T*)m_current->Back(); + return *this; + } + }; + + SG_DList() + { + m_flink = m_blink = this; + } + SG_DList(const SG_DList& other) + { + m_flink = m_blink = this; + } + virtual ~SG_DList() + { + Delink(); + } + + inline bool Empty() // Check for empty queue + { + return ( m_flink == this ); + } + bool AddBack( SG_DList *item ) // Add to the back + { + if (!item->Empty()) + return false; + item->m_blink = m_blink; + item->m_flink = this; + m_blink->m_flink = item; + m_blink = item; + return true; + } + bool AddFront( SG_DList *item ) // Add to the back + { + if (!item->Empty()) + return false; + item->m_flink = m_flink; + item->m_blink = this; + m_flink->m_blink = item; + m_flink = item; + return true; + } + SG_DList *Remove() // Remove from the front + { + if (Empty()) + { + return NULL; + } + SG_DList* item = m_flink; + m_flink = item->m_flink; + m_flink->m_blink = this; + item->m_flink = item->m_blink = item; + return item; + } + bool Delink() // Remove from the middle + { + if (Empty()) + return false; + m_blink->m_flink = m_flink; + m_flink->m_blink = m_blink; + m_flink = m_blink = this; + return true; + } + inline SG_DList *Peek() // Look at front without removing + { + return m_flink; + } + inline SG_DList *Back() // Look at front without removing + { + return m_blink; + } + inline SG_DList *Self() + { + return this; + } +}; + +#endif //__SG_DLIST + diff --git a/source/gameengine/SceneGraph/SG_QList.h b/source/gameengine/SceneGraph/SG_QList.h new file mode 100644 index 00000000000..6656f5a45c8 --- /dev/null +++ b/source/gameengine/SceneGraph/SG_QList.h @@ -0,0 +1,157 @@ +/** + * $Id: SG_QList.h 20741 2009-06-08 20:08:19Z blendix $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#ifndef __SG_QLIST +#define __SG_QLIST + +#include "SG_DList.h" + +/** + * Double-Double circular linked list + * For storing an object is two lists simultaneously + */ +class SG_QList : public SG_DList +{ +protected : + SG_QList* m_fqlink; + SG_QList* m_bqlink; + +public: + template<typename T> class iterator + { + private: + SG_QList& m_head; + T* m_current; + public: + typedef iterator<T> _myT; + iterator(SG_QList& head, SG_QList* current=NULL) : m_head(head) { m_current = (T*)current; } + ~iterator() {} + + void begin() + { + m_current = (T*)m_head.QPeek(); + } + void back() + { + m_current = (T*)m_head.QBack(); + } + bool end() + { + return (m_current == (T*)m_head.Self()); + } + bool add_back(T* item) + { + return m_current->QAddBack(item); + } + T* operator*() + { + return m_current; + } + _myT& operator++() + { + m_current = (T*)m_current->QPeek(); + return *this; + } + _myT& operator--() + { + // no check on NULL! make sure you don't try to increment beyond end + m_current = (T*)m_current->QBack(); + return *this; + } + }; + + SG_QList() : SG_DList() + { + m_fqlink = m_bqlink = this; + } + SG_QList(const SG_QList& other) : SG_DList() + { + m_fqlink = m_bqlink = this; + } + virtual ~SG_QList() + { + QDelink(); + } + + inline bool QEmpty() // Check for empty queue + { + return ( m_fqlink == this ); + } + bool QAddBack( SG_QList *item ) // Add to the back + { + if (!item->QEmpty()) + return false; + item->m_bqlink = m_bqlink; + item->m_fqlink = this; + m_bqlink->m_fqlink = item; + m_bqlink = item; + return true; + } + bool QAddFront( SG_QList *item ) // Add to the back + { + if (!item->Empty()) + return false; + item->m_fqlink = m_fqlink; + item->m_bqlink = this; + m_fqlink->m_bqlink = item; + m_fqlink = item; + return true; + } + SG_QList *QRemove() // Remove from the front + { + if (QEmpty()) + { + return NULL; + } + SG_QList* item = m_fqlink; + m_fqlink = item->m_fqlink; + m_fqlink->m_bqlink = this; + item->m_fqlink = item->m_bqlink = item; + return item; + } + bool QDelink() // Remove from the middle + { + if (QEmpty()) + return false; + m_bqlink->m_fqlink = m_fqlink; + m_fqlink->m_bqlink = m_bqlink; + m_fqlink = m_bqlink = this; + return true; + } + inline SG_QList *QPeek() // Look at front without removing + { + return m_fqlink; + } + inline SG_QList *QBack() // Look at front without removing + { + return m_bqlink; + } +}; + +#endif //__SG_QLIST + |