diff options
author | Erwin Coumans <blender@erwincoumans.com> | 2006-11-30 03:19:27 +0300 |
---|---|---|
committer | Erwin Coumans <blender@erwincoumans.com> | 2006-11-30 03:19:27 +0300 |
commit | 2572b9f72c8f10b01de949e59b481ac5a587aca4 (patch) | |
tree | 8500180c02ce6f7e5ace9c1d62f408d62c8be7f2 /source/gameengine | |
parent | 99d66e1d5e8c9d32c6289cd453ebec3f708aa249 (diff) |
Reserved some Bullet 2.x constraint data.
Although we will delay the main Rigid Body user interface after 2.43 release early 2007, I need some constraint data/UI to make progress with COLLADA Physics.
Added RigidBody constraint UI
LR_ALTKEY+LR_CTRLKEY+LR_SHIFTKEY+ P will bake rigidbody
Contribution by RCRuiz, Ramon Carlos.
Diffstat (limited to 'source/gameengine')
8 files changed, 505 insertions, 8 deletions
diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp index a270b73c80d..b886e4ff54a 100644 --- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp +++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp @@ -348,7 +348,7 @@ extern "C" void StartKetsjiShell(struct ScrArea *area, rasterizer->Init(); // start the engine - ketsjiengine->StartEngine(); + ketsjiengine->StartEngine(true); // the mainloop while (!exitrequested) @@ -449,3 +449,349 @@ extern "C" void StartKetsjiShell(struct ScrArea *area, if (bfd) BLO_blendfiledata_free(bfd); } +#ifdef __cplusplus +extern "C" { +#endif +#include "BSE_headerbuttons.h" +void update_for_newframe(); +#ifdef __cplusplus +} +#endif + +extern "C" void StartKetsjiShellSimulation(struct ScrArea *area, + char* scenename, + struct Main* maggie, + struct SpaceIpo *sipo, + int always_use_expand_framing) +{ + int exitrequested = KX_EXIT_REQUEST_NO_REQUEST; + + Main* blenderdata = maggie; + + char* startscenename = scenename; + char pathname[160]; + strcpy (pathname, maggie->name); + STR_String exitstring = ""; + BlendFileData *bfd= NULL; + + bgl::InitExtensions(1); + + do + { +// View3D *v3d= (View3D*) area->spacedata.first; + + // get some preferences + SYS_SystemHandle syshandle = SYS_GetSystem(); + bool properties = (SYS_GetCommandLineInt(syshandle, "show_properties", 0) != 0); + bool usefixed = (SYS_GetCommandLineInt(syshandle, "fixedtime", 0) != 0); + bool profile = (SYS_GetCommandLineInt(syshandle, "show_profile", 0) != 0); + bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0); + bool game2ipo = true;//(SYS_GetCommandLineInt(syshandle, "game2ipo", 0) != 0); + bool displaylists = (SYS_GetCommandLineInt(syshandle, "displaylists", 0) != 0); + bool usemat = false; + +/* #ifdef GL_ARB_multitexture + if(bgl::RAS_EXT_support._ARB_multitexture && bgl::QueryVersion(1, 1)) { + usemat = (SYS_GetCommandLineInt(syshandle, "blender_material", 0) != 0); + int unitmax=0; + glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, (GLint*)&unitmax); + bgl::max_texture_units = MAXTEX>unitmax?unitmax:MAXTEX; + //std::cout << "using(" << bgl::max_texture_units << ") of(" << unitmax << ") texture units." << std::endl; + } else { + bgl::max_texture_units = 0; + } + #endif + +*/ + // create the canvas, rasterizer and rendertools + RAS_ICanvas* canvas = new KX_BlenderCanvas(area); + //canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE); + 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 && bgl::QueryVersion(1, 1)) + rasterizer = new RAS_VAOpenGLRasterizer(canvas, lock_arrays); + else + rasterizer = new RAS_OpenGLRasterizer(canvas); + + // create the inputdevices + KX_BlenderKeyboardDevice* keyboarddevice = new KX_BlenderKeyboardDevice(); + KX_BlenderMouseDevice* mousedevice = new KX_BlenderMouseDevice(); + + // create a networkdevice + NG_NetworkDeviceInterface* networkdevice = new + NG_LoopBackNetworkDeviceInterface(); + + // get an audiodevice + SND_DeviceManager::Subscribe(); + SND_IAudioDevice* audiodevice = SND_DeviceManager::Instance(); + audiodevice->UseCD(); + + // create a ketsji/blendersystem (only needed for timing and stuff) + KX_BlenderSystem* kxsystem = new KX_BlenderSystem(); + + // create the ketsjiengine + KX_KetsjiEngine* ketsjiengine = new KX_KetsjiEngine(kxsystem); + +/* // set the devices + ketsjiengine->SetKeyboardDevice(keyboarddevice); + ketsjiengine->SetMouseDevice(mousedevice); + ketsjiengine->SetNetworkDevice(networkdevice); + ketsjiengine->SetCanvas(canvas); + ketsjiengine->SetRenderTools(rendertools); + ketsjiengine->SetRasterizer(rasterizer); + ketsjiengine->SetNetworkDevice(networkdevice); + ketsjiengine->SetAudioDevice(audiodevice); + ketsjiengine->SetUseFixedTime(usefixed); + ketsjiengine->SetTimingDisplay(frameRate, profile, properties); + +*/ + + // some blender stuff + MT_CmMatrix4x4 projmat; + MT_CmMatrix4x4 viewmat; + int i; + +/* for (i = 0; i < 16; i++) + { + float *viewmat_linear= (float*) v3d->viewmat; + viewmat.setElem(i, viewmat_linear[i]); + } + for (i = 0; i < 16; i++) + { + float *projmat_linear = (float*) area->winmat; + projmat.setElem(i, projmat_linear[i]); + } +*/ +/* float camzoom = (1.41421 + (v3d->camzoom / 50.0)); + camzoom *= camzoom; + camzoom = 4.0 / camzoom; +*/ +// ketsjiengine->SetDrawType(v3d->drawtype); +// ketsjiengine->SetCameraZoom(camzoom); +/* + // if we got an exitcode 3 (KX_EXIT_REQUEST_START_OTHER_GAME) load a different file + if (exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME || exitrequested == KX_EXIT_REQUEST_RESTART_GAME) + { + exitrequested = KX_EXIT_REQUEST_NO_REQUEST; + if (bfd) BLO_blendfiledata_free(bfd); + + char basedpath[160]; + // base the actuator filename with respect + // to the original file working directory + if (exitstring != "") + strcpy(basedpath, exitstring.Ptr()); + + BLI_convertstringcode(basedpath, pathname, 0); + bfd = load_game_data(basedpath); + + // if it wasn't loaded, try it forced relative + if (!bfd) + { + // just add "//" in front of it + char temppath[162]; + strcpy(temppath, "//"); + strcat(temppath, basedpath); + + BLI_convertstringcode(temppath, pathname, 0); + bfd = load_game_data(temppath); + } + + // if we got a loaded blendfile, proceed + if (bfd) + { + blenderdata = bfd->main; + startscenename = bfd->curscene->id.name + 2; + } + // else forget it, we can't find it + else + { + exitrequested = KX_EXIT_REQUEST_QUIT_GAME; + } + } +*/ + Scene *blscene = NULL; + if (!bfd) + { + blscene = (Scene*) maggie->scene.first; + for (Scene *sce= (Scene*) maggie->scene.first; sce; sce= (Scene*) sce->id.next) + { + if (startscenename == (sce->id.name+2)) + { + blscene = sce; + break; + } + } + } else { + blscene = bfd->curscene; + } + int cframe,startFrame; + if (blscene) + { + cframe=blscene->r.cfra; + startFrame = blscene->r.sfra; + blscene->r.cfra=startFrame; + update_for_newframe(); + ketsjiengine->SetGame2IpoMode(game2ipo,startFrame); + } + + // Quad buffered needs a special window. + if (blscene->r.stereomode != RAS_IRasterizer::RAS_STEREO_QUADBUFFERED) + rasterizer->SetStereoMode((RAS_IRasterizer::StereoMode) blscene->r.stereomode); + + if (exitrequested != KX_EXIT_REQUEST_QUIT_GAME) + { + /*if (v3d->persp != 2) + { + ketsjiengine->EnableCameraOverride(startscenename); + ketsjiengine->SetCameraOverrideUseOrtho((v3d->persp == 0)); + ketsjiengine->SetCameraOverrideProjectionMatrix(projmat); + ketsjiengine->SetCameraOverrideViewMatrix(viewmat); + }*/ + + // create a scene converter, create and convert the startingscene + KX_ISceneConverter* sceneconverter = new KX_BlenderSceneConverter(maggie,sipo, ketsjiengine); + ketsjiengine->SetSceneConverter(sceneconverter); + + if (always_use_expand_framing) + sceneconverter->SetAlwaysUseExpandFraming(true); + + if(usemat) + sceneconverter->SetMaterials(true); + + KX_Scene* startscene = new KX_Scene(keyboarddevice, + mousedevice, + networkdevice, + audiodevice, + startscenename); + + // some python things + PyObject* dictionaryobject = initGamePythonScripting("Ketsji", psl_Lowest); + ketsjiengine->SetPythonDictionary(dictionaryobject); + initRasterizer(rasterizer, canvas); + PyObject *gameLogic = initGameLogic(startscene); + initGameKeys(); + initPythonConstraintBinding(); + + if (sceneconverter) + { + // convert and add scene + sceneconverter->ConvertScene( + startscenename, + startscene, + dictionaryobject, + keyboarddevice, + rendertools, + canvas); + ketsjiengine->AddScene(startscene); + + // init the rasterizer + //rasterizer->Init(); + + // start the engine + ketsjiengine->StartEngine(false); + + // the mainloop + while ((blscene->r.cfra<=blscene->r.efra)&&(!exitrequested)) + { + printf("frame %i\n",blscene->r.cfra); + // first check if we want to exit + exitrequested = ketsjiengine->GetExitCode(); + + // kick the engine + ketsjiengine->NextFrame(); + blscene->r.cfra=blscene->r.cfra+1; + update_for_newframe(); + // render the frame + //ketsjiengine->Render(); + + // test for the ESC key + /*while (qtest()) + { + short val; + unsigned short event = extern_qread(&val); + + if (keyboarddevice->ConvertBlenderEvent(event,val)) + exitrequested = KX_EXIT_REQUEST_BLENDER_ESC; + + if (event==MOUSEX) { + val = val - scrarea_get_win_x(area); + } else if (event==MOUSEY) { + val = scrarea_get_win_height(area) - (val - scrarea_get_win_y(area)) - 1; + } + + mousedevice->ConvertBlenderEvent(event,val); + }*/ + } + exitstring = ketsjiengine->GetExitString(); + // when exiting the mainloop + //dictionaryClearByHand(gameLogic); + //ketsjiengine->StopEngine(); + //exitGamePythonScripting(); + //networkdevice->Disconnect(); + } + if (sceneconverter) + { + delete sceneconverter; + sceneconverter = NULL; + } + } + blscene->r.cfra=cframe; + // set the cursor back to normal + canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL); + + // clean up some stuff + audiodevice->StopCD(); + if (ketsjiengine) + { + delete ketsjiengine; + ketsjiengine = NULL; + } + if (kxsystem) + { + delete kxsystem; + kxsystem = NULL; + } + if (networkdevice) + { + delete networkdevice; + networkdevice = NULL; + } + if (keyboarddevice) + { + delete keyboarddevice; + keyboarddevice = NULL; + } + if (mousedevice) + { + delete mousedevice; + mousedevice = NULL; + } + /*if (rasterizer) + { + delete rasterizer; + rasterizer = NULL; + } + if (rendertools) + { + delete rendertools; + rendertools = NULL; + } + if (canvas) + { + delete canvas; + canvas = NULL; + }*/ + SND_DeviceManager::Unsubscribe(); + + } while (exitrequested == KX_EXIT_REQUEST_RESTART_GAME || exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME); + if (bfd) BLO_blendfiledata_free(bfd); +}
\ No newline at end of file diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index b0986aeca50..de20789235d 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -1515,6 +1515,84 @@ static struct Scene *GetSceneForName(struct Main *maggie, const STR_String& scen return (Scene*) maggie->scene.first; } +#include "DNA_constraint_types.h" +#include "BIF_editconstraint.h" + +bPoseChannel *get_active_posechannel2 (Object *ob) +{ + bArmature *arm= (bArmature*)ob->data; + bPoseChannel *pchan; + + /* find active */ + for(pchan= (bPoseChannel *)ob->pose->chanbase.first; pchan; pchan= pchan->next) { + if(pchan->bone && (pchan->bone->flag & BONE_ACTIVE) && (pchan->bone->layer & arm->layer)) + return pchan; + } + + return NULL; +} + +ListBase *get_active_constraints2(Object *ob) +{ + if (!ob) + return NULL; + + if (ob->flag & OB_POSEMODE) { + bPoseChannel *pchan; + + pchan = get_active_posechannel2(ob); + if (pchan) + return &pchan->constraints; + } + else + return &ob->constraints; + + return NULL; +} + + +void RBJconstraints(Object *ob)//not used +{ + ListBase *conlist; + bConstraint *curcon; + + conlist = get_active_constraints2(ob); + + if (conlist) { + for (curcon = (bConstraint *)conlist->first; curcon; curcon=(bConstraint *)curcon->next) { + + printf("%i\n",curcon->type); + } + + + } +} + +#include "PHY_IPhysicsEnvironment.h" +#include "KX_IPhysicsController.h" +#include "PHY_DynamicTypes.h" + +KX_IPhysicsController* getPhId(CListValue* sumolist,STR_String busc){//not used + + for (int j=0;j<sumolist->GetCount();j++) + { + KX_GameObject* gameobje = (KX_GameObject*) sumolist->GetValue(j); + if (gameobje->GetName()==busc) + return gameobje->GetPhysicsController(); + } + +} + +KX_GameObject* getGameOb(STR_String busc,CListValue* sumolist){ + + for (int j=0;j<sumolist->GetCount();j++) + { + KX_GameObject* gameobje = (KX_GameObject*) sumolist->GetValue(j); + if (gameobje->GetName()==busc) + return gameobje; + } + +} // convert blender objects into ketsji gameobjects void BL_ConvertBlenderObjects(struct Main* maggie, @@ -1812,6 +1890,77 @@ void BL_ConvertBlenderObjects(struct Main* maggie, } + // create physics joints + for (i=0;i<sumolist->GetCount();i++) + { + KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); + struct Object* blenderobject = converter->FindBlenderObject(gameobj); + int nummeshes = gameobj->GetMeshCount(); + RAS_MeshObject* meshobj = 0; + ListBase *conlist; + bConstraint *curcon; + conlist = get_active_constraints2(blenderobject); + if (conlist) { + for (curcon = (bConstraint *)conlist->first; curcon; curcon=(bConstraint *)curcon->next) { + if (curcon->type==CONSTRAINT_TYPE_RIGIDBODYJOINT){ + bRigidBodyJointConstraint *dat=(bRigidBodyJointConstraint *)curcon->data; + if (dat->tar) + if (!dat->child){ + KX_GameObject *gotar=getGameOb(dat->tar->id.name,sumolist); + PHY_IPhysicsController* physctrl = (PHY_IPhysicsController*) (int)gameobj->GetPhysicsController()->GetUserData(); + PHY_IPhysicsController* physctr2 = (PHY_IPhysicsController*) (int)gotar->GetPhysicsController()->GetUserData(); + kxscene->GetPhysicsEnvironment()->createConstraint(physctrl,physctr2,(PHY_ConstraintType)dat->type,(float)dat->pivX,(float)dat->pivY,(float)dat->pivZ,(float)dat->axX,(float)dat->axY,(float)dat->axZ); + /*switch(dat->type){ + case CONSTRAINT_RB_BALL: + KX_GameObject *gotar=getGameOb(dat->tar->id.name,sumolist); + PHY_IPhysicsController* physctrl = (PHY_IPhysicsController*) (int)gameobj->GetPhysicsController()->GetUserData(); + PHY_IPhysicsController* physctr2 = (PHY_IPhysicsController*) (int)gotar->GetPhysicsController()->GetUserData(); + kxscene->GetPhysicsEnvironment()->createConstraint(physctrl,physctr2,(PHY_ConstraintType)dat->type,(float)dat->pivX,(float)dat->pivY,(float)dat->pivZ,(float)dat->axX,(float)dat->axY,(float)dat->axZ); + break; + case CONSTRAINT_RB_HINGE: + KX_GameObject *gotar=getGameOb(dat->tar->id.name,sumolist); + PHY_IPhysicsController* physctrl = (PHY_IPhysicsController*) (int)gameobj->GetPhysicsController()->GetUserData(); + PHY_IPhysicsController* physctr2 = (PHY_IPhysicsController*) (int)gotar->GetPhysicsController()->GetUserData(); + kxscene->GetPhysicsEnvironment()->createConstraint(physctrl,physctr2,(PHY_ConstraintType)dat->type,(float)dat->pivX,(float)dat->pivY,(float)dat->pivZ,(float)dat->axX,(float)dat->axY,(float)dat->axZ); + break; + }*/ + } + } + } + } + + } + + //Intento de actualizar posicion + /*for (i=0;i<sumolist->GetCount();i++) + { + KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); + struct Object* blenderobject = converter->FindBlenderObject(gameobj); + + MT_Point3 pos = MT_Point3( + blenderobject->loc[0]+blenderobject->dloc[0], + blenderobject->loc[1]+blenderobject->dloc[1], + blenderobject->loc[2]+blenderobject->dloc[2] + ); + MT_Vector3 eulxyz = MT_Vector3( + blenderobject->rot[0], + blenderobject->rot[1], + blenderobject->rot[2] + ); + MT_Vector3 scale = MT_Vector3( + blenderobject->size[0], + blenderobject->size[1], + blenderobject->size[2] + ); + + gameobj->NodeSetLocalPosition(pos); + gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz)); + gameobj->NodeSetLocalScale(scale); + gameobj->NodeUpdateGS(0,true); + }*/ + //rcruiz> + + templist->Release(); sumolist->Release(); diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp index 83b2a11e606..10f3ea39616 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp @@ -576,7 +576,7 @@ Ipo* KX_BlenderSceneConverter::findIpoForName(char* objName) } -void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo() +void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo) { KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes(); @@ -604,6 +604,7 @@ void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo() if (ipo) { //clear the curve data + if (clearIpo){ IpoCurve *icu1; int numCurves = 0; for( icu1 = (IpoCurve*)ipo->curve.first; icu1; ) { @@ -618,6 +619,7 @@ void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo() MEM_freeN( tmpicu ); localDel_ipoCurve( tmpicu ,m_sipo); } + } } else { ipo = add_ipo(blenderObject->id.name+2, ID_OB); diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.h b/source/gameengine/Converter/KX_BlenderSceneConverter.h index db2090aa470..c4447c53930 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.h +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.h @@ -130,7 +130,7 @@ public: void RegisterWorldInfo(KX_WorldInfo *worldinfo); - virtual void ResetPhysicsObjectsAnimationIpo(); + virtual void ResetPhysicsObjectsAnimationIpo(bool clearIpo); ///this generates ipo curves for position, rotation, allowing to use game physics in animation virtual void WritePhysicsObjectToAnimationIpo(int frameNumber); diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp index 8554b7c85bc..fd47df7f770 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp @@ -673,7 +673,7 @@ bool GPG_Application::startEngine(void) m_frameTimer = m_system->installTimer(0, kTimerFreq, frameTimerProc, m_mainWindow); } m_rasterizer->Init(); - m_ketsjiengine->StartEngine(); + m_ketsjiengine->StartEngine(true); m_engineRunning = true; } diff --git a/source/gameengine/Ketsji/KX_ISceneConverter.h b/source/gameengine/Ketsji/KX_ISceneConverter.h index 52a65791885..8693eb34d6b 100644 --- a/source/gameengine/Ketsji/KX_ISceneConverter.h +++ b/source/gameengine/Ketsji/KX_ISceneConverter.h @@ -61,7 +61,7 @@ public: virtual bool TryAndLoadNewFile() = 0; - virtual void ResetPhysicsObjectsAnimationIpo() = 0; + virtual void ResetPhysicsObjectsAnimationIpo(bool clearIpo) = 0; ///this generates ipo curves for position, rotation, allowing to use game physics in animation virtual void WritePhysicsObjectToAnimationIpo(int frameNumber) = 0; diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index 4d6b70a0b3c..6a54c613cc0 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -254,7 +254,7 @@ void KX_KetsjiEngine::SetSceneConverter(KX_ISceneConverter* sceneconverter) * Blender into Ketsji native (realtime) format also sets up the * graphics context */ -void KX_KetsjiEngine::StartEngine() +void KX_KetsjiEngine::StartEngine(bool clearIpo) { m_clockTime = m_kxsystem->GetTimeInSeconds(); m_frameTime = m_kxsystem->GetTimeInSeconds(); @@ -266,7 +266,7 @@ void KX_KetsjiEngine::StartEngine() if (m_game2ipo) { - m_sceneconverter->ResetPhysicsObjectsAnimationIpo(); + m_sceneconverter->ResetPhysicsObjectsAnimationIpo(clearIpo); m_sceneconverter->WritePhysicsObjectToAnimationIpo(m_currentFrame); } diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h index d78ad955e1a..ae33e8da998 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.h +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h @@ -205,7 +205,7 @@ public: void NextFrame(); void Render(); - void StartEngine(); + void StartEngine(bool clearIpo); void StopEngine(); void Export(const STR_String& filename); |