Browse Source

Support material creation, guard against NAN in model animation import settings, support breaking prefabs at scene level,

Josh Engebretson 10 years ago
parent
commit
aadde2289d

+ 14 - 0
Resources/EditorData/AtomicEditor/templates/template_material.material

@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<material>
+	<technique name="Techniques/Diff.xml" quality="0" loddistance="0" />
+	<parameter name="UOffset" value="1 0 0 0" />
+	<parameter name="VOffset" value="0 1 0 0" />
+	<parameter name="MatDiffColor" value="0.8 0.8 0.8 1" />
+	<parameter name="MatEmissiveColor" value="0 0 0 1" />
+	<parameter name="MatEnvMapColor" value="1 1 1" />
+	<parameter name="MatSpecColor" value="0.6 0.6 0.6 16" />
+	<cull value="ccw" />
+	<shadowcull value="ccw" />
+	<fill value="solid" />
+	<depthbias constant="0" slopescaled="0" />
+</material>

+ 40 - 0
Script/AtomicEditor/resources/ResourceOps.ts

@@ -114,3 +114,43 @@ export function CreateNewScene(resourcePath: string, sceneName: string, reportEr
     return true;
 
 }
+
+export function CreateNewMaterial(resourcePath: string, materialName: string, reportError: boolean = true): boolean {
+
+    var title = "New Material Error";
+
+    var fs = Atomic.fileSystem;
+
+    if (fs.dirExists(resourcePath) || fs.fileExists(resourcePath)) {
+        if (reportError)
+            resourceOps.sendEvent(EditorEvents.ModalError, { title: title, message: "Already exists: " + resourcePath });
+        return false;
+
+    }
+
+    var templateFilename = "AtomicEditor/templates/template_material.material";
+    var file = Atomic.cache.getFile(templateFilename);
+
+    if (!file) {
+
+        if (reportError)
+            resourceOps.sendEvent(EditorEvents.ModalError, { title: title, message: "Failed to open template: " + templateFilename });
+        return false;
+
+    }
+
+    var out = new Atomic.File(resourcePath, Atomic.FILE_WRITE);
+    var success = out.copy(file);
+    out.close();
+
+    if (!success) {
+        if (reportError)
+            resourceOps.sendEvent(EditorEvents.ModalError, { title: title, message: "Failed template copy: " + templateFilename + " -> " + resourcePath });
+        return false;
+    }
+
+    ToolCore.assetDatabase.scan();
+
+    return true;
+
+}

+ 1 - 1
Script/AtomicEditor/ui/HierarchyFrame.ts

@@ -67,7 +67,7 @@ class HierarchyFrame extends Atomic.UIWidget {
 
                 if (itemID) {
 
-                    this.hierList.setItemIcon(node.id.toString(), IconTemporary);
+                    this.hierList.setItemIcon(node.id.toString(), node.isTemporary() ? IconTemporary : "");
 
                 }
 

+ 9 - 3
Script/AtomicEditor/ui/ProjectFrameMenu.ts

@@ -46,6 +46,10 @@ class ProjectFrameMenus extends Atomic.ScriptObject {
                 return true;
             }
 
+            if (refid == "create_material") {
+                EditorUI.getModelOps().showCreateMaterial(asset.path);
+                return true;
+            }
 
         }
 
