Browse Source

First cut of prefab improvements

Josh Engebretson 10 years ago
parent
commit
ac8f6cdaf8

+ 0 - 23
Script/AtomicEditor/ui/frames/inspector/ComponentInspector.ts

@@ -173,29 +173,6 @@ class ComponentInspector extends Atomic.UISection {
 
 
     addPrefabUI(layout: Atomic.UILayout) {
     addPrefabUI(layout: Atomic.UILayout) {
 
 
-        // expand prefab
-        this.value = 1;
-
-        var fd = new Atomic.UIFontDescription();
-        fd.id = "Vera";
-        fd.size = 11;
-
-        var selectButton = new Atomic.UIButton();
-        selectButton.text = "Select Prefab";
-        selectButton.fontDescription = fd;
-
-        selectButton.onClick = () => {
-
-            var node = (<Atomic.PrefabComponent> this.component).getPrefabNode();
-
-            this.sendEvent("EditorActiveNodeChange", { node: node });
-
-            return true;
-
-        }
-
-        layout.addChild(selectButton);
-
     }
     }
 
 
     acceptAssetDrag(importerTypeName: string, ev: Atomic.DragEndedEvent): ToolCore.AssetImporter {
     acceptAssetDrag(importerTypeName: string, ev: Atomic.DragEndedEvent): ToolCore.AssetImporter {

+ 5 - 5
Script/AtomicEditor/ui/frames/inspector/NodeInspector.ts

@@ -35,8 +35,8 @@ class NodeInspector extends ScriptWidget {
 
 
     getPrefabComponent(node: Atomic.Node): Atomic.PrefabComponent {
     getPrefabComponent(node: Atomic.Node): Atomic.PrefabComponent {
 
 
-        if (node.parent && node.parent.getComponent("PrefabComponent"))
-            return <Atomic.PrefabComponent> node.parent.getComponent("PrefabComponent");
+        if (node.getComponent("PrefabComponent"))
+            return <Atomic.PrefabComponent> node.getComponent("PrefabComponent");
 
 
         if (node.parent)
         if (node.parent)
             return this.getPrefabComponent(node.parent);
             return this.getPrefabComponent(node.parent);
@@ -47,7 +47,7 @@ class NodeInspector extends ScriptWidget {
 
 
     detectPrefab(node: Atomic.Node): boolean {
     detectPrefab(node: Atomic.Node): boolean {
 
 
-        if (node.parent && node.parent.getComponent("PrefabComponent"))
+        if (node.getComponent("PrefabComponent"))
             return true;
             return true;
 
 
         if (node.parent)
         if (node.parent)
@@ -232,8 +232,8 @@ class NodeInspector extends ScriptWidget {
 
 
             var component = components[i];
             var component = components[i];
 
 
-            if (component.isTemporary())
-              continue;
+            //if (component.isTemporary())
+            //  continue;
 
 
             var ci = new ComponentInspector();
             var ci = new ComponentInspector();
 
 

+ 62 - 27
Source/Atomic/Scene/PrefabComponent.cpp

@@ -51,15 +51,53 @@ void PrefabComponent::LoadPrefabNode()
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     XMLFile* xmlfile = cache->GetResource<XMLFile>(prefabGUID_);
     XMLFile* xmlfile = cache->GetResource<XMLFile>(prefabGUID_);
 
 
-    prefabNode_->LoadXML(xmlfile->GetRoot());
-    prefabNode_->SetTemporary(true);
+    if (!xmlfile || !node_)
+        return;
+
+    bool temporary = IsTemporary();
+    unsigned id = GetID();
+
+    // We're going to be removed, so keep ourselves alive and
+    // a reference to node_ as we'll readd
+    SharedPtr<PrefabComponent> keepAlive(this);
+    SharedPtr<Node> node(node_);
+
+    // store original transform
+    Vector3 pos = node->GetPosition();
+    Quaternion rot = node->GetRotation();
+    Vector3 scale = node->GetScale();
+
+    node->LoadXML(xmlfile->GetRoot());
+
+    node->SetPosition(pos);
+    node->SetRotation(rot);
+    node->SetScale(scale);
+
+    // Get the root components of the load node
+    const Vector<SharedPtr<Component>>& rootComponents = node->GetComponents();
+
+    // set all loaded components to be temporary, set all loaded root components and
+    // direct children to temporary
+    for (unsigned i = 0; i < rootComponents.Size(); i++)
+    {
+        rootComponents.At(i)->SetTemporary(true);
+    }
+
+    const Vector<SharedPtr<Node> >& children = node->GetChildren();
+
+    for (unsigned i = 0; i < children.Size(); i++)
+    {
+        children.At(i)->SetTemporary(true);
+    }
 
 
-    prefabNode_->SetPosition(Vector3::ZERO);
-    prefabNode_->SetRotation(Quaternion::IDENTITY);
-    // prefabNode_->SetScale(Vector3::ONE);
+    // readd via stored node, which is the same as node_ after this add
+    this->SetTemporary(temporary);
+    node->AddComponent(this, id, REPLICATED);
 
 
+    // Get all the rigid bodies of the load node
     PODVector<RigidBody*> bodies;
     PODVector<RigidBody*> bodies;
-    prefabNode_->GetComponents<RigidBody>(bodies, true);
+    node_->GetComponents<RigidBody>(bodies, true);
+
     for (unsigned i = 0; i < bodies.Size(); i++)
     for (unsigned i = 0; i < bodies.Size(); i++)
     {
     {
         RigidBody* body = bodies[i];
         RigidBody* body = bodies[i];
@@ -73,14 +111,28 @@ void PrefabComponent::BreakPrefab()
     if (!node_ || !node_->GetScene())
     if (!node_ || !node_->GetScene())
         return;
         return;
 
 
-    SharedPtr<PrefabComponent> keepAlive(this);
+    // flip temporary root children and components to break prefab
+    const Vector<SharedPtr<Component>>& rootComponents = node_->GetComponents();
+    const Vector<SharedPtr<Node> >& children = node_->GetChildren();
+
+    for (unsigned i = 0; i < rootComponents.Size(); i++)
+    {
+        if (rootComponents[i]->IsTemporary())
+        {
+            rootComponents[i]->SetTemporary(false);
+        }
+    }
 
 
-    if (prefabNode_.NotNull())
-        prefabNode_->SetTemporary(false);
+    for (unsigned i = 0; i < children.Size(); i++)
+    {
+        if (children[i]->IsTemporary())
+        {
+            children[i]->SetTemporary(false);
+        }
+    }
 
 
     node_->RemoveComponent(this);
     node_->RemoveComponent(this);
 
 
-
 }
 }
 
 
 void PrefabComponent::HandlePrefabChanged(StringHash eventType, VariantMap& eventData)
 void PrefabComponent::HandlePrefabChanged(StringHash eventType, VariantMap& eventData)
@@ -96,14 +148,7 @@ void PrefabComponent::HandlePrefabChanged(StringHash eventType, VariantMap& even
 
 
 void PrefabComponent::SetPrefabGUID(const String& guid)
 void PrefabComponent::SetPrefabGUID(const String& guid)
 {
 {
-    assert(prefabNode_.Null());
-
-    // ensure to use node_->CreateChild() so in scene, this may be fixed
-    // with update on https://github.com/urho3d/Urho3D/issues/748
-    assert(node_);
-
     prefabGUID_ = guid;
     prefabGUID_ = guid;
-    prefabNode_ = node_->CreateChild();
 
 
     if (prefabGUID_.Length())
     if (prefabGUID_.Length())
     {
     {
@@ -115,16 +160,6 @@ void PrefabComponent::SetPrefabGUID(const String& guid)
 void PrefabComponent::OnNodeSet(Node* node)
 void PrefabComponent::OnNodeSet(Node* node)
 {
 {
     Component::OnNodeSet(node);
     Component::OnNodeSet(node);
-
-
-    if (!node && prefabNode_.NotNull())
-    {
-        // a prefab node might not be temporary is prefab is broken{
-        if (prefabNode_->IsTemporary())
-            prefabNode_->Remove();
-
-        prefabNode_ = NULL;
-    }
 }
 }
 
 
 }
 }

+ 0 - 3
Source/Atomic/Scene/PrefabComponent.h

@@ -28,8 +28,6 @@ public:
     void UndoPrefab();
     void UndoPrefab();
     void BreakPrefab();
     void BreakPrefab();
 
 
-    Node* GetPrefabNode() { return prefabNode_; }
-
 protected:
 protected:
 
 
     /// Handle scene node being assigned at creation.
     /// Handle scene node being assigned at creation.
@@ -42,7 +40,6 @@ private:
 
 
     void LoadPrefabNode();
     void LoadPrefabNode();
 
 
-    SharedPtr<Node> prefabNode_;
     String prefabGUID_;
     String prefabGUID_;
 
 
 };
 };

+ 1 - 0
Source/AtomicJS/Javascript/JSScene.cpp

@@ -204,6 +204,7 @@ static int Node_CreateChildPrefab(duk_context* ctx)
     const char* prefabName = duk_require_string(ctx, 1);
     const char* prefabName = duk_require_string(ctx, 1);
 
 
     duk_push_this(ctx);
     duk_push_this(ctx);
+
     Node* parent = js_to_class_instance<Node>(ctx, -1, 0);
     Node* parent = js_to_class_instance<Node>(ctx, -1, 0);
 
 
     Node* prefabNode = parent->CreateChild(childName);
     Node* prefabNode = parent->CreateChild(childName);

+ 54 - 1
Source/ToolCore/Assets/PrefabImporter.cpp

@@ -49,16 +49,69 @@ void PrefabImporter::HandlePrefabSave(StringHash eventType, VariantMap& eventDat
     if (component->GetPrefabGUID() != asset_->GetGUID())
     if (component->GetPrefabGUID() != asset_->GetGUID())
         return;
         return;
 
 
-    Node* node = component->GetPrefabNode();
+    Node* node = component->GetNode();
+
+    if (!node)
+        return;
+
+    // flip temporary root children and components to not be temporary for save
+    const Vector<SharedPtr<Component>>& rootComponents = node->GetComponents();
+    const Vector<SharedPtr<Node> >& children = node->GetChildren();
+
+    Vector<SharedPtr<Component>> tempComponents;
+    Vector<SharedPtr<Node>> tempChildren;
+
+    for (unsigned i = 0; i < rootComponents.Size(); i++)
+    {
+        if (rootComponents[i]->IsTemporary())
+        {
+            rootComponents[i]->SetTemporary(false);
+            tempComponents.Push(rootComponents[i]);
+        }
+    }
+
+    for (unsigned i = 0; i < children.Size(); i++)
+    {
+        if (children[i]->IsTemporary())
+        {
+            children[i]->SetTemporary(false);
+            tempChildren.Push(children);
+        }
+    }
+
+    // store original transform
+    Vector3 pos = node->GetPosition();
+    Quaternion rot = node->GetRotation();
+    Vector3 scale = node->GetScale();
 
 
     node->SetPosition(Vector3::ZERO);
     node->SetPosition(Vector3::ZERO);
     node->SetRotation(Quaternion::IDENTITY);
     node->SetRotation(Quaternion::IDENTITY);
     node->SetScale(Vector3::ONE);
     node->SetScale(Vector3::ONE);
 
 
+    component->SetTemporary(true);
+
     SharedPtr<File> file(new File(context_, asset_->GetPath(), FILE_WRITE));
     SharedPtr<File> file(new File(context_, asset_->GetPath(), FILE_WRITE));
     node->SaveXML(*file);
     node->SaveXML(*file);
     file->Close();
     file->Close();
 
 
+    component->SetTemporary(false);
+
+    // restore
+    node->SetPosition(pos);
+    node->SetRotation(rot);
+    node->SetScale(scale);
+
+    for (unsigned i = 0; i < tempComponents.Size(); i++)
+    {
+        tempComponents[i]->SetTemporary(true);
+    }
+
+    for (unsigned i = 0; i < tempChildren.Size(); i++)
+    {
+        tempChildren[i]->SetTemporary(true);
+    }
+
+
     FileSystem* fs = GetSubsystem<FileSystem>();
     FileSystem* fs = GetSubsystem<FileSystem>();
     fs->Copy(asset_->GetPath(), asset_->GetCachePath());
     fs->Copy(asset_->GetPath(), asset_->GetCachePath());