소스 검색

Exposed recursive SetEnabled() differently, to match convention of the rest of recursive Node functions and eliminate code duplication.
Added Ctrl+E in editor to toggle enabled/disabled state of selected node hierarchies and components.

Lasse Öörni 12 년 전
부모
커밋
f5b837f460

+ 1 - 0
Bin/Data/Scripts/Editor.as

@@ -77,6 +77,7 @@ void HandleUpdate(StringHash eventType, VariantMap& eventData)
     UpdateStats(timeStep);
     UpdateScene(timeStep);
     UpdateGizmo();
+    UpdateDirtyUI();
 }
 
 void LoadConfig()

+ 1 - 0
Bin/Data/Scripts/Editor/EditorNodeWindow.as

@@ -6,6 +6,7 @@ UIElement@ componentParentContainer;
 XMLFile@ componentXMLResource;
 
 bool applyMaterialList = true;
+bool nodeWindowIconsDirty = false;
 
 const String STRIKED_OUT = "——";   // Two unicode EM DASH (U+2014)
 

+ 21 - 0
Bin/Data/Scripts/Editor/EditorScene.as

@@ -459,6 +459,27 @@ void SceneUnparent()
         hierarchyList.AddSelection(GetNodeListIndex(changedNodes[i]));
 }
 
+void SceneToggleEnable()
+{
+    if (!CheckSceneWindowFocus())
+        return;
+
+    // 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")
+            selectedNodes[i].SetEnabled(!selectedNodes[i].enabled, true);
+    }
+    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")
+            selectedComponents[i].enabled = !selectedComponents[i].enabled;
+    }
+}
+
 bool SceneChangeParent(Node@ sourceNode, Node@ targetNode)
 {
     // Perform the reparenting

+ 6 - 5
Bin/Data/Scripts/Editor/EditorSceneWindow.as

@@ -188,13 +188,14 @@ void UpdateSceneWindowNode(Node@ node)
     UpdateSceneWindowNode(GetNodeListIndex(node), node, hierarchyList.items[GetNodeListIndex(node.parent)]);
 }
 
-void UpdateSceneWindowNodeText(Node@ node)
+void UpdateSceneWindowNodeText(Node@ node, bool iconOnly = false)
 {
     uint index = GetNodeListIndex(node);
     Text@ text = hierarchyList.items[index];
     if (text is null)
         return;
-    text.text = GetNodeTitle(node);
+    if (!iconOnly)
+        text.text = GetNodeTitle(node);
     SetIconEnabledColor(text, node.enabled);
 }
 
@@ -761,8 +762,8 @@ void HandleNodeEnabledChanged(StringHash eventType, VariantMap& eventData)
         return;
     
     Node@ node = eventData["Node"].GetNode();
-    UpdateSceneWindowNodeText(node);
-    UpdateNodeWindowIcons();
+    UpdateSceneWindowNodeText(node, true);
+    nodeWindowIconsDirty = true;
 }
 
 void HandleComponentEnabledChanged(StringHash eventType, VariantMap& eventData)
@@ -772,5 +773,5 @@ void HandleComponentEnabledChanged(StringHash eventType, VariantMap& eventData)
     
     Component@ component = eventData["Component"].GetComponent();
     UpdateSceneWindowComponentText(component);
-    UpdateNodeWindowIcons();
+    nodeWindowIconsDirty = true;
 }

+ 13 - 0
Bin/Data/Scripts/Editor/EditorUI.as

@@ -146,6 +146,7 @@ void CreateMenuBar()
         editPopup.AddChild(CreateMenuItem("Reset position", 0, 0));
         editPopup.AddChild(CreateMenuItem("Reset rotation", 0, 0));
         editPopup.AddChild(CreateMenuItem("Reset scale", 0, 0));
+        editPopup.AddChild(CreateMenuItem("Enable/disable", 'E', QUAL_CTRL));
         editPopup.AddChild(CreateMenuItem("Unparent", 'U', QUAL_CTRL));
         editPopup.AddChild(CreateMenuDivider());
         editPopup.AddChild(CreateMenuItem("Toggle update", 'P', QUAL_CTRL));
@@ -402,6 +403,8 @@ void HandleMenuSelected(StringHash eventType, VariantMap& eventData)
         SceneResetRotation();
     else if (action == "Reset scale")
         SceneResetScale();
+    else if (action == "Enable/disable")
+        SceneToggleEnable();
     else if (action == "Unparent")
         SceneUnparent();
     else if (action == "Select all")
@@ -634,3 +637,13 @@ void SetIconEnabledColor(UIElement@ element, bool enabled, bool partial = false)
             icon.color = enabled ? Color(1,1,1,1) : Color(1,0,0,1);
     }
 }
