📄 worldeditor.cc
字号:
ColorI axisColor( 0x00, 0x80, 0x80 ); // Dark teal
ColorI selectColor( 0x00, 0xff, 0xff ); // Bright teal
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glBegin(GL_LINES);
char axisText[] = "xyz";
// render each of them...
for(U32 i = 0; i < 3; i++)
{
Point3F & centroid = mAxisGizmoCenter;
if( i == mAxisGizmoSelAxis )
glColor3ub( selectColor.red, selectColor.green, selectColor.blue );
else
glColor3ub( axisColor.red, axisColor.green, axisColor.blue );
glVertex3f(centroid.x, centroid.y, centroid.z);
glVertex3f(centroid.x + mAxisGizmoVector[i].x * mAxisGizmoProjLen,
centroid.y + mAxisGizmoVector[i].y * mAxisGizmoProjLen,
centroid.z + mAxisGizmoVector[i].z * mAxisGizmoProjLen);
}
glEnd();
glEnable(GL_DEPTH_TEST);
}
void WorldEditor::renderAxisGizmoText()
{
char axisText[] = "xyz";
ColorI fillColor = mProfile->mFillColorNA;
ColorI textColor = mProfile->mFontColor;
for(U32 i = 0; i < 3; i++)
{
const Point3F & centroid = mAxisGizmoCenter;
Point3F pos(centroid.x + mAxisGizmoVector[i].x * mAxisGizmoProjLen,
centroid.y + mAxisGizmoVector[i].y * mAxisGizmoProjLen,
centroid.z + mAxisGizmoVector[i].z * mAxisGizmoProjLen);
Point3F sPos;
if(project(pos, &sPos))
{
if( i == mAxisGizmoSelAxis ) {
// Draw background box
if( i == mAxisGizmoSelAxis ) {
fillColor = mProfile->mFillColor;
textColor = mProfile->mFontColorHL;
}
else {
fillColor = mProfile->mFillColorNA;
textColor = mProfile->mFontColor;
}
dglDrawRectFill( Point2I((S32)sPos.x - 3, (S32)sPos.y + 2 ),
Point2I( (S32)sPos.x + 8, (S32)sPos.y + mProfile->mFont->getHeight() + 3 ),
fillColor );
dglDrawRect( Point2I( (S32)sPos.x - 3, (S32)sPos.y + 2 ),
Point2I( (S32)sPos.x + 8, (S32)sPos.y + mProfile->mFont->getHeight() + 3 ),
textColor );
}
char buf[2];
buf[0] = axisText[i]; buf[1] = '\0';
dglSetBitmapModulation(textColor);
dglDrawText(mProfile->mFont, Point2I((S32)sPos.x, (S32)sPos.y), buf);
}
}
}
//------------------------------------------------------------------------------
Point3F WorldEditor::snapPoint(const Point3F & pnt)
{
if(!mSnapToGrid)
return(pnt);
Point3F snap;
snap.x = snapFloat(pnt.x, mGridSize.x);
snap.y = snapFloat(pnt.y, mGridSize.y);
snap.z = snapFloat(pnt.z, mGridSize.z);
return(snap);
}
//------------------------------------------------------------------------------
// ClassInfo stuff
WorldEditor::ClassInfo::~ClassInfo()
{
for(U32 i = 0; i < mEntries.size(); i++)
delete mEntries[i];
}
bool WorldEditor::objClassIgnored(const SceneObject * obj)
{
ClassInfo::Entry * entry = getClassEntry(obj);
if(mToggleIgnoreList)
return(!(entry ? entry->mIgnoreCollision : false));
else
return(entry ? entry->mIgnoreCollision : false);
}
WorldEditor::ClassInfo::Entry * WorldEditor::getClassEntry(StringTableEntry name)
{
AssertFatal(name, "WorldEditor::getClassEntry - invalid args");
for(U32 i = 0; i < mClassInfo.mEntries.size(); i++)
if(!dStricmp(name, mClassInfo.mEntries[i]->mName))
return(mClassInfo.mEntries[i]);
return(0);
}
WorldEditor::ClassInfo::Entry * WorldEditor::getClassEntry(const SceneObject * obj)
{
AssertFatal(obj, "WorldEditor::getClassEntry - invalid args");
return(getClassEntry(obj->getClassName()));
}
bool WorldEditor::addClassEntry(ClassInfo::Entry * entry)
{
AssertFatal(entry, "WorldEditor::addClassEntry - invalid args");
if(getClassEntry(entry->mName))
return(false);
mClassInfo.mEntries.push_back(entry);
return(true);
}
//------------------------------------------------------------------------------
// Mouse cursor stuff
bool WorldEditor::grabCursors()
{
struct _cursorInfo {
U32 index;
const char * name;
} infos[] = {
{HandCursor, "EditorHandCursor"},
{RotateCursor, "EditorRotateCursor"},
{ScaleCursor, "EditorRotateCursor"},
{MoveCursor, "EditorMoveCursor"},
{ArrowCursor, "EditorArrowCursor"},
{DefaultCursor, "DefaultCursor"},
};
//
for(U32 i = 0; i < (sizeof(infos) / sizeof(infos[0])); i++)
{
SimObject * obj = Sim::findObject(infos[i].name);
if(!obj)
{
Con::errorf(ConsoleLogEntry::Script, "WorldEditor::grabCursors: failed to find cursor '%s'.", infos[i].name);
return(false);
}
GuiCursor *cursor = dynamic_cast<GuiCursor*>(obj);
if(!cursor)
{
Con::errorf(ConsoleLogEntry::Script, "WorldEditor::grabCursors: object is not a cursor '%s'.", infos[i].name);
return(false);
}
//
mCursors[infos[i].index] = cursor;
}
//
mCurrentCursor = mCursors[DefaultCursor];
return(true);
}
void WorldEditor::setCursor(U32 cursor)
{
AssertFatal(cursor < NumCursors, "WorldEditor::setCursor: invalid cursor");
mCurrentCursor = mCursors[cursor];
}
//------------------------------------------------------------------------------
WorldEditor::WorldEditor()
{
// init the field data
mPlanarMovement = true;
mUndoLimit = 40;
mDropType = DropAtScreenCenter;
mProjectDistance = 2000.f;
mBoundingBoxCollision = true;
mRenderPlane = true;
mRenderPlaneHashes = true;
mGridColor.set(255,255,255,20);
mPlaneDim = 500;
mGridSize.set(10,10,10);
mRenderPopupBackground = true;
mPopupBackgroundColor.set(100,100,100);
mPopupTextColor.set(255,255,0);
mSelectHandle = StringTable->insert("common/editor/SelectHandle");
mDefaultHandle = StringTable->insert("common/editor/DefaultHandle");
mLockedHandle = StringTable->insert("common/editor/LockedHandle");
mObjectTextColor.set(255,255,255);
mObjectsUseBoxCenter = true;
mAxisGizmoMaxScreenLen = 200;
mAxisGizmoActive = true;
mMouseMoveScale = 0.2f;
mMouseRotateScale = 0.01f;
mMouseScaleScale = 0.01f;
mMinScaleFactor = 0.1f;
mMaxScaleFactor = 4000.f;
mObjSelectColor.set(255,0,0);
mObjMouseOverSelectColor.set(0,0,255);
mObjMouseOverColor.set(0,255,0);
mShowMousePopupInfo = true;
mDragRectColor.set(255,255,0);
mRenderObjText = true;
mRenderObjHandle = true;
mObjTextFormat = StringTable->insert("$id$: $name$");
mFaceSelectColor.set(0,0,100,100);
mRenderSelectionBox = true;
mSelectionBoxColor.set(255,255,0);
mSelectionLocked = false;
mSnapToGrid = false;
mSnapRotations = false;
mRotationSnap = 15.f;
mToggleIgnoreList = false;
mRenderNav = false;
mIsDirty = false;
mRedirectID = 0;
//
mHitInfo.obj = 0;
mHitObject = mHitInfo.obj;
//
mDefaultMode = mCurrentMode = Move;
mCurrentCursor = 0;
mMouseDown = false;
mDragSelect = false;
//
mSelected.autoSelect(true);
mDragSelected.autoSelect(false);
}
WorldEditor::~WorldEditor()
{
clearUndo(mUndoList);
clearUndo(mRedoList);
}
//------------------------------------------------------------------------------
bool WorldEditor::onAdd()
{
if(!Parent::onAdd())
return(false);
// grab all the cursors
if(!grabCursors())
return(false);
// create the default class entry
mDefaultClassEntry.mName = 0;
mDefaultClassEntry.mIgnoreCollision = false;
mDefaultClassEntry.mDefaultHandle = TextureHandle(mDefaultHandle, BitmapTexture);
mDefaultClassEntry.mSelectHandle = TextureHandle(mSelectHandle, BitmapTexture);
mDefaultClassEntry.mLockedHandle = TextureHandle(mLockedHandle, BitmapTexture);
if(!(mDefaultClassEntry.mDefaultHandle && mDefaultClassEntry.mSelectHandle && mDefaultClassEntry.mLockedHandle))
return(false);
return(true);
}
/// TGE_Map
bool WorldEditor::onWake()
{
if (! Parent::onWake())
return false;
// SimSet * scopeAlwaysSet = Sim::getGhostAlwaysSet();
// for(SimSet::iterator itr = scopeAlwaysSet->begin(); itr != scopeAlwaysSet->end(); itr++)
// {
// TerrainBlock * terrain = dynamic_cast<TerrainBlock*>(*itr);
// if(terrain)
//{
// mTerrainBlock = terrain;
// break;
//}
// }
return true;
}
//------------------------------------------------------------------------------
void WorldEditor::onEditorEnable()
{
// go through and copy the hidden field to the client objects...
for(SimSetIterator itr(Sim::getRootGroup()); *itr; ++itr)
{
SceneObject * obj = dynamic_cast<SceneObject *>(*itr);
if(!obj)
continue;
#ifndef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
// only work with a server obj...
if(obj->isClientObject())
continue;
#endif
// grab the client object
SceneObject * clientObj = getClientObj(obj);
if(!clientObj)
continue;
//
clientObj->setHidden(obj->isHidden());
}
}
//------------------------------------------------------------------------------
void WorldEditor::get3DCursor(GuiCursor *&cursor, bool &visible, const Gui3DMouseEvent &event)
{
event;
cursor = mCurrentCursor;
visible = true;
}
void WorldEditor::on3DMouseMove(const Gui3DMouseEvent & event)
{
// determine the current movement mode based on the modifiers:
if( event.modifier & SI_ALT )
{
// it's either rotate or scale
// probably rotate more often... so rotate = ALT, scale = ALT CTRL
if(event.modifier & SI_CTRL)
mCurrentMode = Scale;
else
mCurrentMode = Rotate;
}
else
mCurrentMode = Move;
setCursor(ArrowCursor);
mHitInfo.obj = 0;
//
mUsingAxisGizmo = false;
if(collideAxisGizmo(event))
{
setCursor(HandCursor);
mUsingAxisGizmo = true;
mHitMousePos = event.mousePoint;
mHitCentroid = mSelected.getCentroid();
mHitRotation = extractEuler(mSelected[0]->getTransform());
mHitObject = mSelected[0];
}
else
{
CollisionInfo info;
if(collide(event, info) && !objClassIgnored(info.obj))
{
setCursor(HandCursor);
mHitInfo = info;
}
}
//
mHitObject = mHitInfo.obj;
mLastMouseEvent = event;
}
void WorldEditor::on3DMouseDown(const Gui3DMouseEvent & event)
{
mMouseDown = true;
mMouseDragged = false;
mLastRotation = 0.f;
mouseLock();
// use ctrl to toggle vertical movement
mUseVertMove = (event.modifier & SI_CTRL);
// determine the current movement mode based on the modifiers:
if( event.modifier & SI_ALT )
{
// it's either rotate or scale
// probably rotate more often... so rotate = ALT, scale = ALT CTRL
if(event.modifier & SI_CTRL)
mCurrentMode = Scale;
else
mCurrentMode = Rotate;
}
else
mCurrentMode = Move;
// check gizmo first
mUsingAxisGizmo = false;
mNoMouseDrag = false;
if(collideAxisGizmo(event))
{
mUsingAxisGizmo = true;
mHitMousePos = event.mousePoint;
mHitCentroid = mSelected.getCentroid();
mHitRotation = extractEuler(mSelected[0]->getTransform());
mHitObject = mSelected[0];
}
else
{
CollisionInfo info;
if(collide(event, info) && !objClassIgnored(info.obj))
{
if(!mSelectionLocked)
{
if(event.modifier & SI_SHIFT)
{
mNoMouseDrag = true;
if(mSelected.objInSet(info.obj))
{
mSelected.removeObject(info.obj);
Con::executef(this, 3, "onUnSelect", avar("%d", info.obj->getId()));
}
else
{
mSelected.addObject(info.obj);
Con::executef(this, 3, "onSelect", avar("%d", info.obj->getId()));
}
}
else
{
if(!mSelected.objInSet(info.obj))
{
mNoMouseDrag = true;
mSelected.clear();
mSelected.addObject(info.obj);
Con::executef(this, 3, "onSelect", avar("%d", info.obj->getId()));
}
}
}
if(event.mouseClickCount > 1)
{
//
char buf[16];
dSprintf(buf, sizeof(buf), "%d", info.obj->getId());
SimObject * obj = 0;
if(mRedirectID)
obj = Sim::findObject(mRedirectID);
Con::executef(obj ? obj : this, 2, "onDblClick", buf);
}
else {
char buf[16];
dSprintf(buf, sizeof(buf), "%d", info.obj->getId());
SimObject * obj = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -