Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorJoshua Leung <aligorith@gmail.com>2009-07-02 06:53:18 +0400
committerJoshua Leung <aligorith@gmail.com>2009-07-02 06:53:18 +0400
commit78939898c735d6f2048e9fc2aa64a3188ff5732f (patch)
treeecf5e891e2fffcf421c07243bfd9fab1d887bcff /source
parent1588de008a7c9c80d193034c0f8b4dc766620a38 (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.cpp183
-rw-r--r--source/gameengine/Converter/BL_ModifierDeformer.h107
-rw-r--r--source/gameengine/Ketsji/KX_PythonSeq.cpp382
-rw-r--r--source/gameengine/Ketsji/KX_PythonSeq.h60
-rw-r--r--source/gameengine/PyDoc/API_intro.py103
-rw-r--r--source/gameengine/SceneGraph/SG_DList.h161
-rw-r--r--source/gameengine/SceneGraph/SG_QList.h157
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
+