+
+void UpdateDirtyUI()
+{
+    // Perform some event-triggered updates latently in case a large hierarchy was changed
+    if (nodeWindowIconsDirty)
+    {
+        UpdateNodeWindowIcons();
+        nodeWindowIconsDirty = false;
+    }
+}

+ 1 - 0
Docs/GettingStarted.dox

@@ -674,6 +674,7 @@ Ctrl+S          - Save scene
 Ctrl+Shift+S    - Save scene as
 Ctrl+A          - Select/deselect all root level nodes
 Ctrl+X,C,V      - Cut/copy/paste node or component
+Ctrl+E          - Enable/disable node hierarchy or component
 Ctrl+U          - Unparent scene node
 Ctrl+H          - Open the scene hierarchy window
 Ctrl+N          - Open the node / component edit window

+ 1 - 1
Docs/ScriptAPI.dox

@@ -1366,7 +1366,7 @@ Methods:<br>
 - Vector3 LocalToWorld(const Vector4&) const
 - Vector3 WorldToLocal(const Vector3&) const
 - Vector3 WorldToLocal(const Vector4&) const
-- void SetEnabledRecursive(bool)
+- void SetEnabled(bool, bool)
 - bool SaveXML(File@)
 - Node@ Clone(CreateMode arg0 = REPLICATED)
 - ScriptObject@ CreateScriptObject(ScriptFile@, const String&, CreateMode arg2 = REPLICATED)

+ 2 - 2
Engine/Engine/SceneAPI.cpp

@@ -58,8 +58,8 @@ static void RegisterNode(asIScriptEngine* engine)
     // Register Component first. At this point Node is not yet registered, so can not register GetNode for Component
     RegisterComponent<Component>(engine, "Component", false, false);
     RegisterNode<Node>(engine, "Node");
-    engine->RegisterObjectMethod("Node", "void SetEnabledRecursive(bool)", asMETHOD(Node, SetEnabledRecursive), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Node", "void set_enabled(bool)", asMETHOD(Node, SetEnabled), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Node", "void SetEnabled(bool, bool)", asMETHODPR(Node, SetEnabled, (bool, bool), void), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Node", "void set_enabled(bool)", asMETHODPR(Node, SetEnabled, (bool), void), asCALL_THISCALL);
     engine->RegisterObjectMethod("Node", "bool get_enabled() const", asMETHOD(Node, IsEnabled), asCALL_THISCALL);
     engine->RegisterObjectMethod("Node", "bool SaveXML(File@+)", asFUNCTION(NodeSaveXML), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("Node", "Node@+ Clone(CreateMode mode = REPLICATED)", asMETHOD(Node, Clone), asCALL_THISCALL);

+ 4 - 4
Engine/Physics/PhysicsWorld.cpp

@@ -559,10 +559,10 @@ void PhysicsWorld::SendCollisionEvents()
             
             RigidBody* bodyA = static_cast<RigidBody*>(objectA->getUserPointer());
             RigidBody* bodyB = static_cast<RigidBody*>(objectB->getUserPointer());
-			// If it's not a rigidbody, maybe a ghost object
-			if (!bodyA || !bodyB)
-				continue;
-
+            // If it's not a rigidbody, maybe a ghost object
+            if (!bodyA || !bodyB)
+                continue;
+            
             WeakPtr<RigidBody> bodyWeakA(bodyA);
             WeakPtr<RigidBody> bodyWeakB(bodyB);
             

+ 18 - 18
Engine/Physics/RigidBody.cpp

@@ -75,7 +75,7 @@ RigidBody::RigidBody(Context* context) :
     useGravity_(true),
     hasSmoothedTransform_(false),
     readdBody_(false),
-	inWorld_(false)
+    inWorld_(false)
 {
     compoundShape_ = new btCompoundShape();
 }
@@ -138,12 +138,12 @@ void RigidBody::ApplyAttributes()
 
 void RigidBody::OnSetEnabled()
 {
-	bool enabled = IsEnabledEffective();
-
-	if (enabled && !inWorld_)
-		AddBodyToWorld();
-	else if (!enabled && inWorld_)
-		RemoveBodyFromWorld();
+    bool enabled = IsEnabledEffective();
+    
+    if (enabled && !inWorld_)
+        AddBodyToWorld();
+    else if (!enabled && inWorld_)
+        RemoveBodyFromWorld();
 }
 
 void RigidBody::getWorldTransform(btTransform &worldTrans) const
@@ -761,7 +761,7 @@ void RigidBody::ReleaseBody()
         for (PODVector<Constraint*>::Iterator i = constraints.Begin(); i != constraints.End(); ++i)
             (*i)->ReleaseConstraint();
         
-		RemoveBodyFromWorld();
+        RemoveBodyFromWorld();
         
         delete body_;
         body_ = 0;
@@ -887,14 +887,14 @@ void RigidBody::AddBodyToWorld()
         flags &= ~btCollisionObject::CF_KINEMATIC_OBJECT;
     body_->setCollisionFlags(flags);
     
-	if (!IsEnabledEffective())
-		return;
-
+    if (!IsEnabledEffective())
+        return;
+    
     btDiscreteDynamicsWorld* world = physicsWorld_->GetWorld();
     world->addRigidBody(body_, collisionLayer_, collisionMask_);
     inWorld_ = true;
-	readdBody_ = false;
-
+    readdBody_ = false;
+    
     if (mass_ > 0.0f)
         Activate();
     else
@@ -907,11 +907,11 @@ void RigidBody::AddBodyToWorld()
 void RigidBody::RemoveBodyFromWorld()
 {
     if (physicsWorld_ && body_ && inWorld_)
-	{
-		btDiscreteDynamicsWorld* world = physicsWorld_->GetWorld();
-		world->removeRigidBody(body_);
-		inWorld_ = false;
-	}
+    {
+        btDiscreteDynamicsWorld* world = physicsWorld_->GetWorld();
+        world->removeRigidBody(body_);
+        inWorld_ = false;
+    }
 }
 
 void RigidBody::HandleTargetPosition(StringHash eventType, VariantMap& eventData)

+ 5 - 5
Engine/Physics/RigidBody.h

@@ -64,7 +64,7 @@ public:
     virtual void ApplyAttributes();
     /// Handle enabled/disabled state change.
     virtual void OnSetEnabled();
-	/// Return initial world transform to Bullet.
+    /// Return initial world transform to Bullet.
     virtual void getWorldTransform(btTransform &worldTrans) const;
     /// Update world transform from Bullet.
     virtual void setWorldTransform(const btTransform &worldTrans);
@@ -221,8 +221,8 @@ protected:
 private:
     /// Create the rigid body, or re-add to the physics world with changed flags. Calls UpdateMass().
     void AddBodyToWorld();
-	/// Remove the rigid body from the physics world.
-	void RemoveBodyFromWorld();
+    /// Remove the rigid body from the physics world.
+    void RemoveBodyFromWorld();
     /// Handle SmoothedTransform target position update.
     void HandleTargetPosition(StringHash eventType, VariantMap& eventData);
     /// Handle SmoothedTransform target rotation update.
@@ -262,8 +262,8 @@ private:
     bool hasSmoothedTransform_;
     /// Readd body to world flag.
     bool readdBody_;
-	/// Body exists in world flag.
-	bool inWorld_;
+    /// Body exists in world flag.
+    bool inWorld_;
 };
 
 }

