Browse Source

Working on animation controller

Josh Engebretson 10 years ago
parent
commit
2f2efadcef

+ 84 - 11
Script/AtomicEditor/ui/frames/inspector/AttributeInfoEdit.ts

@@ -404,11 +404,11 @@ class FloatAttributeEdit extends AttributeInfoEdit {
 
 
                 if (value == undefined) {
                 if (value == undefined) {
 
 
-                  console.log("WARNING: Undefined value for object: ", this.editType.typeName + "." + attrInfo.name);
-                  widget.text = "???";
+                    console.log("WARNING: Undefined value for object: ", this.editType.typeName + "." + attrInfo.name);
+                    widget.text = "???";
 
 
                 } else {
                 } else {
-                  widget.text = parseFloat(value.toFixed(5)).toString();
+                    widget.text = parseFloat(value.toFixed(5)).toString();
                 }
                 }
 
 
             }
             }
@@ -636,7 +636,7 @@ class ResourceRefAttributeEdit extends AttributeInfoEdit {
 
 
         if (parent) {
         if (parent) {
 
 
-          parent.sendEvent("AttributeEditResourceChanged", { attrInfoEdit: this, resource: resource});
+            parent.sendEvent("AttributeEditResourceChanged", { attrInfoEdit: this, resource: resource });
 
 
         }
         }
 
 
@@ -679,10 +679,17 @@ class ResourceRefAttributeEdit extends AttributeInfoEdit {
                 var text = "";
                 var text = "";
 
 
                 if (resource) {
                 if (resource) {
-                    text = resource.name;
-                    var asset = ToolCore.assetDatabase.getAssetByCachePath(resource.name);
-                    if (asset)
-                        text = asset.name;
+                    if (resource instanceof Atomic.Animation) {
+
+                      text = (<Atomic.Animation>resource).animationName;
+
+                    } else {
+
+                        text = resource.name;
+                        var asset = ToolCore.assetDatabase.getAssetByCachePath(resource.name);
+                        if (asset)
+                            text = asset.name;
+                    }
                 }
                 }
                 this.editField.text = text;
                 this.editField.text = text;
             }
             }
