diff options
author | Campbell Barton <ideasman42@gmail.com> | 2008-06-25 20:25:01 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2008-06-25 20:25:01 +0400 |
commit | 3282d8562719bde5b8be351123135dd5ced250a5 (patch) | |
tree | 9c9b290e1a1b913f85654125e15092ef422ea965 /source | |
parent | cf8807581eae39e44ceb33158df8916a2afb2eb6 (diff) |
svn merge -r15339:HEAD https://svn.blender.org/svnroot/bf-blender/trunk/blender/
Diffstat (limited to 'source')
27 files changed, 666 insertions, 75 deletions
diff --git a/source/blender/blenkernel/BKE_ipo.h b/source/blender/blenkernel/BKE_ipo.h index 922f3201345..5b209cb8f5b 100644 --- a/source/blender/blenkernel/BKE_ipo.h +++ b/source/blender/blenkernel/BKE_ipo.h @@ -31,6 +31,10 @@ #ifndef BKE_IPO_H #define BKE_IPO_H +#ifdef __cplusplus +extern "C" { +#endif + typedef struct CfraElem { struct CfraElem *next, *prev; float cfra; @@ -111,5 +115,9 @@ float IPO_GetFloatValue(struct Ipo *ipo, short c, float ctime); +#ifdef __cplusplus +}; +#endif + #endif diff --git a/source/blender/makesdna/DNA_actuator_types.h b/source/blender/makesdna/DNA_actuator_types.h index 70d603a6ed9..20316f26804 100644 --- a/source/blender/makesdna/DNA_actuator_types.h +++ b/source/blender/makesdna/DNA_actuator_types.h @@ -81,7 +81,7 @@ typedef struct bEditObjectActuator { char name[32]; float linVelocity[3]; /* initial lin. velocity on creation */ short localflag; /* flag for the lin. vel: apply locally */ - short pad; + short dyn_operation; } bEditObjectActuator; typedef struct bSceneActuator { @@ -98,7 +98,8 @@ typedef struct bPropertyActuator { } bPropertyActuator; typedef struct bObjectActuator { - int flag, type; + short flag, type; + int damping; float forceloc[3], forcerot[3]; float loc[3], rot[3]; float dloc[3], drot[3]; @@ -252,6 +253,7 @@ typedef struct FreeCamera { #define ACT_ANG_VEL_LOCAL 32 //#define ACT_ADD_LIN_VEL_LOCAL 64 #define ACT_ADD_LIN_VEL 64 +#define ACT_CLAMP_VEL 128 #define ACT_OBJECT_FORCE 0 #define ACT_OBJECT_TORQUE 1 @@ -358,10 +360,11 @@ typedef struct FreeCamera { /* editObjectActuator->type */ #define ACT_EDOB_ADD_OBJECT 0 #define ACT_EDOB_END_OBJECT 1 -#define ACT_EDOB_REPLACE_MESH 2 +#define ACT_EDOB_REPLACE_MESH 2 #define ACT_EDOB_TRACK_TO 3 -#define ACT_EDOB_MAKE_CHILD 4 -#define ACT_EDOB_END_CHILD 5 +#define ACT_EDOB_DYNAMICS 4 + + /* editObjectActuator->flag */ #define ACT_TRACK_3D 1 diff --git a/source/blender/python/api2_2x/CurNurb.c b/source/blender/python/api2_2x/CurNurb.c index 174b5fb08dc..b2120bd63c6 100644 --- a/source/blender/python/api2_2x/CurNurb.c +++ b/source/blender/python/api2_2x/CurNurb.c @@ -53,6 +53,8 @@ static int CurNurb_setFlagU( BPy_CurNurb * self, PyObject * args ); static PyObject *CurNurb_getFlagV( BPy_CurNurb * self ); static PyObject *CurNurb_oldsetFlagV( BPy_CurNurb * self, PyObject * args ); static int CurNurb_setFlagV( BPy_CurNurb * self, PyObject * args ); +static PyObject *CurNurb_getOrderU( BPy_CurNurb * self ); +static int CurNurb_setOrderU( BPy_CurNurb * self, PyObject * args ); static PyObject *CurNurb_getType( BPy_CurNurb * self ); static PyObject *CurNurb_oldsetType( BPy_CurNurb * self, PyObject * args ); static int CurNurb_setType( BPy_CurNurb * self, PyObject * args ); @@ -176,6 +178,9 @@ static PyGetSetDef BPy_CurNurb_getseters[] = { (getter)CurNurb_getFlagV, (setter)CurNurb_setFlagV, "The knot type in the V direction", NULL}, + {"orderU", + (getter)CurNurb_getOrderU, (setter)CurNurb_setOrderU, + "order setting for U direction", NULL}, {"type", (getter)CurNurb_getType, (setter)CurNurb_setType, "The curve type (poly: bezier, or NURBS)", @@ -710,6 +715,35 @@ static int CurNurb_setFlagV( BPy_CurNurb * self, PyObject * args ) return 0; } +static PyObject *CurNurb_getOrderU( BPy_CurNurb * self ) +{ + return PyInt_FromLong( ( long ) self->nurb->orderu ); +} + +static int CurNurb_setOrderU( BPy_CurNurb * self, PyObject * args ) +{ + int order; + + args = PyNumber_Int( args ); + if( !args ) + return EXPP_ReturnIntError( PyExc_TypeError, + "expected integer argument" ); + + order = ( int )PyInt_AS_LONG( args ); + Py_DECREF( args ); + + if( order < 2 ) order = 2; + else if( order > 6 ) order = 6; + + if( self->nurb->pntsu < order ) + order = self->nurb->pntsu; + + self->nurb->orderu = (short)order; + makeknots( self->nurb, 1, self->nurb->flagu >> 1 ); + + return 0; +} + /* * CurNurb_getIter * diff --git a/source/blender/python/api2_2x/doc/Curve.py b/source/blender/python/api2_2x/doc/Curve.py index ba8d6d21970..765921665cd 100644 --- a/source/blender/python/api2_2x/doc/Curve.py +++ b/source/blender/python/api2_2x/doc/Curve.py @@ -535,6 +535,8 @@ class CurNurb: @type flagU: int @ivar flagV: The CurNurb knot flag V. See L{setFlagU} for description. @type flagV: int + @ivar orderU: The CurNurb knot order U, for nurbs curves only, this is clamped by the number of points, so the orderU will never be greater. + @type orderU: int @ivar type: The type of the curve (Poly: 0, Bezier: 1, NURBS: 4) @type type: int @ivar knotsU: The knot vector in the U direction. The tuple will be empty diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 048b25ed822..702754c1bfe 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -6221,7 +6221,7 @@ static void editing_panel_mesh_texface(void) uiDefButBitS(block, TOG, TF_TILES, B_REDR_3D_IMA, "Tiles", 660,160,60,19, &tf->mode, 0, 0, 0, 0, "Use tilemode for face"); uiDefButBitS(block, TOG, TF_LIGHT, REDRAWVIEW3D, "Light", 720,160,60,19, &tf->mode, 0, 0, 0, 0, "Use light for face"); uiDefButBitS(block, TOG, TF_INVISIBLE, REDRAWVIEW3D, "Invisible",780,160,60,19, &tf->mode, 0, 0, 0, 0, "Make face invisible"); - uiDefButBitS(block, TOG, TF_DYNAMIC, REDRAWVIEW3D, "Collision", 840,160,60,19, &tf->mode, 0, 0, 0, 0, "Use face for collision detection"); + uiDefButBitS(block, TOG, TF_DYNAMIC, REDRAWVIEW3D, "Collision", 840,160,60,19, &tf->mode, 0, 0, 0, 0, "Use face for collision and ray-sensor detection"); uiBlockBeginAlign(block); uiDefButBitS(block, TOG, TF_SHAREDCOL, REDRAWVIEW3D, "Shared", 600,135,60,19, &tf->mode, 0, 0, 0, 0, "Blend vertex colors across face when vertices are shared"); diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c index bfa451428c3..297cde844d3 100644 --- a/source/blender/src/buttons_logic.c +++ b/source/blender/src/buttons_logic.c @@ -1602,7 +1602,7 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh float *fp; short ysize = 0, wval; - char *str, name[32]; + char *str; int myline, stbit; /* yco is at the top of the rect, draw downwards */ @@ -1613,7 +1613,7 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh { case ACT_OBJECT: { - ysize= 129; + ysize= 152; glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); @@ -1651,14 +1651,18 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh uiDefButF(block, NUM, 0, "", xco+45+wval, yco-125, wval, 19, oa->angularvelocity+1, -10000.0, 10000.0, 10, 0, ""); uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-125, wval, 19, oa->angularvelocity+2, -10000.0, 10000.0, 10, 0, ""); - uiDefButBitI(block, TOG, ACT_FORCE_LOCAL, 0, "L", xco+45+3*wval, yco-22, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); - uiDefButBitI(block, TOG, ACT_TORQUE_LOCAL, 0, "L", xco+45+3*wval, yco-41, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); - uiDefButBitI(block, TOG, ACT_DLOC_LOCAL, 0, "L", xco+45+3*wval, yco-64, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); - uiDefButBitI(block, TOG, ACT_DROT_LOCAL, 0, "L", xco+45+3*wval, yco-83, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); - uiDefButBitI(block, TOG, ACT_LIN_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-106, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); - uiDefButBitI(block, TOG, ACT_ANG_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-125, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); + uiDefBut(block, LABEL, 0, "damp", xco, yco-148, 45, 19, NULL, 0, 0, 0, 0, "Number of frames to reach the target velocity"); + uiDefButI(block, NUM, 0, "", xco+45, yco-148, wval, 19, &oa->damping, 0.0, 1000.0, 100, 0, ""); + uiDefButBitS(block, TOG, ACT_CLAMP_VEL, 0, "clamp",xco+45+wval, yco-148, wval, 19, &oa->flag, 0.0, 0.0, 0, 0, "Toggles between SET and CLAMP Velocity"); + + uiDefButBitS(block, TOG, ACT_FORCE_LOCAL, 0, "L", xco+45+3*wval, yco-22, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); + uiDefButBitS(block, TOG, ACT_TORQUE_LOCAL, 0, "L", xco+45+3*wval, yco-41, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); + uiDefButBitS(block, TOG, ACT_DLOC_LOCAL, 0, "L", xco+45+3*wval, yco-64, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); + uiDefButBitS(block, TOG, ACT_DROT_LOCAL, 0, "L", xco+45+3*wval, yco-83, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); + uiDefButBitS(block, TOG, ACT_LIN_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-106, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); + uiDefButBitS(block, TOG, ACT_ANG_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-125, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); - uiDefButBitI(block, TOG, ACT_ADD_LIN_VEL, 0, "add",xco+45+3*wval+15, yco-106, 35, 19, &oa->flag, 0.0, 0.0, 0, 0, "Toggles between ADD and SET linV"); + uiDefButBitS(block, TOG, ACT_ADD_LIN_VEL, 0, "add",xco+45+3*wval+15, yco-106, 35, 19, &oa->flag, 0.0, 0.0, 0, 0, "Toggles between ADD and SET linV"); yco-= ysize; break; @@ -1936,8 +1940,15 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh uiDefButI(block, NUM, 0, "Time:", xco+10+(width-20)/2, yco-44, (width-20)/2-40, 19, &eoa->time, 0.0, 2000.0, 0, 0, "Duration the tracking takes"); uiDefButS(block, TOG, 0, "3D", xco+width-50, yco-44, 40, 19, &eoa->flag, 0.0, 0.0, 0, 0, "Enable 3D tracking"); } - - str= "Edit Object %t|Add Object %x0|End Object %x1|Replace Mesh %x2|Track to %x3"; + else if(eoa->type==ACT_EDOB_DYNAMICS) { + ysize= 48; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + str= "Dynamic Operation %t|Restore Dynamics %x0|Suspend Dynamics %x1|Enable Rigid Body %x2|Disable Rigid Body %x3"; + uiDefButS(block, MENU, B_REDR, str, xco+40, yco-44, (width-80), 19, &(eoa->dyn_operation), 0.0, 0.0, 0, 0, ""); + } + str= "Edit Object %t|Add Object %x0|End Object %x1|Replace Mesh %x2|Track to %x3|Dynamics %x4"; uiDefButS(block, MENU, B_REDR, str, xco+40, yco-24, (width-80), 19, &eoa->type, 0.0, 0.0, 0, 0, ""); yco-= ysize; @@ -2778,7 +2789,6 @@ static uiBlock *controller_state_mask_menu(void *arg_cont) uiBlock *block; uiBut *but; bController *cont = arg_cont; - int mask; short yco = 12, xco = 0, stbit, offset; @@ -2828,7 +2838,6 @@ static void do_object_state_menu(void *arg, int event) static uiBlock *object_state_mask_menu(void *arg_obj) { uiBlock *block; - uiBut *but; short xco = 0; block= uiNewBlock(&curarea->uiblocks, "obstatemenu", UI_EMBOSSP, UI_HELV, curarea->win); diff --git a/source/blender/src/editmesh_mods.c b/source/blender/src/editmesh_mods.c index 812da186f58..e4a7bc6da13 100644 --- a/source/blender/src/editmesh_mods.c +++ b/source/blender/src/editmesh_mods.c @@ -2307,7 +2307,7 @@ void selectconnected_mesh(void) if(em->edges.first==0) return; if( unified_findnearest(&eve, &eed, &efa)==0 ) { - error("Nothing indicated "); + /* error("Nothing indicated "); */ /* this is mostly annoying, eps with occluded geometry */ return; } @@ -2407,7 +2407,7 @@ static void selectconnected_delimit_mesh__internal(short all, short sel) EditFace *efa_mouse = findnearestface(&dist); if( !efa_mouse ) { - error("Nothing indicated "); + /* error("Nothing indicated "); */ /* this is mostly annoying, eps with occluded geometry */ return; } diff --git a/source/blender/src/editsima.c b/source/blender/src/editsima.c index 5761f1c2a73..175a5019708 100644 --- a/source/blender/src/editsima.c +++ b/source/blender/src/editsima.c @@ -2777,15 +2777,17 @@ void image_changed(SpaceImage *sima, Image *image) if(image->id.us==0) id_us_plus(&image->id); else id_lib_extern(&image->id); - +#if 0 /* GE People dont like us messing with their face modes */ if (tface->transp==TF_ADD) {} /* they obviously know what they are doing! - leave as is */ else if (ibuf && ibuf->depth == 32) tface->transp = TF_ALPHA; else tface->transp = TF_SOLID; - +#endif } else { tface->tpage= NULL; tface->mode &= ~TF_TEX; +#if 0 tface->transp = TF_SOLID; +#endif } change = 1; } diff --git a/source/blender/src/space.c b/source/blender/src/space.c index e6c866569f0..d76331151b4 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -442,9 +442,6 @@ static void SaveState(void) if(G.f & G_TEXTUREPAINT) texpaint_enable_mipmap(); - if(G.scene->camera==0 || G.scene->camera->type!=OB_CAMERA) - error("no (correct) camera"); - waitcursor(1); } diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index d44d987ff86..275d185c0b8 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -1678,6 +1678,8 @@ static KX_GameObject *gameobject_from_blenderobject( BL_ShapeDeformer *dcont = new BL_ShapeDeformer((BL_DeformableGameObject*)gameobj, ob, (BL_SkinMeshObject*)meshobj); ((BL_DeformableGameObject*)gameobj)->m_pDeformer = dcont; + if (bHasArmature) + dcont->LoadShapeDrivers(ob->parent); } else if (bHasArmature) { BL_SkinDeformer *dcont = new BL_SkinDeformer(ob, (BL_SkinMeshObject*)meshobj ); ((BL_DeformableGameObject*)gameobj)->m_pDeformer = dcont; @@ -2339,7 +2341,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie, { KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i)); struct Object* blenderobj = converter->FindBlenderObject(gameobj); - gameobj->SetState(blenderobj->state); + gameobj->SetState((blenderobj->init_state)?blenderobj->init_state:blenderobj->state); } #endif //CONVERT_LOGIC diff --git a/source/gameengine/Converter/BL_ShapeDeformer.cpp b/source/gameengine/Converter/BL_ShapeDeformer.cpp index d8e22ae2932..d07c439df8e 100644 --- a/source/gameengine/Converter/BL_ShapeDeformer.cpp +++ b/source/gameengine/Converter/BL_ShapeDeformer.cpp @@ -44,9 +44,12 @@ #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 "BKE_armature.h" #include "BKE_action.h" #include "BKE_key.h" +#include "BKE_ipo.h" #include "MT_Point3.h" extern "C"{ @@ -78,11 +81,55 @@ void BL_ShapeDeformer::ProcessReplica() { } +bool BL_ShapeDeformer::LoadShapeDrivers(Object* arma) +{ + IpoCurve *icu; + + m_shapeDrivers.clear(); + // check if this mesh has armature driven shape keys + if (m_bmesh->key->ipo) { + for(icu= (IpoCurve*)m_bmesh->key->ipo->curve.first; icu; icu= (IpoCurve*)icu->next) { + if(icu->driver && + (icu->flag & IPO_MUTE) == 0 && + icu->driver->type == IPO_DRIVER_TYPE_NORMAL && + icu->driver->ob == arma && + icu->driver->blocktype == ID_AR) { + // this shape key ipo curve has a driver on the parent armature + // record this curve in the shape deformer so that the corresponding + m_shapeDrivers.push_back(icu); + } + } + } + return !m_shapeDrivers.empty(); +} + +bool BL_ShapeDeformer::ExecuteShapeDrivers(void) +{ + if (!m_shapeDrivers.empty() && PoseUpdated()) { + vector<IpoCurve*>::iterator it; + void *poin; + int type; + for (it=m_shapeDrivers.begin(); it!=m_shapeDrivers.end(); it++) { + // no need to set a specific time: this curve has a driver + IpoCurve *icu = *it; + calc_icu(icu, 1.0f); + poin = get_ipo_poin((ID*)m_bmesh->key, icu, &type); + if (poin) + write_ipo_poin(poin, type, icu->curval); + } + ForceUpdate(); + return true; + } + return false; +} + bool BL_ShapeDeformer::Update(void) { bool bShapeUpdate = false; bool bSkinUpdate = false; + ExecuteShapeDrivers(); + /* See if the object shape has changed */ if (m_lastShapeUpdate != m_gameobj->GetLastFrame()) { /* the key coefficient have been set already, we just need to blend the keys */ diff --git a/source/gameengine/Converter/BL_ShapeDeformer.h b/source/gameengine/Converter/BL_ShapeDeformer.h index f9452109e3e..307343d6634 100644 --- a/source/gameengine/Converter/BL_ShapeDeformer.h +++ b/source/gameengine/Converter/BL_ShapeDeformer.h @@ -38,6 +38,7 @@ #include "BL_DeformableGameObject.h" #include <vector> +struct IpoCurve; class BL_ShapeDeformer : public BL_SkinDeformer { @@ -82,8 +83,16 @@ public: virtual ~BL_ShapeDeformer(); bool Update (void); + bool LoadShapeDrivers(Object* arma); + bool ExecuteShapeDrivers(void); + + void ForceUpdate() + { + m_lastShapeUpdate = -1.0; + }; protected: + vector<IpoCurve*> m_shapeDrivers; double m_lastShapeUpdate; BL_DeformableGameObject* m_gameobj; diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp index 526c6479df3..daf6d06503a 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.cpp +++ b/source/gameengine/Converter/BL_SkinDeformer.cpp @@ -157,12 +157,9 @@ void BL_SkinDeformer::ProcessReplica() bool BL_SkinDeformer::Update(void) { /* See if the armature has been updated for this frame */ - if (m_armobj && m_lastArmaUpdate!=m_armobj->GetLastFrame()){ + if (PoseUpdated()){ float obmat[4][4]; // the original object matrice - /* Do all of the posing necessary */ - m_armobj->ApplyPose(); - /* XXX note: where_is_pose() (from BKE_armature.h) calculates all matrices needed to start deforming */ /* but it requires the blender object pointer... */ diff --git a/source/gameengine/Converter/BL_SkinDeformer.h b/source/gameengine/Converter/BL_SkinDeformer.h index 603e716fb1e..c5568c049cb 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.h +++ b/source/gameengine/Converter/BL_SkinDeformer.h @@ -79,6 +79,14 @@ public: virtual ~BL_SkinDeformer(); bool Update (void); bool Apply (class RAS_IPolyMaterial *polymat); + bool PoseUpdated(void) + { + if (m_armobj && m_lastArmaUpdate!=m_armobj->GetLastFrame()) { + m_armobj->ApplyPose(); + return true; + } + return false; + } void ForceUpdate() { diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp index 89e2925a6c1..a50c072914d 100644 --- a/source/gameengine/Converter/KX_ConvertActuators.cpp +++ b/source/gameengine/Converter/KX_ConvertActuators.cpp @@ -62,6 +62,7 @@ #include "KX_SCA_EndObjectActuator.h" #include "KX_SCA_ReplaceMeshActuator.h" #include "KX_ParentActuator.h" +#include "KX_SCA_DynamicActuator.h" #include "KX_Scene.h" #include "KX_KetsjiEngine.h" @@ -137,6 +138,7 @@ void BL_ConvertActuators(char* maggiename, MT_Vector3 angvelvec ( KX_BLENDERTRUNC(obact->angularvelocity[0]), KX_BLENDERTRUNC(obact->angularvelocity[1]), KX_BLENDERTRUNC(obact->angularvelocity[2])); + short damping = obact->damping; drotvec /= BLENDER_HACK_DTIME; //drotvec /= BLENDER_HACK_DTIME; @@ -157,7 +159,7 @@ void BL_ConvertActuators(char* maggiename, bitLocalFlag.DRot = bool((obact->flag & ACT_DROT_LOCAL)!=0); bitLocalFlag.LinearVelocity = bool((obact->flag & ACT_LIN_VEL_LOCAL)!=0); bitLocalFlag.AngularVelocity = bool((obact->flag & ACT_ANG_VEL_LOCAL)!=0); - + bitLocalFlag.ClampVelocity = bool((obact->flag & ACT_CLAMP_VEL)!=0); bitLocalFlag.AddOrSetLinV = bool((obact->flag & ACT_ADD_LIN_VEL)!=0); @@ -168,6 +170,7 @@ void BL_ConvertActuators(char* maggiename, drotvec.getValue(), linvelvec.getValue(), angvelvec.getValue(), + damping, bitLocalFlag ); baseact = tmpbaseact; @@ -600,6 +603,15 @@ void BL_ConvertActuators(char* maggiename, blenderobject->upflag ); baseact = tmptrackact; + break; + } + case ACT_EDOB_DYNAMICS: + { + KX_SCA_DynamicActuator* tmpdynact + = new KX_SCA_DynamicActuator(gameobj, + editobact->dyn_operation + ); + baseact = tmpdynact; } } break; diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp index aa7c75e9633..70443ced7a9 100644 --- a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp +++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp @@ -102,6 +102,13 @@ MT_Vector3 KX_BulletPhysicsController::GetLinearVelocity() CcdPhysicsController::GetLinearVelocity(angVel[0],angVel[1],angVel[2]);//rcruiz return MT_Vector3(angVel[0],angVel[1],angVel[2]); } +MT_Vector3 KX_BulletPhysicsController::GetAngularVelocity() +{ + float angVel[3]; + //CcdPhysicsController::GetAngularVelocity(angVel[0],angVel[1],angVel[2]); + CcdPhysicsController::GetAngularVelocity(angVel[0],angVel[1],angVel[2]);//rcruiz + return MT_Vector3(angVel[0],angVel[1],angVel[2]); +} MT_Vector3 KX_BulletPhysicsController::GetVelocity(const MT_Point3& pos) { float linVel[3]; diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.h b/source/gameengine/Ketsji/KX_BulletPhysicsController.h index 619ac42503f..0853755dffa 100644 --- a/source/gameengine/Ketsji/KX_BulletPhysicsController.h +++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.h @@ -25,6 +25,7 @@ public: virtual void ApplyTorque(const MT_Vector3& torque,bool local); virtual void ApplyForce(const MT_Vector3& force,bool local); virtual MT_Vector3 GetLinearVelocity(); + virtual MT_Vector3 GetAngularVelocity(); virtual MT_Vector3 GetVelocity(const MT_Point3& pos); virtual void SetAngularVelocity(const MT_Vector3& ang_vel,bool local); virtual void SetLinearVelocity(const MT_Vector3& lin_vel,bool local); diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 1b2ac1fcfc6..f2d0174d139 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -664,6 +664,27 @@ MT_Vector3 KX_GameObject::GetLinearVelocity(bool local) return velocity; } +MT_Vector3 KX_GameObject::GetAngularVelocity(bool local) +{ + MT_Vector3 velocity(0.0,0.0,0.0), locvel; + MT_Matrix3x3 ori; + int i, j; + if (m_pPhysicsController1) + { + velocity = m_pPhysicsController1->GetAngularVelocity(); + + if (local) + { + ori = GetSGNode()->GetWorldOrientation(); + + locvel = velocity * ori; + return locvel; + } + } + return velocity; +} + + // scenegraph node stuff @@ -1262,17 +1283,7 @@ PyObject* KX_GameObject::PySuspendDynamics(PyObject* self, PyObject* args, PyObject* kwds) { - if (m_bSuspendDynamics) - { - Py_Return; - } - - if (m_pPhysicsController1) - { - m_pPhysicsController1->SuspendDynamics(); - } - m_bSuspendDynamics = true; - + SuspendDynamics(); Py_Return; } @@ -1282,18 +1293,7 @@ PyObject* KX_GameObject::PyRestoreDynamics(PyObject* self, PyObject* args, PyObject* kwds) { - - if (!m_bSuspendDynamics) - { - Py_Return; - } - - if (m_pPhysicsController1) - { - m_pPhysicsController1->RestoreDynamics(); - } - m_bSuspendDynamics = false; - + RestoreDynamics(); Py_Return; } diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 63a660617c4..a0507cb9dbc 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -46,7 +46,7 @@ #include "GEN_HashedPtr.h" #include "KX_Scene.h" #include "KX_KetsjiEngine.h" /* for m_anim_framerate */ - +#include "KX_IPhysicsController.h" /* for suspend/resume */ #define KX_OB_DYNAMIC 1 @@ -259,6 +259,14 @@ public: ); /** + * Return the angular velocity of the game object. + */ + MT_Vector3 + GetAngularVelocity( + bool local=false + ); + + /** * Align the object to a given normal. */ void @@ -644,6 +652,32 @@ public: */ void Resume(void); + void SuspendDynamics(void) { + if (m_bSuspendDynamics) + { + return; + } + + if (m_pPhysicsController1) + { + m_pPhysicsController1->SuspendDynamics(); + } + m_bSuspendDynamics = true; + } + + void RestoreDynamics(void) { + if (!m_bSuspendDynamics) + { + return; + } + + if (m_pPhysicsController1) + { + m_pPhysicsController1->RestoreDynamics(); + } + m_bSuspendDynamics = false; + } + KX_ClientObjectInfo* getClientInfo() { return m_pClient_info; } /** * @section Python interface functions. diff --git a/source/gameengine/Ketsji/KX_IPhysicsController.h b/source/gameengine/Ketsji/KX_IPhysicsController.h index 009db40d3e8..2ec66a883eb 100644 --- a/source/gameengine/Ketsji/KX_IPhysicsController.h +++ b/source/gameengine/Ketsji/KX_IPhysicsController.h @@ -64,6 +64,7 @@ public: virtual void ApplyTorque(const MT_Vector3& torque,bool local)=0; virtual void ApplyForce(const MT_Vector3& force,bool local)=0; virtual MT_Vector3 GetLinearVelocity()=0; + virtual MT_Vector3 GetAngularVelocity()=0; virtual MT_Vector3 GetVelocity(const MT_Point3& pos)=0; virtual void SetAngularVelocity(const MT_Vector3& ang_vel,bool local)=0; virtual void SetLinearVelocity(const MT_Vector3& lin_vel,bool local)=0; diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.cpp b/source/gameengine/Ketsji/KX_ObjectActuator.cpp index 22a406792f9..03ae14997ab 100644 --- a/source/gameengine/Ketsji/KX_ObjectActuator.cpp +++ b/source/gameengine/Ketsji/KX_ObjectActuator.cpp @@ -50,6 +50,7 @@ KX_ObjectActuator( const MT_Vector3& drot, const MT_Vector3& linV, const MT_Vector3& angV, + const short damping, const KX_LocalFlags& flag, PyTypeObject* T ) : @@ -60,9 +61,16 @@ KX_ObjectActuator( m_drot(drot), m_linear_velocity(linV), m_angular_velocity(angV), + m_linear_length2(0.0), + m_current_linear_factor(0.0), + m_current_angular_factor(0.0), + m_damping(damping), m_bitLocalFlag (flag), - m_active_combined_velocity (false) + m_active_combined_velocity (false), + m_linear_damping_active(false), + m_angular_damping_active(false) { + UpdateFuzzyFlags(); } bool KX_ObjectActuator::Update() @@ -87,42 +95,98 @@ bool KX_ObjectActuator::Update() ); m_active_combined_velocity = false; } + m_linear_damping_active = false; return false; } else if (parent) { - /* Probably better to use some flags, so these MT_zero tests can be */ - /* skipped. */ - if (!MT_fuzzyZero(m_force)) + if (!m_bitLocalFlag.ZeroForce) { - parent->ApplyForce(m_force,(m_bitLocalFlag.Force) != 0); + if (m_bitLocalFlag.ClampVelocity && !m_bitLocalFlag.ZeroLinearVelocity) + { + // The user is requesting not to exceed the velocity set in m_linear_velocity + // The verification is done by projecting the actual speed along the linV direction + // and comparing it with the linV vector length + MT_Vector3 linV; + linV = parent->GetLinearVelocity(m_bitLocalFlag.LinearVelocity); + if (linV.dot(m_linear_velocity) < m_linear_length2) + parent->ApplyForce(m_force,(m_bitLocalFlag.Force) != 0); + } else + { + parent->ApplyForce(m_force,(m_bitLocalFlag.Force) != 0); + } } - if (!MT_fuzzyZero(m_torque)) + if (!m_bitLocalFlag.ZeroTorque) { - parent->ApplyTorque(m_torque,(m_bitLocalFlag.Torque) != 0); + if (m_bitLocalFlag.ClampVelocity && !m_bitLocalFlag.ZeroAngularVelocity) + { + // The user is requesting not to exceed the velocity set in m_angular_velocity + // The verification is done by projecting the actual speed in the + MT_Vector3 angV; + angV = parent->GetAngularVelocity(m_bitLocalFlag.AngularVelocity); + if (angV.dot(m_angular_velocity) < m_angular_velocity.length2()) + parent->ApplyTorque(m_torque,(m_bitLocalFlag.Torque) != 0); + } else + { + parent->ApplyTorque(m_torque,(m_bitLocalFlag.Torque) != 0); + } } - if (!MT_fuzzyZero(m_dloc)) + if (!m_bitLocalFlag.ZeroDLoc) { parent->ApplyMovement(m_dloc,(m_bitLocalFlag.DLoc) != 0); } - if (!MT_fuzzyZero(m_drot)) + if (!m_bitLocalFlag.ZeroDRot) { parent->ApplyRotation(m_drot,(m_bitLocalFlag.DRot) != 0); } - if (!MT_fuzzyZero(m_linear_velocity)) + if (!m_bitLocalFlag.ZeroLinearVelocity && !m_bitLocalFlag.ClampVelocity) { if (m_bitLocalFlag.AddOrSetLinV) { parent->addLinearVelocity(m_linear_velocity,(m_bitLocalFlag.LinearVelocity) != 0); } else { m_active_combined_velocity = true; - parent->setLinearVelocity(m_linear_velocity,(m_bitLocalFlag.LinearVelocity) != 0); + if (m_damping > 0) { + MT_Vector3 linV; + if (!m_linear_damping_active) { + // delta and the start speed (depends on the existing speed in that direction) + linV = parent->GetLinearVelocity(m_bitLocalFlag.LinearVelocity); + // keep only the projection along the desired direction + m_current_linear_factor = linV.dot(m_linear_velocity)/m_linear_length2; + m_linear_damping_active = true; + } + if (m_current_linear_factor < 1.0) + m_current_linear_factor += 1.0/m_damping; + if (m_current_linear_factor > 1.0) + m_current_linear_factor = 1.0; + linV = m_current_linear_factor * m_linear_velocity; + parent->setLinearVelocity(linV,(m_bitLocalFlag.LinearVelocity) != 0); + } else { + parent->setLinearVelocity(m_linear_velocity,(m_bitLocalFlag.LinearVelocity) != 0); + } } } - if (!MT_fuzzyZero(m_angular_velocity)) + if (!m_bitLocalFlag.ZeroAngularVelocity && !m_bitLocalFlag.ClampVelocity) { - parent->setAngularVelocity(m_angular_velocity,(m_bitLocalFlag.AngularVelocity) != 0); m_active_combined_velocity = true; + if (m_damping > 0) { + MT_Vector3 angV; + if (!m_angular_damping_active) { + // delta and the start speed (depends on the existing speed in that direction) + angV = parent->GetAngularVelocity(m_bitLocalFlag.AngularVelocity); + // keep only the projection along the desired direction + m_current_angular_factor = angV.dot(m_angular_velocity)/m_angular_length2; + m_angular_damping_active = true; + } + if (m_current_angular_factor < 1.0) + m_current_angular_factor += 1.0/m_damping; + if (m_current_angular_factor > 1.0) + m_current_angular_factor = 1.0; + angV = m_current_angular_factor * m_angular_velocity; + parent->setAngularVelocity(angV,(m_bitLocalFlag.AngularVelocity) != 0); + } else { + parent->setAngularVelocity(m_angular_velocity,(m_bitLocalFlag.AngularVelocity) != 0); + } } } @@ -199,6 +263,8 @@ PyMethodDef KX_ObjectActuator::Methods[] = { {"setLinearVelocity", (PyCFunction) KX_ObjectActuator::sPySetLinearVelocity, METH_VARARGS}, {"getAngularVelocity", (PyCFunction) KX_ObjectActuator::sPyGetAngularVelocity, METH_VARARGS}, {"setAngularVelocity", (PyCFunction) KX_ObjectActuator::sPySetAngularVelocity, METH_VARARGS}, + {"setVelocityDamping", (PyCFunction) KX_ObjectActuator::sPySetVelocityDamping, METH_VARARGS}, + {"getVelocityDamping", (PyCFunction) KX_ObjectActuator::sPyGetVelocityDamping, METH_VARARGS}, {NULL,NULL} //Sentinel @@ -238,6 +304,7 @@ PyObject* KX_ObjectActuator::PySetForce(PyObject* self, } m_force.setValue(vecArg); m_bitLocalFlag.Force = PyArgToBool(bToggle); + UpdateFuzzyFlags(); Py_Return; } @@ -268,6 +335,7 @@ PyObject* KX_ObjectActuator::PySetTorque(PyObject* self, } m_torque.setValue(vecArg); m_bitLocalFlag.Torque = PyArgToBool(bToggle); + UpdateFuzzyFlags(); Py_Return; } @@ -298,6 +366,7 @@ PyObject* KX_ObjectActuator::PySetDLoc(PyObject* self, } m_dloc.setValue(vecArg); m_bitLocalFlag.DLoc = PyArgToBool(bToggle); + UpdateFuzzyFlags(); Py_Return; } @@ -328,6 +397,7 @@ PyObject* KX_ObjectActuator::PySetDRot(PyObject* self, } m_drot.setValue(vecArg); m_bitLocalFlag.DRot = PyArgToBool(bToggle); + UpdateFuzzyFlags(); Py_Return; } @@ -341,6 +411,7 @@ PyObject* KX_ObjectActuator::PyGetLinearVelocity(PyObject* self, PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_linear_velocity[1])); PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_linear_velocity[2])); PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.LinearVelocity)); + PyList_SetItem(retVal, 4, BoolToPyArg(m_bitLocalFlag.ClampVelocity)); return retVal; } @@ -351,12 +422,15 @@ PyObject* KX_ObjectActuator::PySetLinearVelocity(PyObject* self, PyObject* kwds) { float vecArg[3]; int bToggle = 0; - if (!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1], - &vecArg[2], &bToggle)) { + int bClamp = 0; + if (!PyArg_ParseTuple(args, "fffi|i", &vecArg[0], &vecArg[1], + &vecArg[2], &bToggle, &bClamp)) { return NULL; } m_linear_velocity.setValue(vecArg); m_bitLocalFlag.LinearVelocity = PyArgToBool(bToggle); + m_bitLocalFlag.ClampVelocity = PyArgToBool(bClamp); + UpdateFuzzyFlags(); Py_Return; } @@ -371,6 +445,7 @@ PyObject* KX_ObjectActuator::PyGetAngularVelocity(PyObject* self, PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_angular_velocity[1])); PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_angular_velocity[2])); PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.AngularVelocity)); + PyList_SetItem(retVal, 4, BoolToPyArg(m_bitLocalFlag.ClampVelocity)); return retVal; } @@ -380,15 +455,37 @@ PyObject* KX_ObjectActuator::PySetAngularVelocity(PyObject* self, PyObject* kwds) { float vecArg[3]; int bToggle = 0; - if (!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1], - &vecArg[2], &bToggle)) { + int bClamp = 0; + if (!PyArg_ParseTuple(args, "fffi|i", &vecArg[0], &vecArg[1], + &vecArg[2], &bToggle, &bClamp)) { return NULL; } m_angular_velocity.setValue(vecArg); m_bitLocalFlag.AngularVelocity = PyArgToBool(bToggle); + m_bitLocalFlag.ClampVelocity = PyArgToBool(bClamp); + UpdateFuzzyFlags(); Py_Return; } +/* 13. setVelocityDamping */ +PyObject* KX_ObjectActuator::PySetVelocityDamping(PyObject* self, + PyObject* args, + PyObject* kwds) { + int damping = 0; + if (!PyArg_ParseTuple(args, "i", &damping) || damping < 0 || damping > 1000) { + return NULL; + } + m_damping = damping; + Py_Return; +} + +/* 13. getVelocityDamping */ +PyObject* KX_ObjectActuator::PyGetVelocityDamping(PyObject* self, + PyObject* args, + PyObject* kwds) { + return Py_BuildValue("i",m_damping); +} + diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.h b/source/gameengine/Ketsji/KX_ObjectActuator.h index edbae154b8b..ec6dab5cd48 100644 --- a/source/gameengine/Ketsji/KX_ObjectActuator.h +++ b/source/gameengine/Ketsji/KX_ObjectActuator.h @@ -46,7 +46,13 @@ struct KX_LocalFlags { DLoc(false), LinearVelocity(false), AngularVelocity(false), - AddOrSetLinV(false) + AddOrSetLinV(false), + ClampVelocity(false), + ZeroForce(false), + ZeroDRot(false), + ZeroDLoc(false), + ZeroLinearVelocity(false), + ZeroAngularVelocity(false) { } @@ -57,6 +63,13 @@ struct KX_LocalFlags { unsigned short LinearVelocity : 1; unsigned short AngularVelocity : 1; unsigned short AddOrSetLinV : 1; + unsigned short ClampVelocity : 1; + unsigned short ZeroForce : 1; + unsigned short ZeroTorque : 1; + unsigned short ZeroDRot : 1; + unsigned short ZeroDLoc : 1; + unsigned short ZeroLinearVelocity : 1; + unsigned short ZeroAngularVelocity : 1; }; class KX_ObjectActuator : public SCA_IActuator @@ -69,6 +82,11 @@ class KX_ObjectActuator : public SCA_IActuator MT_Vector3 m_drot; MT_Vector3 m_linear_velocity; MT_Vector3 m_angular_velocity; + MT_Scalar m_linear_length2; + MT_Scalar m_angular_length2; + MT_Scalar m_current_linear_factor; + MT_Scalar m_current_angular_factor; + short m_damping; KX_LocalFlags m_bitLocalFlag; // A hack bool -- oh no sorry everyone @@ -77,6 +95,8 @@ class KX_ObjectActuator : public SCA_IActuator // setting linear velocity. bool m_active_combined_velocity; + bool m_linear_damping_active; + bool m_angular_damping_active; public: enum KX_OBJECT_ACT_VEC_TYPE { @@ -103,6 +123,7 @@ public: const MT_Vector3& drot, const MT_Vector3& linV, const MT_Vector3& angV, + const short damping, const KX_LocalFlags& flag, PyTypeObject* T=&Type ); @@ -110,6 +131,17 @@ public: CValue* GetReplica(); void SetForceLoc(const double force[3]) { /*m_force=force;*/ } + void UpdateFuzzyFlags() + { + m_bitLocalFlag.ZeroForce = MT_fuzzyZero(m_force); + m_bitLocalFlag.ZeroTorque = MT_fuzzyZero(m_torque); + m_bitLocalFlag.ZeroDLoc = MT_fuzzyZero(m_dloc); + m_bitLocalFlag.ZeroDRot = MT_fuzzyZero(m_drot); + m_bitLocalFlag.ZeroLinearVelocity = MT_fuzzyZero(m_linear_velocity); + m_linear_length2 = (m_bitLocalFlag.ZeroLinearVelocity) ? 0.0 : m_linear_velocity.length2(); + m_bitLocalFlag.ZeroAngularVelocity = MT_fuzzyZero(m_angular_velocity); + m_angular_length2 = (m_bitLocalFlag.ZeroAngularVelocity) ? 0.0 : m_angular_velocity.length2(); + } virtual bool Update(); @@ -132,6 +164,8 @@ public: KX_PYMETHOD(KX_ObjectActuator,SetLinearVelocity); KX_PYMETHOD(KX_ObjectActuator,GetAngularVelocity); KX_PYMETHOD(KX_ObjectActuator,SetAngularVelocity); + KX_PYMETHOD(KX_ObjectActuator,SetVelocityDamping); + KX_PYMETHOD(KX_ObjectActuator,GetVelocityDamping); }; #endif //__KX_OBJECTACTUATOR diff --git a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp new file mode 100644 index 00000000000..d44ab477749 --- /dev/null +++ b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp @@ -0,0 +1,206 @@ +// +// Adjust dynamics settins for this object +// +// $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): none yet. +// +// ***** END GPL LICENSE BLOCK ***** + +// +// Previously existed as: + +// \source\gameengine\GameLogic\SCA_DynamicActuator.cpp + +// Please look here for revision history. + +#include "KX_SCA_DynamicActuator.h" + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +/* ------------------------------------------------------------------------- */ +/* Python functions */ +/* ------------------------------------------------------------------------- */ + +/* Integration hooks ------------------------------------------------------- */ + + PyTypeObject + +KX_SCA_DynamicActuator:: + +Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "KX_SCA_DynamicActuator", + sizeof(KX_SCA_DynamicActuator), + 0, + PyDestructor, + 0, + __getattr, + __setattr, + 0, + __repr, + 0, + 0, + 0, + 0, + 0 +}; + +PyParentObject KX_SCA_DynamicActuator::Parents[] = { + &KX_SCA_DynamicActuator::Type, + &SCA_IActuator::Type, + &SCA_ILogicBrick::Type, + &CValue::Type, + NULL +}; + + +PyMethodDef KX_SCA_DynamicActuator::Methods[] = { + KX_PYMETHODTABLE(KX_SCA_DynamicActuator, setOperation), + KX_PYMETHODTABLE(KX_SCA_DynamicActuator, getOperation), + {NULL,NULL} //Sentinel +}; + + + +PyObject* KX_SCA_DynamicActuator::_getattr(const STR_String& attr) +{ + _getattr_up(SCA_IActuator); +} + + + +/* 1. setOperation */ +KX_PYMETHODDEF_DOC(KX_SCA_DynamicActuator, setOperation, +"setOperation(operation?)\n" +"\t - operation? : type of dynamic operation\n" +"\t 0 = restore dynamics\n" +"\t 1 = disable dynamics\n" +"\t 2 = enable rigid body\n" +"\t 3 = disable rigid body\n" +"Change the dynamic status of the parent object.\n") +{ + int dyn_operation; + + if (!PyArg_ParseTuple(args, "i", &dyn_operation)) + { + return NULL; + } + if (dyn_operation <0 || dyn_operation>3) { + PyErr_SetString(PyExc_IndexError, "Dynamic Actuator's setOperation() range must be between 0 and 3"); + return NULL; + } + m_dyn_operation= dyn_operation; + Py_Return; +} + +KX_PYMETHODDEF_DOC(KX_SCA_DynamicActuator, getOperation, +"getOperation() -> integer\n" +"Returns the operation type of this actuator.\n" +) +{ + return PyInt_FromLong((long)m_dyn_operation); +} + + +/* ------------------------------------------------------------------------- */ +/* Native functions */ +/* ------------------------------------------------------------------------- */ + +KX_SCA_DynamicActuator::KX_SCA_DynamicActuator(SCA_IObject *gameobj, + short dyn_operation, + PyTypeObject* T) : + + SCA_IActuator(gameobj, T), + m_dyn_operation(dyn_operation) +{ +} /* End of constructor */ + + +KX_SCA_DynamicActuator::~KX_SCA_DynamicActuator() +{ + // there's nothing to be done here, really.... +} /* end of destructor */ + + + +bool KX_SCA_DynamicActuator::Update() +{ + // bool result = false; /*unused*/ + KX_GameObject *obj = (KX_GameObject*) GetParent(); + bool bNegativeEvent = IsNegativeEvent(); + KX_IPhysicsController* controller; + RemoveAllEvents(); + + if (bNegativeEvent) + return false; // do nothing on negative events + + if (!obj) + return false; // object not accessible, shouldnt happen + controller = obj->GetPhysicsController(); + if (!controller) + return false; // no physic object + + switch (m_dyn_operation) + { + case 0: + obj->RestoreDynamics(); + break; + case 1: + obj->SuspendDynamics(); + break; + case 2: + controller->setRigidBody(true); + break; + case 3: + controller->setRigidBody(false); + break; + } + + return false; +} + + + +CValue* KX_SCA_DynamicActuator::GetReplica() +{ + KX_SCA_DynamicActuator* replica = + new KX_SCA_DynamicActuator(*this); + + if (replica == NULL) + return NULL; + + replica->ProcessReplica(); + + // this will copy properties and so on... + CValue::AddDataToReplica(replica); + + return replica; +}; + + +/* eof */ diff --git a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h new file mode 100644 index 00000000000..b47c3a511d9 --- /dev/null +++ b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h @@ -0,0 +1,76 @@ +// +// Add object to the game world on action of this actuator +// +// $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 ***** +// + +#ifndef __KX_SCA_DYNAMICACTUATOR +#define __KX_SCA_DYNAMICACTUATOR + +#include "SCA_IActuator.h" +#include "SCA_PropertyActuator.h" +#include "SCA_LogicManager.h" + +#include "KX_GameObject.h" +#include "KX_IPhysicsController.h" + +class KX_SCA_DynamicActuator : public SCA_IActuator +{ + Py_Header; + + // dynamics operation to apply to the game object + short m_dyn_operation; + public: + KX_SCA_DynamicActuator( + SCA_IObject* gameobj, + short dyn_operation, + PyTypeObject* T=&Type + ); + + ~KX_SCA_DynamicActuator( + ); + + CValue* + GetReplica( + ); + + virtual bool + Update(); + + virtual PyObject* + _getattr( + const STR_String& attr + ); + + /* 1. setOperation */ + KX_PYMETHOD_DOC(KX_SCA_DynamicActuator,setOperation); + KX_PYMETHOD_DOC(KX_SCA_DynamicActuator,getOperation); + +}; + +#endif diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index d2e1d7cc139..03013786e44 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -866,6 +866,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj) static_cast<BL_ArmatureObject*>( parentobj ) ); releaseParent= false; + shapeDeformer->LoadShapeDrivers(blendobj->parent); } else { diff --git a/source/gameengine/Ketsji/KX_SumoPhysicsController.h b/source/gameengine/Ketsji/KX_SumoPhysicsController.h index 868465c8f10..8c061ae4056 100644 --- a/source/gameengine/Ketsji/KX_SumoPhysicsController.h +++ b/source/gameengine/Ketsji/KX_SumoPhysicsController.h @@ -68,6 +68,8 @@ public: void ApplyTorque(const MT_Vector3& torque,bool local); void ApplyForce(const MT_Vector3& force,bool local); MT_Vector3 GetLinearVelocity(); + MT_Vector3 GetAngularVelocity() // to keep compiler happy + { return MT_Vector3(0.0,0.0,0.0); } MT_Vector3 GetVelocity(const MT_Point3& pos); void SetAngularVelocity(const MT_Vector3& ang_vel,bool local); void SetLinearVelocity(const MT_Vector3& lin_vel,bool local); diff --git a/source/gameengine/PyDoc/KX_GameObject.py b/source/gameengine/PyDoc/KX_GameObject.py index ff55f975543..abcf5a942dd 100644 --- a/source/gameengine/PyDoc/KX_GameObject.py +++ b/source/gameengine/PyDoc/KX_GameObject.py @@ -50,8 +50,9 @@ class KX_GameObject: """ Sets the game object's orientation. - @type orn: 3x3 inverted rotation matrix, or Quaternion. + @type orn: 3x3 rotation matrix, or Quaternion. @param orn: a rotation matrix specifying the new rotation. + @note: When using this matrix with Blender.Mathutils.Matrix() types, it will need to be transposed. """ def alignAxisToVect(vect, axis): """ @@ -71,6 +72,7 @@ class KX_GameObject: @rtype: 3x3 inverted rotation matrix @return: The game object's rotation matrix + @note: When using this matrix with Blender.Mathutils.Matrix() types, it will need to be transposed. """ def getLinearVelocity(local): """ |