diff options
author | Campbell Barton <ideasman42@gmail.com> | 2008-08-17 05:24:40 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2008-08-17 05:24:40 +0400 |
commit | 009f826006eed5b9200b779f8727c5b0c23b6b21 (patch) | |
tree | eb6877672eef1885506e754b3b954f38d9b56186 | |
parent | 46131fbcd4b36fe6202299f3e584b0704eb13beb (diff) |
svn merge -r16106:HEAD https://svn.blender.org/svnroot/bf-blender/trunk/blender
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. + """ |