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:
authorCampbell Barton <ideasman42@gmail.com>2008-06-25 20:25:01 +0400
committerCampbell Barton <ideasman42@gmail.com>2008-06-25 20:25:01 +0400
commit3282d8562719bde5b8be351123135dd5ced250a5 (patch)
tree9c9b290e1a1b913f85654125e15092ef422ea965 /source
parentcf8807581eae39e44ceb33158df8916a2afb2eb6 (diff)
svn merge -r15339:HEAD https://svn.blender.org/svnroot/bf-blender/trunk/blender/
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_ipo.h8
-rw-r--r--source/blender/makesdna/DNA_actuator_types.h13
-rw-r--r--source/blender/python/api2_2x/CurNurb.c34
-rw-r--r--source/blender/python/api2_2x/doc/Curve.py2
-rw-r--r--source/blender/src/buttons_editing.c2
-rw-r--r--source/blender/src/buttons_logic.c35
-rw-r--r--source/blender/src/editmesh_mods.c4
-rw-r--r--source/blender/src/editsima.c6
-rw-r--r--source/blender/src/space.c3
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp4
-rw-r--r--source/gameengine/Converter/BL_ShapeDeformer.cpp47
-rw-r--r--source/gameengine/Converter/BL_ShapeDeformer.h9
-rw-r--r--source/gameengine/Converter/BL_SkinDeformer.cpp5
-rw-r--r--source/gameengine/Converter/BL_SkinDeformer.h8
-rw-r--r--source/gameengine/Converter/KX_ConvertActuators.cpp14
-rw-r--r--source/gameengine/Ketsji/KX_BulletPhysicsController.cpp7
-rw-r--r--source/gameengine/Ketsji/KX_BulletPhysicsController.h1
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp46
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h36
-rw-r--r--source/gameengine/Ketsji/KX_IPhysicsController.h1
-rw-r--r--source/gameengine/Ketsji/KX_ObjectActuator.cpp131
-rw-r--r--source/gameengine/Ketsji/KX_ObjectActuator.h36
-rw-r--r--source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp206
-rw-r--r--source/gameengine/Ketsji/KX_SCA_DynamicActuator.h76
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp1
-rw-r--r--source/gameengine/Ketsji/KX_SumoPhysicsController.h2
-rw-r--r--source/gameengine/PyDoc/KX_GameObject.py4
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):
"""