Browse Source

Merge pull request #150 from AtomicGameEngine/JME-ATOMIC-UPDATEPLATFORMER

2D Editor improvements, LightGroup/Light2D optimizations and editor support, creating prefabs from script
JoshEngebretson 10 years ago
parent
commit
8cb16f3742

+ 8 - 3
Script/AtomicEditor/ui/frames/HierarchyFrame.ts

@@ -58,6 +58,11 @@ class HierarchyFrame extends Atomic.UIWidget {
 
         this.subscribeToEvent("TemporaryChanged", (ev: Atomic.TemporaryChangedEvent) => {
 
+            // this can happen on a temporary status change on a non-scripted class instance
+            if (!ev.serializable) {
+                return;
+            }
+
             if (ev.serializable.typeName == "Node") {
 
                 var node = <Atomic.Node> ev.serializable;
@@ -159,8 +164,8 @@ class HierarchyFrame extends Atomic.UIWidget {
                 var node = this.scene.getNode(selectedId);
                 if (node) {
 
-                  node.removeAllComponents();
-                  node.remove();
+                    node.removeAllComponents();
+                    node.remove();
 
                 }
 
@@ -236,7 +241,7 @@ class HierarchyFrame extends Atomic.UIWidget {
 
             // create
             if (id == "menu create") {
-                if (!ToolCore.toolSystem.project) return;  
+                if (!ToolCore.toolSystem.project) return;
                 var src = MenuItemSources.getMenuItemSource("hierarchy create items");
                 var menu = new Atomic.UIMenuWindow(data.target, "create popup");
                 menu.show(src);

+ 4 - 4
Script/AtomicEditor/ui/frames/ProjectFrame.ts

@@ -136,10 +136,10 @@ class ProjectFrame extends ScriptWidget {
 
             if (this.menu.handlePopupMenu(data.target, data.refid))
                 return true;
-            
+
             // create
             if (id == "menu create") {
-                if (!ToolCore.toolSystem.project) return;  
+                if (!ToolCore.toolSystem.project) return;
                 var src = MenuItemSources.getMenuItemSource("project create items");
                 var menu = new Atomic.UIMenuWindow(data.target, "create popup");
                 menu.show(src);
@@ -308,7 +308,7 @@ class ProjectFrame extends ScriptWidget {
 
         var container: Atomic.UILayout = <Atomic.UILayout> this.getWidget("contentcontainer");
         container.deleteAllChildren();
-        
+
     }
 
     private refreshContent(folder: ToolCore.Asset) {
@@ -391,7 +391,7 @@ class ProjectFrame extends ScriptWidget {
         button.id = asset.guid;
         button.layoutParams = lp;
         button.fontDescription = fd;
-        button.text = asset.name;
+        button.text = asset.name + asset.extension;
         button.skinBg = "TBButton.flat";
         blayout.addChild(button);
 

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

@@ -126,6 +126,11 @@ class ComponentInspector extends Atomic.UISection {
             this.addJSComponentUI(attrsVerticalLayout);
         }
 
+        if (component.typeName == "TileMap2D") {
+            this.addTilemap2DUI(attrsVerticalLayout);
+        }
+
+
         if (component.typeName == "StaticModel" || component.typeName == "AnimatedModel" || component.typeName == "Skybox") {
             this.addModelUI(attrsVerticalLayout, component.typeName);
         }
@@ -489,6 +494,49 @@ class ComponentInspector extends Atomic.UISection {
 
     }
 
+    addTilemap2DUI(layout: Atomic.UILayout) {
+
+        var tilemap = <Atomic.TileMap2D> this.component;
+
+        var o = InspectorUtils.createAttrEditFieldWithSelectButton("TMX File", layout);
+        var field = o.editField;
+        field.readOnly = true;
+        field.text = tilemap.tmxFile ? tilemap.tmxFile.name : "";
+
+        var select = o.selectButton;
+
+        select.onClick = () => {
+
+            // this should allow selecting of sprite sheets as well
+            EditorUI.getModelOps().showResourceSelection("Select TMX File", "TMXImporter", function(asset: ToolCore.Asset) {
+
+                tilemap.tmxFile = <Atomic.TmxFile2D> Atomic.cache.getResource("TmxFile2D", asset.path);
+                if (tilemap.tmxFile)
+                    field.text = tilemap.tmxFile.name;
+            });
+
+        }
+
+        // handle dropping of component on field
+        field.subscribeToEvent(field, "DragEnded", (ev: Atomic.DragEndedEvent) => {
+
+            if (ev.target == field) {
+
+                var importer = this.acceptAssetDrag("TextureImporter", ev);
+
+                if (importer) {
+
+                  tilemap.tmxFile = <Atomic.TmxFile2D> Atomic.cache.getResource("TmxFile2D", importer.asset.path);
+                  if (tilemap.tmxFile)
+                      field.text = tilemap.tmxFile.name;
+
+                }
+            }
+
+        });
+
+    }
+
     addLightCascadeParametersUI(layout: Atomic.UILayout) {
 
         var light = <Atomic.Light> this.component;

+ 8 - 1
Script/AtomicEditor/ui/frames/inspector/CreateComponentButton.ts

@@ -9,8 +9,15 @@ audioCreateSource.addItem(new Atomic.UIMenuItem("SoundSource", "SoundSource"));
 audioCreateSource.addItem(new Atomic.UIMenuItem("SoundSource3D", "SoundSource3D"));
 
 var _2DCreateSource = new Atomic.UIMenuItemSource();
+_2DCreateSource.addItem(new Atomic.UIMenuItem("PhysicsWorld2D", "PhysicsWorld2D"));
 _2DCreateSource.addItem(new Atomic.UIMenuItem("StaticSprite2D", "StaticSprite2D"));
 _2DCreateSource.addItem(new Atomic.UIMenuItem("AnimatedSprite2D", "AnimatedSprite2D"));
+_2DCreateSource.addItem(new Atomic.UIMenuItem("PointLight2D", "PointLight2D"));
+_2DCreateSource.addItem(new Atomic.UIMenuItem("DirectionalLight2D", "DirectionalLight2D"));
+_2DCreateSource.addItem(new Atomic.UIMenuItem("RigidBody2D", "RigidBody2D"));
+_2DCreateSource.addItem(new Atomic.UIMenuItem("CollisionBox2D", "CollisionBox2D"));
+_2DCreateSource.addItem(new Atomic.UIMenuItem("CollisionCircle2D", "CollisionCircle2D"));
+_2DCreateSource.addItem(new Atomic.UIMenuItem("TileMap2D", "TileMap2D"));
 
 var geometryCreateSource = new Atomic.UIMenuItemSource();
 
@@ -51,7 +58,7 @@ var sceneCreateSource = new Atomic.UIMenuItemSource();
 
 sceneCreateSource.addItem(new Atomic.UIMenuItem("Camera", "Camera"));
 sceneCreateSource.addItem(new Atomic.UIMenuItem("Light", "Light"));
-sceneCreateSource.addItem(new Atomic.UIMenuItem("Zone", "create component"));
+sceneCreateSource.addItem(new Atomic.UIMenuItem("Zone", "Zone"));
 
 var subsystemCreateSource = new Atomic.UIMenuItemSource();
 

+ 48 - 3
Script/AtomicEditor/ui/frames/inspector/DataBinding.ts

@@ -93,7 +93,7 @@ class DataBinding {
             var lp = new Atomic.UILayoutParams();
             lp.width = 100;
 
-            for (var i:any = 0; i < 3; i++) {
+            for (var i: any = 0; i < 3; i++) {
                 var select = new Atomic.UIInlineSelect();
                 select.id = String(i + 1);
                 select.fontDescription = fd;
@@ -114,7 +114,7 @@ class DataBinding {
             var lp = new Atomic.UILayoutParams();
             lp.width = 70;
 
-            for (var i:any = 0; i < 4; i++) {
+            for (var i: any = 0; i < 4; i++) {
 
                 var select = new Atomic.UIInlineSelect();
                 select.id = String(i + 1);
@@ -124,6 +124,27 @@ class DataBinding {
                 layout.addChild(select);
             }
 
+        } else if (attrInfo.type == Atomic.VAR_VECTOR2) {
+            var layout = new Atomic.UILayout();
+            widget = layout;
+            layout.spacing = 0;
+
+            var lp = new Atomic.UILayoutParams();
+            lp.width = 100;
+
+            for (var i: any = 0; i < 2; i++) {
+                var select = new Atomic.UIInlineSelect();
+                select.id = String(i + 1);
+                select.fontDescription = fd;
+                select.skinBg = "InspectorVectorAttrName";
+                select.setLimits(-10000000, 10000000);
+                var editlp = new Atomic.UILayoutParams();
+                editlp.minWidth = 60;
+                select.editFieldLayoutParams = editlp;
+                select.layoutParams = lp;
+                layout.addChild(select);
+            }
+
         }
 
         if (widget) {
@@ -163,6 +184,18 @@ class DataBinding {
                     select.value = value[i];
             }
 
+        }
+        else if (attrInfo.type == Atomic.VAR_VECTOR2) {
+
+            var value = object.getAttribute(attrInfo.name);
+
+            for (var i = 0; i < 2; i++) {
+
+                var select = widget.getWidget((i + 1).toString());
+                if (select)
+                    select.value = value[i];
+            }
+
         }
         else if (attrInfo.type == Atomic.VAR_QUATERNION) {
 
@@ -254,7 +287,19 @@ class DataBinding {
 
             object.setAttribute(attrInfo.name, value);
 
-        } else if (type == Atomic.VAR_QUATERNION && srcWidget) {
+        } else if (type == Atomic.VAR_VECTOR2 && srcWidget) {
+
+            var value = object.getAttribute(attrInfo.name);
+
+            if (srcWidget.id == "1")
+                value[0] = srcWidget.value;
+            else if (srcWidget.id == "2")
+                value[1] = srcWidget.value;
+
+            object.setAttribute(attrInfo.name, value);
+
+        }
+        else if (type == Atomic.VAR_QUATERNION && srcWidget) {
 
             var value = object.getAttribute(attrInfo.name);
 

+ 6 - 1
Script/AtomicEditor/ui/frames/inspector/NodeInspector.ts

@@ -230,9 +230,14 @@ class NodeInspector extends ScriptWidget {
 
         for (var i in components) {
 
+            var component = components[i];
+
+            if (component.isTemporary())
+              continue;
+
             var ci = new ComponentInspector();
 
-            ci.inspect(components[i]);
+            ci.inspect(component);
 
             nodeLayout.addChild(ci);
 

+ 1 - 1
Script/Packages/Atomic/Atomic2D.json

@@ -14,7 +14,7 @@
 				 "Light2DGroup", "Light2D", "DirectionalLight2D", "PositionalLight2D", "PointLight2D"],
 	"overloads" : {
 		"AnimatedSprite2D" : {
-			"SetAnimation" : ["AnimationSet2D", "String", "LoopMode2D"]
+			"SetAnimation" : ["String", "LoopMode2D"]
 		},
 		"CollisionBox2D" : {
 			"SetSize" : ["Vector2"]

+ 2 - 1
Script/Packages/Atomic/Scene.json

@@ -39,7 +39,8 @@
 			"getComponents(componentType?:string, recursive?:boolean):Component[];",
 			"getChildAtIndex(index:number):Node;",
 			"createJSComponent(name:string, args?:{});",
-			"getJSComponent(name:string):JSComponent;"
+			"getJSComponent(name:string):JSComponent;",
+			"createChildPrefab(childName:string, prefabPath:string);"
 		],
 		"Scene" : [
 			"getMainCamera():Camera;"

+ 2 - 0
Script/TypeScript/ToolCore.d.ts

@@ -242,6 +242,7 @@ declare module ToolCore {
       guid: string;
       name: string;
       path: string;
+      extension: string;
       relativePath: string;
       cachePath: string;
       importerType: string;
@@ -261,6 +262,7 @@ declare module ToolCore {
       getGUID(): string;
       getName(): string;
       getPath(): string;
+      getExtension(): string;
       // Get the path relative to project
       getRelativePath(): string;
       getCachePath(): string;

+ 184 - 91
Source/Atomic/Atomic2D/Light2D.cpp

@@ -16,6 +16,7 @@
 #include "../Graphics/RenderPath.h"
 #include "../Graphics/Material.h"
 #include "../Graphics/Technique.h"
+#include "../Graphics/Zone.h"
 
 #include "../Atomic2D/RigidBody2D.h"
 #include "../Atomic2D/Renderer2D.h"
@@ -27,20 +28,16 @@
 namespace Atomic
 {
 
-
-static Viewport* __fixmeViewport = NULL;
-void FixMeSetLight2DGroupViewport(Viewport *viewport)
-{
-    __fixmeViewport = viewport;
-}
-
 extern const char* ATOMIC2D_CATEGORY;
 
 Light2D::Light2D(Context* context) : Component(context),
+    lightgroupID_(0),
+    color_(Color::WHITE),
     castShadows_(false),
     softShadows_(false),
     softShadowLength_(2.5f),
-    backtrace_(false)
+    backtrace_(false),
+    raysInitialized_(false)
 {
     SetNumRays(32);
 }
@@ -52,9 +49,48 @@ Light2D::~Light2D()
 
 void Light2D::SetNumRays(int numRays)
 {
+    raysInitialized_ = false;
     rays_.Resize(numRays);
 }
 
+void Light2D::OnSceneSet(Scene* scene)
+{
+    if (scene)
+    {
+        PODVector<Light2DGroup*> lightgroups;
+        scene->GetComponents<Light2DGroup>(lightgroups, true);
+
+        lightgroup_ = 0;
+        for (unsigned i = 0; i < lightgroups.Size(); i++)
+        {
+            Light2DGroup* lightgroup = lightgroups.At(i);
+            if (lightgroup->GetLightGroupID() == lightgroupID_)
+            {
+                lightgroup_ = lightgroup;
+                lightgroup_->AddLight2D(this);
+                break;
+            }
+        }
+
+        if (lightgroup_.Null())
+        {
+            lightgroup_ = node_->CreateComponent<Light2DGroup>();
+            lightgroup_->SetTemporary(true);
+            lightgroup_->AddLight2D(this);
+        }
+    }
+    else
+    {
+        if (lightgroup_)
+        {
+            lightgroup_->RemoveLight2D(this);
+            lightgroup_ = 0;
+        }
+
+    }
+}
+
+
 void Light2D::OnSetEnabled()
 {
     Component::OnSetEnabled();
@@ -77,10 +113,23 @@ void Light2D::RegisterObject(Context* context)
 {
     context->RegisterFactory<Light2D>(ATOMIC2D_CATEGORY);
     COPY_BASE_ATTRIBUTES(Component);
+
+    ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("LightGroup", GetLightGroupID, SetLightGroupID, int, 0, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Color", GetColor, SetColor, Color, Color::WHITE, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Cast Shadows", GetCastShadows, SetCastShadows, bool, false, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Num Rays", GetNumRays, SetNumRays, int, 32, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Soft Shadows", GetSoftShadows, SetSoftShadows, bool, false, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Soft Shadows Length", GetSoftShadowLength, SetSoftShadowLength, float, 2.5f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Backtrace", GetBacktrace, SetBacktrace, bool, false, AM_DEFAULT);
+
 }
 
 void Light2D::CastRays()
 {
+    if (!raysInitialized_ || context_->GetEditorContext())
+        return;
+
     PhysicsWorld2D* physicsWorld = lightgroup_->GetPhysicsWorld();
 
     if (physicsWorld && castShadows_) {
@@ -155,14 +204,17 @@ void DirectionalLight2D::RegisterObject(Context* context)
 {
     context->RegisterFactory<DirectionalLight2D>(ATOMIC2D_CATEGORY);
     COPY_BASE_ATTRIBUTES(Light2D);
+
+    ACCESSOR_ATTRIBUTE("Direction", GetDirection, SetDirection, float, -45.0f, AM_DEFAULT);
 }
 
 void DirectionalLight2D::UpdateVertices()
 {
-    vertices_.Clear();
-
-    if (!lightgroup_ || !enabled_)
+    if (!lightgroup_ || !enabled_ || context_->GetEditorContext())
+    {
+        vertices_.Clear();
         return;
+    }
 
     const BoundingBox& frustumBox = lightgroup_->GetFrustumBox();
 
@@ -171,6 +223,10 @@ void DirectionalLight2D::UpdateVertices()
 
     float width = frustumBox.Size().x_;
     float height = frustumBox.Size().y_;
+
+    if (!width || !height)
+        return;
+
     float sizeOfScreen = width > height ? width : height;
 
     float xAxelOffSet = sizeOfScreen * cos;
@@ -211,6 +267,7 @@ void DirectionalLight2D::UpdateVertices()
         ray.fraction_ = 0.0f;
     }
 
+    raysInitialized_ = true;
     CastRays();
 
     Vertex2D vertex0;
@@ -219,36 +276,50 @@ void DirectionalLight2D::UpdateVertices()
     Vertex2D vertex3;
 
     vertex0.color_ = vertex1.color_ = vertex2.color_ = vertex3.color_ = color_.ToUInt();
+    vertex0.uv_.x_ = 1.0f;
+    vertex2.uv_.x_ = 1.0 ;
+    vertex1.uv_.x_ = 1.0f;
+    vertex3.uv_.x_ = 1.0f;
+
+    int vertexCount = (rayNum - 1) * 6;
+
+    if (softShadows_ && castShadows_)
+        vertexCount *= 2;
+
+    if (vertices_.Size() != vertexCount)
+        vertices_.Resize(vertexCount);
+
+    Vertex2D* v = &vertices_[0];
 
     for (unsigned i = 0; i < rayNum - 1; i++) {
 
         Light2DRay& ray0 = rays_[i];
         Light2DRay& ray1 = rays_[i + 1];
 
-        vertex0.position_ = Vector3( ray0.start_.x_, ray0.start_.y_, 0.0f);
-        vertex1.position_ = Vector3( ray0.end_.x_, ray0.end_.y_, 0.0f);
-        vertex2.position_ = Vector3( ray1.start_.x_, ray1.start_.y_, 0.0f);
-        vertex3.position_ = Vector3( ray1.end_.x_, ray1.end_.y_, 0.0f);
+        vertex0.position_.x_ = ray0.start_.x_;
+        vertex0.position_.y_ = ray0.start_.y_;
 
-        vertex0.uv_.x_ = 1.0f;
-        vertex2.uv_.x_ = 1.0 ;
-        vertex1.uv_.x_ = 1.0f;
-        vertex3.uv_.x_ =  1.0f;
+        vertex1.position_.x_ = ray0.end_.x_;
+        vertex1.position_.y_ = ray0.end_.y_;
+
+        vertex2.position_.x_ = ray1.start_.x_;
+        vertex2.position_.y_ = ray1.start_.y_;
 
-        vertices_.Push(vertex0);
-        vertices_.Push(vertex1);
-        vertices_.Push(vertex3);
+        vertex3.position_.x_ = ray1.end_.x_;
+        vertex3.position_.y_ = ray1.end_.y_;
 
-        vertices_.Push(vertex0);
-        vertices_.Push(vertex3);
-        vertices_.Push(vertex2);
+        *v++ = vertex0;
+        *v++ = vertex1;
+        *v++ = vertex3;
+
+        *v++ = vertex0;
+        *v++ = vertex3;
+        *v++ = vertex2;
 
     }
 
     if (softShadows_ && castShadows_)
     {
-        unsigned uambient = lightgroup_->GetAmbientColor().ToUInt();
-
         // THIS CAN BE OPTIMIZED!
         for (unsigned i = 0; i < rays_.Size() - 1; i++) {
 
@@ -280,13 +351,13 @@ void DirectionalLight2D::UpdateVertices()
             vertex1.uv_.x_ = 1.0;
             vertex2.uv_.x_ = 1.0;
 
-            vertices_.Push(vertex0);
-            vertices_.Push(vertex1);
-            vertices_.Push(vertex2);
+            *v++ = vertex0;
+            *v++ = vertex1;
+            *v++ = vertex2;
 
-            vertices_.Push(vertex0);
-            vertices_.Push(vertex2);
-            vertices_.Push(vertex3);
+            *v++ = vertex0;
+            *v++ = vertex2;
+            *v++ = vertex3;
 
         }
 
@@ -307,15 +378,16 @@ PositionalLight2D::~PositionalLight2D()
 void PositionalLight2D::RegisterObject(Context* context)
 {
     context->RegisterFactory<PositionalLight2D>(ATOMIC2D_CATEGORY);
-    COPY_BASE_ATTRIBUTES(Light2D);
+    COPY_BASE_ATTRIBUTES(Light2D);    
 }
 
 void PositionalLight2D::UpdateVertices()
 {
-    vertices_.Clear();
-
     if (!lightgroup_ || !enabled_)
+    {
+        vertices_.Clear();
         return;
+    }
 
     CastRays();
 
@@ -326,22 +398,37 @@ void PositionalLight2D::UpdateVertices()
 
     vertex0.color_ = vertex1.color_ = vertex2.color_ = vertex3.color_ = color_.ToUInt();
 
+    int vertexCount = (rays_.Size() - 1 ) * 3;
+
+    if (softShadows_ && castShadows_)
+        vertexCount += (rays_.Size() - 1) * 6;
+
+    if (vertices_.Size() != vertexCount)
+        vertices_.Resize(vertexCount);
+
+    Vertex2D* v = &vertices_[0];
+
     for (unsigned i = 0; i < rays_.Size() - 1; i++) {
 
         Light2DRay& ray0 = rays_[i];
         Light2DRay& ray1 = rays_[i + 1];
 
-        vertex0.position_ = Vector3( ray0.start_.x_, ray0.start_.y_, 0.0f);
-        vertex1.position_ = Vector3( ray0.end_.x_, ray0.end_.y_, 0.0f);
-        vertex2.position_ = Vector3( ray1.end_.x_, ray1.end_.y_, 0.0f);
+        vertex0.position_.x_ = ray0.start_.x_;
+        vertex0.position_.y_ = ray0.start_.y_;
+
+        vertex1.position_.x_ = ray0.end_.x_;
+        vertex1.position_.y_ = ray0.end_.y_;
+
+        vertex2.position_.x_ = ray1.end_.x_;
+        vertex2.position_.y_ = ray1.end_.y_;
 
         vertex0.uv_.x_ = 1.0f;
         vertex1.uv_.x_ =  1.0f - ray0.fraction_;
         vertex2.uv_.x_ =  1.0f - ray1.fraction_;
 
-        vertices_.Push(vertex0);
-        vertices_.Push(vertex1);
-        vertices_.Push(vertex2);
+        *v++ = vertex0;
+        *v++ = vertex1;
+        *v++ = vertex2;
 
     }
 
@@ -356,16 +443,17 @@ void PositionalLight2D::UpdateVertices()
             float s0 = (1.0f - ray0.fraction_);
             float s1 = (1.0f - ray1.fraction_);
 
-            vertex0.position_ = Vector3( ray0.end_.x_, ray0.end_.y_, 0.0f);
-
-            vertex1.position_ = Vector3( ray0.end_.x_ + s0 * softShadowLength_ * ray0.cos_,
-                                         (ray0.end_.y_ + s0 * softShadowLength_ * ray0.sin_), 0.0f);
+            vertex0.position_.x_ = ray0.end_.x_;
+            vertex0.position_.y_ = ray0.end_.y_;
 
+            vertex1.position_.x_ = ray0.end_.x_ + s0 * softShadowLength_ * ray0.cos_;
+            vertex1.position_.y_ = ray0.end_.y_ + s0 * softShadowLength_ * ray0.sin_;
 
-            vertex2.position_ = Vector3( ray1.end_.x_ + s1 * softShadowLength_ * ray1.cos_,
-                                         (ray1.end_.y_ + s1 * softShadowLength_ * ray1.sin_), 0.0f);
+            vertex2.position_.x_ = ray1.end_.x_ + s1 * softShadowLength_ * ray1.cos_;
+            vertex2.position_.y_ = ray1.end_.y_ + s1 * softShadowLength_ * ray1.sin_;
 
-            vertex3.position_ = Vector3( ray1.end_.x_, ray1.end_.y_, 0.0f);
+            vertex3.position_.x_ = ray1.end_.x_;
+            vertex3.position_.y_ = ray1.end_.y_;
 
             vertex1.uv_.x_ = 0;
             vertex2.uv_.x_ = 0;
@@ -375,13 +463,13 @@ void PositionalLight2D::UpdateVertices()
             vertex0.uv_.x_ = s0 * .65f;
             vertex3.uv_.x_ = s1 * .65f;
 
-            vertices_.Push(vertex0);
-            vertices_.Push(vertex1);
-            vertices_.Push(vertex2);
+            *v++ = vertex0;
+            *v++ = vertex1;
+            *v++ = vertex2;
 
-            vertices_.Push(vertex0);
-            vertices_.Push(vertex2);
-            vertices_.Push(vertex3);
+            *v++ = vertex0;
+            *v++ = vertex2;
+            *v++ = vertex3;
 
         }
 
@@ -389,7 +477,7 @@ void PositionalLight2D::UpdateVertices()
 }
 
 PointLight2D::PointLight2D(Context* context) : PositionalLight2D(context),
-    radius_(1.0f)
+    radius_(4.0f)
 {
     lightType_ = LIGHT2D_POINT;
 }
@@ -403,18 +491,19 @@ void PointLight2D::RegisterObject(Context* context)
 {
     context->RegisterFactory<PointLight2D>(ATOMIC2D_CATEGORY);
     COPY_BASE_ATTRIBUTES(PositionalLight2D);
+
+    ACCESSOR_ATTRIBUTE("Radius", GetRadius, SetRadius, float, 4.0f, AM_DEFAULT);
 }
 
 void PointLight2D::UpdateVertices()
 {
-    vertices_.Clear();
+    const Node* lightNode = GetNode();
 
-    if (!lightgroup_ || !enabled_)
+    if (!lightgroup_ || !enabled_ || !lightNode)
+    {
+        vertices_.Clear();
         return;
-
-    const PhysicsWorld2D* physicsWorld = lightgroup_->GetPhysicsWorld();
-
-    const Node* lightNode = GetNode();
+    }
 
     Vector2 start = lightNode->GetWorldPosition2D();
 
@@ -430,6 +519,7 @@ void PointLight2D::UpdateVertices()
         ray.fraction_ = 1.0f;
     }
 
+    raysInitialized_ = true;
     PositionalLight2D::UpdateVertices();
 
 }
@@ -443,31 +533,28 @@ void Light2DGroup::RegisterObject(Context* context)
 
 
 
-void Light2DGroup::OnNodeSet(Node* node)
+void Light2DGroup::OnSceneSet(Scene* scene)
 {
-    // Do not call Drawable2D::OnNodeSet(node)
 
-    if (node)
+    if (scene && node_)
     {
-        if (renderer_.Null())
-        {
-            renderer_ = node->GetOrCreateComponent<Renderer2D>();
-            renderer_->SetUseTris(true);
-        }
+        physicsWorld_ = scene->GetOrCreateComponent<PhysicsWorld2D>();
 
-        if (light2DMaterial_.Null())
-            CreateLight2DMaterial();
+        Zone* zone = scene->GetComponent<Zone>();
+        if (zone)
+            SetAmbientColor(zone->GetAmbientColor());
 
-        Scene* scene = GetScene();
-        if (scene)
-        {
-            if (IsEnabledEffective())
-                renderer_->AddDrawable(this);
-        }
+        renderer_ = node_->GetOrCreateComponent<Renderer2D>();
+        renderer_->SetTemporary(true);
+        renderer_->SetUseTris(true);
 
-        node->AddListener(this);
+        if (light2DMaterial_.Null())
+            CreateLight2DMaterial();
 
+        if (IsEnabledEffective())
+            renderer_->AddDrawable(this);
 
+        node_->AddListener(this);
     }
     else
     {
@@ -478,6 +565,7 @@ void Light2DGroup::OnNodeSet(Node* node)
 }
 
 Light2DGroup::Light2DGroup(Context* context) : Drawable2D(context),
+    lightgroupID_(0),
     ambientColor_(0, 0, 0, 0),
     frustum_(0)
 {
@@ -492,7 +580,7 @@ Light2DGroup::~Light2DGroup()
 
     if (renderer)
     {
-        Viewport* viewport = __fixmeViewport ? __fixmeViewport :  renderer->GetViewport(0);
+        Viewport* viewport = renderer->GetViewport(0);
         if (viewport)
         {
             RenderPath* renderpath = viewport->GetRenderPath();
@@ -502,8 +590,6 @@ Light2DGroup::~Light2DGroup()
 
     }
 
-    __fixmeViewport = NULL;
-
 }
 
 void Light2DGroup::HandleBeginViewUpdate(StringHash eventType, VariantMap& eventData)
@@ -568,21 +654,26 @@ void Light2DGroup::UpdateSourceBatches()
 
 void Light2DGroup::AddLight2D(Light2D* light)
 {
-    for (Vector<WeakPtr<Light2D> >::ConstIterator itr = lights_.Begin(); itr != lights_.End(); itr++)
-        if (*itr == light)
-            return;
+    Vector<WeakPtr<Light2D>>::Iterator itr = lights_.Find(WeakPtr<Light2D>(light));
 
-    light->SetLightGroup(this);
+    if (itr != lights_.End())
+        return;
 
     lights_.Push(WeakPtr<Light2D>(light));
 
 }
 
-void Light2DGroup::SetPhysicsWorld(PhysicsWorld2D* physicsWorld)
+void Light2DGroup::RemoveLight2D(Light2D* light)
 {
-    physicsWorld_ = physicsWorld;
+
+    Vector<WeakPtr<Light2D>>::Iterator itr = lights_.Find(WeakPtr<Light2D>(light));
+
+    if (itr != lights_.End())
+        lights_.Erase(itr);
+
 }
 
+
 void Light2DGroup::SetAmbientColor(const Color& color)
 {
     if (color == ambientColor_)
@@ -594,7 +685,7 @@ void Light2DGroup::SetAmbientColor(const Color& color)
     // only on main viewport atm and viewport must first be set
     if (renderer)
     {
-        Viewport* viewport = __fixmeViewport ? __fixmeViewport :  renderer->GetViewport(0);
+        Viewport* viewport = renderer->GetViewport(0);
         if (viewport)
         {
             RenderPath* renderpath = viewport->GetRenderPath();
@@ -606,9 +697,11 @@ void Light2DGroup::SetAmbientColor(const Color& color)
 
 void Light2DGroup::CreateLight2DMaterial()
 {
+    if (context_->GetEditorContext())
+        return;
+
     Renderer* renderer = GetSubsystem<Renderer>();
-    // only on main viewport atm and viewport must first be set
-    Viewport* viewport = __fixmeViewport ? __fixmeViewport :  renderer->GetViewport(0);
+    Viewport* viewport = renderer->GetViewport(0);
     RenderPath* renderpath = viewport->GetRenderPath();
 
     RenderTargetInfo ntarget;

+ 18 - 9
Source/Atomic/Atomic2D/Light2D.h

@@ -42,18 +42,18 @@ public:
     /// Register object factory
     static void RegisterObject(Context* context);
 
-    void SetLightGroup(Light2DGroup* group) { lightgroup_ = group; }
-    Light2DGroup* GetLightGroup() { return lightgroup_; }
+    void SetLightGroupID(int id) { lightgroupID_ = id; }
+    int GetLightGroupID() const { return lightgroupID_; }
 
     const Color& GetColor() const { return color_; }
     void SetColor(const Color& color) { color_ = color; }
 
-    void AddVertices(Vector<Vertex2D>& vertices);
+    void AddVertices(Vector<Vertex2D> &vertices);
 
     virtual void UpdateVertices() {}
 
     void SetNumRays(int numRays);
-    unsigned GetNumRays() const { return rays_.Size(); }
+    int GetNumRays() const { return (int) rays_.Size(); }
 
     virtual void OnSetEnabled();
 
@@ -73,15 +73,20 @@ public:
 
 protected:
 
+    void OnSceneSet(Scene* scene);
+
     void CastRays();
 
+    int lightgroupID_;
     WeakPtr<Light2DGroup> lightgroup_;
+
     Color color_;
     bool castShadows_;
     bool softShadows_;
     bool backtrace_;
     float softShadowLength_;
     PODVector<Light2DRay> rays_;
+    bool raysInitialized_;
     Vector<Vertex2D> vertices_;
     LightType2D lightType_;
 };
@@ -168,10 +173,11 @@ public:
     /// Register object factory. drawable2d must be registered first.
     static void RegisterObject(Context* context);
 
-    void SetPhysicsWorld(PhysicsWorld2D* physicsWorld);
     PhysicsWorld2D* GetPhysicsWorld() { return physicsWorld_; }
 
     void AddLight2D(Light2D* light);
+    void RemoveLight2D(Light2D* light);
+
     Vector<WeakPtr<Light2D> >& GetLights() { return lights_; }
 
     void SetDirty() { /*verticesDirty_ = true;*/ }
@@ -179,6 +185,9 @@ public:
     void SetAmbientColor(const Color& color);
     const Color& GetAmbientColor() { return ambientColor_; }
 
+    void SetLightGroupID(int id) { lightgroupID_ = id; }
+    int GetLightGroupID() const { return lightgroupID_; }
+
     const BoundingBox& GetFrustumBox() const { return frustumBoundingBox_; }
 
 protected:
@@ -186,22 +195,22 @@ protected:
     /// Recalculate the world-space bounding box.
     void OnWorldBoundingBoxUpdate();
 
-    void OnNodeSet(Node* node);
+    void OnSceneSet(Scene* scene);
 
     /// Handle draw order changed.
     virtual void OnDrawOrderChanged();
     /// Update source batches.
     virtual void UpdateSourceBatches();
 
-
 private:
 
-    Color ambientColor_;
     void HandleBeginRendering(StringHash eventType, VariantMap& eventData);
     void HandleBeginViewUpdate(StringHash eventType, VariantMap& eventData);
-
     void CreateLight2DMaterial();
 
+    int lightgroupID_;
+    Color ambientColor_;
+
     Vector<WeakPtr<Light2D> > lights_;
 
     SharedPtr<Material> shadow2DMaterial_;

+ 2 - 1
Source/Atomic/Atomic2D/RigidBody2D.cpp

@@ -39,11 +39,12 @@ namespace Atomic
 extern const char* ATOMIC2D_CATEGORY;
 static const BodyType2D DEFAULT_BODYTYPE = BT_STATIC;
 
+// ATOMIC: Make sure these match box2d order
 static const char* bodyTypeNames[] =
 {
     "Static",
-    "Dynamic",
     "Kinematic",
+    "Dynamic",
     0
 };
 

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

@@ -7,7 +7,6 @@
 namespace Atomic
 {
 
-/// Helper base class for user-defined game logic components that hooks up to update events and forwards them to virtual functions similar to ScriptInstance class.
 class PrefabComponent : public Component
 {
     OBJECT(PrefabComponent);

+ 34 - 10
Source/AtomicEditor/Editors/SceneEditor3D/SceneView3D.cpp

@@ -36,8 +36,13 @@
 #include <ToolCore/Assets/Asset.h>
 #include <ToolCore/Assets/AssetDatabase.h>
 #include <ToolCore/Assets/ModelImporter.h>
-
 #include <ToolCore/Assets/PrefabImporter.h>
+#include <ToolCore/Assets/SpriterImporter.h>
+#include <ToolCore/Assets/TextureImporter.h>
+
+#include <Atomic/Atomic2D/Sprite2D.h>
+#include <Atomic/Atomic2D/AnimationSet2D.h>
+#include <Atomic/Atomic2D/AnimatedSprite2D.h>
 
 #include "../../EditorMode/AEEditorEvents.h"
 
@@ -490,8 +495,6 @@ void SceneView3D::HandleDragEnterWidget(StringHash eventType, VariantMap& eventD
             dragNode_ = scene_->CreateChild(asset->GetName());
             PrefabComponent* pc = dragNode_->CreateComponent<PrefabComponent>();
             pc->SetPrefabGUID(asset->GetGUID());
-            dragNode_->SetName(asset->GetName());
-
         }
         else if (importerType == ModelImporter::GetTypeNameStatic())
         {
@@ -504,18 +507,39 @@ void SceneView3D::HandleDragEnterWidget(StringHash eventType, VariantMap& eventD
                 return;
 
             dragNode_->LoadXML(xml->GetRoot());
-            dragNode_->SetName(asset->GetName());
+        }
+        else if (importerType == SpriterImporter::GetTypeNameStatic())
+        {
+            AnimationSet2D* animationSet = GetSubsystem<ResourceCache>()->GetResource<AnimationSet2D>(asset->GetPath());
+
+            String animationName;
+
+            if (animationSet && animationSet->GetNumAnimations())
+            {
+                animationName = animationSet->GetAnimation(0)->GetName();
+            }
 
-            /*
             dragNode_ = scene_->CreateChild(asset->GetName());
-            preloadResourceScene_ = new Scene(context_);
 
-            SharedPtr<File> file(new File(context_, asset->GetCachePath()));
+            AnimatedSprite2D* sprite = dragNode_->CreateComponent<AnimatedSprite2D>();
+
+            if (!animationName.Length())
+                sprite->SetAnimationSet(animationSet);
+            else
+                sprite->SetAnimation(animationSet, animationName);
 
-            preloadResourceScene_->LoadAsyncXML(file, LOAD_RESOURCES_ONLY);
-            dragAssetGUID_ = asset->GetGUID();
-            */
         }
+        else if (importerType == TextureImporter::GetTypeNameStatic())
+        {
+            dragNode_ = scene_->CreateChild(asset->GetName());
+
+            Sprite2D* spriteGraphic = GetSubsystem<ResourceCache>()->GetResource<Sprite2D>(asset->GetPath());
+
+            StaticSprite2D* sprite = dragNode_->CreateComponent<StaticSprite2D>();
+
+            sprite->SetSprite(spriteGraphic);
+        }
+
 
         if (dragNode_.NotNull())
         {

+ 4 - 1
Source/AtomicJS/Javascript/JSComponent.cpp

@@ -165,6 +165,9 @@ void JSComponent::SetUpdateEventMask(unsigned char mask)
 
 void JSComponent::UpdateReferences(bool remove)
 {
+    if (context_->GetEditorContext())
+        return;
+
     duk_context* ctx = vm_->GetJSContext();
 
     int top = duk_get_top(ctx);
@@ -390,7 +393,7 @@ void JSComponent::OnNodeSet(Node* node)
 {
     if (node)
     {
-
+        UpdateReferences();
     }
     else
     {

+ 41 - 2
Source/AtomicJS/Javascript/JSScene.cpp

@@ -3,11 +3,16 @@
 // https://github.com/AtomicGameEngine/AtomicGameEngine
 
 #include <Atomic/Resource/ResourceCache.h>
+#include <Atomic/Resource/XMLFile.h>
 #include <Atomic/IO/File.h>
 #include <Atomic/Scene/Node.h>
 #include <Atomic/Scene/Scene.h>
 #include <Atomic/Graphics/Camera.h>
 
+#ifdef ATOMIC_3D
+#include <Atomic/Physics/RigidBody.h>
+#endif
+
 #include "JSScene.h"
 #include "JSComponent.h"
 #include "JSVM.h"
@@ -193,6 +198,40 @@ static int Node_SaveXML(duk_context* ctx)
     return 1;
 }
 
+static int Node_CreateChildPrefab(duk_context* ctx)
+{
+    const char* childName = duk_require_string(ctx, 0);
+    const char* prefabName = duk_require_string(ctx, 1);
+
+    duk_push_this(ctx);
+    Node* parent = js_to_class_instance<Node>(ctx, -1, 0);
+
+    Node* prefabNode = parent->CreateChild(childName);
+
+    ResourceCache* cache = parent->GetSubsystem<ResourceCache>();
+    XMLFile* xmlfile = cache->GetResource<XMLFile>(prefabName);
+
+    prefabNode->LoadXML(xmlfile->GetRoot());
+    prefabNode->SetTemporary(true);
+
+    prefabNode->SetPosition(Vector3::ZERO);
+    prefabNode->SetRotation(Quaternion::IDENTITY);
+
+#ifdef ATOMIC_3D
+    PODVector<RigidBody*> bodies;
+    prefabNode->GetComponents<RigidBody>(bodies, true);
+    for (unsigned i = 0; i < bodies.Size(); i++)
+    {
+        RigidBody* body = bodies[i];
+        body->SetTransform(body->GetNode()->GetWorldPosition(), body->GetNode()->GetWorldRotation());
+    }
+#endif
+
+    js_push_class_object_instance(ctx, prefabNode, "Node");
+
+    return 1;
+
+}
 
 static int Scene_LoadXML(duk_context* ctx)
 {
@@ -250,8 +289,6 @@ static int Scene_GetMainCamera(duk_context* ctx)
 
 }
 
-
-
 void jsapi_init_scene(JSVM* vm)
 {
     duk_context* ctx = vm->GetJSContext();
@@ -273,6 +310,8 @@ void jsapi_init_scene(JSVM* vm)
     duk_put_prop_string(ctx, -2, "getChildAtIndex");
     duk_push_c_function(ctx, Node_SaveXML, 1);
     duk_put_prop_string(ctx, -2, "saveXML");
+    duk_push_c_function(ctx, Node_CreateChildPrefab, 2);
+    duk_put_prop_string(ctx, -2, "createChildPrefab");
 
     duk_pop(ctx);
 

+ 17 - 1
Source/ToolCore/Assets/Asset.cpp

@@ -15,6 +15,8 @@
 #include "TextureImporter.h"
 #include "PrefabImporter.h"
 #include "JavascriptImporter.h"
+#include "SpriterImporter.h"
+#include "TMXImporter.h"
 
 #include "AssetEvents.h"
 #include "Asset.h"
@@ -230,7 +232,7 @@ bool Asset::CreateImporter()
     }
     else
     {
-        String ext = GetExtension(path_);
+        String ext = Atomic::GetExtension(path_);
 
         name_ = GetFileName(path_);
 
@@ -265,6 +267,14 @@ bool Asset::CreateImporter()
         {
             importer_ = new MaterialImporter(context_, this);
         }
+        else if (ext == ".scml")
+        {
+            importer_ = new SpriterImporter(context_, this);
+        }
+        else if (ext == ".tmx")
+        {
+            importer_ = new TMXImporter(context_, this);
+        }
         else if (textureFormats.Contains(ext))
         {
             importer_ = new TextureImporter(context_, this);
@@ -287,6 +297,12 @@ String Asset::GetCachePath() const
     return cachePath;
 }
 
+String Asset::GetExtension() const
+{
+
+    return Atomic::GetExtension(path_);
+
+}
 
 bool Asset::SetPath(const String& path)
 {

+ 1 - 0
Source/ToolCore/Assets/Asset.h

@@ -32,6 +32,7 @@ public:
     const String& GetGUID() const { return guid_; }
     const String& GetName() const { return name_; }
     const String& GetPath() const { return path_; }
+    String GetExtension() const;
     /// Get the path relative to project
     String GetRelativePath();
     String GetCachePath() const;

+ 53 - 0
Source/ToolCore/Assets/SpriterImporter.cpp

@@ -0,0 +1,53 @@
+
+#include <Atomic/Resource/ResourceCache.h>
+#include <Atomic/Resource/Image.h>
+
+#include "Asset.h"
+#include "AssetDatabase.h"
+#include "SpriterImporter.h"
+
+namespace ToolCore
+{
+
+SpriterImporter::SpriterImporter(Context* context, Asset *asset) : AssetImporter(context, asset)
+{
+
+}
+
+SpriterImporter::~SpriterImporter()
+{
+
+}
+
+void SpriterImporter::SetDefaults()
+{
+    AssetImporter::SetDefaults();
+}
+
+bool SpriterImporter::Import()
+{
+    return true;
+}
+
+bool SpriterImporter::LoadSettingsInternal()
+{
+    if (!AssetImporter::LoadSettingsInternal())
+        return false;
+
+    JSONValue import = jsonRoot_.GetChild("SpriterImporter", JSON_OBJECT);
+
+    return true;
+}
+
+bool SpriterImporter::SaveSettingsInternal()
+{
+    if (!AssetImporter::SaveSettingsInternal())
+        return false;
+
+    JSONValue import = jsonRoot_.CreateChild("SpriterImporter");
+
+    return true;
+}
+
+
+}

+ 29 - 0
Source/ToolCore/Assets/SpriterImporter.h

@@ -0,0 +1,29 @@
+
+#pragma once
+
+#include "AssetImporter.h"
+
+namespace ToolCore
+{
+
+class SpriterImporter : public AssetImporter
+{
+    OBJECT(SpriterImporter);
+
+public:
+    /// Construct.
+    SpriterImporter(Context* context, Asset* asset);
+    virtual ~SpriterImporter();
+
+    virtual void SetDefaults();
+
+protected:
+
+    bool Import();
+
+    virtual bool LoadSettingsInternal();
+    virtual bool SaveSettingsInternal();
+
+};
+
+}

+ 53 - 0
Source/ToolCore/Assets/TMXImporter.cpp

@@ -0,0 +1,53 @@
+
+#include <Atomic/Resource/ResourceCache.h>
+#include <Atomic/Resource/Image.h>
+
+#include "Asset.h"
+#include "AssetDatabase.h"
+#include "TMXImporter.h"
+
+namespace ToolCore
+{
+
+TMXImporter::TMXImporter(Context* context, Asset *asset) : AssetImporter(context, asset)
+{
+
+}
+
+TMXImporter::~TMXImporter()
+{
+
+}
+
+void TMXImporter::SetDefaults()
+{
+    AssetImporter::SetDefaults();
+}
+
+bool TMXImporter::Import()
+{
+    return true;
+}
+
+bool TMXImporter::LoadSettingsInternal()
+{
+    if (!AssetImporter::LoadSettingsInternal())
+        return false;
+
+    JSONValue import = jsonRoot_.GetChild("TMXImporter", JSON_OBJECT);
+
+    return true;
+}
+
+bool TMXImporter::SaveSettingsInternal()
+{
+    if (!AssetImporter::SaveSettingsInternal())
+        return false;
+
+    JSONValue import = jsonRoot_.CreateChild("TMXImporter");
+
+    return true;
+}
+
+
+}

+ 29 - 0
Source/ToolCore/Assets/TMXImporter.h

@@ -0,0 +1,29 @@
+
+#pragma once
+
+#include "AssetImporter.h"
+
+namespace ToolCore
+{
+
+class TMXImporter : public AssetImporter
+{
+    OBJECT(TMXImporter);
+
+public:
+    /// Construct.
+    TMXImporter(Context* context, Asset* asset);
+    virtual ~TMXImporter();
+
+    virtual void SetDefaults();
+
+protected:
+
+    bool Import();
+
+    virtual bool LoadSettingsInternal();
+    virtual bool SaveSettingsInternal();
+
+};
+
+}