mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-19 20:24:49 +00:00
Merge pull request #1500 from marauder2k9-torque/MissionArea-RemoveTerrainDependency
remove terrain dependency from mission area
This commit is contained in:
commit
0aaddcddb4
|
|
@ -51,7 +51,7 @@ ConsoleDocClass( MissionArea,
|
|||
"@ingroup enviroMisc\n"
|
||||
);
|
||||
|
||||
RectI MissionArea::smMissionArea(Point2I(768, 768), Point2I(512, 512));
|
||||
RectI MissionArea::smMissionArea(Point2I(-100, -100), Point2I(100, 100));
|
||||
|
||||
MissionArea * MissionArea::smServerObject = NULL;
|
||||
|
||||
|
|
@ -59,7 +59,7 @@ MissionArea * MissionArea::smServerObject = NULL;
|
|||
|
||||
MissionArea::MissionArea()
|
||||
{
|
||||
mArea.set(Point2I(768, 768), Point2I(512, 512));
|
||||
mArea.set(Point2I(-100, -100), Point2I(100, 100));
|
||||
mNetFlags.set(Ghostable | ScopeAlways);
|
||||
|
||||
mFlightCeiling = 2000;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,13 @@
|
|||
#include "gui/3d/guiTSControl.h"
|
||||
#include "T3D/gameFunctions.h"
|
||||
#include "terrain/terrData.h"
|
||||
#include "gfx/gfxTransformSaver.h"
|
||||
#include "scene/sceneManager.h"
|
||||
#include "scene/sceneRenderState.h"
|
||||
#include "lighting/lightManager.h"
|
||||
#include "lighting/shadowMap/lightShadowMap.h"
|
||||
#include "math/mathUtils.h"
|
||||
#include "math/util/frustum.h"
|
||||
|
||||
namespace {
|
||||
F32 round_local(F32 val)
|
||||
|
|
@ -65,7 +72,8 @@ GuiMissionAreaCtrl::GuiMissionAreaCtrl()
|
|||
mSquareBitmap = true;
|
||||
|
||||
mMissionArea = 0;
|
||||
mTerrainBlock = 0;
|
||||
mLevelTexture = NULL;
|
||||
mLevelBounds = Box3F::Zero;
|
||||
|
||||
mMissionBoundsColor.set(255,0,0);
|
||||
mCameraColor.set(255,0,0);
|
||||
|
|
@ -75,6 +83,8 @@ GuiMissionAreaCtrl::GuiMissionAreaCtrl()
|
|||
|
||||
mLastHitMode = Handle_None;
|
||||
mSavedDrag = false;
|
||||
|
||||
mBitmap.set(256, 256, GFXFormatR8G8B8, &GFXRenderTargetProfile, "MissionAreaRenderTarget");
|
||||
}
|
||||
|
||||
GuiMissionAreaCtrl::~GuiMissionAreaCtrl()
|
||||
|
|
@ -131,19 +141,6 @@ bool GuiMissionAreaCtrl::onWake()
|
|||
if(!Parent::onWake())
|
||||
return(false);
|
||||
|
||||
//mMissionArea = const_cast<MissionArea*>(MissionArea::getServerObject());
|
||||
//if(!bool(mMissionArea))
|
||||
// Con::warnf(ConsoleLogEntry::General, "GuiMissionAreaCtrl::onWake: no MissionArea object.");
|
||||
|
||||
//mTerrainBlock = getTerrainObj();
|
||||
//if(!bool(mTerrainBlock))
|
||||
// Con::warnf(ConsoleLogEntry::General, "GuiMissionAreaCtrl::onWake: no TerrainBlock object.");
|
||||
|
||||
//if ( !bool(mMissionArea) || !bool(mTerrainBlock) )
|
||||
// return true;
|
||||
|
||||
updateTerrainBitmap();
|
||||
|
||||
// make sure mission area is clamped
|
||||
setArea(getArea());
|
||||
|
||||
|
|
@ -157,7 +154,6 @@ void GuiMissionAreaCtrl::onSleep()
|
|||
{
|
||||
mBitmap = NULL;
|
||||
mMissionArea = 0;
|
||||
mTerrainBlock = 0;
|
||||
|
||||
Parent::onSleep();
|
||||
}
|
||||
|
|
@ -169,6 +165,11 @@ void GuiMissionAreaCtrl::onMouseUp(const GuiEvent & event)
|
|||
if(!bool(mMissionArea))
|
||||
return;
|
||||
|
||||
//unlock the mouse
|
||||
mouseUnlock();
|
||||
|
||||
mLastMousePoint = event.mousePoint;
|
||||
|
||||
RectI box;
|
||||
getScreenMissionArea(box);
|
||||
S32 hit = getHitHandles(event.mousePoint, box);
|
||||
|
|
@ -190,6 +191,11 @@ void GuiMissionAreaCtrl::onMouseDown(const GuiEvent & event)
|
|||
if(!bool(mMissionArea))
|
||||
return;
|
||||
|
||||
setFirstResponder();
|
||||
|
||||
// lock mouse
|
||||
mouseLock();
|
||||
|
||||
RectI box;
|
||||
getScreenMissionArea(box);
|
||||
|
||||
|
|
@ -319,71 +325,6 @@ void GuiMissionAreaCtrl::submitUndo( const UTF8 *name )
|
|||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void GuiMissionAreaCtrl::updateTerrain()
|
||||
{
|
||||
mTerrainBlock = getTerrainObj();
|
||||
updateTerrainBitmap();
|
||||
}
|
||||
|
||||
TerrainBlock * GuiMissionAreaCtrl::getTerrainObj()
|
||||
{
|
||||
SimSet * scopeAlwaysSet = Sim::getGhostAlwaysSet();
|
||||
for(SimSet::iterator itr = scopeAlwaysSet->begin(); itr != scopeAlwaysSet->end(); itr++)
|
||||
{
|
||||
TerrainBlock * terrain = dynamic_cast<TerrainBlock*>(*itr);
|
||||
if(terrain)
|
||||
return(terrain);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
void GuiMissionAreaCtrl::updateTerrainBitmap()
|
||||
{
|
||||
GBitmap * bitmap = createTerrainBitmap();
|
||||
if( bitmap )
|
||||
setBitmapHandle( GFXTexHandle( bitmap, &GFXDefaultGUIProfile, true, String("Terrain Bitmap Update") ) );
|
||||
else
|
||||
setBitmap( "" );
|
||||
}
|
||||
|
||||
GBitmap * GuiMissionAreaCtrl::createTerrainBitmap()
|
||||
{
|
||||
if(!mTerrainBlock)
|
||||
return NULL;
|
||||
|
||||
GBitmap * bitmap = new GBitmap(mTerrainBlock->getBlockSize(), mTerrainBlock->getBlockSize(), false, GFXFormatR8G8B8 );
|
||||
|
||||
// get the min/max
|
||||
F32 min, max;
|
||||
mTerrainBlock->getMinMaxHeight(&min, &max);
|
||||
|
||||
F32 diff = max - min;
|
||||
F32 colRange = 255.0f / diff;
|
||||
|
||||
// This method allocates it's bitmap above, and does all assignment
|
||||
// in the following loop. It is not subject to 24-bit -> 32-bit conversion
|
||||
// problems, because the texture handle creation is where the conversion would
|
||||
// occur, if it occurs. Since the data in the texture is never read back, and
|
||||
// the bitmap is deleted after texture-upload, this is not a problem.
|
||||
for(S32 y = 0; y < mTerrainBlock->getBlockSize() ; y++)
|
||||
{
|
||||
for(S32 x = 0; x < mTerrainBlock->getBlockSize(); x++)
|
||||
{
|
||||
F32 height;
|
||||
height = mTerrainBlock->getHeight(Point2I(x, y));
|
||||
|
||||
U8 col = U8((height - min) * colRange);
|
||||
ColorI color(col, col, col);
|
||||
bitmap->setColor(x, y, color);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return(bitmap);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void GuiMissionAreaCtrl::setMissionArea( MissionArea* area )
|
||||
{
|
||||
mMissionArea = area;
|
||||
|
|
@ -393,6 +334,98 @@ void GuiMissionAreaCtrl::setMissionArea( MissionArea* area )
|
|||
}
|
||||
}
|
||||
|
||||
void GuiMissionAreaCtrl::updateLevelBitmap()
|
||||
{
|
||||
if (mLevelTexture.isNull())
|
||||
mLevelTexture = GFX->allocRenderToTextureTarget();
|
||||
|
||||
mLevelTexture->attachTexture(GFXTextureTarget::DepthStencil, GFXTextureTarget::sDefaultDepthStencil);
|
||||
mLevelTexture->attachTexture(GFXTextureTarget::Color0, mBitmap);
|
||||
|
||||
mLevelBounds = Box3F::Zero;
|
||||
|
||||
for (SimSetIterator iter(Sim::getRootGroup()); *iter; ++iter)
|
||||
{
|
||||
SceneObject* obj = dynamic_cast<SceneObject*>(*iter);
|
||||
if (!obj)
|
||||
continue;
|
||||
|
||||
if (obj->isGlobalBounds())
|
||||
continue;
|
||||
|
||||
// Merge bounds
|
||||
mLevelBounds.intersect(obj->getWorldBox());
|
||||
}
|
||||
|
||||
const F32 minSize = 256.0f;
|
||||
|
||||
// Ensure the bounding box has a minimum size and is square
|
||||
VectorF size = mLevelBounds.getExtents();
|
||||
F32 maxExtent = getMax(getMax(size.x, size.y), minSize);
|
||||
|
||||
// Expand to make it square and centered
|
||||
Point3F center = mLevelBounds.getCenter();
|
||||
|
||||
Point3F halfExtents(maxExtent * 0.5f, maxExtent * 0.5f, size.z * 0.5f);
|
||||
mLevelBounds.minExtents = center - halfExtents;
|
||||
mLevelBounds.maxExtents = center + halfExtents;
|
||||
|
||||
GFXTransformSaver saver;
|
||||
|
||||
// Calculate orthographic dimensions
|
||||
Point3F minPt = mLevelBounds.minExtents;
|
||||
Point3F maxPt = mLevelBounds.maxExtents;
|
||||
|
||||
F32 orthoWidth = maxPt.x - minPt.x;
|
||||
F32 orthoHeight = maxPt.y - minPt.y;
|
||||
F32 nearPlane = 0.01f;
|
||||
F32 farPlane = 1000.0f;
|
||||
|
||||
// Set orthographic projection centered around level bounds
|
||||
GFX->setOrtho(
|
||||
-orthoWidth * 0.5f, orthoWidth * 0.5f, // left/right
|
||||
-orthoHeight * 0.5f, orthoHeight * 0.5f, // bottom/top
|
||||
nearPlane, farPlane,
|
||||
true // flip y
|
||||
);
|
||||
|
||||
GFX->pushActiveRenderTarget();
|
||||
|
||||
// create camera matrix
|
||||
MatrixF lightMatrix(true);
|
||||
VectorF eye = mLevelBounds.getCenter();
|
||||
eye.z += 500.0f;
|
||||
lightMatrix.LookAt(eye, VectorF(0.0f, 0.0f, -1.0f), VectorF(0.0f, -1.0f, 0.0f));
|
||||
lightMatrix.inverse();
|
||||
|
||||
GFX->setWorldMatrix(lightMatrix);
|
||||
GFX->clearTextureStateImmediate(0);
|
||||
|
||||
GFX->setActiveRenderTarget(mLevelTexture);
|
||||
GFX->clear(GFXClearStencil | GFXClearTarget | GFXClearZBuffer, ColorI::BLACK, 1.0f, 0);
|
||||
|
||||
SceneRenderState reflectRenderState
|
||||
(
|
||||
gClientSceneGraph,
|
||||
SPT_Reflect,
|
||||
SceneCameraState::fromGFX()
|
||||
);
|
||||
|
||||
// We don't use a special clipping projection, but still need to initialize
|
||||
// this for objects like SkyBox which will use it during a reflect pass.
|
||||
gClientSceneGraph->setNonClipProjection(GFX->getProjectionMatrix());
|
||||
|
||||
// render scene
|
||||
LIGHTMGR->registerGlobalLights(&reflectRenderState.getCullingFrustum(), false);
|
||||
gClientSceneGraph->renderSceneNoLights(&reflectRenderState);
|
||||
LIGHTMGR->unregisterAllLights();
|
||||
|
||||
// Clean up.
|
||||
mLevelTexture->resolve();
|
||||
|
||||
GFX->popActiveRenderTarget();
|
||||
}
|
||||
|
||||
const RectI & GuiMissionAreaCtrl::getArea()
|
||||
{
|
||||
if( !bool(mMissionArea) )
|
||||
|
|
@ -503,31 +536,33 @@ Point2I GuiMissionAreaCtrl::screenDeltaToWorldDelta(const Point2I &screenPoint)
|
|||
return(Point2I(S32(screenPoint.x / mScale.x), S32(screenPoint.y / mScale.y)));
|
||||
}
|
||||
|
||||
void GuiMissionAreaCtrl::setupScreenTransform(const Point2I & offset)
|
||||
void GuiMissionAreaCtrl::setupScreenTransform(const Point2I& offset)
|
||||
{
|
||||
const MatrixF & terrMat = mTerrainBlock->getTransform();
|
||||
Point3F terrPos;
|
||||
terrMat.getColumn(3, &terrPos);
|
||||
terrPos.z = 0;
|
||||
// Compute 2D size of the bounding box
|
||||
Point2F boxSize(mLevelBounds.len_x(), mLevelBounds.len_y());
|
||||
Point2F boxMin(mLevelBounds.minExtents.x, mLevelBounds.minExtents.y);
|
||||
Point2F boxCenter = Point2F(mLevelBounds.getCenter().x, mLevelBounds.getCenter().y);
|
||||
|
||||
F32 terrDim = mTerrainBlock->getWorldBlockSize();
|
||||
// GUI control size
|
||||
const Point2I& extenti = getExtent();
|
||||
Point2F extent((F32)extenti.x, (F32)extenti.y);
|
||||
|
||||
const Point2I& extenti = getExtent( );
|
||||
Point2F extent( static_cast<F32>( extenti.x ), static_cast<F32>( extenti.y ) );
|
||||
|
||||
if(mSquareBitmap)
|
||||
// Maintain square aspect ratio if requested
|
||||
if (mSquareBitmap)
|
||||
extent.x > extent.y ? extent.x = extent.y : extent.y = extent.x;
|
||||
|
||||
// We need to negate the y-axis so we are correctly oriented with
|
||||
// positive y increase up the screen.
|
||||
mScale.set(extent.x / terrDim, -extent.y / terrDim, 0);
|
||||
// Compute scale (how many pixels per world unit)
|
||||
mScale.set(extent.x / boxSize.x, -extent.y / boxSize.y, 0); // Y flipped
|
||||
|
||||
Point3F terrOffset = -terrPos;
|
||||
terrOffset.convolve(mScale);
|
||||
// Instead of offsetting the center to (0,0), we want to place the box center at GUI center
|
||||
// So we compute the world-to-screen offset for center
|
||||
Point2F screenCenter((F32)offset.x + extent.x * 0.5f, (F32)offset.y + extent.y * 0.5f);
|
||||
|
||||
// We need to add the y extent so we start from the bottom left of the control
|
||||
// rather than the top left.
|
||||
mCenterPos.set(terrOffset.x + F32(offset.x), terrOffset.y + F32(offset.y) + extent.y);
|
||||
Point2F worldCenterOffset = boxCenter * Point2F(mScale.x, mScale.y);
|
||||
|
||||
// Compute the final offset that maps world center to screen center
|
||||
mCenterPos.set(screenCenter.x - worldCenterOffset.x,
|
||||
screenCenter.y - worldCenterOffset.y);
|
||||
}
|
||||
|
||||
void GuiMissionAreaCtrl::getScreenMissionArea(RectI & rect)
|
||||
|
|
@ -575,7 +610,7 @@ void GuiMissionAreaCtrl::onRender(Point2I offset, const RectI & updateRect)
|
|||
setUpdate();
|
||||
|
||||
// draw an x
|
||||
if(!bool(mMissionArea) || !bool(mTerrainBlock))
|
||||
if(!bool(mMissionArea))
|
||||
{
|
||||
GFX->setStateBlock(mSolidStateBlock);
|
||||
PrimBuild::color3i( 0, 0, 0 );
|
||||
|
|
@ -683,12 +718,13 @@ DefineEngineMethod( GuiMissionAreaCtrl, setMissionArea, void, ( MissionArea* are
|
|||
object->setMissionArea( area );
|
||||
}
|
||||
|
||||
DefineEngineMethod( GuiMissionAreaCtrl, updateTerrain, void, ( ),,
|
||||
"@brief Update the terrain bitmap.\n\n")
|
||||
DefineEngineMethod(GuiMissionAreaCtrl, updateLevelBitmap, void, (), ,
|
||||
"@brief Update the level bitmap and bounds.\n\n")
|
||||
{
|
||||
object->updateTerrain();
|
||||
object->updateLevelBitmap();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void GuiMissionAreaUndoAction::undo()
|
||||
|
|
|
|||
|
|
@ -58,10 +58,11 @@ protected:
|
|||
};
|
||||
|
||||
SimObjectPtr<MissionArea> mMissionArea;
|
||||
SimObjectPtr<TerrainBlock> mTerrainBlock;
|
||||
|
||||
GFXStateBlockRef mBlendStateBlock;
|
||||
GFXStateBlockRef mSolidStateBlock;
|
||||
GFXTextureTargetRef mLevelTexture;
|
||||
Box3F mLevelBounds;
|
||||
|
||||
DECLARE_IMAGEASSET(GuiMissionAreaCtrl, HandleBitmap, GFXDefaultGUIProfile)
|
||||
|
||||
|
|
@ -82,10 +83,6 @@ protected:
|
|||
|
||||
void submitUndo( const UTF8 *name = "Action" );
|
||||
|
||||
TerrainBlock * getTerrainObj();
|
||||
GBitmap * createTerrainBitmap();
|
||||
void updateTerrainBitmap();
|
||||
|
||||
//void onUpdate();
|
||||
|
||||
void setupScreenTransform(const Point2I & offset);
|
||||
|
|
@ -132,7 +129,7 @@ public:
|
|||
void onMouseLeave(const GuiEvent & event) override;
|
||||
|
||||
void setMissionArea( MissionArea* area );
|
||||
void updateTerrain();
|
||||
void updateLevelBitmap();
|
||||
|
||||
const RectI & getArea();
|
||||
void setArea(const RectI & area);
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ function MissionAreaEditorPlugin::readSettings( %this )
|
|||
{
|
||||
EditorSettings.beginGroup( "MissionAreaEditor", true );
|
||||
|
||||
MissionAreaEditorTerrainEditor.missionBoundsColor = EditorSettings.value("MissionBoundsColor");
|
||||
MissionAreaEditorLevelEditor.missionBoundsColor = EditorSettings.value("MissionBoundsColor");
|
||||
|
||||
EditorSettings.endGroup();
|
||||
}
|
||||
|
|
@ -146,7 +146,7 @@ function MissionAreaEditorPlugin::writeSettings( %this )
|
|||
{
|
||||
EditorSettings.beginGroup( "MissionAreaEditor", true );
|
||||
|
||||
EditorSettings.setValue( "MissionBoundsColor", MissionAreaEditorTerrainEditor.missionBoundsColor );
|
||||
EditorSettings.setValue( "MissionBoundsColor", MissionAreaEditorLevelEditor.missionBoundsColor );
|
||||
|
||||
EditorSettings.endGroup();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ $guiContent = new GuiMissionAreaEditorCtrl(MissionAreaEditorGui, EditorGuiGroup)
|
|||
VertSizing = "height";
|
||||
isContainer = "1";
|
||||
|
||||
new GuiMissionAreaCtrl(MissionAreaEditorTerrainEditor) {
|
||||
new GuiMissionAreaCtrl(MissionAreaEditorLevelEditor) {
|
||||
canSaveDynamicFields = "0";
|
||||
isContainer = "0";
|
||||
Profile = "EditorDefaultProfile";
|
||||
|
|
|
|||
|
|
@ -290,7 +290,7 @@ function MissionAreaEditorGui::onEditorActivated( %this )
|
|||
{
|
||||
EWorldEditor.selectObject( %ma );
|
||||
EWorldEditor.syncGui();
|
||||
MissionAreaEditorTerrainEditor.updateTerrain();
|
||||
MissionAreaEditorLevelEditor.updateLevelBitmap();
|
||||
%this.setSelectedMissionArea( %ma );
|
||||
%this.onMissionAreaSelected( %this.getSelectedMissionArea() );
|
||||
}
|
||||
|
|
@ -303,18 +303,18 @@ function MissionAreaEditorGui::onEditorDeactivated( %this )
|
|||
function MissionAreaEditorGui::onMissionAreaSelected( %this, %missionArea )
|
||||
{
|
||||
%this.missionArea = %missionArea;
|
||||
MissionAreaEditorTerrainEditor.setMissionArea( %missionArea );
|
||||
MissionAreaEditorLevelEditor.setMissionArea( %missionArea );
|
||||
MissionAreaInspector.inspect( %missionArea );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function MissionAreaEditorTerrainEditor::onMissionAreaModified( %this )
|
||||
function MissionAreaEditorLevelEditor::onMissionAreaModified( %this )
|
||||
{
|
||||
MissionAreaInspector.refresh();
|
||||
}
|
||||
|
||||
function MissionAreaEditorTerrainEditor::onUndo( %this )
|
||||
function MissionAreaEditorLevelEditor::onUndo( %this )
|
||||
{
|
||||
MissionAreaInspector.refresh();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue