| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148 |
- /*
- ** Command & Conquer Renegade(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /***********************************************************************************************
- *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
- ***********************************************************************************************
- * *
- * Project Name : LevelEdit *
- * *
- * $Archive:: /Commando/Code/Tools/LevelEdit/SceneEditor.cpp $*
- * *
- * Author:: Patrick Smith *
- * *
- * $Modtime:: 3/12/02 3:31p $*
- * *
- * $Revision:: 116 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "stdafx.h"
- #include "sceneeditor.h"
- #include "nodemgr.h"
- #include "groupmgr.h"
- #include "utils.h"
- #include "matrix3d.h"
- #include "vector.h"
- #include "leveleditdoc.h"
- #include "filemgr.h"
- #include "cameramgr.h"
- #include "leveleditview.h"
- #include "hittestinfo.h"
- #include "collisiongroups.h"
- #include "mainfrm.h"
- #include "wwaudio.h"
- #include "audiblesound.h"
- #include "mesh.h"
- #include "staticphys.h"
- #include "phys3.h"
- #include "_assetmgr.h"
- #include "editorassetmgr.h"
- #include "humanphys.h"
- #include "pathfindsectorbuilder.h"
- #include "pathfind.h"
- #include "node.h"
- #include "mover.h"
- #include "nodefunction.h"
- #include "chunkio.h"
- #include "decophys.h"
- #include "VisPointNode.h"
- #include "editorchunkids.h"
- #include "presetmgr.h"
- #include "combat.h"
- #include "ccamera.h"
- #include "visenum.h"
- #include "staticaabtreecull.h"
- #include "dynamicaabtreecull.h"
- #include "soundscene.h"
- #include "backgroundmgr.h"
- #include "texture.h"
- #include "smartgameobj.h"
- #include "objectnode.h"
- #include "mousemgr.h"
- #include "lightnode.h"
- #include "light.h"
- #include "euler.h"
- #include "w3d_file.h"
- #include "part_emt.h"
- #include "gameobjmanager.h"
- #include "selectpresetdialog.h"
- #include "actionparams.h"
- #include "generatingvisdialog.h"
- #include "generatingedgesampledvisdialog.h"
- #include "generatinglightvisdialog.h"
- #include "visgenprogress.h"
- #include "vissectorsampler.h"
- #include "vismgr.h"
- #include "generatingmanualvisdialog.h"
- #include "heightdb.h"
- #include "staticanimphys.h"
- #include "conversationmgr.h"
- #include "building.h"
- #include "buildingnode.h"
- #include "vistable.h"
- #include "rendobj.h"
- #include "pscene.h"
- #include "leveledit.h"
- #include "visrendercontext.h"
- #include "mapmgr.h"
- #include "editableheightfield.h"
- #include "heightfieldeditor.h"
- #include "heightfieldmgr.h"
- #include "pathmgr.h"
- //////////////////////////////////////////////////////////////////////
- //
- // SceneEditorClass
- //
- //////////////////////////////////////////////////////////////////////
- SceneEditorClass::SceneEditorClass (void)
- : m_SelectionMgr (NULL),
- m_bLightsOn (true),
- m_bAggregateChildrenVisible (true),
- m_bVisPointsDisplayed (0),
- m_TotalVisPoints (0),
- m_ManualVisPointsVisible (true),
- m_MovingObject (NULL),
- m_DisplaySoundSpheres (false),
- m_DisplayLightSpheres (false),
- m_ShowStaticAnimPhys (true),
- m_ShowEditorObjects (true),
- m_BuildingPowerEnabled (true),
- m_CreateProxies (true),
- PhysicsSceneClass ()
- {
- //
- // Ensure that we are initialized
- //
- Initialize ();
- //
- // Set some default light settings
- //
- Enable_Sun_Light (true);
- Set_Ambient_Light (Vector3 (0.3F, 0.3F, 0.3F));
- Set_Sun_Light_Orientation (0.0F, DEG_TO_RADF (50.0F));
- Update_Lighting ();
- return ;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // ~SceneEditorClass
- //
- //////////////////////////////////////////////////////////////////////
- SceneEditorClass::~SceneEditorClass (void)
- {
- Empty_Local_Clipboard ();
- Cleanup_Resources ();
- Remove_All_Vis_Points ();
- return ;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // Initialize
- //
- //////////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Initialize (void)
- {
- //
- // Load the lighting mode from the registry
- //
- int prelit_mode = theApp.GetProfileInt ("Config", "PrelitMode", WW3D::PRELIT_MODE_LIGHTMAP_MULTI_PASS);
- WW3D::Set_Prelit_Mode ((WW3D::PrelitModeEnum)prelit_mode);
- //
- // Initialize some misc variables
- //
- ParticleEmitterClass::Set_Default_Remove_On_Complete (false);
- Cleanup_Resources ();
- m_ManualVisPointsVisible = true;
- m_BuildingPowerEnabled = true;
- PathfindClass::Get_Instance ()->Reset_Sectors ();
- //
- // Create the node and selection managers
- //
- m_SelectionMgr = new SelectionMgrClass;
- //
- // Reset our undo stack
- //
- m_UndoMgr.Purge_Buffers ();
- //
- // Set-up our collision groups
- //
- Disable_All_Collision_Detections (EDITOR_COLLISION_GROUP);
- Disable_All_Collision_Detections (DEF_COLLISION_GROUP);
- Enable_Collision_Detection (DEF_COLLISION_GROUP, DEF_COLLISION_GROUP);
- Enable_All_Collision_Detections (MOUSE_CLICK_COLLISION_GROUP);
- Enable_All_Collision_Detections (15);
- Disable_All_Collision_Detections (STATIC_OBJ_COLLISION_GROUP);
- Enable_Collision_Detection (STATIC_OBJ_COLLISION_GROUP, 15);
- Disable_Collision_Detection (MOUSE_CLICK_COLLISION_GROUP, 15);
- Enable_All_Collision_Detections (GAME_COLLISION_GROUP);
- Disable_Collision_Detection (GAME_COLLISION_GROUP, EDITOR_COLLISION_GROUP);
- //
- // Refresh the per-level include file list
- //
- STRING_LIST &level_includes =::Get_File_Mgr ()->Get_Include_File_List ();
- level_includes.Delete_All ();
- //
- // Reset the pathfind data
- //
- PathfindClass::Get_Instance ()->Reset_Sectors ();
- PathfindClass::Get_Instance ()->Reset_Portals ();
- //
- // Reset the list of conversations
- //
- ConversationMgrClass::Reset_Conversations (ConversationMgrClass::CATEGORY_LEVEL, true);
- //
- // Reset the map
- //
- MapMgrClass::Set_Map_Title (0);
- MapMgrClass::Set_Map_Texture ("");
- MapMgrClass::Set_Map_Center (Vector2 (0.0F, 0.0F));
- MapMgrClass::Set_Map_Scale (Vector2 (0.0F, 0.0F));
- MapMgrClass::Cloud_All_Cells ();
- //
- // Initialize the heightfield system
- //
- HeightfieldMgrClass::Initialize ();
- HeightfieldEditorClass::Initialize ();
- return ;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // Cleanup_Resources
- //
- //////////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Cleanup_Resources (void)
- {
- //
- // Free the background sound
- //
- if (WWAudioClass::Get_Instance () != NULL) {
- WWAudioClass::Get_Instance ()->Set_Background_Music (NULL);
- }
- //
- // Cleanup the different managers
- //
- m_UndoMgr.Purge_Buffers ();
- SAFE_DELETE (m_SelectionMgr);
- NodeMgrClass::Free_Nodes ();
- NetworkObjectMgrClass::Delete_Pending ();
- // Remove all entries from the group list
- Reset_Global_Groups_List ();
- m_MovingObject = NULL;
- //
- // Shutdown the heightfield system
- //
- HeightfieldEditorClass::Shutdown ();
- HeightfieldMgrClass::Shutdown ();
- return ;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // Create_Node
- //
- //////////////////////////////////////////////////////////////////////
- NodeClass *
- SceneEditorClass::Create_Node
- (
- PresetClass * preset,
- Matrix3D * transform,
- DWORD node_id,
- bool add_to_scene
- )
- {
- ::Get_Main_View ()->Allow_Repaint (false);
- CWaitCursor wait_cursor;
- //
- // Create the new node
- //
- NodeClass *node = NodeMgrClass::Create_Node (preset, node_id);
- ASSERT (node != NULL);
- if (node != NULL) {
- //
- // Find a good starting position for this node in the scene
- //
- if (transform != NULL) {
- node->Set_Transform (*transform);
- } else {
- MoverClass::Position_Node (node);
- }
- //
- // Add the new node to the scene
- //
- if (add_to_scene) {
- node->Add_To_Scene ();
- }
-
- //
- // Update the file manager's database
- //
- Update_File_Mgr (node);
- //
- // Repartition the static culling systems if we are dropping
- // in a terrain.
- //
- if (node->Get_Type () == NODE_TYPE_TERRAIN) {
- Re_Partition_Static_Lights ();
- Re_Partition_Audio_System ();
- } else if (node->Get_Type () == NODE_TYPE_WAYPATH) {
- ::Get_Mouse_Mgr ()->Set_Mouse_Mode (MouseMgrClass::MODE_WAYPATH_EDIT);
- MMWaypathEditClass *mode = (MMWaypathEditClass *)::Get_Mouse_Mgr ()->Get_Mode_Mgr ();
- if (mode != NULL) {
- mode->Set_Waypath ((WaypathNodeClass *)node);
- }
- }
- //
- // Create any linked nodes and put them into the scene
- //
- if (preset != NULL) {
- preset->Create_Linked_Nodes (node);
- }
- //
- // Release our hold on the node
- //
- node->Release_Ref ();
- }
- Set_Modified (true);
- ::Get_Main_View ()->Allow_Repaint (true);
- return node;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // Clone_Node
- //
- //////////////////////////////////////////////////////////////////////
- NodeClass *
- SceneEditorClass::Clone_Node (NodeClass *node)
- {
- NodeClass *new_node = node->Clone ();
- if (new_node != NULL) {
- //
- // Make sure the new node has a name and ID
- //
- NodeMgrClass::Setup_Node_Identity (*new_node);
- NodeMgrClass::Add_Node (new_node);
- //
- // Add the new node to the scene
- //
- new_node->Add_To_Scene ();
-
- //
- // Update the file manager's database
- //
- Update_File_Mgr (new_node);
- }
- return new_node;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // Reload_Lightmap_Models
- //
- //////////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Reload_Lightmap_Models (void)
- {
- //
- // Save the setting in the registry
- //
- theApp.WriteProfileInt ("Config", "PrelitMode", WW3D::Get_Prelit_Mode ());
- //
- // Force free the assets...
- //
- WW3DAssetManager::Get_Instance ()->Free_Assets ();
- //
- // Reload the necessary "tool" assets
- //
- CLevelEditDoc *doc = ::Get_Current_Document ();
- if (doc != NULL) {
- doc->Preload_Human_Data ();
- doc->Preload_Tool_Assets ();
- }
- //
- // Reload all the nodes
- //
- NodeMgrClass::Reload_Nodes ();
- //
- // Make sure we don't toss vis
- //
- Validate_Vis ();
- return ;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // Add_Node
- //
- //////////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Add_Node (NodeClass *node)
- {
- NodeMgrClass::Add_Node (node);
- node->Add_To_Scene ();
- Update_File_Mgr (node);
- return ;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // Delete_Node
- //
- //////////////////////////////////////////////////////////////////////
- bool
- SceneEditorClass::Delete_Node (NodeClass *node, bool allow_undo)
- {
- // Add this operation to our undo manager
- if (allow_undo) {
- Begin_Operation (OPERATION_DELETE, node);
- }
-
- //
- // Remove all files that this node was dependent on from the file manager's list
- //
- Update_File_Mgr (node, false);
- //
- // Remove the node from the level
- //
- node->Remove_From_Scene ();
- node->Show_Selection_Box (false);
- node->On_Delete ();
- NodeMgrClass::Remove_Node (node);
- // Notify the undo manager that this operation is over
- if (allow_undo) {
- End_Operation ();
- }
- Set_Modified (true);
- return true;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // Delete_Nodes
- //
- //////////////////////////////////////////////////////////////////////
- bool
- SceneEditorClass::Delete_Nodes (PresetClass *preset)
- {
- bool retval = true;
- //
- // Build a list of nodes to that are dependent on this preset
- //
- DynamicVectorClass<NodeClass *> node_removal_list;
- for ( NodeClass *node = NodeMgrClass::Get_First ();
- node != NULL;
- node = NodeMgrClass::Get_Next (node))
- {
- if (node->Get_Preset () == preset) {
- node_removal_list.Add (node);
- }
- }
- //
- // Remove these nodes from the level
- //
- for (int index = 0; index < node_removal_list.Count (); index ++) {
- retval &= Delete_Node (node_removal_list[index], false);
- }
- return retval;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // Update_File_Mgr
- //
- //////////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Update_File_Mgr
- (
- NodeClass * node,
- bool add_node
- )
- {
- ::Get_File_Mgr ()->Update (node, add_node);
- return ;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // Clone_Objects
- //
- //////////////////////////////////////////////////////////////////////
- bool
- SceneEditorClass::Clone_Objects (void)
- {
- m_SelectionMgr->Clone_Group ();
- //
- // Loop through all the objects in the current selection
- // and update the file manager's information based on them
- //
- int count = m_SelectionMgr->Get_Count ();
- for (int index = 0; index < count; index ++) {
- NodeClass *node = m_SelectionMgr->Get_At (index);
- Update_File_Mgr (node);
- }
- Set_Modified ();
- return true;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // Add_Groups_To_List
- //
- //////////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Add_Groups_To_List
- (
- NodeClass & node,
- GROUP_LIST &group_list
- )
- {
- /*group_list += node.Get_Groups ();
- // Loop through all the children of this node and
- // add their groups to the list as well
- for (NodeInstanceClass *child = node.Get_Child ();
- child != NULL;
- child = child->Get_Sibling ()) {
- Add_Groups_To_List (*child, group_list);
- }*/
- return ;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // Build_Group_List
- //
- //////////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Build_Group_List
- (
- GROUP_LIST & group_list,
- NodeClass * node
- )
- {
- if (node != NULL) {
- Add_Groups_To_List (*node, group_list);
- } else {
- //
- // Loop through all the objects in the current selection
- // and add thier groups to this list
- //
- for (int index = 0; index < m_SelectionMgr->Get_Count (); index ++) {
- NodeClass *node = m_SelectionMgr->Get_At (index);
- if (node != NULL) {
- Add_Groups_To_List (*node, group_list);
- }
- }
- }
-
- return ;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // Add_Nodes_To_List
- //
- //////////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Add_Nodes_To_List
- (
- NodeClass &node,
- NODE_LIST &node_list
- )
- {
- //
- // Loop through all the children of this node and
- // add them and their children to the list as well
- //
- /*for (NodeInstanceClass *child = node.Get_Child ();
- child != NULL;
- child = child->Get_Sibling ()) {
-
- if (child->Is_Owner_Only () == false) {
- node_list.Add_Unique (child);
- }
-
- Add_Nodes_To_List (*child, node_list);
- }*/
-
- return ;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // Build_Node_List
- //
- //////////////////////////////////////////////////////////////////////
- Vector3
- SceneEditorClass::Build_Node_List (NODE_LIST &node_list)
- {
- //
- // Add all the nodes from the selection set to the list
- //
- for (int index = 0; index < m_SelectionMgr->Get_Count (); index ++) {
- NodeClass *node = m_SelectionMgr->Get_At (index);
- if (node != NULL) {
- node_list.Add_Unique (node);
- }
- }
- m_SelectionMgr->Set_Dirty ();
- return m_SelectionMgr->Get_Center ();
- }
- //////////////////////////////////////////////////////////////////////
- //
- // Build_Node_List
- //
- //////////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Build_Node_List
- (
- NODE_LIST & node_list,
- NodeClass * parent_node
- )
- {
- //
- // Build a complete list of all the groups in the selection set
- //
- GROUP_LIST group_list;
- Build_Group_List (group_list, parent_node);
- // Loop through all the objects of all the groups in the selection
- // set and add them to the list
- for (int group = 0; group < group_list.Count (); group ++) {
- GroupMgrClass *group_mgr = group_list[group];
- group_mgr->Set_Dirty ();
- for (int index = 0; index < group_mgr->Get_Count (); index ++) {
- NodeClass *node = group_mgr->Get_At (index);
- if (node != NULL) {
- node_list.Add_Unique (node);
- Add_Nodes_To_List (*node, node_list);
- }
- }
- }
- //
- // Don't forget to add the nodes from the selection group as well!
- //
- if (parent_node == NULL) {
-
- for (int index = 0; index < m_SelectionMgr->Get_Count (); index ++) {
- NodeClass *node = m_SelectionMgr->Get_At (index);
- if (node != NULL) {
- node_list.Add_Unique (node);
- Add_Nodes_To_List (*node, node_list);
- }
- }
- } else {
- /*if (parent_node->Is_Owner_Only () == false) {
- node_list.Add_Unique (pparent_node);
- }
- Add_Nodes_To_List (*pparent_node, node_list);*/
- }
- return ;
- }
- ///////////////////////////////////////////////////////////////
- //
- // Delete_Nodes
- //
- ///////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Delete_Nodes (void)
- {
- NODE_LIST affected_list;
- //
- // Build a list of all the nodes that are affected by this operation
- //
- for (int index = 0; index < m_SelectionMgr->Get_Count (); index ++) {
- NodeClass *node = m_SelectionMgr->Get_At (index);
- if (node != NULL) {
-
- // Add this node to our list of affected nodes
- affected_list.Add_Unique (node);
- }
- }
- // Add this operation to our undo manager
- Begin_Operation (OPERATION_DELETE, &affected_list);
- //
- // Perfrom the actual delete operation
- //
- for (index = 0; index < affected_list.Count (); index ++) {
- Delete_Node (affected_list[index], false);
- }
-
- // Notify the undo manager that this operation is over
- End_Operation ();
- // Reset the contents of the selection.
- // Note: We create a temporary group here to keep a refcount
- // locked on the selected nodes while we delete the selection group.
- // Remember, freeing the selection group decrements the node's refcounts.
- //GroupMgrClass temp_group = *m_SelectionMgr;
- m_SelectionMgr->Free_List ();
- return ;
- }
- ///////////////////////////////////////////////////////////////
- //
- // Set_Selection
- //
- ///////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Set_Selection (NodeClass *node)
- {
- // Is this item already in the list?
- if (m_SelectionMgr->Is_Item_In_Group (node) == false) {
- //
- // Make this node the only selected node
- //
- m_SelectionMgr->Reset ();
- m_SelectionMgr->Add_Node (node);
- Update_Toolbars ();
- }
-
- return ;
- }
- ///////////////////////////////////////////////////////////////
- //
- // Toggle_Selection
- //
- ///////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Toggle_Selection (NodeClass *node)
- {
- //
- // If this node isn't already in the selection set, then
- // add it. However, if its in the selection set, remove it.
- //
- if (m_SelectionMgr->Is_Item_In_Group (node)) {
- m_SelectionMgr->Remove_Node (node);
- } else {
- m_SelectionMgr->Add_Node (node);
- }
- Update_Toolbars ();
- return ;
- }
- ///////////////////////////////////////////////////////////////
- //
- // Update_Toolbars
- //
- ///////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Update_Toolbars (void)
- {
- bool show_ani_toolbar = false;
- int frame = 0;
- int max_frames = 0;
- if (m_SelectionMgr->Get_Count () > 0) {
-
- //
- // Loop through all the objects in the current selection
- // and output their names to the debug window...
- //
- CString selection_set = "Selection set: ";
- int sel_count = min (m_SelectionMgr->Get_Count (), 4);
- for (int index = 0; index < sel_count; index ++) {
- NodeClass *node = m_SelectionMgr->Get_At (index);
- selection_set += node->Get_Name ();
-
- //
- // Print vis-id and occluder status if we're only printing one object
- //
- PhysClass *phys_obj = node->Peek_Physics_Obj ();
- if (m_SelectionMgr->Get_Count () == 1 && phys_obj != NULL) {
- StaticPhysClass *static_phys_obj = phys_obj->As_StaticPhysClass();
- if (static_phys_obj != NULL) {
- selection_set += (" (");
- CString visid_string;
- visid_string.Format(" VisObjectId = %d, ",static_phys_obj->Get_Vis_Object_ID());
- selection_set += visid_string;
- visid_string.Format(" VisSectorId = %d, ",static_phys_obj->Get_Vis_Sector_ID());
- selection_set += visid_string;
- AABTreeLinkClass *link = (AABTreeLinkClass *)static_phys_obj->Get_Cull_Link ();
- if (link != NULL) {
- visid_string.Format(" CullLink = %d, ",link->Node->Index);
- selection_set += visid_string;
- }
- if (!static_phys_obj->Is_Occluder()) {
- selection_set += CString(" Non-Occluder ");
- }
- selection_set += (")");
- } else if (node->Get_Type () == NODE_TYPE_LIGHT) {
- selection_set += (" (");
- CString visid_string;
- visid_string.Format(" VisSectorId = %d, ",((LightNodeClass *)node)->Get_Vis_Sector_ID());
- selection_set += visid_string;
- selection_set += (")");
- } else {
- selection_set += (" (");
- CString visid_string;
- visid_string.Format(" VisObjectId = %d, ",phys_obj->Get_Vis_Object_ID());
- selection_set += visid_string;
- selection_set += (")");
- }
- }
- selection_set += ", ";
- }
- if (sel_count < m_SelectionMgr->Get_Count ()) {
- selection_set += "and many more....";
- }
- //
- // Now output this string to the debug window
- //
- selection_set += "\r\n";
- ::Output_Message (selection_set);
- }
- // Show/hide the animation toolbar depending on the current state
- CMainFrame *pmainwnd = (CMainFrame *)::AfxGetMainWnd ();
- if (pmainwnd != NULL) {
- pmainwnd->Show_Ani_Toolbar (show_ani_toolbar);
- pmainwnd->Update_Ani_Frame (frame, max_frames);
- }
- return ;
- }
- ///////////////////////////////////////////////////////////////
- //
- // Find_Node_At_Point
- //
- ///////////////////////////////////////////////////////////////
- NodeClass *
- SceneEditorClass::Find_Node_At_Point (CPoint point, Vector3 *intersect_pt)
- {
- //
- // Calculate the ray from the current camera pos through
- // the mouse cursor.
- //
- Vector3 ray_start;
- Vector3 ray_end;
- MoverClass::Get_Mouse_Ray (point, 250.0F, ray_start, ray_end);
- //
- // Cast the ray into the world
- //
- CastResultStruct res;
- if (intersect_pt != NULL) {
- res.ComputeContactPoint = true;
- }
- PhysClass *physobj = MoverClass::Cast_Ray (res, ray_start, ray_end, MOUSE_CLICK_COLLISION_GROUP);
- if ((physobj != NULL) && (physobj->Peek_Model() != NULL)) {
- WWDEBUG_SAY(("Picked model: %s\r\n",physobj->Peek_Model()->Get_Name()));
- }
- //
- // Get the node's pointer that was hit from the raycast
- //
- NodeClass *node = NULL;
- if (physobj != NULL) {
- HITTESTINFO *hit_info = (HITTESTINFO *)physobj->Peek_Model ()->Get_User_Data ();
- if (hit_info != NULL && hit_info->Type == HITTESTINFO::Node) {
- node = hit_info->node;
- //
- // Return the intersection point (if requested)
- //
- if (intersect_pt != NULL) {
- (*intersect_pt) = res.ContactPoint;
- }
- }
- }
-
- // Return a pointer to the node
- return node;
- }
- ///////////////////////////////////////////////////////////////
- //
- // Execute_Function_At_Point
- //
- ///////////////////////////////////////////////////////////////
- bool
- SceneEditorClass::Execute_Function_At_Point (CPoint point)
- {
- bool processed = false;
- //
- // Calculate the ray from the current camera pos through
- // the mouse cursor.
- //
- Vector3 ray_start;
- Vector3 ray_end;
- MoverClass::Get_Mouse_Ray (point, 250.0F, ray_start, ray_end);
-
- //
- // Cast the ray into the world
- //
- CastResultStruct res;
- PhysClass *physobj = MoverClass::Cast_Ray (res, ray_start, ray_end, MOUSE_CLICK_COLLISION_GROUP);
- //
- // Determine if the user clicked on a 'function'
- //
- NodeClass *node = NULL;
- if (physobj != NULL) {
-
- HITTESTINFO *hit_info = (HITTESTINFO *)physobj->Peek_Model ()->Get_User_Data ();
- if ((hit_info != NULL) && hit_info->Type == HITTESTINFO::Function) {
- hit_info->function->On_Click ();
- processed = true;
- }
- }
-
- // Return the true/false result code
- return processed;
- }
- ///////////////////////////////////////////////////////////////
- //
- // Move_Selected_Nodes
- //
- ///////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Move_Selected_Nodes (void)
- {
- float speed_modifier = ::Get_Camera_Mgr ()->Get_Speed_Modifier ();
- float modifier = (::GetAsyncKeyState (VK_CONTROL) < 0) ? speed_modifier : 1.0F;
- Matrix3D coord_system = ::Get_Camera_Mgr ()->Get_Camera ()->Get_Transform ();
- bool move_object = false;
- Vector3 delta (0, 0, 0);
- if (::GetAsyncKeyState (VK_LEFT) < 0) {
- //
- // Move the objects along the x-axis of the current view
- //
- Vector3 movement (-0.05F * modifier, 0, 0);
- delta += coord_system.Rotate_Vector (movement);
- move_object = true;
- } else if (::GetAsyncKeyState (VK_RIGHT) < 0) {
- //
- // Move the objects along the x-axis of the current view
- //
- Vector3 movement (0.05F * modifier, 0, 0);
- delta += coord_system.Rotate_Vector (movement);
- move_object = true;
- }
- if (::GetAsyncKeyState (VK_UP) < 0) {
- //
- // Should we move the object 'up'?
- //
- if (::GetAsyncKeyState (VK_SHIFT) < 0) {
- delta += Vector3 (0, 0, 0.05F * modifier);
- } else {
- //
- // Move the object along the 'ground-plane' at an axis orthogonal to the view's x-axis.
- //
- Vector3 y_vector = Vector3::Cross_Product (coord_system.Get_X_Vector (), Vector3 (0, 0, 1));
- y_vector.Normalize ();
- delta += y_vector * (-0.05F * modifier);
- }
- move_object = true;
- } else if (::GetAsyncKeyState (VK_DOWN) < 0) {
- //
- // Should we move the object 'up'?
- //
- if (::GetAsyncKeyState (VK_SHIFT) < 0) {
- delta += Vector3 (0, 0, -0.05F * modifier);
- } else {
- //
- // Move the object along the 'ground-plane' at an axis orthogonal to the view's x-axis.
- //
- Vector3 y_vector = Vector3::Cross_Product (coord_system.Get_X_Vector (), Vector3 (0, 0, 1));
- y_vector.Normalize ();
- delta += y_vector * (0.05F * modifier);
- }
- move_object = true;
- }
- //
- // Move the selected nodes if necessary
- //
- if (move_object) {
- MoverClass::Move_Nodes (delta);
- }
-
- return ;
- }
- ///////////////////////////////////////////////////////////////
- //
- // On_Frame
- //
- ///////////////////////////////////////////////////////////////
- void
- SceneEditorClass::On_Frame (void)
- {
- //
- // Let the heightfield editor think
- //
- HeightfieldEditorClass::On_Frame_Update ();
- //
- // Get the currently 'focussed' process
- //
- HWND current_focus_wnd = ::GetFocus ();
- DWORD process_id = 0;
- if (current_focus_wnd != NULL) {
- ::GetWindowThreadProcessId (current_focus_wnd, &process_id);
- }
- //
- // If we are the current process, then move the nodes
- //
- if (process_id == ::GetCurrentProcessId ()) {
- Move_Selected_Nodes ();
- }
- if (m_MovingObject != NULL) {
- PathMgrClass::Resolve_Paths (Vector3 (0, 0, 0));
- PhysicalGameObj *game_obj = ((ObjectNodeClass *)m_MovingObject)->Peek_Game_Obj ();
- ((SmartGameObj *)game_obj)->Generate_Control ();
- game_obj->Think ();
- PhysClass *phys_obj = game_obj->Peek_Physical_Object ();
- if (phys_obj != NULL) {
- phys_obj->Timestep (TimeManager::Get_Frame_Seconds ());
- }
- game_obj->Post_Think ();
- #if 0
- ActionClass *action = ((SmartGameObj *)game_obj)->Get_Action ();
- if (action != NULL && action->Get_Movement () == NULL) {
- //m_MovingObject = NULL;
- }
- #endif
- }
- return ;
- }
- ///////////////////////////////////////////////////////////////
- //
- // Record_Vis_Info
- //
- ///////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Record_Vis_Info (const Matrix3D &view_transform, const Vector3 &sample_location)
- {
- // Put up an hour glass
- CWaitCursor wait_cursor;
- PresetClass *preset = PresetMgrClass::Get_First (CLASSID_VIS_POINT_DEF, PresetMgrClass::ID_CLASS);
- if (preset == NULL) {
- CString message = "Missing 'Manual Vis Point' preset. Please create a default preset under the 'Manual Vis Point' folder in the preset library.";
- ::MessageBox (::AfxGetMainWnd ()->m_hWnd, message, "Missing Preset", MB_OK | MB_ICONEXCLAMATION);
- } else {
- //
- // When doing a manual vis, use the FOV and clip settings of the in-game camera
- //
- CameraClass *scene_cam = CombatManager::Get_Camera ();
- WWASSERT (scene_cam != NULL);
-
- float scene_znear = 0;
- float scene_zfar = 0;
- scene_cam->Get_Clip_Planes (scene_znear, scene_zfar);
- scene_cam->Set_Clip_Planes (scene_znear, VIS_FAR_CLIP);
- //
- // Generate the 'vis' information
- //
- VisSampleClass vis_sample = Update_Vis (view_transform * Vector3 (0, 0, -scene_znear), view_transform, (VisDirBitsType)(VIS_FORWARD_BIT | VIS_DONT_RECENTER), scene_cam);
- if (vis_sample.Get_Bits_Changed () > 0 && vis_sample.Sample_Rejected () == false) {
-
- //
- // Convert the matrix to an obj-space transform
- //
- Matrix3D cam_to_world (Vector3 (0, 0, -1), Vector3 (-1, 0, 0), Vector3 (0, 1, 0), Vector3 (0, 0, 0));
- Matrix3D obj_tm = view_transform * cam_to_world;
- //
- // Create the UI
- //
- Create_Vis_Point (view_transform);
- VisPointNodeClass *vis_point = new VisPointNodeClass (preset);
- vis_point->Set_ID (::Get_Node_Mgr ().Get_Node_ID (vis_point->Get_Type ()));
- vis_point->Initialize ();
- vis_point->Add_To_Scene ();
- vis_point->Set_Transform (obj_tm);
- vis_point->Set_Vis_Tile_Location (sample_location);
- vis_point->Save_Camera_Settings (*scene_cam);
- vis_point->Hide (!m_ManualVisPointsVisible);
- ::Get_Node_Mgr ().Add_Node (vis_point);
- vis_point->Release_Ref ();
- Set_Modified (true);
- }
- //
- // Put the normal settings back into the scene camera
- //
- scene_cam->Set_Clip_Planes (scene_znear, scene_zfar);
- }
- return ;
- }
- ///////////////////////////////////////////////////////////////
- //
- // Begin_Operation
- //
- ///////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Begin_Operation
- (
- OPERATION_TYPE type,
- NodeClass * node
- )
- {
- if (node != NULL) {
-
- // Build a list containing the node
- NODE_LIST node_list;
- node_list.Add_Unique (node);
- // Pass this list onto the undo manager
- Begin_Operation (type, &node_list);
- }
- return ;
- }
- ///////////////////////////////////////////////////////////////
- //
- // Begin_Operation
- //
- ///////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Begin_Operation
- (
- OPERATION_TYPE type,
- NODE_LIST * affected_list
- )
- {
- NODE_LIST node_list;
- //
- // If necessary, build a complete list of all the nodes that will be
- // affected by this operation
- //
- if (affected_list == NULL) {
- Build_Node_List (node_list, NULL);
- affected_list = &node_list;
- }
- m_UndoMgr.Begin_Operation (type, *affected_list);
- return ;
- }
- ///////////////////////////////////////////////////////////////
- //
- // End_Operation
- //
- ///////////////////////////////////////////////////////////////
- void
- SceneEditorClass::End_Operation (void)
- {
- m_UndoMgr.End_Operation ();
- return ;
- }
- ///////////////////////////////////////////////////////////////
- //
- // Undo
- //
- ///////////////////////////////////////////////////////////////
- bool
- SceneEditorClass::Undo (void)
- {
- m_UndoMgr.Perform_Undo ();
- return true;
- }
- ///////////////////////////////////////////////////////////////
- //
- // Cut_Objects
- //
- ///////////////////////////////////////////////////////////////
- bool
- SceneEditorClass::Cut_Objects (void)
- {
- bool retval = false;
- // Turn painting off
- CLevelEditView::Allow_Repaint (false);
- // Copy the objects to the clipboard, then delete them
- if (Copy_Objects ()) {
- Delete_Nodes ();
- }
- // Turn painting back on
- CLevelEditView::Allow_Repaint (true);
- // Return the true/false result code
- return retval;
- }
- ///////////////////////////////////////////////////////////////
- //
- // Copy_Objects
- //
- ///////////////////////////////////////////////////////////////
- bool
- SceneEditorClass::Copy_Objects (void)
- {
- Empty_Local_Clipboard ();
-
- // Loop through all the nodes in the current selection
- // and 'copy' them.
- int count = m_SelectionMgr->Get_Count ();
- for (int index = 0; index < count; index ++) {
- NodeClass *node = m_SelectionMgr->Get_At (index);
- //
- // Copy the node and add it to our 'clipboard'
- //
- NodeClass *node_copy = node->Clone ();
- ASSERT (node_copy != NULL);
- if (node_copy != NULL) {
- node_copy->Remove_From_Scene ();
- m_LocalClipboard.Add (node_copy);
- }
- }
-
- return true;
- }
- ///////////////////////////////////////////////////////////////
- //
- // Paste_Objects
- //
- ///////////////////////////////////////////////////////////////
- bool
- SceneEditorClass::Paste_Objects (void)
- {
- bool retval = (m_LocalClipboard.Count () > 0);
- // Turn painting off
- CLevelEditView::Allow_Repaint (false);
- // Reset the selection group
- m_SelectionMgr->Reset ();
- for (int index = 0; index < m_LocalClipboard.Count (); index ++) {
-
- //
- // Copy the node on the clipboard and add it to the scene
- //
- NodeClass *node = m_LocalClipboard[index];
- NodeClass *node_copy = Clone_Node (node);
- if (node_copy != NULL) {
- m_SelectionMgr->Add_Node (node_copy);
- MEMBER_RELEASE (node_copy);
- }
- }
-
- //
- // Cast the nodes along the line-of-sight ray for 500 meters
- //
- Vector3 ray_start;
- Vector3 ray_end;
- MoverClass::Get_LOS_Ray (500.0F, ray_start, ray_end);
- MoverClass::Position_Nodes_Along_Ray (ray_start, ray_end);
- // Turn painting back on
- CLevelEditView::Allow_Repaint (true);
- Update_Toolbars ();
-
- // Return the true/false result code
- return retval;
- }
- ///////////////////////////////////////////////////////////////
- //
- // Can_Paste
- //
- ///////////////////////////////////////////////////////////////
- bool
- SceneEditorClass::Can_Paste (void)
- {
- // Return the true/false result code
- return bool(m_LocalClipboard.Count () > 0);
- }
- ///////////////////////////////////////////////////////////////
- //
- // Empty_Local_Clipboard
- //
- ///////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Empty_Local_Clipboard (void)
- {
- // Loop through all the entries in the clipboard and delete them
- for (int index = 0; index < m_LocalClipboard.Count (); index ++) {
- MEMBER_RELEASE (m_LocalClipboard[index]);
- }
- // Reset the list
- m_LocalClipboard.Delete_All ();
- return ;
- }
- ///////////////////////////////////////////////////////////////
- //
- // Add_Global_Group
- //
- ///////////////////////////////////////////////////////////////
- GroupMgrClass *
- SceneEditorClass::Add_Global_Group
- (
- const CString & name,
- NODE_LIST * initial_list
- )
- {
- // Create a new group with the speicfied name
- UserGroupMgrClass *group = new UserGroupMgrClass;
- group->Set_Name (name);
- // If we have a list of nodes to add to this group,
- // then do so now.
- if (initial_list != NULL) {
- for (int index = 0; index < initial_list->Count (); index ++) {
- group->Add_Node ((*initial_list)[index]);
- }
- }
- // Add this new group manager to our global list
- m_GroupsList.Add_Unique (group);
- // Return a pointer to the new group
- return group;
- }
- ///////////////////////////////////////////////////////////////
- //
- // Remove_Global_Group
- //
- ///////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Remove_Global_Group (GroupMgrClass *group)
- {
- // If this group is in our global list, then remove
- // it from the list, remove it from any UI, and free its memory.
- if (m_GroupsList.Is_Item_In_List (group)) {
- m_GroupsList.Remove (group);
- Remove_Group_From_Toolbar (group);
- SAFE_DELETE (group);
- }
- return ;
- }
- ///////////////////////////////////////////////////////////////
- //
- // Reset_Global_Groups_List
- //
- ///////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Reset_Global_Groups_List (void)
- {
- // Loop through all the groups in our list and
- // free their associated memory.
- for (int index = 0; index < m_GroupsList.Count (); index ++) {
- GroupMgrClass *group = m_GroupsList[index];
- if (group != NULL) {
- Remove_Group_From_Toolbar (group);
- SAFE_DELETE (group);
- }
- }
- // Remove all the entries from the list
- m_GroupsList.Delete_All ();
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Add_Group_To_Toolbar
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Add_Group_To_Toolbar (GroupMgrClass *group)
- {
- ASSERT (group != NULL);
-
- // Get the form representing the groups list, and add this group to it
- /*GroupsPageClass *group_page = ::Get_Groups_Form ();
- if (group_page != NULL) {
- group_page->Add_Group (group);
- }*/
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Remove_Group_From_Toolbar
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Remove_Group_From_Toolbar (GroupMgrClass *group)
- {
- ASSERT (group != NULL);
-
- // Get the form representing the groups list, and remove this group from it
- /*GroupsPageClass *group_page = ::Get_Groups_Form ();
- if (group_page != NULL) {
- group_page->Remove_Group (group);
- }*/
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Turn_Lights_On
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Turn_Lights_On (bool onoff)
- {
- m_bLightsOn = onoff;
- //
- // Loop through all the lights in the world
- //
- /*LightInstanceClass *plight = NULL;
- for (plight = (LightInstanceClass *)::Get_Node_Mgr ().Get_First (NODE_TYPE_LIGHT);
- plight != NULL;
- plight = (LightInstanceClass *)::Get_Node_Mgr ().Get_Next (NODE_TYPE_LIGHT)) {
- plight->Turn_Light_On (onoff);
- }*/
-
- ::Refresh_Main_View ();
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Lock_Nodes
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Lock_Nodes (bool lock)
- {
- //
- // Loop through all the nodes in the current selection
- //
- for (int index = 0; index < m_SelectionMgr->Get_Count (); index ++) {
- NodeClass *node = m_SelectionMgr->Get_At (index);
- if (node != NULL) {
-
- //
- // Lock the node, this keep the node from moving during
- // drag operations.
- //
- node->Lock (lock);
- }
- }
-
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Set_Background_Music
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Set_Background_Music (LPCTSTR filename)
- {
- //
- // Stop the old sound
- //
- WWAudioClass::Get_Instance ()->Set_Background_Music (NULL);
- //
- // Remove the sound file from the file manager
- //
- if (m_BackgroundSoundFilename.GetLength () > 0) {
-
- CString old_path = ::Get_File_Mgr ()->Make_Full_Path (m_BackgroundSoundFilename);
- ::Get_File_Mgr ()->Remove_File (::Get_File_Mgr ()->Find_File (old_path));
- m_BackgroundSoundFilename.Empty ();
- }
- //
- // Set the new background music
- //
- if ((filename != NULL) && (filename[0] != 0)) {
- CString path = ::Get_File_Mgr ()->Make_Full_Path (filename);
- if (::Get_File_Mgr ()->Does_File_Exist (path, true)) {
-
- //
- // Set the background music
- //
- ::Set_Current_Directory (::Strip_Filename_From_Path (path));
- WWAudioClass::Get_Instance ()->Set_Background_Music (::Get_Filename_From_Path (path));
- //
- // Add this sound to the file manager
- //
- ::Get_File_Mgr ()->Add_File (path);
- m_BackgroundSoundFilename = path;
- }
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // View_Aggregate_Children
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::View_Aggregate_Children (bool view)
- {
- // Did the state change?
- /*if (view != m_bAggregateChildrenVisible) {
- m_bAggregateChildrenVisible = view;
- // Make sure to reset the selection for this to work
- m_SelectionMgr->Reset ();
- // Update all the aggregates in the level
- ::Get_Node_Mgr ().Update_Aggregate_Instances ();
- }*/
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Display_Vis_Points
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Display_Vis_Points (bool onoff)
- {
- // Did the state change?
- if (onoff != m_bVisPointsDisplayed) {
- m_bVisPointsDisplayed = onoff;
- //
- // Show/hide all the vis points
- //
- for (int index = 0; index < m_VisPoints.Count (); index ++) {
- DecorationPhysClass *vis_point = m_VisPoints[index];
- if (vis_point != NULL) {
- if (onoff) {
- Add_Dynamic_Object (vis_point);
- } else {
- Remove_Object (vis_point);
- }
- }
- }
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Create_Vis_Point
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Create_Vis_Point (const Matrix3D &transform)
- {
- //
- // Create a new vis-point marker at the location
- //
- DecorationPhysClass *new_point = new DecorationPhysClass;
- new_point->Set_Model_By_Name ("WAYSTART");
- new_point->Set_Transform (transform);
- new_point->Set_Collision_Group (0);
- //
- // Add this new point to our list
- //
- m_VisPoints.Add (new_point);
- if (m_bVisPointsDisplayed) {
- Add_Dynamic_Object (new_point);
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Remove_All_Vis_Points
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Remove_All_Vis_Points (void)
- {
- ::Get_Main_View ()->Allow_Repaint (false);
- CWaitCursor wait_cursor;
- //
- // Build a list of all the vis points in the world
- //
- for (int index = 0; index < m_VisPoints.Count (); index ++) {
- DecorationPhysClass *vis_point = m_VisPoints[index];
- if (vis_point != NULL) {
- Remove_Object (vis_point);
- vis_point->Release_Ref ();
- }
- }
- m_VisPoints.Delete_All ();
- ::Get_Main_View ()->Allow_Repaint (true);
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Discard_Vis
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Discard_Vis (void)
- {
- m_VisLog.Reset_Log ();
- Remove_All_Vis_Points ();
- PhysicsSceneClass::Internal_Vis_Reset ();
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Reset_Vis
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Reset_Vis (bool doitnow)
- {
- m_VisLog.Reset_Log ();
- Remove_All_Vis_Points ();
- PhysicsSceneClass::Reset_Vis (doitnow);
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Internal_Vis_Reset
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Internal_Vis_Reset (void)
- {
- if (VisResetNeeded) {
- PhysicsSceneClass::Internal_Vis_Reset ();
- //
- // Ask all the nodes
- //
- NodeClass *node = NULL;
- for ( node = NodeMgrClass::Get_First ();
- node != NULL;
- node = NodeMgrClass::Get_Next (node))
- {
- node->Update_Cached_Vis_IDs ();
- }
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Get_Vis_Camera_FOV
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Get_Vis_Camera_FOV (double &hfov, double &vfov)
- {
- CameraClass *vis_camera = Get_Vis_Camera ();
- WWASSERT (vis_camera != NULL);
- if (vis_camera != NULL) {
- hfov = vis_camera->Get_Horizontal_FOV ();
- vfov = vis_camera->Get_Vertical_FOV ();
- MEMBER_RELEASE (vis_camera);
- } else {
- hfov = 0;
- vfov = 0;
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Get_Vis_Camera_Clip_Planes
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Get_Vis_Camera_Clip_Planes (float &znear, float &zfar)
- {
- CameraClass *vis_camera = Get_Vis_Camera ();
- WWASSERT (vis_camera != NULL);
- if (vis_camera != NULL) {
- vis_camera->Get_Clip_Planes (znear, zfar);
- MEMBER_RELEASE (vis_camera);
- } else {
- znear = 0;
- zfar = 0;
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Get_Render_Camera
- //
- ////////////////////////////////////////////////////////////////
- CameraClass *
- SceneEditorClass::Get_Render_Camera (void)
- {
- CameraClass *camera = NULL;
- if (::Get_Camera_Mgr ()->Get_Camera_Mode () == CameraMgr::MODE_WALK_THROUGH) {
- camera = CombatManager::Get_Camera ();
- } else {
- camera = ::Get_Camera_Mgr ()->Get_Camera ();
- }
- return camera;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Generate_Pathfind_Portals
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Generate_Pathfind_Portals (void)
- {
- CWaitCursor wait_cursor;
- //
- // Create a pathfind floodfiller object
- //
- PathfindSectorBuilderClass builder;
- builder.Allow_Water_Floodfill (true);
- builder.Initialize ();
- //
- // Find all the pathfind start-points in the level and add
- // them to the floodfiller
- //
- NodeClass *node = NULL;
- for ( node = NodeMgrClass::Get_First ();
- node != NULL;
- node = NodeMgrClass::Get_Next (node))
- {
- if (node->Get_Type () == NODE_TYPE_PATHFIND_START) {
- builder.Add_Start_Point (node->Get_Transform ().Get_Translation ());
- }
- }
-
- //
- // Perform the floodfill from each of the start locations
- //
- builder.Generate_Sectors ();
- builder.Compress_Sectors_For_Pathfind ();
- //
- // Build height data for flying vehicles
- //
- HeightDBClass::Generate ();
- //
- // Cleanup
- //
- builder.Shutdown ();
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Export_VIS
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Export_VIS (LPCTSTR filename)
- {
- //
- // Create the file
- //
- HANDLE hfile = ::CreateFile (filename,
- GENERIC_WRITE,
- 0,
- NULL,
- CREATE_ALWAYS,
- 0L,
- NULL);
- ASSERT (hfile != INVALID_HANDLE_VALUE);
- if (hfile != INVALID_HANDLE_VALUE) {
- RawFileClass file_obj;
- file_obj.Attach (hfile);
- ChunkSaveClass chunk_save (&file_obj);
- //
- // Export the data to this file
- //
- Export_Vis_Data (chunk_save);
- }
-
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Update_Selection_Boxes
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Update_Selection_Boxes (void)
- {
- //
- // Loop through all the nodes in the current selection
- //
- for (int index = 0; index < m_SelectionMgr->Get_Count (); index ++) {
- NodeClass *node = m_SelectionMgr->Get_At (index);
- if (node != NULL) {
-
- //
- // Ask the node to update its selection box (color and pos)
- //
- node->Update_Selection_Box ();
- }
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Re_Partition_Audio_System
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Re_Partition_Audio_System (void)
- {
- const AABoxClass & level_bounds = StaticCullingSystem->Get_Bounding_Box();
- Vector3 min,max;
- min = level_bounds.Center - level_bounds.Extent;
- max = level_bounds.Center + level_bounds.Extent;
- SoundSceneClass *sound_scene = WWAudioClass::Get_Instance ()->Get_Sound_Scene ();
- if (sound_scene != NULL) {
- sound_scene->Re_Partition (min, max);
- }
-
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Are_Manual_Vis_Points_Visible
- //
- ////////////////////////////////////////////////////////////////
- bool
- SceneEditorClass::Are_Manual_Vis_Points_Visible (void)
- {
- return m_ManualVisPointsVisible;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Show_Manual_Vis_Points
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Show_Manual_Vis_Points (bool show_points)
- {
- if (m_ManualVisPointsVisible != show_points) {
- m_ManualVisPointsVisible = show_points;
- NodeClass *node = NULL;
- for ( node = NodeMgrClass::Get_First ();
- node != NULL;
- node = NodeMgrClass::Get_Next (node))
- {
- if (node->Get_Type () == NODE_TYPE_VIS_POINT) {
- node->Hide (!m_ManualVisPointsVisible);
- }
- }
- }
-
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // DoObjectGoto
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::DoObjectGoto (NodeClass *node1, NodeClass *node2)
- {
- SANITY_CHECK(node1 != NULL && node2 != NULL && node1->Get_Type () == NODE_TYPE_OBJECT) {
- return ;
- }
- //
- // Register all the waypaths with the pathfinding system
- //
- for ( NodeClass *node = NodeMgrClass::Get_First (NODE_TYPE_WAYPATH);
- node != NULL;
- node = NodeMgrClass::Get_Next (node, NODE_TYPE_WAYPATH))
- {
- node->Pre_Export ();
- }
- //
- // Force the pathfind system to use any available waypath data
- // in its evaluation
- //
- PathfindClass::Get_Instance ()->Generate_Waypath_Sectors_And_Portals ();
- m_MovingObject = node1;
- PhysicalGameObj *game_obj = ((ObjectNodeClass *)m_MovingObject)->Peek_Game_Obj ();
- if (game_obj != NULL && game_obj->As_SmartGameObj () != NULL) {
- ActionClass *action = ((SmartGameObj *)game_obj)->Get_Action ();
-
- ActionParamsStruct parameters;
- parameters.MoveLocation = node2->Get_Transform ().Get_Translation ();
- parameters.MoveArrivedDistance = 3.0F;
- action->Goto( parameters );
- }
- //
- // Unregister all the waypaths with the pathfinding system
- //
- for ( node = NodeMgrClass::Get_First (NODE_TYPE_WAYPATH);
- node != NULL;
- node = NodeMgrClass::Get_Next (node, NODE_TYPE_WAYPATH))
- {
- node->Post_Export ();
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Export_Lights
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Export_Lights (LPCTSTR filename)
- {
- FileClass *file = _TheFileFactory->Get_File (filename);
- if (file != NULL && file->Create () && file->Open (FileClass::WRITE)) {
- //
- // Write the first chunk header
- //
- ChunkSaveClass csave (file);
- csave.Begin_Chunk (W3D_CHUNK_LIGHTSCAPE);
-
- //
- // Loop over all the lights in the scene
- //
- for ( NodeClass *node = NodeMgrClass::Get_First (NODE_TYPE_LIGHT);
- node != NULL;
- node = NodeMgrClass::Get_Next (node, NODE_TYPE_LIGHT))
- {
- LightNodeClass *light_node = (LightNodeClass *)node;
- //
- // Get the actual light from the editor object
- //
- LightClass *light = light_node->Peek_Light ();
- if (light != NULL) {
-
- //
- // Save this light
- //
- csave.Begin_Chunk (W3D_CHUNK_LIGHTSCAPE_LIGHT);
- light->Save_W3D (csave);
-
- //
- // Save the light's transform as well
- //
- csave.Begin_Chunk (W3D_CHUNK_LIGHT_TRANSFORM);
- Matrix3D tm = light->Get_Transform ();
- W3dLightTransformStruct w3d_tm ={ tm[0][0], tm[0][1], tm[0][2], tm[0][3],
- tm[1][0], tm[1][1], tm[1][2], tm[1][3],
- tm[2][0], tm[2][1], tm[2][2], tm[2][3] };
- csave.Write (&w3d_tm, sizeof (w3d_tm));
- csave.End_Chunk ();
- csave.End_Chunk ();
- }
- }
- csave.End_Chunk ();
- //
- // Close the file
- //
- file->Close ();
- }
- _TheFileFactory->Return_File (file);
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Import_Lights
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Import_Lights
- (
- DynamicVectorClass<StringClass> & filename_list,
- DynamicVectorClass<LightNodeClass *> * node_list
- )
- {
- DynamicVectorClass<LightClass *> light_list;
- ::Get_Main_View ()->Allow_Repaint (false);
- //
- // Build a list of light objects from the LIG files
- //
- for (int index = 0; index < filename_list.Count (); index ++) {
- FileClass *file = _TheFileFactory->Get_File (filename_list[index]);
- if (file != NULL && file->Open ()) {
- //
- // Read the lights from this file
- //
- ChunkLoadClass cload (file);
- int group_id = 0;
- while (cload.Open_Chunk ()) {
- switch (cload.Cur_Chunk_ID ()) {
-
- case W3D_CHUNK_LIGHTSCAPE:
- Build_Light_List (cload, light_list, group_id ++);
- break;
- default:
- ASSERT (0);
- TRACE ("Unrecognized chunk id found while importing lights!\n");
- break;
- }
- cload.Close_Chunk ();
- }
- file->Close ();
- }
- //
- // Delete the file object
- //
- if (file != NULL) {
- _TheFileFactory->Return_File (file);
- }
- }
- //
- // Make sure we don't get duplicate lights
- //
- Filter_Lights (light_list);
- //
- // Get the preset we will use to derive each imported light-node from
- //
- PresetClass *preset = PresetMgrClass::Find_Preset ("Lightscape Imported");
- ASSERT (preset != NULL);
- CString base_name = ::Asset_Name_From_Filename (filename_list[0]);
- //
- // Add the lights to the level
- //
- for (index = 0; index < light_list.Count (); index ++) {
-
- LightClass *light = light_list[index];
- if (light != NULL) {
-
- //
- // Create an editor 'node' for this light and configure it from the
- // light render-object.
- //
- if (light->Get_Type () != LightClass::DIRECTIONAL) {
- Matrix3D tm = light->Get_Transform ();
- LightNodeClass *light_node = (LightNodeClass *)Create_Node (preset, &tm);
- light_node->Initialize_From_Light (light);
- light_node->Set_Group_ID ((int)light->Get_User_Data ());
-
- CString light_name;
- light_name.Format ("%s%04d", (LPCTSTR)base_name, index + 1);
- light_node->Peek_Light_Phys ()->Set_Name (light_name);
- //
- // Add this light to the list the caller supplied us with (if necessary)
- //
- if (node_list != NULL) {
- node_list->Add (light_node);
- light_node->Add_Ref ();
- }
- }
- //
- // Free our hold on the light
- //
- MEMBER_RELEASE (light);
- }
- }
- ::Get_Main_View ()->Allow_Repaint (true);
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Build_Light_List
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Build_Light_List
- (
- ChunkLoadClass & cload,
- DynamicVectorClass<LightClass *> & light_list,
- int group_id
- )
- {
- while (cload.Open_Chunk ()) {
- switch (cload.Cur_Chunk_ID ()) {
- case W3D_CHUNK_LIGHTSCAPE_LIGHT:
- {
- //
- // Load the light and add it to the list
- //
- cload.Open_Chunk ();
- LightClass *light = new LightClass;
- light->Load_W3D (cload);
- light->Set_User_Data ((void *)group_id);
- light_list.Add (light);
- cload.Close_Chunk ();
- //
- // Read the light's transform from the file
- //
- cload.Open_Chunk ();
- ASSERT (cload.Cur_Chunk_ID () == W3D_CHUNK_LIGHT_TRANSFORM);
- if (cload.Cur_Chunk_ID () == W3D_CHUNK_LIGHT_TRANSFORM) {
-
- //
- // Read the transform
- //
- W3dLightTransformStruct w3d_tm = { 0 };
- cload.Read (&w3d_tm, sizeof (w3d_tm));
-
- //
- // Convert the persistent-safe transform to a
- // render-obj friendly transform;
- //
- Matrix3D tm ( w3d_tm.Transform [0][0], w3d_tm.Transform [0][1], w3d_tm.Transform [0][2], w3d_tm.Transform [0][3],
- w3d_tm.Transform [1][0], w3d_tm.Transform [1][1], w3d_tm.Transform [1][2], w3d_tm.Transform [1][3],
- w3d_tm.Transform [2][0], w3d_tm.Transform [2][1], w3d_tm.Transform [2][2], w3d_tm.Transform [2][3]);
- light->Set_Transform (tm);
- }
- cload.Close_Chunk ();
- }
- break;
-
- default:
- ::Output_Message ("Found invalid chunk in light importer.\r\n");
- break;
- }
- cload.Close_Chunk ();
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Filter_Lights
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Filter_Lights (DynamicVectorClass<LightClass *> &light_list)
- {
- //
- // Loop over every light
- //
- for (int index1 = 0; index1 < light_list.Count (); index1 ++) {
- LightClass *light1 = light_list[index1];
- bool is_unique = true;
-
- //
- // Compare this light against every other light
- //
- for (int index2 = 0; index2 < light_list.Count () && is_unique; index2 ++) {
-
- //
- // Don't check against itself
- //
- if (index2 != index1) {
- LightClass *light2 = light_list[index2];
- is_unique = (Compare_Lights (light1, light2) == false);
- }
- }
- //
- // Remove this light from the list if it is not unique
- //
- if (is_unique == false) {
- MEMBER_RELEASE (light1);
- light_list.Delete (index1);
- index1 --;
- }
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Display_Sound_Spheres
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Display_Sound_Spheres (bool onoff)
- {
- if (m_DisplaySoundSpheres != onoff) {
- m_DisplaySoundSpheres = onoff;
- //
- // Loop over all the sounds and tell them to turn the spheres
- // on or off.
- //
- for ( NodeClass *node = NodeMgrClass::Get_First (NODE_TYPE_SOUND);
- node != NULL;
- node = NodeMgrClass::Get_Next (node, NODE_TYPE_SOUND))
- {
- node->Show_Attenuation_Spheres (m_DisplaySoundSpheres);
- }
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Display_Light_Spheres
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Display_Light_Spheres (bool onoff)
- {
- if (m_DisplayLightSpheres != onoff) {
- m_DisplayLightSpheres = onoff;
- //
- // Loop over all the lights and tell them to turn the spheres
- // on or off.
- //
- for ( NodeClass *node = NodeMgrClass::Get_First (NODE_TYPE_LIGHT);
- node != NULL;
- node = NodeMgrClass::Get_Next (node, NODE_TYPE_LIGHT))
- {
- node->Show_Attenuation_Spheres (m_DisplayLightSpheres);
- }
- }
-
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Import_Sunlight
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Import_Sunlight (LPCTSTR filename)
- {
- DynamicVectorClass<LightClass *> light_list;
-
- //
- // Open the file
- //
- FileClass *file = _TheFileFactory->Get_File (filename);
- if (file != NULL && file->Open ()) {
- //
- // Read the lights from this file
- //
- ChunkLoadClass cload (file);
- cload.Open_Chunk ();
- ASSERT (cload.Cur_Chunk_ID () == W3D_CHUNK_LIGHTSCAPE);
- Build_Light_List (cload, light_list);
- cload.Close_Chunk ();
- file->Close ();
- _TheFileFactory->Return_File (file);
- }
- //
- // Try to find all the directional lights
- //
- LightClass *sunlight = NULL;
- bool more_than_one = false;
- for (int index = 0; index < light_list.Count () && !more_than_one; index ++) {
- LightClass *light = light_list[index];
- if (light != NULL) {
-
- //
- // We assume that every directional light is the 'sunlight'.
- //
- if (light->Get_Type () == LightClass::DIRECTIONAL) {
- if (sunlight == NULL) {
- sunlight = light;
- } else {
-
- //
- // Check to make sure all directional lights are the same
- //
- if (Compare_Lights (sunlight, light) == false) {
- more_than_one = true;
- }
- MEMBER_RELEASE (light);
- }
- }
- }
- }
- bool apply_changes = (sunlight != NULL);
- if (more_than_one) {
- //
- // Ask the user if they wish to make these changes
- //
- if (::MessageBox ( ::AfxGetMainWnd ()->m_hWnd,
- "There are multiple sunlight definitions in this file which have different settings. Do you wish to continue?",
- "Ambiguous Lights",
- MB_ICONQUESTION | MB_YESNO) == IDNO)
- {
- apply_changes = false;
- }
- }
- //
- // Reconfigure the sunlight (if necessary)
- //
- if (apply_changes) {
- LightClass *global_sunlight_obj = Get_Sun_Light ();
- Vector3 diffuse;
- sunlight->Get_Diffuse (&diffuse);
- global_sunlight_obj->Set_Diffuse (diffuse);
- global_sunlight_obj->Set_Intensity (sunlight->Get_Intensity ());
- global_sunlight_obj->Set_Transform (sunlight->Get_Transform ());
- MEMBER_RELEASE (global_sunlight_obj);
- //
- // Convert the sun's 3x3 roational matrix to a
- // 'rotation' and 'elevation'.
- //
- Matrix3D tm = sunlight->Get_Transform ();
-
- Vector3 test_vector (0, 0, -1);
- test_vector = tm.Rotate_Vector (test_vector);
- test_vector.Normalize ();
- float rotation = ::atan2 (test_vector.Y, test_vector.X);
- float elevation = ::asin (test_vector.Z);
-
- Set_Sun_Light_Orientation (rotation, elevation);
- Update_Lighting ();
- }
-
- MEMBER_RELEASE (sunlight);
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Compare_Lights
- //
- ////////////////////////////////////////////////////////////////
- bool
- SceneEditorClass::Compare_Lights (LightClass *light1, LightClass *light2)
- {
- bool retval = false;
- //
- // Are the positions and orientations approximately the same?
- // Are they both the same type of light?
- //
- const Matrix3D &tm1 = light1->Get_Transform ();
- const Matrix3D &tm2 = light2->Get_Transform ();
- if ( tm1 == tm2 &&
- light1->Get_Type () == light2->Get_Type ())
- {
- //
- // Are their color's and intensities approx the same?
- //
- Vector3 ambient1;
- Vector3 ambient2;
- Vector3 specular1;
- Vector3 specular2;
- Vector3 diffuse1;
- Vector3 diffuse2;
- light1->Get_Ambient (&ambient1);
- light2->Get_Ambient (&ambient2);
- light1->Get_Specular (&specular1);
- light2->Get_Specular (&specular2);
- light1->Get_Diffuse (&diffuse1);
- light2->Get_Diffuse (&diffuse2);
- float intensity1 = light1->Get_Intensity ();
- float intensity2 = light2->Get_Intensity ();
- if ( ambient1 == ambient2 &&
- specular1 == specular2 &&
- diffuse1 == diffuse2 &&
- intensity1 == intensity2)
- {
- //
- // Are their attenuation ranges the same?
- //
- double inner1 = 0;
- double inner2 = 0;
- double outer1 = 0;
- double outer2 = 0;
- light1->Get_Far_Attenuation_Range (inner1, outer1);
- light2->Get_Far_Attenuation_Range (inner2, outer2);
- if (inner1 == inner2 && outer1 == outer2) {
- retval = true;
- }
- }
- }
- return retval;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Replace_Selection
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Replace_Selection (void)
- {
- //
- // Is there a selection set to replace?
- //
- int count = m_SelectionMgr->Get_Count ();
- if (count > 0) {
- //
- // Configure a dialog that will allow the user to select a preset
- //
- SelectPresetDialogClass dialog (::AfxGetMainWnd ());
- dialog.Set_Title ("Object Replace");
- dialog.Set_Message ("Select the new preset you want to replace the selected objects with.");
- dialog.Allow_None_Selection (false);
- //
- // Let the user pick a preset
- //
- if (dialog.DoModal () == IDOK) {
- PresetClass *preset = dialog.Get_Selection ();
- DynamicVectorClass<NodeClass *> new_nodes;
- CWaitCursor wait_cursor;
- //
- // Loop over all the selected nodes
- //
- for (int index = 0; index < count; index ++) {
-
- //
- // Get the transform of this selected node
- //
- NodeClass *node = m_SelectionMgr->Get_At (index);
- Matrix3D tm = node->Get_Transform ();
- //
- // Create a new node with this same transform
- //
- NodeClass *new_node = Create_Node (preset, &tm, 0, true);
- new_node->Set_ID (node->Get_ID ());
- new_nodes.Add (new_node);
- //
- // Test to see if both node's are game objects of some sort.
- // If they are, then we need to copy the scripts.
- //
- ObjectNodeClass *old_obj_node = node->As_ObjectNodeClass ();
- ObjectNodeClass *new_obj_node = new_node->As_ObjectNodeClass ();
- if (old_obj_node != NULL && new_obj_node != NULL) {
- new_obj_node->Copy_Scripts (*old_obj_node);
- }
- //
- // Delete the old node
- //
- Delete_Node (node, false);
- }
-
- //
- // Clear the selection
- //
- m_SelectionMgr->Reset ();
- //
- // Add the new nodes to the selection set
- //
- for (index = 0; index < new_nodes.Count (); index ++) {
- NodeClass *new_node = new_nodes[index];
- m_SelectionMgr->Add_Node (new_node);
- }
- }
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Generate_Uniform_Sampled_Vis
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Generate_Uniform_Sampled_Vis
- (
- float granularity,
- float sample_height,
- bool ignore_bias,
- bool selection_only,
- bool farm_mode,
- int farm_cpu_index,
- int farm_cpu_total
- )
- {
- GeneratingVisDialogClass dialog (granularity, ::AfxGetMainWnd ());
- dialog.Set_Sample_Height (sample_height);
- dialog.Set_Ignore_Bias (ignore_bias);
- dialog.Do_Selection_Only (selection_only);
- if (farm_mode) {
- dialog.Set_Farm_Mode (farm_cpu_index,farm_cpu_total);
- }
- dialog.DoModal ();
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Generate_Edge_Sampled_Vis
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Generate_Edge_Sampled_Vis
- (
- float granularity,
- bool ignore_bias,
- bool farm_mode,
- int farm_cpu_index,
- int farm_cpu_total
- )
- {
- //
- // Build a list of nodes that should be vis-sampled
- //
- DynamicVectorClass<NodeClass *> node_list;
- VisMgrClass::Build_Node_List (node_list);
- //
- // Determine the first and last node that this cpu is to process. In farm
- // mode, the processing is split up amongst several computers...
- //
- int first_node = 0;
- int last_node = node_list.Count();
- if (farm_mode) {
- int node_count = node_list.Count();
- float nodes_per_processor = (float)node_count / (float)farm_cpu_total;
- first_node = (int)::floor (nodes_per_processor * (float)farm_cpu_index);
- last_node = (int)::ceil (nodes_per_processor * (float)(farm_cpu_index+1));
- }
-
- VisGenProgressClass progress_obj;
- progress_obj.Set_Node_Count (last_node - first_node);
- GeneratingEdgeSampledVisDialogClass *dialog = GeneratingEdgeSampledVisDialogClass::Display ();
- dialog->Set_Progress_Obj (&progress_obj);
- dialog->Enable_Farm_Mode (farm_mode);
- //
- // Perform the per-node vis sampling
- //
- VisSectorSamplerClass sampler (this, &progress_obj, granularity, MOUSE_CLICK_COLLISION_GROUP);
- for ( int index = first_node;
- index < last_node && !progress_obj.Is_Cancel_Requested ();
- index ++)
- {
- NodeClass *node = node_list[index];
- if (node != NULL) {
-
- //
- // Simply pass off the render object onto the sampler class
- // for point generation
- //
- RenderObjClass *render_obj = node->Peek_Render_Obj ();
- if (render_obj != NULL) {
- sampler.Process (render_obj);
- }
- }
- ::General_Pump_Messages ();
- }
- //
- // Now render any manual vis points
- //
- VisMgrClass::Render_Manual_Vis_Points ();
- dialog->Set_Progress_Obj (NULL);
- dialog->Set_Finished (true);
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Generate_Light_Vis
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Generate_Light_Vis
- (
- bool farm_mode,
- int farm_cpu_index,
- int farm_cpu_total
- )
- {
- GeneratingLightVisDialogClass dialog (::AfxGetMainWnd ());
- if (farm_mode) {
- dialog.Set_Farm_Mode (farm_cpu_index,farm_cpu_total);
- }
- dialog.DoModal ();
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Generate_Manual_Vis
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Generate_Manual_Vis
- (
- bool farm_mode,
- int farm_cpu_index,
- int farm_cpu_total
- )
- {
- GeneratingManualVisDialogClass dialog (::AfxGetMainWnd ());
- if (farm_mode) {
- dialog.Set_Farm_Mode (farm_cpu_index, farm_cpu_total);
- }
- dialog.DoModal ();
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Display_Editor_Objects
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Display_Editor_Objects (bool onoff)
- {
- m_ShowEditorObjects = onoff;
- //
- // Loop over all the nodes, picking out the editor-only
- // nodes to show or hide.
- //
- DynamicVectorClass<NodeClass *> node_list;
- NodeMgrClass::Build_Full_Node_List (node_list);
- for (int index = 0; index < node_list.Count (); index ++) {
- NodeClass *node = node_list[index];
- if (node != NULL) {
- int type = node->Get_Type ();
- //
- // Does this node have an editor-only display object?
- //
- if ( type == NODE_TYPE_ZONE ||
- type == NODE_TYPE_WAYPATH ||
- type == NODE_TYPE_WAYPOINT ||
- type == NODE_TYPE_LIGHT ||
- type == NODE_TYPE_TRANSITION ||
- type == NODE_TYPE_TRANSITION_CHARACTER ||
- type == NODE_TYPE_SOUND ||
- type == NODE_TYPE_VIS ||
- type == NODE_TYPE_VIS_POINT ||
- type == NODE_TYPE_PATHFIND_START ||
- type == NODE_TYPE_DUMMY_OBJECT ||
- type == NODE_TYPE_COVER_SPOT ||
- type == NODE_TYPE_COVER_ATTACK_POINT ||
- type == NODE_TYPE_DAMAGE_ZONE ||
- type == NODE_TYPE_BUILDING ||
- type == NODE_TYPE_EDITOR_ONLY_OBJ)
- {
- node->Hide (!onoff);
- }
- }
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Display_Static_Anim_Phys
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Display_Static_Anim_Phys (bool onoff)
- {
- m_ShowStaticAnimPhys = onoff;
- //
- // Get the list of all static objects from the physics scene
- //
- RefPhysListIterator iterator = ::Get_Scene_Editor ()->Get_Static_Object_Iterator ();
- for (iterator.First (); !iterator.Is_Done (); iterator.Next ()) {
- //
- // Is this object a static anim phys?
- //
- PhysClass *phys_obj = iterator.Peek_Obj ();
- StaticAnimPhysClass *static_phys_obj = phys_obj->As_StaticAnimPhysClass ();
- if (static_phys_obj != NULL && static_phys_obj->Peek_Model () != NULL) {
-
- //
- // Hide the static anim phys object and turn off its collision
- //
- static_phys_obj->Peek_Model ()->Set_Hidden (!onoff);
- if (onoff == false) {
- phys_obj->Inc_Ignore_Counter ();
- } else if (phys_obj->Is_Ignore_Me ()) {
- phys_obj->Dec_Ignore_Counter ();
- }
- }
- }
- /*for ( NodeClass *node = NodeMgrClass::Get_First ();
- node != NULL;
- node = NodeMgrClass::Get_Next (node))
- {
- PhysClass *phys_obj = node->Peek_Physics_Obj ();
- if (phys_obj != NULL && phys_obj->As_StaticAnimPhysClass () != NULL) {
- node->Hide (!onoff);
- }
- }*/
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Enable_Building_Power
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Enable_Building_Power (bool onoff)
- {
- //
- // Make sure the buildings are in a good state
- //
- GameObjManager::Update_Building_Collection_Spheres ();
- GameObjManager::Init_Buildings ();
- //
- // Loop over all the lights and tell them to turn the spheres
- // on or off.
- //
- for ( NodeClass *node = NodeMgrClass::Get_First (NODE_TYPE_BUILDING);
- node != NULL;
- node = NodeMgrClass::Get_Next (node, NODE_TYPE_BUILDING))
- {
- ((BuildingNodeClass *)node)->Enable_Power (onoff);
- ((BuildingNodeClass *)node)->Set_Normalized_Health (onoff * 1.0F);
- }
-
- m_BuildingPowerEnabled = onoff;
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Reset_Dynamic_Object_Visibility_Status
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Reset_Dynamic_Object_Visibility_Status (void)
- {
- //
- // Get the list of all dynamic objects from the physics scene
- //
- RefPhysListIterator iterator = ::Get_Scene_Editor ()->Get_Dynamic_Object_Iterator ();
- for (iterator.First (); !iterator.Is_Done (); iterator.Next ()) {
- //
- // Make sure this phys obj is a dynamic object
- //
- PhysClass *phys_obj = iterator.Peek_Obj ();
- DynamicPhysClass *dyn_phys_obj = phys_obj->As_DynamicPhysClass ();
- if (dyn_phys_obj != NULL) {
- //
- // Reset this dynamic object's visibility
- //
- dyn_phys_obj->Update_Visibility_Status ();
- }
- }
-
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Reset_Vis_For_Node
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Reset_Vis_For_Node (NodeClass *node)
- {
- if (node == NULL || node->Is_Static () == false) {
- return ;
- }
- //
- // Make sure this is a static phys object
- //
- PhysClass *phys = node->Peek_Physics_Obj ();
- if (phys != NULL && phys->As_StaticPhysClass () != NULL) {
- StaticPhysClass *static_phys = phys->As_StaticPhysClass ();
-
- //
- // Get this sector's id
- //
- int vis_id = static_phys->Get_Vis_Sector_ID ();
- if (vis_id > 0) {
- //
- // Get the vis table for this sector
- //
- VisTableClass *vis_table = VisTableManager.Get_Vis_Table(vis_id, false);
- if (vis_table != NULL) {
-
- //
- // Reset the visibility data for this sector
- //
- vis_table->Reset_All ();
- VisTableManager.Update_Vis_Table(vis_id,vis_table);
- REF_PTR_RELEASE(vis_table);
- }
- }
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Update_Lighting
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Update_Lighting (void)
- {
- Vector3 lev_min;
- Vector3 lev_max;
- Vector3 sundirection;
-
- Get_Level_Extents (lev_min, lev_max);
- AABoxClass box;
- box.Center = lev_min + ((lev_max - lev_min) * 0.5F);
- box.Extent = ((lev_max - lev_min) * 0.5F);
- Invalidate_Lighting_Caches (box);
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Set_Sun_Light_Orientation
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Set_Sun_Light_Orientation (float yaw, float pitch)
- {
- PhysicsSceneClass::Set_Sun_Light_Orientation (yaw, pitch);
- }
- ////////////////////////////////////////////////////////////////
- //
- // Show_Vis_Window
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::Show_Vis_Window (bool onoff)
- {
- if (m_VisWindow.m_hWnd == NULL) {
- m_VisWindow.Create ();
- }
- m_VisWindow.ShowWindow (onoff ? SW_SHOW : SW_HIDE);
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Is_Vis_Window_Visible
- //
- ////////////////////////////////////////////////////////////////
- bool
- SceneEditorClass::Is_Vis_Window_Visible (void)
- {
- bool retval = true;
- if ( m_VisWindow.m_hWnd == NULL ||
- m_VisWindow.IsWindowVisible () == false)
- {
- retval = false;
- }
- return retval;
- }
- ////////////////////////////////////////////////////////////////
- //
- // On_Vis_Occluders_Rendered
- //
- ////////////////////////////////////////////////////////////////
- void
- SceneEditorClass::On_Vis_Occluders_Rendered
- (
- VisRenderContextClass & context,
- VisSampleClass & sample
- )
- {
- m_VisWindow.Update_Display (*context.VisRasterizer);
- return ;
- }
|