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
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2008-08-17 05:24:40 +0400
committerCampbell Barton <ideasman42@gmail.com>2008-08-17 05:24:40 +0400
commit009f826006eed5b9200b779f8727c5b0c23b6b21 (patch)
treeeb6877672eef1885506e754b3b954f38d9b56186
parent46131fbcd4b36fe6202299f3e584b0704eb13beb (diff)
svn merge -r16106:HEAD https://svn.blender.org/svnroot/bf-blender/trunk/blender
-rw-r--r--CMakeLists.txt1
-rw-r--r--projectfiles_vc7/gameengine/gamelogic/SCA_GameLogic.vcproj6
-rw-r--r--source/blender/blenkernel/intern/ipo.c8
-rw-r--r--source/blender/blenkernel/intern/particle_system.c49
-rw-r--r--source/blender/blenkernel/intern/sca.c3
-rw-r--r--source/blender/blenloader/intern/writefile.c3
-rw-r--r--source/blender/makesdna/DNA_ipo_types.h8
-rw-r--r--source/blender/makesdna/DNA_sensor_types.h10
-rw-r--r--source/blender/src/buttons_logic.c38
-rw-r--r--source/blender/src/editipo_lib.c2
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp39
-rw-r--r--source/gameengine/Converter/KX_ConvertSensors.cpp37
-rw-r--r--source/gameengine/GameLogic/SCA_DelaySensor.cpp257
-rw-r--r--source/gameengine/GameLogic/SCA_DelaySensor.h77
-rw-r--r--source/gameengine/GameLogic/SCA_ISensor.cpp13
-rw-r--r--source/gameengine/GameLogic/SCA_ISensor.h1
-rw-r--r--source/gameengine/GameLogic/SCA_PythonController.cpp4
-rw-r--r--source/gameengine/PyDoc/GameLogic.py1
-rw-r--r--source/gameengine/PyDoc/SCA_DelaySensor.py56
-rw-r--r--source/gameengine/PyDoc/SCA_ISensor.py6
20 files changed, 582 insertions, 37 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 69ddb779445..dc7876a3b61 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -63,7 +63,6 @@ OPTION(WITH_QUICKTIME "Enable Quicktime Support" OFF)
OPTION(WITH_OPENEXR "Enable OpenEXR Support (http://www.openexr.com)" ON)
OPTION(WITH_FFMPEG "Enable FFMPeg Support (http://ffmpeg.mplayerhq.hu/)" OFF)
OPTION(WITH_OPENAL "Enable OpenAL Support (http://www.openal.org)" ON)
-OPTION(YESIAMSTUPID "Enable execution on 64-bit platforms" OFF)
OPTION(WITH_OPENMP "Enable OpenMP (has to be supported by the compiler)" OFF)
IF(NOT WITH_GAMEENGINE AND WITH_PLAYER)
diff --git a/projectfiles_vc7/gameengine/gamelogic/SCA_GameLogic.vcproj b/projectfiles_vc7/gameengine/gamelogic/SCA_GameLogic.vcproj
index 7e2db4f564f..5f14b5a09a1 100644
--- a/projectfiles_vc7/gameengine/gamelogic/SCA_GameLogic.vcproj
+++ b/projectfiles_vc7/gameengine/gamelogic/SCA_GameLogic.vcproj
@@ -348,6 +348,9 @@
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_ANDController.cpp">
</File>
<File
+ RelativePath="..\..\..\source\gameengine\GameLogic\SCA_DelaySensor.cpp">
+ </File>
+ <File
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_EventManager.cpp">
</File>
<File
@@ -466,6 +469,9 @@
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_ANDController.h">
</File>
<File
+ RelativePath="..\..\..\source\gameengine\GameLogic\SCA_DelaySensor.h">
+ </File>
+ <File
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_EventManager.h">
</File>
<File
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index 1a027356c8f..b1d50c2080b 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -182,7 +182,7 @@ int part_ar[PART_TOTIPO]= {
PART_EMIT_FREQ, PART_EMIT_LIFE, PART_EMIT_VEL, PART_EMIT_AVE, PART_EMIT_SIZE,
PART_AVE, PART_SIZE, PART_DRAG, PART_BROWN, PART_DAMP, PART_LENGTH, PART_CLUMP,
PART_GRAV_X, PART_GRAV_Y, PART_GRAV_Z, PART_KINK_AMP, PART_KINK_FREQ, PART_KINK_SHAPE,
- PART_BB_TILT
+ PART_BB_TILT, PART_PD_FSTR, PART_PD_FFALL, PART_PD_FMAXD
};
@@ -1631,6 +1631,12 @@ void *get_ipo_poin(ID *id, IpoCurve *icu, int *type)
poin= &(part->kink_shape); break;
case PART_BB_TILT:
poin= &(part->bb_tilt); break;
+ case PART_PD_FSTR:
+ poin= (part->pd?(&(part->pd->f_strength)):NULL); break;
+ case PART_PD_FFALL:
+ poin= (part->pd?(&(part->pd->f_power)):NULL); break;
+ case PART_PD_FMAXD:
+ poin= (part->pd?(&(part->pd->maxdist)):NULL); break;
}
}
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index d1c0cdec71d..942c6505975 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -3948,27 +3948,44 @@ static void boid_body(BoidVecFunc *bvf, ParticleData *pa, ParticleSystem *psys,
bvf->Addf(dvec,dvec,bvec);
bvf->Addf(state->co,state->co,dvec);
- /* air speed from wind effectors */
- if(psys->effectors.first){
+ /* air speed from wind and vortex effectors */
+ if(psys->effectors.first) {
ParticleEffectorCache *ec;
- for(ec=psys->effectors.first; ec; ec=ec->next){
- if(ec->type & PSYS_EC_EFFECTOR){
+ for(ec=psys->effectors.first; ec; ec=ec->next) {
+ if(ec->type & PSYS_EC_EFFECTOR) {
Object *eob = ec->ob;
PartDeflect *pd = eob->pd;
+ float direction[3], vec_to_part[3];
+ float falloff;
+
+ if(pd->f_strength != 0.0f) {
+ VecCopyf(direction, eob->obmat[2]);
+ VecSubf(vec_to_part, state->co, eob->obmat[3]);
+
+ falloff=effector_falloff(pd, direction, vec_to_part);
+
+ switch(pd->forcefield) {
+ case PFIELD_WIND:
+ if(falloff <= 0.0f)
+ ; /* don't do anything */
+ else {
+ Normalize(direction);
+ VecMulf(direction, pd->f_strength * falloff);
+ bvf->Addf(state->co, state->co, direction);
+ }
+ break;
+ case PFIELD_VORTEX:
+ {
+ float distance, mag_vec[3];
+ Crossf(mag_vec, direction, vec_to_part);
+ Normalize(mag_vec);
- if(pd->forcefield==PFIELD_WIND && pd->f_strength!=0.0){
- float distance, wind[3];
- VecCopyf(wind,eob->obmat[2]);
- distance=VecLenf(state->co,eob->obmat[3]);
-
- if (distance < 0.001) distance = 0.001f;
+ distance = VecLength(vec_to_part);
- if(pd->flag&PFIELD_USEMAX && distance > pd->maxdist)
- ;
- else{
- Normalize(wind);
- VecMulf(wind,pd->f_strength/(float)pow((double)distance,(double)pd->f_power));
- bvf->Addf(state->co,state->co,wind);
+ VecMulf(mag_vec, pd->f_strength * distance * falloff);
+ bvf->Addf(state->co, state->co, mag_vec);
+ break;
+ }
}
}
}
diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c
index fcf1c7ce311..47d11bb9d29 100644
--- a/source/blender/blenkernel/intern/sca.c
+++ b/source/blender/blenkernel/intern/sca.c
@@ -153,6 +153,9 @@ void init_sensor(bSensor *sens)
case SENS_ACTUATOR:
sens->data= MEM_callocN(sizeof(bActuatorSensor), "actsens");
break;
+ case SENS_DELAY:
+ sens->data= MEM_callocN(sizeof(bDelaySensor), "delaysens");
+ break;
case SENS_MOUSE:
ms=sens->data= MEM_callocN(sizeof(bMouseSensor), "mousesens");
ms->type= LEFTMOUSE;
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 0cc87c7bdef..6dc41dfc99c 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -608,6 +608,9 @@ static void write_sensors(WriteData *wd, ListBase *lb)
case SENS_ACTUATOR:
writestruct(wd, DATA, "bActuatorSensor", 1, sens->data);
break;
+ case SENS_DELAY:
+ writestruct(wd, DATA, "bDelaySensor", 1, sens->data);
+ break;
case SENS_COLLISION:
writestruct(wd, DATA, "bCollisionSensor", 1, sens->data);
break;
diff --git a/source/blender/makesdna/DNA_ipo_types.h b/source/blender/makesdna/DNA_ipo_types.h
index 9d48b571ece..9e3ce491dd2 100644
--- a/source/blender/makesdna/DNA_ipo_types.h
+++ b/source/blender/makesdna/DNA_ipo_types.h
@@ -362,8 +362,8 @@ typedef short IPO_Channel;
/* ******************** */
/* particle ipos */
-#define PART_TOTIPO 19
-#define PART_TOTNAM 19
+#define PART_TOTIPO 22
+#define PART_TOTNAM 22
#define PART_EMIT_FREQ 1
#define PART_EMIT_LIFE 2
@@ -389,6 +389,10 @@ typedef short IPO_Channel;
#define PART_BB_TILT 19
+#define PART_PD_FSTR 20
+#define PART_PD_FFALL 21
+#define PART_PD_FMAXD 22
+
/* these are IpoCurve specific */
/* **************** IPO ********************* */
diff --git a/source/blender/makesdna/DNA_sensor_types.h b/source/blender/makesdna/DNA_sensor_types.h
index c0306f43730..b5d8511c698 100644
--- a/source/blender/makesdna/DNA_sensor_types.h
+++ b/source/blender/makesdna/DNA_sensor_types.h
@@ -88,6 +88,13 @@ typedef struct bActuatorSensor {
char name[32];
} bActuatorSensor;
+typedef struct bDelaySensor {
+ short delay;
+ short duration;
+ short flag;
+ short pad;
+} bDelaySensor;
+
typedef struct bCollisionSensor {
char name[32]; /* property name */
char materialName[32]; /* material */
@@ -204,6 +211,7 @@ typedef struct bJoystickSensor {
#define SENS_MESSAGE 10
#define SENS_JOYSTICK 11
#define SENS_ACTUATOR 12
+#define SENS_DELAY 13
/* sensor->flag */
#define SENS_SHOW 1
#define SENS_DEL 2
@@ -254,5 +262,7 @@ typedef struct bJoystickSensor {
#define SENS_JOY_HAT 2
#define SENS_JOY_HAT_DIR 0
+#define SENS_DELAY_REPEAT 1
+
#endif
diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c
index 5cf1958678e..e16e058e093 100644
--- a/source/blender/src/buttons_logic.c
+++ b/source/blender/src/buttons_logic.c
@@ -683,6 +683,8 @@ static char *sensor_name(int type)
return "Property";
case SENS_ACTUATOR:
return "Actuator";
+ case SENS_DELAY:
+ return "Delay";
case SENS_MOUSE:
return "Mouse";
case SENS_COLLISION:
@@ -704,7 +706,7 @@ static char *sensor_name(int type)
static char *sensor_pup(void)
{
/* the number needs to match defines in game.h */
- return "Sensors %t|Always %x0|Keyboard %x3|Mouse %x5|"
+ return "Sensors %t|Always %x0|Delay %x13|Keyboard %x3|Mouse %x5|"
"Touch %x1|Collision %x6|Near %x2|Radar %x7|"
"Property %x4|Random %x8|Ray %x9|Message %x10|Joystick %x11|Actuator %x12";
}
@@ -1000,6 +1002,7 @@ static int get_col_sensor(int type)
{
switch(type) {
case SENS_ALWAYS: return TH_BUT_ACTION;
+ case SENS_DELAY: return TH_BUT_ACTION;
case SENS_TOUCH: return TH_BUT_NEUTRAL;
case SENS_COLLISION: return TH_BUT_SETTING;
case SENS_NEAR: return TH_BUT_SETTING1;
@@ -1070,8 +1073,8 @@ static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short
bRaySensor *raySens = NULL;
bMessageSensor *mes = NULL;
bJoystickSensor *joy = NULL;
- bActuatorSensor *as = NULL;
-
+ bActuatorSensor *as = NULL;
+ bDelaySensor *ds = NULL;
short ysize;
char *str;
@@ -1297,6 +1300,27 @@ static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short
yco-= ysize;
break;
}
+ case SENS_DELAY:
+ {
+ ysize= 48;
+
+ glRects(xco, yco-ysize, xco+width, yco);
+ uiEmboss((float)xco, (float)yco-ysize,
+ (float)xco+width, (float)yco, 1);
+
+ draw_default_sensor_header(sens, block, xco, yco, width);
+ ds = sens->data;
+
+ uiDefButS(block, NUM, 0, "Delay",(short)(10+xco),(short)(yco-44),(short)((width-22)*0.4+10), 19,
+ &ds->delay, 0.0, 5000.0, 0, 0, "Delay in number of frames before the positive trigger");
+ uiDefButS(block, NUM, 0, "Dur",(short)(10+xco+(width-22)*0.4+10),(short)(yco-44),(short)((width-22)*0.4-10), 19,
+ &ds->duration, 0.0, 5000.0, 0, 0, "If >0, delay in number of frames before the negative trigger following the positive trigger");
+ uiDefButBitS(block, TOG, SENS_DELAY_REPEAT, 0, "REP",(short)(xco + 10 + (width-22)*0.8),(short)(yco - 44),
+ (short)(0.20 * (width-22)), 19, &ds->flag, 0.0, 0.0, 0, 0,
+ "Toggle repeat option. If selected, the sensor restarts after Delay+Dur frames");
+ yco-= ysize;
+ break;
+ }
case SENS_MOUSE:
{
ms= sens->data;
@@ -1689,7 +1713,7 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
uiDefBut(block, LABEL, 0, "Torque", xco, yco-106, 55, 19, NULL, 0, 0, 0, 0, "Sets the torque");
uiDefButF(block, NUM, 0, "", xco+45, yco-106, wval, 19, oa->forcerot, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+wval, yco-106, wval, 19, oa->forcerot+1, -10000.0, 10000.0, 10, 0, "");
- uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-6106, wval, 19, oa->forcerot+2, -10000.0, 10000.0, 10, 0, "");
+ uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-106, wval, 19, oa->forcerot+2, -10000.0, 10000.0, 10, 0, "");
}
if ( ob->gameflag & OB_DYNAMIC )
@@ -3183,7 +3207,8 @@ void logic_buts(void)
while(cont) {
for (iact=0; iact<cont->totlinks; iact++) {
act = cont->links[iact];
- act->flag |= ACT_LINKED;
+ if (act)
+ act->flag |= ACT_LINKED;
}
controller_state_mask |= cont->state_mask;
cont = cont->next;
@@ -3231,7 +3256,8 @@ void logic_buts(void)
/* this controller is visible, mark all its actuator */
for (iact=0; iact<cont->totlinks; iact++) {
act = cont->links[iact];
- act->flag |= ACT_VISIBLE;
+ if (act)
+ 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");
diff --git a/source/blender/src/editipo_lib.c b/source/blender/src/editipo_lib.c
index 048db2dbe2d..e91f160cb1f 100644
--- a/source/blender/src/editipo_lib.c
+++ b/source/blender/src/editipo_lib.c
@@ -103,7 +103,7 @@ char *ic_name_empty[1] ={ "" };
char *fluidsim_ic_names[FLUIDSIM_TOTNAM] = { "Fac-Visc", "Fac-Time", "GravX","GravY","GravZ", "VelX","VelY","VelZ", "Active" };
char *part_ic_names[PART_TOTNAM] = { "E_Freq", "E_Life", "E_Speed", "E_Angular", "E_Size",
"Angular", "Size", "Drag", "Brown", "Damp", "Length", "Clump",
-"GravX", "GravY", "GravZ", "KinkAmp", "KinkFreq", "KinkShape", "BBTilt"};
+"GravX", "GravY", "GravZ", "KinkAmp", "KinkFreq", "KinkShape", "BBTilt", "FStreng", "FFall", "FMaxD"};
/* gets the appropriate icon for the given blocktype */
int geticon_ipo_blocktype(short blocktype)
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index 0fb957e3813..748f26834cd 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -1918,10 +1918,22 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
//parentinversenode->SetLocalOrientation(parinvtrans.getBasis());
// Extract the rotation and the scaling from the basis
- MT_Matrix3x3 inverseOrientation(parinvtrans.getRotation());
- parentinversenode->SetLocalOrientation(inverseOrientation);
- MT_Matrix3x3 scale(inverseOrientation.transposed()*parinvtrans.getBasis());
- parentinversenode->SetLocalScale(MT_Vector3(scale[0][0], scale[1][1], scale[2][2]));
+ MT_Matrix3x3 ori(parinvtrans.getBasis());
+ MT_Vector3 x(ori.getColumn(0));
+ MT_Vector3 y(ori.getColumn(1));
+ MT_Vector3 z(ori.getColumn(2));
+ MT_Vector3 scale(x.length(), y.length(), z.length());
+ if (!MT_fuzzyZero(scale[0]))
+ x /= scale[0];
+ if (!MT_fuzzyZero(scale[1]))
+ y /= scale[1];
+ if (!MT_fuzzyZero(scale[2]))
+ z /= scale[2];
+ ori.setColumn(0, x);
+ ori.setColumn(1, y);
+ ori.setColumn(2, z);
+ parentinversenode->SetLocalOrientation(ori);
+ parentinversenode->SetLocalScale(scale);
parentinversenode->AddChild(gameobj->GetSGNode());
}
@@ -2101,7 +2113,24 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
float* fl = (float*) blenderobject->parentinv;
MT_Transform parinvtrans(fl);
parentinversenode->SetLocalPosition(parinvtrans.getOrigin());
- parentinversenode->SetLocalOrientation(parinvtrans.getBasis());
+
+ // Extract the rotation and the scaling from the basis
+ MT_Matrix3x3 ori(parinvtrans.getBasis());
+ MT_Vector3 x(ori.getColumn(0));
+ MT_Vector3 y(ori.getColumn(1));
+ MT_Vector3 z(ori.getColumn(2));
+ MT_Vector3 scale(x.length(), y.length(), z.length());
+ if (!MT_fuzzyZero(scale[0]))
+ x /= scale[0];
+ if (!MT_fuzzyZero(scale[1]))
+ y /= scale[1];
+ if (!MT_fuzzyZero(scale[2]))
+ z /= scale[2];
+ ori.setColumn(0, x);
+ ori.setColumn(1, y);
+ ori.setColumn(2, z);
+ parentinversenode->SetLocalOrientation(ori);
+ parentinversenode->SetLocalScale(scale);
parentinversenode->AddChild(gameobj->GetSGNode());
}
diff --git a/source/gameengine/Converter/KX_ConvertSensors.cpp b/source/gameengine/Converter/KX_ConvertSensors.cpp
index 5e433bb821b..4806df36090 100644
--- a/source/gameengine/Converter/KX_ConvertSensors.cpp
+++ b/source/gameengine/Converter/KX_ConvertSensors.cpp
@@ -65,6 +65,7 @@ probably misplaced */
#include "SCA_JoystickSensor.h"
#include "KX_NetworkMessageSensor.h"
#include "SCA_ActuatorSensor.h"
+#include "SCA_DelaySensor.h"
#include "SCA_PropertySensor.h"
@@ -281,6 +282,22 @@ void BL_ConvertSensors(struct Object* blenderobject,
break;
}
+ case SENS_DELAY:
+ {
+ // we can reuse the Always event manager for the delay sensor
+ SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::ALWAYS_EVENTMGR);
+ if (eventmgr)
+ {
+ bDelaySensor* delaysensor = (bDelaySensor*)sens->data;
+ gamesensor = new SCA_DelaySensor(eventmgr,
+ gameobj,
+ delaysensor->delay,
+ delaysensor->duration,
+ (delaysensor->flag & SENS_DELAY_REPEAT) != 0);
+ }
+ break;
+ }
+
case SENS_COLLISION:
{
SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
@@ -741,10 +758,24 @@ void BL_ConvertSensors(struct Object* blenderobject,
for (int i=0;i<sens->totlinks;i++)
{
bController* linkedcont = (bController*) sens->links[i];
- SCA_IController* gamecont = converter->FindGameController(linkedcont);
+ if (linkedcont) {
+ SCA_IController* gamecont = converter->FindGameController(linkedcont);
- if (gamecont) {
- logicmgr->RegisterToSensor(gamecont,gamesensor);
+ if (gamecont) {
+ logicmgr->RegisterToSensor(gamecont,gamesensor);
+ } else {
+ printf(
+ "Warning, sensor \"%s\" could not find its controller"
+ "(link %d of %d)\n"
+ "\tthere has been an error converting the blender controller for the game engine,"
+ "logic may be incorrect\n", sens->name, i+1, sens->totlinks);
+ }
+ } else {
+ printf(
+ "Warning, sensor \"%s\" has lost a link to a controller"
+ "(link %d of %d)\n"
+ "\tpossible causes are partially appended objects or an error reading the file,"
+ "logic may be incorrect\n", sens->name, i+1, sens->totlinks);
}
}
// done with gamesensor
diff --git a/source/gameengine/GameLogic/SCA_DelaySensor.cpp b/source/gameengine/GameLogic/SCA_DelaySensor.cpp
new file mode 100644
index 00000000000..4d05250e91c
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_DelaySensor.cpp
@@ -0,0 +1,257 @@
+/**
+ * Delay trigger
+ *
+ * $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 *****
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef WIN32
+// This warning tells us about truncation of __long__ stl-generated names.
+// It can occasionally cause DevStudio to have internal compiler warnings.
+#pragma warning( disable : 4786 )
+#endif
+
+#include "SCA_DelaySensor.h"
+#include "SCA_LogicManager.h"
+#include "SCA_EventManager.h"
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+SCA_DelaySensor::SCA_DelaySensor(class SCA_EventManager* eventmgr,
+ SCA_IObject* gameobj,
+ int delay,
+ int duration,
+ bool repeat,
+ PyTypeObject* T)
+ : SCA_ISensor(gameobj,eventmgr, T),
+ m_delay(delay),
+ m_duration(duration),
+ m_repeat(repeat)
+{
+ Init();
+}
+
+void SCA_DelaySensor::Init()
+{
+ m_lastResult = false;
+ m_frameCount = -1;
+ m_reset = true;
+}
+
+SCA_DelaySensor::~SCA_DelaySensor()
+{
+ /* intentionally empty */
+}
+
+CValue* SCA_DelaySensor::GetReplica()
+{
+ CValue* replica = new SCA_DelaySensor(*this);
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+bool SCA_DelaySensor::IsPositiveTrigger()
+{
+ return (m_invert ? !m_lastResult : m_lastResult);
+}
+
+bool SCA_DelaySensor::Evaluate(CValue* event)
+{
+ bool trigger = false;
+ bool result;
+
+ if (m_frameCount==-1) {
+ // this is needed to ensure ON trigger in case delay==0
+ // and avoid spurious OFF trigger when duration==0
+ m_lastResult = false;
+ m_frameCount = 0;
+ }
+
+ if (m_frameCount<m_delay) {
+ m_frameCount++;
+ result = false;
+ } else if (m_duration > 0) {
+ if (m_frameCount < m_delay+m_duration) {
+ m_frameCount++;
+ result = true;
+ } else {
+ result = false;
+ if (m_repeat)
+ m_frameCount = -1;
+ }
+ } else {
+ result = true;
+ if (m_repeat)
+ m_frameCount = -1;
+ }
+ if ((m_reset && m_level) || result != m_lastResult)
+ trigger = true;
+ m_reset = false;
+ m_lastResult = result;
+ return trigger;
+}
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_DelaySensor::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_DelaySensor",
+ sizeof(SCA_DelaySensor),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject SCA_DelaySensor::Parents[] = {
+ &SCA_DelaySensor::Type,
+ &SCA_ISensor::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef SCA_DelaySensor::Methods[] = {
+ /* setProperty */
+ {"setDelay", (PyCFunction) SCA_DelaySensor::sPySetDelay, METH_VARARGS, SetDelay_doc},
+ {"setDuration", (PyCFunction) SCA_DelaySensor::sPySetDuration, METH_VARARGS, SetDuration_doc},
+ {"setRepeat", (PyCFunction) SCA_DelaySensor::sPySetRepeat, METH_VARARGS, SetRepeat_doc},
+ /* getProperty */
+ {"getDelay", (PyCFunction) SCA_DelaySensor::sPyGetDelay, METH_NOARGS, GetDelay_doc},
+ {"getDuration", (PyCFunction) SCA_DelaySensor::sPyGetDuration, METH_NOARGS, GetDuration_doc},
+ {"getRepeat", (PyCFunction) SCA_DelaySensor::sPyGetRepeat, METH_NOARGS, GetRepeat_doc},
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* SCA_DelaySensor::_getattr(const STR_String& attr) {
+ _getattr_up(SCA_ISensor);
+}
+
+char SCA_DelaySensor::SetDelay_doc[] =
+"setDelay(delay)\n"
+"\t- delay: length of the initial OFF period as number of frame\n"
+"\t 0 for immediate trigger\n"
+"\tSet the initial delay before the positive trigger\n";
+PyObject* SCA_DelaySensor::PySetDelay(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ int delay;
+
+ if(!PyArg_ParseTuple(args, "i", &delay)) {
+ return NULL;
+ }
+ if (delay < 0) {
+ PyErr_SetString(PyExc_ValueError, "Delay cannot be negative");
+ return NULL;
+ }
+ m_delay = delay;
+ Py_Return;
+}
+
+char SCA_DelaySensor::SetDuration_doc[] =
+"setDuration(duration)\n"
+"\t- duration: length of the ON period in number of frame after the initial off period\n"
+"\t 0 for no ON period\n"
+"\tSet the duration of the ON pulse after initial delay.\n"
+"\tIf > 0, a negative trigger is fired at the end of the ON pulse.\n";
+PyObject* SCA_DelaySensor::PySetDuration(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ int duration;
+
+ if(!PyArg_ParseTuple(args, "i", &duration)) {
+ return NULL;
+ }
+ if (duration < 0) {
+ PyErr_SetString(PyExc_ValueError, "Duration cannot be negative");
+ return NULL;
+ }
+ m_duration = duration;
+ Py_Return;
+}
+
+char SCA_DelaySensor::SetRepeat_doc[] =
+"setRepeat(repeat)\n"
+"\t- repeat: 1 if the initial OFF-ON cycle should be repeated indefinately\n"
+"\t 0 if the initial OFF-ON cycle should run only once\n"
+"\tSet the sensor repeat mode\n";
+PyObject* SCA_DelaySensor::PySetRepeat(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ int repeat;
+
+ if(!PyArg_ParseTuple(args, "i", &repeat)) {
+ return NULL;
+ }
+ m_repeat = (repeat != 0);
+ Py_Return;
+}
+
+char SCA_DelaySensor::GetDelay_doc[] =
+"getDelay()\n"
+"\tReturn the delay parameter value\n";
+PyObject* SCA_DelaySensor::PyGetDelay(PyObject* self)
+{
+ return PyInt_FromLong(m_delay);
+}
+
+char SCA_DelaySensor::GetDuration_doc[] =
+"getDuration()\n"
+"\tReturn the duration parameter value\n";
+PyObject* SCA_DelaySensor::PyGetDuration(PyObject* self)
+{
+ return PyInt_FromLong(m_duration);
+}
+
+char SCA_DelaySensor::GetRepeat_doc[] =
+"getRepeat()\n"
+"\tReturn the repeat parameter value\n";
+PyObject* SCA_DelaySensor::PyGetRepeat(PyObject* self)
+{
+ return BoolToPyArg(m_repeat);
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_DelaySensor.h b/source/gameengine/GameLogic/SCA_DelaySensor.h
new file mode 100644
index 00000000000..a997fabe3cd
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_DelaySensor.h
@@ -0,0 +1,77 @@
+/**
+ * SCA_DelaySensor.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_DELAYSENSOR
+#define __KX_DELAYSENSOR
+#include "SCA_ISensor.h"
+
+class SCA_DelaySensor : public SCA_ISensor
+{
+ Py_Header;
+ bool m_lastResult;
+ bool m_repeat;
+ int m_delay;
+ int m_duration;
+ int m_frameCount;
+
+public:
+ SCA_DelaySensor(class SCA_EventManager* eventmgr,
+ SCA_IObject* gameobj,
+ int delay,
+ int duration,
+ bool repeat,
+ PyTypeObject* T =&Type);
+ virtual ~SCA_DelaySensor();
+ virtual CValue* GetReplica();
+ virtual bool Evaluate(CValue* event);
+ virtual bool IsPositiveTrigger();
+ virtual void Init();
+
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(const STR_String& attr);
+
+ /* setProperty */
+ KX_PYMETHOD_DOC(SCA_DelaySensor,SetDelay);
+ KX_PYMETHOD_DOC(SCA_DelaySensor,SetDuration);
+ KX_PYMETHOD_DOC(SCA_DelaySensor,SetRepeat);
+ /* getProperty */
+ KX_PYMETHOD_DOC_NOARGS(SCA_DelaySensor,GetDelay);
+ KX_PYMETHOD_DOC_NOARGS(SCA_DelaySensor,GetDuration);
+ KX_PYMETHOD_DOC_NOARGS(SCA_DelaySensor,GetRepeat);
+
+};
+
+#endif //__KX_ALWAYSSENSOR
+
diff --git a/source/gameengine/GameLogic/SCA_ISensor.cpp b/source/gameengine/GameLogic/SCA_ISensor.cpp
index 2dc49924062..f99b9b789d7 100644
--- a/source/gameengine/GameLogic/SCA_ISensor.cpp
+++ b/source/gameengine/GameLogic/SCA_ISensor.cpp
@@ -189,6 +189,8 @@ PyMethodDef SCA_ISensor::Methods[] = {
METH_NOARGS, GetLevel_doc},
{"setLevel", (PyCFunction) SCA_ISensor::sPySetLevel,
METH_VARARGS, SetLevel_doc},
+ {"reset", (PyCFunction) SCA_ISensor::sPyReset,
+ METH_NOARGS, Reset_doc},
{NULL,NULL} //Sentinel
};
@@ -390,4 +392,15 @@ PyObject* SCA_ISensor::PySetUseNegPulseMode(PyObject* self, PyObject* args, PyOb
Py_Return;
}
+char SCA_ISensor::Reset_doc[] =
+"reset()\n"
+"\tReset sensor internal state, effect depends on the type of sensor and settings.\n"
+"\tThe sensor is put in its initial state as if it was just activated.\n";
+PyObject* SCA_ISensor::PyReset(PyObject* self)
+{
+ Init();
+ Py_Return;
+}
+
+
/* eof */
diff --git a/source/gameengine/GameLogic/SCA_ISensor.h b/source/gameengine/GameLogic/SCA_ISensor.h
index d5dabbce3ee..fc8f0bd0011 100644
--- a/source/gameengine/GameLogic/SCA_ISensor.h
+++ b/source/gameengine/GameLogic/SCA_ISensor.h
@@ -148,6 +148,7 @@ public:
KX_PYMETHOD_DOC(SCA_ISensor,SetInvert);
KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,GetLevel);
KX_PYMETHOD_DOC(SCA_ISensor,SetLevel);
+ KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,Reset);
};
diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp
index cd1b029fc34..f9081c90288 100644
--- a/source/gameengine/GameLogic/SCA_PythonController.cpp
+++ b/source/gameengine/GameLogic/SCA_PythonController.cpp
@@ -248,7 +248,7 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr)
{
// didn't compile, so instead of compile, complain
// something is wrong, tell the user what went wrong
- printf("PYTHON SCRIPT ERROR:\n");
+ printf("Python compile error from controller \"%s\": \n", GetName().Ptr());
//PyRun_SimpleString(m_scriptText.Ptr());
PyErr_Print();
return;
@@ -285,7 +285,7 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr)
else
{
// something is wrong, tell the user what went wrong
- printf("PYTHON SCRIPT ERROR:\n");
+ printf("Python script error from controller \"%s\": \n", GetName().Ptr());
PyErr_Print();
//PyRun_SimpleString(m_scriptText.Ptr());
}
diff --git a/source/gameengine/PyDoc/GameLogic.py b/source/gameengine/PyDoc/GameLogic.py
index 7e36a15c0f7..b5fe25b4e13 100644
--- a/source/gameengine/PyDoc/GameLogic.py
+++ b/source/gameengine/PyDoc/GameLogic.py
@@ -42,6 +42,7 @@ Documentation for the GameLogic Module.
- L{SCA_MouseSensor}
- L{SCA_PropertySensor}
- L{SCA_RandomSensor}
+ - L{SCA_DelaySensor}
You can also access actuators linked to the controller::
# To get an actuator attached to the controller:
diff --git a/source/gameengine/PyDoc/SCA_DelaySensor.py b/source/gameengine/PyDoc/SCA_DelaySensor.py
new file mode 100644
index 00000000000..46b74f461a7
--- /dev/null
+++ b/source/gameengine/PyDoc/SCA_DelaySensor.py
@@ -0,0 +1,56 @@
+# $Id$
+# Documentation for SCA_DelaySensor
+from SCA_IActuator import *
+
+class SCA_DelaySensor(SCA_ISensor):
+ """
+ The Delay sensor generates positive and negative triggers at precise time,
+ expressed in number of frames. The delay parameter defines the length
+ of the initial OFF period. A positive trigger is generated at the end of this period.
+ The duration parameter defines the length of the ON period following the OFF period.
+ There is a negative trigger at the end of the ON period. If duration is 0, the sensor
+ stays ON and there is no negative trigger.
+ The sensor runs the OFF-ON cycle once unless the repeat option is set: the
+ OFF-ON cycle repeats indefinately (or the OFF cycle if duration is 0).
+ Use SCA_ISensor::reset() at any time to restart sensor.
+ """
+ def setDelay(delay):
+ """
+ Set the initial delay before the positive trigger.
+
+ @param delay: length of the initial OFF period as number of frame, 0 for immediate trigger
+ @type delay: integer
+ """
+ def setDuration(duration):
+ """
+ Set the duration of the ON pulse after initial delay and the generation of the positive trigger.
+ If duration is greater than 0, a negative trigger is sent at the end of the ON pulse.
+
+ @param duration: length of the ON period in number of frame after the initial OFF period
+ @type duration: integer
+ """
+ def setRepeat(repeat):
+ """
+ Set if the sensor repeat mode.
+
+ @param repeat: 1 if the OFF-ON cycle should be repeated indefinately, 0 if it should run once.
+ @type repeat: integer
+ """
+ def getDelay():
+ """
+ Return the delay parameter value.
+
+ @rtype: integer
+ """
+ def getDuration():
+ """
+ Return the duration parameter value
+
+ @rtype: integer
+ """
+ def getRepeat():
+ """
+ Return the repeat parameter value
+
+ @rtype: KX_TRUE or KX_FALSE
+ """
diff --git a/source/gameengine/PyDoc/SCA_ISensor.py b/source/gameengine/PyDoc/SCA_ISensor.py
index 0ebc2debb31..33f0e976284 100644
--- a/source/gameengine/PyDoc/SCA_ISensor.py
+++ b/source/gameengine/PyDoc/SCA_ISensor.py
@@ -77,4 +77,10 @@ class SCA_ISensor(SCA_ILogicBrick):
@param level: Detect level instead of edge? (KX_TRUE, KX_FALSE)
@type level: boolean
"""
+ def reset():
+ """
+ Reset sensor internal state, effect depends on the type of sensor and settings.
+
+ The sensor is put in its initial state as if it was just activated.
+ """