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())
906 void KX_KetsjiEngine::RequestExit(int exitrequestmode)
908 m_exitcode = exitrequestmode;
913 void KX_KetsjiEngine::SetNameNextGame(const STR_String& nextgame)
915 m_exitstring = nextgame;
920 int KX_KetsjiEngine::GetExitCode()
922 // if a gameactuator has set an exitcode or if there are no scenes left
925 if (m_scenes.begin()==m_scenes.end())
926 m_exitcode = KX_EXIT_REQUEST_NO_SCENES_LEFT;
934 const STR_String& KX_KetsjiEngine::GetExitString()
941 void KX_KetsjiEngine::DoSound(KX_Scene* scene)
943 m_logger->StartLog(tc_sound, m_kxsystem->GetTimeInSeconds(), true);
945 KX_Camera* cam = scene->GetActiveCamera();
948 MT_Point3 listenerposition = cam->NodeGetWorldPosition();
949 MT_Vector3 listenervelocity = cam->GetLinearVelocity();
950 MT_Matrix3x3 listenerorientation = cam->NodeGetWorldOrientation();
952 SND_Scene* soundscene = scene->GetSoundScene();
953 soundscene->SetListenerTransform(
956 listenerorientation);
958 soundscene->Proceed();
963 void KX_KetsjiEngine::SetBackGround(KX_WorldInfo* wi)
967 if (m_drawingmode == RAS_IRasterizer::KX_TEXTURED)
969 m_rasterizer->SetBackColor(
970 wi->getBackColorRed(),
971 wi->getBackColorGreen(),
972 wi->getBackColorBlue(),
981 void KX_KetsjiEngine::SetWorldSettings(KX_WorldInfo* wi)
986 m_rasterizer->SetAmbientColor(
987 wi->getAmbientColorRed(),
988 wi->getAmbientColorGreen(),
989 wi->getAmbientColorBlue()
992 if (m_drawingmode == RAS_IRasterizer::KX_TEXTURED)
996 m_rasterizer->SetFog(
998 wi->getMistDistance(),
999 wi->getMistColorRed(),
1000 wi->getMistColorGreen(),
1001 wi->getMistColorBlue()
1006 m_rasterizer->DisableFog();
1014 void KX_KetsjiEngine::SetDrawType(int drawingmode)
1016 m_drawingmode = drawingmode;
1021 void KX_KetsjiEngine::EnableCameraOverride(const STR_String& forscene)
1023 m_overrideCam = true;
1024 m_overrideSceneName = forscene;
1029 void KX_KetsjiEngine::SetCameraZoom(float camzoom)
1031 m_cameraZoom = camzoom;
1036 void KX_KetsjiEngine::SetCameraOverrideUseOrtho(bool useOrtho)
1038 m_overrideCamUseOrtho = useOrtho;
1043 void KX_KetsjiEngine::SetCameraOverrideProjectionMatrix(const MT_CmMatrix4x4& mat)
1045 m_overrideCamProjMat = mat;
1049 void KX_KetsjiEngine::SetCameraOverrideViewMatrix(const MT_CmMatrix4x4& mat)
1051 m_overrideCamViewMat = mat;
1054 void KX_KetsjiEngine::SetCameraOverrideClipping(float near, float far)
1056 m_overrideCamNear = near;
1057 m_overrideCamFar = far;
1060 void KX_KetsjiEngine::GetSceneViewport(KX_Scene *scene, KX_Camera* cam, RAS_Rect& area, RAS_Rect& viewport)
1062 // In this function we make sure the rasterizer settings are upto
1063 // date. We compute the viewport so that logic
1064 // using this information is upto date.
1066 // Note we postpone computation of the projection matrix
1067 // so that we are using the latest camera position.
1068 if (cam->GetViewport()) {
1069 RAS_Rect userviewport;
1071 userviewport.SetLeft(cam->GetViewportLeft());
1072 userviewport.SetBottom(cam->GetViewportBottom());
1073 userviewport.SetRight(cam->GetViewportRight());
1074 userviewport.SetTop(cam->GetViewportTop());
1076 // Don't do bars on user specified viewport
1077 RAS_FrameSettings settings = scene->GetFramingType();
1078 if(settings.FrameType() == RAS_FrameSettings::e_frame_bars)
1079 settings.SetFrameType(RAS_FrameSettings::e_frame_extend);
1081 RAS_FramingManager::ComputeViewport(
1082 scene->GetFramingType(),
1087 area = userviewport;
1089 else if ( m_overrideCam || (scene->GetName() != m_overrideSceneName) || m_overrideCamUseOrtho ) {
1090 RAS_FramingManager::ComputeViewport(
1091 scene->GetFramingType(),
1092 m_canvas->GetDisplayArea(),
1096 area = m_canvas->GetDisplayArea();
1098 viewport.SetLeft(0);
1099 viewport.SetBottom(0);
1100 viewport.SetRight(int(m_canvas->GetWidth()));
1101 viewport.SetTop(int(m_canvas->GetHeight()));
1103 area = m_canvas->GetDisplayArea();
1107 void KX_KetsjiEngine::RenderShadowBuffers(KX_Scene *scene)
1109 CListValue *objectlist = scene->GetObjectList();
1112 m_rendertools->SetAuxilaryClientInfo(scene);
1114 for(i=0; i<objectlist->GetCount(); i++) {
1115 KX_GameObject *gameobj = (KX_GameObject*)objectlist->GetValue(i);
1117 if(!gameobj->IsLight())
1120 KX_LightObject *light = (KX_LightObject*)gameobj;
1124 if(m_drawingmode == RAS_IRasterizer::KX_TEXTURED && light->HasShadowBuffer()) {
1125 /* make temporary camera */
1126 RAS_CameraData camdata = RAS_CameraData();
1127 KX_Camera *cam = new KX_Camera(scene, scene->m_callbacks, camdata, false);
1128 cam->SetName("__shadow__cam__");
1130 MT_Transform camtrans;
1132 /* switch drawmode for speed */
1133 drawmode = m_rasterizer->GetDrawingMode();
1134 m_rasterizer->SetDrawingMode(RAS_IRasterizer::KX_SHADOW);
1136 /* binds framebuffer object, sets up camera .. */
1137 light->BindShadowBuffer(m_rasterizer, cam, camtrans);
1140 scene->UpdateMeshTransformations();
1141 scene->CalculateVisibleMeshes(m_rasterizer, cam, light->GetShadowLayer());
1144 m_rasterizer->ClearDepthBuffer();
1145 scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools);
1147 /* unbind framebuffer object, restore drawmode, free camera */
1148 light->UnbindShadowBuffer(m_rasterizer);
1149 m_rasterizer->SetDrawingMode(drawmode);
1156 void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
1158 bool override_camera;
1159 RAS_Rect viewport, area;
1160 float left, right, bottom, top, nearfrust, farfrust, focallength;
1161 const float ortho = 100.0;
1162 // KX_Camera* cam = scene->GetActiveCamera();
1167 GetSceneViewport(scene, cam, area, viewport);
1169 // store the computed viewport in the scene
1170 scene->SetSceneViewport(viewport);
1172 // set the viewport for this frame and scene
1173 m_canvas->SetViewPort(viewport.GetLeft(), viewport.GetBottom(),
1174 viewport.GetRight(), viewport.GetTop());
1176 // see KX_BlenderMaterial::Activate
1177 //m_rasterizer->SetAmbient();
1178 m_rasterizer->DisplayFog();
1180 override_camera = m_overrideCam && (scene->GetName() == m_overrideSceneName);
1181 override_camera = override_camera && (cam->GetName() == "__default__cam__");
1183 if (override_camera && m_overrideCamUseOrtho) {
1184 MT_CmMatrix4x4 projmat = m_overrideCamProjMat;
1185 m_rasterizer->SetProjectionMatrix(projmat);
1186 } else if (cam->hasValidProjectionMatrix() && !cam->GetViewport() )
1188 m_rasterizer->SetProjectionMatrix(cam->GetProjectionMatrix());
1191 RAS_FrameFrustum frustum;
1192 float lens = cam->GetLens();
1193 bool orthographic = !cam->GetCameraData()->m_perspective;
1194 nearfrust = cam->GetCameraNear();
1195 farfrust = cam->GetCameraFar();
1196 focallength = cam->GetFocalLength();
1198 if(override_camera) {
1199 nearfrust = m_overrideCamNear;
1200 farfrust = m_overrideCamFar;
1205 nearfrust = (nearfrust + 1.0)*ortho;
1209 RAS_FramingManager::ComputeFrustum(
1210 scene->GetFramingType(),
1219 left = frustum.x1 * m_cameraZoom;
1220 right = frustum.x2 * m_cameraZoom;
1221 bottom = frustum.y1 * m_cameraZoom;
1222 top = frustum.y2 * m_cameraZoom;
1223 nearfrust = frustum.camnear;
1224 farfrust = frustum.camfar;
1226 MT_Matrix4x4 projmat = m_rasterizer->GetFrustumMatrix(
1227 left, right, bottom, top, nearfrust, farfrust, focallength);
1229 cam->SetProjectionMatrix(projmat);
1231 // Otherwise the projection matrix for each eye will be the same...
1232 if (m_rasterizer->Stereo())
1233 cam->InvalidateProjectionMatrix();
1236 MT_Transform camtrans(cam->GetWorldToCamera());
1237 if (!cam->GetCameraData()->m_perspective)
1238 camtrans.getOrigin()[2] *= ortho;
1239 MT_Matrix4x4 viewmat(camtrans);
1241 m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldPosition(),
1242 cam->GetCameraLocation(), cam->GetCameraOrientation());
1243 cam->SetModelviewMatrix(viewmat);
1245 //redundant, already done in
1246 //scene->UpdateMeshTransformations();
1248 // The following actually reschedules all vertices to be
1249 // redrawn. There is a cache between the actual rescheduling
1250 // and this call though. Visibility is imparted when this call
1251 // runs through the individual objects.
1253 m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
1254 SG_SetActiveStage(SG_STAGE_CULLING);
1256 scene->CalculateVisibleMeshes(m_rasterizer,cam);
1258 m_logger->StartLog(tc_rasterizer, m_kxsystem->GetTimeInSeconds(), true);
1259 SG_SetActiveStage(SG_STAGE_RENDER);
1261 scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools);
1263 if (scene->GetPhysicsEnvironment())
1264 scene->GetPhysicsEnvironment()->debugDrawWorld();
1266 m_rasterizer->FlushDebugLines();
1271 void KX_KetsjiEngine::PostRenderFrame()
1273 m_rendertools->PushMatrix();
1274 m_rendertools->Render2DFilters(m_canvas);
1275 m_rendertools->MotionBlur(m_rasterizer);
1276 m_rendertools->PopMatrix();
1279 void KX_KetsjiEngine::StopEngine()
1286 // printf("TestHandlesPhysicsObjectToAnimationIpo\n");
1287 m_sceneconverter->TestHandlesPhysicsObjectToAnimationIpo();
1290 KX_SceneList::iterator sceneit;
1291 for (sceneit = m_scenes.begin();sceneit != m_scenes.end() ; sceneit++)
1293 KX_Scene* scene = *sceneit;
1294 m_sceneconverter->RemoveScene(scene);
1298 // cleanup all the stuff
1299 m_rasterizer->Exit();
1303 // Scene Management is able to switch between scenes
1304 // and have several scene's running in parallel
1305 void KX_KetsjiEngine::AddScene(KX_Scene* scene)
1307 m_scenes.push_back(scene);
1308 PostProcessScene(scene);
1309 SceneListsChanged();
1314 void KX_KetsjiEngine::PostProcessScene(KX_Scene* scene)
1316 bool override_camera = (m_overrideCam && (scene->GetName() == m_overrideSceneName));
1318 SG_SetActiveStage(SG_STAGE_SCENE);
1320 // if there is no activecamera, or the camera is being
1321 // overridden we need to construct a temporarily camera
1322 if (!scene->GetActiveCamera() || override_camera)
1324 KX_Camera* activecam = NULL;
1326 RAS_CameraData camdata = RAS_CameraData();
1327 activecam = new KX_Camera(scene,KX_Scene::m_callbacks,camdata);
1328 activecam->SetName("__default__cam__");
1330 // set transformation
1331 if (override_camera) {
1332 const MT_CmMatrix4x4& cammatdata = m_overrideCamViewMat;
1333 MT_Transform trans = MT_Transform(cammatdata.getPointer());
1334 MT_Transform camtrans;
1335 camtrans.invert(trans);
1337 activecam->NodeSetLocalPosition(camtrans.getOrigin());
1338 activecam->NodeSetLocalOrientation(camtrans.getBasis());
1339 activecam->NodeUpdateGS(0);
1341 activecam->NodeSetLocalPosition(MT_Point3(0.0, 0.0, 0.0));
1342 activecam->NodeSetLocalOrientation(MT_Vector3(0.0, 0.0, 0.0));
1343 activecam->NodeUpdateGS(0);
1346 scene->AddCamera(activecam);
1347 scene->SetActiveCamera(activecam);
1348 scene->GetObjectList()->Add(activecam->AddRef());
1349 scene->GetRootParentList()->Add(activecam->AddRef());
1350 //done with activecam
1351 activecam->Release();
1354 scene->UpdateParents(0.0);
1359 void KX_KetsjiEngine::RenderDebugProperties()
1361 STR_String debugtxt;
1362 int xcoord = 10; // mmmm, these constants were taken from blender source
1363 int ycoord = 14; // to 'mimic' behaviour
1365 float tottime = m_logger->GetAverage();
1366 if (tottime < 1e-6f) {
1370 // Set viewport to entire canvas
1372 m_canvas->SetViewPort(0, 0, int(m_canvas->GetWidth()), int(m_canvas->GetHeight()));
1374 /* Framerate display */
1375 if (m_show_framerate) {
1376 debugtxt.Format("swap : %.3f (%.3f frames per second)", tottime, 1.0/tottime);
1377 m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED,
1381 m_canvas->GetWidth() /* RdV, TODO ?? */,
1382 m_canvas->GetHeight() /* RdV, TODO ?? */);
1386 /* Profile and framerate display */
1389 for (int j = tc_first; j < tc_numCategories; j++)
1391 debugtxt.Format(m_profileLabels[j]);
1392 m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED,
1395 m_canvas->GetWidth(),
1396 m_canvas->GetHeight());
1397 double time = m_logger->GetAverage((KX_TimeCategory)j);
1398 debugtxt.Format("%2.2f %%", time/tottime * 100.f);
1399 m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED,
1401 xcoord + 60 ,ycoord,
1402 m_canvas->GetWidth(),
1403 m_canvas->GetHeight());
1408 /* Property display*/
1409 if (m_show_debug_properties && m_propertiesPresent)
1411 KX_SceneList::iterator sceneit;
1412 for (sceneit = m_scenes.begin();sceneit != m_scenes.end() ; sceneit++)
1414 KX_Scene* scene = *sceneit;
1415 /* the 'normal' debug props */
1416 vector<SCA_DebugProp*>& debugproplist = scene->GetDebugProperties();
1418 for (vector<SCA_DebugProp*>::iterator it = debugproplist.begin();
1419 !(it==debugproplist.end());it++)
1421 CValue* propobj = (*it)->m_obj;
1422 STR_String objname = propobj->GetName();
1423 STR_String propname = (*it)->m_name;
1424 if (propname == "__state__")
1426 // reserve name for object state
1427 KX_GameObject* gameobj = static_cast<KX_GameObject*>(propobj);
1428 unsigned int state = gameobj->GetState();
1429 debugtxt = objname + "." + propname + " = ";
1431 for (int statenum=1;state;state >>= 1, statenum++)
1439 debugtxt += STR_String(statenum);
1443 m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED,
1447 m_canvas->GetWidth(),
1448 m_canvas->GetHeight());
1453 CValue* propval = propobj->GetProperty(propname);
1456 STR_String text = propval->GetText();
1457 debugtxt = objname + "." + propname + " = " + text;
1458 m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED,
1462 m_canvas->GetWidth(),
1463 m_canvas->GetHeight());
1473 KX_SceneList* KX_KetsjiEngine::CurrentScenes()
1480 KX_Scene* KX_KetsjiEngine::FindScene(const STR_String& scenename)
1482 KX_SceneList::iterator sceneit = m_scenes.begin();
1484 // bit risky :) better to split the second clause
1485 while ( (sceneit != m_scenes.end())
1486 && ((*sceneit)->GetName() != scenename))
1491 return ((sceneit == m_scenes.end()) ? NULL : *sceneit);
1496 void KX_KetsjiEngine::ConvertAndAddScene(const STR_String& scenename,bool overlay)
1498 // only add scene when it doesn't exist!
1499 if (FindScene(scenename))
1501 STR_String tmpname = scenename;
1502 printf("warning: scene %s already exists, not added!\n",tmpname.Ptr());
1508 m_addingOverlayScenes.insert(scenename);
1512 m_addingBackgroundScenes.insert(scenename);
1520 void KX_KetsjiEngine::RemoveScene(const STR_String& scenename)
1522 if (FindScene(scenename))
1524 m_removingScenes.insert(scenename);
1528 // STR_String tmpname = scenename;
1529 std::cout << "warning: scene " << scenename << " does not exist, not removed!" << std::endl;
1535 void KX_KetsjiEngine::RemoveScheduledScenes()
1537 if (m_removingScenes.size())
1539 set<STR_String>::iterator scenenameit;
1540 for (scenenameit=m_removingScenes.begin();scenenameit != m_removingScenes.end();scenenameit++)
1542 STR_String scenename = *scenenameit;
1544 KX_SceneList::iterator sceneit;
1545 for (sceneit = m_scenes.begin();sceneit != m_scenes.end() ; sceneit++)
1547 KX_Scene* scene = *sceneit;
1548 if (scene->GetName()==scenename)
1550 m_sceneconverter->RemoveScene(scene);
1551 m_scenes.erase(sceneit);
1556 m_removingScenes.clear();
1562 KX_Scene* KX_KetsjiEngine::CreateScene(const STR_String& scenename)
1564 Scene *scene = m_sceneconverter->GetBlenderSceneForName(scenename);
1565 KX_Scene* tmpscene = new KX_Scene(m_keyboarddevice,
1572 m_sceneconverter->ConvertScene(scenename,
1584 void KX_KetsjiEngine::AddScheduledScenes()
1586 set<STR_String>::iterator scenenameit;
1588 if (m_addingOverlayScenes.size())
1590 for (scenenameit = m_addingOverlayScenes.begin();
1591 scenenameit != m_addingOverlayScenes.end();
1594 STR_String scenename = *scenenameit;
1595 KX_Scene* tmpscene = CreateScene(scenename);
1596 m_scenes.push_back(tmpscene);
1597 PostProcessScene(tmpscene);
1599 m_addingOverlayScenes.clear();
1602 if (m_addingBackgroundScenes.size())
1604 for (scenenameit = m_addingBackgroundScenes.begin();
1605 scenenameit != m_addingBackgroundScenes.end();
1608 STR_String scenename = *scenenameit;
1609 KX_Scene* tmpscene = CreateScene(scenename);
1610 m_scenes.insert(m_scenes.begin(),tmpscene);
1611 PostProcessScene(tmpscene);
1614 m_addingBackgroundScenes.clear();
1620 void KX_KetsjiEngine::ReplaceScene(const STR_String& oldscene,const STR_String& newscene)
1622 m_replace_scenes.insert(std::make_pair(oldscene,newscene));
1625 // replace scene is not the same as removing and adding because the
1626 // scene must be in exact the same place (to maintain drawingorder)
1627 // (nzc) - should that not be done with a scene-display list? It seems
1628 // stupid to rely on the mem allocation order...
1629 void KX_KetsjiEngine::ReplaceScheduledScenes()
1631 if (m_replace_scenes.size())
1633 set<pair<STR_String,STR_String> >::iterator scenenameit;
1635 for (scenenameit = m_replace_scenes.begin();
1636 scenenameit != m_replace_scenes.end();
1639 STR_String oldscenename = (*scenenameit).first;
1640 STR_String newscenename = (*scenenameit).second;
1642 /* Scenes are not supposed to be included twice... I think */
1643 KX_SceneList::iterator sceneit;
1644 for (sceneit = m_scenes.begin();sceneit != m_scenes.end() ; sceneit++)
1646 KX_Scene* scene = *sceneit;
1647 if (scene->GetName() == oldscenename)
1649 m_sceneconverter->RemoveScene(scene);
1650 KX_Scene* tmpscene = CreateScene(newscenename);
1651 m_scenes[i]=tmpscene;
1652 PostProcessScene(tmpscene);
1657 m_replace_scenes.clear();
1663 void KX_KetsjiEngine::SuspendScene(const STR_String& scenename)
1665 KX_Scene* scene = FindScene(scenename);
1666 if (scene) scene->Suspend();
1671 void KX_KetsjiEngine::ResumeScene(const STR_String& scenename)
1673 KX_Scene* scene = FindScene(scenename);
1674 if (scene) scene->Resume();
1679 void KX_KetsjiEngine::SetUseFixedTime(bool bUseFixedTime)
1681 m_bFixedTime = bUseFixedTime;
1685 void KX_KetsjiEngine::SetGame2IpoMode(bool game2ipo,int startFrame)
1687 m_game2ipo = game2ipo;
1690 //when recording physics keyframes, always run at a fixed framerate
1691 m_bFixedTime = true;
1693 m_currentFrame = startFrame;
1696 bool KX_KetsjiEngine::GetUseFixedTime(void) const
1698 return m_bFixedTime;
1701 double KX_KetsjiEngine::GetSuspendedDelta()
1703 return m_suspendeddelta;
1706 double KX_KetsjiEngine::GetTicRate()
1711 void KX_KetsjiEngine::SetTicRate(double ticrate)
1713 m_ticrate = ticrate;
1716 double KX_KetsjiEngine::GetAnimFrameRate()
1718 return m_anim_framerate;
1721 double KX_KetsjiEngine::GetClockTime(void) const
1726 void KX_KetsjiEngine::SetAnimFrameRate(double framerate)
1728 m_anim_framerate = framerate;
1731 double KX_KetsjiEngine::GetAverageFrameRate()
1733 return m_average_framerate;
1736 void KX_KetsjiEngine::SetTimingDisplay(bool frameRate, bool profile, bool properties)
1738 m_show_framerate = frameRate;
1739 m_show_profile = profile;
1740 m_show_debug_properties = properties;
1745 void KX_KetsjiEngine::GetTimingDisplay(bool& frameRate, bool& profile, bool& properties) const
1747 frameRate = m_show_framerate;
1748 profile = m_show_profile;
1749 properties = m_show_debug_properties;
1754 void KX_KetsjiEngine::ProcessScheduledScenes(void)
1756 // Check whether there will be changes to the list of scenes
1757 if (m_addingOverlayScenes.size() ||
1758 m_addingBackgroundScenes.size() ||
1759 m_replace_scenes.size() ||
1760 m_removingScenes.size()) {
1762 // Change the scene list
1763 ReplaceScheduledScenes();
1764 RemoveScheduledScenes();
1765 AddScheduledScenes();
1768 SceneListsChanged();
1774 void KX_KetsjiEngine::SceneListsChanged(void)
1776 m_propertiesPresent = false;
1777 KX_SceneList::iterator sceneit = m_scenes.begin();
1778 while ((sceneit != m_scenes.end()) && (!m_propertiesPresent))
1780 KX_Scene* scene = *sceneit;
1781 vector<SCA_DebugProp*>& debugproplist = scene->GetDebugProperties();
1782 m_propertiesPresent = !debugproplist.empty();
1788 void KX_KetsjiEngine::SetHideCursor(bool hideCursor)
1790 m_hideCursor = hideCursor;
1794 bool KX_KetsjiEngine::GetHideCursor(void) const
1796 return m_hideCursor;
1800 void KX_KetsjiEngine::SetUseOverrideFrameColor(bool overrideFrameColor)
1802 m_overrideFrameColor = overrideFrameColor;
1806 bool KX_KetsjiEngine::GetUseOverrideFrameColor(void) const
1808 return m_overrideFrameColor;
1812 void KX_KetsjiEngine::SetOverrideFrameColor(float r, float g, float b)
1814 m_overrideFrameColorR = r;
1815 m_overrideFrameColorG = g;
1816 m_overrideFrameColorB = b;
1820 void KX_KetsjiEngine::GetOverrideFrameColor(float& r, float& g, float& b) const
1822 r = m_overrideFrameColorR;
1823 g = m_overrideFrameColorG;
1824 b = m_overrideFrameColorB;