gameFunctions.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platform/platform.h"
  23. #include "T3D/gameFunctions.h"
  24. #include "T3D/gameBase/gameConnection.h"
  25. #include "T3D/camera.h"
  26. #include "T3D/sfx/sfx3DWorld.h"
  27. #include "console/consoleTypes.h"
  28. #include "gui/3d/guiTSControl.h"
  29. #include "core/util/journal/process.h"
  30. #include "materials/materialManager.h"
  31. #include "math/mEase.h"
  32. #include "core/module.h"
  33. #include "console/engineAPI.h"
  34. #include "platform/output/IDisplayDevice.h"
  35. #include "postFx/postEffectManager.h"
  36. #include "gfx/gfxTransformSaver.h"
  37. static void RegisterGameFunctions();
  38. static void Process3D();
  39. MODULE_BEGIN( 3D )
  40. MODULE_INIT_AFTER( Process )
  41. MODULE_INIT_AFTER( Scene )
  42. MODULE_SHUTDOWN_BEFORE( Process )
  43. MODULE_SHUTDOWN_BEFORE( Sim )
  44. MODULE_SHUTDOWN_BEFORE( Scene )
  45. MODULE_INIT
  46. {
  47. Process::notify(Process3D, PROCESS_TIME_ORDER);
  48. GameConnection::smFovUpdate.notify(GameSetCameraFov);
  49. RegisterGameFunctions();
  50. }
  51. MODULE_SHUTDOWN
  52. {
  53. GameConnection::smFovUpdate.remove(GameSetCameraFov);
  54. Process::remove(Process3D);
  55. }
  56. MODULE_END;
  57. static S32 gEaseInOut = Ease::InOut;
  58. static S32 gEaseIn = Ease::In;
  59. static S32 gEaseOut = Ease::Out;
  60. static S32 gEaseLinear = Ease::Linear;
  61. static S32 gEaseQuadratic= Ease::Quadratic;
  62. static S32 gEaseCubic= Ease::Cubic;
  63. static S32 gEaseQuartic = Ease::Quartic;
  64. static S32 gEaseQuintic = Ease::Quintic;
  65. static S32 gEaseSinusoidal= Ease::Sinusoidal;
  66. static S32 gEaseExponential = Ease::Exponential;
  67. static S32 gEaseCircular = Ease::Circular;
  68. static S32 gEaseElastic = Ease::Elastic;
  69. static S32 gEaseBack = Ease::Back;
  70. static S32 gEaseBounce = Ease::Bounce;
  71. extern bool gEditingMission;
  72. extern void ShowInit();
  73. //------------------------------------------------------------------------------
  74. /// Camera and FOV info
  75. namespace CameraAndFOV{
  76. const U32 MaxZoomSpeed = 2000; ///< max number of ms to reach target FOV
  77. static F32 sConsoleCameraFov = 90.f; ///< updated to camera FOV each frame
  78. static F32 sDefaultFov = 90.f; ///< normal FOV
  79. static F32 sCameraFov = 90.f; ///< current camera FOV
  80. static F32 sTargetFov = 90.f; ///< the desired FOV
  81. static F32 sLastCameraUpdateTime = 0; ///< last time camera was updated
  82. static S32 sZoomSpeed = 500; ///< ms per 90deg fov change
  83. /// A scale to apply to the normal visible distance
  84. /// typically used for tuning performance.
  85. static F32 sVisDistanceScale = 1.0f;
  86. } // namespace {}
  87. // query
  88. static SimpleQueryList sgServerQueryList;
  89. static U32 sgServerQueryIndex = 0;
  90. //SERVER FUNCTIONS ONLY
  91. ConsoleFunctionGroupBegin( Containers, "Spatial query functions. <b>Server side only!</b>");
  92. DefineEngineFunction( containerFindFirst, const char*, (U32 typeMask, Point3F origin, Point3F size), , "(int mask, Point3F point, float x, float y, float z)"
  93. "@brief Find objects matching the bitmask type within a box centered at point, with extents x, y, z.\n\n"
  94. "@returns The first object found, or an empty string if nothing was found. Thereafter, you can get more "
  95. "results using containerFindNext()."
  96. "@see containerFindNext\n"
  97. "@ingroup Game")
  98. {
  99. //find out what we're looking for
  100. //build the container volume
  101. Box3F queryBox;
  102. queryBox.minExtents = origin;
  103. queryBox.maxExtents = origin;
  104. queryBox.minExtents -= size;
  105. queryBox.maxExtents += size;
  106. //initialize the list, and do the query
  107. sgServerQueryList.mList.clear();
  108. gServerContainer.findObjects(queryBox, typeMask, SimpleQueryList::insertionCallback, &sgServerQueryList);
  109. //return the first element
  110. sgServerQueryIndex = 0;
  111. static const U32 bufSize = 100;
  112. char *buff = Con::getReturnBuffer(bufSize);
  113. if (sgServerQueryList.mList.size())
  114. dSprintf(buff, bufSize, "%d", sgServerQueryList.mList[sgServerQueryIndex++]->getId());
  115. else
  116. buff[0] = '\0';
  117. return buff;
  118. }
  119. DefineEngineFunction( containerFindNext, const char*, (), , "()"
  120. "@brief Get more results from a previous call to containerFindFirst().\n\n"
  121. "@note You must call containerFindFirst() to begin the search.\n"
  122. "@returns The next object found, or an empty string if nothing else was found.\n"
  123. "@see containerFindFirst()\n"
  124. "@ingroup Game")
  125. {
  126. //return the next element
  127. static const U32 bufSize = 100;
  128. char *buff = Con::getReturnBuffer(bufSize);
  129. if (sgServerQueryIndex < sgServerQueryList.mList.size())
  130. dSprintf(buff, bufSize, "%d", sgServerQueryList.mList[sgServerQueryIndex++]->getId());
  131. else
  132. buff[0] = '\0';
  133. return buff;
  134. }
  135. ConsoleFunctionGroupEnd( Containers );
  136. //------------------------------------------------------------------------------
  137. bool GameGetCameraTransform(MatrixF *mat, Point3F *velocity)
  138. {
  139. // Return the position and velocity of the control object
  140. GameConnection* connection = GameConnection::getConnectionToServer();
  141. return connection && connection->getControlCameraTransform(0, mat) &&
  142. connection->getControlCameraVelocity(velocity);
  143. }
  144. //------------------------------------------------------------------------------
  145. DefineEngineFunction( setDefaultFov, void, ( F32 defaultFOV ),,
  146. "@brief Set the default FOV for a camera.\n"
  147. "@param defaultFOV The default field of view in degrees\n"
  148. "@ingroup CameraSystem")
  149. {
  150. CameraAndFOV::sDefaultFov = mClampF(defaultFOV, MinCameraFov, MaxCameraFov);
  151. if(CameraAndFOV::sCameraFov == CameraAndFOV::sTargetFov)
  152. CameraAndFOV::sTargetFov = CameraAndFOV::sDefaultFov;
  153. }
  154. DefineEngineFunction( setZoomSpeed, void, ( S32 speed ),,
  155. "@brief Set the zoom speed of the camera.\n"
  156. "This affects how quickly the camera changes from one field of view "
  157. "to another.\n"
  158. "@param speed The camera's zoom speed in ms per 90deg FOV change\n"
  159. "@ingroup CameraSystem")
  160. {
  161. CameraAndFOV::sZoomSpeed = mClamp(speed, 0, CameraAndFOV::MaxZoomSpeed);
  162. }
  163. DefineEngineFunction( setFov, void, ( F32 FOV ),,
  164. "@brief Set the FOV of the camera.\n"
  165. "@param FOV The camera's new FOV in degrees\n"
  166. "@ingroup CameraSystem")
  167. {
  168. CameraAndFOV::sTargetFov = mClampF(FOV, MinCameraFov, MaxCameraFov);
  169. }
  170. F32 GameGetCameraFov()
  171. {
  172. return(CameraAndFOV::sCameraFov);
  173. }
  174. void GameSetCameraFov(F32 fov)
  175. {
  176. CameraAndFOV::sTargetFov = CameraAndFOV::sCameraFov = fov;
  177. }
  178. void GameSetCameraTargetFov(F32 fov)
  179. {
  180. CameraAndFOV::sTargetFov = fov;
  181. }
  182. void GameUpdateCameraFov()
  183. {
  184. F32 time = F32(Platform::getVirtualMilliseconds());
  185. // need to update fov?
  186. if(CameraAndFOV::sTargetFov != CameraAndFOV::sCameraFov)
  187. {
  188. F32 delta = time - CameraAndFOV::sLastCameraUpdateTime;
  189. // snap zoom?
  190. if((CameraAndFOV::sZoomSpeed == 0) || (delta <= 0.0f))
  191. CameraAndFOV::sCameraFov = CameraAndFOV::sTargetFov;
  192. else
  193. {
  194. // gZoomSpeed is time in ms to zoom 90deg
  195. F32 step = 90.f * (delta / F32(CameraAndFOV::sZoomSpeed));
  196. if(CameraAndFOV::sCameraFov > CameraAndFOV::sTargetFov)
  197. {
  198. CameraAndFOV::sCameraFov -= step;
  199. if(CameraAndFOV::sCameraFov < CameraAndFOV::sTargetFov)
  200. CameraAndFOV::sCameraFov = CameraAndFOV::sTargetFov;
  201. }
  202. else
  203. {
  204. CameraAndFOV::sCameraFov += step;
  205. if(CameraAndFOV::sCameraFov > CameraAndFOV::sTargetFov)
  206. CameraAndFOV::sCameraFov = CameraAndFOV::sTargetFov;
  207. }
  208. }
  209. }
  210. // the game connection controls the vertical and the horizontal
  211. GameConnection * connection = GameConnection::getConnectionToServer();
  212. if(connection)
  213. {
  214. // check if fov is valid on control object
  215. if(connection->isValidControlCameraFov(CameraAndFOV::sCameraFov))
  216. connection->setControlCameraFov(CameraAndFOV::sCameraFov);
  217. else
  218. {
  219. // will set to the closest fov (fails only on invalid control object)
  220. if(connection->setControlCameraFov(CameraAndFOV::sCameraFov))
  221. {
  222. F32 setFov = CameraAndFOV::sCameraFov;
  223. connection->getControlCameraFov(&setFov);
  224. CameraAndFOV::sTargetFov =CameraAndFOV::sCameraFov = setFov;
  225. }
  226. }
  227. }
  228. // update the console variable
  229. CameraAndFOV::sConsoleCameraFov = CameraAndFOV::sCameraFov;
  230. CameraAndFOV::sLastCameraUpdateTime = time;
  231. }
  232. //--------------------------------------------------------------------------
  233. #ifdef TORQUE_DEBUG
  234. // ConsoleFunction(dumpTSShapes, void, 1, 1, "dumpTSShapes();")
  235. // {
  236. // argc, argv;
  237. // FindMatch match("*.dts", 4096);
  238. // gResourceManager->findMatches(&match);
  239. // for (U32 i = 0; i < match.numMatches(); i++)
  240. // {
  241. // U32 j;
  242. // Resource<TSShape> shape = ResourceManager::get().load(match.matchList[i]);
  243. // if (bool(shape) == false)
  244. // Con::errorf(" aaa Couldn't load: %s", match.matchList[i]);
  245. // U32 numMeshes = 0, numSkins = 0;
  246. // for (j = 0; j < shape->meshes.size(); j++)
  247. // if (shape->meshes[j])
  248. // numMeshes++;
  249. // for (j = 0; j < shape->skins.size(); j++)
  250. // if (shape->skins[j])
  251. // numSkins++;
  252. // Con::printf(" aaa Shape: %s (%d meshes, %d skins)", match.matchList[i], numMeshes, numSkins);
  253. // Con::printf(" aaa Meshes");
  254. // for (j = 0; j < shape->meshes.size(); j++)
  255. // {
  256. // if (shape->meshes[j])
  257. // Con::printf(" aaa %d -> nf: %d, nmf: %d, nvpf: %d (%d, %d, %d, %d, %d)",
  258. // shape->meshes[j]->meshType & TSMesh::TypeMask,
  259. // shape->meshes[j]->numFrames,
  260. // shape->meshes[j]->numMatFrames,
  261. // shape->meshes[j]->vertsPerFrame,
  262. // shape->meshes[j]->verts.size(),
  263. // shape->meshes[j]->norms.size(),
  264. // shape->meshes[j]->tverts.size(),
  265. // shape->meshes[j]->primitives.size(),
  266. // shape->meshes[j]->indices.size());
  267. // }
  268. // Con::printf(" aaa Skins");
  269. // for (j = 0; j < shape->skins.size(); j++)
  270. // {
  271. // if (shape->skins[j])
  272. // Con::printf(" aaa %d -> nf: %d, nmf: %d, nvpf: %d (%d, %d, %d, %d, %d)",
  273. // shape->skins[j]->meshType & TSMesh::TypeMask,
  274. // shape->skins[j]->numFrames,
  275. // shape->skins[j]->numMatFrames,
  276. // shape->skins[j]->vertsPerFrame,
  277. // shape->skins[j]->verts.size(),
  278. // shape->skins[j]->norms.size(),
  279. // shape->skins[j]->tverts.size(),
  280. // shape->skins[j]->primitives.size(),
  281. // shape->skins[j]->indices.size());
  282. // }
  283. // }
  284. // }
  285. #endif
  286. bool GameProcessCameraQuery(CameraQuery *query)
  287. {
  288. GameConnection* connection = GameConnection::getConnectionToServer();
  289. if (connection && connection->getControlCameraTransform(0.032f, &query->cameraMatrix))
  290. {
  291. query->object = dynamic_cast<GameBase*>(connection->getCameraObject());
  292. query->nearPlane = gClientSceneGraph->getNearClip();
  293. // Scale the normal visible distance by the performance
  294. // tuning scale which we never let over 1.
  295. CameraAndFOV::sVisDistanceScale = mClampF( CameraAndFOV::sVisDistanceScale, 0.01f, 1.0f );
  296. query->farPlane = gClientSceneGraph->getVisibleDistance() * CameraAndFOV::sVisDistanceScale;
  297. // Provide some default values
  298. query->stereoTargets[0] = 0;
  299. query->stereoTargets[1] = 0;
  300. query->eyeOffset[0] = Point3F::Zero;
  301. query->eyeOffset[1] = Point3F::Zero;
  302. query->hasFovPort = false;
  303. query->hasStereoTargets = false;
  304. query->displayDevice = NULL;
  305. F32 cameraFov = 0.0f;
  306. bool fovSet = false;
  307. // Try to use the connection's display deivce, if any, but only if the editor
  308. // is not open
  309. if(!gEditingMission && connection->hasDisplayDevice())
  310. {
  311. IDisplayDevice* display = connection->getDisplayDevice();
  312. query->displayDevice = display;
  313. // Note: all eye values are invalid until this is called
  314. display->setDrawCanvas(query->drawCanvas);
  315. display->setCurrentConnection(connection);
  316. // Display may activate AFTER so we need to call this again just in case
  317. display->onStartFrame();
  318. // The connection's display device may want to set the eye offset
  319. if(display->providesEyeOffsets())
  320. {
  321. display->getEyeOffsets(query->eyeOffset);
  322. }
  323. // Grab field of view for both eyes
  324. if (display->providesFovPorts())
  325. {
  326. display->getFovPorts(query->fovPort);
  327. fovSet = true;
  328. query->hasFovPort = true;
  329. }
  330. // Grab the latest overriding render view transforms
  331. connection->getControlCameraEyeTransforms(display, query->eyeTransforms);
  332. connection->getControlCameraHeadTransform(display, &query->headMatrix);
  333. display->getStereoViewports(query->stereoViewports);
  334. display->getStereoTargets(query->stereoTargets);
  335. query->hasStereoTargets = true;
  336. }
  337. else
  338. {
  339. query->eyeTransforms[0] = query->cameraMatrix;
  340. query->eyeTransforms[1] = query->cameraMatrix;
  341. query->headMatrix = query->cameraMatrix;
  342. }
  343. // Use the connection's FOV settings if requried
  344. if(!connection->getControlCameraFov(&cameraFov))
  345. {
  346. return false;
  347. }
  348. query->fov = mDegToRad(cameraFov);
  349. return true;
  350. }
  351. return false;
  352. }
  353. void GameRenderWorld()
  354. {
  355. PROFILE_START(GameRenderWorld);
  356. FrameAllocator::setWaterMark(0);
  357. gClientSceneGraph->renderScene( SPT_Diffuse );
  358. // renderScene leaves some states dirty, which causes problems if GameTSCtrl is the last Gui object rendered
  359. GFX->updateStates();
  360. AssertFatal(FrameAllocator::getWaterMark() == 0,
  361. "Error, someone didn't reset the water mark on the frame allocator!");
  362. FrameAllocator::setWaterMark(0);
  363. PROFILE_END();
  364. }
  365. //================================================================================================
  366. //Render a full frame from a given transform and frustum, and render out to a target
  367. //================================================================================================
  368. void renderFrame(GFXTextureTargetRef* target, MatrixF transform, Frustum frustum, U32 typeMask, ColorI canvasClearColor)
  369. {
  370. if (!GFX->allowRender() || GFX->canCurrentlyRender())
  371. return;
  372. PROFILE_START(GameFunctions_RenderFrame);
  373. GFX->setActiveRenderTarget(*target);
  374. if (!GFX->getActiveRenderTarget())
  375. return;
  376. GFXTarget* renderTarget = GFX->getActiveRenderTarget();
  377. if (renderTarget == NULL)
  378. return;
  379. // Make sure the root control is the size of the canvas.
  380. Point2I size = renderTarget->getSize();
  381. if (size.x == 0 || size.y == 0)
  382. return;
  383. //Now, getting to the meat of it!
  384. #ifdef TORQUE_GFX_STATE_DEBUG
  385. GFX->getDebugStateManager()->startFrame();
  386. #endif
  387. RectI targetRect(0, 0, size.x, size.y);
  388. // Signal the interested parties.
  389. GuiCanvas::getGuiCanvasFrameSignal().trigger(true);
  390. GFXTransformSaver saver;
  391. // Gross hack to make sure we don't end up with advanced lighting and msaa
  392. // at the same time, which causes artifacts. At the same time we don't
  393. // want to just throw the settings the user has chosen if the light manager
  394. // changes at a later time.
  395. /*GFXVideoMode mode = mPlatformWindow->getVideoMode();
  396. if (dStricmp(LIGHTMGR->getId(), "ADVLM") == 0 && mode.antialiasLevel > 0)
  397. {
  398. const char *pref = Con::getVariable("$pref::Video::mode");
  399. mode.parseFromString(pref);
  400. mode.antialiasLevel = 0;
  401. mPlatformWindow->setVideoMode(mode);
  402. Con::printf("AntiAliasing has been disabled; it is not compatible with AdvancedLighting.");
  403. }
  404. else if (dStricmp(LIGHTMGR->getId(), "BLM") == 0)
  405. {
  406. const char *pref = Con::getVariable("$pref::Video::mode");
  407. U32 prefAA = dAtoi(StringUnit::getUnit(pref, 5, " "));
  408. if (prefAA != mode.antialiasLevel)
  409. {
  410. mode.parseFromString(pref);
  411. mPlatformWindow->setVideoMode(mode);
  412. Con::printf("AntiAliasing has been enabled while running BasicLighting.");
  413. }
  414. }*/
  415. // Begin GFX
  416. PROFILE_START(GameFunctions_RenderFrame_GFXBeginScene);
  417. bool beginSceneRes = GFX->beginScene();
  418. PROFILE_END();
  419. PROFILE_START(GameFunctions_RenderFrame_OffscreenCanvases);
  420. // Render all offscreen canvas objects here since we may need them in the render loop
  421. if (GuiOffscreenCanvas::sList.size() != 0)
  422. {
  423. // Reset the entire state since oculus shit will have barfed it.
  424. GFX->updateStates(true);
  425. for (Vector<GuiOffscreenCanvas*>::iterator itr = GuiOffscreenCanvas::sList.begin(); itr != GuiOffscreenCanvas::sList.end(); itr++)
  426. {
  427. (*itr)->renderFrame(false, false);
  428. }
  429. GFX->setActiveRenderTarget(renderTarget);
  430. }
  431. PROFILE_END();
  432. // Can't render if waiting for device to reset.
  433. if (!beginSceneRes)
  434. {
  435. // Since we already triggered the signal once for begin-of-frame,
  436. // we should be consistent and trigger it again for end-of-frame.
  437. GuiCanvas::getGuiCanvasFrameSignal().trigger(false);
  438. return;
  439. }
  440. // Clear the current viewport area
  441. GFX->setViewport(targetRect);
  442. GFX->clear(GFXClearZBuffer | GFXClearStencil | GFXClearTarget, canvasClearColor, 1.0f, 0);
  443. // Make sure we have a clean matrix state
  444. // before we start rendering anything!
  445. GFX->setWorldMatrix(MatrixF::Identity);
  446. GFX->setViewMatrix(MatrixF::Identity);
  447. GFX->setProjectionMatrix(MatrixF::Identity);
  448. {
  449. GFXStateBlockDesc d;
  450. d.cullDefined = true;
  451. d.cullMode = GFXCullNone;
  452. d.zDefined = true;
  453. d.zEnable = false;
  454. GFXStateBlockRef mDefaultGuiSB = GFX->createStateBlock(d);
  455. GFX->setClipRect(targetRect);
  456. GFX->setStateBlock(mDefaultGuiSB);
  457. GFXTargetRef origTarget = GFX->getActiveRenderTarget();
  458. // Clear the zBuffer so GUI doesn't hose object rendering accidentally
  459. GFX->clear(GFXClearZBuffer, ColorI(20, 20, 20), 1.0f, 0);
  460. GFX->setFrustum(frustum);
  461. MatrixF mSaveProjection = GFX->getProjectionMatrix();
  462. // We're going to be displaying this render at size of this control in
  463. // pixels - let the scene know so that it can calculate e.g. reflections
  464. // correctly for that final display result.
  465. gClientSceneGraph->setDisplayTargetResolution(size);
  466. // Set the GFX world matrix to the world-to-camera transform, but don't
  467. // change the cameraMatrix in mLastCameraQuery. This is because
  468. // mLastCameraQuery.cameraMatrix is supposed to contain the camera-to-world
  469. // transform. In-place invert would save a copy but mess up any GUIs that
  470. // depend on that value.
  471. CameraQuery camera;
  472. GameProcessCameraQuery(&camera);
  473. MatrixF worldToCamera = transform;
  474. RotationF tranRot = RotationF(transform);
  475. EulerF trf = tranRot.asEulerF(RotationF::Degrees);
  476. Point3F pos = transform.getPosition();
  477. GFX->setWorldMatrix(worldToCamera);
  478. mSaveProjection = GFX->getProjectionMatrix();
  479. MatrixF mSaveModelview = GFX->getWorldMatrix();
  480. Point2F mSaveWorldToScreenScale = GFX->getWorldToScreenScale();
  481. Frustum mSaveFrustum = GFX->getFrustum();
  482. mSaveFrustum.setTransform(transform);
  483. // Set the default non-clip projection as some
  484. // objects depend on this even in non-reflect cases.
  485. gClientSceneGraph->setNonClipProjection(mSaveProjection);
  486. // Give the post effect manager the worldToCamera, and cameraToScreen matrices
  487. PFXMGR->setFrameMatrices(mSaveModelview, mSaveProjection);
  488. //renderWorld(guiViewport);
  489. PROFILE_START(GameFunctions_RenderFrame_RenderWorld);
  490. FrameAllocator::setWaterMark(0);
  491. gClientSceneGraph->renderScene(SPT_Reflect, typeMask);
  492. // renderScene leaves some states dirty, which causes problems if GameTSCtrl is the last Gui object rendered
  493. GFX->updateStates();
  494. AssertFatal(FrameAllocator::getWaterMark() == 0,
  495. "Error, someone didn't reset the water mark on the frame allocator!");
  496. FrameAllocator::setWaterMark(0);
  497. PROFILE_END();
  498. }
  499. PROFILE_START(GameFunctions_RenderFrame_GFXEndScene);
  500. GFX->endScene();
  501. PROFILE_END();
  502. #ifdef TORQUE_GFX_STATE_DEBUG
  503. GFX->getDebugStateManager()->endFrame();
  504. #endif
  505. saver.restore();
  506. PROFILE_END();
  507. }
  508. //================================================================================================
  509. static void Process3D()
  510. {
  511. MATMGR->updateTime();
  512. // Update the SFX world, if there is one.
  513. if( gSFX3DWorld )
  514. gSFX3DWorld->update();
  515. }
  516. static void RegisterGameFunctions()
  517. {
  518. Con::addVariable( "$pref::Camera::distanceScale", TypeF32, &CameraAndFOV::sVisDistanceScale,
  519. "A scale to apply to the normal visible distance, typically used for tuning performance.\n"
  520. "@ingroup Game");
  521. Con::addVariable( "$cameraFov", TypeF32, &CameraAndFOV::sConsoleCameraFov,
  522. "The camera's Field of View.\n\n"
  523. "@ingroup Game" );
  524. // Stuff game types into the console
  525. Con::setIntVariable("$TypeMasks::StaticObjectType", StaticObjectType);
  526. Con::setIntVariable("$TypeMasks::EnvironmentObjectType", EnvironmentObjectType);
  527. Con::setIntVariable("$TypeMasks::TerrainObjectType", TerrainObjectType);
  528. Con::setIntVariable("$TypeMasks::WaterObjectType", WaterObjectType);
  529. Con::setIntVariable("$TypeMasks::TriggerObjectType", TriggerObjectType);
  530. Con::setIntVariable("$TypeMasks::MarkerObjectType", MarkerObjectType);
  531. Con::setIntVariable("$TypeMasks::GameBaseObjectType", GameBaseObjectType);
  532. Con::setIntVariable("$TypeMasks::ShapeBaseObjectType", ShapeBaseObjectType);
  533. Con::setIntVariable("$TypeMasks::CameraObjectType", CameraObjectType);
  534. Con::setIntVariable("$TypeMasks::StaticShapeObjectType", StaticShapeObjectType);
  535. Con::setIntVariable("$TypeMasks::DynamicShapeObjectType", DynamicShapeObjectType);
  536. Con::setIntVariable("$TypeMasks::PlayerObjectType", PlayerObjectType);
  537. Con::setIntVariable("$TypeMasks::ItemObjectType", ItemObjectType);
  538. Con::setIntVariable("$TypeMasks::VehicleObjectType", VehicleObjectType);
  539. Con::setIntVariable("$TypeMasks::VehicleBlockerObjectType", VehicleBlockerObjectType);
  540. Con::setIntVariable("$TypeMasks::ProjectileObjectType", ProjectileObjectType);
  541. Con::setIntVariable("$TypeMasks::ExplosionObjectType", ExplosionObjectType);
  542. Con::setIntVariable("$TypeMasks::CorpseObjectType", CorpseObjectType);
  543. Con::setIntVariable("$TypeMasks::DebrisObjectType", DebrisObjectType);
  544. Con::setIntVariable("$TypeMasks::PhysicalZoneObjectType", PhysicalZoneObjectType);
  545. Con::setIntVariable("$TypeMasks::LightObjectType", LightObjectType);
  546. // PATHSHAPE
  547. Con::setIntVariable("$TypeMasks::PathShapeObjectType", PathShapeObjectType);
  548. // PATHSHAPE END
  549. Con::setIntVariable("$TypeMasks::TurretObjectType", TurretObjectType);
  550. Con::addVariable("Ease::InOut", TypeS32, &gEaseInOut,
  551. "InOut ease for curve movement.\n"
  552. "@ingroup Game");
  553. Con::addVariable("Ease::In", TypeS32, &gEaseIn,
  554. "In ease for curve movement.\n"
  555. "@ingroup Game");
  556. Con::addVariable("Ease::Out", TypeS32, &gEaseOut,
  557. "Out ease for curve movement.\n"
  558. "@ingroup Game");
  559. Con::addVariable("Ease::Linear", TypeS32, &gEaseLinear,
  560. "Linear ease for curve movement.\n"
  561. "@ingroup Game");
  562. Con::addVariable("Ease::Quadratic", TypeS32, &gEaseQuadratic,
  563. "Quadratic ease for curve movement.\n"
  564. "@ingroup Game");
  565. Con::addVariable("Ease::Cubic", TypeS32, &gEaseCubic,
  566. "Cubic ease for curve movement.\n"
  567. "@ingroup Game");
  568. Con::addVariable("Ease::Quartic", TypeS32, &gEaseQuartic,
  569. "Quartic ease for curve movement.\n"
  570. "@ingroup Game");
  571. Con::addVariable("Ease::Quintic", TypeS32, &gEaseQuintic,
  572. "Quintic ease for curve movement.\n"
  573. "@ingroup Game");
  574. Con::addVariable("Ease::Sinusoidal", TypeS32, &gEaseSinusoidal,
  575. "Sinusoidal ease for curve movement.\n"
  576. "@ingroup Game");
  577. Con::addVariable("Ease::Exponential", TypeS32, &gEaseExponential,
  578. "Exponential ease for curve movement.\n"
  579. "@ingroup Game");
  580. Con::addVariable("Ease::Circular", TypeS32, &gEaseCircular,
  581. "Circular ease for curve movement.\n"
  582. "@ingroup Game");
  583. Con::addVariable("Ease::Elastic", TypeS32, &gEaseElastic,
  584. "Elastic ease for curve movement.\n"
  585. "@ingroup Game");
  586. Con::addVariable("Ease::Back", TypeS32, &gEaseBack,
  587. "Backwards ease for curve movement.\n"
  588. "@ingroup Game");
  589. Con::addVariable("Ease::Bounce", TypeS32, &gEaseBounce,
  590. "Bounce ease for curve movement.\n"
  591. "@ingroup Game");
  592. }