@@ -718,9 +725,20 @@ class ResourceRefAttributeEdit extends AttributeInfoEdit {
 
 
         selectButton.onClick = () => {
         selectButton.onClick = () => {
 
 
-            EditorUI.getModelOps().showResourceSelection("Select " + resourceTypeName + " Resource", importerName, function(asset: ToolCore.Asset) {
+            EditorUI.getModelOps().showResourceSelection("Select " + resourceTypeName + " Resource", importerName, resourceTypeName, function(retObject: any) {
+
+                var resource: Atomic.Resource = null;
+
+                if (retObject instanceof ToolCore.Asset) {
+
+                    resource = (<ToolCore.Asset>retObject).getResource(resourceTypeName);
+
+                } else if (retObject instanceof Atomic.Resource) {
+
+                    resource = <Atomic.Resource>retObject;
+
+                }
 
 
-                var resource = asset.getResource(resourceTypeName);
                 this.editType.onAttributeInfoEdited(this.attrInfo, resource, this.refListIndex);
                 this.editType.onAttributeInfoEdited(this.attrInfo, resource, this.refListIndex);
                 this.onResourceChanged(resource);
                 this.onResourceChanged(resource);
                 this.refresh();
                 this.refresh();
@@ -770,6 +788,7 @@ class ResourceRefListAttributeEdit extends AttributeInfoEdit {
 
 
     layout: Atomic.UILayout;
     layout: Atomic.UILayout;
     refEdits: ResourceRefAttributeEdit[] = [];
     refEdits: ResourceRefAttributeEdit[] = [];
+    sizeEdit: Atomic.UIEditField;
 
 
     initialize(editType: SerializableEditType, attrInfo: Atomic.AttributeInfo): boolean {
     initialize(editType: SerializableEditType, attrInfo: Atomic.AttributeInfo): boolean {
 
 
@@ -803,9 +822,19 @@ class ResourceRefListAttributeEdit extends AttributeInfoEdit {
 
 
         var lp = new Atomic.UILayoutParams();
         var lp = new Atomic.UILayoutParams();
         lp.width = 304;
         lp.width = 304;
-
         layout.layoutParams = lp;
         layout.layoutParams = lp;
 
 
+        var name = this.attrInfo.name + " Size";
+        if (name == "AnimationResources")
+          name = "Animations";
+
+        var sizeEdit = this.sizeEdit = InspectorUtils.createAttrEditField(name, layout);
+
+        var lp = new Atomic.UILayoutParams();
+        lp.width = 198;
+        sizeEdit.layoutParams = lp;
+
+        sizeEdit.subscribeToEvent(sizeEdit, "UIWidgetEditComplete", (ev) => this.handleUIWidgetEditCompleteEvent(ev));
 
 
         this.editWidget = layout;
         this.editWidget = layout;
 
 
@@ -821,6 +850,48 @@ class ResourceRefListAttributeEdit extends AttributeInfoEdit {
 
 
     }
     }
 
 
+    handleUIWidgetEditCompleteEvent(ev) {
+
+        var size = Number(this.sizeEdit.text);
+
+        if (size > 64 || size < 0)
+            return;
+
+        var editType = this.editType;
+
+        var refresh = false;
+
+        for (var i in editType.objects) {
+
+            var object = editType.objects[i];
+            var value = object.getAttribute(this.attrInfo.name);
+
+            if (value.resources.length > size) {
+
+                value.resources.length = size;
+                object.setAttribute(this.attrInfo.name, value);
+                refresh = true;
+
+            } else if (value.resources.length < size) {
+
+                for (var j = value.resources.length; j < size; j++) {
+
+                    value.resources.push(null);
+
+                }
+
+                object.setAttribute(this.attrInfo.name, value);
+                refresh = true;
+
+            }
+
+        }
+
+        if (refresh)
+            this.refresh();
+
+    }
+
     refresh() {
     refresh() {
 
 
         var editType = this.editType;
         var editType = this.editType;
@@ -848,6 +919,8 @@ class ResourceRefListAttributeEdit extends AttributeInfoEdit {
 
 
         }
         }
 
 
+        this.sizeEdit.text = maxLength.toString();
+
         if (maxLength == -1) {
         if (maxLength == -1) {
             this.visibility = Atomic.UI_WIDGET_VISIBILITY_GONE;
             this.visibility = Atomic.UI_WIDGET_VISIBILITY_GONE;
             return;
             return;

+ 4 - 1
Script/AtomicEditor/ui/frames/inspector/InspectorUtils.ts

@@ -71,8 +71,11 @@ class InspectorUtils {
   static createAttrEditField(name:string, parent:Atomic.UIWidget):Atomic.UIEditField {
   static createAttrEditField(name:string, parent:Atomic.UIWidget):Atomic.UIEditField {
 
 
     var attrLayout = new Atomic.UILayout();
     var attrLayout = new Atomic.UILayout();
-    attrLayout.layoutDistribution = Atomic.UI_LAYOUT_DISTRIBUTION_GRAVITY;
 
 
+    attrLayout.layoutSize = Atomic.UI_LAYOUT_SIZE_AVAILABLE;
+    attrLayout.gravity = Atomic.UI_GRAVITY_LEFT_RIGHT;
+    attrLayout.layoutDistribution = Atomic.UI_LAYOUT_DISTRIBUTION_GRAVITY;
+    
     var _name = InspectorUtils.createAttrName(name);
     var _name = InspectorUtils.createAttrName(name);
     attrLayout.addChild(_name);
     attrLayout.addChild(_name);
 
 

+ 1 - 1
Script/AtomicEditor/ui/frames/inspector/MaterialInspector.ts

@@ -237,7 +237,7 @@ class MaterialInspector extends ScriptWidget {
 
 
         var inspector = this;
         var inspector = this;
 
 
-        EditorUI.getModelOps().showResourceSelection("Select Texture", "TextureImporter", function(asset: ToolCore.Asset, args: any) {
+        EditorUI.getModelOps().showResourceSelection("Select Texture", "TextureImporter", "Texture2D", function(asset: ToolCore.Asset, args: any) {
 
 
             var texture = <Atomic.Texture2D> Atomic.cache.getResource("Texture2D", asset.path);
             var texture = <Atomic.Texture2D> Atomic.cache.getResource("Texture2D", asset.path);
 
 

+ 1 - 1
Script/AtomicEditor/ui/frames/inspector/TextureSelector.ts

@@ -35,7 +35,7 @@ class TextureSelector extends Atomic.UIWindow {
 
 
         var db = ToolCore.getAssetDatabase();
         var db = ToolCore.getAssetDatabase();
 
 
-        var textures = db.getAssetsByImporterType("TextureImporter");
+        var textures = db.getAssetsByImporterType("TextureImporter", "Texture2D");
 
 
         for (var i in textures) {
         for (var i in textures) {
 
 

+ 2 - 2
Script/AtomicEditor/ui/modal/ModalOps.ts

@@ -120,11 +120,11 @@ class ModalOps extends Atomic.ScriptObject {
     }
     }
 
 
 
 
-    showResourceSelection(windowText: string, importerType: string, callback: (asset: ToolCore.Asset, args: any) => void, args: any = undefined) {
+    showResourceSelection(windowText: string, importerType: string, resourceType:string, callback: (retObject: any, args: any) => void, args: any = undefined) {
 
 
         if (this.show()) {
         if (this.show()) {
 
 
-            this.opWindow = new ResourceSelection(windowText, importerType, callback, args);
+            this.opWindow = new ResourceSelection(windowText, importerType, resourceType, callback, args);
 
 
         }
         }
 
 

+ 54 - 15
Script/AtomicEditor/ui/modal/ResourceSelection.ts

@@ -12,33 +12,56 @@ import ModalWindow = require("./ModalWindow");
 class ResourceSelection extends ModalWindow {
 class ResourceSelection extends ModalWindow {
 
 
     folderList: Atomic.UIListView;
     folderList: Atomic.UIListView;
-    callback: (asset: ToolCore.Asset, args:any) => void;
-    args:any;
+    callback: (returnObject: any, args: any) => void;
+    args: any;
+    resourceType: string;
 
 
-    populate(importerType: string) {
+    populate(importerType: string, resourceType: string) {
 
 
         var db = ToolCore.assetDatabase;
         var db = ToolCore.assetDatabase;
-        var assets = db.getAssetsByImporterType(importerType);
+        var assets = db.getAssetsByImporterType(importerType, resourceType);
 
 
         for (var i in assets) {
         for (var i in assets) {
 
 
             var asset = assets[i];
             var asset = assets[i];
 
 
             if (importerType == "JavascriptImporter") {
             if (importerType == "JavascriptImporter") {
-                if (!(<ToolCore.JavascriptImporter> asset.importer).isComponentFile())
+                if (!(<ToolCore.JavascriptImporter>asset.importer).isComponentFile())
                     continue;
                     continue;
             }
             }
 
 
-            this.folderList.addRootItem(asset.relativePath, "", asset.guid);
+            // TODO: Generalize this for other cache assets
+            if (resourceType == "Animation") {
+
+                var modelImporter = <ToolCore.ModelImporter>(asset.importer);
+                var animations = modelImporter.getAnimations();
+
+                if (animations.length) {
+
+                    for (var i in animations) {
+
+                        this.folderList.addRootItem(animations[i].animationName + " : " + asset.name, "", animations[i].name);
+
+                    }
+
+
+                }
+
+            } else {
+
+                this.folderList.addRootItem(asset.relativePath, "", asset.guid);
+
+            }
 
 
         }
         }
 
 
     }
     }
 
 
-    constructor(windowText: string, importerType: string, callback: (asset: ToolCore.Asset, args:any) => void, args:any) {
+    constructor(windowText: string, importerType: string, resourceType: string, callback: (asset: ToolCore.Asset, args: any) => void, args: any) {
 
 
         super();
         super();
 
 
+        this.resourceType = resourceType;
         this.callback = callback;
         this.callback = callback;
         this.args = args;
         this.args = args;
 
 
@@ -52,7 +75,7 @@ class ResourceSelection extends ModalWindow {
 
 
         foldercontainer.addChild(folderList);
         foldercontainer.addChild(folderList);
 
 
-        this.populate(importerType);
+        this.populate(importerType, resourceType);
 
 
         this.text = windowText;
         this.text = windowText;
         this.setSize(800, 600);
         this.setSize(800, 600);
@@ -62,9 +85,9 @@ class ResourceSelection extends ModalWindow {
 
 
     handleWidgetEvent(ev: Atomic.UIWidgetEvent) {
     handleWidgetEvent(ev: Atomic.UIWidgetEvent) {
 
 
-        if(ev.count >= 2) {
+        if (ev.count >= 2) {
             var id = ev.target.id;
             var id = ev.target.id;
-            if(id == this.folderList.rootList.id) {
+            if (id == this.folderList.rootList.id) {
                 this.selectFile();
                 this.selectFile();
             }
             }
         }
         }
@@ -89,12 +112,28 @@ class ResourceSelection extends ModalWindow {
 
 
     }
     }
 
 
-    selectFile():boolean {
+    selectFile(): boolean {
+
         var id = this.folderList.selectedItemID;
         var id = this.folderList.selectedItemID;
-        if(id.length) {
-            this.callback(ToolCore.assetDatabase.getAssetByGUID(id), this.args);
-            this.hide();
-            return true;
+
+        if (this.resourceType == "Animation") {
+
+          if (id.length) {
+              this.callback(Atomic.cache.getResource("Animation", id), this.args);
+              this.hide();
+              return true;
+          }
+
+          this.hide();
+          return true;
+
+        } else {
+
+            if (id.length) {
+                this.callback(ToolCore.assetDatabase.getAssetByGUID(id), this.args);
+                this.hide();
+                return true;
+            }
         }
         }
         return false;
         return false;
     }
     }

+ 4 - 1
Script/Packages/ToolCore/ToolCore.json

@@ -15,9 +15,12 @@
 						 	 "ProjectBuildSettings", "MacBuildSettings", "WindowsBuildSettings", "WebBuildSettings", "AndroidBuildSettings", "IOSBuildSettings"],
 						 	 "ProjectBuildSettings", "MacBuildSettings", "WindowsBuildSettings", "WebBuildSettings", "AndroidBuildSettings", "IOSBuildSettings"],
 	"typescript_decl" : {
 	"typescript_decl" : {
 
 
+		"ModelImporter" : [
+			"getAnimations():Atomic.Animation[];"	
+		],
 		"AssetDatabase" : [
 		"AssetDatabase" : [
 			"getFolderAssets(folder:string):ToolCore.Asset[];",
 			"getFolderAssets(folder:string):ToolCore.Asset[];",
-			"getAssetsByImporterType(type:string):ToolCore.Asset[];"
+			"getAssetsByImporterType(importerType:string, resourceType:string):ToolCore.Asset[];"
 		]
 		]
 	}
 	}
 
 

+ 82 - 26
Source/Atomic/Atomic3D/AnimationController.cpp

@@ -52,7 +52,10 @@ static const unsigned MAX_NODE_ANIMATION_STATES = 256;
 extern const char* LOGIC_CATEGORY;
 extern const char* LOGIC_CATEGORY;
 
 
 AnimationController::AnimationController(Context* context) :
 AnimationController::AnimationController(Context* context) :
-    Component(context)
+    Component(context),
+    animationResourcesAttr_(Animation::GetTypeStatic()),
+    autoPlay_(true),
+    autoPlayed_(false)
 {
 {
 }
 }
 
 
@@ -71,6 +74,12 @@ void AnimationController::RegisterObject(Context* context)
         Variant::emptyBuffer, AM_NET | AM_LATESTDATA | AM_NOEDIT);
         Variant::emptyBuffer, AM_NET | AM_LATESTDATA | AM_NOEDIT);
     MIXED_ACCESSOR_ATTRIBUTE("Node Animation States", GetNodeAnimationStatesAttr, SetNodeAnimationStatesAttr, VariantVector,
     MIXED_ACCESSOR_ATTRIBUTE("Node Animation States", GetNodeAnimationStatesAttr, SetNodeAnimationStatesAttr, VariantVector,
         Variant::emptyVariantVector, AM_FILE | AM_NOEDIT);
         Variant::emptyVariantVector, AM_FILE | AM_NOEDIT);
+
+    // ATOMIC BEGIN
+    MIXED_ACCESSOR_ATTRIBUTE("Animation", GetAnimationAttr, SetAnimationAttr, ResourceRef, ResourceRef(Animation::GetTypeStatic()), AM_DEFAULT);
+    ATTRIBUTE("Autoplay", bool, autoPlay_, true, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("AnimationResources", GetAnimationResourcesAttr, SetAnimationResourcesAttr, ResourceRefList, ResourceRefList(Animation::GetTypeStatic()), AM_DEFAULT);
+    // ATOMIC END
 }
 }
 
 
 void AnimationController::OnSetEnabled()
 void AnimationController::OnSetEnabled()
@@ -87,6 +96,12 @@ void AnimationController::OnSetEnabled()
 
 
 void AnimationController::Update(float timeStep)
 void AnimationController::Update(float timeStep)
 {
 {
+    if (autoPlay_ && !autoPlayed_ && animation_.NotNull())
+    {
+        autoPlayed_ = true;
+        Play(animation_->GetAnimationName(), 0, true);
+    }
+
     // Loop through animations
     // Loop through animations
     for (Vector<AnimationControl>::Iterator i = animations_.Begin(); i != animations_.End();)
     for (Vector<AnimationControl>::Iterator i = animations_.Begin(); i != animations_.End();)
     {
     {
@@ -166,12 +181,19 @@ bool AnimationController::Play(const String& name, unsigned char layer, bool loo
         Animation* newAnimation = 0;
         Animation* newAnimation = 0;
 
 
         // Check if we're using attached animation resource
         // Check if we're using attached animation resource
-        for (unsigned i = 0; i < animationsResources_.Size(); i++)
+        if (animation_.NotNull() && animation_->GetAnimationName() == name)
         {
         {
-            if (name == animationsResources_[i]->GetAnimationName())
+            newAnimation = animation_;
+        }
+        else
+        {
+            for (unsigned i = 0; i < animationResources_.Size(); i++)
             {
             {
-                newAnimation = GetSubsystem<ResourceCache>()->GetResource<Animation>(animationsResources_[i]->GetName());
-                break;
+                if (name == animationResources_[i]->GetAnimationName())
+                {
+                    newAnimation = animationResources_[i];
+                    break;
+                }
             }
             }
         }
         }
 
 
@@ -806,7 +828,9 @@ VariantVector AnimationController::GetNodeAnimationStatesAttr() const
 void AnimationController::OnSceneSet(Scene* scene)
 void AnimationController::OnSceneSet(Scene* scene)
 {
 {
     if (scene && IsEnabledEffective())
     if (scene && IsEnabledEffective())
+    {
         SubscribeToEvent(scene, E_SCENEPOSTUPDATE, HANDLER(AnimationController, HandleScenePostUpdate));
         SubscribeToEvent(scene, E_SCENEPOSTUPDATE, HANDLER(AnimationController, HandleScenePostUpdate));
+    }
     else if (!scene)
     else if (!scene)
         UnsubscribeFromEvent(E_SCENEPOSTUPDATE);
         UnsubscribeFromEvent(E_SCENEPOSTUPDATE);
 }
 }
@@ -856,12 +880,19 @@ void AnimationController::FindAnimation(const String& name, unsigned& index, Ani
     StringHash nameHash(name);
     StringHash nameHash(name);
 
 
     // Check if we're using attached animation resource
     // Check if we're using attached animation resource
-    for (unsigned i = 0; i < animationsResources_.Size(); i++)
+    if (animation_.NotNull() && animation_->GetAnimationName() == name)
+    {
+        nameHash = animation_->GetName();
+    }
+    else
     {
     {
-        if (name == animationsResources_[i]->GetAnimationName())
+        for (unsigned i = 0; i < animationResources_.Size(); i++)
         {
         {
-            nameHash = animationsResources_[i]->GetName();
-            break;
+            if (name == animationResources_[i]->GetAnimationName())
+            {
+                nameHash = animationResources_[i]->GetName();
+                break;
+            }
         }
         }
     }
     }
 
 
@@ -892,6 +923,19 @@ void AnimationController::HandleScenePostUpdate(StringHash eventType, VariantMap
     Update(eventData[P_TIMESTEP].GetFloat());
     Update(eventData[P_TIMESTEP].GetFloat());
 }
 }
 
 
+// ATOMIC BEGIN
+
+void AnimationController::SetAnimationAttr(const ResourceRef& value)
+{
+    ResourceCache* cache = GetSubsystem<ResourceCache>();
+    animation_ = cache->GetResource<Animation>(value.name_);
+}
+
+ResourceRef AnimationController::GetAnimationAttr() const
+{
+    return GetResourceRef(animation_, Animation::GetTypeStatic());
+}
+
 void AnimationController::AddAnimationResource(Animation* animation)
 void AnimationController::AddAnimationResource(Animation* animation)
 {
 {
     if (!animation)
     if (!animation)
@@ -899,8 +943,8 @@ void AnimationController::AddAnimationResource(Animation* animation)
 
 
     SharedPtr<Animation> anim(animation);
     SharedPtr<Animation> anim(animation);
 
 
-    if (!animationsResources_.Contains(anim))
-        animationsResources_.Push(anim);
+    if (!animationResources_.Contains(anim))
+        animationResources_.Push(anim);
 }
 }
 
 
 void AnimationController::RemoveAnimationResource(Animation* animation)
 void AnimationController::RemoveAnimationResource(Animation* animation)
@@ -908,34 +952,46 @@ void AnimationController::RemoveAnimationResource(Animation* animation)
     if (!animation)
     if (!animation)
         return;
         return;
 
 
-    animationsResources_.Remove(SharedPtr<Animation>(animation));
+    animationResources_.Remove(SharedPtr<Animation>(animation));
 
 
 }
 }
 
 
 void AnimationController::ClearAnimationResources()
 void AnimationController::ClearAnimationResources()
 {
 {
-    animationsResources_.Clear();
+    animationResources_.Clear();
 }
 }
 
 
-void AnimationController::ApplyAttributes()
+void AnimationController::SetAnimationResourcesAttr(const ResourceRefList& value)
 {
 {
+    animationResources_.Clear();
 
 
-    // This currently requires that the AnimationController is after the AnimatedModel
-    // component on the node, look into removing the requirement
-
-    AnimatedModel* animatedModel = GetComponent<AnimatedModel>();
-
-    if (!animatedModel)
-        return;
-
-    Model* model = animatedModel->GetModel();
+    ResourceCache* cache = GetSubsystem<ResourceCache>();
+    for (unsigned i = 0; i < value.names_.Size(); ++i)
+    {
+        Animation* animation = cache->GetResource<Animation>(value.names_[i]);
+        if (!animation)
+        {
+            //LOGERRORF("AnimationController::SetAnimationResourcesAttr - Unable to load animation: %s", value.names_[i].CString());
+            animationResources_.Push(SharedPtr<Animation>(0));
+        }
+        else
+        {
+            animationResources_.Push(SharedPtr<Animation>(animation));
+        }
 
 
-    if (!model)
-        return;
+    }
 
 
-    animationsResources_ = model->GetAnimationResources();
+}
 
 
+const ResourceRefList& AnimationController::GetAnimationResourcesAttr() const
+{
+    animationResourcesAttr_.names_.Resize(animationResources_.Size());
+    for (unsigned i = 0; i < animationResources_.Size(); ++i)
+        animationResourcesAttr_.names_[i] = GetResourceName(animationResources_[i]);
 
 
+    return animationResourcesAttr_;
 }
 }
 
 
+// ATOMIC END
+
 }
 }

+ 26 - 7
Source/Atomic/Atomic3D/AnimationController.h

@@ -180,20 +180,29 @@ public:
     /// Return node animation states attribute.
     /// Return node animation states attribute.
     VariantVector GetNodeAnimationStatesAttr() const;
     VariantVector GetNodeAnimationStatesAttr() const;
 
 
-    // Animation Resources
+    // ATOMIC BEGIN
 
 
     void AddAnimationResource(Animation* animation);
     void AddAnimationResource(Animation* animation);
     void RemoveAnimationResource(Animation* animation);
     void RemoveAnimationResource(Animation* animation);
     void ClearAnimationResources();
     void ClearAnimationResources();
+    const Vector<SharedPtr<Animation>>& GetAnimationResources() { return animationResources_; }
+
+    /// Set animation resources attribute.
+    void SetAnimationResourcesAttr(const ResourceRefList& value);
+    /// Return animation resources attribute.
+    const ResourceRefList& GetAnimationResourcesAttr() const;
+
+    /// Set animation attribute.
+    void SetAnimationAttr(const ResourceRef& value);
+    /// Return animation attribute.
+    ResourceRef GetAnimationAttr() const;
+
+    // ATOMIC END
 
 
 protected:
 protected:
     /// Handle scene being assigned.
     /// Handle scene being assigned.
     virtual void OnSceneSet(Scene* scene);
     virtual void OnSceneSet(Scene* scene);
 
 
-    // ATOMIC BEGIN
-    void ApplyAttributes();
-    // ATOMIC END
-
 private:
 private:
     /// Add an animation state either to AnimatedModel or as a node animation.
     /// Add an animation state either to AnimatedModel or as a node animation.
     AnimationState* AddAnimationState(Animation* animation);
     AnimationState* AddAnimationState(Animation* animation);
@@ -211,8 +220,18 @@ private:
     /// Attribute buffer for network replication.
     /// Attribute buffer for network replication.
     mutable VectorBuffer attrBuffer_;
     mutable VectorBuffer attrBuffer_;
 
 
-    /// animation resources
-    Vector<SharedPtr<Animation> > animationsResources_;
+    // ATOMIC BEGIN
+
+    SharedPtr<Animation> animation_;
+    bool autoPlay_;
+    bool autoPlayed_;
+
+    /// animation resources    
+    Vector<SharedPtr<Animation>> animationResources_;
+    mutable ResourceRefList animationResourcesAttr_;
+
+    // ATOMIC END
+
 };
 };
 
 
 }
 }

+ 0 - 47
Source/Atomic/Atomic3D/Model.cpp

@@ -302,16 +302,6 @@ bool Model::BeginLoad(Deserializer& source)
     // MODEL_VERSION
     // MODEL_VERSION
     unsigned version = source.ReadUInt();
     unsigned version = source.ReadUInt();
 
 
-    ResourceRefList animList = source.ReadResourceRefList();
-
-    animationsResources_.Clear();
-
-    ResourceCache* cache = GetSubsystem<ResourceCache>();
-    for (unsigned i = 0; i < animList.names_.Size(); ++i)
-    {
-        AddAnimationResource(cache->GetResource<Animation>(animList.names_[i]));
-    }
-
     SetMemoryUse(memoryUse);
     SetMemoryUse(memoryUse);
     return true;
     return true;
 }
 }
@@ -455,14 +445,6 @@ bool Model::Save(Serializer& dest) const
 
 
     dest.WriteUInt(MODEL_VERSION);
     dest.WriteUInt(MODEL_VERSION);
 
 
-    // animation resources
-
-    ResourceRefList animList(Animation::GetTypeStatic());
-    animList.names_.Resize(animationsResources_.Size());
-    for (unsigned i = 0; i < animationsResources_.Size(); ++i)
-        animList.names_[i] = GetResourceName(animationsResources_[i]);
-    dest.WriteResourceRefList(animList);
-
     // ATOMIC END
     // ATOMIC END
 
 
 
 
@@ -767,33 +749,4 @@ unsigned Model::GetMorphRangeCount(unsigned bufferIndex) const
     return bufferIndex < vertexBuffers_.Size() ? morphRangeCounts_[bufferIndex] : 0;
     return bufferIndex < vertexBuffers_.Size() ? morphRangeCounts_[bufferIndex] : 0;
 }
 }
 
 
-// ATOMIC BEGIN
-
-void Model::AddAnimationResource(Animation* animation)
-{
-    if (!animation)
-        return;
-
-    SharedPtr<Animation> anim(animation);
-
-    if (!animationsResources_.Contains(anim))
-        animationsResources_.Push(anim);
-}
-
-void Model::RemoveAnimationResource(Animation* animation)
-{
-    if (!animation)
-        return;
-
-    animationsResources_.Remove(SharedPtr<Animation>(animation));
-
-}
-
-void Model::ClearAnimationResources()
-{
-    animationsResources_.Clear();
-}
-
-// ATOMIC END
-
 }
 }

+ 0 - 16
Source/Atomic/Atomic3D/Model.h

@@ -209,16 +209,6 @@ public:
     /// Return vertex buffer morph range vertex count.
     /// Return vertex buffer morph range vertex count.
     unsigned GetMorphRangeCount(unsigned bufferIndex) const;
     unsigned GetMorphRangeCount(unsigned bufferIndex) const;
 
 
-    // ATOMIC BEGIN
-
-    void AddAnimationResource(Animation* animation);
-    void RemoveAnimationResource(Animation* animation);
-    void ClearAnimationResources();
-    unsigned GetAnimationCount() const { return animationsResources_.Size(); }
-    const Vector<SharedPtr<Animation>>& GetAnimationResources() { return animationsResources_; }
-
-    // ATOMIC END
-
 private:
 private:
     /// Bounding box.
     /// Bounding box.
     BoundingBox boundingBox_;
     BoundingBox boundingBox_;
@@ -247,12 +237,6 @@ private:
     /// Geometry definitions for asynchronous loading.
     /// Geometry definitions for asynchronous loading.
     Vector<PODVector<GeometryDesc> > loadGeometries_;
     Vector<PODVector<GeometryDesc> > loadGeometries_;
 
 
-    // ATOMIC BEGIN
-
-    /// animation resources
-    Vector<SharedPtr<Animation> > animationsResources_;
-
-    // ATOMIC END
 };
 };
 
 
 }
 }

+ 3 - 1
Source/ToolCore/Assets/AssetDatabase.cpp

@@ -382,7 +382,7 @@ void AssetDatabase::GetFolderAssets(String folder, PODVector<Asset*>& assets) co
 
 
 }
 }
 
 
-void AssetDatabase::GetAssetsByImporterType(StringHash type, PODVector<Asset*>& assets) const
+void AssetDatabase::GetAssetsByImporterType(StringHash type, const String &resourceType, PODVector<Asset*>& assets) const
 {
 {
     assets.Clear();
     assets.Clear();
 
 
@@ -538,6 +538,8 @@ String AssetDatabase::GetResourceImporterName(const String& resourceTypeName)
         resourceTypeToImporterType_["JSONFile"] = "JSONImporter";
         resourceTypeToImporterType_["JSONFile"] = "JSONImporter";
         resourceTypeToImporterType_["ParticleEffect2D"] = "PEXImporter";
         resourceTypeToImporterType_["ParticleEffect2D"] = "PEXImporter";
 
 
+        resourceTypeToImporterType_["Animation"] = "ModelImporter";
+
 
 
 #ifdef ATOMIC_DOTNET
 #ifdef ATOMIC_DOTNET
         resourceTypeToImporterType_["CSComponentAssembly"] = "NETAssemblyImporter";
         resourceTypeToImporterType_["CSComponentAssembly"] = "NETAssemblyImporter";

+ 1 - 1
Source/ToolCore/Assets/AssetDatabase.h

@@ -44,7 +44,7 @@ public:
 
 
     String GetResourceImporterName(const String& resourceTypeName);
     String GetResourceImporterName(const String& resourceTypeName);
 
 
-    void GetAssetsByImporterType(StringHash type, PODVector<Asset*>& assets) const;
+    void GetAssetsByImporterType(StringHash type, const String& resourceType, PODVector<Asset*>& assets) const;
 
 
     void GetDirtyAssets(PODVector<Asset*>& assets);
     void GetDirtyAssets(PODVector<Asset*>& assets);
 
 

+ 41 - 36
Source/ToolCore/Assets/ModelImporter.cpp

@@ -13,6 +13,7 @@
 
 
 #include <Atomic/Atomic3D/AnimatedModel.h>
 #include <Atomic/Atomic3D/AnimatedModel.h>
 #include <Atomic/Atomic3D/Animation.h>
 #include <Atomic/Atomic3D/Animation.h>
+#include <Atomic/Atomic3D/AnimationController.h>
 #include <Atomic/Atomic3D/StaticModel.h>
 #include <Atomic/Atomic3D/StaticModel.h>
 #include <Atomic/Atomic3D/Model.h>
 #include <Atomic/Atomic3D/Model.h>
 
 
@@ -104,18 +105,12 @@ bool ModelImporter::ImportAnimation(const String& filename, const String& name,
             ResourceCache* cache = GetSubsystem<ResourceCache>();
             ResourceCache* cache = GetSubsystem<ResourceCache>();
 
 
             AnimatedModel* animatedModel = importNode_->GetComponent<AnimatedModel>();
             AnimatedModel* animatedModel = importNode_->GetComponent<AnimatedModel>();
-
-            if (animatedModel)
+            AnimationController* controller = importNode_->GetComponent<AnimationController>();
+            if (animatedModel && controller)
             {
             {
-                Model* model = animatedModel->GetModel();
-
-                if (model)
-                {
-                    SharedPtr<Animation> animation = cache->GetTempResource<Animation>(fileName + extension);
-                    if (animation)
-                        model->AddAnimationResource(animation);
-                }
-
+                SharedPtr<Animation> animation = cache->GetTempResource<Animation>(fileName + extension);
+                if (animation)
+                    controller->AddAnimationResource(animation);
             }
             }
 
 
             LOGINFOF("Import Info: %s : %s", info.name_.CString(), fileName.CString());
             LOGINFOF("Import Info: %s : %s", info.name_.CString(), fileName.CString());
@@ -132,8 +127,8 @@ bool ModelImporter::ImportAnimations()
 {
 {
     if (!animationInfo_.Size())
     if (!animationInfo_.Size())
     {
     {
-       if (!ImportAnimation(asset_->GetPath(), "RootAnim"))
-           return false;
+        if (!ImportAnimation(asset_->GetPath(), "RootAnim"))
+            return false;
     }
     }
 
 
     // embedded animations
     // embedded animations
@@ -174,8 +169,8 @@ bool ModelImporter::ImportAnimations()
 
 
                 if (!importer->animationInfo_.Size())
                 if (!importer->animationInfo_.Size())
                 {
                 {
-                   if (!ImportAnimation(asset->GetPath(), animationName))
-                       return false;
+                    if (!ImportAnimation(asset->GetPath(), animationName))
+                        return false;
                 }
                 }
                 else
                 else
                 {
                 {
@@ -247,28 +242,9 @@ bool ModelImporter::Import()
                 ImportAnimations();
                 ImportAnimations();
             }
             }
 
 
-            AnimatedModel* animatedModel = importNode_->GetComponent<AnimatedModel>();
-            if (animatedModel)
-            {
-                Model* model = animatedModel->GetModel();
-                if (model && model->GetAnimationCount())
-                {
-                    // resave with animation info
-
-                    File mdlFile(context_);
-                    if (!mdlFile.Open(asset_->GetCachePath() + ".mdl", FILE_WRITE))
-                    {
-                        ErrorExit("Could not open output file " + asset_->GetCachePath() + ".mdl");
-                        return false;
-                    }
-
-                    model->Save(mdlFile);
-                }
-            }
         }
         }
     }
     }
 
 
-
     File outFile(context_);
     File outFile(context_);
 
 
     if (!outFile.Open(asset_->GetCachePath(), FILE_WRITE))
     if (!outFile.Open(asset_->GetCachePath(), FILE_WRITE))
@@ -304,6 +280,35 @@ void ModelImporter::SetAnimationCount(unsigned count)
 
 
 }
 }
 
 
+void ModelImporter::GetAnimations(PODVector<Animation*>& animations)
+{
+    animations.Clear();
+
+    SharedPtr<File> file(new File(context_, asset_->GetCachePath()));
+    SharedPtr<XMLFile> xml(new XMLFile(context_));
+
+    if (!xml->Load(*file))
+        return;
+
+    SharedPtr<Node> node(new Node(context_));
+    node->LoadXML(xml->GetRoot());
+
+    AnimationController* controller = node->GetComponent<AnimationController>();
+
+    if (!controller)
+        return;
+
+    const Vector<SharedPtr<Animation>>& animresources = controller->GetAnimationResources();
+
+    for (unsigned i = 0; i < animresources.Size(); i++)
+    {
+        if (animresources[i].NotNull())
+        {
+            animations.Push(animresources[i]);
+        }
+    }
+}
+
 bool ModelImporter::LoadSettingsInternal(JSONValue& jsonRoot)
 bool ModelImporter::LoadSettingsInternal(JSONValue& jsonRoot)
 {
 {
     if (!AssetImporter::LoadSettingsInternal(jsonRoot))
     if (!AssetImporter::LoadSettingsInternal(jsonRoot))
@@ -361,9 +366,9 @@ bool ModelImporter::SaveSettingsInternal(JSONValue& jsonRoot)
         animInfo.Push(jinfo);
         animInfo.Push(jinfo);
     }
     }
 
 
-   save.Set("animInfo", animInfo);
+    save.Set("animInfo", animInfo);
 
 
-   jsonRoot.Set("ModelImporter", save);
+    jsonRoot.Set("ModelImporter", save);
 
 
     return true;
     return true;
 }
 }

+ 3 - 0
Source/ToolCore/Assets/ModelImporter.h

@@ -12,6 +12,7 @@
 namespace Atomic
 namespace Atomic
 {
 {
     class Node;
     class Node;
+    class Animation;
 }
 }
 
 
 using namespace Atomic;
 using namespace Atomic;
@@ -71,6 +72,8 @@ public:
 
 
     Resource* GetResource(const String& typeName = String::EMPTY);
     Resource* GetResource(const String& typeName = String::EMPTY);
 
 
+    void GetAnimations(PODVector<Atomic::Animation *>& animations);
+
     AnimationImportInfo* GetAnimationInfo(unsigned index) { return animationInfo_[index]; }
     AnimationImportInfo* GetAnimationInfo(unsigned index) { return animationInfo_[index]; }
 
 
     /// Instantiate a node from the asset
     /// Instantiate a node from the asset

+ 29 - 3
Source/ToolCoreJS/ToolCoreJS.cpp

@@ -5,6 +5,8 @@
 // license information: https://github.com/AtomicGameEngine/AtomicGameEngine
 // license information: https://github.com/AtomicGameEngine/AtomicGameEngine
 //
 //
 
 
+#include <Atomic/Atomic3D/Animation.h>
+
 #include <AtomicJS/Javascript/JSVM.h>
 #include <AtomicJS/Javascript/JSVM.h>
 #include <ToolCore/ToolEnvironment.h>
 #include <ToolCore/ToolEnvironment.h>
 #include <ToolCore/ToolSystem.h>
 #include <ToolCore/ToolSystem.h>
@@ -13,6 +15,8 @@
 #include <ToolCore/License/LicenseSystem.h>
 #include <ToolCore/License/LicenseSystem.h>
 #include <ToolCore/Build/BuildSystem.h>
 #include <ToolCore/Build/BuildSystem.h>
 
 
+#include <ToolCore/Assets/ModelImporter.h>
+
 using namespace Atomic;
 using namespace Atomic;
 
 
 namespace Atomic
 namespace Atomic
@@ -87,6 +91,7 @@ static int AssetDatabase_GetAssetsByImporterType(duk_context* ctx)
     Project* project = ts->GetProject();
     Project* project = ts->GetProject();
 
 
     StringHash type = duk_require_string(ctx, 0);
     StringHash type = duk_require_string(ctx, 0);
+    String resourceType = duk_require_string(ctx, 1);
 
 
     duk_push_array(ctx);
     duk_push_array(ctx);
 
 
@@ -94,7 +99,7 @@ static int AssetDatabase_GetAssetsByImporterType(duk_context* ctx)
         return 1;
         return 1;
 
 
     PODVector<Asset*> assets;
     PODVector<Asset*> assets;
-    db->GetAssetsByImporterType(type, assets);
+    db->GetAssetsByImporterType(type, resourceType, assets);
 
 
     for(unsigned i = 0; i < assets.Size(); i++)
     for(unsigned i = 0; i < assets.Size(); i++)
     {
     {
@@ -105,6 +110,24 @@ static int AssetDatabase_GetAssetsByImporterType(duk_context* ctx)
     return 1;
     return 1;
 }
 }
 
 
+static int ModelImporter_GetAnimations(duk_context* ctx)
+{
+    duk_push_this(ctx);
+    ModelImporter* importer = js_to_class_instance<ModelImporter>(ctx, -1, 0);
+
+    PODVector<Animation*> animations;
+    importer->GetAnimations(animations);
+
+    duk_push_array(ctx);
+
+    for(unsigned i = 0; i < animations.Size(); i++)
+    {
+        js_push_class_object_instance(ctx, animations[i], 0);
+        duk_put_prop_index(ctx, -2, i);
+    }
+
+    return 1;
+}
 
 
 void jsapi_init_toolcore(JSVM* vm)
 void jsapi_init_toolcore(JSVM* vm)
 {
 {
@@ -146,11 +169,14 @@ void jsapi_init_toolcore(JSVM* vm)
     js_class_get_prototype(ctx, "ToolCore", "AssetDatabase");
     js_class_get_prototype(ctx, "ToolCore", "AssetDatabase");
     duk_push_c_function(ctx, AssetDatabase_GetFolderAssets, 1);
     duk_push_c_function(ctx, AssetDatabase_GetFolderAssets, 1);
     duk_put_prop_string(ctx, -2, "getFolderAssets");
     duk_put_prop_string(ctx, -2, "getFolderAssets");
-    duk_push_c_function(ctx, AssetDatabase_GetAssetsByImporterType, 1);
+    duk_push_c_function(ctx, AssetDatabase_GetAssetsByImporterType, 2);
     duk_put_prop_string(ctx, -2, "getAssetsByImporterType");
     duk_put_prop_string(ctx, -2, "getAssetsByImporterType");
     duk_pop(ctx);
     duk_pop(ctx);
 
 
-
+    js_class_get_prototype(ctx, "ToolCore", "ModelImporter");
+    duk_push_c_function(ctx, ModelImporter_GetAnimations, 0);
+    duk_put_prop_string(ctx, -2, "getAnimations");
+    duk_pop(ctx);
 }
 }
 
 
 }
 }