@@ -124,6 +128,7 @@ var assetGeneralContextItems = {
 var assetFolderContextItems = {
     "Create Folder": ["create_folder", undefined, "Folder.icon"],
     "Create Component": ["create_component", undefined, "ComponentBitmap"],
+    "Create Material": ["create_material", undefined, "ComponentBitmap"],
     "Create Scene": ["create_scene", undefined, "ComponentBitmap"],
     "-1": null,
     "Reveal in Finder": ["reveal_folder", undefined, ""],
@@ -132,7 +137,8 @@ var assetFolderContextItems = {
 };
 
 var createItems = {
-    "Folder": ["create_folder", undefined, "Folder.icon"],
-    "-1": null,
-    "Script": ["create_script", undefined, "JavascriptBitmap"]
+  "Create Folder": ["create_folder", undefined, "Folder.icon"],
+  "Create Component": ["create_component", undefined, "ComponentBitmap"],
+  "Create Material": ["create_material", undefined, "ComponentBitmap"],
+  "Create Scene": ["create_scene", undefined, "ComponentBitmap"],
 };

+ 10 - 2
Script/AtomicEditor/ui/inspector/ModelInspector.ts

@@ -33,8 +33,16 @@ class ModelInspector extends InspectorWidget {
           var endEdit = this.endEdits[i];
 
           info.name = nameEdit.text;
-          info.startTime = Number(startEdit.text);
-          info.endTime = Number(endEdit.text);
+
+          // guard against NAN
+          var _startTime = Number(startEdit.text);
+          var _endTime = Number(endEdit.text);
+
+          if (isNaN(_startTime)) _startTime = 0;
+          if (isNaN(_endTime)) _endTime = 0;
+
+          info.startTime = _startTime;
+          info.endTime = _endTime;;
 
         }
 

+ 20 - 0
Script/AtomicEditor/ui/inspector/NodeInspector.ts

@@ -233,9 +233,29 @@ class NodeInspector extends ScriptWidget {
 
             }
 
+            var breakButton = new Atomic.UIButton();
+            breakButton.text = "Break";
+            breakButton.fontDescription = fd;
+
+            breakButton.onClick = () => {
+
+                var prefabComponent = this.getPrefabComponent(this.node);
+
+                if (prefabComponent) {
+
+                    prefabComponent.breakPrefab();
+
+                    return true;
+
+                }
+
+            }
+
+
             prefabLayout.addChild(name);
             prefabLayout.addChild(saveButton);
             prefabLayout.addChild(undoButton);
+            prefabLayout.addChild(breakButton);
 
             attrsVerticalLayout.addChild(prefabLayout);
 

+ 11 - 0
Script/AtomicEditor/ui/modal/ModalOps.ts

@@ -61,6 +61,17 @@ class ModalOps extends Atomic.ScriptObject {
 
     }
 
+    showCreateMaterial(resourcePath:string) {
+
+      if (this.show()) {
+
+          this.opWindow = new UIResourceOps.CreateMaterial(resourcePath);
+
+      }
+
+    }
+
+
     showResourceDelete(asset:ToolCore.Asset) {
 
       if (this.show()) {

+ 52 - 0
Script/AtomicEditor/ui/modal/UIResourceOps.ts

@@ -206,3 +206,55 @@ export class CreateScene extends ModalWindow {
     nameField: Atomic.UIEditField;
 
 }
+
+export class CreateMaterial extends ModalWindow {
+
+    constructor(resourcePath: string) {
+
+        super();
+
+        this.resourcePath = resourcePath;
+        this.init("New Material", "AtomicEditor/editor/ui/resourcecreatecomponent.tb.txt");
+        this.nameField = <Atomic.UIEditField> this.getWidget("component_name");
+    }
+
+    handleWidgetEvent(ev: Atomic.UIWidgetEvent) {
+
+        if (ev.type == Atomic.UI_EVENT_TYPE_CLICK) {
+
+            var id = ev.target.id;
+
+            if (id == "create") {
+
+                var materialName = this.nameField.text;
+                var outputFile = Atomic.addTrailingSlash(this.resourcePath) + materialName;
+
+                if (outputFile.indexOf(".material") == -1) outputFile += ".material";
+
+                if (ResourceOps.CreateNewMaterial(outputFile, materialName)) {
+
+                    this.hide();
+
+                    this.sendEvent(EditorEvents.EditResource, { path:outputFile});
+
+                }
+
+                return true;
+
+            }
+
+            if (id == "cancel") {
+
+                this.hide();
+
+                return true;
+            }
+
+        }
+
+    }
+
+    resourcePath: string;
+    nameField: Atomic.UIEditField;
+
+}

+ 14 - 0
Script/TypeScript/Atomic.d.ts

@@ -574,6 +574,17 @@ declare module Atomic {
    export var TEXT_ALIGN_CENTER: TEXT_ALIGN;
 
 
+   // enum UI_EDIT_TYPE
+   export type UI_EDIT_TYPE = number;
+   export var UI_EDIT_TYPE_TEXT: UI_EDIT_TYPE;
+   export var UI_EDIT_TYPE_SEARCH: UI_EDIT_TYPE;
+   export var UI_EDIT_TYPE_PASSWORD: UI_EDIT_TYPE;
+   export var UI_EDIT_TYPE_EMAIL: UI_EDIT_TYPE;
+   export var UI_EDIT_TYPE_PHONE: UI_EDIT_TYPE;
+   export var UI_EDIT_TYPE_URL: UI_EDIT_TYPE;
+   export var UI_EDIT_TYPE_NUMBER: UI_EDIT_TYPE;
+
+
    // enum UI_AXIS
    export type UI_AXIS = number;
    export var UI_AXIS_X: UI_AXIS;
@@ -1814,6 +1825,7 @@ declare module Atomic {
       getPrefabGUID(): string;
       savePrefab(): boolean;
       undoPrefab(): void;
+      breakPrefab(): void;
       getPrefabNode(): Node;
 
    }
@@ -7028,12 +7040,14 @@ declare module Atomic {
    export class UIEditField extends UIWidget {
 
       textAlign: TEXT_ALIGN;
+      editType: UI_EDIT_TYPE;
       readOnly: boolean;
       wrapping: boolean;
 
       constructor(createWidget?: boolean);
 
       setTextAlign(align: TEXT_ALIGN): void;
+      setEditType(type: UI_EDIT_TYPE): void;
       setReadOnly(readonly: boolean): void;
       setWrapping(wrap: boolean): void;
       getWrapping(): boolean;

+ 23 - 5
Source/Atomic/Scene/PrefabComponent.cpp

@@ -52,23 +52,37 @@ void PrefabComponent::LoadPrefabNode()
     XMLFile* xmlfile = cache->GetResource<XMLFile>(prefabGUID_);
 
     prefabNode_->LoadXML(xmlfile->GetRoot());
+    prefabNode_->SetTemporary(true);
+
     prefabNode_->SetPosition(Vector3::ZERO);
     prefabNode_->SetRotation(Quaternion::IDENTITY);
     prefabNode_->SetScale(Vector3::ONE);
-    prefabNode_->SetTemporary(true);
 
     PODVector<RigidBody*> bodies;
     prefabNode_->GetComponents<RigidBody>(bodies, true);
     for (unsigned i = 0; i < bodies.Size(); i++)
     {
         RigidBody* body = bodies[i];
-
-        body->SetPosition(body->GetNode()->GetWorldPosition());
-        body->SetRotation(body->GetNode()->GetWorldRotation());
+        body->SetTransform(body->GetNode()->GetWorldPosition(), body->GetNode()->GetWorldRotation());
     }
 
 }
 
+void PrefabComponent::BreakPrefab()
+{
+    if (!node_ || !node_->GetScene())
+        return;
+
+    SharedPtr<PrefabComponent> keepAlive(this);
+
+    if (prefabNode_.NotNull())
+        prefabNode_->SetTemporary(false);
+
+    node_->RemoveComponent(this);
+
+
+}
+
 void PrefabComponent::HandlePrefabChanged(StringHash eventType, VariantMap& eventData)
 {
     using namespace PrefabChanged;
@@ -102,9 +116,13 @@ void PrefabComponent::OnNodeSet(Node* node)
 {
     Component::OnNodeSet(node);
 
+
     if (!node && prefabNode_.NotNull())
     {
-        prefabNode_->Remove();
+        // a prefab node might not be temporary is prefab is broken{
+        if (prefabNode_->IsTemporary())
+            prefabNode_->Remove();
+
         prefabNode_ = NULL;
     }
 }

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

@@ -27,6 +27,7 @@ public:
 
     bool SavePrefab();
     void UndoPrefab();
+    void BreakPrefab();
 
     Node* GetPrefabNode() { return prefabNode_; }
 

+ 12 - 0
Source/Atomic/UI/UIEditField.cpp

@@ -59,6 +59,18 @@ bool UIEditField::GetWrapping()
 
 }
 
+void UIEditField::SetEditType(UI_EDIT_TYPE type)
+{
+    if (!widget_)
+        return;
+
+    // safe cast?
+    TBEditField* w = (TBEditField*) widget_;
+
+    w->SetEditType((tb::EDIT_TYPE) type);
+
+}
+
 void UIEditField::SetTextAlign(TEXT_ALIGN align)
 {
     if (!widget_)

+ 13 - 0
Source/Atomic/UI/UIEditField.h

@@ -3,6 +3,8 @@
 
 #include "UIWidget.h"
 
+#include <TurboBadger/tb_editfield.h>
+
 namespace Atomic
 {
 
@@ -13,6 +15,15 @@ enum TEXT_ALIGN
     TEXT_ALIGN_CENTER	///< Aligned center
 };
 
+enum UI_EDIT_TYPE {
+    UI_EDIT_TYPE_TEXT = tb::EDIT_TYPE_TEXT,
+    UI_EDIT_TYPE_SEARCH = tb::EDIT_TYPE_SEARCH,
+    UI_EDIT_TYPE_PASSWORD = tb::EDIT_TYPE_PASSWORD,
+    UI_EDIT_TYPE_EMAIL = tb::EDIT_TYPE_EMAIL,
+    UI_EDIT_TYPE_PHONE = tb::EDIT_TYPE_PHONE,
+    UI_EDIT_TYPE_URL = tb::EDIT_TYPE_URL,
+    UI_EDIT_TYPE_NUMBER = tb::EDIT_TYPE_NUMBER
+};
 
 class UIEditField : public UIWidget
 {
@@ -25,6 +36,8 @@ public:
 
     void SetTextAlign(TEXT_ALIGN align);
 
+    void SetEditType(UI_EDIT_TYPE type);
+
     void SetReadOnly(bool readonly);
 
     void SetWrapping(bool wrap);