4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21 * All rights reserved.
23 * The Original Code is: all of this file.
25 * Contributor(s): none yet.
27 * ***** END GPL LICENSE BLOCK *****
28 * The engine ties all game modules together.
32 #pragma warning (disable : 4786)
37 #include "KX_KetsjiEngine.h"
39 #include "ListValue.h"
41 #include "VectorValue.h"
42 #include "BoolValue.h"
43 #include "FloatValue.h"
45 #define KX_NUM_ITERATIONS 4
46 #include "RAS_BucketManager.h"
48 #include "RAS_IRasterizer.h"
49 #include "RAS_IRenderTools.h"
50 #include "RAS_ICanvas.h"
51 #include "STR_String.h"
52 #include "MT_Vector3.h"
53 #include "MT_Transform.h"
54 #include "SCA_IInputDevice.h"
56 #include "MT_CmMatrix4x4.h"
57 #include "KX_Camera.h"
60 #include "KX_PythonInit.h"
61 #include "KX_PyConstraintBinding.h"
62 #include "PHY_IPhysicsEnvironment.h"
65 #include "SumoPhysicsEnvironment.h"
68 #include "SND_Scene.h"
69 #include "SND_IAudioDevice.h"
71 #include "NG_NetworkScene.h"
72 #include "NG_NetworkDeviceInterface.h"
74 #include "KX_WorldInfo.h"
75 #include "KX_ISceneConverter.h"
76 #include "KX_TimeCategoryLogger.h"
78 #include "RAS_FramingManager.h"
81 // If define: little test for Nzc: guarded drawing. If the canvas is
82 // not valid, skip rendering this frame.
83 //#define NZC_GUARDED_OUTPUT
84 #define DEFAULT_LOGIC_TIC_RATE 60.0
85 #define DEFAULT_PHYSICS_TIC_RATE 60.0
87 const char KX_KetsjiEngine::m_profileLabels[tc_numCategories][15] = {
88 "Physics:", // tc_physics
90 "Network:", // tc_network
91 "Scenegraph:", // tc_scenegraph
93 "Rasterizer:", // tc_rasterizer
94 "Services:", // tc_services
95 "Overhead:", // tc_overhead
96 "Outside:" // tc_outside
99 double KX_KetsjiEngine::m_ticrate = DEFAULT_LOGIC_TIC_RATE;
100 double KX_KetsjiEngine::m_anim_framerate = 25.0;
101 double KX_KetsjiEngine::m_suspendedtime = 0.0;
102 double KX_KetsjiEngine::m_suspendeddelta = 0.0;
103 double KX_KetsjiEngine::m_average_framerate = 0.0;
107 * Constructor of the Ketsji Engine
109 KX_KetsjiEngine::KX_KetsjiEngine(KX_ISystem* system)
114 m_sceneconverter(NULL),
115 m_networkdevice(NULL),
117 m_pythondictionary(NULL),
118 m_keyboarddevice(NULL),
121 m_propertiesPresent(false),
123 m_bInitialized(false),
131 m_previousClockTime(0.f),
134 m_exitcode(KX_EXIT_REQUEST_NO_REQUEST),
140 m_overrideCam(false),
141 m_overrideCamUseOrtho(false),
142 m_overrideCamNear(0.0),
143 m_overrideCamFar(0.0),
152 // Set up timing info display variables
153 m_show_framerate(false),
154 m_show_profile(false),
155 m_showProperties(false),
156 m_showBackground(false),
157 m_show_debug_properties(false),
161 // Default behavior is to hide the cursor every frame.
164 m_overrideFrameColor(false),
165 m_overrideFrameColorR(0.0),
166 m_overrideFrameColorG(0.0),
167 m_overrideFrameColorB(0.0)
169 // Initialize the time logger
170 m_logger = new KX_TimeCategoryLogger (25);
172 for (int i = tc_first; i < tc_numCategories; i++)
173 m_logger->AddCategory((KX_TimeCategory)i);
180 * Destructor of the Ketsji Engine, release all memory
182 KX_KetsjiEngine::~KX_KetsjiEngine()
191 void KX_KetsjiEngine::SetKeyboardDevice(SCA_IInputDevice* keyboarddevice)
193 MT_assert(keyboarddevice);
194 m_keyboarddevice = keyboarddevice;
199 void KX_KetsjiEngine::SetMouseDevice(SCA_IInputDevice* mousedevice)
201 MT_assert(mousedevice);
202 m_mousedevice = mousedevice;
207 void KX_KetsjiEngine::SetNetworkDevice(NG_NetworkDeviceInterface* networkdevice)
209 MT_assert(networkdevice);
210 m_networkdevice = networkdevice;
215 void KX_KetsjiEngine::SetAudioDevice(SND_IAudioDevice* audiodevice)
217 MT_assert(audiodevice);
218 m_audiodevice = audiodevice;
223 void KX_KetsjiEngine::SetCanvas(RAS_ICanvas* canvas)
231 void KX_KetsjiEngine::SetRenderTools(RAS_IRenderTools* rendertools)
233 MT_assert(rendertools);
234 m_rendertools = rendertools;
239 void KX_KetsjiEngine::SetRasterizer(RAS_IRasterizer* rasterizer)
241 MT_assert(rasterizer);
242 m_rasterizer = rasterizer;
247 * At the moment the GameLogic module is imported into 'pythondictionary' after this function is called.
248 * if this function ever changes to assign a copy, make sure the game logic module is imported into this dictionary before hand.
250 void KX_KetsjiEngine::SetPythonDictionary(PyObject* pythondictionary)
252 MT_assert(pythondictionary);
253 m_pythondictionary = pythondictionary;
258 void KX_KetsjiEngine::SetSceneConverter(KX_ISceneConverter* sceneconverter)
260 MT_assert(sceneconverter);
261 m_sceneconverter = sceneconverter;
264 void KX_KetsjiEngine::InitDome(float size, short res, short mode, short angle, float resbuf, struct Text* text)
266 m_dome = new KX_Dome(m_canvas, m_rasterizer, m_rendertools,this, size, res, mode, angle, resbuf, text);
270 void KX_KetsjiEngine::RenderDome()
272 GLuint viewport[4]={0};
273 glGetIntegerv(GL_VIEWPORT,(GLint *)viewport);
274 // unsigned int m_viewport[4] = {viewport[0], viewport[1], viewport[2], viewport[3]};
276 m_dome->SetViewPort(viewport);
278 KX_Scene* firstscene = *m_scenes.begin();
279 const RAS_FrameSettings &framesettings = firstscene->GetFramingType();
281 m_logger->StartLog(tc_rasterizer, m_kxsystem->GetTimeInSeconds(), true);
283 // hiding mouse cursor each frame
284 // (came back when going out of focus and then back in again)
286 m_canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE);
288 // clear the entire game screen with the border color
289 // only once per frame
291 m_canvas->BeginDraw();
293 // BeginFrame() sets the actual drawing area. You can use a part of the window
297 int n_renders=m_dome->GetNumberRenders();// usually 4 or 6
298 KX_SceneList::iterator sceneit;
299 for (int i=0;i<n_renders;i++){
300 m_canvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER|RAS_ICanvas::DEPTH_BUFFER);
301 for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++)
302 // for each scene, call the proceed functions
304 KX_Scene* scene = *sceneit;
305 KX_Camera* cam = scene->GetActiveCamera();
307 m_rendertools->BeginFrame(m_rasterizer);
308 // pass the scene's worldsettings to the rasterizer
309 SetWorldSettings(scene->GetWorldInfo());
313 RenderShadowBuffers(scene);
314 scene->UpdateMeshTransformations();//I need to run it somewherelse, otherwise Im overrunning it
316 // Avoid drawing the scene with the active camera twice when it's viewport is enabled
317 if(cam && !cam->GetViewport())
319 if (scene->IsClearingZBuffer())
320 m_rasterizer->ClearDepthBuffer();
322 m_rendertools->SetAuxilaryClientInfo(scene);
325 m_dome->RenderDomeFrame(scene,cam, i);
328 list<class KX_Camera*>* cameras = scene->GetCameras();
330 // Draw the scene once for each camera with an enabled viewport
331 list<KX_Camera*>::iterator it = cameras->begin();
332 while(it != cameras->end())
334 if((*it)->GetViewport())
336 if (scene->IsClearingZBuffer())
337 m_rasterizer->ClearDepthBuffer();
339 m_rendertools->SetAuxilaryClientInfo(scene);
342 m_dome->RenderDomeFrame(scene, (*it),i);
348 m_dome->BindImages(i);
351 // m_dome->Dome_PostRender(scene, cam, stereomode);
352 m_canvas->EndFrame();//XXX do we really need that?
354 m_canvas->SetViewPort(0, 0, m_canvas->GetWidth(), m_canvas->GetHeight());
356 if (m_overrideFrameColor) //XXX why do we want
358 // Do not use the framing bar color set in the Blender scenes
359 m_canvas->ClearColor(
360 m_overrideFrameColorR,
361 m_overrideFrameColorG,
362 m_overrideFrameColorB,
368 // Use the framing bar color set in the Blender scenes
369 m_canvas->ClearColor(
370 framesettings.BarRed(),
371 framesettings.BarGreen(),
372 framesettings.BarBlue(),
384 * Ketsji Init(), Initializes datastructures and converts data from
385 * Blender into Ketsji native (realtime) format also sets up the
388 void KX_KetsjiEngine::StartEngine(bool clearIpo)
390 m_clockTime = m_kxsystem->GetTimeInSeconds();
391 m_frameTime = m_kxsystem->GetTimeInSeconds();
392 m_previousClockTime = m_kxsystem->GetTimeInSeconds();
395 m_bInitialized = true;
396 m_ticrate = DEFAULT_LOGIC_TIC_RATE;
400 m_sceneconverter->ResetPhysicsObjectsAnimationIpo(clearIpo);
401 m_sceneconverter->WritePhysicsObjectToAnimationIpo(m_currentFrame);
406 void KX_KetsjiEngine::ClearFrame()
408 // clear unless we're drawing overlapping stereo
409 if(m_rasterizer->InterlacedStereo() &&
410 m_rasterizer->GetEye() == RAS_IRasterizer::RAS_STEREO_RIGHTEYE)
413 // clear the viewports with the background color of the first scene
414 bool doclear = false;
415 KX_SceneList::iterator sceneit;
416 RAS_Rect clearvp, area, viewport;
418 for (sceneit = m_scenes.begin(); sceneit != m_scenes.end(); sceneit++)
420 KX_Scene* scene = *sceneit;
421 //const RAS_FrameSettings &framesettings = scene->GetFramingType();
422 list<class KX_Camera*>* cameras = scene->GetCameras();
424 list<KX_Camera*>::iterator it;
425 for(it = cameras->begin(); it != cameras->end(); it++)
427 GetSceneViewport(scene, (*it), area, viewport);
434 if(viewport.GetLeft() < clearvp.GetLeft())
435 clearvp.SetLeft(viewport.GetLeft());
436 if(viewport.GetBottom() < clearvp.GetBottom())
437 clearvp.SetBottom(viewport.GetBottom());
438 if(viewport.GetRight() > clearvp.GetRight())
439 clearvp.SetRight(viewport.GetRight());
440 if(viewport.GetTop() > clearvp.GetTop())
441 clearvp.SetTop(viewport.GetTop());
448 KX_Scene* firstscene = *m_scenes.begin();
449 SetBackGround(firstscene->GetWorldInfo());
451 m_canvas->SetViewPort(clearvp.GetLeft(), clearvp.GetBottom(),
452 clearvp.GetRight(), clearvp.GetTop());
453 m_rasterizer->ClearColorBuffer();
457 bool KX_KetsjiEngine::BeginFrame()
459 // set the area used for rendering (stereo can assign only a subset)
460 m_rasterizer->SetRenderArea();
462 if (m_canvas->BeginDraw())
466 m_rasterizer->BeginFrame(m_drawingmode , m_kxsystem->GetTimeInSeconds());
467 m_rendertools->BeginFrame(m_rasterizer);
476 void KX_KetsjiEngine::EndFrame()
478 // Show profiling info
479 m_logger->StartLog(tc_overhead, m_kxsystem->GetTimeInSeconds(), true);
480 if (m_show_framerate || m_show_profile || (m_show_debug_properties && m_propertiesPresent))
482 RenderDebugProperties();
485 m_average_framerate = m_logger->GetAverage();
486 if (m_average_framerate < 1e-6)
487 m_average_framerate = 1e-6;
488 m_average_framerate = 1.0/m_average_framerate;
490 // Go to next profiling measurement, time spend after this call is shown in the next frame.
491 m_logger->NextMeasurement(m_kxsystem->GetTimeInSeconds());
493 m_logger->StartLog(tc_rasterizer, m_kxsystem->GetTimeInSeconds(), true);
494 m_rasterizer->EndFrame();
495 // swap backbuffer (drawing into this buffer) <-> front/visible buffer
496 m_rasterizer->SwapBuffers();
497 m_rendertools->EndFrame(m_rasterizer);
503 //#include "PIL_time.h"
504 //#include "LinearMath/btQuickprof.h"
507 bool KX_KetsjiEngine::NextFrame()
510 // static hidden::Clock sClock;
512 m_logger->StartLog(tc_services, m_kxsystem->GetTimeInSeconds(),true);
514 //float dt = sClock.getTimeMicroseconds() * 0.000001f;
518 m_clockTime += 1./m_ticrate;
522 // m_clockTime += dt;
523 m_clockTime = m_kxsystem->GetTimeInSeconds();
526 double deltatime = m_clockTime - m_frameTime;
529 printf("problem with clock\n");
536 // Compute the number of logic frames to do each update (fixed tic bricks)
537 int frames =int(deltatime*m_ticrate+1e-6);
539 // printf("****************************************");
540 // printf("dt = %f, deltatime = %f, frames = %d\n",dt, deltatime,frames);
545 KX_SceneList::iterator sceneit;
551 // printf("framedOut: %d\n",frames);
552 m_frameTime+=(frames-frameOut)*(1.0/m_ticrate);
557 bool doRender = frames>0;
563 m_frameTime += 1.0/m_ticrate;
565 for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); ++sceneit)
566 // for each scene, call the proceed functions
568 KX_Scene* scene = *sceneit;
570 /* Suspension holds the physics and logic processing for an
571 * entire scene. Objects can be suspended individually, and
572 * the settings for that preceed the logic and physics
574 m_logger->StartLog(tc_logic, m_kxsystem->GetTimeInSeconds(), true);
576 m_sceneconverter->resetNoneDynamicObjectToIpo();//this is for none dynamic objects with ipo
578 scene->UpdateObjectActivity();
580 if (!scene->IsSuspended())
582 // if the scene was suspended recalcutlate the delta tu "curtime"
583 m_suspendedtime = scene->getSuspendedTime();
584 if (scene->getSuspendedTime()!=0.0)
585 scene->setSuspendedDelta(scene->getSuspendedDelta()+m_clockTime-scene->getSuspendedTime());
586 m_suspendeddelta = scene->getSuspendedDelta();
589 m_logger->StartLog(tc_network, m_kxsystem->GetTimeInSeconds(), true);
590 SG_SetActiveStage(SG_STAGE_NETWORK);
591 scene->GetNetworkScene()->proceed(m_frameTime);
593 //m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
594 //SG_SetActiveStage(SG_STAGE_NETWORK_UPDATE);
595 //scene->UpdateParents(m_frameTime);
597 m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true);
598 SG_SetActiveStage(SG_STAGE_PHYSICS1);
599 // set Python hooks for each scene
600 PHY_SetActiveEnvironment(scene->GetPhysicsEnvironment());
601 KX_SetActiveScene(scene);
603 scene->GetPhysicsEnvironment()->endFrame();
605 // Update scenegraph after physics step. This maps physics calculations
606 // into node positions.
607 //m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
608 //SG_SetActiveStage(SG_STAGE_PHYSICS1_UPDATE);
609 //scene->UpdateParents(m_frameTime);
611 // Process sensors, and controllers
612 m_logger->StartLog(tc_logic, m_kxsystem->GetTimeInSeconds(), true);
613 SG_SetActiveStage(SG_STAGE_CONTROLLER);
614 scene->LogicBeginFrame(m_frameTime);
616 // Scenegraph needs to be updated again, because Logic Controllers
617 // can affect the local matrices.
618 m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
619 SG_SetActiveStage(SG_STAGE_CONTROLLER_UPDATE);
620 scene->UpdateParents(m_frameTime);
624 // Do some cleanup work for this logic frame
625 m_logger->StartLog(tc_logic, m_kxsystem->GetTimeInSeconds(), true);
626 SG_SetActiveStage(SG_STAGE_ACTUATOR);
627 scene->LogicUpdateFrame(m_frameTime, true);
629 scene->LogicEndFrame();
631 // Actuators can affect the scenegraph
632 m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
633 SG_SetActiveStage(SG_STAGE_ACTUATOR_UPDATE);
634 scene->UpdateParents(m_frameTime);
636 m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true);
637 SG_SetActiveStage(SG_STAGE_PHYSICS2);
638 scene->GetPhysicsEnvironment()->beginFrame();
640 // Perform physics calculations on the scene. This can involve
641 // many iterations of the physics solver.
642 scene->GetPhysicsEnvironment()->proceedDeltaTime(m_frameTime,1.0/m_ticrate);//m_deltatimerealDeltaTime);
644 m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
645 SG_SetActiveStage(SG_STAGE_PHYSICS2_UPDATE);
646 scene->UpdateParents(m_frameTime);
651 m_sceneconverter->WritePhysicsObjectToAnimationIpo(++m_currentFrame);
654 scene->setSuspendedTime(0.0);
657 if(scene->getSuspendedTime()==0.0)
658 scene->setSuspendedTime(m_clockTime);
662 m_logger->StartLog(tc_services, m_kxsystem->GetTimeInSeconds(), true);
665 // update system devices
666 m_logger->StartLog(tc_logic, m_kxsystem->GetTimeInSeconds(), true);
667 if (m_keyboarddevice)
668 m_keyboarddevice->NextFrame();
671 m_mousedevice->NextFrame();
674 m_networkdevice->NextFrame();
677 m_audiodevice->NextFrame();
680 ProcessScheduledScenes();
685 bool bUseAsyncLogicBricks= false;//true;
687 if (bUseAsyncLogicBricks)
689 // Logic update sub frame: this will let some logic bricks run at the
691 for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); ++sceneit)
692 // for each scene, call the proceed functions
694 KX_Scene* scene = *sceneit;
696 if (!scene->IsSuspended())
698 // if the scene was suspended recalcutlate the delta tu "curtime"
699 m_suspendedtime = scene->getSuspendedTime();
700 if (scene->getSuspendedTime()!=0.0)
701 scene->setSuspendedDelta(scene->getSuspendedDelta()+m_clockTime-scene->getSuspendedTime());
702 m_suspendeddelta = scene->getSuspendedDelta();
704 // set Python hooks for each scene
705 PHY_SetActiveEnvironment(scene->GetPhysicsEnvironment());
706 KX_SetActiveScene(scene);
708 m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
709 SG_SetActiveStage(SG_STAGE_PHYSICS1);
710 scene->UpdateParents(m_clockTime);
712 // Perform physics calculations on the scene. This can involve
713 // many iterations of the physics solver.
714 m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true);
715 scene->GetPhysicsEnvironment()->proceedDeltaTime(m_clockTime,0.f);
716 // Update scenegraph after physics step. This maps physics calculations
717 // into node positions.
718 m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
719 SG_SetActiveStage(SG_STAGE_PHYSICS2);
720 scene->UpdateParents(m_clockTime);
722 // Do some cleanup work for this logic frame
723 m_logger->StartLog(tc_logic, m_kxsystem->GetTimeInSeconds(), true);
724 scene->LogicUpdateFrame(m_clockTime, false);
726 // Actuators can affect the scenegraph
727 m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
728 SG_SetActiveStage(SG_STAGE_ACTUATOR);
729 scene->UpdateParents(m_clockTime);
731 scene->setSuspendedTime(0.0);
734 if(scene->getSuspendedTime()==0.0)
735 scene->setSuspendedTime(m_clockTime);
739 m_logger->StartLog(tc_services, m_kxsystem->GetTimeInSeconds(), true);
744 m_previousClockTime = m_clockTime;
746 // Start logging time spend outside main loop
747 m_logger->StartLog(tc_outside, m_kxsystem->GetTimeInSeconds(), true);
754 void KX_KetsjiEngine::Render()
760 KX_Scene* firstscene = *m_scenes.begin();
761 const RAS_FrameSettings &framesettings = firstscene->GetFramingType();
763 m_logger->StartLog(tc_rasterizer, m_kxsystem->GetTimeInSeconds(), true);
764 SG_SetActiveStage(SG_STAGE_RENDER);
766 // hiding mouse cursor each frame
767 // (came back when going out of focus and then back in again)
769 m_canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE);
771 // clear the entire game screen with the border color
772 // only once per frame
773 m_canvas->BeginDraw();
774 if (m_drawingmode == RAS_IRasterizer::KX_TEXTURED) {
775 m_canvas->SetViewPort(0, 0, m_canvas->GetWidth(), m_canvas->GetHeight());
776 if (m_overrideFrameColor)
778 // Do not use the framing bar color set in the Blender scenes
779 m_canvas->ClearColor(
780 m_overrideFrameColorR,
781 m_overrideFrameColorG,
782 m_overrideFrameColorB,
788 // Use the framing bar color set in the Blender scenes
789 m_canvas->ClearColor(
790 framesettings.BarRed(),
791 framesettings.BarGreen(),
792 framesettings.BarBlue(),
796 // clear the -whole- viewport
797 m_canvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER|RAS_ICanvas::DEPTH_BUFFER);
800 m_rasterizer->SetEye(RAS_IRasterizer::RAS_STEREO_LEFTEYE);
802 // BeginFrame() sets the actual drawing area. You can use a part of the window
806 KX_SceneList::iterator sceneit;
807 for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++)
808 // for each scene, call the proceed functions
810 KX_Scene* scene = *sceneit;
811 KX_Camera* cam = scene->GetActiveCamera();
812 // pass the scene's worldsettings to the rasterizer
813 SetWorldSettings(scene->GetWorldInfo());
816 RenderShadowBuffers(scene);
818 // Avoid drawing the scene with the active camera twice when it's viewport is enabled
819 if(cam && !cam->GetViewport())
821 if (scene->IsClearingZBuffer())
822 m_rasterizer->ClearDepthBuffer();
824 m_rendertools->SetAuxilaryClientInfo(scene);
827 RenderFrame(scene, cam);
830 list<class KX_Camera*>* cameras = scene->GetCameras();
832 // Draw the scene once for each camera with an enabled viewport
833 list<KX_Camera*>::iterator it = cameras->begin();
834 while(it != cameras->end())
836 if((*it)->GetViewport())
838 if (scene->IsClearingZBuffer())
839 m_rasterizer->ClearDepthBuffer();
841 m_rendertools->SetAuxilaryClientInfo(scene);
844 RenderFrame(scene, (*it));
851 // only one place that checks for stereo
852 if(m_rasterizer->Stereo())
854 m_rasterizer->SetEye(RAS_IRasterizer::RAS_STEREO_RIGHTEYE);
860 for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++)
861 // for each scene, call the proceed functions
863 KX_Scene* scene = *sceneit;
864 KX_Camera* cam = scene->GetActiveCamera();
866 // pass the scene's worldsettings to the rasterizer
867 SetWorldSettings(scene->GetWorldInfo());
869 if (scene->IsClearingZBuffer())
870 m_rasterizer->ClearDepthBuffer();
872 //pass the scene, for picking and raycasting (shadows)
873 m_rendertools->SetAuxilaryClientInfo(scene);
876 //RenderFrame(scene);
877 RenderFrame(scene, cam);
879 list<class KX_Camera*>* cameras = scene->GetCameras();
881 // Draw the scene once for each camera with an enabled viewport
882 list<KX_Camera*>::iterator it = cameras->begin();
883 while(it != cameras->end())
885 if((*it)->GetViewport())
887 if (scene->IsClearingZBuffer())
888 m_rasterizer->ClearDepthBuffer();
890 m_rendertools->SetAuxilaryClientInfo(scene);
893 RenderFrame(scene, (*it));
899 } // if(m_rasterizer->Stereo())
901 // run the 2dfilters and motion blur once for all the scenes
909 void KX_KetsjiEngine::RequestExit(int exitrequestmode)
911 m_exitcode = exitrequestmode;
916 void KX_KetsjiEngine::SetNameNextGame(const STR_String& nextgame)
918 m_exitstring = nextgame;
923 int KX_KetsjiEngine::GetExitCode()
925 // if a gameactuator has set an exitcode or if there are no scenes left
928 if (m_scenes.begin()==m_scenes.end())
929 m_exitcode = KX_EXIT_REQUEST_NO_SCENES_LEFT;
937 const STR_String& KX_KetsjiEngine::GetExitString()
944 void KX_KetsjiEngine::DoSound(KX_Scene* scene)
946 m_logger->StartLog(tc_sound, m_kxsystem->GetTimeInSeconds(), true);
948 KX_Camera* cam = scene->GetActiveCamera();
951 MT_Point3 listenerposition = cam->NodeGetWorldPosition();
952 MT_Vector3 listenervelocity = cam->GetLinearVelocity();
953 MT_Matrix3x3 listenerorientation = cam->NodeGetWorldOrientation();
955 SND_Scene* soundscene = scene->GetSoundScene();
956 soundscene->SetListenerTransform(
959 listenerorientation);
961 soundscene->Proceed();
966 void KX_KetsjiEngine::SetBackGround(KX_WorldInfo* wi)
970 if (m_drawingmode == RAS_IRasterizer::KX_TEXTURED)
972 m_rasterizer->SetBackColor(
973 wi->getBackColorRed(),
974 wi->getBackColorGreen(),
975 wi->getBackColorBlue(),
984 void KX_KetsjiEngine::SetWorldSettings(KX_WorldInfo* wi)
989 m_rasterizer->SetAmbientColor(
990 wi->getAmbientColorRed(),
991 wi->getAmbientColorGreen(),
992 wi->getAmbientColorBlue()
995 if (m_drawingmode == RAS_IRasterizer::KX_TEXTURED)
999 m_rasterizer->SetFog(
1001 wi->getMistDistance(),
1002 wi->getMistColorRed(),
1003 wi->getMistColorGreen(),
1004 wi->getMistColorBlue()
1009 m_rasterizer->DisableFog();
1017 void KX_KetsjiEngine::SetDrawType(int drawingmode)
1019 m_drawingmode = drawingmode;
1024 void KX_KetsjiEngine::EnableCameraOverride(const STR_String& forscene)
1026 m_overrideCam = true;
1027 m_overrideSceneName = forscene;
1032 void KX_KetsjiEngine::SetCameraZoom(float camzoom)
1034 m_cameraZoom = camzoom;
1039 void KX_KetsjiEngine::SetCameraOverrideUseOrtho(bool useOrtho)
1041 m_overrideCamUseOrtho = useOrtho;
1046 void KX_KetsjiEngine::SetCameraOverrideProjectionMatrix(const MT_CmMatrix4x4& mat)
1048 m_overrideCamProjMat = mat;
1052 void KX_KetsjiEngine::SetCameraOverrideViewMatrix(const MT_CmMatrix4x4& mat)
1054 m_overrideCamViewMat = mat;
1057 void KX_KetsjiEngine::SetCameraOverrideClipping(float near, float far)
1059 m_overrideCamNear = near;
1060 m_overrideCamFar = far;
1063 void KX_KetsjiEngine::GetSceneViewport(KX_Scene *scene, KX_Camera* cam, RAS_Rect& area, RAS_Rect& viewport)
1065 // In this function we make sure the rasterizer settings are upto
1066 // date. We compute the viewport so that logic
1067 // using this information is upto date.
1069 // Note we postpone computation of the projection matrix
1070 // so that we are using the latest camera position.
1071 if (cam->GetViewport()) {
1072 RAS_Rect userviewport;
1074 userviewport.SetLeft(cam->GetViewportLeft());
1075 userviewport.SetBottom(cam->GetViewportBottom());
1076 userviewport.SetRight(cam->GetViewportRight());
1077 userviewport.SetTop(cam->GetViewportTop());
1079 // Don't do bars on user specified viewport
1080 RAS_FrameSettings settings = scene->GetFramingType();
1081 if(settings.FrameType() == RAS_FrameSettings::e_frame_bars)
1082 settings.SetFrameType(RAS_FrameSettings::e_frame_extend);
1084 RAS_FramingManager::ComputeViewport(
1085 scene->GetFramingType(),
1090 area = userviewport;
1092 else if ( m_overrideCam || (scene->GetName() != m_overrideSceneName) || m_overrideCamUseOrtho ) {
1093 RAS_FramingManager::ComputeViewport(
1094 scene->GetFramingType(),
1095 m_canvas->GetDisplayArea(),
1099 area = m_canvas->GetDisplayArea();
1101 viewport.SetLeft(0);
1102 viewport.SetBottom(0);
1103 viewport.SetRight(int(m_canvas->GetWidth()));
1104 viewport.SetTop(int(m_canvas->GetHeight()));
1106 area = m_canvas->GetDisplayArea();
1110 void KX_KetsjiEngine::RenderShadowBuffers(KX_Scene *scene)
1112 CListValue *objectlist = scene->GetObjectList();
1115 m_rendertools->SetAuxilaryClientInfo(scene);
1117 for(i=0; i<objectlist->GetCount(); i++) {
1118 KX_GameObject *gameobj = (KX_GameObject*)objectlist->GetValue(i);
1120 if(!gameobj->IsLight())
1123 KX_LightObject *light = (KX_LightObject*)gameobj;
1127 if(m_drawingmode == RAS_IRasterizer::KX_TEXTURED && light->HasShadowBuffer()) {
1128 /* make temporary camera */
1129 RAS_CameraData camdata = RAS_CameraData();
1130 KX_Camera *cam = new KX_Camera(scene, scene->m_callbacks, camdata, false);
1131 cam->SetName("__shadow__cam__");
1133 MT_Transform camtrans;
1135 /* switch drawmode for speed */
1136 drawmode = m_rasterizer->GetDrawingMode();
1137 m_rasterizer->SetDrawingMode(RAS_IRasterizer::KX_SHADOW);
1139 /* binds framebuffer object, sets up camera .. */
1140 light->BindShadowBuffer(m_rasterizer, cam, camtrans);
1143 scene->UpdateMeshTransformations();
1144 scene->CalculateVisibleMeshes(m_rasterizer, cam, light->GetShadowLayer());
1147 m_rasterizer->ClearDepthBuffer();
1148 scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools);
1150 /* unbind framebuffer object, restore drawmode, free camera */
1151 light->UnbindShadowBuffer(m_rasterizer);
1152 m_rasterizer->SetDrawingMode(drawmode);
1159 void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
1161 bool override_camera;
1162 RAS_Rect viewport, area;
1163 float left, right, bottom, top, nearfrust, farfrust, focallength;
1164 const float ortho = 100.0;
1165 // KX_Camera* cam = scene->GetActiveCamera();
1170 GetSceneViewport(scene, cam, area, viewport);
1172 // store the computed viewport in the scene
1173 scene->SetSceneViewport(viewport);
1175 // set the viewport for this frame and scene
1176 m_canvas->SetViewPort(viewport.GetLeft(), viewport.GetBottom(),
1177 viewport.GetRight(), viewport.GetTop());
1179 // see KX_BlenderMaterial::Activate
1180 //m_rasterizer->SetAmbient();
1181 m_rasterizer->DisplayFog();
1183 override_camera = m_overrideCam && (scene->GetName() == m_overrideSceneName);
1184 override_camera = override_camera && (cam->GetName() == "__default__cam__");
1186 if (override_camera && m_overrideCamUseOrtho) {
1187 MT_CmMatrix4x4 projmat = m_overrideCamProjMat;
1188 m_rasterizer->SetProjectionMatrix(projmat);
1189 } else if (cam->hasValidProjectionMatrix() && !cam->GetViewport() )
1191 m_rasterizer->SetProjectionMatrix(cam->GetProjectionMatrix());
1194 RAS_FrameFrustum frustum;
1195 float lens = cam->GetLens();
1196 bool orthographic = !cam->GetCameraData()->m_perspective;
1197 nearfrust = cam->GetCameraNear();
1198 farfrust = cam->GetCameraFar();
1199 focallength = cam->GetFocalLength();
1201 if(override_camera) {
1202 nearfrust = m_overrideCamNear;
1203 farfrust = m_overrideCamFar;
1208 nearfrust = (nearfrust + 1.0)*ortho;
1212 RAS_FramingManager::ComputeFrustum(
1213 scene->GetFramingType(),
1222 left = frustum.x1 * m_cameraZoom;
1223 right = frustum.x2 * m_cameraZoom;
1224 bottom = frustum.y1 * m_cameraZoom;
1225 top = frustum.y2 * m_cameraZoom;
1226 nearfrust = frustum.camnear;
1227 farfrust = frustum.camfar;
1229 MT_Matrix4x4 projmat = m_rasterizer->GetFrustumMatrix(
1230 left, right, bottom, top, nearfrust, farfrust, focallength);
1232 cam->SetProjectionMatrix(projmat);
1234 // Otherwise the projection matrix for each eye will be the same...
1235 if (m_rasterizer->Stereo())
1236 cam->InvalidateProjectionMatrix();
1239 MT_Transform camtrans(cam->GetWorldToCamera());
1240 if (!cam->GetCameraData()->m_perspective)
1241 camtrans.getOrigin()[2] *= ortho;
1242 MT_Matrix4x4 viewmat(camtrans);
1244 m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldPosition(),
1245 cam->GetCameraLocation(), cam->GetCameraOrientation());
1246 cam->SetModelviewMatrix(viewmat);
1248 //redundant, already done in
1249 //scene->UpdateMeshTransformations();
1251 // The following actually reschedules all vertices to be
1252 // redrawn. There is a cache between the actual rescheduling
1253 // and this call though. Visibility is imparted when this call
1254 // runs through the individual objects.
1256 m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
1257 SG_SetActiveStage(SG_STAGE_CULLING);
1259 scene->CalculateVisibleMeshes(m_rasterizer,cam);
1261 m_logger->StartLog(tc_rasterizer, m_kxsystem->GetTimeInSeconds(), true);
1262 SG_SetActiveStage(SG_STAGE_RENDER);
1264 scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools);
1266 if (scene->GetPhysicsEnvironment())
1267 scene->GetPhysicsEnvironment()->debugDrawWorld();
1269 m_rasterizer->FlushDebugLines();
1272 void KX_KetsjiEngine::PostRenderFrame()
1274 m_rendertools->Render2DFilters(m_canvas);
1275 m_rendertools->MotionBlur(m_rasterizer);
1278 void KX_KetsjiEngine::StopEngine()
1285 // printf("TestHandlesPhysicsObjectToAnimationIpo\n");
1286 m_sceneconverter->TestHandlesPhysicsObjectToAnimationIpo();
1289 KX_SceneList::iterator sceneit;
1290 for (sceneit = m_scenes.begin();sceneit != m_scenes.end() ; sceneit++)
1292 KX_Scene* scene = *sceneit;
1293 m_sceneconverter->RemoveScene(scene);
1297 // cleanup all the stuff
1298 m_rasterizer->Exit();
1302 // Scene Management is able to switch between scenes
1303 // and have several scene's running in parallel
1304 void KX_KetsjiEngine::AddScene(KX_Scene* scene)
1306 m_scenes.push_back(scene);
1307 PostProcessScene(scene);
1308 SceneListsChanged();
1313 void KX_KetsjiEngine::PostProcessScene(KX_Scene* scene)
1315 bool override_camera = (m_overrideCam && (scene->GetName() == m_overrideSceneName));
1317 SG_SetActiveStage(SG_STAGE_SCENE);
1319 // if there is no activecamera, or the camera is being
1320 // overridden we need to construct a temporarily camera
1321 if (!scene->GetActiveCamera() || override_camera)
1323 KX_Camera* activecam = NULL;
1325 RAS_CameraData camdata = RAS_CameraData();
1326 activecam = new KX_Camera(scene,KX_Scene::m_callbacks,camdata);
1327 activecam->SetName("__default__cam__");
1329 // set transformation
1330 if (override_camera) {
1331 const MT_CmMatrix4x4& cammatdata = m_overrideCamViewMat;
1332 MT_Transform trans = MT_Transform(cammatdata.getPointer());
1333 MT_Transform camtrans;
1334 camtrans.invert(trans);
1336 activecam->NodeSetLocalPosition(camtrans.getOrigin());
1337 activecam->NodeSetLocalOrientation(camtrans.getBasis());
1338 activecam->NodeUpdateGS(0);
1340 activecam->NodeSetLocalPosition(MT_Point3(0.0, 0.0, 0.0));
1341 activecam->NodeSetLocalOrientation(MT_Vector3(0.0, 0.0, 0.0));
1342 activecam->NodeUpdateGS(0);
1345 scene->AddCamera(activecam);
1346 scene->SetActiveCamera(activecam);
1347 scene->GetObjectList()->Add(activecam->AddRef());
1348 scene->GetRootParentList()->Add(activecam->AddRef());
1349 //done with activecam
1350 activecam->Release();
1353 scene->UpdateParents(0.0);
1358 void KX_KetsjiEngine::RenderDebugProperties()
1360 STR_String debugtxt;
1361 int xcoord = 10; // mmmm, these constants were taken from blender source
1362 int ycoord = 14; // to 'mimic' behaviour
1364 float tottime = m_logger->GetAverage();
1365 if (tottime < 1e-6f) {
1369 // Set viewport to entire canvas
1371 m_canvas->SetViewPort(0, 0, int(m_canvas->GetWidth()), int(m_canvas->GetHeight()));
1373 /* Framerate display */
1374 if (m_show_framerate) {
1375 debugtxt.Format("swap : %.3f (%.3f frames per second)", tottime, 1.0/tottime);
1376 m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED,
1380 m_canvas->GetWidth() /* RdV, TODO ?? */,
1381 m_canvas->GetHeight() /* RdV, TODO ?? */);
1385 /* Profile and framerate display */
1388 for (int j = tc_first; j < tc_numCategories; j++)
1390 debugtxt.Format(m_profileLabels[j]);
1391 m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED,
1394 m_canvas->GetWidth(),
1395 m_canvas->GetHeight());
1396 double time = m_logger->GetAverage((KX_TimeCategory)j);
1397 debugtxt.Format("%2.2f %%", time/tottime * 100.f);
1398 m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED,
1400 xcoord + 60 ,ycoord,
1401 m_canvas->GetWidth(),
1402 m_canvas->GetHeight());
1407 /* Property display*/
1408 if (m_show_debug_properties && m_propertiesPresent)
1410 KX_SceneList::iterator sceneit;
1411 for (sceneit = m_scenes.begin();sceneit != m_scenes.end() ; sceneit++)
1413 KX_Scene* scene = *sceneit;
1414 /* the 'normal' debug props */
1415 vector<SCA_DebugProp*>& debugproplist = scene->GetDebugProperties();
1417 for (vector<SCA_DebugProp*>::iterator it = debugproplist.begin();
1418 !(it==debugproplist.end());it++)
1420 CValue* propobj = (*it)->m_obj;
1421 STR_String objname = propobj->GetName();
1422 STR_String propname = (*it)->m_name;
1423 if (propname == "__state__")
1425 // reserve name for object state
1426 KX_GameObject* gameobj = static_cast<KX_GameObject*>(propobj);
1427 unsigned int state = gameobj->GetState();
1428 debugtxt = objname + "." + propname + " = ";
1430 for (int statenum=1;state;state >>= 1, statenum++)
1438 debugtxt += STR_String(statenum);
1442 m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED,
1446 m_canvas->GetWidth(),
1447 m_canvas->GetHeight());
1452 CValue* propval = propobj->GetProperty(propname);
1455 STR_String text = propval->GetText();
1456 debugtxt = objname + "." + propname + " = " + text;
1457 m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED,
1461 m_canvas->GetWidth(),
1462 m_canvas->GetHeight());
1472 KX_SceneList* KX_KetsjiEngine::CurrentScenes()
1479 KX_Scene* KX_KetsjiEngine::FindScene(const STR_String& scenename)
1481 KX_SceneList::iterator sceneit = m_scenes.begin();
1483 // bit risky :) better to split the second clause
1484 while ( (sceneit != m_scenes.end())
1485 && ((*sceneit)->GetName() != scenename))
1490 return ((sceneit == m_scenes.end()) ? NULL : *sceneit);
1495 void KX_KetsjiEngine::ConvertAndAddScene(const STR_String& scenename,bool overlay)
1497 // only add scene when it doesn't exist!
1498 if (FindScene(scenename))
1500 STR_String tmpname = scenename;
1501 printf("warning: scene %s already exists, not added!\n",tmpname.Ptr());
1507 m_addingOverlayScenes.insert(scenename);
1511 m_addingBackgroundScenes.insert(scenename);
1519 void KX_KetsjiEngine::RemoveScene(const STR_String& scenename)
1521 if (FindScene(scenename))
1523 m_removingScenes.insert(scenename);
1527 // STR_String tmpname = scenename;
1528 std::cout << "warning: scene " << scenename << " does not exist, not removed!" << std::endl;
1534 void KX_KetsjiEngine::RemoveScheduledScenes()
1536 if (m_removingScenes.size())
1538 set<STR_String>::iterator scenenameit;
1539 for (scenenameit=m_removingScenes.begin();scenenameit != m_removingScenes.end();scenenameit++)
1541 STR_String scenename = *scenenameit;
1543 KX_SceneList::iterator sceneit;
1544 for (sceneit = m_scenes.begin();sceneit != m_scenes.end() ; sceneit++)
1546 KX_Scene* scene = *sceneit;
1547 if (scene->GetName()==scenename)
1549 m_sceneconverter->RemoveScene(scene);
1550 m_scenes.erase(sceneit);
1555 m_removingScenes.clear();
1561 KX_Scene* KX_KetsjiEngine::CreateScene(const STR_String& scenename)
1563 Scene *scene = m_sceneconverter->GetBlenderSceneForName(scenename);
1564 KX_Scene* tmpscene = new KX_Scene(m_keyboarddevice,
1571 m_sceneconverter->ConvertScene(scenename,
1583 void KX_KetsjiEngine::AddScheduledScenes()
1585 set<STR_String>::iterator scenenameit;
1587 if (m_addingOverlayScenes.size())
1589 for (scenenameit = m_addingOverlayScenes.begin();
1590 scenenameit != m_addingOverlayScenes.end();
1593 STR_String scenename = *scenenameit;
1594 KX_Scene* tmpscene = CreateScene(scenename);
1595 m_scenes.push_back(tmpscene);
1596 PostProcessScene(tmpscene);
1598 m_addingOverlayScenes.clear();
1601 if (m_addingBackgroundScenes.size())
1603 for (scenenameit = m_addingBackgroundScenes.begin();
1604 scenenameit != m_addingBackgroundScenes.end();
1607 STR_String scenename = *scenenameit;
1608 KX_Scene* tmpscene = CreateScene(scenename);
1609 m_scenes.insert(m_scenes.begin(),tmpscene);
1610 PostProcessScene(tmpscene);
1613 m_addingBackgroundScenes.clear();
1619 void KX_KetsjiEngine::ReplaceScene(const STR_String& oldscene,const STR_String& newscene)
1621 m_replace_scenes.insert(std::make_pair(oldscene,newscene));
1624 // replace scene is not the same as removing and adding because the
1625 // scene must be in exact the same place (to maintain drawingorder)
1626 // (nzc) - should that not be done with a scene-display list? It seems
1627 // stupid to rely on the mem allocation order...
1628 void KX_KetsjiEngine::ReplaceScheduledScenes()
1630 if (m_replace_scenes.size())
1632 set<pair<STR_String,STR_String> >::iterator scenenameit;
1634 for (scenenameit = m_replace_scenes.begin();
1635 scenenameit != m_replace_scenes.end();
1638 STR_String oldscenename = (*scenenameit).first;
1639 STR_String newscenename = (*scenenameit).second;
1641 /* Scenes are not supposed to be included twice... I think */
1642 KX_SceneList::iterator sceneit;
1643 for (sceneit = m_scenes.begin();sceneit != m_scenes.end() ; sceneit++)
1645 KX_Scene* scene = *sceneit;
1646 if (scene->GetName() == oldscenename)
1648 m_sceneconverter->RemoveScene(scene);
1649 KX_Scene* tmpscene = CreateScene(newscenename);
1650 m_scenes[i]=tmpscene;
1651 PostProcessScene(tmpscene);
1656 m_replace_scenes.clear();
1662 void KX_KetsjiEngine::SuspendScene(const STR_String& scenename)
1664 KX_Scene* scene = FindScene(scenename);
1665 if (scene) scene->Suspend();
1670 void KX_KetsjiEngine::ResumeScene(const STR_String& scenename)
1672 KX_Scene* scene = FindScene(scenename);
1673 if (scene) scene->Resume();
1678 void KX_KetsjiEngine::SetUseFixedTime(bool bUseFixedTime)
1680 m_bFixedTime = bUseFixedTime;
1684 void KX_KetsjiEngine::SetGame2IpoMode(bool game2ipo,int startFrame)
1686 m_game2ipo = game2ipo;
1689 //when recording physics keyframes, always run at a fixed framerate
1690 m_bFixedTime = true;
1692 m_currentFrame = startFrame;
1695 bool KX_KetsjiEngine::GetUseFixedTime(void) const
1697 return m_bFixedTime;
1700 double KX_KetsjiEngine::GetSuspendedDelta()
1702 return m_suspendeddelta;
1705 double KX_KetsjiEngine::GetTicRate()
1710 void KX_KetsjiEngine::SetTicRate(double ticrate)
1712 m_ticrate = ticrate;
1715 double KX_KetsjiEngine::GetAnimFrameRate()
1717 return m_anim_framerate;
1720 double KX_KetsjiEngine::GetClockTime(void) const
1725 void KX_KetsjiEngine::SetAnimFrameRate(double framerate)
1727 m_anim_framerate = framerate;
1730 double KX_KetsjiEngine::GetAverageFrameRate()
1732 return m_average_framerate;
1735 void KX_KetsjiEngine::SetTimingDisplay(bool frameRate, bool profile, bool properties)
1737 m_show_framerate = frameRate;
1738 m_show_profile = profile;
1739 m_show_debug_properties = properties;
1744 void KX_KetsjiEngine::GetTimingDisplay(bool& frameRate, bool& profile, bool& properties) const
1746 frameRate = m_show_framerate;
1747 profile = m_show_profile;
1748 properties = m_show_debug_properties;
1753 void KX_KetsjiEngine::ProcessScheduledScenes(void)
1755 // Check whether there will be changes to the list of scenes
1756 if (m_addingOverlayScenes.size() ||
1757 m_addingBackgroundScenes.size() ||
1758 m_replace_scenes.size() ||
1759 m_removingScenes.size()) {
1761 // Change the scene list
1762 ReplaceScheduledScenes();
1763 RemoveScheduledScenes();
1764 AddScheduledScenes();
1767 SceneListsChanged();
1773 void KX_KetsjiEngine::SceneListsChanged(void)
1775 m_propertiesPresent = false;
1776 KX_SceneList::iterator sceneit = m_scenes.begin();
1777 while ((sceneit != m_scenes.end()) && (!m_propertiesPresent))
1779 KX_Scene* scene = *sceneit;
1780 vector<SCA_DebugProp*>& debugproplist = scene->GetDebugProperties();
1781 m_propertiesPresent = !debugproplist.empty();
1787 void KX_KetsjiEngine::SetHideCursor(bool hideCursor)
1789 m_hideCursor = hideCursor;
1793 bool KX_KetsjiEngine::GetHideCursor(void) const
1795 return m_hideCursor;
1799 void KX_KetsjiEngine::SetUseOverrideFrameColor(bool overrideFrameColor)
1801 m_overrideFrameColor = overrideFrameColor;
1805 bool KX_KetsjiEngine::GetUseOverrideFrameColor(void) const
1807 return m_overrideFrameColor;
1811 void KX_KetsjiEngine::SetOverrideFrameColor(float r, float g, float b)
1813 m_overrideFrameColorR = r;
1814 m_overrideFrameColorG = g;
1815 m_overrideFrameColorB = b;
1819 void KX_KetsjiEngine::GetOverrideFrameColor(float& r, float& g, float& b) const
1821 r = m_overrideFrameColorR;
1822 g = m_overrideFrameColorG;
1823 b = m_overrideFrameColorB;