| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664 |
- /// Urho3D editor scene handling
- #include "Scripts/Editor/EditorHierarchyWindow.as"
- #include "Scripts/Editor/EditorInspectorWindow.as"
- #include "Scripts/Editor/EditorCubeCapture.as"
- const int PICK_GEOMETRIES = 0;
- const int PICK_LIGHTS = 1;
- const int PICK_ZONES = 2;
- const int PICK_RIGIDBODIES = 3;
- const int PICK_UI_ELEMENTS = 4;
- const int MAX_PICK_MODES = 5;
- const int MAX_UNDOSTACK_SIZE = 256;
- Scene@ editorScene;
- String instantiateFileName;
- CreateMode instantiateMode = REPLICATED;
- bool sceneModified = false;
- bool runUpdate = false;
- Array<Node@> selectedNodes;
- Array<Component@> selectedComponents;
- Node@ editNode;
- Array<Node@> editNodes;
- Array<Component@> editComponents;
- uint numEditableComponentsPerNode = 1;
- Array<XMLFile@> sceneCopyBuffer;
- bool suppressSceneChanges = false;
- bool inSelectionModify = false;
- bool skipMruScene = false;
- Array<EditActionGroup> undoStack;
- uint undoStackPos = 0;
- bool revertOnPause = false;
- XMLFile@ revertData;
- Vector3 lastOffsetForSmartDuplicate;
- void ClearSceneSelection()
- {
- selectedNodes.Clear();
- selectedComponents.Clear();
- editNode = null;
- editNodes.Clear();
- editComponents.Clear();
- numEditableComponentsPerNode = 1;
- HideGizmo();
- }
- void CreateScene()
- {
- // Create a scene only once here
- editorScene = Scene();
- // Allow access to the scene from the console
- script.defaultScene = editorScene;
- // Always pause the scene, and do updates manually
- editorScene.updateEnabled = false;
- }
- bool ResetScene()
- {
- ui.cursor.shape = CS_BUSY;
- if (messageBoxCallback is null && sceneModified)
- {
- MessageBox@ messageBox = MessageBox("Scene has been modified.\nContinue to reset?", "Warning");
- if (messageBox.window !is null)
- {
- Button@ cancelButton = messageBox.window.GetChild("CancelButton", true);
- cancelButton.visible = true;
- cancelButton.focus = true;
- SubscribeToEvent(messageBox, "MessageACK", "HandleMessageAcknowledgement");
- messageBoxCallback = @ResetScene;
- return false;
- }
- }
- else
- messageBoxCallback = null;
- suppressSceneChanges = true;
- // Create a scene with default values, these will be overridden when loading scenes
- editorScene.Clear();
- editorScene.CreateComponent("Octree");
- editorScene.CreateComponent("DebugRenderer");
- // Release resources that became unused after the scene clear
- cache.ReleaseAllResources(false);
- sceneModified = false;
- revertData = null;
- StopSceneUpdate();
- UpdateWindowTitle();
- DisableInspectorLock();
- UpdateHierarchyItem(editorScene, true);
- ClearEditActions();
- suppressSceneChanges = false;
- ResetCamera();
- CreateGizmo();
- CreateGrid();
- SetActiveViewport(viewports[0]);
- return true;
- }
- void SetResourcePath(String newPath, bool usePreferredDir = true, bool additive = false)
- {
- if (newPath.empty)
- return;
- if (!IsAbsolutePath(newPath))
- newPath = fileSystem.currentDir + newPath;
- if (usePreferredDir)
- newPath = AddTrailingSlash(cache.GetPreferredResourceDir(newPath));
- else
- newPath = AddTrailingSlash(newPath);
- if (newPath == sceneResourcePath)
- return;
- // Remove the old scene resource path if any. However make sure that the default data paths do not get removed
- if (!additive)
- {
- cache.ReleaseAllResources(false);
- renderer.ReloadShaders();
- String check = AddTrailingSlash(sceneResourcePath);
- bool isDefaultResourcePath = check.Compare(fileSystem.programDir + "Data/", false) == 0 ||
- check.Compare(fileSystem.programDir + "CoreData/", false) == 0;
- if (!sceneResourcePath.empty && !isDefaultResourcePath)
- cache.RemoveResourceDir(sceneResourcePath);
- }
- else
- {
- // If additive (path of a loaded prefab) check that the new path isn't already part of an old path
- Array<String>@ resourceDirs = cache.resourceDirs;
- for (uint i = 0; i < resourceDirs.length; ++i)
- {
- if (newPath.StartsWith(resourceDirs[i], false))
- return;
- }
- }
- // Add resource path as first priority so that it takes precedence over the default data paths
- cache.AddResourceDir(newPath, 0);
- RebuildResourceDatabase();
- if (!additive)
- {
- sceneResourcePath = newPath;
- uiScenePath = GetResourceSubPath(newPath, "Scenes");
- uiElementPath = GetResourceSubPath(newPath, "UI");
- uiNodePath = GetResourceSubPath(newPath, "Objects");
- uiScriptPath = GetResourceSubPath(newPath, "Scripts");
- uiParticlePath = GetResourceSubPath(newPath, "Particle");
- }
- }
- String GetResourceSubPath(String basePath, const String&in subPath)
- {
- basePath = AddTrailingSlash(basePath);
- if (fileSystem.DirExists(basePath + subPath))
- return AddTrailingSlash(basePath + subPath);
- else
- return basePath;
- }
- bool LoadScene(const String&in fileName)
- {
- if (fileName.empty)
- return false;
- ui.cursor.shape = CS_BUSY;
- // Always load the scene from the filesystem, not from resource paths
- if (!fileSystem.FileExists(fileName))
- {
- MessageBox("No such scene.\n" + fileName);
- return false;
- }
- File file(fileName, FILE_READ);
- if (!file.open)
- {
- MessageBox("Could not open file.\n" + fileName);
- return false;
- }
- // Add the scene's resource path in case it's necessary
- String newScenePath = GetPath(fileName);
- if (!rememberResourcePath || !sceneResourcePath.StartsWith(newScenePath, false))
- SetResourcePath(newScenePath);
- suppressSceneChanges = true;
- sceneModified = false;
- revertData = null;
- StopSceneUpdate();
- String extension = GetExtension(fileName);
- bool loaded;
- if (extension == ".xml")
- loaded = editorScene.LoadXML(file);
- else if (extension == ".json")
- loaded = editorScene.LoadJSON(file);
- else
- loaded = editorScene.Load(file);
- // Release resources which are not used by the new scene
- cache.ReleaseAllResources(false);
- // Always pause the scene, and do updates manually
- editorScene.updateEnabled = false;
- UpdateWindowTitle();
- DisableInspectorLock();
- UpdateHierarchyItem(editorScene, true);
- CollapseHierarchy();
- ClearEditActions();
- suppressSceneChanges = false;
- // global variable to mostly bypass adding mru upon importing tempscene
- if (!skipMruScene)
- UpdateSceneMru(fileName);
- skipMruScene = false;
- ResetCamera();
- CreateGizmo();
- CreateGrid();
- SetActiveViewport(viewports[0]);
- return loaded;
- }
- bool SaveScene(const String&in fileName)
- {
- if (fileName.empty)
- return false;
- ui.cursor.shape = CS_BUSY;
- // Unpause when saving so that the scene will work properly when loaded outside the editor
- editorScene.updateEnabled = true;
- MakeBackup(fileName);
- File file(fileName, FILE_WRITE);
- String extension = GetExtension(fileName);
- bool success;
- if (extension == ".xml")
- success = editorScene.SaveXML(file);
- else if (extension == ".json")
- success = editorScene.SaveJSON(file);
- else
- success = editorScene.Save(file);
- RemoveBackup(success, fileName);
- // Save all the terrains we've modified
- terrainEditor.Save();
- editorScene.updateEnabled = false;
- if (success)
- {
- UpdateSceneMru(fileName);
- sceneModified = false;
- UpdateWindowTitle();
- }
- else
- MessageBox("Could not save scene successfully!\nSee Urho3D.log for more detail.");
- return success;
- }
- bool SaveSceneWithExistingName()
- {
- if (editorScene.fileName.empty || editorScene.fileName == TEMP_SCENE_NAME)
- return PickFile();
- else
- return SaveScene(editorScene.fileName);
- }
- Node@ CreateNode(CreateMode mode, bool raycastToMouse = false)
- {
- Node@ newNode = null;
- if (editNode !is null)
- newNode = editNode.CreateChild("", mode);
- else
- newNode = editorScene.CreateChild("", mode);
- newNode.worldPosition = GetNewNodePosition(raycastToMouse);
- // Create an undo action for the create
- CreateNodeAction action;
- action.Define(newNode);
- SaveEditAction(action);
- SetSceneModified();
- FocusNode(newNode);
- return newNode;
- }
- void CreateComponent(const String&in componentType)
- {
- // If this is the root node, do not allow to create duplicate scene-global components
- if (editNode is editorScene && CheckForExistingGlobalComponent(editNode, componentType))
- return;
- // Group for storing undo actions
- EditActionGroup group;
- // For now, make a local node's all components local
- /// \todo Allow to specify the createmode
- for (uint i = 0; i < editNodes.length; ++i)
- {
- Component@ newComponent = editNodes[i].CreateComponent(componentType, editNodes[i].replicated ? REPLICATED : LOCAL);
- if (newComponent !is null)
- {
- // Some components such as CollisionShape do not create their internal object before the first call to ApplyAttributes()
- // to prevent unnecessary initialization with default values. Call now
- newComponent.ApplyAttributes();
- CreateComponentAction action;
- action.Define(newComponent);
- group.actions.Push(action);
- }
- }
- SaveEditActionGroup(group);
- SetSceneModified();
- // Although the edit nodes selection are not changed, call to ensure attribute inspector notices new components of the edit nodes
- HandleHierarchyListSelectionChange();
- }
- void CreateLoadedComponent(Component@ component)
- {
- if (component is null) return;
- CreateComponentAction action;
- action.Define(component);
- SaveEditAction(action);
- SetSceneModified();
- FocusComponent(component);
- }
- Node@ LoadNode(const String&in fileName, Node@ parent = null, bool raycastToMouse = false)
- {
- if (fileName.empty)
- return null;
- if (!fileSystem.FileExists(fileName))
- {
- MessageBox("No such node file.\n" + fileName);
- return null;
- }
- File file(fileName, FILE_READ);
- if (!file.open)
- {
- MessageBox("Could not open file.\n" + fileName);
- return null;
- }
- ui.cursor.shape = CS_BUSY;
- // Before instantiating, add object's resource path if necessary
- SetResourcePath(GetPath(fileName), true, true);
- Node@ newNode = InstantiateNodeFromFile(file, GetNewNodePosition(raycastToMouse), Quaternion(), 1, parent, instantiateMode);
- if (newNode !is null)
- {
- FocusNode(newNode);
- instantiateFileName = fileName;
- }
- return newNode;
- }
- Node@ InstantiateNodeFromFile(File@ file, const Vector3& position, const Quaternion& rotation, float scaleMod = 1.0f, Node@ parent = null, CreateMode mode = REPLICATED)
- {
- if (file is null)
- return null;
- Node@ newNode;
- uint numSceneComponent = editorScene.numComponents;
- suppressSceneChanges = true;
- String extension = GetExtension(file.name);
- if (extension == ".xml")
- newNode = editorScene.InstantiateXML(file, position, rotation, mode);
- else if (extension == ".json")
- newNode = editorScene.InstantiateJSON(file, position, rotation, mode);
- else
- newNode = editorScene.Instantiate(file, position, rotation, mode);
- suppressSceneChanges = false;
- if (parent !is null)
- newNode.parent = parent;
- if (newNode !is null)
- {
- newNode.scale = newNode.scale * scaleMod;
- AdjustNodePositionByAABB(newNode);
- // Create an undo action for the load
- CreateNodeAction action;
- action.Define(newNode);
- SaveEditAction(action);
- SetSceneModified();
- if (numSceneComponent != editorScene.numComponents)
- UpdateHierarchyItem(editorScene);
- else
- UpdateHierarchyItem(newNode);
- }
- return newNode;
- }
- void AdjustNodePositionByAABB(Node@ newNode)
- {
- if (alignToAABBBottom)
- {
- Drawable@ drawable = GetFirstDrawable(newNode);
- if (drawable !is null)
- {
- BoundingBox aabb = drawable.worldBoundingBox;
- Vector3 aabbBottomCenter(aabb.center.x, aabb.min.y, aabb.center.z);
- Vector3 offset = aabbBottomCenter - newNode.worldPosition;
- newNode.worldPosition = newNode.worldPosition - offset;
- }
- }
- }
- bool SaveNode(const String&in fileName)
- {
- if (fileName.empty)
- return false;
- ui.cursor.shape = CS_BUSY;
- MakeBackup(fileName);
- File file(fileName, FILE_WRITE);
- if (!file.open)
- {
- MessageBox("Could not open file.\n" + fileName);
- return false;
- }
- String extension = GetExtension(fileName);
- bool success;
- if (extension == ".xml")
- success = editNode.SaveXML(file);
- else if (extension == ".json")
- success = editNode.SaveJSON(file);
- else
- success = editNode.Save(file);
- RemoveBackup(success, fileName);
- if (success)
- instantiateFileName = fileName;
- else
- MessageBox("Could not save node successfully!\nSee Urho3D.log for more detail.");
- return success;
- }
- void UpdateScene(float timeStep)
- {
- if (runUpdate)
- editorScene.Update(timeStep);
- }
- void StopSceneUpdate()
- {
- runUpdate = false;
- audio.Stop();
- toolBarDirty = true;
- // If scene should revert on update stop, load saved data now
- if (revertOnPause && revertData !is null)
- {
- suppressSceneChanges = true;
- editorScene.Clear();
- editorScene.LoadXML(revertData.root);
- CreateGrid();
- UpdateHierarchyItem(editorScene, true);
- ClearEditActions();
- suppressSceneChanges = false;
- }
- revertData = null;
- }
- void StartSceneUpdate()
- {
- runUpdate = true;
- // Run audio playback only when scene is updating, so that audio components' time-dependent attributes stay constant when
- // paused (similar to physics)
- audio.Play();
- toolBarDirty = true;
- // Save scene data for reverting if enabled
- if (revertOnPause)
- {
- revertData = XMLFile();
- XMLElement root = revertData.CreateRoot("scene");
- editorScene.SaveXML(root);
- }
- else
- revertData = null;
- }
- bool ToggleSceneUpdate()
- {
- if (!runUpdate)
- StartSceneUpdate();
- else
- StopSceneUpdate();
- return true;
- }
- bool ShowLayerMover()
- {
- if (ui.focusElement is null)
- return ShowLayerEditor();
- else
- return false;
- }
- void SetSceneModified()
- {
- if (!sceneModified)
- {
- sceneModified = true;
- UpdateWindowTitle();
- }
- }
- bool SceneDelete()
- {
- ui.cursor.shape = CS_BUSY;
- BeginSelectionModify();
- // Clear the selection now to prevent repopulation of selectedNodes and selectedComponents combo
- hierarchyList.ClearSelection();
- // Group for storing undo actions
- EditActionGroup group;
- // Remove nodes
- for (uint i = 0; i < selectedNodes.length; ++i)
- {
- Node@ node = selectedNodes[i];
- if (node.parent is null || node.scene is null)
- continue; // Root or already deleted
- uint nodeIndex = GetListIndex(node);
- // Create undo action
- DeleteNodeAction action;
- action.Define(node);
- group.actions.Push(action);
- node.Remove();
- SetSceneModified();
- // If deleting only one node, select the next item in the same index
- if (selectedNodes.length == 1 && selectedComponents.empty)
- hierarchyList.selection = nodeIndex;
- }
- // Then remove components, if they still remain
- for (uint i = 0; i < selectedComponents.length; ++i)
- {
- Component@ component = selectedComponents[i];
- Node@ node = component.node;
- if (node is null)
- continue; // Already deleted
- uint index = GetComponentListIndex(component);
- uint nodeIndex = GetListIndex(node);
- if (index == NO_ITEM || nodeIndex == NO_ITEM)
- continue;
- // Do not allow to remove the Octree, DebugRenderer or MaterialCache2D or DrawableProxy2D from the root node
- if (node is editorScene && (component.typeName == "Octree" || component.typeName == "DebugRenderer" ||
- component.typeName == "MaterialCache2D" || component.typeName == "DrawableProxy2D"))
- continue;
- // Create undo action
- DeleteComponentAction action;
- action.Define(component);
- group.actions.Push(action);
- node.RemoveComponent(component);
- SetSceneModified();
- // If deleting only one component, select the next item in the same index
- if (selectedComponents.length == 1 && selectedNodes.empty)
- hierarchyList.selection = index;
- }
- SaveEditActionGroup(group);
- EndSelectionModify();
- return true;
- }
- bool SceneCut()
- {
- return SceneCopy() && SceneDelete();
- }
- bool SceneCopy()
- {
- ui.cursor.shape = CS_BUSY;
- sceneCopyBuffer.Clear();
- // Copy components
- if (!selectedComponents.empty)
- {
- for (uint i = 0; i < selectedComponents.length; ++i)
- {
- XMLFile@ xml = XMLFile();
- XMLElement rootElem = xml.CreateRoot("component");
- selectedComponents[i].SaveXML(rootElem);
- rootElem.SetBool("local", !selectedComponents[i].replicated);
- sceneCopyBuffer.Push(xml);
- }
- }
- // Copy nodes
- else
- {
- for (uint i = 0; i < selectedNodes.length; ++i)
- {
- // Skip the root scene node as it cannot be copied
- if (selectedNodes[i] is editorScene)
- continue;
- XMLFile@ xml = XMLFile();
- XMLElement rootElem = xml.CreateRoot("node");
- selectedNodes[i].SaveXML(rootElem);
- rootElem.SetBool("local", !selectedNodes[i].replicated);
- sceneCopyBuffer.Push(xml);
- }
- }
- return true;
- }
- bool ScenePaste(bool pasteRoot = false, bool duplication = false)
- {
- ui.cursor.shape = CS_BUSY;
- // Group for storing undo actions
- EditActionGroup group;
- for (uint i = 0; i < sceneCopyBuffer.length; ++i)
- {
- XMLElement rootElem = sceneCopyBuffer[i].root;
- String mode = rootElem.name;
- if (mode == "component" && editNode !is null)
- {
- // If this is the root node, do not allow to create duplicate scene-global components
- if (editNode is editorScene && CheckForExistingGlobalComponent(editNode, rootElem.GetAttribute("type")))
- return false;
- // If copied component was local, make the new local too
- Component@ newComponent = editNode.CreateComponent(rootElem.GetAttribute("type"), rootElem.GetBool("local") ? LOCAL :
- REPLICATED);
- if (newComponent is null)
- return false;
- newComponent.LoadXML(rootElem);
- newComponent.ApplyAttributes();
- // Create an undo action
- CreateComponentAction action;
- action.Define(newComponent);
- group.actions.Push(action);
- }
- else if (mode == "node")
- {
- // If copied node was local, make the new local too
- Node@ newNode;
- // Are we pasting into the root node?
- if (pasteRoot)
- newNode = editorScene.CreateChild("", rootElem.GetBool("local") ? LOCAL : REPLICATED);
- else
- {
- // If we are duplicating or have the original node selected, paste into the selected nodes parent
- if (duplication || editNode is null || editNode.id == rootElem.GetUInt("id"))
- {
- if (editNode !is null && editNode.parent !is null)
- newNode = editNode.parent.CreateChild("", rootElem.GetBool("local") ? LOCAL : REPLICATED);
- else
- newNode = editorScene.CreateChild("", rootElem.GetBool("local") ? LOCAL : REPLICATED);
- }
- // If we aren't duplicating, paste into the selected node
- else
- {
- newNode = editNode.CreateChild("", rootElem.GetBool("local") ? LOCAL : REPLICATED);
- }
- }
- newNode.LoadXML(rootElem);
- // Create an undo action
- CreateNodeAction action;
- action.Define(newNode);
- group.actions.Push(action);
- }
- }
- SaveEditActionGroup(group);
- SetSceneModified();
- return true;
- }
- bool SceneDuplicate()
- {
- Array<XMLFile@> copy = sceneCopyBuffer;
- if (!SceneCopy())
- {
- sceneCopyBuffer = copy;
- return false;
- }
- if (!ScenePaste(false, true))
- {
- sceneCopyBuffer = copy;
- return false;
- }
- sceneCopyBuffer = copy;
- return true;
- }
- bool SceneUnparent()
- {
- if (!CheckHierarchyWindowFocus() || !selectedComponents.empty || selectedNodes.empty)
- return false;
- ui.cursor.shape = CS_BUSY;
- // Group for storing undo actions
- EditActionGroup group;
- // Parent selected nodes to root
- Array<Node@> changedNodes;
- for (uint i = 0; i < selectedNodes.length; ++i)
- {
- Node@ sourceNode = selectedNodes[i];
- if (sourceNode.parent is null || sourceNode.parent is editorScene)
- continue; // Root or already parented to root
- // Perform the reparenting, continue loop even if action fails
- ReparentNodeAction action;
- action.Define(sourceNode, editorScene);
- group.actions.Push(action);
- SceneChangeParent(sourceNode, editorScene, false);
- changedNodes.Push(sourceNode);
- }
- // Reselect the changed nodes at their new position in the list
- for (uint i = 0; i < changedNodes.length; ++i)
- hierarchyList.AddSelection(GetListIndex(changedNodes[i]));
- SaveEditActionGroup(group);
- SetSceneModified();
- return true;
- }
- bool NodesParentToLastSelected()
- {
- if (lastSelectedNode.Get() is null)
- return false;
- if (!CheckHierarchyWindowFocus() || !selectedComponents.empty || selectedNodes.empty)
- return false;
- ui.cursor.shape = CS_BUSY;
- // Group for storing undo actions
- EditActionGroup group;
- // Parent selected nodes to root
- Array<Node@> changedNodes;
- // Find new parent node it selected last
- Node@ lastNode = lastSelectedNode.Get(); //GetListNode(hierarchyList.selection);
- for (uint i = 0; i < selectedNodes.length; ++i)
- {
- Node@ sourceNode = selectedNodes[i];
- if ( sourceNode.id == lastNode.id)
- continue; // Skip last node it is parent
- if (sourceNode.parent.id == lastNode.id)
- continue; // Root or already parented to root
- // Perform the reparenting, continue loop even if action fails
- ReparentNodeAction action;
- action.Define(sourceNode, lastNode);
- group.actions.Push(action);
- SceneChangeParent(sourceNode, lastNode, false);
- changedNodes.Push(sourceNode);
- }
- // Reselect the changed nodes at their new position in the list
- for (uint i = 0; i < changedNodes.length; ++i)
- hierarchyList.AddSelection(GetListIndex(changedNodes[i]));
- SaveEditActionGroup(group);
- SetSceneModified();
- return true;
- }
- bool SceneSmartDuplicateNode()
- {
- const float minOffset = 0.1;
- if (!CheckHierarchyWindowFocus() || !selectedComponents.empty
- || selectedNodes.empty || lastSelectedNode.Get() is null)
- return false;
- Node@ node = lastSelectedNode.Get();
- Node@ parent = node.parent;
- Vector3 offset = Vector3(1,0,0); // default offset
- if (parent is editorScene) // if parent of selected node is Scene make empty parent for it and place in same position;
- {
- parent = CreateNode(LOCAL);
- SceneChangeParent(parent, editorScene, false);
- parent.worldPosition = node.worldPosition;
- parent.name = node.name + "Group";
- node.name = parent.name + "Instance" + String(parent.numChildren);
- SceneChangeParent(node, parent, false);
- parent = node.parent;
- SelectNode(node, false);
- }
- Vector3 size;
- BoundingBox bb;
- // get bb for offset
- Drawable@ drawable = GetFirstDrawable(node);
- if (drawable !is null)
- {
- bb = drawable.boundingBox;
- size = bb.size * drawable.node.worldScale;
- offset = Vector3(size.x, 0, 0);
- }
- // make offset on axis that select user by mouse
- if (gizmoAxisX.selected)
- {
- if (size.x < minOffset) size.x = minOffset;
- offset = node.worldRotation * Vector3(size.x,0,0);
- }
- else if (gizmoAxisY.selected)
- {
- if (size.y < minOffset) size.y = minOffset;
- offset = node.worldRotation * Vector3(0,size.y,0);
- }
- else if (gizmoAxisZ.selected)
- {
- if (size.z < minOffset) size.z = minOffset;
- offset = node.worldRotation * Vector3(0,0,size.z);
- }
- else
- offset = lastOffsetForSmartDuplicate;
- Vector3 lastInstancePosition = node.worldPosition;
- SelectNode(node, false);
- SceneDuplicate();
- Node@ newInstance = parent.children[parent.numChildren-1];
- SelectNode(newInstance, false);
- newInstance.worldPosition = lastInstancePosition;
- newInstance.Translate(offset, TS_WORLD);
- newInstance.name = parent.name + "Instance" + String(parent.numChildren-1);
- lastOffsetForSmartDuplicate = offset;
- UpdateNodeAttributes();
- return true;
- }
- bool ViewCloser()
- {
- if (selectedNodes.length > 0 || selectedNodes.length > 0)
- LocateNodesAndComponents(selectedNodes, selectedComponents);
- return true;
- }
- bool SceneToggleEnable()
- {
- if (!CheckHierarchyWindowFocus())
- return false;
- ui.cursor.shape = CS_BUSY;
- EditActionGroup group;
- // Toggle enabled state of nodes recursively
- for (uint i = 0; i < selectedNodes.length; ++i)
- {
- // Do not attempt to disable the Scene
- if (selectedNodes[i].typeName == "Node")
- {
- bool oldEnabled = selectedNodes[i].enabled;
- selectedNodes[i].SetEnabledRecursive(!oldEnabled);
- // Create undo action
- ToggleNodeEnabledAction action;
- action.Define(selectedNodes[i], oldEnabled);
- group.actions.Push(action);
- }
- }
- for (uint i = 0; i < selectedComponents.length; ++i)
- {
- // Some components purposefully do not expose the Enabled attribute, and it does not affect them in any way
- // (Octree, PhysicsWorld). Check that the first attribute is in fact called "Is Enabled"
- if (selectedComponents[i].numAttributes > 0 && selectedComponents[i].attributeInfos[0].name == "Is Enabled")
- {
- bool oldEnabled = selectedComponents[i].enabled;
- selectedComponents[i].enabled = !oldEnabled;
- // Create undo action
- EditAttributeAction action;
- action.Define(selectedComponents[i], 0, Variant(oldEnabled));
- group.actions.Push(action);
- }
- }
- SaveEditActionGroup(group);
- SetSceneModified();
- return true;
- }
- bool SceneEnableAllNodes()
- {
- if (!CheckHierarchyWindowFocus())
- return false;
- ui.cursor.shape = CS_BUSY;
- EditActionGroup group;
- // Toggle enabled state of nodes recursively
- Array<Node@> allNodes;
- allNodes = editorScene.GetChildren(true);
- for (uint i = 0; i < allNodes.length; ++i)
- {
- // Do not attempt to disable the Scene
- if (allNodes[i].typeName == "Node")
- {
- bool oldEnabled = allNodes[i].enabled;
- if (oldEnabled == false)
- allNodes[i].SetEnabledRecursive(true);
- // Create undo action
- ToggleNodeEnabledAction action;
- action.Define(allNodes[i], oldEnabled);
- group.actions.Push(action);
- }
- }
- Array<Component@> allComponents;
- allComponents = editorScene.GetComponents();
- for (uint i = 0; i < allComponents.length; ++i)
- {
- // Some components purposefully do not expose the Enabled attribute, and it does not affect them in any way
- // (Octree, PhysicsWorld). Check that the first attribute is in fact called "Is Enabled"
- if (allComponents[i].numAttributes > 0 && allComponents[i].attributeInfos[0].name == "Is Enabled")
- {
- bool oldEnabled = allComponents[i].enabled;
- allComponents[i].enabled = true;
- // Create undo action
- EditAttributeAction action;
- action.Define(allComponents[i], 0, Variant(oldEnabled));
- group.actions.Push(action);
- }
- }
- SaveEditActionGroup(group);
- SetSceneModified();
- return true;
- }
- bool SceneChangeParent(Node@ sourceNode, Node@ targetNode, bool createUndoAction = true)
- {
- // Create undo action if requested
- if (createUndoAction)
- {
- ReparentNodeAction action;
- action.Define(sourceNode, targetNode);
- SaveEditAction(action);
- }
- sourceNode.parent = targetNode;
- SetSceneModified();
- // Return true if success
- if (sourceNode.parent is targetNode)
- {
- UpdateNodeAttributes(); // Parent change may have changed local transform
- return true;
- }
- else
- return false;
- }
- bool SceneChangeParent(Node@ sourceNode, Array<Node@> sourceNodes, Node@ targetNode, bool createUndoAction = true)
- {
- // Create undo action if requested
- if (createUndoAction)
- {
- ReparentNodeAction action;
- action.Define(sourceNodes, targetNode);
- SaveEditAction(action);
- }
- for (uint i = 0; i < sourceNodes.length; ++i)
- {
- Node@ node = sourceNodes[i];
- node.parent = targetNode;
- }
- SetSceneModified();
- // Return true if success
- if (sourceNode.parent is targetNode)
- {
- UpdateNodeAttributes(); // Parent change may have changed local transform
- return true;
- }
- else
- return false;
- }
- bool SceneReorder(Node@ sourceNode, Node@ targetNode)
- {
- if (sourceNode is null || targetNode is null || sourceNode.parent is null || sourceNode.parent !is targetNode.parent)
- return false;
- if (sourceNode is targetNode)
- return true; // No-op
- Node@ parent = sourceNode.parent;
- uint destIndex = SceneFindChildIndex(parent, targetNode);
- ReorderNodeAction action;
- action.Define(sourceNode, destIndex);
- SaveEditAction(action);
- PerformReorder(parent, sourceNode, destIndex);
- return true;
- }
- bool SceneReorder(Component@ sourceComponent, Component@ targetComponent)
- {
- if (sourceComponent is null || targetComponent is null || sourceComponent.node !is targetComponent.node)
- return false;
- if (sourceComponent is targetComponent)
- return true; // No-op
- Node@ node = sourceComponent.node;
- uint destIndex = SceneFindComponentIndex(node, targetComponent);
- ReorderComponentAction action;
- action.Define(sourceComponent, destIndex);
- SaveEditAction(action);
- PerformReorder(node, sourceComponent, destIndex);
- return true;
- }
- void PerformReorder(Node@ parent, Node@ child, uint destIndex)
- {
- suppressSceneChanges = true;
- // Removal from scene zeroes the ID. Be prepared to restore it
- uint oldId = child.id;
- parent.RemoveChild(child);
- child.id = oldId;
- parent.AddChild(child, destIndex);
- UpdateHierarchyItem(parent); // Force update to make sure the order is current
- SetSceneModified();
- suppressSceneChanges = false;
- }
- void PerformReorder(Node@ node, Component@ component, uint destIndex)
- {
- suppressSceneChanges = true;
- node.ReorderComponent(component, destIndex);
- UpdateHierarchyItem(node); // Force update to make sure the order is current
- SetSceneModified();
- suppressSceneChanges = false;
- }
- uint SceneFindChildIndex(Node@ parent, Node@ child)
- {
- for (uint i = 0; i < parent.numChildren; ++i)
- {
- if (parent.children[i] is child)
- return i;
- }
- return -1;
- }
- uint SceneFindComponentIndex(Node@ node, Component@ component)
- {
- for (uint i = 0; i < node.numComponents; ++i)
- {
- if (node.components[i] is component)
- return i;
- }
- return -1;
- }
- bool SceneResetPosition()
- {
- if (editNode !is null)
- {
- Transform oldTransform;
- oldTransform.Define(editNode);
- editNode.position = Vector3(0.0, 0.0, 0.0);
- // Create undo action
- EditNodeTransformAction action;
- action.Define(editNode, oldTransform);
- SaveEditAction(action);
- SetSceneModified();
- UpdateNodeAttributes();
- return true;
- }
- else
- return false;
- }
- bool SceneResetRotation()
- {
- if (editNode !is null)
- {
- Transform oldTransform;
- oldTransform.Define(editNode);
- editNode.rotation = Quaternion();
- // Create undo action
- EditNodeTransformAction action;
- action.Define(editNode, oldTransform);
- SaveEditAction(action);
- SetSceneModified();
- UpdateNodeAttributes();
- return true;
- }
- else
- return false;
- }
- bool SceneResetScale()
- {
- if (editNode !is null)
- {
- Transform oldTransform;
- oldTransform.Define(editNode);
- editNode.scale = Vector3(1.0, 1.0, 1.0);
- // Create undo action
- EditNodeTransformAction action;
- action.Define(editNode, oldTransform);
- SaveEditAction(action);
- SetSceneModified();
- UpdateNodeAttributes();
- return true;
- }
- else
- return false;
- }
- bool SceneResetTransform()
- {
- if (editNode !is null)
- {
- Transform oldTransform;
- oldTransform.Define(editNode);
- editNode.position = Vector3(0.0, 0.0, 0.0);
- editNode.rotation = Quaternion();
- editNode.scale = Vector3(1.0, 1.0, 1.0);
- // Create undo action
- EditNodeTransformAction action;
- action.Define(editNode, oldTransform);
- SaveEditAction(action);
- SetSceneModified();
- UpdateNodeAttributes();
- return true;
- }
- else
- return false;
- }
- bool SceneSelectAll()
- {
- BeginSelectionModify();
- Array<Node@> rootLevelNodes = editorScene.GetChildren();
- Array<uint> indices;
- for (uint i = 0; i < rootLevelNodes.length; ++i)
- indices.Push(GetListIndex(rootLevelNodes[i]));
- hierarchyList.SetSelections(indices);
- EndSelectionModify();
- return true;
- }
- bool SceneResetToDefault()
- {
- ui.cursor.shape = CS_BUSY;
- // Group for storing undo actions
- EditActionGroup group;
- // Reset selected component to their default
- if (!selectedComponents.empty)
- {
- for (uint i = 0; i < selectedComponents.length; ++i)
- {
- Component@ component = selectedComponents[i];
- ResetAttributesAction action;
- action.Define(component);
- group.actions.Push(action);
- component.ResetToDefault();
- component.ApplyAttributes();
- for (uint j = 0; j < component.numAttributes; ++j)
- PostEditAttribute(component, j);
- }
- }
- // OR reset selected nodes to their default
- else
- {
- for (uint i = 0; i < selectedNodes.length; ++i)
- {
- Node@ node = selectedNodes[i];
- ResetAttributesAction action;
- action.Define(node);
- group.actions.Push(action);
- node.ResetToDefault();
- node.ApplyAttributes();
- for (uint j = 0; j < node.numAttributes; ++j)
- PostEditAttribute(node, j);
- }
- }
- SaveEditActionGroup(group);
- SetSceneModified();
- attributesFullDirty = true;
- return true;
- }
- bool SceneRebuildNavigation()
- {
- ui.cursor.shape = CS_BUSY;
- Array<Component@>@ navMeshes = editorScene.GetComponents("NavigationMesh", true);
- if (navMeshes.empty)
- {
- @navMeshes = editorScene.GetComponents("DynamicNavigationMesh", true);
- if (navMeshes.empty)
- {
- MessageBox("No NavigationMesh components in the scene, nothing to rebuild.");
- return false;
- }
- }
- bool success = true;
- for (uint i = 0; i < navMeshes.length; ++i)
- {
- NavigationMesh@ navMesh = navMeshes[i];
- if (!navMesh.Build())
- success = false;
- }
- return success;
- }
- bool SceneRenderZoneCubemaps()
- {
- bool success = false;
- Array<Zone@> capturedThisCall;
- bool alreadyCapturing = activeCubeCapture.length > 0; // May have managed to quickly queue up a second round of zones to render cubemaps for
- for (uint i = 0; i < selectedNodes.length; ++i)
- {
- Array<Component@>@ zones = selectedNodes[i].GetComponents("Zone", true);
- for (uint z = 0; z < zones.length; ++z)
- {
- Zone@ zone = cast<Zone>(zones[z]);
- if (zone !is null)
- {
- activeCubeCapture.Push(EditorCubeCapture(zone));
- capturedThisCall.Push(zone);
- }
- }
- }
- for (uint i = 0; i < selectedComponents.length; ++i)
- {
- Zone@ zone = cast<Zone>(selectedComponents[i]);
- if (zone !is null)
- {
- if (capturedThisCall.FindByRef(zone) < 0)
- {
- activeCubeCapture.Push(EditorCubeCapture(zone));
- capturedThisCall.Push(zone);
- }
- }
- }
- // Start rendering cubemaps if there are any to render and the queue isn't already running
- if (activeCubeCapture.length > 0 && !alreadyCapturing)
- activeCubeCapture[0].Start();
- if (capturedThisCall.length <= 0)
- {
- MessageBox("No zones selected to render cubemaps for/");
- }
- return capturedThisCall.length > 0;
- }
- bool SceneAddChildrenStaticModelGroup()
- {
- StaticModelGroup@ smg = cast<StaticModelGroup>(editComponents.length > 0 ? editComponents[0] : null);
- if (smg is null && editNode !is null)
- smg = editNode.GetComponent("StaticModelGroup");
- if (smg is null)
- {
- MessageBox("Must have a StaticModelGroup component selected.");
- return false;
- }
- uint attrIndex = GetAttributeIndex(smg, "Instance Nodes");
- Variant oldValue = smg.attributes[attrIndex];
- Array<Node@> children = smg.node.GetChildren(true);
- for (uint i = 0; i < children.length; ++i)
- smg.AddInstanceNode(children[i]);
- EditAttributeAction action;
- action.Define(smg, attrIndex, oldValue);
- SaveEditAction(action);
- SetSceneModified();
- FocusComponent(smg);
- return true;
- }
- bool SceneSetChildrenSplinePath(bool makeCycle)
- {
- SplinePath@ sp = cast<SplinePath>(editComponents.length > 0 ? editComponents[0] : null);
- if (sp is null && editNode !is null)
- sp = editNode.GetComponent("SplinePath");
- if (sp is null)
- {
- MessageBox("Must have a SplinePath component selected.");
- return false;
- }
- uint attrIndex = GetAttributeIndex(sp, "Control Points");
- Variant oldValue = sp.attributes[attrIndex];
- Array<Node@> children = sp.node.GetChildren(true);
- if (children.length >= 2)
- {
- sp.ClearControlPoints();
- for (uint i = 0; i < children.length; ++i)
- sp.AddControlPoint(children[i]);
- }
- else
- {
- MessageBox("You must have a minimum two children Nodes in selected Node.");
- return false;
- }
- if (makeCycle)
- sp.AddControlPoint(children[0]);
- EditAttributeAction action;
- action.Define(sp, attrIndex, oldValue);
- SaveEditAction(action);
- SetSceneModified();
- FocusComponent(sp);
- return true;
- }
- void AssignMaterial(StaticModel@ model, String materialPath)
- {
- Material@ material = cache.GetResource("Material", materialPath);
- if (material is null)
- return;
- ResourceRefList materials = model.GetAttribute("Material").GetResourceRefList();
- Array<String> oldMaterials;
- for(uint i = 0; i < materials.length; ++i)
- oldMaterials.Push(materials.names[i]);
- model.material = material;
- AssignMaterialAction action;
- action.Define(model, oldMaterials, material);
- SaveEditAction(action);
- SetSceneModified();
- FocusComponent(model);
- }
- void UpdateSceneMru(String filename)
- {
- while (uiRecentScenes.Find(filename) > -1)
- uiRecentScenes.Erase(uiRecentScenes.Find(filename));
- uiRecentScenes.Insert(0, filename);
- for (uint i = uiRecentScenes.length - 1; i >= maxRecentSceneCount; i--)
- uiRecentScenes.Erase(i);
- PopulateMruScenes();
- }
- Drawable@ GetFirstDrawable(Node@ node)
- {
- Array<Node@> nodes = node.GetChildren(true);
- nodes.Insert(0, node);
- for (uint i = 0; i < nodes.length; ++i)
- {
- Array<Component@> components = nodes[i].GetComponents();
- for (uint j = 0; j < components.length; ++j)
- {
- Drawable@ drawable = cast<Drawable>(components[j]);
- if (drawable !is null)
- return drawable;
- }
- }
- return null;
- }
- void AssignModel(StaticModel@ assignee, String modelPath)
- {
- Model@ model = cache.GetResource("Model", modelPath);
- if (model is null)
- return;
- Model@ oldModel = assignee.model;
- assignee.model = model;
- AssignModelAction action;
- action.Define(assignee, oldModel, model);
- SaveEditAction(action);
- SetSceneModified();
- FocusComponent(assignee);
- }
- void CreateModelWithStaticModel(String filepath, Node@ parent)
- {
- if (parent is null)
- return;
- /// \todo should be able to specify the createmode
- if (parent is editorScene)
- parent = CreateNode(REPLICATED);
- Model@ model = cache.GetResource("Model", filepath);
- if (model is null)
- return;
- StaticModel@ staticModel = parent.GetOrCreateComponent("StaticModel");
- staticModel.model = model;
- if (applyMaterialList)
- staticModel.ApplyMaterialList();
- CreateLoadedComponent(staticModel);
- }
- void CreateModelWithAnimatedModel(String filepath, Node@ parent)
- {
- if (parent is null)
- return;
- /// \todo should be able to specify the createmode
- if (parent is editorScene)
- parent = CreateNode(REPLICATED);
- Model@ model = cache.GetResource("Model", filepath);
- if (model is null)
- return;
- AnimatedModel@ animatedModel = parent.GetOrCreateComponent("AnimatedModel");
- animatedModel.model = model;
- if (applyMaterialList)
- animatedModel.ApplyMaterialList();
- CreateLoadedComponent(animatedModel);
- }
- bool ColorWheelSetupBehaviorForColoring()
- {
- Menu@ menu = GetEventSender();
- if (menu is null)
- return false;
- coloringPropertyName = menu.name;
- if (coloringPropertyName == "menuCancel") return false;
- if (coloringComponent.typeName == "Light")
- {
- Light@ light = cast<Light>(coloringComponent);
- if (light !is null)
- {
- if (coloringPropertyName == "menuLightColor")
- {
- coloringOldColor = light.color;
- ShowColorWheelWithColor(coloringOldColor);
- }
- else if (coloringPropertyName == "menuSpecularIntensity")
- {
- // ColorWheel have only 0-1 range output of V-value(BW), and for huge-range values we divide in and multiply out
- float scaledSpecular = light.specularIntensity * 0.1f;
- coloringOldScalar = scaledSpecular;
- ShowColorWheelWithColor(Color(scaledSpecular,scaledSpecular,scaledSpecular));
- }
- else if (coloringPropertyName == "menuBrightnessMultiplier")
- {
- float scaledBrightness = light.brightness * 0.1f;
- coloringOldScalar = scaledBrightness;
- ShowColorWheelWithColor(Color(scaledBrightness,scaledBrightness,scaledBrightness));
- }
- }
- }
- else if (coloringComponent.typeName == "StaticModel")
- {
- StaticModel@ model = cast<StaticModel>(coloringComponent);
- if (model !is null)
- {
- Material@ mat = model.materials[0];
- if (mat !is null)
- {
- if (coloringPropertyName == "menuDiffuseColor")
- {
- Variant oldValue = mat.shaderParameters["MatDiffColor"];
- Array<String> values = oldValue.ToString().Split(' ');
- coloringOldColor = Color(values[0].ToFloat(),values[1].ToFloat(),values[2].ToFloat(),values[3].ToFloat()); //RGBA
- ShowColorWheelWithColor(coloringOldColor);
- }
- else if (coloringPropertyName == "menuSpecularColor")
- {
- Variant oldValue = mat.shaderParameters["MatSpecColor"];
- Array<String> values = oldValue.ToString().Split(' ');
- coloringOldColor = Color(values[0].ToFloat(),values[1].ToFloat(),values[2].ToFloat());
- coloringOldScalar = values[3].ToFloat();
- ShowColorWheelWithColor(Color(coloringOldColor.r, coloringOldColor.g, coloringOldColor.b, coloringOldScalar/128.0f)); //RGB + shine
- }
- else if (coloringPropertyName == "menuEmissiveColor")
- {
- Variant oldValue = mat.shaderParameters["MatEmissiveColor"];
- Array<String> values = oldValue.ToString().Split(' ');
- coloringOldColor = Color(values[0].ToFloat(),values[1].ToFloat(),values[2].ToFloat()); // RGB
- ShowColorWheelWithColor(coloringOldColor);
- }
- else if (coloringPropertyName == "menuEnvironmentMapColor")
- {
- Variant oldValue = mat.shaderParameters["MatEnvMapColor"];
- Array<String> values = oldValue.ToString().Split(' ');
- coloringOldColor = Color(values[0].ToFloat(),values[1].ToFloat(),values[2].ToFloat()); //RGB
- ShowColorWheelWithColor(coloringOldColor);
- }
- }
- }
- }
- else if (coloringComponent.typeName == "Zone")
- {
- Zone@ zone = cast<Zone>(coloringComponent);
- if (zone !is null)
- {
- if (coloringPropertyName == "menuAmbientColor")
- {
- coloringOldColor = zone.ambientColor;
- }
- else if (coloringPropertyName == "menuFogColor")
- {
- coloringOldColor = zone.fogColor;
- }
- ShowColorWheelWithColor(coloringOldColor);
- }
- }
- else if (coloringComponent.typeName == "Text3D")
- {
- Text3D@ txt = cast<Text3D>(coloringComponent);
- if (txt !is null)
- {
- if (coloringPropertyName == "c" || coloringPropertyName == "tl")
- coloringOldColor = txt.colors[C_TOPLEFT];
- else if (coloringPropertyName == "tr")
- coloringOldColor = txt.colors[C_TOPRIGHT];
- else if (coloringPropertyName == "bl")
- coloringOldColor = txt.colors[C_BOTTOMLEFT];
- else if (coloringPropertyName == "br")
- coloringOldColor = txt.colors[C_BOTTOMRIGHT];
- ShowColorWheelWithColor(coloringOldColor);
- }
- }
- return true;
- }
|