#include "stdafx.h" #include "AreaEditor.h" #include "resource.h" #include "MainFrame.h" #include "TabWindow.h" #include "MapEditorView.h" #include "AreaTransformDialog.h" #include "AreaLightDialog.h" #include "AreaFogDialog.h" #include "AreaEtcDialog.h" #include "TerrainEditor.h" #include "ObjectEditor.h" #include "Engine/MouseAgent.h" #include "Engine/KeyAgent.h" #include "Engine/CameraManager.h" #include "Engine/FreeCamera.h" #include "Engine/WorldManager.h" #include "Engine/SceneManager.h" #include "Engine/AreaSceneNode.h" #include "Engine/Terrain.h" cAreaEditor* cAreaEditor::mSingleton = 0; cAreaEditor::cAreaEditor() : mTransformDialog( 0 ) , mLightDialog( 0 ) , mFogDialog( 0 ) , mEtcDialog( 0 ) , mCreatedSet( 64 ) { assert( mSingleton == 0 && "bad singleton!" ); mSingleton = this; mSelectedNode = SCENEMAN->GetGlobalArea(); mPickedArray.Reserve( 16 ); NiDataStream::GetFactory()->SetCallback( NiDataStreamFactory::ForceCPUReadAccessCallback ); /// °æ°è ±¸¸¦ ·Îµù NiStream stream; if( stream.Load( "MapData/Sphere.nif" ) ) { NiNode* node = NiDynamicCast(NiNode, stream.GetObjectAt(0)); assert( node ); NiMesh* geom = (NiMesh*)node->GetAt( 0 ); assert( geom ); NiMaterialProperty* m = (NiMaterialProperty*)geom->GetProperty( NiProperty::MATERIAL ); assert( m && "null material property" ); mMatProp = m; m->SetAmbientColor( NiColor::WHITE ); m->SetDiffuseColor( NiColor::WHITE ); m->SetSpecularColor( NiColor::WHITE ); m->SetEmittance( NiColor::BLACK ); NiVertexColorProperty* vp = (NiVertexColorProperty*)geom->GetProperty( NiProperty::VERTEX_COLOR ); assert( vp && "null vertex color property" ); vp->SetSourceMode( NiVertexColorProperty::SOURCE_IGNORE ); vp->SetLightingMode( NiVertexColorProperty::LIGHTING_E ); NiWireframeProperty* wp = (NiWireframeProperty*)geom->GetProperty( NiProperty::WIREFRAME ); assert( wp && "null wireframe property" ); wp->SetWireframe( true ); geom->UpdateProperties(); geom->Update( 0.0f ); mSphereGeom = geom; stream.RemoveAllObjects(); } } cAreaEditor::~cAreaEditor() { mSingleton = 0; } void cAreaEditor::Clear() { mCreatedSet.Clear(); mPickedArray.Clear(); if( mTransformDialog ) mTransformDialog->SetEnabled( false ); } void cAreaEditor::Render() { if( mSphereGeom == 0 ) return; NiRenderer* renderer = NiRenderer::GetRenderer(); cCamera* cam = CAMERAMAN->GetCurrent(); NiPoint3 right = cam->GetWorldRightVector(); NiPoint3 up = cam->GetWorldUpVector(); cCreatedSet::cIterator i = mCreatedSet.Begin(); cCreatedSet::cIterator end = mCreatedSet.End(); for( ; i != end; ++i ) { cAreaSceneNode* n = *i; if( n == mSelectedNode ) { mMatProp->SetEmittance( NiColor(1.0f, 0.0f, 0.0f) ); mSphereGeom->UpdateProperties(); } else if( mMatProp->GetEmittance() != NiColor::BLACK ) { mMatProp->SetEmittance( NiColor::BLACK ); mSphereGeom->UpdateProperties(); } mSphereGeom->SetTranslate( n->GetCenter() ); mSphereGeom->SetScale( n->GetRadius() / 100.0f ); mSphereGeom->Update( 0.0f, false ); mSphereGeom->RenderImmediate( renderer ); } } void cAreaEditor::Init() { /// Áö¿ò Clear(); /// ÃʱâÈ­ //SelectArea( 0, true ); } bool cAreaEditor::Save( cFileSaver& saver ) { /// Àå¸é ³ëµåµéÀ» ÀúÀå cCreatedSet::cIterator i = mCreatedSet.Begin(); cCreatedSet::cIterator end = mCreatedSet.End(); for( ; i != end; ++i ) { if( (*i)->Save( saver ) == false ) { assert( 0 && "failed to save area nodes" ); return false; } } return true; } bool cAreaEditor::CreateArea() { cAreaSceneNodeParam param; cAreaSceneNode* n = SCENEMAN->CreateArea( param ); if( n ) { /// »ý¼º ™V¿¡ Ãß°¡ mCreatedSet.Insert( n ); /// »ý¼ºµÈ ¿ÀºêÁ§Æ®¸¦ ¼±Åà SelectArea( n ); /// º¯°æ ¿©ºÎ¸¦ ¼³Á¤ MAIN->SetSceneModified( true ); } return n != 0; } void cAreaEditor::CopyArea() { if( mSelectedNode == 0 ) return; /// ³ëµå¸¦ º¹»ç cAreaSceneNode* n = Clone( mSelectedNode ); if( n == 0 ) { assert( 0 ); return; } /// ¿øº» ±×·ì À§Ä¡ À̵¿ SetAreaTranslate( mSelectedNode->GetTranslate() + NiPoint3(0.0f, 0.0f, 300.0f), true ); /// ºä¸¦ °»½Å VIEW->Update(); /// º¯°æ ¿©ºÎ¸¦ ¼³Á¤ MAIN->SetSceneModified( true ); } bool cAreaEditor::Pick( CPoint point ) { mPickedArray.Clear(); if( SCENEMAN->Pick( &mPickedArray, point.x, point.y, true, SCENENODE_AREA ) ) { SelectArea( (cAreaSceneNode*)mPickedArray[0] ); return true; } else { DeselectAll(); return false; } } void cAreaEditor::DeselectAll() { if( mCreatedSet.IsEmpty() == false && mSelectedNode != SCENEMAN->GetGlobalArea() ) { SelectArea( 0 ); } } void cAreaEditor::SelectArea( cAreaSceneNode* n, bool force ) { if( n == 0 ) n = SCENEMAN->GetGlobalArea(); if( force == false && mSelectedNode == n ) return; else mSelectedNode = n; /// WORLDMAN->SetArea( *n ); /// ´ÙÀ̾ó·Î±×¸¦ °»½Å if( mTransformDialog ) { if( n == SCENEMAN->GetGlobalArea() ) { mTransformDialog->SetEnabled( false ); } else { mTransformDialog->UpdateArea( n->GetWorldTranslate(), n->GetRadius() ); } } if( mLightDialog ) { mLightDialog->UpdateSky( n->GetSkyAmbient(), n->GetSkyDimmer() ); mLightDialog->UpdateTerrain( n->GetTerrainAmbient(), n->GetTerrainDimmer() ); mLightDialog->UpdateStaticObject( n->GetStaticObjectAmbient(), n->GetStaticObjectDimmer() ); mLightDialog->UpdateDynamicObject( n->GetDynamicObjectAmbient(), n->GetDynamicObjectDimmer() ); } if( mFogDialog ) mFogDialog->Update( n->IsFogEnabled(), n->GetFogColor(), n->GetFogDepth() ); if( mEtcDialog ) mEtcDialog->Update( n->GetGroupIndex() ); /// ÁÖº¯±¤À» Àû¿ë WORLDMAN->SetSkyAmbient( n->GetSkyAmbient() ); WORLDMAN->SetSkyDimmer( n->GetSkyDimmer() ); TERRAINEDIT->SetAmbientLightAmbient( n->GetTerrainAmbient() ); TERRAINEDIT->SetAmbientLightDimmer( n->GetTerrainDimmer() ); OBJECTEDIT->SetAmbientLightAmbient( 0, n->GetStaticObjectAmbient() ); OBJECTEDIT->SetAmbientLightDimmer( 0, n->GetStaticObjectDimmer() ); OBJECTEDIT->SetAmbientLightAmbient( 1, n->GetDynamicObjectAmbient() ); OBJECTEDIT->SetAmbientLightDimmer( 1, n->GetDynamicObjectDimmer() ); /// ¾È°³¸¦ Àû¿ë TERRAINEDIT->SetFog( n->IsFogEnabled(), n->GetFogColor(), n->GetFogDepth() ); OBJECTEDIT->SetFog( n->IsFogEnabled(), n->GetFogColor(), n->GetFogDepth() ); /// ºä¸¦ °»½Å VIEW->Update(); } void cAreaEditor::AttachAreaToTerrain( CPoint point ) { if( mSelectedNode == 0 || mSelectedNode == SCENEMAN->GetGlobalArea() ) return; NiPoint3 pos; if( TERRAIN->Pick( &pos, point.x, point.y ) ) { SetAreaTranslate( pos, true ); } } void cAreaEditor::AttachAreaToObject( CPoint point ) { if( mSelectedNode == 0 || mSelectedNode == SCENEMAN->GetGlobalArea() ) return; mPickedArray.Clear(); if( SCENEMAN->Pick( &mPickedArray, point.x, point.y, true, SCENENODE_STATIC ) ) { cSceneNode* n = mPickedArray[0]; SetAreaTranslate( n->GetPickPos(), true ); } } void cAreaEditor::SetAreaTranslate( const NiPoint3& trans, bool updateDialog ) { if( mSelectedNode == 0 || mSelectedNode == SCENEMAN->GetGlobalArea() ) return; mSelectedNode->SetTranslate( trans ); mSelectedNode->Update(); if( updateDialog ) mTransformDialog->UpdateArea( mSelectedNode->GetWorldTranslate(), mSelectedNode->GetRadius() ); VIEW->Update(); /// º¯°æ ¿©ºÎ¸¦ ¼³Á¤ MAIN->SetSceneModified( true ); } void cAreaEditor::SetAreaRadius( float radius, bool updateDialog ) { if( mSelectedNode == 0 || mSelectedNode == SCENEMAN->GetGlobalArea() ) return; float maxr = float(TERRAINEDIT->GetResolution() * TERRAINEDIT->GetMetersPerVertex()) * 25.0f; if( radius < 600.0f ) radius = 600.0f; else if( radius > 20000.0f ) radius = 20000.0f; else if( radius > maxr ) radius = maxr; mSelectedNode->SetRadius( radius ); mSelectedNode->Update(); if( updateDialog ) mTransformDialog->UpdateArea( mSelectedNode->GetWorldTranslate(), mSelectedNode->GetRadius() ); VIEW->Update(); /// º¯°æ ¿©ºÎ¸¦ ¼³Á¤ MAIN->SetSceneModified( true ); } void cAreaEditor::SetAreaGroupIndex( unsigned int groupIndex ) { if( mSelectedNode == 0 || mSelectedNode == SCENEMAN->GetGlobalArea() ) return; mSelectedNode->SetGroupIndex( groupIndex ); /// º¯°æ ¿©ºÎ¸¦ ¼³Á¤ MAIN->SetSceneModified( true ); } bool cAreaEditor::Kill( cAreaSceneNode* node ) { /// »ý¼º ™V¿¡¼­ Á¦°Å mCreatedSet.Erase( node ); /// Àå¸é °ü¸®ÀڷκÎÅÍ Á¦°Å SCENEMAN->DestroyNode( node ); //SCENEMAN->DestroyArea( node ); return true; } cAreaSceneNode* cAreaEditor::Clone( cAreaSceneNode* node ) { cAreaSceneNodeParam param; param.mTranslate = node->GetWorldTranslate(); param.mRotate = node->GetWorldRotate(); param.mScale = node->GetWorldScale(); param.mRadius = node->mRadius; param.mSkyAmbient = node->mSkyAmbient; param.mSkyDimmer = node->mSkyDimmer; param.mTerrainAmbient = node->mTerrainAmbient; param.mTerrainDimmer = node->mTerrainDimmer; param.mStaticObjectAmbient = node->mStaticObjectAmbient; param.mStaticObjectDimmer = node->mStaticObjectDimmer; param.mDynamicObjectAmbient = node->mDynamicObjectAmbient; param.mDynamicObjectDimmer = node->mDynamicObjectDimmer; param.mFogEnabled = node->mFogEnabled; param.mFogColor = node->mFogColor; param.mFogDepth = node->mFogDepth; param.mGroupIndex = node->mGroupIndex; cAreaSceneNode* n = SCENEMAN->CreateArea( param ); if( n ) { /// »ý¼º ™V¿¡ Ãß°¡ mCreatedSet.Insert( n ); } return n; } void cAreaEditor::DeleteArea() { if( mSelectedNode == 0 || mSelectedNode == SCENEMAN->GetGlobalArea() ) return; Kill( mSelectedNode ); SelectArea( 0 ); mTransformDialog->SetEnabled( false ); VIEW->Update(); /// º¯°æ ¿©ºÎ¸¦ ¼³Á¤ MAIN->SetSceneModified( true ); } void cAreaEditor::SetSkyAmbient( const NiColor& color ) { mSelectedNode->SetSkyAmbient( color ); WORLDMAN->SetSkyAmbient( color ); /// º¯°æ ¿©ºÎ¸¦ ¼³Á¤ MAIN->SetSceneModified( true ); } void cAreaEditor::SetSkyDimmer( float dimmer ) { mSelectedNode->SetSkyDimmer( dimmer ); WORLDMAN->SetSkyDimmer( dimmer ); /// º¯°æ ¿©ºÎ¸¦ ¼³Á¤ MAIN->SetSceneModified( true ); } void cAreaEditor::SetTerrainAmbient( const NiColor& color ) { mSelectedNode->SetTerrainAmbient( color ); TERRAINEDIT->SetAmbientLightAmbient( color ); /// º¯°æ ¿©ºÎ¸¦ ¼³Á¤ MAIN->SetSceneModified( true ); } void cAreaEditor::SetTerrainDimmer( float dimmer ) { mSelectedNode->SetTerrainDimmer( dimmer ); TERRAINEDIT->SetAmbientLightDimmer( dimmer ); /// º¯°æ ¿©ºÎ¸¦ ¼³Á¤ MAIN->SetSceneModified( true ); } void cAreaEditor::SetStaticObjectAmbient( const NiColor& color ) { mSelectedNode->SetStaticObjectAmbient( color ); OBJECTEDIT->SetAmbientLightAmbient( 0, color ); /// º¯°æ ¿©ºÎ¸¦ ¼³Á¤ MAIN->SetSceneModified( true ); } void cAreaEditor::SetStaticObjectDimmer( float dimmer ) { mSelectedNode->SetStaticObjectDimmer( dimmer ); OBJECTEDIT->SetAmbientLightDimmer( 0, dimmer ); /// º¯°æ ¿©ºÎ¸¦ ¼³Á¤ MAIN->SetSceneModified( true ); } void cAreaEditor::SetDynamicObjectAmbient( const NiColor& color ) { mSelectedNode->SetDynamicObjectAmbient( color ); OBJECTEDIT->SetAmbientLightAmbient( 1, color ); /// º¯°æ ¿©ºÎ¸¦ ¼³Á¤ MAIN->SetSceneModified( true ); } void cAreaEditor::SetDynamicObjectDimmer( float dimmer ) { mSelectedNode->SetDynamicObjectDimmer( dimmer ); OBJECTEDIT->SetAmbientLightDimmer( 1, dimmer ); /// º¯°æ ¿©ºÎ¸¦ ¼³Á¤ MAIN->SetSceneModified( true ); } void cAreaEditor::SetFog( bool enabled, const NiColor& color, float depth ) { cAreaSceneNode* n = mSelectedNode; n->SetFogEnabled( enabled ); n->SetFogColor( color ); n->SetFogDepth( depth ); TERRAINEDIT->SetFog( enabled, color, n->GetFogDepth() ); OBJECTEDIT->SetFog( enabled, color, n->GetFogDepth() ); /// ºä¸¦ °»½Å VIEW->Update(); /// º¯°æ ¿©ºÎ¸¦ ¼³Á¤ MAIN->SetSceneModified( true ); } void cAreaEditor::SetFogColor( const NiColor& color ) { mSelectedNode->SetFogColor( color ); SelectArea( mSelectedNode, true ); /// ºä¸¦ °»½Å VIEW->Update(); /// º¯°æ ¿©ºÎ¸¦ ¼³Á¤ MAIN->SetSceneModified( true ); } void cAreaEditor::SetFogDepth( float depth ) { cAreaSceneNode* n = mSelectedNode; n->SetFogDepth( depth ); TERRAINEDIT->SetFogDepth( depth ); OBJECTEDIT->SetFogDepth( depth ); /// ºä¸¦ °»½Å VIEW->Update(); /// º¯°æ ¿©ºÎ¸¦ ¼³Á¤ MAIN->SetSceneModified( true ); } void cAreaEditor::OnMouseMove( CPoint point ) { if( MOUSE->IsLButtonDown() ) { if( KEY->IsDown(KEY_X) ) { NiPoint3 t = mTransformDialog->GetTranslate(); t.x += ((point.x - mMousePos.x) - (point.y - mMousePos.y)) * 10.0f; SetAreaTranslate( t, true ); } if( KEY->IsDown(KEY_Y) || KEY->IsDown(KEY_C) ) { NiPoint3 t = mTransformDialog->GetTranslate(); t.y += ((point.x - mMousePos.x) - (point.y - mMousePos.y)) * 10.0f; SetAreaTranslate( t, true ); } if( KEY->IsDown(KEY_Z) ) { NiPoint3 t = mTransformDialog->GetTranslate(); t.z -= (point.y - mMousePos.y) * 10.0f; SetAreaTranslate( t, true ); } if( KEY->IsDown(KEY_R) ) { float r = mTransformDialog->GetRadius(); r += ((point.x - mMousePos.x) - (point.y - mMousePos.y)) * 10.0f; SetAreaRadius( r, true ); } } mMousePos = point; } void cAreaEditor::OnLButtonDown_Transform( CPoint point ) { if( KEY->IsDown(KEY_X) || KEY->IsDown(KEY_Y) || KEY->IsDown(KEY_Z) || KEY->IsDown(KEY_C) || KEY->IsDown(KEY_R) ) { mMousePos = point; return; } switch( mTransformDialog->GetCheckedButton() ) { case IDC_BUTTON_LFORM_PICK: { Pick( point ); } break; case IDC_BUTTON_LFORM_TO_TERRAIN: { AttachAreaToTerrain( point ); } break; case IDC_BUTTON_LFORM_TO_OBJECT: { AttachAreaToObject( point ); } break; } } void cAreaEditor::OnRButtonDown_Transform( CPoint point, bool ctrl ) { if( KEY->IsDown(KEY_X) || KEY->IsDown(KEY_Y) || KEY->IsDown(KEY_Z) || KEY->IsDown(KEY_C) ) { mMousePos = point; return; } if( ctrl ) { cCamera* cam = CAMERAMAN->GetCamera(0); NiPoint3 camPos = cam->GetWorldTranslate(); NiPoint3 pos; mPickedArray.Clear(); bool picked = TERRAIN->Pick( &pos, point.x, point.y ); if( SCENEMAN->Pick( &mPickedArray, point.x, point.y, true, SCENENODE_STATIC ) ) { cSceneNode* n = (cSceneNode*)mPickedArray[0]; const NiPoint3& pickPos = n->GetPickPos(); if( picked ) { if( (pickPos-camPos).Length() < (pos-camPos).Length() ) pos = pickPos; } else { picked = true; pos = pickPos; } } if( picked ) { SetAreaTranslate( pos, true ); } } } void cAreaEditor::OnKeyDown( UINT c ) { switch( c ) { case KEY_DELETE: { if( mSelectedNode == 0 ) return; int mb = MessageBox( 0, "Do you want to delete selected area?", "Area", MB_YESNO ); if( mb == IDYES ) { DeleteArea(); } } break; } }