diff options
author | Erwin Coumans <blender@erwincoumans.com> | 2005-08-22 19:47:56 +0400 |
---|---|---|
committer | Erwin Coumans <blender@erwincoumans.com> | 2005-08-22 19:47:56 +0400 |
commit | 65a52fc419a990036cdf77ccb8bc724b0aefa8b5 (patch) | |
tree | 7a29645d8ae599b64fdd6419a23757e4104eaaf1 | |
parent | 838d9385226a550a0d6f06ad2dee92ec5dbb5e9a (diff) |
- prepared for automatic game physics -> animation (ipo) conversion (this allows to use bullet for animation)
- default the m_edgecode to 65535, the wireframe was invisible. when is the edgecode available again ?
- added an extra condition, nearsensor is not yet working for bullet, but it crashed.
-rw-r--r-- | source/gameengine/Converter/KX_BlenderSceneConverter.cpp | 461 | ||||
-rw-r--r-- | source/gameengine/Converter/KX_BlenderSceneConverter.h | 7 | ||||
-rw-r--r-- | source/gameengine/Converter/KX_ConvertSensors.cpp | 1 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_ISceneConverter.h | 7 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_MouseFocusSensor.h | 2 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_NearSensor.cpp | 9 | ||||
-rw-r--r-- | source/gameengine/Rasterizer/RAS_Polygon.cpp | 2 |
7 files changed, 484 insertions, 5 deletions
diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp index 8edbe5220a8..fa716981bd1 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp @@ -461,3 +461,464 @@ void KX_BlenderSceneConverter::RegisterWorldInfo( { m_worldinfos.push_back(worldinfo); } + + +void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo() +{ + //todo,before 2.38/2.40 release, Erwin +} + + ///this generates ipo curves for position, rotation, allowing to use game physics in animation +void KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber) +{ + //todo, before 2.38/2.40 release, Erwin +#ifdef TURN_THIS_PYTHON_CODE_INTO_CPP + + //all stuff needed to bake keyframes into blender objects + //this allows physics simulation of the game engine to be automatically turned into blender ipo curves + //so bullet physics can be used for animations + + + + static PyObject *Ipo_getCurve( BPy_Ipo * self, PyObject * args ) + { + char *str, *str1; + IpoCurve *icu = 0; + + if( !PyArg_ParseTuple( args, "s", &str ) ) + return ( EXPP_ReturnPyObjError + ( PyExc_TypeError, "expected string argument" ) ); + + for( icu = self->ipo->curve.first; icu; icu = icu->next ) { + str1 = getIpoCurveName( icu ); + if( !strcmp( str1, str ) ) + return IpoCurve_CreatePyObject( icu ); + } + + Py_INCREF( Py_None ); + return Py_None; + } + + static PyObject *Ipo_addCurve( BPy_Ipo * self, PyObject * args ) + { + int param = 0; /* numeric curve name constant */ + int ok = 0; + int ipofound = 0; + char *cur_name = 0; /* input arg: curve name */ + Ipo *ipo = 0; + IpoCurve *icu = 0; + Link *link; + + if( !PyArg_ParseTuple( args, "s", &cur_name ) ) + return ( EXPP_ReturnPyObjError + ( PyExc_TypeError, "expected string argument" ) ); + + + /* chase down the ipo list looking for ours */ + link = G.main->ipo.first; + + while( link ) { + ipo = ( Ipo * ) link; + if( ipo == self->ipo ) { + ipofound = 1; + break; + } + link = link->next; + } + + if( ipo && ipofound ) { + /* ok. continue */ + } else { /* runtime error here: our ipo not found */ + return ( EXPP_ReturnPyObjError + ( PyExc_RuntimeError, "Ipo not found" ) ); + } + + + /* + depending on the block type, + check if the input arg curve name is valid + and set param to numeric value. + */ + switch ( ipo->blocktype ) { + case ID_OB: + ok = Ipo_obIcuName( cur_name, ¶m ); + break; + case ID_CA: + ok = Ipo_caIcuName( cur_name, ¶m ); + break; + case ID_LA: + ok = Ipo_laIcuName( cur_name, ¶m ); + break; + case ID_TE: + ok = Ipo_texIcuName( cur_name, ¶m ); + break; + case ID_WO: + ok = Ipo_woIcuName( cur_name, ¶m ); + break; + case ID_MA: + ok = Ipo_maIcuName( cur_name, ¶m ); + break; + case ID_AC: + ok = Ipo_acIcuName( cur_name, ¶m ); + break; + case IPO_CO: + ok = Ipo_coIcuName( cur_name, ¶m ); + break; + case ID_CU: + ok = Ipo_cuIcuName( cur_name, ¶m ); + break; + case ID_KE: + ok = Ipo_keIcuName( cur_name, ¶m ); + break; + case ID_SEQ: + ok = Ipo_seqIcuName( cur_name, ¶m ); + break; + default: + ok = 0; + } + + if( !ok ) /* curve type was invalid */ + return EXPP_ReturnPyObjError + ( PyExc_NameError, "curve name was invalid" ); + + /* ask blender to create the new ipo curve */ + icu = get_ipocurve( NULL, ipo->blocktype, param, self->ipo ); + + if( icu == 0 ) /* could not create curve */ + return EXPP_ReturnPyObjError + ( PyExc_RuntimeError, + "blender could not create ipo curve" ); + + allspace( REMAKEIPO, 0 ); + EXPP_allqueue( REDRAWIPO, 0 ); + + /* create a bpy wrapper for the new ipo curve */ + return IpoCurve_CreatePyObject( icu ); + } + + static PyObject *Ipo_getNBezPoints( BPy_Ipo * self, PyObject * args ) + { + int num = 0, i = 0; + IpoCurve *icu = 0; + if( !PyArg_ParseTuple( args, "i", &num ) ) + return ( EXPP_ReturnPyObjError + ( PyExc_TypeError, "expected int argument" ) ); + icu = self->ipo->curve.first; + if( !icu ) + return ( EXPP_ReturnPyObjError + ( PyExc_TypeError, "No IPO curve" ) ); + for( i = 0; i < num; i++ ) { + if( !icu ) + return ( EXPP_ReturnPyObjError + ( PyExc_TypeError, "Bad curve number" ) ); + icu = icu->next; + + } + return ( PyInt_FromLong( icu->totvert ) ); + } + + static PyObject *Ipo_DeleteBezPoints( BPy_Ipo * self, PyObject * args ) + { + int num = 0, i = 0; + IpoCurve *icu = 0; + if( !PyArg_ParseTuple( args, "i", &num ) ) + return ( EXPP_ReturnPyObjError + ( PyExc_TypeError, "expected int argument" ) ); + icu = self->ipo->curve.first; + if( !icu ) + return ( EXPP_ReturnPyObjError + ( PyExc_TypeError, "No IPO curve" ) ); + for( i = 0; i < num; i++ ) { + if( !icu ) + return ( EXPP_ReturnPyObjError + ( PyExc_TypeError, "Bad curve number" ) ); + icu = icu->next; + + } + icu->totvert--; + return ( PyInt_FromLong( icu->totvert ) ); + } + + /*****************************************************************************/ + /* Function: M_Object_Get */ + /* Python equivalent: Blender.Object.Get */ + /*****************************************************************************/ + PyObject *M_Object_Get( PyObject * self, PyObject * args ) + { + struct Object *object; + BPy_Object *blen_object; + char *name = NULL; + + PyArg_ParseTuple( args, "|s", &name ); + + if( name != NULL ) { + object = GetObjectByName( name ); + + if( object == NULL ) { + /* No object exists with the name specified in the argument name. */ + return ( EXPP_ReturnPyObjError( PyExc_AttributeError, + "Unknown object specified." ) ); + } + blen_object = + ( BPy_Object * ) PyObject_NEW( BPy_Object, + &Object_Type ); + blen_object->object = object; + + return ( ( PyObject * ) blen_object ); + } else { + /* No argument has been given. Return a list of all objects. */ + PyObject *obj_list; + Link *link; + int index; + + obj_list = PyList_New( BLI_countlist( &( G.main->object ) ) ); + + if( obj_list == NULL ) { + return ( EXPP_ReturnPyObjError( PyExc_SystemError, + "List creation failed." ) ); + } + + link = G.main->object.first; + index = 0; + while( link ) { + object = ( Object * ) link; + blen_object = + ( BPy_Object * ) PyObject_NEW( BPy_Object, + &Object_Type ); + blen_object->object = object; + + PyList_SetItem( obj_list, index, + ( PyObject * ) blen_object ); + index++; + link = link->next; + } + return ( obj_list ); + } + } + + + static PyObject *M_Ipo_New( PyObject * self, PyObject * args ) + { + Ipo *add_ipo( char *name, int idcode ); + char *name = NULL, *code = NULL; + int idcode = -1; + BPy_Ipo *pyipo; + Ipo *blipo; + + if( !PyArg_ParseTuple( args, "ss", &code, &name ) ) + return ( EXPP_ReturnPyObjError + ( PyExc_TypeError, + "expected string string arguments" ) ); + + if( !strcmp( code, "Object" ) ) + idcode = ID_OB; + if( !strcmp( code, "Camera" ) ) + idcode = ID_CA; + if( !strcmp( code, "World" ) ) + idcode = ID_WO; + if( !strcmp( code, "Material" ) ) + idcode = ID_MA; + if( !strcmp( code, "Texture" ) ) + idcode = ID_TE; + if( !strcmp( code, "Lamp" ) ) + idcode = ID_LA; + if( !strcmp( code, "Action" ) ) + idcode = ID_AC; + if( !strcmp( code, "Constraint" ) ) + idcode = IPO_CO; + if( !strcmp( code, "Sequence" ) ) + idcode = ID_SEQ; + if( !strcmp( code, "Curve" ) ) + idcode = ID_CU; + if( !strcmp( code, "Key" ) ) + idcode = ID_KE; + + if( idcode == -1 ) + return ( EXPP_ReturnPyObjError + ( PyExc_TypeError, "Bad code" ) ); + + + blipo = add_ipo( name, idcode ); + + if( blipo ) { + /* return user count to zero because add_ipo() inc'd it */ + blipo->id.us = 0; + /* create python wrapper obj */ + pyipo = ( BPy_Ipo * ) PyObject_NEW( BPy_Ipo, &Ipo_Type ); + } else + return ( EXPP_ReturnPyObjError( PyExc_RuntimeError, + "couldn't create Ipo Data in Blender" ) ); + + if( pyipo == NULL ) + return ( EXPP_ReturnPyObjError( PyExc_MemoryError, + "couldn't create Ipo Data object" ) ); + + pyipo->ipo = blipo; + + return ( PyObject * ) pyipo; + } + + + + static PyObject *Object_setIpo( BPy_Object * self, PyObject * args ) + { + PyObject *pyipo = 0; + Ipo *ipo = NULL; + Ipo *oldipo; + + if( !PyArg_ParseTuple( args, "O!", &Ipo_Type, &pyipo ) ) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "expected Ipo as argument" ); + + ipo = Ipo_FromPyObject( pyipo ); + + if( !ipo ) + return EXPP_ReturnPyObjError( PyExc_RuntimeError, + "null ipo!" ); + + if( ipo->blocktype != ID_OB ) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "this ipo is not an object ipo" ); + + oldipo = self->object->ipo; + if( oldipo ) { + ID *id = &oldipo->id; + if( id->us > 0 ) + id->us--; + } + + ( ( ID * ) & ipo->id )->us++; + + self->object->ipo = ipo; + + Py_INCREF( Py_None ); + return Py_None; + } + + + static PyObject *M_Ipo_Get( PyObject * self, PyObject * args ) + { + char *name = NULL; + Ipo *ipo_iter; + PyObject *ipolist, *pyobj; + BPy_Ipo *wanted_ipo = NULL; + char error_msg[64]; + + if( !PyArg_ParseTuple( args, "|s", &name ) ) + return ( EXPP_ReturnPyObjError( PyExc_TypeError, + "expected string argument (or nothing)" ) ); + + ipo_iter = G.main->ipo.first; + + if( name ) { /* (name) - Search ipo by name */ + while( ( ipo_iter ) && ( wanted_ipo == NULL ) ) { + if( strcmp( name, ipo_iter->id.name + 2 ) == 0 ) { + wanted_ipo = + ( BPy_Ipo * ) PyObject_NEW( BPy_Ipo, + &Ipo_Type ); + if( wanted_ipo ) + wanted_ipo->ipo = ipo_iter; + } + ipo_iter = ipo_iter->id.next; + } + + if( wanted_ipo == NULL ) { /* Requested ipo doesn't exist */ + PyOS_snprintf( error_msg, sizeof( error_msg ), + "Ipo \"%s\" not found", name ); + return ( EXPP_ReturnPyObjError + ( PyExc_NameError, error_msg ) ); + } + + return ( PyObject * ) wanted_ipo; + } + + else { /* () - return a list with all ipos in the scene */ + int index = 0; + + ipolist = PyList_New( BLI_countlist( &( G.main->ipo ) ) ); + + if( ipolist == NULL ) + return ( EXPP_ReturnPyObjError( PyExc_MemoryError, + "couldn't create PyList" ) ); + + while( ipo_iter ) { + pyobj = Ipo_CreatePyObject( ipo_iter ); + + if( !pyobj ) + return ( EXPP_ReturnPyObjError + ( PyExc_MemoryError, + "couldn't create PyString" ) ); + + PyList_SET_ITEM( ipolist, index, pyobj ); + + ipo_iter = ipo_iter->id.next; + index++; + } + + return ( ipolist ); + } + } + + + + static PyObject *M_Ipo_Recalc( PyObject * self, PyObject * args ) + { + void testhandles_ipocurve( IpoCurve * icu ); + PyObject *a; + IpoCurve *icu; + if( !PyArg_ParseTuple( args, "O", &a ) ) + return ( EXPP_ReturnPyObjError + ( PyExc_TypeError, "expected ipo argument)" ) ); + icu = IpoCurve_FromPyObject( a ); + testhandles_ipocurve( icu ); + + Py_INCREF( Py_None ); + return Py_None; + + } + + + static PyObject *IpoCurve_addBezier( C_IpoCurve * self, PyObject * args ) + { + short MEM_freeN( void *vmemh ); + void *MEM_mallocN( unsigned int len, char *str ); + float x, y; + int npoints; + IpoCurve *icu; + BezTriple *bzt, *tmp; + static char name[10] = "mlml"; + PyObject *popo = 0; + if( !PyArg_ParseTuple( args, "O", &popo ) ) + return ( EXPP_ReturnPyObjError + ( PyExc_TypeError, "expected tuple argument" ) ); + + x = (float)PyFloat_AsDouble( PyTuple_GetItem( popo, 0 ) ); + y = (float)PyFloat_AsDouble( PyTuple_GetItem( popo, 1 ) ); + icu = self->ipocurve; + npoints = icu->totvert; + tmp = icu->bezt; + icu->bezt = MEM_mallocN( sizeof( BezTriple ) * ( npoints + 1 ), name ); + if( tmp ) { + memmove( icu->bezt, tmp, sizeof( BezTriple ) * npoints ); + MEM_freeN( tmp ); + } + memmove( icu->bezt + npoints, icu->bezt, sizeof( BezTriple ) ); + icu->totvert++; + bzt = icu->bezt + npoints; + bzt->vec[0][0] = x - 1; + bzt->vec[1][0] = x; + bzt->vec[2][0] = x + 1; + bzt->vec[0][1] = y - 1; + bzt->vec[1][1] = y; + bzt->vec[2][1] = y + 1; + /* set handle type to Auto */ + bzt->h1 = HD_AUTO; + bzt->h2 = HD_AUTO; + + Py_INCREF( Py_None ); + return Py_None; + } + +#endif +} + diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.h b/source/gameengine/Converter/KX_BlenderSceneConverter.h index c5759c84beb..d4048ce3ed2 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.h +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.h @@ -115,6 +115,13 @@ public: SCA_IController *FindGameController(struct bController *for_controller); void RegisterWorldInfo(KX_WorldInfo *worldinfo); + + virtual void ResetPhysicsObjectsAnimationIpo(); + + ///this generates ipo curves for position, rotation, allowing to use game physics in animation + virtual void WritePhysicsObjectToAnimationIpo(int frameNumber); + + }; #endif //__KX_BLENDERSCENECONVERTER_H diff --git a/source/gameengine/Converter/KX_ConvertSensors.cpp b/source/gameengine/Converter/KX_ConvertSensors.cpp index 4bd1e3d5469..eb91427f2d3 100644 --- a/source/gameengine/Converter/KX_ConvertSensors.cpp +++ b/source/gameengine/Converter/KX_ConvertSensors.cpp @@ -68,6 +68,7 @@ probably misplaced */ #include "SCA_JoystickSensor.h" #include "KX_NetworkMessageSensor.h" + #include "SCA_PropertySensor.h" #include "SCA_RandomSensor.h" #include "KX_RaySensor.h" diff --git a/source/gameengine/Ketsji/KX_ISceneConverter.h b/source/gameengine/Ketsji/KX_ISceneConverter.h index 63e73b4af53..b3422605c87 100644 --- a/source/gameengine/Ketsji/KX_ISceneConverter.h +++ b/source/gameengine/Ketsji/KX_ISceneConverter.h @@ -59,6 +59,13 @@ public: virtual void SetNewFileName(const STR_String& filename) = 0; virtual bool TryAndLoadNewFile() = 0; + + + virtual void ResetPhysicsObjectsAnimationIpo() = 0; + + ///this generates ipo curves for position, rotation, allowing to use game physics in animation + virtual void WritePhysicsObjectToAnimationIpo(int frameNumber) = 0; + }; #endif //__KX_ISCENECONVERTER_H diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.h b/source/gameengine/Ketsji/KX_MouseFocusSensor.h index 94b2fc72e6d..85ff0b83df6 100644 --- a/source/gameengine/Ketsji/KX_MouseFocusSensor.h +++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.h @@ -138,7 +138,7 @@ class KX_MouseFocusSensor : public SCA_MouseSensor * the object was hit. */ MT_Vector3 m_hitNormal; - class SCA_IObject* m_hitObject; + SCA_IObject* m_hitObject; /** diff --git a/source/gameengine/Ketsji/KX_NearSensor.cpp b/source/gameengine/Ketsji/KX_NearSensor.cpp index bd3a4fc0b37..5c6f038e23d 100644 --- a/source/gameengine/Ketsji/KX_NearSensor.cpp +++ b/source/gameengine/Ketsji/KX_NearSensor.cpp @@ -63,15 +63,18 @@ KX_NearSensor::KX_NearSensor(SCA_EventManager* eventmgr, m_ResetMargin(resetmargin) { + gameobj->getClientInfo()->m_sensors.remove(this); m_client_info = new KX_ClientObjectInfo(gameobj, KX_ClientObjectInfo::NEAR); m_client_info->m_sensors.push_back(this); //DT_ShapeHandle shape = (DT_ShapeHandle) vshape; m_physCtrl = ctrl; - m_physCtrl->SetMargin(m_Margin); - m_physCtrl->setNewClientInfo(m_client_info); - + if (m_physCtrl) + { + m_physCtrl->SetMargin(m_Margin); + m_physCtrl->setNewClientInfo(m_client_info); + } SynchronizeTransform(); } diff --git a/source/gameengine/Rasterizer/RAS_Polygon.cpp b/source/gameengine/Rasterizer/RAS_Polygon.cpp index bfd87d4e416..310c58882c9 100644 --- a/source/gameengine/Rasterizer/RAS_Polygon.cpp +++ b/source/gameengine/Rasterizer/RAS_Polygon.cpp @@ -65,7 +65,7 @@ RAS_Polygon::RAS_Polygon(RAS_MaterialBucket* bucket, :m_bucket(bucket), m_vertexindexbase(numverts), m_numverts(numverts), - m_edgecode(0) + m_edgecode(65535) { m_vertexindexbase.m_vtxarray = vtxarrayindex ;//m_bucket->FindVertexArray(numverts); m_polyFlags.Visible = visible; |