//----------------------------------------------------------------------------- // Commander Map HUD // // Portions Copyright (c) GarageGames.Com // Copyright (c) Ben Garney //----------------------------------------------------------------------------- // These includes are probably overkill -- BJG #include "platform/platform.h" #include "platform/platformVideo.h" #include "platform/platformAudio.h" #include "platform/platformInput.h" #include "core/findMatch.h" #include "dgl/dgl.h" #include "game/game.h" #include "math/mMath.h" #include "console/simBase.h" #include "console/console.h" #include "terrain/terrData.h" #include "terrain/terrRender.h" #include "terrain/waterBlock.h" #include "game/collisionTest.h" #include "game/showTSShape.h" #include "sceneGraph/sceneGraph.h" #include "gui/guiTSControl.h" #include "game/moveManager.h" #include "console/consoleTypes.h" #include "game/shapeBase.h" #include "core/dnet.h" #include "game/gameConnection.h" #include "core/fileStream.h" #include "gui/guiCanvas.h" #include "dgl/gTexManager.h" #include "sceneGraph/sceneLighting.h" #include "terrain/sky.h" #include "game/ambientAudioManager.h" #include "sim/frameAllocator.h" #include "sceneGraph/detailManager.h" #include "gui/guiMLTextCtrl.h" #include "platform/profiler.h" #include "game/fx/underLava.h" //----------------------------------------------------------------------------- class GuiCommanderHud : public GuiTSCtrl { private: typedef GuiTSCtrl Parent; Point2F mPanSpeed; F32 mZoomSpeed; S32 mLastRenderTime; public: Point2F mPanGoal, mCurPan; F32 mZoomGoal, mCurZoom; GuiCommanderHud(); bool processCameraQuery(CameraQuery *query); void renderWorld(const RectI &updateRect); void onRender( Point2I, const RectI &); static void initPersistFields(); DECLARE_CONOBJECT( GuiCommanderHud ); }; //----------------------------------------------------------------------------- IMPLEMENT_CONOBJECT( GuiCommanderHud ); GuiCommanderHud::GuiCommanderHud() : mPanSpeed(10, 10), mZoomSpeed(1), mCurPan(0,0), mCurZoom(M_PI_F/2), mPanGoal(0,0), mZoomGoal(M_PI_F/2), mLastRenderTime(0) { } void GuiCommanderHud::initPersistFields() { Parent::initPersistFields(); addField("panSpeed", TypePoint2F, Offset(mPanSpeed, GuiCommanderHud), "Set the speed (x/y) we pan to our goal."); addField("zoomSpeed", TypeF32, Offset(mZoomSpeed, GuiCommanderHud), "Set the speed we zoom with to our goal."); } bool GuiCommanderHud::processCameraQuery(CameraQuery *q) { // Scale ranges based on the highest/lowest point in the terrain F32 maxHi = gClientSceneGraph->getCurrentTerrain()->findSquare(8, 0,0)->maxHeight / 10; F32 minHi = gClientSceneGraph->getCurrentTerrain()->findSquare(8, 0,0)->minHeight / 10; q->object = NULL; q->nearPlane = 1; q->farPlane = mFabs(maxHi) + mFabs(minHi); q->fov = mCurZoom; // Make us high up, facing straight down. q->cameraMatrix = MatrixF(EulerF(3.14/2, 0, 0)); // rotate us to look straight down q->cameraMatrix.setPosition(Point3F(mCurPan.x,mCurPan.y, maxHi + 100)); // and high enough we won't clip return true; } void GuiCommanderHud::renderWorld(const RectI &updateRect) { // Set up state TerrainRender::mRenderingCommander = true; F32 oldVisDist = gClientSceneGraph->getVisibleDistance(); gClientSceneGraph->setVisibleDistance(2000); F32 oldFogDist = gClientSceneGraph->getFogDistance(); gClientSceneGraph->setFogDistance(2000); // set up the camera and viewport stuff: // Render (stolen from GameRenderWorld) PROFILE_START(GameRenderCommanderWorld); FrameAllocator::setWaterMark(0); #if defined(GATHER_METRICS) && GATHER_METRICS > 1 TextureManager::smTextureCacheMisses = 0; #endif glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glClear(GL_DEPTH_BUFFER_BIT); glDisable(GL_CULL_FACE); glMatrixMode(GL_MODELVIEW); dglSetCanonicalState(); // If you want to render other things, change this mask. gClientSceneGraph->renderScene( EnvironmentObjectType | TerrainObjectType | InteriorObjectType | WaterObjectType ); glDisable(GL_DEPTH_TEST); #if defined(GATHER_METRICS) && GATHER_METRICS > 1 Con::setFloatVariable("Video::texResidentPercentage", TextureManager::getResidentFraction()); Con::setIntVariable("Video::textureCacheMisses", TextureManager::smTextureCacheMisses); #endif AssertFatal(FrameAllocator::getWaterMark() == 0, "Error, someone didn't reset the water mark on the frame allocator!"); FrameAllocator::setWaterMark(0); PROFILE_END(); // Restore state gClientSceneGraph->setVisibleDistance(oldVisDist); gClientSceneGraph->setFogDistance (oldFogDist); TerrainRender::mRenderingCommander = false; dglSetClipRect(updateRect); } void GuiCommanderHud::onRender(Point2I offset, const RectI &updateRect) { // Update pan/zoom S32 time = Platform::getVirtualMilliseconds(); S32 dt = time - mLastRenderTime; mLastRenderTime = time; mCurPan += (mPanGoal - mCurPan) * (F32)dt/1000.f; mCurZoom += (mZoomGoal - mCurZoom) * (F32)dt/1000.f; // Render the world... Parent::onRender(offset, updateRect); // If you wanted to render custom GUI elements, like a sensor map, icons for // players/vehicles/objectives, you would do it here by calling project() // for all their positions and drawing bitmaps at the appropriate locations. } ConsoleMethod(GuiCommanderHud, pan, void, 4, 4, "(x, y) Cut to a location.") { object->mPanGoal.set(dAtof(argv[2]), dAtof(argv[3])); object->mCurPan.set (dAtof(argv[2]), dAtof(argv[3])); } ConsoleMethod(GuiCommanderHud, panTo, void, 4, 4, "(x, y) Smoothly pan to a location.") { object->mPanGoal.set(dAtof(argv[2]), dAtof(argv[3])); } ConsoleMethod(GuiCommanderHud, zoom, void, 3, 3, "(val) Zoom to a specified level.") { object->mZoomGoal = dAtof(argv[2]); object->mCurZoom = dAtof(argv[2]); } ConsoleMethod(GuiCommanderHud, zoomTo, void, 3, 3, "(val) Smoothly zoom to a specified level.") { object->mZoomGoal = dAtof(argv[2]); } ConsoleMethod(GuiCommanderHud, zoomToArea, void, 6, 7, "(top, left, right, bottom, bool cut) Smoothly zoom to view the specified area. If cut is set, we jump there.") { // Parse arguments F32 top, left, right, bottom; top = dAtof(argv[2]); left = dAtof(argv[3]); right = dAtof(argv[4]); bottom = dAtof(argv[5]); // Figure out the center of the area Point2F center; center.x = (left + right) * 0.5f; center.y = (top + bottom) * 0.5f; object->mZoomGoal = mFabs(left - right) / 200; // Cheesy scaling fakery. // And set our motion object->mPanGoal = center; // Cut if requested if(argc > 6) if(dAtob(argv[6])) { object->mCurPan = object->mPanGoal; object->mCurZoom = object->mZoomGoal; } }