+ 9 - 13
Engine/Scene/Node.cpp

@@ -434,6 +434,11 @@ void Node::Scale(const Vector3& scale)
 }
 
 void Node::SetEnabled(bool enable)
+{
+    SetEnabled(enable, false);
+}
+
+void Node::SetEnabled(bool enable, bool recursive)
 {
     // The enabled state of the whole scene can not be changed. SetUpdateEnabled() is used instead to start/stop updates.
     if (GetType() == Scene::GetTypeStatic())
@@ -478,21 +483,12 @@ void Node::SetEnabled(bool enable)
             }
         }
     }
-}
-
-void Node::SetEnabledRecursive(bool enable)
-{
-    // The enabled state of the whole scene can not be changed. SetUpdateEnabled() is used instead to start/stop updates.
-    if (GetType() == Scene::GetTypeStatic())
+    
+    if (recursive)
     {
-        LOGERROR("Can not change enabled state of the Scene");
-        return;
+        for (Vector<SharedPtr<Node> >::Iterator i = children_.Begin(); i != children_.End(); ++i)
+            (*i)->SetEnabled(enable, recursive);
     }
-    
-    SetEnabled(enable);
-    
-    for (Vector<SharedPtr<Node> >::Iterator i = children_.Begin(); i != children_.End(); ++i)
-        (*i)->SetEnabledRecursive(enable);
 }
 
 void Node::SetOwner(Connection* owner)

+ 3 - 3
Engine/Scene/Node.h

@@ -129,10 +129,10 @@ public:
     void Scale(float scale);
     /// Modify scale.
     void Scale(const Vector3& scale);
-    /// Set enabled/disabled state. Components in a disabled node become effectively disabled regardless of their own enable/disable state.
+    /// Set enabled/disabled state without recursion. Components in a disabled node become effectively disabled regardless of their own enable/disable state.
     void SetEnabled(bool enable);
-    /// Set enabled/disabled state recursively also to child nodes.
-    void SetEnabledRecursive(bool enable);
+    /// Set enabled/disabled state with optional recursion.
+    void SetEnabled(bool enable, bool recursive);
     /// Set owner connection for networking.
     void SetOwner(Connection* owner);
     /// Mark node and child nodes to need world transform recalculation. Notify listener components.