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:
authorAndre Susano Pinto <andresusanopinto@gmail.com>2008-07-01 02:57:52 +0400
committerAndre Susano Pinto <andresusanopinto@gmail.com>2008-07-01 02:57:52 +0400
commitc7dbc6548811f37bfeda4013ab70e342d50707b7 (patch)
tree4b85e06024dfe328f686ae82d3a413d4f7c2d85c /source
parent09c898bd65069ec75a38f6ad28ced45454d87720 (diff)
svn merge -r 15292:15392 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/blenkernel/intern/action.c2
-rw-r--r--source/blender/blenkernel/intern/image.c4
-rw-r--r--source/blender/blenkernel/intern/ipo.c2
-rw-r--r--source/blender/blenkernel/intern/modifier.c74
-rw-r--r--source/blender/blenkernel/intern/particle_system.c1
-rw-r--r--source/blender/blenkernel/intern/sca.c3
-rw-r--r--source/blender/blenkernel/intern/text.c3
-rw-r--r--source/blender/blenlib/BLI_arithb.h1
-rw-r--r--source/blender/blenlib/intern/arithb.c68
-rw-r--r--source/blender/blenloader/intern/readfile.c12
-rw-r--r--source/blender/blenloader/intern/writefile.c3
-rw-r--r--source/blender/imbuf/IMB_imbuf_types.h1
-rw-r--r--source/blender/imbuf/intern/IMB_anim.h3
-rw-r--r--source/blender/imbuf/intern/anim.c88
-rw-r--r--source/blender/include/BIF_butspace.h2
-rw-r--r--source/blender/include/BIF_interface.h1
-rw-r--r--source/blender/include/BIF_oops.h2
-rw-r--r--source/blender/include/butspace.h4
-rw-r--r--source/blender/include/transform.h6
-rw-r--r--source/blender/makesdna/DNA_actuator_types.h30
-rw-r--r--source/blender/makesdna/DNA_controller_types.h7
-rw-r--r--source/blender/makesdna/DNA_object_types.h6
-rw-r--r--source/blender/makesdna/DNA_sensor_types.h3
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h2
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_math.c2
-rw-r--r--source/blender/python/api2_2x/CurNurb.c34
-rw-r--r--source/blender/python/api2_2x/Lamp.c13
-rw-r--r--source/blender/python/api2_2x/Mathutils.c62
-rw-r--r--source/blender/python/api2_2x/doc/Curve.py2
-rw-r--r--source/blender/render/intern/source/pipeline.c6
-rw-r--r--source/blender/src/buttons_editing.c2
-rw-r--r--source/blender/src/buttons_logic.c696
-rw-r--r--source/blender/src/buttons_scene.c2
-rw-r--r--source/blender/src/drawaction.c11
-rw-r--r--source/blender/src/drawview.c3
-rw-r--r--source/blender/src/editaction.c13
-rw-r--r--source/blender/src/editfont.c4
-rw-r--r--source/blender/src/editmesh_mods.c4
-rw-r--r--source/blender/src/editobject.c2
-rw-r--r--source/blender/src/editseq.c3
-rw-r--r--source/blender/src/editsima.c6
-rw-r--r--source/blender/src/interface.c4
-rw-r--r--source/blender/src/oops.c1
-rw-r--r--source/blender/src/poseobject.c4
-rw-r--r--source/blender/src/sequence.c14
-rw-r--r--source/blender/src/space.c24
-rw-r--r--source/blender/src/transform.c8
-rw-r--r--source/blender/src/transform_constraints.c19
-rw-r--r--source/blender/src/transform_generics.c9
-rw-r--r--source/blender/src/transform_snap.c553
-rw-r--r--source/blender/src/view.c36
-rw-r--r--source/creator/creator.c4
-rw-r--r--source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp34
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp4
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h2
-rw-r--r--source/gameengine/Converter/BL_ActionActuator.cpp49
-rw-r--r--source/gameengine/Converter/BL_ActionActuator.h7
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp10
-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.cpp33
-rw-r--r--source/gameengine/Converter/KX_ConvertControllers.cpp29
-rw-r--r--source/gameengine/Converter/KX_ConvertSensors.cpp5
-rw-r--r--source/gameengine/Expressions/Value.cpp24
-rw-r--r--source/gameengine/Expressions/Value.h2
-rw-r--r--source/gameengine/GameLogic/SCA_2DFilterActuator.cpp4
-rw-r--r--source/gameengine/GameLogic/SCA_2DFilterActuator.h2
-rw-r--r--source/gameengine/GameLogic/SCA_AlwaysSensor.cpp7
-rw-r--r--source/gameengine/GameLogic/SCA_AlwaysSensor.h2
-rw-r--r--source/gameengine/GameLogic/SCA_IActuator.cpp10
-rw-r--r--source/gameengine/GameLogic/SCA_IActuator.h7
-rw-r--r--source/gameengine/GameLogic/SCA_IController.cpp97
-rw-r--r--source/gameengine/GameLogic/SCA_IController.h4
-rw-r--r--source/gameengine/GameLogic/SCA_IObject.cpp13
-rw-r--r--source/gameengine/GameLogic/SCA_IObject.h19
-rw-r--r--source/gameengine/GameLogic/SCA_ISensor.cpp57
-rw-r--r--source/gameengine/GameLogic/SCA_ISensor.h17
-rw-r--r--source/gameengine/GameLogic/SCA_JoystickSensor.cpp6
-rw-r--r--source/gameengine/GameLogic/SCA_JoystickSensor.h1
-rw-r--r--source/gameengine/GameLogic/SCA_KeyboardSensor.cpp33
-rw-r--r--source/gameengine/GameLogic/SCA_KeyboardSensor.h2
-rw-r--r--source/gameengine/GameLogic/SCA_LogicManager.cpp20
-rw-r--r--source/gameengine/GameLogic/SCA_MouseSensor.cpp15
-rw-r--r--source/gameengine/GameLogic/SCA_MouseSensor.h2
-rw-r--r--source/gameengine/GameLogic/SCA_NANDController.cpp144
-rw-r--r--source/gameengine/GameLogic/SCA_NANDController.h56
-rw-r--r--source/gameengine/GameLogic/SCA_NORController.cpp144
-rw-r--r--source/gameengine/GameLogic/SCA_NORController.h56
-rw-r--r--source/gameengine/GameLogic/SCA_PropertySensor.cpp8
-rw-r--r--source/gameengine/GameLogic/SCA_PropertySensor.h1
-rw-r--r--source/gameengine/GameLogic/SCA_PythonController.cpp9
-rw-r--r--source/gameengine/GameLogic/SCA_PythonController.h1
-rw-r--r--source/gameengine/GameLogic/SCA_RandomSensor.cpp16
-rw-r--r--source/gameengine/GameLogic/SCA_RandomSensor.h1
-rw-r--r--source/gameengine/GameLogic/SCA_XNORController.cpp148
-rw-r--r--source/gameengine/GameLogic/SCA_XNORController.h56
-rw-r--r--source/gameengine/GameLogic/SCA_XORController.cpp148
-rw-r--r--source/gameengine/GameLogic/SCA_XORController.h56
-rw-r--r--source/gameengine/GamePlayer/common/GPC_RenderTools.cpp4
-rw-r--r--source/gameengine/GamePlayer/common/GPC_RenderTools.h2
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_Application.cpp12
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_ghost.cpp3
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp7
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h1
-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.cpp109
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h44
-rw-r--r--source/gameengine/Ketsji/KX_IPhysicsController.h1
-rw-r--r--source/gameengine/Ketsji/KX_MouseFocusSensor.cpp13
-rw-r--r--source/gameengine/Ketsji/KX_MouseFocusSensor.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_RadarSensor.cpp1
-rw-r--r--source/gameengine/Ketsji/KX_RaySensor.cpp14
-rw-r--r--source/gameengine/Ketsji/KX_RaySensor.h1
-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.cpp3
-rw-r--r--source/gameengine/Ketsji/KX_StateActuator.cpp207
-rw-r--r--source/gameengine/Ketsji/KX_StateActuator.h83
-rw-r--r--source/gameengine/Ketsji/KX_SumoPhysicsController.h2
-rw-r--r--source/gameengine/Ketsji/KX_TouchSensor.cpp14
-rw-r--r--source/gameengine/Ketsji/KX_TouchSensor.h1
-rw-r--r--source/gameengine/PyDoc/KX_GameObject.py38
-rw-r--r--source/gameengine/PyDoc/SCA_PythonController.py8
-rw-r--r--source/gameengine/Rasterizer/RAS_2DFilterManager.cpp101
-rw-r--r--source/gameengine/Rasterizer/RAS_2DFilterManager.h10
-rw-r--r--source/gameengine/Rasterizer/RAS_IRenderTools.h2
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp3
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp5
134 files changed, 3658 insertions, 796 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/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 05f2e69fce1..5b96bf11056 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -350,7 +350,7 @@ static void copy_pose_channel_data(bPoseChannel *pchan, const bPoseChannel *chan
pchan->flag= chan->flag;
con= chan->constraints.first;
- for(pcon= pchan->constraints.first; pcon; pcon= pcon->next) {
+ for(pcon= pchan->constraints.first; pcon; pcon= pcon->next, con= con->next) {
pcon->enforce= con->enforce;
pcon->headtail= con->headtail;
}
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index b2557c9c07e..c73279746fb 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -857,8 +857,8 @@ void BKE_add_image_extension(char *string, int imtype)
extension= ".bmp";
}
else if(G.have_libtiff && (imtype==R_TIFF)) {
- if(!BLI_testextensie(string, ".tif"))
- extension= ".tif";
+ if(!BLI_testextensie(string, ".tif") &&
+ !BLI_testextensie(string, ".tiff")) extension= ".tif";
}
#ifdef WITH_OPENEXR
else if( ELEM(imtype, R_OPENEXR, R_MULTILAYER)) {
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index 321d4f1d37e..59eb3837aab 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -1859,7 +1859,7 @@ void set_icu_vars(IpoCurve *icu)
/* yafray: aperture & focal distance params */
switch(icu->adrcode) {
case CAM_LENS:
- icu->ymin= 5.0;
+ icu->ymin= 1.0;
icu->ymax= 1000.0;
break;
case CAM_STA:
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 561a97d8646..d3cc451c6fc 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -1424,10 +1424,10 @@ void vertgroup_flip_name (char *name, int strip_number)
}
static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
- Object *ob,
- DerivedMesh *dm,
- int initFlags,
- int axis)
+ Object *ob,
+ DerivedMesh *dm,
+ int initFlags,
+ int axis)
{
int i;
float tolerance = mmd->tolerance;
@@ -1436,7 +1436,7 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
int maxVerts = dm->getNumVerts(dm);
int maxEdges = dm->getNumEdges(dm);
int maxFaces = dm->getNumFaces(dm);
- int vector_size, j, a, b;
+ int vector_size=0, j, a, b;
bDeformGroup *def, *defb;
bDeformGroup **vector_def = NULL;
int (*indexMap)[2];
@@ -1465,7 +1465,7 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
if (mmd->mirror_ob) {
float obinv[4][4];
-
+
Mat4Invert(obinv, mmd->mirror_ob->obmat);
Mat4MulMat4(mtx, ob->obmat, obinv);
Mat4Invert(imtx, mtx);
@@ -1476,16 +1476,16 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
MVert *mv = CDDM_get_vert(result, numVerts);
int isShared;
float co[3];
-
+
dm->getVert(dm, i, &inMV);
-
+
VecCopyf(co, inMV.co);
-
+
if (mmd->mirror_ob) {
VecMat4MulVecfl(co, mtx, co);
}
isShared = ABS(co[axis])<=tolerance;
-
+
/* Because the topology result (# of vertices) must be the same if
* the mesh data is overridden by vertex cos, have to calc sharedness
* based on original coordinates. This is why we test before copy.
@@ -1493,10 +1493,10 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
DM_copy_vert_data(dm, result, i, numVerts, 1);
*mv = inMV;
numVerts++;
-
+
indexMap[i][0] = numVerts - 1;
indexMap[i][1] = !isShared;
-
+
if(isShared) {
co[axis] = 0;
if (mmd->mirror_ob) {
@@ -1508,33 +1508,33 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
} else {
MVert *mv2 = CDDM_get_vert(result, numVerts);
MDeformVert *dvert = NULL;
-
+
DM_copy_vert_data(dm, result, i, numVerts, 1);
*mv2 = *mv;
-
+
co[axis] = -co[axis];
if (mmd->mirror_ob) {
VecMat4MulVecfl(co, imtx, co);
}
VecCopyf(mv2->co, co);
-
+
if (mmd->flag & MOD_MIR_VGROUP){
dvert = DM_get_vert_data(result, numVerts, CD_MDEFORMVERT);
-
+
if (dvert)
{
for(j = 0; j < dvert[0].totweight; ++j)
{
char tmpname[32];
-
+
if(dvert->dw[j].def_nr < 0 ||
dvert->dw[j].def_nr >= vector_size)
continue;
-
+
def = vector_def[dvert->dw[j].def_nr];
strcpy(tmpname, def->name);
vertgroup_flip_name(tmpname,0);
-
+
for(b = 0, defb = ob->defbase.first; defb;
defb = defb->next, b++)
{
@@ -1547,7 +1547,7 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
}
}
}
-
+
numVerts++;
}
}
@@ -1555,25 +1555,25 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
for(i = 0; i < maxEdges; i++) {
MEdge inMED;
MEdge *med = CDDM_get_edge(result, numEdges);
-
+
dm->getEdge(dm, i, &inMED);
-
+
DM_copy_edge_data(dm, result, i, numEdges, 1);
*med = inMED;
numEdges++;
-
+
med->v1 = indexMap[inMED.v1][0];
med->v2 = indexMap[inMED.v2][0];
if(initFlags)
med->flag |= ME_EDGEDRAW | ME_EDGERENDER;
-
+
if(indexMap[inMED.v1][1] || indexMap[inMED.v2][1]) {
MEdge *med2 = CDDM_get_edge(result, numEdges);
-
+
DM_copy_edge_data(dm, result, i, numEdges, 1);
*med2 = *med;
numEdges++;
-
+
med2->v1 += indexMap[inMED.v1][1];
med2->v2 += indexMap[inMED.v2][1];
}
@@ -1582,13 +1582,13 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
for(i = 0; i < maxFaces; i++) {
MFace inMF;
MFace *mf = CDDM_get_face(result, numFaces);
-
+
dm->getFace(dm, i, &inMF);
-
+
DM_copy_face_data(dm, result, i, numFaces, 1);
*mf = inMF;
numFaces++;
-
+
mf->v1 = indexMap[inMF.v1][0];
mf->v2 = indexMap[inMF.v2][0];
mf->v3 = indexMap[inMF.v3][0];
@@ -1600,15 +1600,15 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
|| (mf->v4 && indexMap[inMF.v4][1])) {
MFace *mf2 = CDDM_get_face(result, numFaces);
static int corner_indices[4] = {2, 1, 0, 3};
-
+
DM_copy_face_data(dm, result, i, numFaces, 1);
*mf2 = *mf;
-
+
mf2->v1 += indexMap[inMF.v1][1];
mf2->v2 += indexMap[inMF.v2][1];
mf2->v3 += indexMap[inMF.v3][1];
if(inMF.v4) mf2->v4 += indexMap[inMF.v4][1];
-
+
/* mirror UVs if enabled */
if(mmd->flag & (MOD_MIR_MIRROR_U | MOD_MIR_MIRROR_V)) {
MTFace *tf = result->getFaceData(result, numFaces, CD_MTFACE);
@@ -1622,14 +1622,14 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
}
}
}
-
+
/* Flip face normal */
SWAP(int, mf2->v1, mf2->v3);
DM_swap_face_data(result, numFaces, corner_indices);
-
+
test_index_face(mf2, &result->faceData, numFaces, inMF.v4?4:3);
numFaces++;
- }
+ }
}
if (vector_def) MEM_freeN(vector_def);
@@ -1644,8 +1644,8 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
}
static DerivedMesh *mirrorModifier__doMirror(MirrorModifierData *mmd,
- Object *ob, DerivedMesh *dm,
- int initFlags)
+ Object *ob, DerivedMesh *dm,
+ int initFlags)
{
DerivedMesh *result = dm;
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index f06ef221795..458171cc232 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -2596,6 +2596,7 @@ static void precalc_effectors(Object *ob, ParticleSystem *psys, ParticleSystemMo
for(ec= lb->first; ec; ec= ec->next) {
PartDeflect *pd= ec->ob->pd;
+ co = NULL;
if(ec->type==PSYS_EC_EFFECTOR && pd->forcefield==PFIELD_GUIDE && ec->ob->type==OB_CURVE
&& part->phystype!=PART_PHYS_BOIDS) {
diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c
index 92544f19721..16ca5d7542d 100644
--- a/source/blender/blenkernel/intern/sca.c
+++ b/source/blender/blenkernel/intern/sca.c
@@ -465,6 +465,9 @@ void init_actuator(bActuator *act)
case ACT_PARENT:
act->data = MEM_callocN(sizeof( bParentActuator ), "parent act");
break;
+ case ACT_STATE:
+ act->data = MEM_callocN(sizeof( bStateActuator ), "state act");
+ break;
default:
; /* this is very severe... I cannot make any memory for this */
/* logic brick... */
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 876547042dc..53b7bb975a3 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -942,7 +942,8 @@ char *txt_to_buf (Text *text)
if (!text) return NULL;
if (!text->curl) return NULL;
if (!text->sell) return NULL;
-
+ if (!text->lines.first) return NULL;
+
linef= text->lines.first;
charf= 0;
diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h
index 4d277cf98e1..4fa880c36d1 100644
--- a/source/blender/blenlib/BLI_arithb.h
+++ b/source/blender/blenlib/BLI_arithb.h
@@ -374,6 +374,7 @@ void LocQuatSizeToMat4(float mat[][4], float loc[3], float quat[4], float size[3
void tubemap(float x, float y, float z, float *u, float *v);
void spheremap(float x, float y, float z, float *u, float *v);
+int LineIntersectLine(float v1[3], float v2[3], float v3[3], float v4[3], float i1[3], float i2[3]);
int LineIntersectsTriangle(float p1[3], float p2[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv);
int RayIntersectsTriangle(float p1[3], float d[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv);
int SweepingSphereIntersectsTriangleUV(float p1[3], float p2[3], float radius, float v0[3], float v1[3], float v2[3], float *lambda, float *ipoint);
diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c
index 322a9e6fd02..2084ab3da5f 100644
--- a/source/blender/blenlib/intern/arithb.c
+++ b/source/blender/blenlib/intern/arithb.c
@@ -4032,6 +4032,74 @@ int AxialLineIntersectsTriangle(int axis, float p1[3], float p2[3], float v0[3],
return 1;
}
+/* Returns the number of point of interests
+ * 0 - lines are colinear
+ * 1 - lines are coplanar, i1 is set to intersection
+ * 2 - i1 and i2 are the nearest points on line 1 (v1, v2) and line 2 (v3, v4) respectively
+ * */
+int LineIntersectLine(float v1[3], float v2[3], float v3[3], float v4[3], float i1[3], float i2[3])
+{
+ float a[3], b[3], c[3], ab[3], cb[3], dir1[3], dir2[3];
+ float d;
+
+ VecSubf(c, v3, v1);
+ VecSubf(a, v2, v1);
+ VecSubf(b, v4, v3);
+
+ VecCopyf(dir1, a);
+ Normalize(dir1);
+ VecCopyf(dir2, b);
+ Normalize(dir2);
+ d = Inpf(dir1, dir2);
+ if (d == 1.0f || d == -1.0f) {
+ /* colinear */
+ return 0;
+ }
+
+ Crossf(ab, a, b);
+ d = Inpf(c, ab);
+
+ /* test if the two lines are coplanar */
+ if (d > -0.000001f && d < 0.000001f) {
+ Crossf(cb, c, b);
+
+ VecMulf(a, Inpf(cb, ab) / Inpf(ab, ab));
+ VecAddf(i1, v1, a);
+ VecCopyf(i2, i1);
+
+ return 1; /* one intersection only */
+ }
+ /* if not */
+ else {
+ float n[3], t[3];
+ float v3t[3], v4t[3];
+ VecSubf(t, v1, v3);
+
+ /* offset between both plane where the lines lies */
+ Crossf(n, a, b);
+ Projf(t, t, n);
+
+ /* for the first line, offset the second line until it is coplanar */
+ VecAddf(v3t, v3, t);
+ VecAddf(v4t, v4, t);
+
+ VecSubf(c, v3t, v1);
+ VecSubf(a, v2, v1);
+ VecSubf(b, v4t, v3);
+
+ Crossf(ab, a, b);
+ Crossf(cb, c, b);
+
+ VecMulf(a, Inpf(cb, ab) / Inpf(ab, ab));
+ VecAddf(i1, v1, a);
+
+ /* for the second line, just substract the offset from the first intersection point */
+ VecSubf(i2, i1, t);
+
+ return 2; /* two nearest points */
+ }
+}
+
int AabbIntersectAabb(float min1[3], float max1[3], float min2[3], float max2[3])
{
return (min1[0]<max2[0] && min1[1]<max2[1] && min1[2]<max2[2] &&
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index fa7cbb06139..9cfce5e34fa 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -3011,6 +3011,9 @@ static void lib_link_object(FileData *fd, Main *main)
bParentActuator *parenta = act->data;
parenta->ob = newlibadr(fd, ob->id.lib, parenta->ob);
}
+ else if(act->type==ACT_STATE) {
+ /* bStateActuator *statea = act->data; */
+ }
act= act->next;
}
@@ -3307,11 +3310,19 @@ static void direct_link_object(FileData *fd, Object *ob)
direct_link_constraints(fd, &ob->constraints);
link_glob_list(fd, &ob->controllers);
+ if (ob->init_state) {
+ /* if a known first state is specified, set it so that the game will start ok */
+ ob->state = ob->init_state;
+ } else if (!ob->state) {
+ ob->state = 1;
+ }
cont= ob->controllers.first;
while(cont) {
cont->data= newdataadr(fd, cont->data);
cont->links= newdataadr(fd, cont->links);
test_pointer_array(fd, (void **)&cont->links);
+ if (cont->state_mask == 0)
+ cont->state_mask = 1;
cont= cont->next;
}
@@ -7635,6 +7646,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
+
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
/* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 2595b95bbf0..9f28e13ff7b 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -715,6 +715,9 @@ static void write_actuators(WriteData *wd, ListBase *lb)
case ACT_PARENT:
writestruct(wd, DATA, "bParentActuator", 1, act->data);
break;
+ case ACT_STATE:
+ writestruct(wd, DATA, "bStateActuator", 1, act->data);
+ break;
default:
; /* error: don't know how to write this file */
}
diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h
index 94203bab447..73ef83393b0 100644
--- a/source/blender/imbuf/IMB_imbuf_types.h
+++ b/source/blender/imbuf/IMB_imbuf_types.h
@@ -149,6 +149,7 @@ typedef enum {
#define IB_zbuffloat (1 << 16)
#define IB_multilayer (1 << 17)
#define IB_imginfo (1 << 18)
+#define IB_animdeinterlace (1 << 19)
/*
* The bit flag is stored in the ImBuf.ftype variable.
diff --git a/source/blender/imbuf/intern/IMB_anim.h b/source/blender/imbuf/intern/IMB_anim.h
index 71d35949833..7dc1f966b71 100644
--- a/source/blender/imbuf/intern/IMB_anim.h
+++ b/source/blender/imbuf/intern/IMB_anim.h
@@ -183,8 +183,9 @@ struct anim {
AVFormatContext *pFormatCtx;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
- AVFrame *pFrameRGB;
AVFrame *pFrame;
+ AVFrame *pFrameRGB;
+ AVFrame *pFrameDeinterlaced;
struct SwsContext *img_convert_ctx;
int videoStream;
#endif
diff --git a/source/blender/imbuf/intern/anim.c b/source/blender/imbuf/intern/anim.c
index 87d67f5263b..720f5b0f7c8 100644
--- a/source/blender/imbuf/intern/anim.c
+++ b/source/blender/imbuf/intern/anim.c
@@ -600,6 +600,7 @@ static int startffmpeg(struct anim * anim) {
anim->videoStream = videoStream;
anim->pFrame = avcodec_alloc_frame();
+ anim->pFrameDeinterlaced = avcodec_alloc_frame();
anim->pFrameRGB = avcodec_alloc_frame();
if (avpicture_get_size(PIX_FMT_BGR32, anim->x, anim->y)
@@ -609,10 +610,20 @@ static int startffmpeg(struct anim * anim) {
avcodec_close(anim->pCodecCtx);
av_close_input_file(anim->pFormatCtx);
av_free(anim->pFrameRGB);
+ av_free(anim->pFrameDeinterlaced);
av_free(anim->pFrame);
return -1;
}
+ if (anim->ib_flags & IB_animdeinterlace) {
+ avpicture_fill((AVPicture*) anim->pFrameDeinterlaced,
+ MEM_callocN(avpicture_get_size(
+ anim->pCodecCtx->pix_fmt,
+ anim->x, anim->y),
+ "ffmpeg deinterlace"),
+ anim->pCodecCtx->pix_fmt, anim->x, anim->y);
+ }
+
if (pCodecCtx->has_b_frames) {
anim->preseek = 25; /* FIXME: detect gopsize ... */
} else {
@@ -638,12 +649,13 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
AVPacket packet;
int64_t pts_to_search = 0;
int pos_found = 1;
+ int filter_y = 0;
if (anim == 0) return (0);
ibuf = IMB_allocImBuf(anim->x, anim->y, 24, IB_rect, 0);
- avpicture_fill((AVPicture *)anim->pFrameRGB,
+ avpicture_fill((AVPicture*) anim->pFrameRGB,
(unsigned char*) ibuf->rect,
PIX_FMT_BGR32, anim->x, anim->y);
@@ -722,6 +734,32 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
}
if(frameFinished && pos_found == 1) {
+ AVFrame * input = anim->pFrame;
+
+ /* This means the data wasnt read properly,
+ this check stops crashing */
+ if (input->data[0]==0 && input->data[1]==0
+ && input->data[2]==0 && input->data[3]==0){
+ av_free_packet(&packet);
+ break;
+ }
+
+ if (anim->ib_flags & IB_animdeinterlace) {
+ if (avpicture_deinterlace(
+ (AVPicture*)
+ anim->pFrameDeinterlaced,
+ (const AVPicture*)
+ anim->pFrame,
+ anim->pCodecCtx->pix_fmt,
+ anim->pCodecCtx->width,
+ anim->pCodecCtx->height)
+ < 0) {
+ filter_y = 1;
+ } else {
+ input = anim->pFrameDeinterlaced;
+ }
+ }
+
if (G.order == B_ENDIAN) {
int * dstStride
= anim->pFrameRGB->linesize;
@@ -735,8 +773,8 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
unsigned char* top;
sws_scale(anim->img_convert_ctx,
- anim->pFrame->data,
- anim->pFrame->linesize,
+ input->data,
+ input->linesize,
0,
anim->pCodecCtx->height,
dst2,
@@ -793,27 +831,25 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
int i;
unsigned char* r;
- /* This means the data wasnt read properly, this check stops crashing */
- if (anim->pFrame->data[0]!=0 || anim->pFrame->data[1]!=0 || anim->pFrame->data[2]!=0 || anim->pFrame->data[3]!=0) {
- sws_scale(anim->img_convert_ctx,
- anim->pFrame->data,
- anim->pFrame->linesize,
- 0,
- anim->pCodecCtx->height,
- dst2,
- dstStride2);
+ sws_scale(anim->img_convert_ctx,
+ input->data,
+ input->linesize,
+ 0,
+ anim->pCodecCtx->height,
+ dst2,
+ dstStride2);
- /* workaround: sws_scale
- sets alpha = 0... */
+ /* workaround: sws_scale
+ sets alpha = 0... */
- r = (unsigned char*) ibuf->rect;
-
- for (i = 0; i < ibuf->x * ibuf->y;i++){
- r[3] = 0xff;
- r+=4;
- }
+ r = (unsigned char*) ibuf->rect;
+
+ for (i = 0; i < ibuf->x * ibuf->y;i++){
+ r[3] = 0xff;
+ r+=4;
}
+
av_free_packet(&packet);
break;
}
@@ -823,6 +859,10 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
av_free_packet(&packet);
}
+ if (filter_y && ibuf) {
+ IMB_filtery(ibuf);
+ }
+
return(ibuf);
}
@@ -834,6 +874,11 @@ static void free_anim_ffmpeg(struct anim * anim) {
av_close_input_file(anim->pFormatCtx);
av_free(anim->pFrameRGB);
av_free(anim->pFrame);
+
+ if (anim->ib_flags & IB_animdeinterlace) {
+ MEM_freeN(anim->pFrameDeinterlaced->data[0]);
+ }
+ av_free(anim->pFrameDeinterlaced);
sws_freeContext(anim->img_convert_ctx);
}
anim->duration = 0;
@@ -983,6 +1028,7 @@ struct ImBuf * IMB_anim_absolute(struct anim * anim, int position) {
char head[256], tail[256];
unsigned short digits;
int pic;
+ int filter_y = (anim->ib_flags & IB_animdeinterlace);
if (anim == NULL) return(0);
@@ -1040,6 +1086,7 @@ struct ImBuf * IMB_anim_absolute(struct anim * anim, int position) {
case ANIM_FFMPEG:
ibuf = ffmpeg_fetchibuf(anim, position);
if (ibuf) anim->curposition = position;
+ filter_y = 0; /* done internally */
break;
#endif
#ifdef WITH_REDCODE
@@ -1052,6 +1099,7 @@ struct ImBuf * IMB_anim_absolute(struct anim * anim, int position) {
if (ibuf) {
if (anim->ib_flags & IB_ttob) IMB_flipy(ibuf);
+ if (filter_y) IMB_filtery(ibuf);
sprintf(ibuf->name, "%s.%04d", anim->name, anim->curposition + 1);
}
diff --git a/source/blender/include/BIF_butspace.h b/source/blender/include/BIF_butspace.h
index cbbd8013c82..f0b37814947 100644
--- a/source/blender/include/BIF_butspace.h
+++ b/source/blender/include/BIF_butspace.h
@@ -99,6 +99,8 @@ extern void validate_editbonebutton_cb(void *bonev, void *namev);
#define BUTS_ACT_SEL 64
#define BUTS_ACT_ACT 128
#define BUTS_ACT_LINK 256
+#define BUTS_SENS_STATE 512
+#define BUTS_ACT_STATE 1024
/* buttons grid */
diff --git a/source/blender/include/BIF_interface.h b/source/blender/include/BIF_interface.h
index fbd4e4ecd91..3da4466d4d3 100644
--- a/source/blender/include/BIF_interface.h
+++ b/source/blender/include/BIF_interface.h
@@ -185,6 +185,7 @@ void uiDrawBlock(struct uiBlock *block);
void uiGetMouse(int win, short *adr);
void uiComposeLinks(uiBlock *block);
void uiSetButLock(int val, char *lockstr);
+uiBut *uiFindInlink(uiBlock *block, void *poin);
void uiClearButLock(void);
int uiDoBlocks(struct ListBase *lb, int event, int movemouse_quit);
void uiSetCurFont(uiBlock *block, int index);
diff --git a/source/blender/include/BIF_oops.h b/source/blender/include/BIF_oops.h
index adeac4f3871..2375a918d0e 100644
--- a/source/blender/include/BIF_oops.h
+++ b/source/blender/include/BIF_oops.h
@@ -43,6 +43,8 @@ struct Camera;
struct Texture;
struct Lattice;
struct bArmature;
+struct Tex;
+
void add_curve_oopslinks(struct Curve *cu, struct Oops *oops, short flag);
void add_from_link(struct Oops *from, struct Oops *oops);
void add_material_oopslinks(struct Material *ma, struct Oops *oops, short flag);
diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h
index 7571d64be91..c0542e3f34c 100644
--- a/source/blender/include/butspace.h
+++ b/source/blender/include/butspace.h
@@ -52,6 +52,8 @@ struct Image;
#define BUTS_ACT_SEL 64
#define BUTS_ACT_ACT 128
#define BUTS_ACT_LINK 256
+#define BUTS_SENS_STATE 512
+#define BUTS_ACT_STATE 1024
/* internal */
@@ -583,6 +585,8 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
#define B_SETACTOR 2715
#define B_SETMAINACTOR 2716
#define B_SETDYNA 2717
+#define B_SET_STATE_BIT 2718
+#define B_INIT_STATE_BIT 2719
/* *********************** */
#define B_FPAINTBUTS 2900
diff --git a/source/blender/include/transform.h b/source/blender/include/transform.h
index 7d497dc05ec..4e3b80134f9 100644
--- a/source/blender/include/transform.h
+++ b/source/blender/include/transform.h
@@ -102,9 +102,9 @@ typedef struct TransCon {
/* Apply function pointer for linear vectorial transformation */
/* The last three parameters are pointers to the in/out/printable vectors */
void (*applySize)(struct TransInfo *, struct TransData *, float [3][3]);
- /* Apply function pointer for rotation transformation (prototype will change */
- void (*applyRot)(struct TransInfo *, struct TransData *, float [3]);
- /* Apply function pointer for rotation transformation (prototype will change */
+ /* Apply function pointer for size transformation */
+ void (*applyRot)(struct TransInfo *, struct TransData *, float [3], float *);
+ /* Apply function pointer for rotation transformation */
} TransCon;
typedef struct TransDataIpokey {
diff --git a/source/blender/makesdna/DNA_actuator_types.h b/source/blender/makesdna/DNA_actuator_types.h
index a326f5b01d6..51f03a676e4 100644
--- a/source/blender/makesdna/DNA_actuator_types.h
+++ b/source/blender/makesdna/DNA_actuator_types.h
@@ -50,6 +50,7 @@ typedef struct bActionActuator {
short type, flag; /* Playback type */
int sta, end; /* Start & End frames */
char name[32]; /* For property-driven playback */
+ char frameProp[32]; /* Set this property to the actions current frame */
int blendin; /* Number of frames of blending */
short priority; /* Execution priority */
short strideaxis; /* Displacement axis */
@@ -80,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 {
@@ -97,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];
@@ -190,11 +192,13 @@ typedef struct bVisibilityActuator {
} bVisibilityActuator;
typedef struct bTwoDFilterActuator{
- char pad[4];
- /* Tells what type of 2D Filter*/
+ char pad[2];
+ /* bitwise flag for enabling or disabling depth(bit 0) and luminance(bit 1) */
+ short texture_flag;
+ /* Tells what type of 2D Filter */
short type;
/* (flag == 0) means 2D filter is activate and
- (flag != 0) means 2D filter is inactive*/
+ (flag != 0) means 2D filter is inactive */
short flag;
int int_arg;
/* a float argument */
@@ -208,6 +212,11 @@ typedef struct bParentActuator {
struct Object *ob;
} bParentActuator;
+typedef struct bStateActuator {
+ int type; /* 0=Set, 1=Add, 2=Rem, 3=Chg */
+ unsigned int mask; /* the bits to change */
+} bStateActuator;
+
typedef struct bActuator {
struct bActuator *next, *prev, *mynew;
short type;
@@ -246,6 +255,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
@@ -279,11 +289,14 @@ typedef struct FreeCamera {
#define ACT_2DFILTER 19
#define ACT_PARENT 20
#define ACT_SHAPEACTION 21
+#define ACT_STATE 22
/* actuator flag */
#define ACT_SHOW 1
#define ACT_DEL 2
#define ACT_NEW 4
+#define ACT_LINKED 8
+#define ACT_VISIBLE 16
/* link codes */
#define LINK_SENSOR 0
@@ -349,10 +362,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/makesdna/DNA_controller_types.h b/source/blender/makesdna/DNA_controller_types.h
index 95c9b0d0cf7..376f95b0145 100644
--- a/source/blender/makesdna/DNA_controller_types.h
+++ b/source/blender/makesdna/DNA_controller_types.h
@@ -57,7 +57,7 @@ typedef struct bController {
struct bSensor **slinks;
short val, valo;
- int pad5;
+ unsigned int state_mask;
} bController;
@@ -66,11 +66,16 @@ typedef struct bController {
#define CONT_LOGIC_OR 1
#define CONT_EXPRESSION 2
#define CONT_PYTHON 3
+#define CONT_LOGIC_NAND 4
+#define CONT_LOGIC_NOR 5
+#define CONT_LOGIC_XOR 6
+#define CONT_LOGIC_XNOR 7
/* controller->flag */
#define CONT_SHOW 1
#define CONT_DEL 2
#define CONT_NEW 4
+#define CONT_MASK 8
#endif
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index 83168248b9a..c4e8cb4925b 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -216,7 +216,9 @@ typedef struct Object {
struct DerivedMesh *derivedDeform, *derivedFinal;
int lastDataMask; /* the custom data layer mask that was last used to calculate derivedDeform and derivedFinal */
- int pad;
+ unsigned int state; /* bit masks of game controllers that are active */
+ unsigned int init_state; /* bit masks of initial state as recorded by the users */
+ int pad2;
/*#ifdef WITH_VERSE*/
void *vnode; /* pointer at object VerseNode */
@@ -440,6 +442,8 @@ extern Object workob;
#define OB_ADDCONT 512
#define OB_ADDACT 1024
#define OB_SHOWCONT 2048
+#define OB_SETSTBIT 4096
+#define OB_INITSTBIT 8192
/* ob->restrictflag */
#define OB_RESTRICT_VIEW 1
diff --git a/source/blender/makesdna/DNA_sensor_types.h b/source/blender/makesdna/DNA_sensor_types.h
index 90e2b8f9f41..ae7b92bb06c 100644
--- a/source/blender/makesdna/DNA_sensor_types.h
+++ b/source/blender/makesdna/DNA_sensor_types.h
@@ -144,7 +144,7 @@ typedef struct bSensor {
/* just add here, to avoid align errors... */
short invert; /* Whether or not to invert the output. */
- short freq2; /* The negative pulsing frequency? Not used anymore... */
+ short level; /* Whether the sensor is level base (edge by default) */
int pad;
} bSensor;
@@ -202,6 +202,7 @@ typedef struct bJoystickSensor {
#define SENS_DEL 2
#define SENS_NEW 4
#define SENS_NOT 8
+#define SENS_VISIBLE 16
/* sensor->pulse */
#define SENS_PULSE_CONT 0
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index acc1651e9fa..3de5b0ff5ba 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -310,7 +310,7 @@ extern UserDef U; /* from usiblender.c !!!! */
#define USER_DUP_ACT (1 << 10)
/* gameflags */
-#define USER_VERTEX_ARRAYS 1
+#define USER_DEPRECATED_FLAG 1
#define USER_DISABLE_SOUND 2
#define USER_DISABLE_MIPMAP 4
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_math.c b/source/blender/nodes/intern/CMP_nodes/CMP_math.c
index d00ce18a44f..421c1343df7 100644
--- a/source/blender/nodes/intern/CMP_nodes/CMP_math.c
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_math.c
@@ -57,7 +57,7 @@ static void do_math(bNode *node, float *out, float *in, float *in2)
break;
case 3: /* Divide */
{
- if(in[1]==0) /* We don't want to divide by zero. */
+ if(in2[0]==0) /* We don't want to divide by zero. */
out[0]= 0.0;
else
out[0]= in[0] / in2[0];
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/Lamp.c b/source/blender/python/api2_2x/Lamp.c
index ef3174ac4ed..53d25a6429d 100644
--- a/source/blender/python/api2_2x/Lamp.c
+++ b/source/blender/python/api2_2x/Lamp.c
@@ -1520,12 +1520,11 @@ static PyObject *Lamp_oldsetType( BPy_Lamp * self, PyObject * value )
char *type = PyString_AsString(value);
PyObject *arg, *error;
- /* parse string argument */
-
- if( !value )
- return ( EXPP_ReturnPyObjError( PyExc_TypeError,
- "expected string argument" ) );
-
+ /* parse string argument */
+ if( !type )
+ return EXPP_ReturnPyObjError ( PyExc_TypeError,
+ "expected string argument" );
+
/* check for valid arguments, set type accordingly */
if( !strcmp( type, "Lamp" ) )
@@ -1546,7 +1545,7 @@ static PyObject *Lamp_oldsetType( BPy_Lamp * self, PyObject * value )
/* build tuple, call wrapper */
- arg = Py_BuildValue( "(i)", type );
+ arg = Py_BuildValue( "(i)", self->lamp->type );
error = EXPP_setterWrapper ( (void *)self, arg, (setter)Lamp_setType );
Py_DECREF ( arg );
return error;
diff --git a/source/blender/python/api2_2x/Mathutils.c b/source/blender/python/api2_2x/Mathutils.c
index 87ac3e3e6ba..85c56a61628 100644
--- a/source/blender/python/api2_2x/Mathutils.c
+++ b/source/blender/python/api2_2x/Mathutils.c
@@ -1452,8 +1452,8 @@ PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args )
"vectors must be of the same size\n" ) );
if( vec1->size == 3 || vec1->size == 2) {
- float a[3], b[3], c[3], ab[3], cb[3], dir1[3], dir2[3];
- float d;
+ int result;
+
if (vec1->size == 3) {
VECCOPY(v1, vec1->vec);
VECCOPY(v2, vec2->vec);
@@ -1477,63 +1477,19 @@ PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args )
v4[1] = vec4->vec[1];
v4[2] = 0.0f;
}
+
+ result = LineIntersectLine(v1, v2, v3, v4, i1, i2);
- VecSubf(c, v3, v1);
- VecSubf(a, v2, v1);
- VecSubf(b, v4, v3);
-
- VECCOPY(dir1, a);
- Normalize(dir1);
- VECCOPY(dir2, b);
- Normalize(dir2);
- d = Inpf(dir1, dir2);
- if (d == 1.0f || d == -1.0f) {
+ if (result == 0) {
/* colinear */
return EXPP_incr_ret( Py_None );
}
-
- Crossf(ab, a, b);
- d = Inpf(c, ab);
-
- /* test if the two lines are coplanar */
- if (d > -0.000001f && d < 0.000001f) {
- Crossf(cb, c, b);
-
- VecMulf(a, Inpf(cb, ab) / Inpf(ab, ab));
- VecAddf(i1, v1, a);
- VECCOPY(i2, i1);
- }
- /* if not */
else {
- float n[3], t[3];
- VecSubf(t, v1, v3);
-
- /* offset between both plane where the lines lies */
- Crossf(n, a, b);
- Projf(t, t, n);
-
- /* for the first line, offset the second line until it is coplanar */
- VecAddf(v3, v3, t);
- VecAddf(v4, v4, t);
-
- VecSubf(c, v3, v1);
- VecSubf(a, v2, v1);
- VecSubf(b, v4, v3);
-
- Crossf(ab, a, b);
- Crossf(cb, c, b);
-
- VecMulf(a, Inpf(cb, ab) / Inpf(ab, ab));
- VecAddf(i1, v1, a);
-
- /* for the second line, just substract the offset from the first intersection point */
- VecSubf(i2, i1, t);
+ tuple = PyTuple_New( 2 );
+ PyTuple_SetItem( tuple, 0, newVectorObject(i1, vec1->size, Py_NEW) );
+ PyTuple_SetItem( tuple, 1, newVectorObject(i2, vec1->size, Py_NEW) );
+ return tuple;
}
-
- tuple = PyTuple_New( 2 );
- PyTuple_SetItem( tuple, 0, newVectorObject(i1, vec1->size, Py_NEW) );
- PyTuple_SetItem( tuple, 1, newVectorObject(i2, vec1->size, Py_NEW) );
- return tuple;
}
else {
return ( EXPP_ReturnPyObjError( PyExc_TypeError,
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/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index ebb52c49132..6a0af82b4d7 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -2675,9 +2675,9 @@ void RE_set_max_threads(int threads)
void RE_init_threadcount(Render *re)
{
- if ((re->r.mode & R_FIXED_THREADS)==0 || commandline_threads == 0) { /* Automatic threads */
+ if(commandline_threads >= 1) { /* only set as an arg in background mode */
+ re->r.threads= MIN2(commandline_threads, BLENDER_MAX_THREADS);
+ } else if ((re->r.mode & R_FIXED_THREADS)==0 || commandline_threads == 0) { /* Automatic threads */
re->r.threads = BLI_system_thread_count();
- } else if(commandline_threads >= 1 && commandline_threads<=BLENDER_MAX_THREADS) {
- re->r.threads= commandline_threads;
}
}
diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c
index a9261185f42..179a094a981 100644
--- a/source/blender/src/buttons_editing.c
+++ b/source/blender/src/buttons_editing.c
@@ -6311,7 +6311,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 b6877b2e2b7..4e5e8a605ee 100644
--- a/source/blender/src/buttons_logic.c
+++ b/source/blender/src/buttons_logic.c
@@ -88,6 +88,7 @@
#include "mydevice.h"
#include "nla.h" /* For __NLA : Important, do not remove */
#include "butspace.h" // own module
+#include "interface.h"
/* internals */
void buttons_enji(uiBlock *, Object *);
@@ -228,7 +229,7 @@ static void sca_move_sensor(void *datav, void *data2_unused)
bSensor *sens_to_delete= datav;
int val;
Base *base;
- bSensor *sens;
+ bSensor *sens, *tmp;
val= pupmenu("Move up%x1|Move down %x2");
@@ -245,12 +246,24 @@ static void sca_move_sensor(void *datav, void *data2_unused)
if(sens) {
if( val==1 && sens->prev) {
- BLI_remlink(&base->object->sensors, sens);
- BLI_insertlinkbefore(&base->object->sensors, sens->prev, sens);
+ for (tmp=sens->prev; tmp; tmp=tmp->prev) {
+ if (tmp->flag & SENS_VISIBLE)
+ break;
+ }
+ if (tmp) {
+ BLI_remlink(&base->object->sensors, sens);
+ BLI_insertlinkbefore(&base->object->sensors, tmp, sens);
+ }
}
else if( val==2 && sens->next) {
- BLI_remlink(&base->object->sensors, sens);
- BLI_insertlink(&base->object->sensors, sens->next, sens);
+ for (tmp=sens->next; tmp; tmp=tmp->next) {
+ if (tmp->flag & SENS_VISIBLE)
+ break;
+ }
+ if (tmp) {
+ BLI_remlink(&base->object->sensors, sens);
+ BLI_insertlink(&base->object->sensors, tmp, sens);
+ }
}
BIF_undo_push("Move sensor");
allqueue(REDRAWBUTSLOGIC, 0);
@@ -267,7 +280,7 @@ static void sca_move_controller(void *datav, void *data2_unused)
bController *controller_to_del= datav;
int val;
Base *base;
- bController *cont;
+ bController *cont, *tmp;
val= pupmenu("Move up%x1|Move down %x2");
@@ -284,12 +297,27 @@ static void sca_move_controller(void *datav, void *data2_unused)
if(cont) {
if( val==1 && cont->prev) {
- BLI_remlink(&base->object->controllers, cont);
- BLI_insertlinkbefore(&base->object->controllers, cont->prev, cont);
+ /* locate the controller that has the same state mask but is earlier in the list */
+ tmp = cont->prev;
+ while(tmp) {
+ if(tmp->state_mask & cont->state_mask)
+ break;
+ tmp = tmp->prev;
+ }
+ if (tmp) {
+ BLI_remlink(&base->object->controllers, cont);
+ BLI_insertlinkbefore(&base->object->controllers, tmp, cont);
+ }
}
else if( val==2 && cont->next) {
+ tmp = cont->next;
+ while(tmp) {
+ if(tmp->state_mask & cont->state_mask)
+ break;
+ tmp = tmp->next;
+ }
BLI_remlink(&base->object->controllers, cont);
- BLI_insertlink(&base->object->controllers, cont->next, cont);
+ BLI_insertlink(&base->object->controllers, tmp, cont);
}
BIF_undo_push("Move controller");
allqueue(REDRAWBUTSLOGIC, 0);
@@ -306,7 +334,7 @@ static void sca_move_actuator(void *datav, void *data2_unused)
bActuator *actuator_to_move= datav;
int val;
Base *base;
- bActuator *act;
+ bActuator *act, *tmp;
val= pupmenu("Move up%x1|Move down %x2");
@@ -323,12 +351,25 @@ static void sca_move_actuator(void *datav, void *data2_unused)
if(act) {
if( val==1 && act->prev) {
- BLI_remlink(&base->object->actuators, act);
- BLI_insertlinkbefore(&base->object->actuators, act->prev, act);
+ /* locate the first visible actuators before this one */
+ for (tmp = act->prev; tmp; tmp=tmp->prev) {
+ if (tmp->flag & ACT_VISIBLE)
+ break;
+ }
+ if (tmp) {
+ BLI_remlink(&base->object->actuators, act);
+ BLI_insertlinkbefore(&base->object->actuators, tmp, act);
+ }
}
else if( val==2 && act->next) {
- BLI_remlink(&base->object->actuators, act);
- BLI_insertlink(&base->object->actuators, act->next, act);
+ for (tmp=act->next; tmp; tmp=tmp->next) {
+ if (tmp->flag & ACT_VISIBLE)
+ break;
+ }
+ if (tmp) {
+ BLI_remlink(&base->object->actuators, act);
+ BLI_insertlink(&base->object->actuators, tmp, act);
+ }
}
BIF_undo_push("Move actuator");
allqueue(REDRAWBUTSLOGIC, 0);
@@ -348,7 +389,7 @@ void do_logic_buts(unsigned short event)
bActuator *act;
Base *base;
Object *ob;
- int didit;
+ int didit, bit;
ob= OBACT;
if(ob==0) return;
@@ -462,6 +503,18 @@ void do_logic_buts(unsigned short event)
make_unique_prop_names(cont->name);
base->object->scaflag |= OB_SHOWCONT;
BLI_addtail(&(base->object->controllers), cont);
+ /* set the controller state mask from the current object state.
+ A controller is always in a single state, so select the lowest bit set
+ from the object state */
+ for (bit=0; bit<32; bit++) {
+ if (base->object->state & (1<<bit))
+ break;
+ }
+ cont->state_mask = (1<<bit);
+ if (cont->state_mask == 0) {
+ /* shouldn't happen, object state is never 0 */
+ cont->state_mask = 1;
+ }
}
base= base->next;
}
@@ -469,6 +522,32 @@ void do_logic_buts(unsigned short event)
allqueue(REDRAWBUTSLOGIC, 0);
break;
+ case B_SET_STATE_BIT:
+ base= FIRSTBASE;
+ while(base) {
+ if(base->object->scaflag & OB_SETSTBIT) {
+ base->object->scaflag &= ~OB_SETSTBIT;
+ base->object->state = 0x3FFFFFFF;
+ }
+ base= base->next;
+ }
+ allqueue(REDRAWBUTSLOGIC, 0);
+ break;
+
+ case B_INIT_STATE_BIT:
+ base= FIRSTBASE;
+ while(base) {
+ if(base->object->scaflag & OB_INITSTBIT) {
+ base->object->scaflag &= ~OB_INITSTBIT;
+ base->object->state = base->object->init_state;
+ if (!base->object->state)
+ base->object->state = 1;
+ }
+ base= base->next;
+ }
+ allqueue(REDRAWBUTSLOGIC, 0);
+ break;
+
case B_CHANGE_CONT:
base= FIRSTBASE;
while(base) {
@@ -505,7 +584,7 @@ void do_logic_buts(unsigned short event)
BIF_undo_push("Delete controller");
allqueue(REDRAWBUTSLOGIC, 0);
break;
-
+
case B_ADD_ACT:
base= FIRSTBASE;
while(base) {
@@ -661,6 +740,14 @@ static char *controller_name(int type)
return "AND";
case CONT_LOGIC_OR:
return "OR";
+ case CONT_LOGIC_NAND:
+ return "NAND";
+ case CONT_LOGIC_NOR:
+ return "NOR";
+ case CONT_LOGIC_XOR:
+ return "XOR";
+ case CONT_LOGIC_XNOR:
+ return "XNOR";
case CONT_EXPRESSION:
return "Expression";
case CONT_PYTHON:
@@ -671,7 +758,7 @@ static char *controller_name(int type)
static char *controller_pup(void)
{
- return "Controllers %t|AND %x0|OR %x1|Expression %x2|Python %x3";
+ return "Controllers %t|AND %x0|OR %x1|XOR %x6|NAND %x4|NOR %x5|XNOR %x7|Expression %x2|Python %x3";
}
static char *actuator_name(int type)
@@ -717,6 +804,8 @@ static char *actuator_name(int type)
return "2D Filter";
case ACT_PARENT:
return "Parent";
+ case ACT_STATE:
+ return "State";
}
return "unknown";
}
@@ -732,21 +821,21 @@ static char *actuator_pup(Object *owner)
return "Actuators %t|Action %x15|Motion %x0|Constraint %x9|Ipo %x1"
"|Camera %x3|Sound %x5|Property %x6|Edit Object %x10"
"|Scene %x11|Random %x13|Message %x14|CD %x16|Game %x17"
- "|Visibility %x18|2D Filter %x19|Parent %x20";
+ "|Visibility %x18|2D Filter %x19|Parent %x20|State %x22";
break;
case OB_MESH:
return "Actuators %t|Shape Action %x21|Motion %x0|Constraint %x9|Ipo %x1"
"|Camera %x3|Sound %x5|Property %x6|Edit Object %x10"
"|Scene %x11|Random %x13|Message %x14|CD %x16|Game %x17"
- "|Visibility %x18|2D Filter %x19|Parent %x20";
+ "|Visibility %x18|2D Filter %x19|Parent %x20|State %x22";
break;
default:
return "Actuators %t|Motion %x0|Constraint %x9|Ipo %x1"
"|Camera %x3|Sound %x5|Property %x6|Edit Object %x10"
"|Scene %x11|Random %x13|Message %x14|CD %x16|Game %x17"
- "|Visibility %x18|2D Filter %x19|Parent %x20";
+ "|Visibility %x18|2D Filter %x19|Parent %x20|State %x22";
}
}
@@ -815,7 +904,8 @@ static ID **get_selected_and_linked_obs(short *count, short scavisflag)
if(scavisflag & BUTS_ACT_ACT) OBACT->scavisflag |= OB_VIS_ACT;
}
- if(scavisflag & (BUTS_SENS_LINK|BUTS_CONT_LINK|BUTS_ACT_LINK)) {
+ /* BUTS_XXX_STATE are similar to BUTS_XXX_LINK for selecting the object */
+ if(scavisflag & (BUTS_SENS_LINK|BUTS_CONT_LINK|BUTS_ACT_LINK|BUTS_SENS_STATE|BUTS_ACT_STATE)) {
doit= 1;
while(doit) {
doit= 0;
@@ -824,7 +914,7 @@ static ID **get_selected_and_linked_obs(short *count, short scavisflag)
while(ob) {
/* 1st case: select sensor when controller selected */
- if((scavisflag & BUTS_SENS_LINK) && (ob->scavisflag & OB_VIS_SENS)==0) {
+ if((scavisflag & (BUTS_SENS_LINK|BUTS_SENS_STATE)) && (ob->scavisflag & OB_VIS_SENS)==0) {
sens= ob->sensors.first;
while(sens) {
for(a=0; a<sens->totlinks; a++) {
@@ -879,7 +969,7 @@ static ID **get_selected_and_linked_obs(short *count, short scavisflag)
}
/* 4th case: select actuator when controller selected */
- if( (scavisflag & BUTS_ACT_LINK) && (ob->scavisflag & OB_VIS_CONT)) {
+ if( (scavisflag & (BUTS_ACT_LINK|BUTS_ACT_STATE)) && (ob->scavisflag & OB_VIS_CONT)) {
cont= ob->controllers.first;
while(cont) {
for(a=0; a<cont->totlinks; a++) {
@@ -984,6 +1074,10 @@ static void draw_default_sensor_header(bSensor *sens,
(short)(x + 10 + 0.85 * (w-20)), (short)(y - 19), (short)(0.15 * (w-20)), 19,
&sens->invert, 0.0, 0.0, 0, 0,
"Invert the level (output) of this sensor");
+ uiDefButS(block, TOG, 1, "Lvl",
+ (short)(x + 10 + 0.70 * (w-20)), (short)(y - 19), (short)(0.15 * (w-20)), 19,
+ &sens->level, 0.0, 0.0, 0, 0,
+ "Level detector versus edge detector (only applicable in case of logic state transition)");
}
static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short yco, short width,char* objectname)
@@ -1458,6 +1552,7 @@ static int get_col_actuator(int type)
case ACT_GAME: return TH_BUT_SETTING2;
case ACT_VISIBILITY: return TH_BUT_NUM;
case ACT_CONSTRAINT: return TH_BUT_ACTION;
+ case ACT_STATE: return TH_BUT_SETTING2;
default: return TH_BUT_NEUTRAL;
}
}
@@ -1468,7 +1563,23 @@ static void set_col_actuator(int item, int medium)
}
-static short draw_actuatorbuttons(bActuator *act, uiBlock *block, short xco, short yco, short width)
+char *get_state_name(Object *ob, short bit)
+{
+ bController *cont;
+ unsigned int mask;
+
+ mask = (1<<bit);
+ cont = ob->controllers.first;
+ while (cont) {
+ if (cont->state_mask & mask) {
+ return cont->name;
+ }
+ cont = cont->next;
+ }
+ return (char*)"";
+}
+
+static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, short xco, short yco, short width)
{
bSoundActuator *sa = NULL;
bCDActuator *cda = NULL;
@@ -1487,11 +1598,12 @@ static short draw_actuatorbuttons(bActuator *act, uiBlock *block, short xco, sho
bVisibilityActuator *visAct = NULL;
bTwoDFilterActuator *tdfa = NULL;
bParentActuator *parAct = NULL;
+ bStateActuator *staAct = NULL;
float *fp;
short ysize = 0, wval;
char *str;
- int myline;
+ int myline, stbit;
/* yco is at the top of the rect, draw downwards */
uiBlockSetEmboss(block, UI_EMBOSSM);
@@ -1501,7 +1613,7 @@ static short draw_actuatorbuttons(bActuator *act, uiBlock *block, short xco, sho
{
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);
@@ -1539,14 +1651,18 @@ static short draw_actuatorbuttons(bActuator *act, uiBlock *block, short xco, sho
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;
@@ -1573,31 +1689,34 @@ static short draw_actuatorbuttons(bActuator *act, uiBlock *block, short xco, sho
#else
str= "Action types %t|Play %x0|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x6";
#endif
- uiDefButS(block, MENU, B_REDR, str, xco+30, yco-24, width-60, 19, &aa->type, 0.0, 0.0, 0.0, 0.0, "Action playback type");
- uiDefIDPoinBut(block, test_actionpoin_but, ID_AC, 1, "AC: ", xco+30, yco-44, width-60, 19, &aa->act, "Action name");
+ uiDefButS(block, MENU, B_REDR, str, xco+30, yco-24, (width-60)/2, 19, &aa->type, 0.0, 0.0, 0.0, 0.0, "Action playback type");
+ uiDefIDPoinBut(block, test_actionpoin_but, ID_AC, 1, "AC: ", xco+30 + ((width-60)/2), yco-24, (width-60)/2, 19, &aa->act, "Action name");
if(aa->type == ACT_ACTION_FROM_PROP)
{
- uiDefBut(block, TEX, 0, "Prop: ",xco+30, yco-64, width-60, 19, aa->name, 0.0, 31.0, 0, 0, "Use this property to define the Action position");
+ uiDefBut(block, TEX, 0, "Prop: ",xco+30, yco-44, width-60, 19, aa->name, 0.0, 31.0, 0, 0, "Use this property to define the Action position");
}
else
{
- uiDefButI(block, NUM, 0, "Sta: ",xco+30, yco-64, (width-60)/2, 19, &aa->sta, 0.0, MAXFRAMEF, 0, 0, "Start frame");
- uiDefButI(block, NUM, 0, "End: ",xco+30+(width-60)/2, yco-64, (width-60)/2, 19, &aa->end, 0.0, MAXFRAMEF, 0, 0, "End frame");
+ uiDefButI(block, NUM, 0, "Sta: ",xco+30, yco-44, (width-60)/2, 19, &aa->sta, 0.0, MAXFRAMEF, 0, 0, "Start frame");
+ uiDefButI(block, NUM, 0, "End: ",xco+30+(width-60)/2, yco-44, (width-60)/2, 19, &aa->end, 0.0, MAXFRAMEF, 0, 0, "End frame");
}
+
+ uiDefButI(block, NUM, 0, "Blendin: ", xco+30, yco-64, (width-60)/2, 19, &aa->blendin, 0.0, MAXFRAMEF, 0.0, 0.0, "Number of frames of motion blending");
+ uiDefButS(block, NUM, 0, "Priority: ", xco+30+(width-60)/2, yco-64, (width-60)/2, 19, &aa->priority, 0.0, 100.0, 0.0, 0.0, "Execution priority - lower numbers will override actions with higher numbers, With 2 or more actions at once, the overriding channels must be lower in the stack");
-
-
- uiDefButI(block, NUM, 0, "Blendin: ", xco+30, yco-84, (width-60)/2, 19, &aa->blendin, 0.0, MAXFRAMEF, 0.0, 0.0, "Number of frames of motion blending");
- uiDefButS(block, NUM, 0, "Priority: ", xco+30+(width-60)/2, yco-84, (width-60)/2, 19, &aa->priority, 0.0, 100.0, 0.0, 0.0, "Execution priority - lower numbers will override actions with higher numbers");
+ uiDefBut(block, TEX, 0, "FrameProp: ",xco+30, yco-84, width-60, 19, aa->frameProp, 0.0, 31.0, 0, 0, "Assign this property this actions current frame number");
+
#ifdef __NLA_ACTION_BY_MOTION_ACTUATOR
if(aa->type == ACT_ACTION_MOTION)
{
- uiDefButF(block, NUM, 0, "Cycle: ",xco+30, yco-104, (width-60)/2, 19, &aa->stridelength, 0.0, 2500.0, 0, 0, "Distance covered by a single cycle of the action");
+ uiDefButF(block, NUM, 0, "Cycle: ",xco+30, yco-84, (width-60)/2, 19, &aa->stridelength, 0.0, 2500.0, 0, 0, "Distance covered by a single cycle of the action");
}
#endif
+
+
yco-=ysize;
break;
}
@@ -1821,8 +1940,15 @@ static short draw_actuatorbuttons(bActuator *act, uiBlock *block, short xco, sho
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;
@@ -2022,6 +2148,37 @@ static short draw_actuatorbuttons(bActuator *act, uiBlock *block, short xco, sho
break;
+ case ACT_STATE:
+ ysize = 34;
+
+ glRects(xco, yco-ysize, xco+width, yco);
+ uiEmboss((float)xco,
+ (float)yco-ysize, (float)xco+width, (float)yco, 1);
+
+ staAct = act->data;
+
+ str= "Operation %t|Cpy %x0|Add %x1|Sub %x2|Inv %x3";
+
+ uiDefButI(block, MENU, B_REDR, str,
+ xco + 10, yco - 24, 65, 19, &staAct->type,
+ 0.0, 0.0, 0, 0,
+ "Select the bit operation on object state mask");
+
+ for (wval=0; wval<15; wval+=5) {
+ uiBlockBeginAlign(block);
+ for (stbit=0; stbit<5; stbit++) {
+ uiDefButBitI(block, TOG, (1<<(stbit+wval)), 0, "", (short)(xco+85+12*stbit+13*wval), yco-17, 12, 12, (int *)&(staAct->mask), 0, 0, 0, 0, get_state_name(ob, (short)(wval+stbit)));
+ }
+ for (stbit=0; stbit<5; stbit++) {
+ uiDefButBitI(block, TOG, (1<<(stbit+wval+15)), 0, "", (short)(xco+85+12*stbit+13*wval), yco-29, 12, 12, (int *)&(staAct->mask), 0, 0, 0, 0, get_state_name(ob, (short)(wval+stbit+15)));
+ }
+ }
+ uiBlockEndAlign(block);
+
+ yco-= ysize;
+
+ break;
+
case ACT_RANDOM:
ysize = 69;
@@ -2225,7 +2382,11 @@ static short draw_actuatorbuttons(bActuator *act, uiBlock *block, short xco, sho
break;
case ACT_2DFILTER_CUSTOMFILTER:
uiDefButI(block, NUM, B_REDR, "Pass Number:", xco+30,yco-44,width-60,19,&tdfa->int_arg,0.0,MAX_RENDER_PASS-1,0.0,0.0,"Set motion blur value");
- uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "Script: ", xco+30,yco-64,width-60, 19, &tdfa->text, "");
+ uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "Script: ", xco+30,yco-64,width/2-32, 19, &tdfa->text, "");
+ uiDefButS(block, TOG|BIT|0, B_REDR, "Depth", xco+width/2+2 , yco - 64, width/4-16 , 19,
+ &tdfa->texture_flag, 0.0, 0.0, 0, 0, "Includes Depth Texture (bgl_DepthTexture)");
+ uiDefButS(block, TOG|BIT|1, B_REDR, "Luminance", xco+3*width/4-14 , yco - 64, width/4-16 , 19,
+ &tdfa->texture_flag, 0.0, 0.0, 0, 0, "Includes Luminance Texture (bgl_LuminanceTexture)");
break;
}
@@ -2596,6 +2757,118 @@ void buttons_bullet(uiBlock *block, Object *ob)
uiBlockEndAlign(block);
}
+static void check_object_state(void *arg1_but, void *arg2_mask)
+{
+ unsigned int *cont_mask = arg2_mask;
+ uiBut *but = arg1_but;
+
+ if (*cont_mask == 0 || !(G.qual & LR_SHIFTKEY))
+ *cont_mask = (1<<but->retval);
+ but->retval = B_REDR;
+}
+
+static void check_controller_state_mask(void *arg1_but, void *arg2_mask)
+{
+ unsigned int *cont_mask = arg2_mask;
+ uiBut *but = arg1_but;
+
+ /* a controller is always in a single state */
+ *cont_mask = (1<<but->retval);
+ but->retval = B_REDR;
+}
+
+static int first_bit(unsigned int mask)
+{
+ int bit;
+
+ for (bit=0; bit<32; bit++) {
+ if (mask & (1<<bit))
+ return bit;
+ }
+ return -1;
+}
+
+static uiBlock *controller_state_mask_menu(void *arg_cont)
+{
+ uiBlock *block;
+ uiBut *but;
+ bController *cont = arg_cont;
+
+ short yco = 12, xco = 0, stbit, offset;
+
+ block= uiNewBlock(&curarea->uiblocks, "Controller state mask", UI_EMBOSS, UI_HELV, curarea->win);
+
+ /* use this for a fake extra empy space around the buttons */
+ uiDefBut(block, LABEL, 0, "", -5, -5, 200, 34, NULL, 0, 0, 0, 0, "");
+
+ for (offset=0; offset<15; offset+=5) {
+ uiBlockBeginAlign(block);
+ for (stbit=0; stbit<5; stbit++) {
+ but = uiDefButBitI(block, TOG, (1<<(stbit+offset)), (stbit+offset), "", (short)(xco+12*stbit+13*offset), yco, 12, 12, (int *)&(cont->state_mask), 0, 0, 0, 0, "");
+ uiButSetFunc(but, check_controller_state_mask, but, &(cont->state_mask));
+ }
+ for (stbit=0; stbit<5; stbit++) {
+ but = uiDefButBitI(block, TOG, (1<<(stbit+offset+15)), (stbit+offset+15), "", (short)(xco+12*stbit+13*offset), yco-12, 12, 12, (int *)&(cont->state_mask), 0, 0, 0, 0, "");
+ uiButSetFunc(but, check_controller_state_mask, but, &(cont->state_mask));
+ }
+ }
+ uiBlockEndAlign(block);
+
+ uiBlockSetDirection(block, UI_TOP);
+
+ return block;
+}
+
+static void do_object_state_menu(void *arg, int event)
+{
+ Object *ob = arg;
+
+ switch (event) {
+ case 0:
+ ob->state = 0x3FFFFFFF;
+ break;
+ case 1:
+ ob->state = ob->init_state;
+ if (!ob->state)
+ ob->state = 1;
+ break;
+ case 2:
+ ob->init_state = ob->state;
+ break;
+ }
+ allqueue(REDRAWBUTSLOGIC, 0);
+}
+
+static uiBlock *object_state_mask_menu(void *arg_obj)
+{
+ uiBlock *block;
+ short xco = 0;
+
+ block= uiNewBlock(&curarea->uiblocks, "obstatemenu", UI_EMBOSSP, UI_HELV, curarea->win);
+ uiBlockSetButmFunc(block, do_object_state_menu, arg_obj);
+
+ uiDefBut(block, BUTM, 1, "Set all bits", 0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefBut(block, BUTM, 1, "Recall init state", 0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 1, "");
+ uiDefBut(block, SEPR, 0, "", 0, (short)(xco-=6), 160, 6, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, BUTM, 1, "Store init state", 0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 2, "");
+
+ uiBlockSetDirection(block, UI_TOP);
+ return block;
+}
+
+static int is_sensor_linked(uiBlock *block, bSensor *sens)
+{
+ bController *cont;
+ int i, count;
+
+ for (count=0, i=0; i<sens->totlinks; i++) {
+ cont = sens->links[i];
+ if (uiFindInlink(block, cont) != NULL)
+ return 1;
+ }
+ return 0;
+}
+
/* never used, see CVS 1.134 for the code */
/* static FreeCamera *new_freecamera(void) */
@@ -2614,7 +2887,7 @@ void logic_buts(void)
uiBlock *block;
uiBut *but;
World *wrld;
- int a;
+ int a, iact, stbit, offset;
short xco, yco, count, width, ycoo;
char *pupstr, name[32];
@@ -2686,158 +2959,241 @@ void logic_buts(void)
uiClearButLock();
idar= get_selected_and_linked_obs(&count, G.buts->scaflag);
-
+
+ /* clean ACT_LINKED and ACT_VISIBLE of all potentially visible actuators so that
+ we can determine which is actually linked/visible */
+ for(a=0; a<count; a++) {
+ ob= (Object *)idar[a];
+ act= ob->actuators.first;
+ while(act) {
+ act->flag &= ~(ACT_LINKED|ACT_VISIBLE);
+ act = act->next;
+ }
+ /* same for sensors */
+ sens= ob->sensors.first;
+ while(sens) {
+ sens->flag &= ~(SENS_VISIBLE);
+ sens = sens->next;
+ }
+ }
+
+ /* start with the controller because we need to know which one is visible */
/* ******************************* */
- xco= 375; yco= 170; width= 230;
+ xco= 695; yco= 170; width= 275;
uiBlockSetEmboss(block, UI_EMBOSSP);
- uiDefBlockBut(block, sensor_menu, NULL, "Sensors", xco-10, yco+35, 80, 19, "");
+ uiDefBlockBut(block, controller_menu, NULL, "Controllers", xco-10, yco+35, 100, 19, "");
uiBlockSetEmboss(block, UI_EMBOSS);
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, BUTS_SENS_SEL, B_REDR, "Sel", xco+110, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show all selected Objects");
- uiDefButBitS(block, TOG, BUTS_SENS_ACT, B_REDR, "Act", xco+110+(width-100)/3, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show active Object");
- uiDefButBitS(block, TOG, BUTS_SENS_LINK, B_REDR, "Link", xco+110+2*(width-100)/3, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller");
+ uiDefButBitS(block, TOG, BUTS_CONT_SEL, B_REDR, "Sel", xco+110, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show all selected Objects");
+ uiDefButBitS(block, TOG, BUTS_CONT_ACT, B_REDR, "Act", xco+110+(width-100)/3, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show active Object");
+ uiDefButBitS(block, TOG, BUTS_CONT_LINK, B_REDR, "Link", xco+110+2*(width-100)/3, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show linked Objects to Sensor/Actuator");
uiBlockEndAlign(block);
+ ob= OBACT;
+
for(a=0; a<count; a++) {
ob= (Object *)idar[a];
uiClearButLock();
uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
-
- if( (ob->scavisflag & OB_VIS_SENS) == 0) continue;
-
+ if( (ob->scavisflag & OB_VIS_CONT) == 0) continue;
+
/* presume it is only objects for now */
uiBlockSetEmboss(block, UI_EMBOSS);
uiBlockBeginAlign(block);
- if(ob->sensors.first) uiSetCurFont(block, UI_HELVB);
- uiDefButBitS(block, TOG, OB_SHOWSENS, B_REDR, ob->id.name+2,(short)(xco-10), yco, (short)(width-30), 19, &ob->scaflag, 0, 31, 0, 0, "Object name, click to show/hide sensors");
- if(ob->sensors.first) uiSetCurFont(block, UI_HELV);
- uiDefButBitS(block, TOG, OB_ADDSENS, B_ADD_SENS, "Add",(short)(xco+width-40), yco, 50, 19, &ob->scaflag, 0, 0, 0, 0, "Add a new Sensor");
+ if(ob->controllers.first) uiSetCurFont(block, UI_HELVB);
+ uiDefButBitS(block, TOG, OB_SHOWCONT, B_REDR, ob->id.name+2,(short)(xco-10), yco, (short)(width-30), 19, &ob->scaflag, 0, 0, 0, 0, "Active Object name");
+ if(ob->controllers.first) uiSetCurFont(block, UI_HELV);
+ uiDefButBitS(block, TOG, OB_ADDCONT, B_ADD_CONT, "Add",(short)(xco+width-40), yco, 50, 19, &ob->scaflag, 0, 0, 0, 0, "Add a new Controller");
uiBlockEndAlign(block);
- yco-=20;
+ yco-=17;
- if(ob->scaflag & OB_SHOWSENS) {
-
- sens= ob->sensors.first;
- while(sens) {
- uiBlockSetEmboss(block, UI_EMBOSSM);
- uiDefIconButBitS(block, TOG, SENS_DEL, B_DEL_SENS, ICON_X, xco, yco, 22, 19, &sens->flag, 0, 0, 0, 0, "Delete Sensor");
- uiDefIconButBitS(block, ICONTOG, SENS_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &sens->flag, 0, 0, 0, 0, "Sensor settings");
+ /* mark all actuators linked to these controllers */
+ /* note that some of these actuators could be from objects that are not in the display list.
+ It's ok because those actuators will not be displayed here */
+ cont= ob->controllers.first;
+ while(cont) {
+ for (iact=0; iact<cont->totlinks; iact++) {
+ act = cont->links[iact];
+ act->flag |= ACT_LINKED;
+ }
+ cont = cont->next;
+ }
- ycoo= yco;
- if(sens->flag & SENS_SHOW)
- {
- uiDefButS(block, MENU, B_CHANGE_SENS, sensor_pup(), (short)(xco+22), yco, 100, 19, &sens->type, 0, 0, 0, 0, "Sensor type");
- but= uiDefBut(block, TEX, 1, "", (short)(xco+122), yco, (short)(width-144), 19, sens->name, 0, 31, 0, 0, "Sensor name");
- uiButSetFunc(but, make_unique_prop_names_cb, sens->name, (void*) 0);
+ if(ob->scaflag & OB_SHOWCONT) {
- sens->otype= sens->type;
- yco= draw_sensorbuttons(sens, block, xco, yco, width,ob->id.name);
- if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2;
+ /* first show the state */
+ uiBlockSetEmboss(block, UI_EMBOSSP);
+ uiDefBlockBut(block, object_state_mask_menu, ob, "State", (short)(xco-10), (short)(yco-10), 40, 19, "Object state menu: store and retrieve initial state");
+ uiBlockSetEmboss(block, UI_EMBOSS);
+ if (!ob->state)
+ ob->state = 1;
+ for (offset=0; offset<15; offset+=5) {
+ uiBlockBeginAlign(block);
+ for (stbit=0; stbit<5; stbit++) {
+ but = uiDefButBitI(block, TOG, 1<<(stbit+offset), stbit+offset, "", (short)(xco+35+12*stbit+13*offset), yco, 12, 12, (int *)&(ob->state), 0, 0, 0, 0, get_state_name(ob, (short)(stbit+offset)));
+ uiButSetFunc(but, check_object_state, but, &(ob->state));
}
- else {
- set_col_sensor(sens->type, 1);
- glRecti(xco+22, yco, xco+width-22,yco+19);
- but= uiDefBut(block, LABEL, 0, sensor_name(sens->type), (short)(xco+22), yco, 100, 19, sens, 0, 0, 0, 0, "");
- uiButSetFunc(but, sca_move_sensor, sens, NULL);
- but= uiDefBut(block, LABEL, 0, sens->name, (short)(xco+122), yco, (short)(width-144), 19, sens, 0, 31, 0, 0, "");
- uiButSetFunc(but, sca_move_sensor, sens, NULL);
+ for (stbit=0; stbit<5; stbit++) {
+ but = uiDefButBitI(block, TOG, 1<<(stbit+offset+15), stbit+offset+15, "", (short)(xco+35+12*stbit+13*offset), yco-12, 12, 12, (int *)&(ob->state), 0, 0, 0, 0, get_state_name(ob, (short)(stbit+offset+15)));
+ uiButSetFunc(but, check_object_state, but, &(ob->state));
}
+ }
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOG, OB_SETSTBIT, B_SET_STATE_BIT, "All",(short)(xco+235), yco-10, 25, 19, &ob->scaflag, 0, 0, 0, 0, "Set all state bits");
+ uiDefButBitS(block, TOG, OB_INITSTBIT, B_INIT_STATE_BIT, "Ini",(short)(xco+260), yco-10, 25, 19, &ob->scaflag, 0, 0, 0, 0, "Set the initial state");
+ uiBlockEndAlign(block);
- but= uiDefIconBut(block, LINK, 0, ICON_LINK, (short)(xco+width), ycoo, 19, 19, NULL, 0, 0, 0, 0, "");
- uiSetButLink(but, NULL, (void ***)&(sens->links), &sens->totlinks, LINK_SENSOR, LINK_CONTROLLER);
-
- yco-=20;
+ yco-=35;
+
+ /* display only the controllers that match the current state */
+ offset = 0;
+ for (stbit=0; stbit<32; stbit++) {
+ if (!(ob->state & (1<<stbit)))
+ continue;
+ /* add a separation between controllers of different states */
+ if (offset) {
+ offset = 0;
+ yco -= 6;
+ }
+ cont= ob->controllers.first;
+ while(cont) {
+ if (cont->state_mask & (1<<stbit)) {
+ /* this controller is visible, mark all its actuator */
+ for (iact=0; iact<cont->totlinks; iact++) {
+ act = cont->links[iact];
+ act->flag |= ACT_VISIBLE;
+ }
+ uiBlockSetEmboss(block, UI_EMBOSSM);
+ uiDefIconButBitS(block, TOG, CONT_DEL, B_DEL_CONT, ICON_X, xco, yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Delete Controller");
+ uiDefIconButBitS(block, ICONTOG, CONT_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Controller settings");
+ uiBlockSetEmboss(block, UI_EMBOSSP);
+ sprintf(name, "%d", first_bit(cont->state_mask)+1);
+ uiDefBlockBut(block, controller_state_mask_menu, cont, name, (short)(xco+width-44), yco, 22, 19, "Set controller state mask");
+ uiBlockSetEmboss(block, UI_EMBOSSM);
+
+ if(cont->flag & CONT_SHOW) {
+ cont->otype= cont->type;
+ uiDefButS(block, MENU, B_CHANGE_CONT, controller_pup(),(short)(xco+22), yco, 100, 19, &cont->type, 0, 0, 0, 0, "Controller type");
+ but= uiDefBut(block, TEX, 1, "", (short)(xco+122), yco, (short)(width-166), 19, cont->name, 0, 31, 0, 0, "Controller name");
+ uiButSetFunc(but, make_unique_prop_names_cb, cont->name, (void*) 0);
+
+ ycoo= yco;
+ yco= draw_controllerbuttons(cont, block, xco, yco, width);
+ if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2;
+ }
+ else {
+ cpack(0x999999);
+ glRecti(xco+22, yco, xco+width-22,yco+19);
+ but= uiDefBut(block, LABEL, 0, controller_name(cont->type), (short)(xco+22), yco, 100, 19, cont, 0, 0, 0, 0, "Controller type");
+ uiButSetFunc(but, sca_move_controller, cont, NULL);
+ but= uiDefBut(block, LABEL, 0, cont->name,(short)(xco+122), yco,(short)(width-166), 19, cont, 0, 0, 0, 0, "Controller name");
+ uiButSetFunc(but, sca_move_controller, cont, NULL);
+ ycoo= yco;
+ }
+
+ but= uiDefIconBut(block, LINK, 0, ICON_LINK, (short)(xco+width), ycoo, 19, 19, NULL, 0, 0, 0, 0, "");
+ uiSetButLink(but, NULL, (void ***)&(cont->links), &cont->totlinks, LINK_CONTROLLER, LINK_ACTUATOR);
+
+ uiDefIconBut(block, INLINK, 0, ICON_INLINK,(short)(xco-19), ycoo, 19, 19, cont, LINK_CONTROLLER, 0, 0, 0, "");
+ /* offset is >0 if at least one controller was displayed */
+ offset++;
+ yco-=20;
+ }
+ cont= cont->next;
+ }
- sens= sens->next;
}
yco-= 6;
}
}
-
+
/* ******************************* */
- xco= 675; yco= 170; width= 230;
+ xco= 375; yco= 170; width= 250;
uiBlockSetEmboss(block, UI_EMBOSSP);
- uiDefBlockBut(block, controller_menu, NULL, "Controllers", xco-10, yco+35, 100, 19, "");
+ uiDefBlockBut(block, sensor_menu, NULL, "Sensors", xco-10, yco+35, 70, 19, "");
uiBlockSetEmboss(block, UI_EMBOSS);
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, BUTS_CONT_SEL, B_REDR, "Sel", xco+110, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show all selected Objects");
- uiDefButBitS(block, TOG, BUTS_CONT_ACT, B_REDR, "Act", xco+110+(width-100)/3, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show active Object");
- uiDefButBitS(block, TOG, BUTS_CONT_LINK, B_REDR, "Link", xco+110+2*(width-100)/3, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show linked Objects to Sensor/Actuator");
+ uiDefButBitS(block, TOG, BUTS_SENS_SEL, B_REDR, "Sel", xco+80, yco+35, (width-70)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show all selected Objects");
+ uiDefButBitS(block, TOG, BUTS_SENS_ACT, B_REDR, "Act", xco+80+(width-70)/4, yco+35, (width-70)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show active Object");
+ uiDefButBitS(block, TOG, BUTS_SENS_LINK, B_REDR, "Link", xco+80+2*(width-70)/4, yco+35, (width-70)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller");
+ uiDefButBitS(block, TOG, BUTS_SENS_STATE, B_REDR, "Sta", xco+80+3*(width-70)/4, yco+35, (width-70)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show only sensors connected to active states");
uiBlockEndAlign(block);
- ob= OBACT;
-
for(a=0; a<count; a++) {
ob= (Object *)idar[a];
uiClearButLock();
uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
- if( (ob->scavisflag & OB_VIS_CONT) == 0) continue;
-
+
+ if( (ob->scavisflag & OB_VIS_SENS) == 0) continue;
+
/* presume it is only objects for now */
uiBlockSetEmboss(block, UI_EMBOSS);
uiBlockBeginAlign(block);
- if(ob->controllers.first) uiSetCurFont(block, UI_HELVB);
- uiDefButBitS(block, TOG, OB_SHOWCONT, B_REDR, ob->id.name+2,(short)(xco-10), yco, (short)(width-30), 19, &ob->scaflag, 0, 0, 0, 0, "Active Object name");
- if(ob->controllers.first) uiSetCurFont(block, UI_HELV);
- uiDefButBitS(block, TOG, OB_ADDCONT, B_ADD_CONT, "Add",(short)(xco+width-40), yco, 50, 19, &ob->scaflag, 0, 0, 0, 0, "Add a new Controller");
+ if(ob->sensors.first) uiSetCurFont(block, UI_HELVB);
+ uiDefButBitS(block, TOG, OB_SHOWSENS, B_REDR, ob->id.name+2,(short)(xco-10), yco, (short)(width-30), 19, &ob->scaflag, 0, 31, 0, 0, "Object name, click to show/hide sensors");
+ if(ob->sensors.first) uiSetCurFont(block, UI_HELV);
+ uiDefButBitS(block, TOG, OB_ADDSENS, B_ADD_SENS, "Add",(short)(xco+width-40), yco, 50, 19, &ob->scaflag, 0, 0, 0, 0, "Add a new Sensor");
uiBlockEndAlign(block);
yco-=20;
- if(ob->scaflag & OB_SHOWCONT) {
-
- cont= ob->controllers.first;
- while(cont) {
- uiBlockSetEmboss(block, UI_EMBOSSM);
- uiDefIconButBitS(block, TOG, CONT_DEL, B_DEL_CONT, ICON_X, xco, yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Delete Controller");
- uiDefIconButBitS(block, ICONTOG, CONT_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Controller settings");
-
- if(cont->flag & CONT_SHOW) {
- cont->otype= cont->type;
- uiDefButS(block, MENU, B_CHANGE_CONT, controller_pup(),(short)(xco+22), yco, 100, 19, &cont->type, 0, 0, 0, 0, "Controller type");
- but= uiDefBut(block, TEX, 1, "", (short)(xco+122), yco, (short)(width-144), 19, cont->name, 0, 31, 0, 0, "Controller name");
- uiButSetFunc(but, make_unique_prop_names_cb, cont->name, (void*) 0);
-
- ycoo= yco;
- yco= draw_controllerbuttons(cont, block, xco, yco, width);
- if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2;
- }
- else {
- cpack(0x999999);
- glRecti(xco+22, yco, xco+width-22,yco+19);
- but= uiDefBut(block, LABEL, 0, controller_name(cont->type), (short)(xco+22), yco, 100, 19, cont, 0, 0, 0, 0, "Controller type");
- uiButSetFunc(but, sca_move_controller, cont, NULL);
- but= uiDefBut(block, LABEL, 0, cont->name,(short)(xco+122), yco,(short)(width-144), 19, cont, 0, 0, 0, 0, "Controller name");
- uiButSetFunc(but, sca_move_controller, cont, NULL);
+ if(ob->scaflag & OB_SHOWSENS) {
+
+ sens= ob->sensors.first;
+ while(sens) {
+ if (!(G.buts->scaflag & BUTS_SENS_STATE) ||
+ sens->totlinks == 0 || /* always display sensor without links so that is can be edited */
+ is_sensor_linked(block, sens)) {
+ sens->flag |= SENS_VISIBLE;
+ uiBlockSetEmboss(block, UI_EMBOSSM);
+ uiDefIconButBitS(block, TOG, SENS_DEL, B_DEL_SENS, ICON_X, xco, yco, 22, 19, &sens->flag, 0, 0, 0, 0, "Delete Sensor");
+ uiDefIconButBitS(block, ICONTOG, SENS_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &sens->flag, 0, 0, 0, 0, "Sensor settings");
+
ycoo= yco;
+ if(sens->flag & SENS_SHOW)
+ {
+ uiDefButS(block, MENU, B_CHANGE_SENS, sensor_pup(), (short)(xco+22), yco, 100, 19, &sens->type, 0, 0, 0, 0, "Sensor type");
+ but= uiDefBut(block, TEX, 1, "", (short)(xco+122), yco, (short)(width-144), 19, sens->name, 0, 31, 0, 0, "Sensor name");
+ uiButSetFunc(but, make_unique_prop_names_cb, sens->name, (void*) 0);
+
+ sens->otype= sens->type;
+ yco= draw_sensorbuttons(sens, block, xco, yco, width,ob->id.name);
+ if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2;
+ }
+ else {
+ set_col_sensor(sens->type, 1);
+ glRecti(xco+22, yco, xco+width-22,yco+19);
+ but= uiDefBut(block, LABEL, 0, sensor_name(sens->type), (short)(xco+22), yco, 100, 19, sens, 0, 0, 0, 0, "");
+ uiButSetFunc(but, sca_move_sensor, sens, NULL);
+ but= uiDefBut(block, LABEL, 0, sens->name, (short)(xco+122), yco, (short)(width-144), 19, sens, 0, 31, 0, 0, "");
+ uiButSetFunc(but, sca_move_sensor, sens, NULL);
+ }
+
+ but= uiDefIconBut(block, LINK, 0, ICON_LINK, (short)(xco+width), ycoo, 19, 19, NULL, 0, 0, 0, 0, "");
+ uiSetButLink(but, NULL, (void ***)&(sens->links), &sens->totlinks, LINK_SENSOR, LINK_CONTROLLER);
+
+ yco-=20;
}
-
- but= uiDefIconBut(block, LINK, 0, ICON_LINK, (short)(xco+width), ycoo, 19, 19, NULL, 0, 0, 0, 0, "");
- uiSetButLink(but, NULL, (void ***)&(cont->links), &cont->totlinks, LINK_CONTROLLER, LINK_ACTUATOR);
-
- uiDefIconBut(block, INLINK, 0, ICON_INLINK,(short)(xco-19), ycoo, 19, 19, cont, LINK_CONTROLLER, 0, 0, 0, "");
-
- yco-=20;
-
- cont= cont->next;
+ sens= sens->next;
}
yco-= 6;
}
}
-
+
/* ******************************* */
- xco= 985; yco= 170; width= 280;
+ xco= 1040; yco= 170; width= 280;
uiBlockSetEmboss(block, UI_EMBOSSP);
- uiDefBlockBut(block, actuator_menu, NULL, "Actuators", xco-10, yco+35, 100, 19, "");
+ uiDefBlockBut(block, actuator_menu, NULL, "Actuators", xco-10, yco+35, 90, 19, "");
uiBlockSetEmboss(block, UI_EMBOSS);
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, BUTS_ACT_SEL, B_REDR, "Sel", xco+110, yco+35, (width-110)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show all selected Objects");
- uiDefButBitS(block, TOG, BUTS_ACT_ACT, B_REDR, "Act", xco+110+(width-110)/3, yco+35, (width-110)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show active Object");
- uiDefButBitS(block, TOG, BUTS_ACT_LINK, B_REDR, "Link", xco+110+2*(width-110)/3, yco+35, (width-110)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller");
+ uiDefButBitS(block, TOG, BUTS_ACT_SEL, B_REDR, "Sel", xco+110, yco+35, (width-100)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show all selected Objects");
+ uiDefButBitS(block, TOG, BUTS_ACT_ACT, B_REDR, "Act", xco+110+(width-100)/4, yco+35, (width-100)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show active Object");
+ uiDefButBitS(block, TOG, BUTS_ACT_LINK, B_REDR, "Link", xco+110+2*(width-100)/4, yco+35, (width-100)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller");
+ uiDefButBitS(block, TOG, BUTS_ACT_STATE, B_REDR, "Sta", xco+110+3*(width-100)/4, yco+35, (width-100)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show only actuators connected to active states");
uiBlockEndAlign(block);
for(a=0; a<count; a++) {
ob= (Object *)idar[a];
@@ -2859,34 +3215,38 @@ void logic_buts(void)
act= ob->actuators.first;
while(act) {
- uiBlockSetEmboss(block, UI_EMBOSSM);
- uiDefIconButBitS(block, TOG, ACT_DEL, B_DEL_ACT, ICON_X, xco, yco, 22, 19, &act->flag, 0, 0, 0, 0, "Delete Actuator");
- uiDefIconButBitS(block, ICONTOG, ACT_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &act->flag, 0, 0, 0, 0, "Actuator settings");
+ if (!(G.buts->scaflag & BUTS_ACT_STATE) ||
+ !(act->flag & ACT_LINKED) || /* always display actuators without links so that is can be edited */
+ (act->flag & ACT_VISIBLE)) { /* this actuator has visible connection, display it */
+ act->flag |= ACT_VISIBLE; /* mark the actuator as visible to help implementing the up/down action */
+ uiBlockSetEmboss(block, UI_EMBOSSM);
+ uiDefIconButBitS(block, TOG, ACT_DEL, B_DEL_ACT, ICON_X, xco, yco, 22, 19, &act->flag, 0, 0, 0, 0, "Delete Actuator");
+ uiDefIconButBitS(block, ICONTOG, ACT_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &act->flag, 0, 0, 0, 0, "Actuator settings");
+
+ if(act->flag & ACT_SHOW) {
+ act->otype= act->type;
+ uiDefButS(block, MENU, B_CHANGE_ACT, actuator_pup(ob), (short)(xco+22), yco, 100, 19, &act->type, 0, 0, 0, 0, "Actuator type");
+ but= uiDefBut(block, TEX, 1, "", (short)(xco+122), yco, (short)(width-144), 19, act->name, 0, 31, 0, 0, "Actuator name");
+ uiButSetFunc(but, make_unique_prop_names_cb, act->name, (void*) 0);
+
+ ycoo= yco;
+ yco= draw_actuatorbuttons(ob, act, block, xco, yco, width);
+ if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2;
+ }
+ else {
+ set_col_actuator(act->type, 1);
+ glRecti((short)(xco+22), yco, (short)(xco+width-22),(short)(yco+19));
+ but= uiDefBut(block, LABEL, 0, actuator_name(act->type), (short)(xco+22), yco, 100, 19, act, 0, 0, 0, 0, "Actuator type");
+ uiButSetFunc(but, sca_move_actuator, act, NULL);
+ but= uiDefBut(block, LABEL, 0, act->name, (short)(xco+122), yco, (short)(width-144), 19, act, 0, 0, 0, 0, "Actuator name");
+ uiButSetFunc(but, sca_move_actuator, act, NULL);
+ ycoo= yco;
+ }
- if(act->flag & ACT_SHOW) {
- act->otype= act->type;
- uiDefButS(block, MENU, B_CHANGE_ACT, actuator_pup(ob), (short)(xco+22), yco, 100, 19, &act->type, 0, 0, 0, 0, "Actuator type");
- but= uiDefBut(block, TEX, 1, "", (short)(xco+122), yco, (short)(width-144), 19, act->name, 0, 31, 0, 0, "Actuator name");
- uiButSetFunc(but, make_unique_prop_names_cb, act->name, (void*) 0);
+ uiDefIconBut(block, INLINK, 0, ICON_INLINK,(short)(xco-19), ycoo, 19, 19, act, LINK_ACTUATOR, 0, 0, 0, "");
- ycoo= yco;
- yco= draw_actuatorbuttons(act, block, xco, yco, width);
- if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2;
- }
- else {
- set_col_actuator(act->type, 1);
- glRecti((short)(xco+22), yco, (short)(xco+width-22),(short)(yco+19));
- but= uiDefBut(block, LABEL, 0, actuator_name(act->type), (short)(xco+22), yco, 100, 19, act, 0, 0, 0, 0, "Actuator type");
- uiButSetFunc(but, sca_move_actuator, act, NULL);
- but= uiDefBut(block, LABEL, 0, act->name, (short)(xco+122), yco, (short)(width-144), 19, act, 0, 0, 0, 0, "Actuator name");
- uiButSetFunc(but, sca_move_actuator, act, NULL);
- ycoo= yco;
+ yco-=20;
}
-
- uiDefIconBut(block, INLINK, 0, ICON_INLINK,(short)(xco-19), ycoo, 19, 19, act, LINK_ACTUATOR, 0, 0, 0, "");
-
- yco-=20;
-
act= act->next;
}
yco-= 6;
diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c
index 3797a92f16f..1c98950080a 100644
--- a/source/blender/src/buttons_scene.c
+++ b/source/blender/src/buttons_scene.c
@@ -900,7 +900,7 @@ static void seq_panel_filter_video()
"Convert input to float data");
uiDefButBitI(block, TOG, SEQ_FILTERY,
- B_SEQ_BUT_RELOAD, "FilterY",
+ B_SEQ_BUT_RELOAD_FILE, "De-Inter",
170,110,80,19, &last_seq->flag,
0.0, 21.0, 100, 0,
"For video movies to remove fields");
diff --git a/source/blender/src/drawaction.c b/source/blender/src/drawaction.c
index 8c4958a651a..89466151a39 100644
--- a/source/blender/src/drawaction.c
+++ b/source/blender/src/drawaction.c
@@ -474,10 +474,13 @@ static void draw_channel_names(void)
indent= 0;
special= -1;
- if (EXPANDED_AGRP(agrp))
- expand = ICON_TRIA_DOWN;
- else
- expand = ICON_TRIA_RIGHT;
+ /* only show expand if there are any channels */
+ if (agrp->channels.first) {
+ if (EXPANDED_AGRP(agrp))
+ expand = ICON_TRIA_DOWN;
+ else
+ expand = ICON_TRIA_RIGHT;
+ }
if (EDITABLE_AGRP(agrp))
protect = ICON_UNLOCKED;
diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c
index deb7ddc068d..2f1cdb8b951 100644
--- a/source/blender/src/drawview.c
+++ b/source/blender/src/drawview.c
@@ -246,7 +246,8 @@ void default_gl_light(void)
glDisable(GL_COLOR_MATERIAL);
}
-/* also called when render 'ogl' */
+/* also called when render 'ogl'
+ keep synced with Myinit_gl_stuff in the game engine! */
void init_gl_stuff(void)
{
float mat_ambient[] = { 0.0, 0.0, 0.0, 0.0 };
diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c
index 40b6b7ba6fe..f93a1526e3c 100644
--- a/source/blender/src/editaction.c
+++ b/source/blender/src/editaction.c
@@ -390,7 +390,7 @@ static void actdata_filter_actionchannel (ListBase *act_data, bActionChannel *ac
static void actdata_filter_action (ListBase *act_data, bAction *act, int filter_mode)
{
- bActListElem *ale;
+ bActListElem *ale=NULL;
bActionGroup *agrp;
bActionChannel *achan, *lastchan=NULL;
@@ -429,6 +429,15 @@ static void actdata_filter_action (ListBase *act_data, bAction *act, int filter_
for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
actdata_filter_actionchannel(act_data, achan, filter_mode);
}
+
+ /* remove group from filtered list if last element is group
+ * (i.e. only if group had channels, which were all hidden)
+ */
+ if ( (ale) && (act_data->last == ale) &&
+ (ale->data == agrp) && (agrp->channels.first) )
+ {
+ BLI_freelinkN(act_data, ale);
+ }
}
}
}
@@ -3648,7 +3657,7 @@ static void mouse_actionchannels (short mval[])
{
bActionGroup *agrp= (bActionGroup *)act_channel;
- if (mval[0] < 16) {
+ if ((mval[0] < 16) && (agrp->channels.first)) {
/* toggle expand */
agrp->flag ^= AGRP_EXPANDED;
}
diff --git a/source/blender/src/editfont.c b/source/blender/src/editfont.c
index cb245867c89..a3b05a008c8 100644
--- a/source/blender/src/editfont.c
+++ b/source/blender/src/editfont.c
@@ -354,7 +354,7 @@ void txt_export_to_object(struct Text *text)
// char sdir[FILE_MAXDIR];
// char sfile[FILE_MAXFILE];
- if(!text) return;
+ if(!text || !text->lines.first) return;
id = (ID *)text;
@@ -429,7 +429,7 @@ void txt_export_to_objects(struct Text *text)
int linenum = 0;
float offset[3] = {0.0,0.0,0.0};
- if(!text) return;
+ if(!text || !text->lines.first) return;
id = (ID *)text;
diff --git a/source/blender/src/editmesh_mods.c b/source/blender/src/editmesh_mods.c
index d5e34779173..c7a75b32df1 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/editobject.c b/source/blender/src/editobject.c
index 3c945775b5b..2e5785eaab8 100644
--- a/source/blender/src/editobject.c
+++ b/source/blender/src/editobject.c
@@ -5942,7 +5942,7 @@ void hide_objects(int select)
Base *base;
short changed = 0, changed_act = 0;
for(base = FIRSTBASE; base; base=base->next){
- if(TESTBASELIB(base)==select){
+ if ((base->lay & G.vd->lay) && (TESTBASELIB(base)==select)) {
base->flag &= ~SELECT;
base->object->flag = base->flag;
base->object->restrictflag |= OB_RESTRICT_VIEW;
diff --git a/source/blender/src/editseq.c b/source/blender/src/editseq.c
index fb0fac4489d..b9351f82d1e 100644
--- a/source/blender/src/editseq.c
+++ b/source/blender/src/editseq.c
@@ -2634,12 +2634,13 @@ void set_filter_seq(void)
ed= G.scene->ed;
if(ed==0) return;
- if(okee("Set FilterY")==0) return;
+ if(okee("Set Deinterlace")==0) return;
WHILE_SEQ(ed->seqbasep) {
if(seq->flag & SELECT) {
if(seq->type==SEQ_MOVIE) {
seq->flag |= SEQ_FILTERY;
+ reload_sequence_new_file(seq);
}
}
diff --git a/source/blender/src/editsima.c b/source/blender/src/editsima.c
index 5f8485267bc..18a9803dcae 100644
--- a/source/blender/src/editsima.c
+++ b/source/blender/src/editsima.c
@@ -2690,15 +2690,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/interface.c b/source/blender/src/interface.c
index 6582866d9a1..4fbf92d646e 100644
--- a/source/blender/src/interface.c
+++ b/source/blender/src/interface.c
@@ -2797,6 +2797,10 @@ static void ui_add_link_line(ListBase *listb, uiBut *but, uiBut *bt)
line->to= bt;
}
+uiBut *uiFindInlink(uiBlock *block, void *poin)
+{
+ return ui_find_inlink(block, poin);
+}
void uiComposeLinks(uiBlock *block)
{
diff --git a/source/blender/src/oops.c b/source/blender/src/oops.c
index 99645b5e71f..51d83eff3e6 100644
--- a/source/blender/src/oops.c
+++ b/source/blender/src/oops.c
@@ -1153,7 +1153,6 @@ void build_oops()
}
}
else if(type==ID_AR && G.soops->visiflag & OOPS_AR) {
- bArmature *ar= ob->data;
oops= add_test_oops(ob->data);
}
}
diff --git a/source/blender/src/poseobject.c b/source/blender/src/poseobject.c
index dcceea971f7..cc08bf53a72 100644
--- a/source/blender/src/poseobject.c
+++ b/source/blender/src/poseobject.c
@@ -1627,6 +1627,8 @@ void pose_flipquats(void)
pchan->quat[3]= -pchan->quat[3];
}
}
-
+
+ /* do autokey */
+ autokeyframe_pose_cb_func(ob, TFM_ROTATION, 0);
}
diff --git a/source/blender/src/sequence.c b/source/blender/src/sequence.c
index bf519dd6e9c..6851929bbc2 100644
--- a/source/blender/src/sequence.c
+++ b/source/blender/src/sequence.c
@@ -445,7 +445,10 @@ void reload_sequence_new_file(Sequence * seq)
seq->strip->len = seq->len;
} else if (seq->type == SEQ_MOVIE) {
if(seq->anim) IMB_free_anim(seq->anim);
- seq->anim = openanim(str, IB_rect);
+ seq->anim = openanim(
+ str, IB_rect |
+ ((seq->flag & SEQ_FILTERY)
+ ? IB_animdeinterlace : 0));
if (!seq->anim) {
return;
@@ -1445,7 +1448,7 @@ static void input_preprocess(Sequence * seq, TStripElem* se, int cfra)
seq->strip->orx= se->ibuf->x;
seq->strip->ory= se->ibuf->y;
- if(seq->flag & SEQ_FILTERY) {
+ if((seq->flag & SEQ_FILTERY) && seq->type != SEQ_MOVIE) {
IMB_filtery(se->ibuf);
}
@@ -1772,8 +1775,11 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra,
BLI_join_dirfile(name, seq->strip->dir, seq->strip->stripdata->name);
BLI_convertstringcode(name, G.sce);
BLI_convertstringframe(name, G.scene->r.cfra);
-
- seq->anim = openanim(name, IB_rect);
+
+ seq->anim = openanim(
+ name, IB_rect |
+ ((seq->flag & SEQ_FILTERY)
+ ? IB_animdeinterlace : 0));
}
if(seq->anim) {
IMB_anim_set_preseek(seq->anim, seq->anim_preseek);
diff --git a/source/blender/src/space.c b/source/blender/src/space.c
index c49486a6294..4422411b1c5 100644
--- a/source/blender/src/space.c
+++ b/source/blender/src/space.c
@@ -378,9 +378,6 @@ void space_set_commmandline_options(void) {
if ( (syshandle = SYS_GetSystem()) ) {
/* User defined settings */
- a= (U.gameflags & USER_VERTEX_ARRAYS);
- SYS_WriteCommandLineInt(syshandle, "vertexarrays", a);
-
a= (U.gameflags & USER_DISABLE_SOUND);
SYS_WriteCommandLineInt(syshandle, "noaudio", a);
@@ -437,9 +434,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);
}
@@ -4258,15 +4252,11 @@ void drawinfospace(ScrArea *sa, void *spacedata)
uiDefButS(block, MENU, B_GLRESLIMITCHANGED, "GL Texture Clamp Off%x0|%l|GL Texture Clamp 8192%x8192|GL Texture Clamp 4096%x4096|GL Texture Clamp 2048%x2048|GL Texture Clamp 1024%x1024|GL Texture Clamp 512%x512|GL Texture Clamp 256%x256|GL Texture Clamp 128%x128",
(xpos+edgsp+(5*mpref)+(5*midsp)),y4,mpref,buth, &(U.glreslimit), 0, 0, 0, 0, "Limit the texture size to save graphics memory");
- uiDefButBitI(block, TOG, USER_VERTEX_ARRAYS, 0, "Vertex Arrays",
- (xpos+edgsp+(5*mpref)+(5*midsp)),y3,mpref,buth,
- &(U.gameflags), 0, 0, 0, 0, "Toggles between vertex arrays on (less reliable) and off (more reliable)");
-
uiDefButI(block, NUM, 0, "Time Out ",
- (xpos+edgsp+(5*mpref)+(5*midsp)), y2, mpref, buth,
+ (xpos+edgsp+(5*mpref)+(5*midsp)), y3, mpref, buth,
&U.textimeout, 0.0, 3600.0, 30, 2, "Time since last access of a GL texture in seconds after which it is freed. (Set to 0 to keep textures allocated)");
uiDefButI(block, NUM, 0, "Collect Rate ",
- (xpos+edgsp+(5*mpref)+(5*midsp)), y1, mpref, buth,
+ (xpos+edgsp+(5*mpref)+(5*midsp)), y2, mpref, buth,
&U.texcollectrate, 1.0, 3600.0, 30, 2, "Number of seconds between each run of the GL texture garbage collector.");
/* *** */
@@ -4976,11 +4966,13 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
break;
case DKEY:
- if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY))
+ if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY)) {
duplicate_marker();
- else if ((G.qual==LR_SHIFTKEY)) {
+ } else if ((G.qual==LR_SHIFTKEY)) {
if(sseq->mainb) break;
add_duplicate_seq();
+ } else if (G.qual == 0) {
+ set_filter_seq();
}
break;
case EKEY:
@@ -4988,10 +4980,6 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if((G.qual==0))
transform_seq('e', 0);
break;
- case FKEY:
- if((G.qual==0))
- set_filter_seq();
- break;
case GKEY:
if (G.qual & LR_CTRLKEY)
transform_markers('g', 0);
diff --git a/source/blender/src/transform.c b/source/blender/src/transform.c
index 4270ce6a069..705a5f868e7 100644
--- a/source/blender/src/transform.c
+++ b/source/blender/src/transform.c
@@ -2621,7 +2621,7 @@ static void applyRotation(TransInfo *t, float angle, float axis[3])
continue;
if (t->con.applyRot) {
- t->con.applyRot(t, td, axis);
+ t->con.applyRot(t, td, axis, NULL);
VecRotToMat3(axis, angle * td->factor, mat);
}
else if (t->flag & T_PROP_EDIT) {
@@ -2654,7 +2654,7 @@ int Rotation(TransInfo *t, short mval[2])
snapGrid(t, &final);
if (t->con.applyRot) {
- t->con.applyRot(t, NULL, axis);
+ t->con.applyRot(t, NULL, axis, &final);
}
applySnapping(t, &final);
@@ -3314,7 +3314,7 @@ int PushPull(TransInfo *t, short mval[2])
}
if (t->con.applyRot && t->con.mode & CON_APPLY) {
- t->con.applyRot(t, NULL, axis);
+ t->con.applyRot(t, NULL, axis, NULL);
}
for(i = 0 ; i < t->total; i++, td++) {
@@ -3326,7 +3326,7 @@ int PushPull(TransInfo *t, short mval[2])
VecSubf(vec, t->center, td->center);
if (t->con.applyRot && t->con.mode & CON_APPLY) {
- t->con.applyRot(t, td, axis);
+ t->con.applyRot(t, td, axis, NULL);
if (isLockConstraint(t)) {
float dvec[3];
Projf(dvec, vec, axis);
diff --git a/source/blender/src/transform_constraints.c b/source/blender/src/transform_constraints.c
index 2d01c2303fc..796b013cb88 100644
--- a/source/blender/src/transform_constraints.c
+++ b/source/blender/src/transform_constraints.c
@@ -393,7 +393,7 @@ static void applyObjectConstraintSize(TransInfo *t, TransData *td, float smat[3]
* (ie: not doing counterclockwise rotations when the mouse moves clockwise).
*/
-static void applyAxisConstraintRot(TransInfo *t, TransData *td, float vec[3])
+static void applyAxisConstraintRot(TransInfo *t, TransData *td, float vec[3], float *angle)
{
if (!td && t->con.mode & CON_APPLY) {
int mode = t->con.mode & (CON_AXIS0|CON_AXIS1|CON_AXIS2);
@@ -413,9 +413,9 @@ static void applyAxisConstraintRot(TransInfo *t, TransData *td, float vec[3])
break;
}
/* don't flip axis if asked to or if num input */
- if (!(mode & CON_NOFLIP) && hasNumInput(&t->num) == 0) {
+ if (angle && (mode & CON_NOFLIP) == 0 && hasNumInput(&t->num) == 0) {
if (Inpf(vec, t->viewinv[2]) > 0.0f) {
- VecMulf(vec, -1.0f);
+ *angle = -(*angle);
}
}
}
@@ -435,10 +435,15 @@ static void applyAxisConstraintRot(TransInfo *t, TransData *td, float vec[3])
* (ie: not doing counterclockwise rotations when the mouse moves clockwise).
*/
-static void applyObjectConstraintRot(TransInfo *t, TransData *td, float vec[3])
+static void applyObjectConstraintRot(TransInfo *t, TransData *td, float vec[3], float *angle)
{
- if (td && t->con.mode & CON_APPLY) {
+ if (t->con.mode & CON_APPLY) {
int mode = t->con.mode & (CON_AXIS0|CON_AXIS1|CON_AXIS2);
+
+ /* on setup call, use first object */
+ if (td == NULL) {
+ td= t->data;
+ }
switch(mode) {
case CON_AXIS0:
@@ -454,9 +459,9 @@ static void applyObjectConstraintRot(TransInfo *t, TransData *td, float vec[3])
VECCOPY(vec, td->axismtx[2]);
break;
}
- if (!(mode & CON_NOFLIP)) {
+ if (angle && (mode & CON_NOFLIP) == 0 && hasNumInput(&t->num) == 0) {
if (Inpf(vec, t->viewinv[2]) > 0.0f) {
- VecMulf(vec, -1.0f);
+ *angle = -(*angle);
}
}
}
diff --git a/source/blender/src/transform_generics.c b/source/blender/src/transform_generics.c
index eaa4a1d0ecf..6cb7a34d1bc 100644
--- a/source/blender/src/transform_generics.c
+++ b/source/blender/src/transform_generics.c
@@ -325,7 +325,7 @@ void recalcData(TransInfo *t)
else {
for (base=G.scene->base.first; base; base=base->next) {
/* recalculate scale of selected nla-strips */
- if (base->object->nlastrips.first) {
+ if (base->object && base->object->nlastrips.first) {
Object *bob= base->object;
bActionStrip *strip;
@@ -398,8 +398,15 @@ void recalcData(TransInfo *t)
}
}
else if(G.sipo->blocktype==ID_OB) {
+ Object *ob= OBACT;
Base *base= FIRSTBASE;
+ /* only if this if active object has this ipo in an action (assumes that current ipo is in action) */
+ if ((ob) && (ob->ipoflag & OB_ACTION_OB) && (G.sipo->pin==0)) {
+ ob->ctime= -1234567.0f;
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
+ }
+
while(base) {
if(base->object->ipo==G.sipo->ipo) {
do_ob_ipo(base->object);
diff --git a/source/blender/src/transform_snap.c b/source/blender/src/transform_snap.c
index 295cfa4574c..d16308f17ae 100644
--- a/source/blender/src/transform_snap.c
+++ b/source/blender/src/transform_snap.c
@@ -412,7 +412,7 @@ float RotationBetween(TransInfo *t, float p1[3], float p2[3])
if (t->con.applyRot != NULL && (t->con.mode & CON_APPLY)) {
float axis[3], tmp[3];
- t->con.applyRot(t, NULL, axis);
+ t->con.applyRot(t, NULL, axis, NULL);
Projf(tmp, end, axis);
VecSubf(end, end, tmp);
@@ -737,136 +737,6 @@ void TargetSnapClosest(TransInfo *t)
}
/*================================================================*/
-
-/* find snapping point on face, return 1 on success */
-int snapFace(MFace *face, EditFace *efa, MVert *verts, float *intersect, float *loc, float *no)
-{
- MVert *v[4];
- EditVert *eve[4];
- int totvert;
- int result = 0;
-
- v[0] = verts + face->v1;
- v[1] = verts + face->v2;
- v[2] = verts + face->v3;
-
- if (face->v4)
- {
- v[3] = verts + face->v4;
- totvert = 4;
- }
- else
- {
- v[3] = NULL;
- totvert = 3;
- }
-
- if (efa)
- {
- eve[0] = efa->v1;
- eve[1] = efa->v2;
- eve[2] = efa->v3;
- eve[3] = efa->v4;
- }
-
- switch(G.scene->snap_mode)
- {
- case SCE_SNAP_MODE_VERTEX:
- {
- float min_dist = FLT_MAX;
- int i;
-
- for(i = 0; i < totvert; i++)
- {
-
- if (efa == NULL || (eve[i]->f1 & SELECT) == 0)
- {
- float vert_dist = VecLenf(v[i]->co, intersect);
-
- if (vert_dist < min_dist)
- {
- result = 1;
-
- min_dist = vert_dist;
-
- VECCOPY(loc, v[i]->co);
- NormalShortToFloat(no, v[i]->no);
- }
- }
- }
- break;
- }
- case SCE_SNAP_MODE_EDGE:
- {
- float min_dist = FLT_MAX;
- int i;
-
- for(i = 0; i < totvert; i++)
- {
- MVert *v1, *v2;
- EditVert *eve1, *eve2;
-
- v1 = v[i];
- v2 = v[(i + 1) % totvert];
-
- eve1 = eve[i];
- eve2 = eve[(i + 1) % totvert];
-
- if (efa == NULL || ((eve1->f1 & SELECT) == 0 && (eve2->f1 & SELECT) == 0))
- {
- float edge_loc[3];
- float vec[3];
- float mul;
- float edge_dist;
-
- VecSubf(edge_loc, v2->co, v1->co);
- VecSubf(vec, intersect, v1->co);
-
- mul = Inpf(vec, edge_loc) / Inpf(edge_loc, edge_loc);
-
- VecMulf(edge_loc, mul);
- VecAddf(edge_loc, edge_loc, v1->co);
-
- edge_dist = VecLenf(edge_loc, intersect);
-
- if (edge_dist < min_dist)
- {
- float n1[3], n2[3];
- result = 1;
-
- min_dist = edge_dist;
-
- VECCOPY(loc, edge_loc);
-
- NormalShortToFloat(n1, v1->no);
- NormalShortToFloat(n2, v2->no);
- VecLerpf(no, n1, n2, mul);
- Normalize(no);
- }
- }
- }
- break;
- }
- case SCE_SNAP_MODE_FACE:
- {
- if (efa == NULL || ((efa->f1 & SELECT) == 0))
- {
- result = 1;
-
- VECCOPY(loc, intersect);
-
- if (totvert == 4)
- CalcNormFloat4(v[0]->co, v[1]->co, v[2]->co, v[3]->co, no);
- else
- CalcNormFloat(v[0]->co, v[1]->co, v[2]->co, no);
- }
- break;
- }
- }
-
- return result;
-}
-
int snapDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], float *loc, float *no, int *dist, float *depth, short EditMesh)
{
int retval = 0;
@@ -891,7 +761,7 @@ int snapDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_sta
Mat4Mul3Vecfl(imat, ray_normal_local);
- /* If number of vert is more than an arbitrary limit,
+ /* If number of vert is more than an arbitrary limit,
* test against boundbox first
* */
if (totface > 16) {
@@ -900,117 +770,219 @@ int snapDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_sta
}
if (test == 1) {
- MVert *verts = dm->getVertArray(dm);
- MFace *faces = dm->getFaceArray(dm);
- int *index_array = NULL;
- int index = 0;
- int i;
- if (EditMesh)
+ switch (G.scene->snap_mode)
{
- index_array = dm->getFaceDataArray(dm, CD_ORIGINDEX);
- EM_init_index_arrays(0, 0, 1);
- }
-
- for( i = 0; i < totface; i++) {
- EditFace *efa = NULL;
- MFace *f = faces + i;
- float lambda;
- int result;
-
- test = 1; /* reset for every face */
-
- if (EditMesh)
- {
- if (index_array)
- {
- index = index_array[i];
- }
- else
- {
- index = i;
- }
+ case SCE_SNAP_MODE_FACE:
+ {
+ MVert *verts = dm->getVertArray(dm);
+ MFace *faces = dm->getFaceArray(dm);
+ int *index_array = NULL;
+ int index = 0;
+ int i;
- if (index == ORIGINDEX_NONE)
+ if (EditMesh)
{
- test = 0;
+ index_array = dm->getFaceDataArray(dm, CD_ORIGINDEX);
+ EM_init_index_arrays(0, 0, 1);
}
- else
- {
- efa = EM_get_face_for_index(index);
+
+ for( i = 0; i < totface; i++) {
+ EditFace *efa = NULL;
+ MFace *f = faces + i;
+ float lambda;
+ int result;
- if (efa && efa->f1 & SELECT)
+ test = 1; /* reset for every face */
+
+ if (EditMesh)
{
- test = 0;
+ if (index_array)
+ {
+ index = index_array[i];
+ }
+ else
+ {
+ index = i;
+ }
+
+ if (index == ORIGINDEX_NONE)
+ {
+ test = 0;
+ }
+ else
+ {
+ efa = EM_get_face_for_index(index);
+
+ if (efa && efa->f & SELECT)
+ {
+ test = 0;
+ }
+ }
}
- }
- }
-
-
- if (test)
- {
- result = RayIntersectsTriangle(ray_start_local, ray_normal_local, verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, &lambda, NULL);
-
- if (result) {
- float location[3], normal[3];
- float intersect[3];
- VECCOPY(intersect, ray_normal_local);
- VecMulf(intersect, lambda);
- VecAddf(intersect, intersect, ray_start_local);
- if (snapFace(f, efa, verts, intersect, location, normal))
- {
- float new_depth;
- int screen_loc[2];
- int new_dist;
-
- Mat4MulVecfl(obmat, location);
-
- new_depth = VecLenf(location, ray_start);
-
- project_int(location, screen_loc);
- new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]);
+ if (test)
+ {
+ result = RayIntersectsTriangle(ray_start_local, ray_normal_local, verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, &lambda, NULL);
- if (new_dist <= *dist && new_depth < *depth)
- {
- *depth = new_depth;
- retval = 1;
+ if (result) {
+ float location[3], normal[3];
+ float intersect[3];
+ float new_depth;
+ int screen_loc[2];
+ int new_dist;
- VECCOPY(loc, location);
- VECCOPY(no, normal);
+ VECCOPY(intersect, ray_normal_local);
+ VecMulf(intersect, lambda);
+ VecAddf(intersect, intersect, ray_start_local);
- Mat3MulVecfl(timat, no);
- Normalize(no);
-
- project_int(loc, screen_loc);
+ VECCOPY(location, intersect);
+
+ if (f->v4)
+ CalcNormFloat4(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, verts[f->v4].co, normal);
+ else
+ CalcNormFloat(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, normal);
+
+ Mat4MulVecfl(obmat, location);
+
+ new_depth = VecLenf(location, ray_start);
+
+ project_int(location, screen_loc);
+ new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]);
+
+ if (new_dist <= *dist && new_depth < *depth)
+ {
+ *depth = new_depth;
+ retval = 1;
+
+ VECCOPY(loc, location);
+ VECCOPY(no, normal);
+
+ Mat3MulVecfl(timat, no);
+ Normalize(no);
+
+ *dist = new_dist;
+ }
+ }
+
+ if (f->v4 && result == 0)
+ {
+ result = RayIntersectsTriangle(ray_start_local, ray_normal_local, verts[f->v3].co, verts[f->v4].co, verts[f->v1].co, &lambda, NULL);
- *dist = new_dist;
- }
+ if (result) {
+ float location[3], normal[3];
+ float intersect[3];
+ float new_depth;
+ int screen_loc[2];
+ int new_dist;
+
+ VECCOPY(intersect, ray_normal_local);
+ VecMulf(intersect, lambda);
+ VecAddf(intersect, intersect, ray_start_local);
+
+ VECCOPY(location, intersect);
+
+ if (f->v4)
+ CalcNormFloat4(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, verts[f->v4].co, normal);
+ else
+ CalcNormFloat(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, normal);
+
+ Mat4MulVecfl(obmat, location);
+
+ new_depth = VecLenf(location, ray_start);
+
+ project_int(location, screen_loc);
+ new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]);
+
+ if (new_dist <= *dist && new_depth < *depth)
+ {
+ *depth = new_depth;
+ retval = 1;
+
+ VECCOPY(loc, location);
+ VECCOPY(no, normal);
+
+ Mat3MulVecfl(timat, no);
+ Normalize(no);
+
+ *dist = new_dist;
+ }
+ }
+ }
}
}
-
- if (f->v4 && result == 0)
+
+ if (EditMesh)
{
- result = RayIntersectsTriangle(ray_start_local, ray_normal_local, verts[f->v3].co, verts[f->v4].co, verts[f->v1].co, &lambda, NULL);
+ EM_free_index_arrays();
+ }
+ break;
+ }
+ case SCE_SNAP_MODE_VERTEX:
+ {
+ MVert *verts = dm->getVertArray(dm);
+ int *index_array = NULL;
+ int index = 0;
+ int i;
+
+ if (EditMesh)
+ {
+ index_array = dm->getVertDataArray(dm, CD_ORIGINDEX);
+ EM_init_index_arrays(1, 0, 0);
+ }
+
+ for( i = 0; i < totvert; i++) {
+ EditVert *eve = NULL;
+ MVert *v = verts + i;
- if (result) {
- float location[3], normal[3];
- float intersect[3];
+ test = 1; /* reset for every vert */
+
+ if (EditMesh)
+ {
+ if (index_array)
+ {
+ index = index_array[i];
+ }
+ else
+ {
+ index = i;
+ }
- VECCOPY(intersect, ray_normal_local);
- VecMulf(intersect, lambda);
- VecAddf(intersect, intersect, ray_start_local);
-
- if (snapFace(f, efa, verts, intersect, location, normal))
- {
+ if (index == ORIGINDEX_NONE)
+ {
+ test = 0;
+ }
+ else
+ {
+ eve = EM_get_vert_for_index(index);
+
+ if (eve && eve->f & SELECT)
+ {
+ test = 0;
+ }
+ }
+ }
+
+
+ if (test)
+ {
+ float dvec[3];
+
+ VecSubf(dvec, v->co, ray_start_local);
+
+ if (Inpf(ray_normal_local, dvec) > 0)
+ {
+ float location[3];
float new_depth;
int screen_loc[2];
int new_dist;
+ VECCOPY(location, v->co);
+
Mat4MulVecfl(obmat, location);
- new_depth = VecLenf(location, ray_start);
+ new_depth = VecLenf(location, ray_start);
project_int(location, screen_loc);
new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]);
@@ -1021,8 +993,8 @@ int snapDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_sta
retval = 1;
VECCOPY(loc, location);
- VECCOPY(no, normal);
+ NormalShortToFloat(no, v->no);
Mat3MulVecfl(timat, no);
Normalize(no);
@@ -1031,12 +1003,145 @@ int snapDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_sta
}
}
}
+
+ if (EditMesh)
+ {
+ EM_free_index_arrays();
+ }
+ break;
+ }
+ case SCE_SNAP_MODE_EDGE:
+ {
+ MVert *verts = dm->getVertArray(dm);
+ MEdge *edges = dm->getEdgeArray(dm);
+ int totedge = dm->getNumEdges(dm);
+ int *index_array = NULL;
+ int index = 0;
+ int i;
+
+ if (EditMesh)
+ {
+ index_array = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
+ EM_init_index_arrays(0, 1, 0);
+ }
+
+ for( i = 0; i < totedge; i++) {
+ EditEdge *eed = NULL;
+ MEdge *e = edges + i;
+
+ test = 1; /* reset for every vert */
+
+ if (EditMesh)
+ {
+ if (index_array)
+ {
+ index = index_array[i];
+ }
+ else
+ {
+ index = i;
+ }
+
+ if (index == ORIGINDEX_NONE)
+ {
+ test = 0;
+ }
+ else
+ {
+ eed = EM_get_edge_for_index(index);
+
+ if (eed && ((eed->v1->f & SELECT) || (eed->v2->f & SELECT)))
+ {
+ test = 0;
+ }
+ }
+ }
+
+
+ if (test)
+ {
+ float intersect[3] = {0, 0, 0}, ray_end[3], dvec[3];
+ int result;
+
+ VECCOPY(ray_end, ray_normal_local);
+ VecMulf(ray_end, 2000);
+ VecAddf(ray_end, ray_start_local, ray_end);
+
+ result = LineIntersectLine(verts[e->v1].co, verts[e->v2].co, ray_start_local, ray_end, intersect, dvec); /* dvec used but we don't care about result */
+
+ if (result)
+ {
+ float edge_loc[3], vec[3];
+ float mul;
+
+ /* check for behind ray_start */
+ VecSubf(dvec, intersect, ray_start_local);
+
+ VecSubf(edge_loc, verts[e->v1].co, verts[e->v2].co);
+ VecSubf(vec, intersect, verts[e->v2].co);
+
+ mul = Inpf(vec, edge_loc) / Inpf(edge_loc, edge_loc);
+
+ if (mul > 1) {
+ mul = 1;
+ VECCOPY(intersect, verts[e->v1].co);
+ }
+ else if (mul < 0) {
+ mul = 0;
+ VECCOPY(intersect, verts[e->v2].co);
+ }
+
+ if (Inpf(ray_normal_local, dvec) > 0)
+ {
+ float location[3];
+ float new_depth;
+ int screen_loc[2];
+ int new_dist;
+
+ VECCOPY(location, intersect);
+
+ Mat4MulVecfl(obmat, location);
+
+ new_depth = VecLenf(location, ray_start);
+
+ project_int(location, screen_loc);
+ new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]);
+
+ if (new_dist <= *dist && new_depth < *depth)
+ {
+ float n1[3], n2[3];
+
+ *depth = new_depth;
+ retval = 1;
+
+ VecSubf(edge_loc, verts[e->v1].co, verts[e->v2].co);
+ VecSubf(vec, intersect, verts[e->v2].co);
+
+ mul = Inpf(vec, edge_loc) / Inpf(edge_loc, edge_loc);
+
+ NormalShortToFloat(n1, verts[e->v1].no);
+ NormalShortToFloat(n2, verts[e->v2].no);
+ VecLerpf(no, n2, n1, mul);
+ Normalize(no);
+
+ VECCOPY(loc, location);
+
+ Mat3MulVecfl(timat, no);
+ Normalize(no);
+
+ *dist = new_dist;
+ }
+ }
+ }
+ }
+ }
+
+ if (EditMesh)
+ {
+ EM_free_index_arrays();
+ }
+ break;
}
- }
-
- if (EditMesh)
- {
- EM_free_index_arrays();
}
}
}
diff --git a/source/blender/src/view.c b/source/blender/src/view.c
index 356a297b284..f457f9203ff 100644
--- a/source/blender/src/view.c
+++ b/source/blender/src/view.c
@@ -689,10 +689,6 @@ void viewmoveNDOFfly(int mode)
if (G.vd->ndoffilter)
filterNDOFvalues(fval);
-// for(i=0;i<7;i++) printf("%f ",dval[i]);
-// printf("\n");
-
-
// Scale input values
// if(dval[6] == 0) return; // guard against divide by zero
@@ -701,12 +697,6 @@ void viewmoveNDOFfly(int mode)
// user scaling
dval[i] = dval[i] * ndof_axis_scale[i];
-
- // non-linear scaling
- if(dval[i]<0.0f)
- dval[i] = -1.0f * dval[i] * dval[i];
- else
- dval[i] = dval[i] * dval[i];
}
@@ -1216,18 +1206,16 @@ void viewmoveNDOF(int mode)
// prevTime = now;
// sbadjust *= 60 * frametime; /* normalize ndof device adjustments to 100Hz for framerate independence */
- /* fetch the current state of the ndof device */
+ /* fetch the current state of the ndof device & enforce dominant mode if selected */
getndof(fval);
- // printf(" motion command %f %f %f %f %f %f %f \n", fval[0], fval[1], fval[2],
- // fval[3], fval[4], fval[5], fval[6]);
- if (G.vd->ndoffilter)
- filterNDOFvalues(fval);
+ if (G.vd->ndoffilter)
+ filterNDOFvalues(fval);
// put scaling back here, was previously in ghostwinlay
- fval[0] = fval[0] * (1.0f/1200.0f);
- fval[1] = fval[1] * (1.0f/1200.0f);
- fval[2] = fval[2] * (1.0f/1200.0f);
+ fval[0] = fval[0] * (1.0f/600.0f);
+ fval[1] = fval[1] * (1.0f/600.0f);
+ fval[2] = fval[2] * (1.0f/1100.0f);
fval[3] = fval[3] * 0.00005f;
fval[4] =-fval[4] * 0.00005f;
fval[5] = fval[5] * 0.00005f;
@@ -1255,14 +1243,16 @@ void viewmoveNDOF(int mode)
VECCOPY(obofs, G.vd->ofs);
}
- /* calc an adjustment based on distance from camera */
- if (ob) {
+ /* calc an adjustment based on distance from camera
+ disabled per patch 14402 */
+ d = 1.0f;
+
+/* if (ob) {
VecSubf(diff, obofs, G.vd->ofs);
d = VecLength(diff);
}
- else {
- d = 1.0f;
- }
+*/
+
reverse = (G.vd->persmat[2][1] < 0.0f) ? -1.0f : 1.0f;
/*----------------------------------------------------
diff --git a/source/creator/creator.c b/source/creator/creator.c
index 2e6b5d7353e..9589f1e3e94 100644
--- a/source/creator/creator.c
+++ b/source/creator/creator.c
@@ -195,7 +195,7 @@ static void print_help(void)
printf (" (formats that can be compiled into blender, not available on all systems)\n");
printf (" \tHDR TIFF EXR MULTILAYER MPEG AVICODEC QUICKTIME CINEON DPX DDS\n");
printf (" -x <bool>\tSet option to add the file extension to the end of the file.\n");
- printf (" -t <threads>\tUse amount of <threads> for rendering.\n");
+ printf (" -t <threads>\tUse amount of <threads> for rendering (background mode only).\n");
printf (" [1-8], 0 for systems processor count.\n");
printf ("\nAnimation playback options:\n");
printf (" -a <file(s)>\tPlayback <file(s)>, only operates this way when -b is not used.\n");
@@ -723,6 +723,8 @@ int main(int argc, char **argv)
a++;
if(G.background) {
RE_set_max_threads(atoi(argv[a]));
+ } else {
+ printf("Warning: threads can only be set in background mode\n");
}
break;
case 'x': /* extension */
diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
index 06aa0609ad9..4af5ac4d5d2 100644
--- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
+++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
@@ -165,20 +165,14 @@ extern "C" void StartKetsjiShell(struct ScrArea *area,
RAS_IRenderTools* rendertools = new KX_BlenderRenderTools();
RAS_IRasterizer* rasterizer = NULL;
- // let's see if we want to use vertexarrays or not
- int usevta = SYS_GetCommandLineInt(syshandle,"vertexarrays",1);
- bool useVertexArrays = (usevta > 0);
-
- bool lock_arrays = (displaylists && useVertexArrays);
-
- if(displaylists){
- if (useVertexArrays)
- rasterizer = new RAS_ListRasterizer(canvas, true, lock_arrays);
+ if(displaylists) {
+ if (GLEW_VERSION_1_1)
+ rasterizer = new RAS_ListRasterizer(canvas, true, true);
else
rasterizer = new RAS_ListRasterizer(canvas);
}
- else if (useVertexArrays && GLEW_VERSION_1_1)
- rasterizer = new RAS_VAOpenGLRasterizer(canvas, lock_arrays);
+ else if (GLEW_VERSION_1_1)
+ rasterizer = new RAS_VAOpenGLRasterizer(canvas, false);
else
rasterizer = new RAS_OpenGLRasterizer(canvas);
@@ -513,16 +507,14 @@ extern "C" void StartKetsjiShellSimulation(struct ScrArea *area,
RAS_IRenderTools* rendertools = new KX_BlenderRenderTools();
RAS_IRasterizer* rasterizer = NULL;
- // let's see if we want to use vertexarrays or not
- int usevta = SYS_GetCommandLineInt(syshandle,"vertexarrays",1);
- bool useVertexArrays = (usevta > 0);
-
- bool lock_arrays = (displaylists && useVertexArrays);
-
- if(displaylists && !useVertexArrays)
- rasterizer = new RAS_ListRasterizer(canvas);
- else if (useVertexArrays && GLEW_VERSION_1_1)
- rasterizer = new RAS_VAOpenGLRasterizer(canvas, lock_arrays);
+ if(displaylists) {
+ if (GLEW_VERSION_1_1)
+ rasterizer = new RAS_ListRasterizer(canvas, true, true);
+ else
+ rasterizer = new RAS_ListRasterizer(canvas);
+ }
+ else if (GLEW_VERSION_1_1)
+ rasterizer = new RAS_VAOpenGLRasterizer(canvas, false);
else
rasterizer = new RAS_OpenGLRasterizer(canvas);
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
index 07a3649aa0f..73d2870720a 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
+++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
@@ -483,9 +483,9 @@ void KX_BlenderRenderTools::MotionBlur(RAS_IRasterizer* rasterizer)
}
}
-void KX_BlenderRenderTools::Update2DFilter(RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text)
+void KX_BlenderRenderTools::Update2DFilter(RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text, short texture_flag)
{
- m_filtermanager.EnableFilter(filtermode, pass, text);
+ m_filtermanager.EnableFilter(filtermode, pass, text, texture_flag);
}
void KX_BlenderRenderTools::Render2DFilters(RAS_ICanvas* canvas)
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h
index 31eaa14d66b..7748e31156d 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h
+++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h
@@ -101,7 +101,7 @@ public:
virtual void MotionBlur(RAS_IRasterizer* rasterizer);
- virtual void Update2DFilter(RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text);
+ virtual void Update2DFilter(RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text, short texture_flag);
virtual void Render2DFilters(RAS_ICanvas* canvas);
diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp
index ad126ebf123..5050da3fe7f 100644
--- a/source/gameengine/Converter/BL_ActionActuator.cpp
+++ b/source/gameengine/Converter/BL_ActionActuator.cpp
@@ -49,6 +49,7 @@
#include "BLI_arithb.h"
#include "MT_Matrix4x4.h"
#include "BKE_utildefines.h"
+#include "FloatValue.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -348,6 +349,18 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
break;
}
+ /* Set the property if its defined */
+ if (m_framepropname[0] != '\0') {
+ CValue* propowner = GetParent();
+ CValue* oldprop = propowner->GetProperty(m_framepropname);
+ CValue* newval = new CFloatValue(m_localtime);
+ if (oldprop) {
+ oldprop->SetValue(newval);
+ } else {
+ propowner->SetProperty(m_framepropname, newval);
+ }
+ newval->Release();
+ }
if (bNegativeEvent)
m_blendframe=0.0;
@@ -446,6 +459,7 @@ PyMethodDef BL_ActionActuator::Methods[] = {
{"setPriority", (PyCFunction) BL_ActionActuator::sPySetPriority, METH_VARARGS, SetPriority_doc},
{"setFrame", (PyCFunction) BL_ActionActuator::sPySetFrame, METH_VARARGS, SetFrame_doc},
{"setProperty", (PyCFunction) BL_ActionActuator::sPySetProperty, METH_VARARGS, SetProperty_doc},
+ {"setFrameProperty", (PyCFunction) BL_ActionActuator::sPySetFrameProperty, METH_VARARGS, SetFrameProperty_doc},
{"setBlendtime", (PyCFunction) BL_ActionActuator::sPySetBlendtime, METH_VARARGS, SetBlendtime_doc},
{"getAction", (PyCFunction) BL_ActionActuator::sPyGetAction, METH_VARARGS, GetAction_doc},
@@ -455,6 +469,7 @@ PyMethodDef BL_ActionActuator::Methods[] = {
{"getPriority", (PyCFunction) BL_ActionActuator::sPyGetPriority, METH_VARARGS, GetPriority_doc},
{"getFrame", (PyCFunction) BL_ActionActuator::sPyGetFrame, METH_VARARGS, GetFrame_doc},
{"getProperty", (PyCFunction) BL_ActionActuator::sPyGetProperty, METH_VARARGS, GetProperty_doc},
+ {"getFrameProperty", (PyCFunction) BL_ActionActuator::sPyGetFrameProperty, METH_VARARGS, GetFrameProperty_doc},
{"setChannel", (PyCFunction) BL_ActionActuator::sPySetChannel, METH_VARARGS, SetChannel_doc},
// {"getChannel", (PyCFunction) BL_ActionActuator::sPyGetChannel, METH_VARARGS},
{"getType", (PyCFunction) BL_ActionActuator::sPyGetType, METH_VARARGS, GetType_doc},
@@ -502,6 +517,21 @@ PyObject* BL_ActionActuator::PyGetProperty(PyObject* self,
return result;
}
+/* getProperty */
+char BL_ActionActuator::GetFrameProperty_doc[] =
+"getFrameProperty()\n"
+"\tReturns the name of the property, that is set to the current frame number.\n";
+
+PyObject* BL_ActionActuator::PyGetFrameProperty(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ PyObject *result;
+
+ result = Py_BuildValue("s", (const char *)m_framepropname);
+
+ return result;
+}
+
/* getFrame */
char BL_ActionActuator::GetFrame_doc[] =
"getFrame()\n"
@@ -763,6 +793,25 @@ PyObject* BL_ActionActuator::PySetProperty(PyObject* self,
return Py_None;
}
+/* setFrameProperty */
+char BL_ActionActuator::SetFrameProperty_doc[] =
+"setFrameProperty(prop)\n"
+"\t - prop : A string specifying the property of the frame set up update.\n";
+
+PyObject* BL_ActionActuator::PySetFrameProperty(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ char *string;
+
+ if (PyArg_ParseTuple(args,"s",&string))
+ {
+ m_framepropname = string;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
/*
PyObject* BL_ActionActuator::PyGetChannel(PyObject* self,
PyObject* args,
diff --git a/source/gameengine/Converter/BL_ActionActuator.h b/source/gameengine/Converter/BL_ActionActuator.h
index 62edcc7fad7..190f727c9c3 100644
--- a/source/gameengine/Converter/BL_ActionActuator.h
+++ b/source/gameengine/Converter/BL_ActionActuator.h
@@ -40,6 +40,7 @@ public:
Py_Header;
BL_ActionActuator(SCA_IObject* gameobj,
const STR_String& propname,
+ const STR_String& framepropname,
float starttime,
float endtime,
struct bAction *action,
@@ -67,7 +68,8 @@ public:
m_blendpose(NULL),
m_userpose(NULL),
m_action(action),
- m_propname(propname)
+ m_propname(propname),
+ m_framepropname(framepropname)
{
};
virtual ~BL_ActionActuator();
@@ -84,6 +86,7 @@ public:
KX_PYMETHOD_DOC(BL_ActionActuator,SetEnd);
KX_PYMETHOD_DOC(BL_ActionActuator,SetFrame);
KX_PYMETHOD_DOC(BL_ActionActuator,SetProperty);
+ KX_PYMETHOD_DOC(BL_ActionActuator,SetFrameProperty);
KX_PYMETHOD_DOC(BL_ActionActuator,SetBlendtime);
KX_PYMETHOD_DOC(BL_ActionActuator,SetChannel);
@@ -94,6 +97,7 @@ public:
KX_PYMETHOD_DOC(BL_ActionActuator,GetEnd);
KX_PYMETHOD_DOC(BL_ActionActuator,GetFrame);
KX_PYMETHOD_DOC(BL_ActionActuator,GetProperty);
+ KX_PYMETHOD_DOC(BL_ActionActuator,GetFrameProperty);
// KX_PYMETHOD(BL_ActionActuator,GetChannel);
KX_PYMETHOD_DOC(BL_ActionActuator,GetType);
KX_PYMETHOD_DOC(BL_ActionActuator,SetType);
@@ -138,6 +142,7 @@ protected:
struct bPose* m_userpose;
struct bAction *m_action;
STR_String m_propname;
+ STR_String m_framepropname;
};
enum {
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index 32946267202..665783a1ba5 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -1668,6 +1668,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;
@@ -2324,6 +2326,14 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
bool isInActiveLayer = (blenderobj->lay & activeLayerBitInfo)!=0;
BL_ConvertSensors(blenderobj,gameobj,logicmgr,kxscene,keydev,executePriority,activeLayerBitInfo,isInActiveLayer,canvas,converter);
}
+ // apply the initial state to controllers
+ for ( i=0;i<logicbrick_conversionlist->GetCount();i++)
+ {
+ KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i));
+ struct Object* blenderobj = converter->FindBlenderObject(gameobj);
+ gameobj->SetState((blenderobj->init_state)?blenderobj->init_state:blenderobj->state);
+ }
+
#endif //CONVERT_LOGIC
logicbrick_conversionlist->Release();
diff --git a/source/gameengine/Converter/BL_ShapeDeformer.cpp b/source/gameengine/Converter/BL_ShapeDeformer.cpp
index 3ae634905b9..eb5c1467ea5 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 9bbdde3fb2c..9f8361dbaca 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 1015221c392..dd7119b1031 100644
--- a/source/gameengine/Converter/BL_SkinDeformer.cpp
+++ b/source/gameengine/Converter/BL_SkinDeformer.cpp
@@ -149,12 +149,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 f219c3a1472..ea26c55a44e 100644
--- a/source/gameengine/Converter/KX_ConvertActuators.cpp
+++ b/source/gameengine/Converter/KX_ConvertActuators.cpp
@@ -56,11 +56,13 @@
#include "KX_ConstraintActuator.h"
#include "KX_CameraActuator.h"
#include "KX_GameActuator.h"
+#include "KX_StateActuator.h"
#include "KX_VisibilityActuator.h"
#include "KX_SCA_AddObjectActuator.h"
#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"
@@ -136,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;
@@ -156,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);
@@ -167,6 +170,7 @@ void BL_ConvertActuators(char* maggiename,
drotvec.getValue(),
linvelvec.getValue(),
angvelvec.getValue(),
+ damping,
bitLocalFlag
);
baseact = tmpbaseact;
@@ -177,10 +181,12 @@ void BL_ConvertActuators(char* maggiename,
if (blenderobject->type==OB_ARMATURE){
bActionActuator* actact = (bActionActuator*) bact->data;
STR_String propname = (actact->name ? actact->name : "");
+ STR_String propframe = (actact->frameProp ? actact->frameProp : "");
BL_ActionActuator* tmpbaseact = new BL_ActionActuator(
gameobj,
propname,
+ propframe,
actact->sta,
actact->end,
actact->act,
@@ -597,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;
@@ -857,7 +872,19 @@ void BL_ConvertActuators(char* maggiename,
baseact = tmp_vis_act;
}
break;
-
+
+ case ACT_STATE:
+ {
+ bStateActuator *sta_act = (bStateActuator *) bact->data;
+ KX_StateActuator * tmp_sta_act = NULL;
+
+ tmp_sta_act =
+ new KX_StateActuator(gameobj, sta_act->type, sta_act->mask);
+
+ baseact = tmp_sta_act;
+ }
+ break;
+
case ACT_2DFILTER:
{
bTwoDFilterActuator *_2dfilter = (bTwoDFilterActuator*) bact->data;
@@ -917,7 +944,7 @@ void BL_ConvertActuators(char* maggiename,
}
tmp = new SCA_2DFilterActuator(gameobj, filtermode, _2dfilter->flag,
- _2dfilter->float_arg,_2dfilter->int_arg,ketsjiEngine->GetRasterizer(),rendertools);
+ _2dfilter->float_arg,_2dfilter->int_arg,_2dfilter->texture_flag,ketsjiEngine->GetRasterizer(),rendertools);
if (_2dfilter->text)
{
diff --git a/source/gameengine/Converter/KX_ConvertControllers.cpp b/source/gameengine/Converter/KX_ConvertControllers.cpp
index a26cfa95b6d..da490b4ee85 100644
--- a/source/gameengine/Converter/KX_ConvertControllers.cpp
+++ b/source/gameengine/Converter/KX_ConvertControllers.cpp
@@ -35,6 +35,10 @@
// Controller
#include "SCA_ANDController.h"
#include "SCA_ORController.h"
+#include "SCA_NANDController.h"
+#include "SCA_NORController.h"
+#include "SCA_XORController.h"
+#include "SCA_XNORController.h"
#include "SCA_PythonController.h"
#include "SCA_ExpressionController.h"
@@ -112,6 +116,30 @@ void BL_ConvertControllers(
LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter);
break;
}
+ case CONT_LOGIC_NAND:
+ {
+ gamecontroller = new SCA_NANDController(gameobj);
+ LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter);
+ break;
+ }
+ case CONT_LOGIC_NOR:
+ {
+ gamecontroller = new SCA_NORController(gameobj);
+ LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter);
+ break;
+ }
+ case CONT_LOGIC_XOR:
+ {
+ gamecontroller = new SCA_XORController(gameobj);
+ LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter);
+ break;
+ }
+ case CONT_LOGIC_XNOR:
+ {
+ gamecontroller = new SCA_XNORController(gameobj);
+ LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter);
+ break;
+ }
case CONT_EXPRESSION:
{
bExpressionCont* bexpcont = (bExpressionCont*) bcontr->data;
@@ -161,6 +189,7 @@ void BL_ConvertControllers(
if (gamecontroller)
{
gamecontroller->SetExecutePriority(executePriority++);
+ gamecontroller->SetState(bcontr->state_mask);
STR_String uniquename = bcontr->name;
uniquename += "#CONTR#";
uniqueint++;
diff --git a/source/gameengine/Converter/KX_ConvertSensors.cpp b/source/gameengine/Converter/KX_ConvertSensors.cpp
index 80fa3838d60..e7e4eeae7d2 100644
--- a/source/gameengine/Converter/KX_ConvertSensors.cpp
+++ b/source/gameengine/Converter/KX_ConvertSensors.cpp
@@ -251,6 +251,7 @@ void BL_ConvertSensors(struct Object* blenderobject,
bool neg_pulsemode = false;
int frequency = 0;
bool invert = false;
+ bool level = false;
while(sens)
{
@@ -263,7 +264,8 @@ void BL_ConvertSensors(struct Object* blenderobject,
frequency = sens->freq;
invert = !(sens->invert == 0);
-
+ level = !(sens->level == 0);
+
switch (sens->type)
{
case SENS_ALWAYS:
@@ -711,6 +713,7 @@ void BL_ConvertSensors(struct Object* blenderobject,
neg_pulsemode,
frequency);
gamesensor->SetInvert(invert);
+ gamesensor->SetLevel(level);
gamesensor->SetName(STR_String(sens->name));
gameobj->AddSensor(gamesensor);
diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp
index 56208ab4ad5..f0195d5df82 100644
--- a/source/gameengine/Expressions/Value.cpp
+++ b/source/gameengine/Expressions/Value.cpp
@@ -520,11 +520,6 @@ void CValue::CloneProperties(CValue *replica)
}
-
-
-
-
-
double* CValue::GetVector3(bool bGetTransformedVec)
{
assertd(false); // don;t get vector from me
@@ -775,6 +770,25 @@ int CValue::_setattr(const STR_String& attr,PyObject* pyobj)
//PyObjectPlus::_setattr(attr,value);
return 0;
};
+
+PyObject* CValue::ConvertKeysToPython( void )
+{
+ PyObject *pylist = PyList_New( 0 );
+ PyObject *pystr;
+
+ if (m_pNamedPropertyArray)
+ {
+ for ( std::map<STR_String,CValue*>::iterator it = m_pNamedPropertyArray->begin();
+ !(it == m_pNamedPropertyArray->end());it++)
+ {
+ pystr = PyString_FromString( (*it).first );
+ PyList_Append(pylist, pystr);
+ Py_DECREF( pystr );
+ }
+ }
+ return pylist;
+}
+
/*
PyObject* CValue::PyMake(PyObject* ignored,PyObject* args)
{
diff --git a/source/gameengine/Expressions/Value.h b/source/gameengine/Expressions/Value.h
index ccb9c34749d..561e5521d60 100644
--- a/source/gameengine/Expressions/Value.h
+++ b/source/gameengine/Expressions/Value.h
@@ -253,6 +253,8 @@ public:
virtual int _delattr(const STR_String& attr);
virtual int _setattr(const STR_String& attr,PyObject* value);
+ virtual PyObject* ConvertKeysToPython( void );
+
KX_PYMETHOD(CValue,GetName);
#else
diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
index f3b5b1fdda2..56249bb52ec 100644
--- a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
+++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
@@ -18,6 +18,7 @@ SCA_2DFilterActuator::SCA_2DFilterActuator(
short flag,
float float_arg,
int int_arg,
+ short texture_flag,
RAS_IRasterizer* rasterizer,
RAS_IRenderTools* rendertools,
PyTypeObject* T)
@@ -25,6 +26,7 @@ SCA_2DFilterActuator::SCA_2DFilterActuator(
m_type(type),
m_flag(flag),
m_int_arg(int_arg),
+ m_texture_flag(texture_flag),
m_float_arg(float_arg),
m_rasterizer(rasterizer),
m_rendertools(rendertools)
@@ -72,7 +74,7 @@ bool SCA_2DFilterActuator::Update()
}
else if(m_type < RAS_2DFilterManager::RAS_2DFILTER_NUMBER_OF_FILTERS)
{
- m_rendertools->Update2DFilter(m_type, m_int_arg, m_shaderText);
+ m_rendertools->Update2DFilter(m_type, m_int_arg, m_shaderText, m_texture_flag);
}
return true;
}
diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.h b/source/gameengine/GameLogic/SCA_2DFilterActuator.h
index 7b0cfff951e..451a7b9491a 100644
--- a/source/gameengine/GameLogic/SCA_2DFilterActuator.h
+++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.h
@@ -16,6 +16,7 @@ private:
short m_flag;
float m_float_arg;
int m_int_arg;
+ short m_texture_flag;
STR_String m_shaderText;
RAS_IRasterizer* m_rasterizer;
RAS_IRenderTools* m_rendertools;
@@ -28,6 +29,7 @@ public:
short flag,
float float_arg,
int int_arg,
+ short texture_flag,
RAS_IRasterizer* rasterizer,
RAS_IRenderTools* rendertools,
PyTypeObject* T=&Type
diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp
index 67df5d091ab..f9fbf2387c4 100644
--- a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp
@@ -53,10 +53,13 @@ SCA_AlwaysSensor::SCA_AlwaysSensor(class SCA_EventManager* eventmgr,
: SCA_ISensor(gameobj,eventmgr, T)
{
//SetDrawColor(255,0,0);
- m_alwaysresult = true;
+ Init();
}
-
+void SCA_AlwaysSensor::Init()
+{
+ m_alwaysresult = true;
+}
SCA_AlwaysSensor::~SCA_AlwaysSensor()
{
diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.h b/source/gameengine/GameLogic/SCA_AlwaysSensor.h
index 474ed025432..8bf2a8aa98e 100644
--- a/source/gameengine/GameLogic/SCA_AlwaysSensor.h
+++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.h
@@ -45,6 +45,8 @@ public:
virtual CValue* GetReplica();
virtual bool Evaluate(CValue* event);
virtual bool IsPositiveTrigger();
+ virtual void Init();
+
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
diff --git a/source/gameengine/GameLogic/SCA_IActuator.cpp b/source/gameengine/GameLogic/SCA_IActuator.cpp
index 568d0eb4a89..eeca2d7b44c 100644
--- a/source/gameengine/GameLogic/SCA_IActuator.cpp
+++ b/source/gameengine/GameLogic/SCA_IActuator.cpp
@@ -36,6 +36,7 @@ using namespace std;
SCA_IActuator::SCA_IActuator(SCA_IObject* gameobj,
PyTypeObject* T) :
+ m_links(0),
SCA_ILogicBrick(gameobj,T)
{
// nothing to do
@@ -109,3 +110,12 @@ SCA_IActuator::~SCA_IActuator()
RemoveAllEvents();
}
+void SCA_IActuator::DecLink()
+{
+ m_links--;
+ if (m_links < 0)
+ {
+ printf("Warning: actuator %s has negative m_links: %d\n", m_name.Ptr(), m_links);
+ m_links = 0;
+ }
+}
diff --git a/source/gameengine/GameLogic/SCA_IActuator.h b/source/gameengine/GameLogic/SCA_IActuator.h
index b802aa4b298..774b27c5ad4 100644
--- a/source/gameengine/GameLogic/SCA_IActuator.h
+++ b/source/gameengine/GameLogic/SCA_IActuator.h
@@ -34,8 +34,11 @@
class SCA_IActuator : public SCA_ILogicBrick
{
+ friend class SCA_LogicManager;
protected:
std::vector<CValue*> m_events;
+ int m_links; // number of active links to controllers
+ // when 0, the actuator is automatically stopped
void RemoveAllEvents();
public:
@@ -83,6 +86,10 @@ public:
*/
bool IsNegativeEvent() const;
virtual ~SCA_IActuator();
+
+ void IncLink() { m_links++; }
+ void DecLink();
+ bool IsNoLink() const { return !m_links; }
};
#endif //__KX_IACTUATOR
diff --git a/source/gameengine/GameLogic/SCA_IController.cpp b/source/gameengine/GameLogic/SCA_IController.cpp
index 5cb62678c6b..bbe5a51db3c 100644
--- a/source/gameengine/GameLogic/SCA_IController.cpp
+++ b/source/gameengine/GameLogic/SCA_IController.cpp
@@ -29,6 +29,7 @@
#include "SCA_IController.h"
#include "SCA_LogicManager.h"
#include "SCA_IActuator.h"
+#include "SCA_ISensor.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -37,6 +38,7 @@
SCA_IController::SCA_IController(SCA_IObject* gameobj,
PyTypeObject* T)
:
+ m_statemask(0),
SCA_ILogicBrick(gameobj,T)
{
}
@@ -45,6 +47,7 @@ SCA_IController::SCA_IController(SCA_IObject* gameobj,
SCA_IController::~SCA_IController()
{
+ UnlinkAllActuators();
}
@@ -65,6 +68,14 @@ const std::vector<class SCA_IActuator*>& SCA_IController::GetLinkedActuators()
void SCA_IController::UnlinkAllSensors()
{
+ if (IsActive())
+ {
+ std::vector<class SCA_ISensor*>::iterator sensit;
+ for (sensit = m_linkedsensors.begin();!(sensit==m_linkedsensors.end());++sensit)
+ {
+ (*sensit)->DecLink();
+ }
+ }
m_linkedsensors.clear();
}
@@ -72,6 +83,14 @@ void SCA_IController::UnlinkAllSensors()
void SCA_IController::UnlinkAllActuators()
{
+ if (IsActive())
+ {
+ std::vector<class SCA_IActuator*>::iterator actit;
+ for (actit = m_linkedactuators.begin();!(actit==m_linkedactuators.end());++actit)
+ {
+ (*actit)->DecLink();
+ }
+ }
m_linkedactuators.clear();
}
@@ -95,26 +114,94 @@ void SCA_IController::Trigger(SCA_LogicManager* logicmgr)
void SCA_IController::LinkToActuator(SCA_IActuator* actua)
{
m_linkedactuators.push_back(actua);
+ if (IsActive())
+ {
+ actua->IncLink();
+ }
}
void SCA_IController::UnlinkActuator(class SCA_IActuator* actua)
{
std::vector<class SCA_IActuator*>::iterator actit;
- std::vector<class SCA_IActuator*>::iterator actfound = m_linkedactuators.end();
for (actit = m_linkedactuators.begin();!(actit==m_linkedactuators.end());++actit)
{
if ((*actit) == actua)
- actfound = actit;
+ {
+ break;
+ }
}
- if (!(actfound==m_linkedactuators.end()))
+ if (!(actit==m_linkedactuators.end()))
{
- m_linkedactuators.erase(actfound);
+ m_linkedactuators.erase(actit);
+ if (IsActive())
+ {
+ (*actit)->DecLink();
+ }
}
-
}
void SCA_IController::LinkToSensor(SCA_ISensor* sensor)
{
m_linkedsensors.push_back(sensor);
+ if (IsActive())
+ {
+ sensor->IncLink();
+ }
+}
+
+void SCA_IController::UnlinkSensor(class SCA_ISensor* sensor)
+{
+ std::vector<class SCA_ISensor*>::iterator sensit;
+ for (sensit = m_linkedsensors.begin();!(sensit==m_linkedsensors.end());++sensit)
+ {
+ if ((*sensit) == sensor)
+ {
+ break;
+ }
+
+ }
+ if (!(sensit==m_linkedsensors.end()))
+ {
+ m_linkedsensors.erase(sensit);
+ if (IsActive())
+ {
+ (*sensit)->DecLink();
+ }
+ }
}
+
+void SCA_IController::ApplyState(unsigned int state)
+{
+ std::vector<class SCA_IActuator*>::iterator actit;
+ std::vector<class SCA_ISensor*>::iterator sensit;
+
+ if (m_statemask & state)
+ {
+ if (!IsActive())
+ {
+ // reactive the controller, all the links to actuator are valid again
+ for (actit = m_linkedactuators.begin();!(actit==m_linkedactuators.end());++actit)
+ {
+ (*actit)->IncLink();
+ }
+ for (sensit = m_linkedsensors.begin();!(sensit==m_linkedsensors.end());++sensit)
+ {
+ (*sensit)->IncLink();
+ }
+ SetActive(true);
+ }
+ } else if (IsActive())
+ {
+ for (actit = m_linkedactuators.begin();!(actit==m_linkedactuators.end());++actit)
+ {
+ (*actit)->DecLink();
+ }
+ for (sensit = m_linkedsensors.begin();!(sensit==m_linkedsensors.end());++sensit)
+ {
+ (*sensit)->DecLink();
+ }
+ SetActive(false);
+ }
+}
+
diff --git a/source/gameengine/GameLogic/SCA_IController.h b/source/gameengine/GameLogic/SCA_IController.h
index 79e956dec4e..f67c0942eb4 100644
--- a/source/gameengine/GameLogic/SCA_IController.h
+++ b/source/gameengine/GameLogic/SCA_IController.h
@@ -36,6 +36,7 @@ class SCA_IController : public SCA_ILogicBrick
protected:
std::vector<class SCA_ISensor*> m_linkedsensors;
std::vector<class SCA_IActuator*> m_linkedactuators;
+ unsigned int m_statemask;
public:
SCA_IController(SCA_IObject* gameobj,PyTypeObject* T);
virtual ~SCA_IController();
@@ -47,6 +48,9 @@ public:
void UnlinkAllSensors();
void UnlinkAllActuators();
void UnlinkActuator(class SCA_IActuator* actua);
+ void UnlinkSensor(class SCA_ISensor* sensor);
+ void SetState(unsigned int state) { m_statemask = state; }
+ void ApplyState(unsigned int state);
};
diff --git a/source/gameengine/GameLogic/SCA_IObject.cpp b/source/gameengine/GameLogic/SCA_IObject.cpp
index 6df9e23f3fa..826e7bbdf0e 100644
--- a/source/gameengine/GameLogic/SCA_IObject.cpp
+++ b/source/gameengine/GameLogic/SCA_IObject.cpp
@@ -40,7 +40,7 @@
MT_Point3 SCA_IObject::m_sDummy=MT_Point3(0,0,0);
-SCA_IObject::SCA_IObject(PyTypeObject* T): CValue(T)
+SCA_IObject::SCA_IObject(PyTypeObject* T): m_state(0), CValue(T)
{
m_suspended = false;
}
@@ -329,6 +329,17 @@ void SCA_IObject::Resume(void)
}
}
+void SCA_IObject::SetState(unsigned int state)
+{
+ m_state = state;
+ // update the status of the controllers
+ SCA_ControllerList::iterator contit;
+ for (contit = m_controllers.begin(); contit != m_controllers.end(); contit++)
+ {
+ (*contit)->ApplyState(m_state);
+ }
+}
+
/* ------------------------------------------------------------------------- */
diff --git a/source/gameengine/GameLogic/SCA_IObject.h b/source/gameengine/GameLogic/SCA_IObject.h
index e8251e0ceaa..07b4310a91e 100644
--- a/source/gameengine/GameLogic/SCA_IObject.h
+++ b/source/gameengine/GameLogic/SCA_IObject.h
@@ -67,7 +67,12 @@ protected:
* Ignore updates?
*/
bool m_suspended;
-
+
+ /**
+ * current state = bit mask of state that are active
+ */
+ unsigned int m_state;
+
public:
SCA_IObject(PyTypeObject* T=&Type);
@@ -111,7 +116,17 @@ public:
* Resume progress
*/
void Resume(void);
-
+
+ /**
+ * Set the object state
+ */
+ void SetState(unsigned int state);
+
+ /**
+ * Get the object state
+ */
+ unsigned int GetState(void) { return m_state; }
+
// const class MT_Point3& ConvertPythonPylist(PyObject* pylist);
// here come the python forwarded methods
diff --git a/source/gameengine/GameLogic/SCA_ISensor.cpp b/source/gameengine/GameLogic/SCA_ISensor.cpp
index 9fdee0c19da..6cfae9d8919 100644
--- a/source/gameengine/GameLogic/SCA_ISensor.cpp
+++ b/source/gameengine/GameLogic/SCA_ISensor.cpp
@@ -52,8 +52,10 @@ SCA_ISensor::SCA_ISensor(SCA_IObject* gameobj,
SCA_ILogicBrick(gameobj,T),
m_triggered(false)
{
+ m_links = 0;
m_suspended = false;
m_invert = false;
+ m_level = false;
m_pos_ticks = 0;
m_neg_ticks = 0;
m_pos_pulsemode = false;
@@ -94,6 +96,10 @@ void SCA_ISensor::SetInvert(bool inv) {
m_invert = inv;
}
+void SCA_ISensor::SetLevel(bool lvl) {
+ m_level = lvl;
+}
+
float SCA_ISensor::GetNumber() {
return IsPositiveTrigger();
@@ -111,6 +117,25 @@ void SCA_ISensor::Resume() {
m_suspended = false;
}
+void SCA_ISensor::Init() {
+ printf("Sensor %s has no init function, please report this bug to Blender.org\n", m_name);
+}
+
+void SCA_ISensor::DecLink() {
+ m_links--;
+ if (m_links < 0)
+ {
+ printf("Warning: sensor %s has negative m_links: %d\n", m_name.Ptr(), m_links);
+ m_links = 0;
+ }
+ if (!m_links)
+ {
+ // sensor is detached from all controllers, initialize it so that it
+ // is fresh as at startup when it is reattached again.
+ Init();
+ }
+}
+
/* python integration */
PyTypeObject SCA_ISensor::Type = {
@@ -157,6 +182,10 @@ PyMethodDef SCA_ISensor::Methods[] = {
METH_VARARGS, GetInvert_doc},
{"setInvert", (PyCFunction) SCA_ISensor::sPySetInvert,
METH_VARARGS, SetInvert_doc},
+ {"getLevel", (PyCFunction) SCA_ISensor::sPyGetLevel,
+ METH_VARARGS, GetLevel_doc},
+ {"setLevel", (PyCFunction) SCA_ISensor::sPySetLevel,
+ METH_VARARGS, SetLevel_doc},
{NULL,NULL} //Sentinel
};
@@ -177,7 +206,8 @@ void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr, CValue* event)
{
// calculate if a __triggering__ is wanted
- if (!m_suspended) {
+ // don't evaluate a sensor that is not connected to any controller
+ if (m_links && !m_suspended) {
bool result = this->Evaluate(event);
if (result) {
logicmgr->AddActivatedSensor(this);
@@ -307,6 +337,31 @@ PyObject* SCA_ISensor::PySetInvert(PyObject* self, PyObject* args, PyObject* kwd
Py_Return;
}
+char SCA_ISensor::GetLevel_doc[] =
+"getLevel()\n"
+"\tReturns whether this sensor is a level detector or a edge detector.\n"
+"\tIt makes a difference only in case of logic state transition (state actuator).\n"
+"\tA level detector will immediately generate a pulse if the condition for the\n"
+"\tdetector is met when entering the state. A edge detector will wait for an off-on\n"
+"\ttransition to occur.\n"
+"\tOnly some sensors implement this feature: keyboard.\n";
+PyObject* SCA_ISensor::PyGetLevel(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ return BoolToPyArg(m_level);
+}
+
+char SCA_ISensor::SetLevel_doc[] =
+"setLevel(level?)\n"
+"\t- level?: Detect level instead of edge? (KX_TRUE, KX_FALSE)\n"
+"\tSet whether to detect level or edge transition when entering a state.\n";
+PyObject* SCA_ISensor::PySetLevel(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ int pyarg = 0;
+ if(!PyArg_ParseTuple(args, "i", &pyarg)) { return NULL; }
+ m_level = PyArgToBool(pyarg);
+ Py_Return;
+}
+
char SCA_ISensor::GetUseNegPulseMode_doc[] =
"getUseNegPulseMode()\n"
"\tReturns whether negative pulse mode is active.\n";
diff --git a/source/gameengine/GameLogic/SCA_ISensor.h b/source/gameengine/GameLogic/SCA_ISensor.h
index e14fb34241a..3527b87ebdb 100644
--- a/source/gameengine/GameLogic/SCA_ISensor.h
+++ b/source/gameengine/GameLogic/SCA_ISensor.h
@@ -61,9 +61,15 @@ class SCA_ISensor : public SCA_ILogicBrick
/** invert the output signal*/
bool m_invert;
+ /** detect level instead of edge*/
+ bool m_level;
+
/** Sensor must ignore updates? */
bool m_suspended;
+ /** number of connections to controller */
+ int m_links;
+
/** Pass the activation on to the logic manager.*/
void SignalActivation(class SCA_LogicManager* logicmgr);
@@ -81,6 +87,7 @@ public:
void Activate(class SCA_LogicManager* logicmgr,CValue* event);
virtual bool Evaluate(CValue* event) = 0;
virtual bool IsPositiveTrigger();
+ virtual void Init();
virtual PyObject* _getattr(const STR_String& attr);
virtual CValue* GetReplica()=0;
@@ -101,6 +108,8 @@ public:
virtual void Delete() { Release(); }
/** Set inversion of pulses on or off. */
void SetInvert(bool inv);
+ /** set the level detection on or off */
+ void SetLevel(bool lvl);
void RegisterToManager();
virtual float GetNumber();
@@ -114,6 +123,12 @@ public:
/** Resume sensing. */
void Resume();
+ void IncLink()
+ { m_links++; }
+ void DecLink();
+ bool IsNoLink() const
+ { return !m_links; }
+
/* Python functions: */
KX_PYMETHOD_DOC(SCA_ISensor,IsPositive);
KX_PYMETHOD_DOC(SCA_ISensor,GetUsePosPulseMode);
@@ -124,6 +139,8 @@ public:
KX_PYMETHOD_DOC(SCA_ISensor,SetUseNegPulseMode);
KX_PYMETHOD_DOC(SCA_ISensor,GetInvert);
KX_PYMETHOD_DOC(SCA_ISensor,SetInvert);
+ KX_PYMETHOD_DOC(SCA_ISensor,GetLevel);
+ KX_PYMETHOD_DOC(SCA_ISensor,SetLevel);
};
diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp
index b0e7fee130d..8668c22f044 100644
--- a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp
@@ -64,9 +64,13 @@ std::cout << " button flag "<< m_buttonf << std::endl;
std::cout << " hat " << m_hat << std::endl;
std::cout << " hat flag " << m_hatf << std::endl;
*/
- m_istrig=0;
+ Init();
}
+void SCA_JoystickSensor::Init()
+{
+ m_istrig=(m_invert)?1:0;
+}
SCA_JoystickSensor::~SCA_JoystickSensor()
{
diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.h b/source/gameengine/GameLogic/SCA_JoystickSensor.h
index 2fbe1edf1e7..69068da6494 100644
--- a/source/gameengine/GameLogic/SCA_JoystickSensor.h
+++ b/source/gameengine/GameLogic/SCA_JoystickSensor.h
@@ -95,6 +95,7 @@ public:
virtual bool Evaluate(CValue* event);
virtual bool IsPositiveTrigger();
+ virtual void Init();
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
index f13b1bcf4c9..43ce25f94df 100644
--- a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
@@ -62,7 +62,7 @@ SCA_KeyboardSensor::SCA_KeyboardSensor(SCA_KeyboardManager* keybdmgr,
if (hotkey == SCA_IInputDevice::KX_ESCKEY)
keybdmgr->GetInputDevice()->HookEscape();
// SetDrawColor(0xff0000ff);
- m_val=0;
+ Init();
}
@@ -71,7 +71,14 @@ SCA_KeyboardSensor::~SCA_KeyboardSensor()
{
}
-
+void SCA_KeyboardSensor::Init()
+{
+ // this function is used when the sensor is disconnected from all controllers
+ // by the state engine. It reinitializes the sensor as if it was just created.
+ // However, if the target key is pressed when the sensor is reactivated, it
+ // will not generated an event (see remark in Evaluate()).
+ m_val = (m_invert)?1:0;
+}
CValue* SCA_KeyboardSensor::GetReplica()
{
@@ -169,10 +176,10 @@ bool SCA_KeyboardSensor::Evaluate(CValue* eventval)
{
if (m_val == 0)
{
- //see comment below
- //m_val = 1;
- //result = true;
- ;
+ if (m_level) {
+ m_val = 1;
+ result = true;
+ }
}
} else
{
@@ -222,15 +229,11 @@ bool SCA_KeyboardSensor::Evaluate(CValue* eventval)
{
if (m_val == 0)
{
- //hmm, this abnormal situation may occur in the following cases:
- //- the key was pressed while the scene was suspended
- //- this is a new scene and the key is active from the start
- //In the second case, it's dangerous to activate the sensor
- //(think of a key to go to next scene)
- //What we really need is a edge/level flag in the key sensor
- //m_val = 1;
- //result = true;
- ;
+ if (m_level)
+ {
+ m_val = 1;
+ result = true;
+ }
}
}
}
diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.h b/source/gameengine/GameLogic/SCA_KeyboardSensor.h
index e87eddecd32..b86f6931d27 100644
--- a/source/gameengine/GameLogic/SCA_KeyboardSensor.h
+++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.h
@@ -114,6 +114,8 @@ public:
PyTypeObject* T=&Type );
virtual ~SCA_KeyboardSensor();
virtual CValue* GetReplica();
+ virtual void Init();
+
short int GetHotkey();
virtual bool Evaluate(CValue* event);
diff --git a/source/gameengine/GameLogic/SCA_LogicManager.cpp b/source/gameengine/GameLogic/SCA_LogicManager.cpp
index 49f01d643e5..fb1a2c29eb6 100644
--- a/source/gameengine/GameLogic/SCA_LogicManager.cpp
+++ b/source/gameengine/GameLogic/SCA_LogicManager.cpp
@@ -165,6 +165,11 @@ void* SCA_LogicManager::FindBlendObjByGameMeshName(const STR_String& gamemeshnam
void SCA_LogicManager::RemoveSensor(SCA_ISensor* sensor)
{
+ controllerlist contlist = m_sensorcontrollermapje[sensor];
+ for (controllerlist::const_iterator c= contlist.begin();!(c==contlist.end());c++)
+ {
+ (*c)->UnlinkSensor(sensor);
+ }
m_sensorcontrollermapje.erase(sensor);
for (vector<SCA_EventManager*>::const_iterator ie=m_eventmanagers.begin();
@@ -176,6 +181,8 @@ void SCA_LogicManager::RemoveSensor(SCA_ISensor* sensor)
void SCA_LogicManager::RemoveController(SCA_IController* controller)
{
+ controller->UnlinkAllSensors();
+ controller->UnlinkAllActuators();
std::map<SCA_ISensor*,controllerlist>::iterator sit;
for (sit = m_sensorcontrollermapje.begin();!(sit==m_sensorcontrollermapje.end());++sit)
{
@@ -236,7 +243,8 @@ void SCA_LogicManager::BeginFrame(double curtime, double fixedtime)
!(c==contlist.end());c++)
{
SCA_IController* contr = *c;//controllerarray->at(c);
- triggeredControllerSet.insert(SmartControllerPtr(contr,0));
+ if (contr->IsActive())
+ triggeredControllerSet.insert(SmartControllerPtr(contr,0));
}
//sensor->SetActive(false);
}
@@ -273,6 +281,16 @@ void SCA_LogicManager::UpdateFrame(double curtime, bool frame)
(*ia)->SetActive(false);
//m_activeactuators.pop_back();
+ } else if ((*ia)->IsNoLink())
+ {
+ // This actuator has no more links but it still active
+ // make sure it will get a negative event on next frame to stop it
+ // Do this check after Update() rather than before to make sure
+ // that all the actuators that are activated at same time than a state
+ // actuator have a chance to execute.
+ CValue* event = new CBoolValue(false);
+ (*ia)->RemoveAllEvents();
+ (*ia)->AddEvent(event);
}
}
diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.cpp b/source/gameengine/GameLogic/SCA_MouseSensor.cpp
index 8810b7470ed..42d35837489 100644
--- a/source/gameengine/GameLogic/SCA_MouseSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_MouseSensor.cpp
@@ -58,7 +58,6 @@ SCA_MouseSensor::SCA_MouseSensor(SCA_MouseManager* eventmgr,
{
m_mousemode = mousemode;
m_triggermode = true;
- m_val = 0; /* stores the latest attribute */
switch (m_mousemode) {
case KX_MOUSESENSORMODE_LEFTBUTTON:
@@ -79,7 +78,12 @@ SCA_MouseSensor::SCA_MouseSensor(SCA_MouseManager* eventmgr,
default:
; /* ignore, no hotkey */
}
+ Init();
+}
+void SCA_MouseSensor::Init()
+{
+ m_val = (m_invert)?1:0; /* stores the latest attribute */
}
SCA_MouseSensor::~SCA_MouseSensor()
@@ -164,10 +168,11 @@ bool SCA_MouseSensor::Evaluate(CValue* event)
{
if (m_val == 0)
{
- //dangerous
- //m_val = 1;
- //result = true;
- ;
+ if (m_level)
+ {
+ m_val = 1;
+ result = true;
+ }
}
} else
{
diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.h b/source/gameengine/GameLogic/SCA_MouseSensor.h
index 86c9d96a800..26a1c5e3fd2 100644
--- a/source/gameengine/GameLogic/SCA_MouseSensor.h
+++ b/source/gameengine/GameLogic/SCA_MouseSensor.h
@@ -96,7 +96,7 @@ class SCA_MouseSensor : public SCA_ISensor
virtual ~SCA_MouseSensor();
virtual CValue* GetReplica();
virtual bool Evaluate(CValue* event);
-
+ virtual void Init();
virtual bool IsPositiveTrigger();
short int GetModeKey();
SCA_IInputDevice::KX_EnumInputs GetHotKey();
diff --git a/source/gameengine/GameLogic/SCA_NANDController.cpp b/source/gameengine/GameLogic/SCA_NANDController.cpp
new file mode 100644
index 00000000000..5b869ee8298
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_NANDController.cpp
@@ -0,0 +1,144 @@
+/**
+ * 'Nand' together all inputs
+ *
+ * $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 *****
+ */
+
+#include "SCA_NANDController.h"
+#include "SCA_ISensor.h"
+#include "SCA_LogicManager.h"
+#include "BoolValue.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+SCA_NANDController::SCA_NANDController(SCA_IObject* gameobj,
+ PyTypeObject* T)
+ :
+ SCA_IController(gameobj,T)
+{
+}
+
+
+
+SCA_NANDController::~SCA_NANDController()
+{
+}
+
+
+
+void SCA_NANDController::Trigger(SCA_LogicManager* logicmgr)
+{
+
+ bool sensorresult = false;
+
+ for (vector<SCA_ISensor*>::const_iterator is=m_linkedsensors.begin();
+ !(is==m_linkedsensors.end());is++)
+ {
+ SCA_ISensor* sensor = *is;
+ if (!sensor->IsPositiveTrigger())
+ {
+ sensorresult = true;
+ break;
+ }
+ }
+
+ CValue* newevent = new CBoolValue(sensorresult);
+
+ for (vector<SCA_IActuator*>::const_iterator i=m_linkedactuators.begin();
+ !(i==m_linkedactuators.end());i++)
+ {
+ SCA_IActuator* actua = *i;//m_linkedactuators.at(i);
+ logicmgr->AddActiveActuator(actua,newevent);
+ }
+
+ // every actuator that needs the event, has a it's own reference to it now so
+ // release it (so to be clear: if there is no actuator, it's deleted right now)
+ newevent->Release();
+
+}
+
+
+
+CValue* SCA_NANDController::GetReplica()
+{
+ CValue* replica = new SCA_NANDController(*this);
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_NANDController::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_NANDController",
+ sizeof(SCA_NANDController),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject SCA_NANDController::Parents[] = {
+ &SCA_NANDController::Type,
+ &SCA_IController::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef SCA_NANDController::Methods[] = {
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* SCA_NANDController::_getattr(const STR_String& attr) {
+ _getattr_up(SCA_IController);
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_NANDController.h b/source/gameengine/GameLogic/SCA_NANDController.h
new file mode 100644
index 00000000000..1193ff64f07
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_NANDController.h
@@ -0,0 +1,56 @@
+/**
+ * SCA_NANDController.h
+ *
+ * $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 *****
+ */
+
+#ifndef __KX_NANDCONTROLLER
+#define __KX_NANDCONTROLLER
+
+#include "SCA_IController.h"
+
+class SCA_NANDController : public SCA_IController
+{
+ Py_Header;
+ //virtual void Trigger(class SCA_LogicManager* logicmgr);
+public:
+ SCA_NANDController(SCA_IObject* gameobj,PyTypeObject* T=&Type);
+ virtual ~SCA_NANDController();
+ virtual CValue* GetReplica();
+ virtual void Trigger(SCA_LogicManager* logicmgr);
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(const STR_String& attr);
+
+};
+
+#endif //__KX_NANDCONTROLLER
+
diff --git a/source/gameengine/GameLogic/SCA_NORController.cpp b/source/gameengine/GameLogic/SCA_NORController.cpp
new file mode 100644
index 00000000000..2866dec0b74
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_NORController.cpp
@@ -0,0 +1,144 @@
+/**
+ * 'Nor' together all inputs
+ *
+ * $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 *****
+ */
+
+#include "SCA_NORController.h"
+#include "SCA_ISensor.h"
+#include "SCA_LogicManager.h"
+#include "BoolValue.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+SCA_NORController::SCA_NORController(SCA_IObject* gameobj,
+ PyTypeObject* T)
+ :
+ SCA_IController(gameobj,T)
+{
+}
+
+
+
+SCA_NORController::~SCA_NORController()
+{
+}
+
+
+
+void SCA_NORController::Trigger(SCA_LogicManager* logicmgr)
+{
+
+ bool sensorresult = true;
+
+ for (vector<SCA_ISensor*>::const_iterator is=m_linkedsensors.begin();
+ !(is==m_linkedsensors.end());is++)
+ {
+ SCA_ISensor* sensor = *is;
+ if (sensor->IsPositiveTrigger())
+ {
+ sensorresult = false;
+ break;
+ }
+ }
+
+ CValue* newevent = new CBoolValue(sensorresult);
+
+ for (vector<SCA_IActuator*>::const_iterator i=m_linkedactuators.begin();
+ !(i==m_linkedactuators.end());i++)
+ {
+ SCA_IActuator* actua = *i;//m_linkedactuators.at(i);
+ logicmgr->AddActiveActuator(actua,newevent);
+ }
+
+ // every actuator that needs the event, has a it's own reference to it now so
+ // release it (so to be clear: if there is no actuator, it's deleted right now)
+ newevent->Release();
+
+}
+
+
+
+CValue* SCA_NORController::GetReplica()
+{
+ CValue* replica = new SCA_NORController(*this);
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_NORController::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_NORController",
+ sizeof(SCA_NORController),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject SCA_NORController::Parents[] = {
+ &SCA_NORController::Type,
+ &SCA_IController::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef SCA_NORController::Methods[] = {
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* SCA_NORController::_getattr(const STR_String& attr) {
+ _getattr_up(SCA_IController);
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_NORController.h b/source/gameengine/GameLogic/SCA_NORController.h
new file mode 100644
index 00000000000..aab59e3d46c
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_NORController.h
@@ -0,0 +1,56 @@
+/**
+ * SCA_NORController.h
+ *
+ * $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 *****
+ */
+
+#ifndef __KX_NORCONTROLLER
+#define __KX_NORCONTROLLER
+
+#include "SCA_IController.h"
+
+class SCA_NORController : public SCA_IController
+{
+ Py_Header;
+ //virtual void Trigger(class SCA_LogicManager* logicmgr);
+public:
+ SCA_NORController(SCA_IObject* gameobj,PyTypeObject* T=&Type);
+ virtual ~SCA_NORController();
+ virtual CValue* GetReplica();
+ virtual void Trigger(SCA_LogicManager* logicmgr);
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(const STR_String& attr);
+
+};
+
+#endif //__KX_NORCONTROLLER
+
diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.cpp b/source/gameengine/GameLogic/SCA_PropertySensor.cpp
index f1fcb18d32e..655e9060238 100644
--- a/source/gameengine/GameLogic/SCA_PropertySensor.cpp
+++ b/source/gameengine/GameLogic/SCA_PropertySensor.cpp
@@ -54,10 +54,8 @@ SCA_PropertySensor::SCA_PropertySensor(SCA_EventManager* eventmgr,
m_checkpropval(propval),
m_checkpropmaxval(propmaxval),
m_checkpropname(propname),
- m_lastresult(false),
m_range_expr(NULL)
{
- m_recentresult=false;
//CParser pars;
//pars.SetContext(this->AddRef());
//CValue* resultval = m_rightexpr->Calculate();
@@ -73,7 +71,13 @@ SCA_PropertySensor::SCA_PropertySensor(SCA_EventManager* eventmgr,
{
PrecalculateRangeExpression();
}
+ Init();
+}
+void SCA_PropertySensor::Init()
+{
+ m_recentresult = false;
+ m_lastresult = m_invert?true:false;
}
void SCA_PropertySensor::PrecalculateRangeExpression()
diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.h b/source/gameengine/GameLogic/SCA_PropertySensor.h
index 81c9b958f25..6871cb3afdc 100644
--- a/source/gameengine/GameLogic/SCA_PropertySensor.h
+++ b/source/gameengine/GameLogic/SCA_PropertySensor.h
@@ -77,6 +77,7 @@ public:
virtual void Delete();
virtual ~SCA_PropertySensor();
virtual CValue* GetReplica();
+ virtual void Init();
void PrecalculateRangeExpression();
bool CheckPropertyCondition();
diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp
index 44cdc0a7de5..be00117cd21 100644
--- a/source/gameengine/GameLogic/SCA_PythonController.cpp
+++ b/source/gameengine/GameLogic/SCA_PythonController.cpp
@@ -232,6 +232,7 @@ PyMethodDef SCA_PythonController::Methods[] = {
METH_VARARGS, SCA_PythonController::GetSensor_doc},
{"getScript", (PyCFunction) SCA_PythonController::sPyGetScript, METH_VARARGS},
{"setScript", (PyCFunction) SCA_PythonController::sPySetScript, METH_VARARGS},
+ {"getState", (PyCFunction) SCA_PythonController::sPyGetState, METH_VARARGS},
{NULL,NULL} //Sentinel
};
@@ -442,4 +443,12 @@ PyObject* SCA_PythonController::PySetScript(PyObject* self,
Py_Return;
}
+/* 1. getScript */
+PyObject* SCA_PythonController::PyGetState(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ return PyInt_FromLong(m_statemask);
+}
+
/* eof */
diff --git a/source/gameengine/GameLogic/SCA_PythonController.h b/source/gameengine/GameLogic/SCA_PythonController.h
index 63975234da9..f3af54f402f 100644
--- a/source/gameengine/GameLogic/SCA_PythonController.h
+++ b/source/gameengine/GameLogic/SCA_PythonController.h
@@ -81,6 +81,7 @@ class SCA_PythonController : public SCA_IController
KX_PYMETHOD_DOC(SCA_PythonController,GetActuators);
KX_PYMETHOD(SCA_PythonController,SetScript);
KX_PYMETHOD(SCA_PythonController,GetScript);
+ KX_PYMETHOD(SCA_PythonController,GetState);
};
diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.cpp b/source/gameengine/GameLogic/SCA_RandomSensor.cpp
index 0e856e0d6bb..3626522e49a 100644
--- a/source/gameengine/GameLogic/SCA_RandomSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_RandomSensor.cpp
@@ -50,16 +50,9 @@ SCA_RandomSensor::SCA_RandomSensor(SCA_EventManager* eventmgr,
PyTypeObject* T)
: SCA_ISensor(gameobj,eventmgr, T)
{
- m_iteration = 0;
- m_interval = 0;
- m_lastdraw = false;
-
// m_basegenerator is never deleted => memory leak
m_basegenerator = new SCA_RandomNumberGenerator(startseed);
- m_currentDraw = m_basegenerator->Draw();
- //registration is done globally, don't do it here
- //Note: it was probably done to work around a bug in Evaluate(). It is now fixed
- //RegisterToManager();
+ Init();
}
@@ -69,6 +62,13 @@ SCA_RandomSensor::~SCA_RandomSensor()
/* Nothing to be done here. */
}
+void SCA_RandomSensor::Init()
+{
+ m_iteration = 0;
+ m_interval = 0;
+ m_lastdraw = false;
+ m_currentDraw = m_basegenerator->Draw();
+}
CValue* SCA_RandomSensor::GetReplica()
diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.h b/source/gameengine/GameLogic/SCA_RandomSensor.h
index cc54179aa4e..d29bfb6837a 100644
--- a/source/gameengine/GameLogic/SCA_RandomSensor.h
+++ b/source/gameengine/GameLogic/SCA_RandomSensor.h
@@ -54,6 +54,7 @@ public:
virtual CValue* GetReplica();
virtual bool Evaluate(CValue* event);
virtual bool IsPositiveTrigger();
+ virtual void Init();
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
diff --git a/source/gameengine/GameLogic/SCA_XNORController.cpp b/source/gameengine/GameLogic/SCA_XNORController.cpp
new file mode 100644
index 00000000000..3ef7c07fe0a
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_XNORController.cpp
@@ -0,0 +1,148 @@
+/**
+ * 'Xnor' together all inputs
+ *
+ * $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 *****
+ */
+
+#include "SCA_XNORController.h"
+#include "SCA_ISensor.h"
+#include "SCA_LogicManager.h"
+#include "BoolValue.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+SCA_XNORController::SCA_XNORController(SCA_IObject* gameobj,
+ PyTypeObject* T)
+ :
+ SCA_IController(gameobj,T)
+{
+}
+
+
+
+SCA_XNORController::~SCA_XNORController()
+{
+}
+
+
+
+void SCA_XNORController::Trigger(SCA_LogicManager* logicmgr)
+{
+
+ bool sensorresult = true;
+
+ for (vector<SCA_ISensor*>::const_iterator is=m_linkedsensors.begin();
+ !(is==m_linkedsensors.end());is++)
+ {
+ SCA_ISensor* sensor = *is;
+ if (sensor->IsPositiveTrigger())
+ {
+ if (sensorresult == false)
+ {
+ sensorresult = true;
+ break;
+ }
+ sensorresult = false;
+ }
+ }
+
+ CValue* newevent = new CBoolValue(sensorresult);
+
+ for (vector<SCA_IActuator*>::const_iterator i=m_linkedactuators.begin();
+ !(i==m_linkedactuators.end());i++)
+ {
+ SCA_IActuator* actua = *i;//m_linkedactuators.at(i);
+ logicmgr->AddActiveActuator(actua,newevent);
+ }
+
+ // every actuator that needs the event, has a it's own reference to it now so
+ // release it (so to be clear: if there is no actuator, it's deleted right now)
+ newevent->Release();
+
+}
+
+
+
+CValue* SCA_XNORController::GetReplica()
+{
+ CValue* replica = new SCA_XNORController(*this);
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_XNORController::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_XNORController",
+ sizeof(SCA_XNORController),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject SCA_XNORController::Parents[] = {
+ &SCA_XNORController::Type,
+ &SCA_IController::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef SCA_XNORController::Methods[] = {
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* SCA_XNORController::_getattr(const STR_String& attr) {
+ _getattr_up(SCA_IController);
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_XNORController.h b/source/gameengine/GameLogic/SCA_XNORController.h
new file mode 100644
index 00000000000..4b1eaee95d8
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_XNORController.h
@@ -0,0 +1,56 @@
+/**
+ * SCA_XNORController.h
+ *
+ * $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 *****
+ */
+
+#ifndef __KX_XNORCONTROLLER
+#define __KX_XNORCONTROLLER
+
+#include "SCA_IController.h"
+
+class SCA_XNORController : public SCA_IController
+{
+ Py_Header;
+ //virtual void Trigger(class SCA_LogicManager* logicmgr);
+public:
+ SCA_XNORController(SCA_IObject* gameobj,PyTypeObject* T=&Type);
+ virtual ~SCA_XNORController();
+ virtual CValue* GetReplica();
+ virtual void Trigger(SCA_LogicManager* logicmgr);
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(const STR_String& attr);
+
+};
+
+#endif //__KX_XNORCONTROLLER
+
diff --git a/source/gameengine/GameLogic/SCA_XORController.cpp b/source/gameengine/GameLogic/SCA_XORController.cpp
new file mode 100644
index 00000000000..6499c62f5f2
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_XORController.cpp
@@ -0,0 +1,148 @@
+/**
+ * 'Xor' together all inputs
+ *
+ * $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 *****
+ */
+
+#include "SCA_XORController.h"
+#include "SCA_ISensor.h"
+#include "SCA_LogicManager.h"
+#include "BoolValue.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+SCA_XORController::SCA_XORController(SCA_IObject* gameobj,
+ PyTypeObject* T)
+ :
+ SCA_IController(gameobj,T)
+{
+}
+
+
+
+SCA_XORController::~SCA_XORController()
+{
+}
+
+
+
+void SCA_XORController::Trigger(SCA_LogicManager* logicmgr)
+{
+
+ bool sensorresult = false;
+
+ for (vector<SCA_ISensor*>::const_iterator is=m_linkedsensors.begin();
+ !(is==m_linkedsensors.end());is++)
+ {
+ SCA_ISensor* sensor = *is;
+ if (sensor->IsPositiveTrigger())
+ {
+ if (sensorresult == true)
+ {
+ sensorresult = false;
+ break;
+ }
+ sensorresult = true;
+ }
+ }
+
+ CValue* newevent = new CBoolValue(sensorresult);
+
+ for (vector<SCA_IActuator*>::const_iterator i=m_linkedactuators.begin();
+ !(i==m_linkedactuators.end());i++)
+ {
+ SCA_IActuator* actua = *i;//m_linkedactuators.at(i);
+ logicmgr->AddActiveActuator(actua,newevent);
+ }
+
+ // every actuator that needs the event, has a it's own reference to it now so
+ // release it (so to be clear: if there is no actuator, it's deleted right now)
+ newevent->Release();
+
+}
+
+
+
+CValue* SCA_XORController::GetReplica()
+{
+ CValue* replica = new SCA_XORController(*this);
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_XORController::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_XORController",
+ sizeof(SCA_XORController),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject SCA_XORController::Parents[] = {
+ &SCA_XORController::Type,
+ &SCA_IController::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef SCA_XORController::Methods[] = {
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* SCA_XORController::_getattr(const STR_String& attr) {
+ _getattr_up(SCA_IController);
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_XORController.h b/source/gameengine/GameLogic/SCA_XORController.h
new file mode 100644
index 00000000000..f50cd33c125
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_XORController.h
@@ -0,0 +1,56 @@
+/**
+ * SCA_XORController.h
+ *
+ * $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 *****
+ */
+
+#ifndef __KX_XORCONTROLLER
+#define __KX_XORCONTROLLER
+
+#include "SCA_IController.h"
+
+class SCA_XORController : public SCA_IController
+{
+ Py_Header;
+ //virtual void Trigger(class SCA_LogicManager* logicmgr);
+public:
+ SCA_XORController(SCA_IObject* gameobj,PyTypeObject* T=&Type);
+ virtual ~SCA_XORController();
+ virtual CValue* GetReplica();
+ virtual void Trigger(SCA_LogicManager* logicmgr);
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(const STR_String& attr);
+
+};
+
+#endif //__KX_XORCONTROLLER
+
diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
index 44eeccedbd1..a5017574873 100644
--- a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
+++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
@@ -602,9 +602,9 @@ void GPC_RenderTools::MotionBlur(RAS_IRasterizer* rasterizer)
}
}
-void GPC_RenderTools::Update2DFilter(RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text)
+void GPC_RenderTools::Update2DFilter(RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text, short texture_flag)
{
- m_filtermanager.EnableFilter(filtermode, pass, text);
+ m_filtermanager.EnableFilter(filtermode, pass, text, texture_flag);
}
void GPC_RenderTools::Render2DFilters(RAS_ICanvas* canvas)
diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.h b/source/gameengine/GamePlayer/common/GPC_RenderTools.h
index f7230cb0865..cb7193f3513 100644
--- a/source/gameengine/GamePlayer/common/GPC_RenderTools.h
+++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.h
@@ -142,7 +142,7 @@ public:
virtual void MotionBlur(RAS_IRasterizer* rasterizer);
- virtual void Update2DFilter(RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text);
+ virtual void Update2DFilter(RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text, short texture_flag);
virtual void Render2DFilters(RAS_ICanvas* canvas);
diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
index c4cf698d5ee..d6908b53d40 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
@@ -496,7 +496,6 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode)
bool fixed_framerate= (SYS_GetCommandLineInt(syshandle, "fixed_framerate", fixedFr) != 0);
bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0);
- bool useVertexArrays = SYS_GetCommandLineInt(syshandle,"vertexarrays",1) != 0;
bool useLists = (SYS_GetCommandLineInt(syshandle, "displaylists", G.fileflags & G_FILE_DIAPLAY_LISTS) != 0);
if(GLEW_ARB_multitexture && GLEW_VERSION_1_1) {
@@ -514,16 +513,17 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode)
if (!m_rendertools)
goto initFailed;
- if(useLists)
- if (useVertexArrays) {
+ if(useLists) {
+ if(GLEW_VERSION_1_1)
m_rasterizer = new RAS_ListRasterizer(m_canvas, true);
- } else {
+ else
m_rasterizer = new RAS_ListRasterizer(m_canvas);
- }
- else if (useVertexArrays && GLEW_VERSION_1_1)
+ }
+ else if (GLEW_VERSION_1_1)
m_rasterizer = new RAS_VAOpenGLRasterizer(m_canvas);
else
m_rasterizer = new RAS_OpenGLRasterizer(m_canvas);
+
m_rasterizer->SetStereoMode((RAS_IRasterizer::StereoMode) stereoMode);
if (!m_rasterizer)
goto initFailed;
diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
index bc80c0a7612..8222e5c8bac 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
@@ -187,11 +187,10 @@ void usage(char* program)
printf(" show_framerate 0 Show the frame rate\n");
printf(" show_properties 0 Show debug properties\n");
printf(" show_profile 0 Show profiling information\n");
- printf(" vertexarrays 1 Enable vertex arrays\n");
printf(" blender_material 0 Enable material settings\n");
printf("\n");
printf("example: %s -p 10 10 320 200 -g noaudio c:\\loadtest.blend\n", program);
- printf("example: %s -g vertexarrays = 0 c:\\loadtest.blend\n", program);
+ printf("example: %s -g show_framerate = 0 c:\\loadtest.blend\n", program);
}
char *get_filename(int argc, char **argv) {
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp
index e320453b7aa..027cb2a0ffa 100644
--- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp
@@ -58,10 +58,15 @@ KX_NetworkMessageSensor::KX_NetworkMessageSensor(
m_NetworkScene(NetworkScene),
m_subject(subject),
m_frame_message_count (0),
- m_IsUp(false),
m_BodyList(NULL),
m_SubjectList(NULL)
{
+ Init();
+}
+
+void KX_NetworkMessageSensor::Init()
+{
+ m_IsUp = false;
}
KX_NetworkMessageSensor::~KX_NetworkMessageSensor()
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h
index d051b715aab..6fd92d17be3 100644
--- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h
@@ -65,6 +65,7 @@ public:
virtual CValue* GetReplica();
virtual bool Evaluate(CValue* event);
virtual bool IsPositiveTrigger();
+ virtual void Init();
void EndFrame();
/* ------------------------------------------------------------- */
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 eaa6564ba84..b7750e68e8f 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
@@ -782,6 +803,9 @@ void KX_GameObject::Suspend(void)
PyMethodDef KX_GameObject::Methods[] = {
{"setVisible",(PyCFunction) KX_GameObject::sPySetVisible, METH_VARARGS},
+ {"getVisible",(PyCFunction) KX_GameObject::sPyGetVisible, METH_VARARGS},
+ {"setState",(PyCFunction) KX_GameObject::sPySetState, METH_VARARGS},
+ {"getState",(PyCFunction) KX_GameObject::sPyGetState, METH_VARARGS},
{"alignAxisToVect",(PyCFunction) KX_GameObject::sPyAlignAxisToVect, METH_VARARGS},
{"setPosition", (PyCFunction) KX_GameObject::sPySetPosition, METH_VARARGS},
{"getPosition", (PyCFunction) KX_GameObject::sPyGetPosition, METH_VARARGS},
@@ -802,6 +826,8 @@ PyMethodDef KX_GameObject::Methods[] = {
{"removeParent", (PyCFunction)KX_GameObject::sPyRemoveParent,METH_VARARGS},
{"getMesh", (PyCFunction)KX_GameObject::sPyGetMesh,METH_VARARGS},
{"getPhysicsId", (PyCFunction)KX_GameObject::sPyGetPhysicsId,METH_VARARGS},
+ {"getPropertyNames", (PyCFunction)KX_GameObject::sPyGetPropertyNames,METH_VARARGS},
+ {"endObject",(PyCFunction) KX_GameObject::sPyEndObject, METH_VARARGS},
KX_PYMETHODTABLE(KX_GameObject, getDistanceTo),
KX_PYMETHODTABLE(KX_GameObject, rayCastTo),
KX_PYMETHODTABLE(KX_GameObject, rayCast),
@@ -835,6 +861,18 @@ PyObject* KX_GameObject::sPySetPosition(PyObject* self,
}
+PyObject* KX_GameObject::PyEndObject(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+
+ KX_Scene *scene = PHY_GetActiveScene();
+ scene->DelayedRemoveObject(this);
+
+ return Py_None;
+
+}
+
PyObject* KX_GameObject::PyGetPosition(PyObject* self,
PyObject* args,
@@ -1074,6 +1112,45 @@ PyObject* KX_GameObject::PySetVisible(PyObject* self,
}
+PyObject* KX_GameObject::PyGetVisible(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ return PyInt_FromLong(m_bVisible);
+}
+
+PyObject* KX_GameObject::PyGetState(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ int state = 0;
+ state |= GetState();
+ return PyInt_FromLong(state);
+}
+
+PyObject* KX_GameObject::PySetState(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ int state_i;
+ unsigned int state = 0;
+
+ if (PyArg_ParseTuple(args,"i",&state_i))
+ {
+ state |= state_i;
+ if ((state & ((1<<30)-1)) == 0) {
+ PyErr_SetString(PyExc_AttributeError, "The state bitfield was not between 0 and 30 (1<<0 and 1<<29)");
+ return NULL;
+ }
+ SetState(state);
+ }
+ else
+ {
+ return NULL;
+ }
+ Py_Return;
+}
+
PyObject* KX_GameObject::PyGetVelocity(PyObject* self,
@@ -1262,17 +1339,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 +1349,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;
}
@@ -1383,6 +1439,13 @@ PyObject* KX_GameObject::PyGetPhysicsId(PyObject* self,
return PyInt_FromLong((long)physid);
}
+PyObject* KX_GameObject::PyGetPropertyNames(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ return ConvertKeysToPython();
+}
+
KX_PYMETHODDEF_DOC(KX_GameObject, getDistanceTo,
"getDistanceTo(other): get distance to another point/KX_GameObject")
{
diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h
index 63a660617c4..89f4cb396d1 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.
@@ -676,7 +710,7 @@ public:
PyObject* args,
PyObject* kwds
);
-
+
KX_PYMETHOD(KX_GameObject,GetPosition);
KX_PYMETHOD(KX_GameObject,GetLinearVelocity);
KX_PYMETHOD(KX_GameObject,GetVelocity);
@@ -684,7 +718,10 @@ public:
KX_PYMETHOD(KX_GameObject,GetReactionForce);
KX_PYMETHOD(KX_GameObject,GetOrientation);
KX_PYMETHOD(KX_GameObject,SetOrientation);
+ KX_PYMETHOD(KX_GameObject,GetVisible);
KX_PYMETHOD(KX_GameObject,SetVisible);
+ KX_PYMETHOD(KX_GameObject,GetState);
+ KX_PYMETHOD(KX_GameObject,SetState);
KX_PYMETHOD(KX_GameObject,AlignAxisToVect);
KX_PYMETHOD(KX_GameObject,SuspendDynamics);
KX_PYMETHOD(KX_GameObject,RestoreDynamics);
@@ -697,9 +734,12 @@ public:
KX_PYMETHOD(KX_GameObject,SetParent);
KX_PYMETHOD(KX_GameObject,RemoveParent);
KX_PYMETHOD(KX_GameObject,GetPhysicsId);
+ KX_PYMETHOD(KX_GameObject,GetPropertyNames);
+ KX_PYMETHOD(KX_GameObject,EndObject);
KX_PYMETHOD_DOC(KX_GameObject,rayCastTo);
KX_PYMETHOD_DOC(KX_GameObject,rayCast);
KX_PYMETHOD_DOC(KX_GameObject,getDistanceTo);
+
private :
/**
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_MouseFocusSensor.cpp b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
index 60b90138abe..f89d32bbe66 100644
--- a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
+++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
@@ -69,11 +69,14 @@ KX_MouseFocusSensor::KX_MouseFocusSensor(SCA_MouseManager* eventmgr,
m_gp_canvas(canvas),
m_kxscene(kxscene)
{
+ Init();
+}
- m_mouse_over_in_previous_frame = false;
+void KX_MouseFocusSensor::Init()
+{
+ m_mouse_over_in_previous_frame = (m_invert)?true:false;
m_positive_event = false;
m_hitObject = 0;
-
}
bool KX_MouseFocusSensor::Evaluate(CValue* event)
@@ -89,13 +92,13 @@ bool KX_MouseFocusSensor::Evaluate(CValue* event)
obHasFocus = ParentObjectHasFocus();
if (!obHasFocus) {
+ m_positive_event = false;
if (m_mouse_over_in_previous_frame) {
- m_positive_event = false;
- result = true;
+ result = true;
}
} else {
+ m_positive_event = true;
if (!m_mouse_over_in_previous_frame) {
- m_positive_event = true;
result = true;
}
}
diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.h b/source/gameengine/Ketsji/KX_MouseFocusSensor.h
index 86f32fbf4be..b011ebe1288 100644
--- a/source/gameengine/Ketsji/KX_MouseFocusSensor.h
+++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.h
@@ -68,6 +68,7 @@ class KX_MouseFocusSensor : public SCA_MouseSensor
* @attention Overrides default evaluate.
*/
virtual bool Evaluate(CValue* event);
+ virtual void Init();
virtual bool IsPositiveTrigger() {
bool result = m_positive_event;
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_RadarSensor.cpp b/source/gameengine/Ketsji/KX_RadarSensor.cpp
index 31fffffa3c1..987e0b946b2 100644
--- a/source/gameengine/Ketsji/KX_RadarSensor.cpp
+++ b/source/gameengine/Ketsji/KX_RadarSensor.cpp
@@ -71,7 +71,6 @@ KX_RadarSensor::KX_RadarSensor(SCA_EventManager* eventmgr,
//sumoObj->setClientObject(&m_client_info);
}
-
KX_RadarSensor::~KX_RadarSensor()
{
diff --git a/source/gameengine/Ketsji/KX_RaySensor.cpp b/source/gameengine/Ketsji/KX_RaySensor.cpp
index a85dc61cac8..e847c59bae1 100644
--- a/source/gameengine/Ketsji/KX_RaySensor.cpp
+++ b/source/gameengine/Ketsji/KX_RaySensor.cpp
@@ -60,17 +60,19 @@ KX_RaySensor::KX_RaySensor(class SCA_EventManager* eventmgr,
m_bFindMaterial(bFindMaterial),
m_distance(distance),
m_scene(ketsjiScene),
- m_bTriggered(false),
- m_axis(axis),
- m_rayHit(false),
- m_hitObject(NULL)
+ m_axis(axis)
{
-
+ Init();
}
-
+void KX_RaySensor::Init()
+{
+ m_bTriggered = (m_invert)?true:false;
+ m_rayHit = false;
+ m_hitObject = NULL;
+}
KX_RaySensor::~KX_RaySensor()
{
diff --git a/source/gameengine/Ketsji/KX_RaySensor.h b/source/gameengine/Ketsji/KX_RaySensor.h
index 8a317ffaa07..f4305b053d1 100644
--- a/source/gameengine/Ketsji/KX_RaySensor.h
+++ b/source/gameengine/Ketsji/KX_RaySensor.h
@@ -66,6 +66,7 @@ public:
virtual bool Evaluate(CValue* event);
virtual bool IsPositiveTrigger();
+ virtual void Init();
bool RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data);
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 fff33ca82fd..a7e91e27df3 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -754,8 +754,6 @@ int KX_Scene::NewRemoveObject(class CValue* gameobj)
for (SCA_ControllerList::iterator itc = controllers.begin();
!(itc==controllers.end());itc++)
{
- (*itc)->UnlinkAllSensors();
- (*itc)->UnlinkAllActuators();
m_logicmgr->RemoveController(*itc);
}
@@ -868,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_StateActuator.cpp b/source/gameengine/Ketsji/KX_StateActuator.cpp
new file mode 100644
index 00000000000..95a79f0c480
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_StateActuator.cpp
@@ -0,0 +1,207 @@
+/*
+ * $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 *****
+ * Actuator to toggle visibility/invisibility of objects
+ */
+
+#include "KX_StateActuator.h"
+#include "KX_GameObject.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+KX_StateActuator::KX_StateActuator(
+ SCA_IObject* gameobj,
+ int operation,
+ unsigned int mask,
+ PyTypeObject* T
+ )
+ : SCA_IActuator(gameobj,T),
+ m_operation(operation),
+ m_mask(mask)
+{
+ // intentionally empty
+}
+
+KX_StateActuator::~KX_StateActuator(
+ void
+ )
+{
+ // intentionally empty
+}
+
+CValue*
+KX_StateActuator::GetReplica(
+ void
+ )
+{
+ KX_StateActuator* replica = new KX_StateActuator(*this);
+ replica->ProcessReplica();
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+ return replica;
+}
+
+bool
+KX_StateActuator::Update()
+{
+ bool bNegativeEvent = IsNegativeEvent();
+ unsigned int objMask;
+
+ RemoveAllEvents();
+ if (bNegativeEvent) return false;
+
+ KX_GameObject *obj = (KX_GameObject*) GetParent();
+
+ objMask = obj->GetState();
+ switch (m_operation)
+ {
+ case OP_CPY:
+ objMask = m_mask;
+ break;
+ case OP_SET:
+ objMask |= m_mask;
+ break;
+ case OP_CLR:
+ objMask &= ~m_mask;
+ break;
+ case OP_NEG:
+ objMask ^= m_mask;
+ break;
+ default:
+ // unsupported operation, no nothing
+ return false;
+ }
+ obj->SetState(objMask);
+ return false;
+}
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject
+KX_StateActuator::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "KX_StateActuator",
+ sizeof(KX_StateActuator),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject
+KX_StateActuator::Parents[] = {
+ &KX_StateActuator::Type,
+ &SCA_IActuator::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef
+KX_StateActuator::Methods[] = {
+ {"setOperation", (PyCFunction) KX_StateActuator::sPySetOperation,
+ METH_VARARGS, SetOperation_doc},
+ {"setMask", (PyCFunction) KX_StateActuator::sPySetMask,
+ METH_VARARGS, SetMask_doc},
+ {NULL,NULL} //Sentinel
+};
+
+PyObject*
+KX_StateActuator::_getattr(
+ const STR_String& attr
+ )
+{
+ _getattr_up(SCA_IActuator);
+};
+
+
+
+/* set operation ---------------------------------------------------------- */
+char
+KX_StateActuator::SetOperation_doc[] =
+"setOperation(op)\n"
+"\t - op : bit operation (0=Copy, 1=Set, 2=Clear, 3=Negate)"
+"\tSet the type of bit operation to be applied on object state mask.\n"
+"\tUse setMask() to specify the bits that will be modified.\n";
+PyObject*
+
+KX_StateActuator::PySetOperation(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ int oper;
+
+ if(!PyArg_ParseTuple(args, "i", &oper)) {
+ return NULL;
+ }
+
+ m_operation = oper;
+
+ Py_Return;
+}
+
+/* set mask ---------------------------------------------------------- */
+char
+KX_StateActuator::SetMask_doc[] =
+"setMask(mask)\n"
+"\t - mask : bits that will be modified"
+"\tSet the value that defines the bits that will be modified by the operation.\n"
+"\tThe bits that are 1 in the value will be updated in the object state,\n"
+"\tthe bits that are 0 are will be left unmodified expect for the Copy operation\n"
+"\twhich copies the value to the object state.\n";
+PyObject*
+
+KX_StateActuator::PySetMask(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ int mask;
+
+ if(!PyArg_ParseTuple(args, "i", &mask)) {
+ return NULL;
+ }
+
+ m_mask = mask;
+
+ Py_Return;
+}
+
+
diff --git a/source/gameengine/Ketsji/KX_StateActuator.h b/source/gameengine/Ketsji/KX_StateActuator.h
new file mode 100644
index 00000000000..8698e51b2c1
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_StateActuator.h
@@ -0,0 +1,83 @@
+/*
+ * $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 *****
+ * Actuator to toggle visibility/invisibility of objects
+ */
+
+#ifndef __KX_STATEACTUATOR
+#define __KX_STATEACTUATOR
+
+#include "SCA_IActuator.h"
+
+class KX_StateActuator : public SCA_IActuator
+{
+ Py_Header;
+
+ /** Make visible? */
+ enum {
+ OP_CPY = 0,
+ OP_SET,
+ OP_CLR,
+ OP_NEG
+ };
+ int m_operation;
+ unsigned int m_mask;
+
+ public:
+
+ KX_StateActuator(
+ SCA_IObject* gameobj,
+ int operation,
+ unsigned int mask,
+ PyTypeObject* T=&Type
+ );
+
+ virtual
+ ~KX_StateActuator(
+ void
+ );
+
+ virtual CValue*
+ GetReplica(
+ void
+ );
+
+ virtual bool
+ Update();
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(const STR_String& attr);
+ //KX_PYMETHOD_DOC
+ KX_PYMETHOD_DOC(KX_StateActuator,SetOperation);
+ KX_PYMETHOD_DOC(KX_StateActuator,SetMask);
+};
+
+#endif
+
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/Ketsji/KX_TouchSensor.cpp b/source/gameengine/Ketsji/KX_TouchSensor.cpp
index 3f185359de0..5311f059f03 100644
--- a/source/gameengine/Ketsji/KX_TouchSensor.cpp
+++ b/source/gameengine/Ketsji/KX_TouchSensor.cpp
@@ -77,18 +77,14 @@ KX_TouchSensor::KX_TouchSensor(SCA_EventManager* eventmgr,KX_GameObject* gameobj
:SCA_ISensor(gameobj,eventmgr,T),
m_touchedpropname(touchedpropname),
m_bFindMaterial(bFindMaterial),
-m_eventmgr(eventmgr),
+m_eventmgr(eventmgr)
/*m_sumoObj(sumoObj),*/
-m_bCollision(false),
-m_bTriggered(false),
-m_bLastTriggered(false)
{
// KX_TouchEventManager* touchmgr = (KX_TouchEventManager*) eventmgr;
// m_resptable = touchmgr->GetResponseTable();
// m_solidHandle = m_sumoObj->getObjectHandle();
- m_hitObject = NULL;
m_colliders = new CListValue();
KX_ClientObjectInfo *client_info = gameobj->getClientInfo();
@@ -98,8 +94,16 @@ m_bLastTriggered(false)
m_physCtrl = dynamic_cast<PHY_IPhysicsController*>(gameobj->GetPhysicsController());
MT_assert( !gameobj->GetPhysicsController() || m_physCtrl );
+ Init();
}
+void KX_TouchSensor::Init()
+{
+ m_bCollision = false;
+ m_bTriggered = false;
+ m_bLastTriggered = (m_invert)?true:false;
+ m_hitObject = NULL;
+}
KX_TouchSensor::~KX_TouchSensor()
{
diff --git a/source/gameengine/Ketsji/KX_TouchSensor.h b/source/gameengine/Ketsji/KX_TouchSensor.h
index f594196628a..056440ccd6c 100644
--- a/source/gameengine/Ketsji/KX_TouchSensor.h
+++ b/source/gameengine/Ketsji/KX_TouchSensor.h
@@ -72,6 +72,7 @@ public:
virtual CValue* GetReplica();
virtual void SynchronizeTransform();
virtual bool Evaluate(CValue* event);
+ virtual void Init();
virtual void ReParent(SCA_IObject* parent);
virtual void RegisterSumo(KX_TouchEventManager* touchman);
diff --git a/source/gameengine/PyDoc/KX_GameObject.py b/source/gameengine/PyDoc/KX_GameObject.py
index ff55f975543..ec7496daa75 100644
--- a/source/gameengine/PyDoc/KX_GameObject.py
+++ b/source/gameengine/PyDoc/KX_GameObject.py
@@ -25,13 +25,37 @@ class KX_GameObject:
@ivar timeOffset: adjust the slowparent delay at runtime.
@type timeOffset: float
"""
-
+ def endObject(visible):
+ """
+ Delete this object, can be used inpace of the EndObject Actuator.
+ The actual removal of the object from the scene is delayed.
+ """
+ def getVisible(visible):
+ """
+ Gets the game object's visible flag.
+
+ @type visible: boolean
+ """
def setVisible(visible):
"""
Sets the game object's visible flag.
@type visible: boolean
"""
+ def getState():
+ """
+ Gets the game object's state bitmask.
+
+ @rtype: int
+ @return: the objects state.
+ """
+ def setState():
+ """
+ Sets the game object's visible flag.
+ The bitmasks for states from 1 to 30 can be set with (1<<0, 1<<1, 1<<2 ... 1<<29)
+
+ @type visible: boolean
+ """
def setPosition(pos):
"""
Sets the game object's position.
@@ -50,8 +74,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 +96,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):
"""
@@ -174,6 +200,12 @@ class KX_GameObject:
"""
Returns the user data object associated with this game object's physics controller.
"""
+ def getPropertyNames():
+ """
+ Gets a list of all property names.
+ @rtype: list
+ @return: All property names for this object.
+ """
def getDistanceTo(other):
"""
Returns the distance to another object or point.
@@ -214,7 +246,7 @@ class KX_GameObject:
If is casted from/to object center or explicit [x,y,z] points.
The ray does not have X-Ray capability: the first object hit (other than self object) stops the ray
If a property was specified and the first object hit does not have that property, there is no hit
- The ray ignores collision-free objects
+ The ray ignores collision-free objects and faces that dont have the collision flag enabled, you can however use ghost objects.
@param to: [x,y,z] or object to which the ray is casted
@type to: L{KX_GameObject} or 3-tuple
diff --git a/source/gameengine/PyDoc/SCA_PythonController.py b/source/gameengine/PyDoc/SCA_PythonController.py
index eb9e57c0819..6d91736d636 100644
--- a/source/gameengine/PyDoc/SCA_PythonController.py
+++ b/source/gameengine/PyDoc/SCA_PythonController.py
@@ -46,4 +46,12 @@ class SCA_PythonController(SCA_IController):
@type script: string.
"""
+ def getState():
+ """
+ Get the controllers state bitmask, this can be used with the GameObject's state to test if the the controller is active.
+ This for instance will always be true however you could compare with a previous state to see when the state was activated.
+ GameLogic.getCurrentController().getState() & GameLogic.getCurrentController().getOwner().getState()
+
+ @rtype: int
+ """
diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
index e9ab4ccca8d..23153fcd86c 100644
--- a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
+++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
@@ -54,7 +54,7 @@
RAS_2DFilterManager::RAS_2DFilterManager():
-texname(-1), texturewidth(-1), textureheight(-1),
+texturewidth(-1), textureheight(-1),
canvaswidth(-1), canvasheight(-1),
numberoffilters(0)
{
@@ -72,8 +72,9 @@ numberoffilters(0)
{
m_filters[passindex] = 0;
m_enabled[passindex] = 0;
+ texflag[passindex] = 0;
}
-
+ texname[0] = texname[1] = texname[2] = -1;
}
RAS_2DFilterManager::~RAS_2DFilterManager()
@@ -150,30 +151,54 @@ unsigned int RAS_2DFilterManager::CreateShaderProgram(int filtermode)
return 0;
}
-void RAS_2DFilterManager::StartShaderProgram(unsigned int shaderprogram)
+void RAS_2DFilterManager::StartShaderProgram(int passindex)
{
GLint uniformLoc;
- glUseProgramObjectARB(shaderprogram);
- uniformLoc = glGetUniformLocationARB(shaderprogram, "bgl_RenderedTexture");
+ glUseProgramObjectARB(m_filters[passindex]);
+ uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_RenderedTexture");
glActiveTextureARB(GL_TEXTURE0);
- //glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, texname);
+ glBindTexture(GL_TEXTURE_2D, texname[0]);
if (uniformLoc != -1)
{
glUniform1iARB(uniformLoc, 0);
}
- uniformLoc = glGetUniformLocationARB(shaderprogram, "bgl_TextureCoordinateOffset");
+
+ /* send depth texture to glsl program if it needs */
+ if(texflag[passindex] & 0x1){
+ uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_DepthTexture");
+ glActiveTextureARB(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, texname[1]);
+
+ if (uniformLoc != -1)
+ {
+ glUniform1iARB(uniformLoc, 1);
+ }
+ }
+
+ /* send luminance texture to glsl program if it needs */
+ if(texflag[passindex] & 0x1){
+ uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_LuminanceTexture");
+ glActiveTextureARB(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_2D, texname[2]);
+
+ if (uniformLoc != -1)
+ {
+ glUniform1iARB(uniformLoc, 2);
+ }
+ }
+
+ uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_TextureCoordinateOffset");
if (uniformLoc != -1)
{
glUniform2fvARB(uniformLoc, 9, textureoffsets);
}
- uniformLoc = glGetUniformLocationARB(shaderprogram, "bgl_RenderedTextureWidth");
+ uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_RenderedTextureWidth");
if (uniformLoc != -1)
{
glUniform1fARB(uniformLoc,texturewidth);
}
- uniformLoc = glGetUniformLocationARB(shaderprogram, "bgl_RenderedTextureHeight");
+ uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_RenderedTextureHeight");
if (uniformLoc != -1)
{
glUniform1fARB(uniformLoc,textureheight);
@@ -187,14 +212,33 @@ void RAS_2DFilterManager::EndShaderProgram()
void RAS_2DFilterManager::SetupTexture()
{
- if(texname!=-1)
+ if(texname[0]!=-1 || texname[1]!=-1)
{
- glDeleteTextures(1,(const GLuint *)&texname);
+ glDeleteTextures(2, (GLuint*)texname);
}
- glGenTextures(1, (GLuint *)&texname);
- glBindTexture(GL_TEXTURE_2D, texname);
+ glGenTextures(3, (GLuint*)texname);
+
+ glBindTexture(GL_TEXTURE_2D, texname[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texturewidth, textureheight, 0, GL_RGB,
- GL_UNSIGNED_BYTE, 0);
+ GL_UNSIGNED_BYTE, 0);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+
+ glBindTexture(GL_TEXTURE_2D, texname[1]);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, texturewidth,textureheight, 0, GL_DEPTH_COMPONENT,
+ GL_FLOAT,NULL);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE,
+ GL_NONE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+
+ glBindTexture(GL_TEXTURE_2D, texname[2]);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE16, texturewidth, textureheight, 0, GL_LUMINANCE,
+ GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
@@ -246,12 +290,27 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
int passindex;
bool first = true;
+
for(passindex =0; passindex<MAX_RENDER_PASS; passindex++)
{
if(m_filters[passindex] && m_enabled[passindex])
{
if(first)
{
+ /* this pass needs depth texture*/
+ if(texflag[passindex] & 0x1){
+ glActiveTextureARB(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, texname[1]);
+ glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, 0,0, texturewidth,textureheight, 0);
+ }
+
+ /* this pass needs luminance texture*/
+ if(texflag[passindex] & 0x2){
+ glActiveTextureARB(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_2D, texname[2]);
+ glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, 0,0, texturewidth,textureheight, 0);
+ }
+
glGetIntegerv(GL_VIEWPORT,(GLint *)viewport);
glViewport(0, 0, texturewidth, textureheight);
@@ -263,11 +322,13 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
first = false;
}
- StartShaderProgram(m_filters[passindex]);
+ StartShaderProgram(passindex);
- glBindTexture(GL_TEXTURE_2D, texname);
- glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, texturewidth, textureheight, 0);
+ glActiveTextureARB(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, texname[0]);
+ glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, texturewidth, textureheight, 0);
+
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_QUADS);
@@ -288,7 +349,7 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
}
}
-void RAS_2DFilterManager::EnableFilter(RAS_2DFILTER_MODE mode, int pass, STR_String& text)
+void RAS_2DFilterManager::EnableFilter(RAS_2DFILTER_MODE mode, int pass, STR_String& text, short tflag)
{
if(!isshadersupported)
return;
@@ -313,11 +374,13 @@ void RAS_2DFilterManager::EnableFilter(RAS_2DFILTER_MODE mode, int pass, STR_Str
glDeleteObjectARB(m_filters[pass]);
m_enabled[pass] = 0;
m_filters[pass] = 0;
+ texflag[pass] = 0;
return;
}
if(mode == RAS_2DFILTER_CUSTOMFILTER)
{
+ texflag[pass] = tflag;
if(m_filters[pass])
glDeleteObjectARB(m_filters[pass]);
m_filters[pass] = CreateShaderProgram(text.Ptr());
diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.h b/source/gameengine/Rasterizer/RAS_2DFilterManager.h
index cff868556e0..faf7c652388 100644
--- a/source/gameengine/Rasterizer/RAS_2DFilterManager.h
+++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.h
@@ -37,17 +37,21 @@ class RAS_2DFilterManager
private:
unsigned int CreateShaderProgram(char* shadersource);
unsigned int CreateShaderProgram(int filtermode);
- void StartShaderProgram(unsigned int shaderprogram);
+ void StartShaderProgram(int passindex);
void EndShaderProgram();
float textureoffsets[18];
float view[4];
- unsigned int texname;
+ /* texname[0] contains render to texture, texname[1] contains depth texture, texname[2] contains luminance texture*/
+ unsigned int texname[3];
int texturewidth;
int textureheight;
int canvaswidth;
int canvasheight;
int numberoffilters;
+ /* bit 0: enable/disable depth texture
+ * bit 1: enable/disable luminance texture*/
+ short texflag[MAX_RENDER_PASS];
bool isshadersupported;
public:
@@ -83,6 +87,6 @@ public:
void RenderFilters(RAS_ICanvas* canvas);
- void EnableFilter(RAS_2DFILTER_MODE mode, int pass, STR_String& text);
+ void EnableFilter(RAS_2DFILTER_MODE mode, int pass, STR_String& text, short tflag);
};
#endif
diff --git a/source/gameengine/Rasterizer/RAS_IRenderTools.h b/source/gameengine/Rasterizer/RAS_IRenderTools.h
index bcbf907741b..781f90d4124 100644
--- a/source/gameengine/Rasterizer/RAS_IRenderTools.h
+++ b/source/gameengine/Rasterizer/RAS_IRenderTools.h
@@ -185,7 +185,7 @@ public:
virtual
void
- Update2DFilter(RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text)=0;
+ Update2DFilter(RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text, short textureflag)=0;
virtual
void
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
index d3c0426de86..18147b53f4c 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
@@ -125,6 +125,9 @@ static void Myinit_gl_stuff(void)
glDisable(GL_TEXTURE_1D);
glDisable(GL_TEXTURE_2D);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+
glPixelTransferi(GL_MAP_COLOR, GL_FALSE);
glPixelTransferi(GL_RED_SCALE, 1);
glPixelTransferi(GL_RED_BIAS, 0);
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp
index ce76318c2ce..c4702fe5a74 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp
@@ -91,9 +91,10 @@ void RAS_VAOpenGLRasterizer::SetDrawingMode(int drawingmode)
void RAS_VAOpenGLRasterizer::Exit()
{
- glDisableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
- glDisableClientState(GL_NORMAL_ARRAY);
EnableTextures(false);
RAS_OpenGLRasterizer::Exit();