📄 missionareaeditor.cc
字号:
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
#include "editor/missionAreaEditor.h"
#include "dgl/gBitmap.h"
#include "terrain/terrData.h"
#include "sim/sceneObject.h"
#include "dgl/dgl.h"
#include "console/consoleTypes.h"
#include "gui/core/guiCanvas.h"
#include "gui/core/guiTSControl.h"
#include "game/game.h"
#include "game/objectTypes.h"
#include "game/shapeBase.h"
#include "game/gameConnection.h"
#include "core/bitMatrix.h"
IMPLEMENT_CONOBJECT(MissionAreaEditor);
// unnamed namespace for static data
namespace {
static const Point3F BoxNormals[] =
{
Point3F( 1, 0, 0),
Point3F(-1, 0, 0),
Point3F( 0, 1, 0),
Point3F( 0,-1, 0),
Point3F( 0, 0, 1),
Point3F( 0, 0,-1)
};
static U32 BoxVerts[][4] = {
{7,6,4,5}, // +x
{0,2,3,1}, // -x
{7,3,2,6}, // +y
{0,1,5,4}, // -y
{7,5,1,3}, // +z
{0,4,6,2} // -z
};
static Point3F BoxPnts[] = {
Point3F(0,0,0),
Point3F(0,0,1),
Point3F(0,1,0),
Point3F(0,1,1),
Point3F(1,0,0),
Point3F(1,0,1),
Point3F(1,1,0),
Point3F(1,1,1)
};
F32 round_local(F32 val)
{
if(val >= 0.f)
{
F32 floor = mFloor(val);
if((val - floor) >= 0.5f)
return(floor + 1.f);
return(floor);
}
else
{
F32 ceil = mCeil(val);
if((val - ceil) <= -0.5f)
return(ceil - 1.f);
return(ceil);
}
}
S32 clamp(S32 val, S32 resolution)
{
return(S32(round_local(F32(val) / F32(resolution))) * resolution);
}
}
//------------------------------------------------------------------------------
MissionAreaEditor::MissionAreaEditor()
{
//
mMissionArea = 0;
mTerrainBlock = 0;
//
mCurrentCursor = 0;
mLastHitMode = 0;
// field data
mSquareBitmap = true;
mEnableEditing = true;
mRenderCamera = true;
mHandleFrameColor.set(255,255,255);
mHandleFillColor.set(0,0,0);
mDefaultObjectColor.set(0,255,0,100);
mWaterObjectColor.set(0,0,255,100);
mMissionBoundsColor.set(255,0,0);
mCameraColor.set(255,0,0);
mEnableMirroring = false;
mMirrorIndex = 0;
mMirrorLineColor.set(255,0,255,128);
mMirrorArrowColor.set(255,0,255,128);
}
//------------------------------------------------------------------------------
const RectI & MissionAreaEditor::getArea()
{
AssertFatal(mMissionArea, "MissionAreaEditor::getArea: no MissionArea obj!");
if(!bool(mMissionArea))
return(MissionArea::smMissionArea);
return(mMissionArea->getArea());
}
bool MissionAreaEditor::clampArea(RectI & area)
{
if(!bool(mTerrainBlock))
return(false);
S32 res = mTerrainBlock->getSquareSize();
area.point.x = clamp(area.point.x, res);
area.point.y = clamp(area.point.y, res);
area.extent.x = clamp(area.extent.x, res << 1);
area.extent.y = clamp(area.extent.y, res << 1);
return(true);
}
void MissionAreaEditor::setArea(const RectI & area)
{
AssertFatal(mMissionArea, "MissionAreaEditor::setArea: no MissionArea obj!");
if(bool(mMissionArea))
{
RectI clamped = area;
if(clampArea(clamped))
{
mMissionArea->setArea(clamped);
onUpdate();
}
}
}
//------------------------------------------------------------------------------
void MissionAreaEditor::getCursor(GuiCursor *&cursor, bool &visible, const GuiEvent &)
{
cursor = mCurrentCursor;
visible = true;
}
void MissionAreaEditor::setCursor(U32 cursor)
{
AssertFatal(cursor < NumCursors, "MissionAreaEditor::setCursor: invalid cursor");
mCurrentCursor = mCursors[cursor];
}
//------------------------------------------------------------------------------
bool MissionAreaEditor::grabCursors()
{
struct {
U32 index;
const char * name;
} infos[] = {
{DefaultCursor, "DefaultCursor" },
{HandCursor, "EditorHandCursor" },
{GrabCursor, "EditorMoveCursor" },
{VertResizeCursor, "EditorUpDownCursor" },
{HorizResizeCursor, "EditorLeftRightCursor" },
{DiagRightResizeCursor, "EditorDiagRightCursor" },
{DiagLeftResizeCursor, "EditorDiagLeftCursor" }
};
for(U32 i = 0; i < (sizeof(infos) / sizeof(infos[0])); i++)
{
SimObject * obj = Sim::findObject(infos[i].name);
if(!obj)
{
Con::errorf(ConsoleLogEntry::Script, "MissionAreaEditor::grabCursors: failed to find cursor '%s'.", infos[i].name);
return(false);
}
GuiCursor *cursor = dynamic_cast<GuiCursor*>(obj);
if(!cursor)
{
Con::errorf(ConsoleLogEntry::Script, "MissionAreaEditor::grabCursors: object is not a cursor '%s'.", infos[i].name);
return(false);
}
mCursors[infos[i].index] = cursor;
}
mCurrentCursor = mCursors[DefaultCursor];
return(true);
}
//------------------------------------------------------------------------------
TerrainBlock * MissionAreaEditor::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);
}
//------------------------------------------------------------------------------
GBitmap * MissionAreaEditor::createTerrainBitmap()
{
GBitmap * bitmap = new GBitmap(TerrainBlock::BlockSize, TerrainBlock::BlockSize, false, GBitmap::RGB);
if(!bitmap)
return(0);
U8 * pBits = bitmap->getAddress(0,0);
// get the min/max
GridSquare * gSquare = mTerrainBlock->findSquare(TerrainBlock::BlockShift, Point2I(0,0));
F32 min = fixedToFloat(gSquare->minHeight);
F32 max = fixedToFloat(gSquare->maxHeight);
F32 diff = max - min;
for(U32 y = 0; y < TerrainBlock::BlockSize; y++)
for(U32 x = 0; x < TerrainBlock::BlockSize; x++)
{
F32 height = fixedToFloat(mTerrainBlock->getHeight(x, y));
U8 col = U8((height - min) / diff * 255.f);
*pBits++ = col;
*pBits++ = col;
*pBits++ = col;
}
return(bitmap);
}
//------------------------------------------------------------------------------
bool MissionAreaEditor::onAdd()
{
if(!Parent::onAdd())
return(false);
if(!grabCursors())
return(false);
return(true);
}
//------------------------------------------------------------------------------
void MissionAreaEditor::updateTerrainBitmap()
{
const GBitmap * bitmap = createTerrainBitmap();
if(bitmap)
setBitmap(TextureHandle("maTerrain", bitmap, true));
}
bool MissionAreaEditor::onWake()
{
if(!Parent::onWake())
return(false);
mMissionArea = const_cast<MissionArea*>(MissionArea::getServerObject());
if(!bool(mMissionArea))
{
Con::errorf(ConsoleLogEntry::General, "MissionAreaEditor::onWake: no MissionArea object.");
return(false);
}
mTerrainBlock = getTerrainObj();
if(!bool(mTerrainBlock))
{
Con::errorf(ConsoleLogEntry::General, "MissionAreaEditor::onWake: no TerrainBlock object.");
return true;
//return(false);
}
updateTerrainBitmap();
// make sure mission area is clamped
setArea(getArea());
onUpdate();
setActive(true);
return(true);
}
void MissionAreaEditor::onSleep()
{
mTextureHandle = NULL;
mMissionArea = 0;
mTerrainBlock = 0;
Parent::onSleep();
}
//------------------------------------------------------------------------------
void MissionAreaEditor::onUpdate()
{
if(!bool(mMissionArea))
return;
char buf[48];
const RectI & area = mMissionArea->getArea();
dSprintf(buf, sizeof(buf), "%d %d %d %d", area.point.x, area.point.y, area.extent.x, area.extent.y);
Con::executef(this, 2, "onUpdate", buf);
}
void MissionAreaEditor::parentResized(const Point2I & oldParentExtent, const Point2I & newParentExtent)
{
static Point2I offset = (oldParentExtent - getPosition()) - getExtent();
resize(getPosition(), newParentExtent - getPosition() - offset);
}
//------------------------------------------------------------------------------
Point2F MissionAreaEditor::worldToScreen(const Point2F & pos)
{
return(Point2F(mCenterPos.x + (pos.x * mScale.x), mCenterPos.y + (pos.y * mScale.y)));
}
Point2F MissionAreaEditor::screenToWorld(const Point2F & pos)
{
return(Point2F((pos.x - mCenterPos.x) / mScale.x, (pos.y - mCenterPos.y) / mScale.y));
}
//------------------------------------------------------------------------------
void MissionAreaEditor::getScreenMissionArea(RectI & rect)
{
RectI area = mMissionArea->getArea();
Point2F pos = worldToScreen(Point2F(area.point.x, area.point.y));
Point2F end = worldToScreen(Point2F(area.point.x + area.extent.x, area.point.y + area.extent.y));
//
rect.point.x = S32(round_local(pos.x));
rect.point.y = S32(round_local(pos.y));
rect.extent.x = S32(round_local(end.x - pos.x));
rect.extent.y = S32(round_local(end.y - pos.y));
}
void MissionAreaEditor::getScreenMissionArea(RectF & rect)
{
RectI area = mMissionArea->getArea();
Point2F pos = worldToScreen(Point2F(area.point.x, area.point.y));
Point2F end = worldToScreen(Point2F(area.point.x + area.extent.x, area.point.y + area.extent.y));
//
rect.point.x = pos.x;
rect.point.y = pos.y;
rect.extent.x = end.x - pos.x;
rect.extent.y = end.y - pos.y;
}
//------------------------------------------------------------------------------
void MissionAreaEditor::setupScreenTransform(const Point2I & offset)
{
const MatrixF & terrMat = mTerrainBlock->getTransform();
Point3F terrPos;
terrMat.getColumn(3, &terrPos);
terrPos.z = 0;
F32 terrDim = F32(mTerrainBlock->getSquareSize() * TerrainBlock::BlockSize);
const Point2I& extenti = getExtent( );
Point2F extent( static_cast<F32>( extenti.x ), static_cast<F32>( extenti.y ) );
if(mSquareBitmap)
extent.x > extent.y ? extent.x = extent.y : extent.y = extent.x;
//
mScale.set(extent.x / terrDim, extent.y / terrDim, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -