📄 missionareaeditor.cc
字号:
void MissionAreaEditor::onMouseUp(const GuiEvent & event)
{
if(!bool(mMissionArea))
return;
RectI box;
getScreenMissionArea(box);
S32 hit = getSizingHitKnobs(event.mousePoint, box);
// set the current cursor
updateCursor(hit);
mLastHitMode = hit;
}
void MissionAreaEditor::onMouseDown(const GuiEvent & event)
{
if(!bool(mMissionArea))
return;
if(!mEnableEditing || mEnableMirroring)
{
Point2F pos = screenToWorld(Point2F(event.mousePoint.x, event.mousePoint.y));
setControlObjPos(pos);
return;
}
RectI box;
getScreenMissionArea(box);
mLastHitMode = getSizingHitKnobs(event.mousePoint, box);
if(mLastHitMode == moving)
setCursor(GrabCursor);
mLastMousePoint = event.mousePoint;
}
void MissionAreaEditor::onMouseMove(const GuiEvent & event)
{
if(!bool(mMissionArea))
return;
RectI box;
getScreenMissionArea(box);
S32 hit = getSizingHitKnobs(event.mousePoint, box);
// set the current cursor...
updateCursor(hit);
mLastHitMode = hit;
}
// update the mission area here...
void MissionAreaEditor::onMouseDragged(const GuiEvent & event)
{
if(!bool(mMissionArea))
return;
if(!mLastHitMode)
return;
RectF box;
getScreenMissionArea(box);
Point2F mouseDiff(event.mousePoint.x - mLastMousePoint.x,
event.mousePoint.y - mLastMousePoint.y);
// what we drag'n?
if(mLastHitMode == moving)
box.point += mouseDiff;
else
{
// dont allow the box to be < 1x1 'pixels'
if(mLastHitMode & sizingLeft)
{
if(mouseDiff.x >= box.extent.x)
mouseDiff.x = box.extent.x - 1;
box.point.x += mouseDiff.x;
box.extent.x -= mouseDiff.x;
}
if(mLastHitMode & sizingRight)
{
if(mouseDiff.x + box.extent.x <= 0)
mouseDiff.x = -(box.extent.x - 1);
box.extent.x += mouseDiff.x;
}
if(mLastHitMode & sizingTop)
{
if(mouseDiff.y >= box.extent.y)
mouseDiff.y = box.extent.y - 1;
box.point.y += mouseDiff.y;
box.extent.y -= mouseDiff.y;
}
if(mLastHitMode & sizingBottom)
{
if(mouseDiff.y + box.extent.y <= 0)
mouseDiff.y = -(box.extent.y - 1);
box.extent.y += mouseDiff.y;
}
}
//
Point2F min = screenToWorld(box.point);
Point2F max = screenToWorld(box.point + box.extent);
RectI iBox((S32)round_local(min.x), (S32)round_local(min.y), (S32)round_local(max.x - min.x), (S32)round_local(max.y - min.y));
setArea(iBox);
mLastMousePoint = event.mousePoint;
}
void MissionAreaEditor::onMouseEnter(const GuiEvent &)
{
mLastHitMode = nothing;
setCursor(DefaultCursor);
}
void MissionAreaEditor::onMouseLeave(const GuiEvent &)
{
mLastHitMode = nothing;
setCursor(DefaultCursor);
}
//------------------------------------------------------------------------------
void MissionAreaEditor::setControlObjPos(const Point2F & pos)
{
GameConnection * connection = GameConnection::getLocalClientConnection();
ShapeBase * obj = 0;
if(connection)
obj = connection->getControlObject();
if(!obj)
{
Con::errorf(ConsoleLogEntry::General, "MissionAreaEditor::setControlObjPos: could not get a control object!");
return;
}
// move it
MatrixF mat = obj->getTransform();
Point3F current;
mat.getColumn(3, ¤t);
//
if(bool(mTerrainBlock))
{
F32 height;
mTerrainBlock->getHeight(pos, &height);
if(current.z < height)
current.z = height + 10.f;
}
//
current.set(pos.x, pos.y, current.z);
mat.setColumn(3, current);
obj->setTransform(mat);
}
//------------------------------------------------------------------------------
// the following globals allocations needed for cCenterWorld are allocated when first refd.
static U16 *heights = NULL;
static U8 *baseMaterials = NULL;
static TerrainBlock::Material *materials = NULL;
static bool cwAllocs = false;
//------------------------------------------------------------------------------
ConsoleMethod( MissionAreaEditor, centerWorld, void, 2, 2, "Realign the world so that the mission area is centered.\n\n"
"This method moves every SceneObject (including terrain) in the world so that the center of the world is "
"the center of the mission area.")
{
if(!object->missionAreaObjValid())
{
Con::errorf(ConsoleLogEntry::General, "MissionAreaEditor::cCenterWorld: no MissionArea obj!");
return;
}
//
SimSet * missionGroup = dynamic_cast<SimSet*>(Sim::findObject("missionGroup"));
if(!missionGroup)
{
Con::errorf(ConsoleLogEntry::General, "MissionAreaEditor::cCenterWorld: no mission group found!");
return;
}
// make sure we're allocated.
// !!!!!TBD -- NOTE THAT THIS IS LEAKED ON EXIT!
if (!cwAllocs)
{
U32 allocSize = TerrainBlock::BlockSize * TerrainBlock::BlockSize;
heights = new U16[allocSize];
if (NULL==heights)
{
Con::errorf(ConsoleLogEntry::General, "MissionAreaEditor::cCenterWorld: out of memory!");
return;
}
baseMaterials = new U8[allocSize];
if (NULL==baseMaterials)
{
Con::errorf(ConsoleLogEntry::General, "MissionAreaEditor::cCenterWorld: out of memory!");
return;
}
materials = new TerrainBlock::Material[allocSize];
if (NULL==materials)
{
Con::errorf(ConsoleLogEntry::General, "MissionAreaEditor::cCenterWorld: out of memory!");
return;
}
cwAllocs = true;
}
// make sure area is clamped to terrain square size!
object->setArea(object->getArea());
RectI area = object->getArea();
// calc offset
Point2I offset(area.point.x + (area.extent.x >> 1),
area.point.y + (area.extent.y >> 1));
if(!offset.x || !offset.y)
return;
Point3F offset3F(offset.x, offset.y, 0.f);
// update all the scene objects
for(SimSetIterator itr(missionGroup); *itr; ++itr)
{
SceneObject * obj = dynamic_cast<SceneObject*>(*itr);
if(!obj)
continue;
// terrain is handled special like (mission area is forced to align to
// terrain square sizes because terrain cannot move)
TerrainBlock * terrain = dynamic_cast<TerrainBlock*>(*itr);
if(terrain)
{
// get the new start location in gridSquare space
Point2I start((offset.x / (S32) terrain->getSquareSize()) & TerrainBlock::BlockMask,
(offset.y / (S32) terrain->getSquareSize()) & TerrainBlock::BlockMask);
// update the grid block
if(start.x || start.y)
{
for(U32 y = 0; y < TerrainBlock::BlockSize; y++)
for(U32 x = 0; x < TerrainBlock::BlockSize; x++)
{
Point2I pos((start.x + x) & TerrainBlock::BlockMask,
(start.y + y) & TerrainBlock::BlockMask);
heights[x + y * TerrainBlock::BlockSize] = terrain->getHeight(pos.x, pos.y);
baseMaterials[x + y * TerrainBlock::BlockSize] = terrain->getBaseMaterial(pos.x, pos.y);
materials[x + y * TerrainBlock::BlockSize] = *terrain->getMaterial(pos.x, pos.y);
}
U16 * heightsAddr = terrain->getHeightAddress(0,0);
U8 * baseMaterialsAddr = terrain->getBaseMaterialAddress(0,0);
TerrainBlock::Material * materialsAddr = terrain->getMaterial(0,0);
dMemcpy(heightsAddr, heights, sizeof(heights));
dMemcpy(baseMaterialsAddr, baseMaterials, sizeof(baseMaterials));
dMemcpy(materialsAddr, materials, sizeof(materials));
terrain->buildGridMap();
terrain->rebuildEmptyFlags();
terrain->packEmptySquares();
}
object->updateTerrainBitmap();
}
else
{
MatrixF objMat = obj->getTransform();
Point3F pos;
objMat.getColumn(3, &pos);
pos -= offset3F;
objMat.setColumn(3, pos);
obj->setTransform(objMat);
}
}
char buf[64];
dSprintf(buf, sizeof(buf), "%g %g %g", -offset3F.x, -offset3F.y, -offset3F.z);
Con::executef(object, 2, "onWorldOffset", buf);
// move the mission area
area.point.x -= offset.x;
area.point.y -= offset.y;
object->setArea(area);
}
//------------------------------------------------------------------------------
ConsoleMethod(MissionAreaEditor, getArea, const char *, 2, 2, "Return a 4-tuple: area_x area_y area_width are_height")
{
if(!object->missionAreaObjValid())
{
Con::errorf(ConsoleLogEntry::General, "MissionAreaEditor::cGetArea: no MissionArea obj!");
return("");
}
//
RectI area = object->getArea();
char * ret = Con::getReturnBuffer(64);
dSprintf(ret, 64, "%d %d %d %d", area.point.x, area.point.y, area.extent.x, area.extent.y);
return(ret);
}
ConsoleMethod( MissionAreaEditor, setArea, void, 3, 6, "(int x, int y, int w, int h)"
"Set the mission area to the specified co-ordinates/extents.")
{
if(!object->missionAreaObjValid())
{
Con::errorf(ConsoleLogEntry::General, "MissionAreaEditor::cSetArea: no MissionArea obj!");
return;
}
RectI area;
//
if(argc == 3)
dSscanf(argv[2], "%d %d %d %d", &area.point.x, &area.point.y, &area.extent.x, &area.extent.y);
else if(argc == 6)
{
area.point.x = dAtoi(argv[2]);
area.point.y = dAtoi(argv[3]);
area.extent.x = dAtoi(argv[4]);
area.extent.y = dAtoi(argv[5]);
}
else
Con::errorf(ConsoleLogEntry::General, "MissionAreaEditor::cSetArea: invalid number of arguments!");
//
object->setArea(area);
}
ConsoleMethod( MissionAreaEditor, updateTerrain, void, 2, 2, "Update the terrain bitmap that is rendered as background in the control.")
{
//
if(!object->getTerrainObj())
{
Con::errorf(ConsoleLogEntry::General, "MissionAreaEditor::cUpdateTerrain: no terrain found!");
return;
}
//
object->updateTerrainBitmap();
}
//------------------------------------------------------------------------------
void MissionAreaEditor::initPersistFields()
{
Parent::initPersistFields();
addGroup("Mirror");
addField("enableMirroring", TypeBool, Offset(mEnableMirroring, MissionAreaEditor));
addField("mirrorIndex", TypeS32, Offset(mMirrorIndex, MissionAreaEditor));
addField("mirrorLineColor", TypeColorI, Offset(mMirrorLineColor, MissionAreaEditor));
addField("mirrorArrowColor", TypeColorI, Offset(mMirrorArrowColor, MissionAreaEditor));
endGroup("Mirror");
addGroup("Misc");
addField("handleFrameColor", TypeColorI, Offset(mHandleFrameColor, MissionAreaEditor));
addField("handleFillColor", TypeColorI, Offset(mHandleFillColor, MissionAreaEditor));
addField("defaultObjectColor", TypeColorI, Offset(mDefaultObjectColor, MissionAreaEditor));
addField("waterObjectColor", TypeColorI, Offset(mWaterObjectColor, MissionAreaEditor));
addField("missionBoundsColor", TypeColorI, Offset(mMissionBoundsColor, MissionAreaEditor));
addField("cameraColor", TypeColorI, Offset(mCameraColor, MissionAreaEditor));
addField("squareBitmap", TypeBool, Offset(mSquareBitmap, MissionAreaEditor));
addField("enableEditing", TypeBool, Offset(mEnableEditing, MissionAreaEditor));
addField("renderCamera", TypeBool, Offset(mRenderCamera, MissionAreaEditor));
endGroup("Misc");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -