Browse Source

Updated 3dsmax exporter to 0.6
3dsmax exporters can be compiled directly from repo's folder

David Catuhe 8 years ago
parent
commit
732bdab22a
78 changed files with 75955 additions and 34681 deletions
  1. 132 0
      Exporters/3ds Max/ActionsBuilder/ActionsBuilder.csproj
  2. 0 42
      Exporters/3ds Max/ActionsBuilder/README.md
  3. 86 86
      Exporters/3ds Max/ActionsBuilder/Sources/actionsbuilder.actionNode.js
  4. 118 118
      Exporters/3ds Max/ActionsBuilder/Sources/actionsbuilder.contextMenu.js
  5. 351 351
      Exporters/3ds Max/ActionsBuilder/Sources/actionsbuilder.js
  6. 255 255
      Exporters/3ds Max/ActionsBuilder/Sources/actionsbuilder.list.js
  7. 107 101
      Exporters/3ds Max/ActionsBuilder/Sources/actionsbuilder.main.js
  8. 111 110
      Exporters/3ds Max/ActionsBuilder/Sources/actionsbuilder.max.js
  9. 561 550
      Exporters/3ds Max/ActionsBuilder/Sources/actionsbuilder.parameters.js
  10. 85 85
      Exporters/3ds Max/ActionsBuilder/Sources/actionsbuilder.toolbar.js
  11. 433 433
      Exporters/3ds Max/ActionsBuilder/Sources/actionsbuilder.utils.js
  12. 631 647
      Exporters/3ds Max/ActionsBuilder/Sources/actionsbuilder.viewer.js
  13. 47131 24102
      Exporters/3ds Max/ActionsBuilder/Sources/babylon.max.js
  14. 0 48
      Exporters/3ds Max/ActionsBuilder/Sources/fonts/SinkinSans/SinkinSans_NOTICE.txt
  15. 97 94
      Exporters/3ds Max/ActionsBuilder/Sources/index-debug.html
  16. 191 191
      Exporters/3ds Max/ActionsBuilder/Sources/index.css
  17. 72 72
      Exporters/3ds Max/ActionsBuilder/Sources/index.html
  18. 62 0
      Exporters/3ds Max/ActionsBuilder/actionsbuilder.actionNode.js
  19. 100 100
      Exporters/3ds Max/ActionsBuilder/actionsbuilder.actionNode.ts
  20. 104 0
      Exporters/3ds Max/ActionsBuilder/actionsbuilder.contextMenu.js
  21. 148 148
      Exporters/3ds Max/ActionsBuilder/actionsbuilder.contextMenu.ts
  22. 316 0
      Exporters/3ds Max/ActionsBuilder/actionsbuilder.js
  23. 209 0
      Exporters/3ds Max/ActionsBuilder/actionsbuilder.list.js
  24. 305 305
      Exporters/3ds Max/ActionsBuilder/actionsbuilder.list.ts
  25. 96 0
      Exporters/3ds Max/ActionsBuilder/actionsbuilder.main.js
  26. 115 106
      Exporters/3ds Max/ActionsBuilder/actionsbuilder.main.ts
  27. 440 0
      Exporters/3ds Max/ActionsBuilder/actionsbuilder.parameters.js
  28. 649 637
      Exporters/3ds Max/ActionsBuilder/actionsbuilder.parameters.ts
  29. 80 0
      Exporters/3ds Max/ActionsBuilder/actionsbuilder.toolbar.js
  30. 93 93
      Exporters/3ds Max/ActionsBuilder/actionsbuilder.toolbar.ts
  31. 326 326
      Exporters/3ds Max/ActionsBuilder/actionsbuilder.ts
  32. 370 0
      Exporters/3ds Max/ActionsBuilder/actionsbuilder.utils.js
  33. 526 526
      Exporters/3ds Max/ActionsBuilder/actionsbuilder.utils.ts
  34. 539 0
      Exporters/3ds Max/ActionsBuilder/actionsbuilder.viewer.js
  35. 772 772
      Exporters/3ds Max/ActionsBuilder/actionsbuilder.viewer.ts
  36. 42 42
      Exporters/3ds Max/ActionsBuilder/gulpfile.js
  37. 10 11
      Exporters/3ds Max/ActionsBuilder/package.json
  38. 69 69
      Exporters/3ds Max/ActionsBuilder/raphaeljs.d.ts
  39. 31 0
      Exporters/3ds Max/ActionsBuilder/web.Debug.config
  40. 32 0
      Exporters/3ds Max/ActionsBuilder/web.Release.config
  41. 11 0
      Exporters/3ds Max/ActionsBuilder/web.config
  42. 3 0
      Exporters/3ds Max/BabylonExport.Entities/BabylonAbstractMesh.cs
  43. 17 0
      Exporters/3ds Max/BabylonExport.Entities/BabylonExport.Entities.csproj
  44. 0 3
      Exporters/3ds Max/BabylonExport.Entities/BabylonMesh.cs
  45. 3 3
      Exporters/3ds Max/BabylonExport.Entities/packages.config
  46. 66 0
      Exporters/3ds Max/BabylonFileConverter/BabylonFileConverter.csproj
  47. 374 0
      Exporters/3ds Max/BabylonFileConverter/BinaryConverter.cs
  48. 36 0
      Exporters/3ds Max/BabylonFileConverter/Properties/AssemblyInfo.cs
  49. 4 0
      Exporters/3ds Max/BabylonFileConverter/packages.config
  50. BIN
      Exporters/3ds Max/Max2Babylon-0.5.0.zip
  51. 223 34
      Exporters/3ds Max/Max2Babylon.sln
  52. 273 293
      Exporters/3ds Max/Max2Babylon/2015/Max2Babylon2015.csproj
  53. 36 36
      Exporters/3ds Max/Max2Babylon/2015/Properties/AssemblyInfo.cs
  54. 63 63
      Exporters/3ds Max/Max2Babylon/2015/Properties/Resources.Designer.cs
  55. 119 119
      Exporters/3ds Max/Max2Babylon/2015/Properties/Resources.resx
  56. 6 0
      Exporters/3ds Max/Max2Babylon/2015/packages.config
  57. 9 12
      Exporters/3ds Max/Max2Babylon/2017/Max2Babylon2017.csproj
  58. 6 0
      Exporters/3ds Max/Max2Babylon/2017/packages.config
  59. 0 80
      Exporters/3ds Max/Max2Babylon/BabylonActionsBuilderActionItem.cs
  60. 95 95
      Exporters/3ds Max/Max2Babylon/Exporter/ActionBuilder/BabylonActionsBuilderActionItem.cs
  61. 27 27
      Exporters/3ds Max/Max2Babylon/Exporter/ActionBuilder/BabylonExporter.Action.cs
  62. 5 0
      Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Mesh.cs
  63. 208 187
      Exporters/3ds Max/Max2Babylon/Max2Babylon.csproj
  64. 36 36
      Exporters/3ds Max/Max2Babylon/Properties/AssemblyInfo.cs
  65. 63 63
      Exporters/3ds Max/Max2Babylon/Properties/Resources.Designer.cs
  66. 119 119
      Exporters/3ds Max/Max2Babylon/Properties/Resources.resx
  67. BIN
      Exporters/3ds Max/Max2Babylon/Refs/BabylonFileConverter.dll
  68. BIN
      Exporters/3ds Max/Max2Babylon/Refs/Newtonsoft.Json.dll
  69. BIN
      Exporters/3ds Max/Max2Babylon/Refs/SharpDX.dll
  70. 1 0
      Exporters/3ds Max/Max2Babylon/Tools/WebServer.cs
  71. 5 3
      Exporters/3ds Max/Max2Babylon/packages.config
  72. BIN
      Exporters/3ds Max/Refs/Autodesk.Max.dll
  73. 8 8
      dist/preview release/babylon.core.js
  74. 3251 3054
      dist/preview release/babylon.d.ts
  75. 9 9
      dist/preview release/babylon.js
  76. 208 9
      dist/preview release/babylon.max.js
  77. 14868 0
      dist/preview release/babylon.module.d.ts
  78. 8 8
      dist/preview release/babylon.noworker.js

+ 132 - 0
Exporters/3ds Max/ActionsBuilder/ActionsBuilder.csproj

@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.Default.props" Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.Default.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <ProjectGuid>{293A754C-3D80-42FB-99D8-7C9386CD297E}</ProjectGuid>
+    <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
+    <OutputType>Library</OutputType>
+    <OutputPath>bin</OutputPath>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <DebugType>full</DebugType>
+    <DebugSymbols>true</DebugSymbols>
+    <TypeScriptToolsVersion>2.1</TypeScriptToolsVersion>
+    <UseIISExpress>true</UseIISExpress>
+    <IISExpressSSLPort />
+    <IISExpressAnonymousAuthentication />
+    <IISExpressWindowsAuthentication />
+    <IISExpressUseClassicPipelineMode />
+    <SccProjectName>SAK</SccProjectName>
+    <SccLocalPath>SAK</SccLocalPath>
+    <SccAuxPath>SAK</SccAuxPath>
+    <SccProvider>SAK</SccProvider>
+    <UseGlobalApplicationHostFile />
+  </PropertyGroup>
+  <ItemGroup>
+    <Content Include="gulpfile.js" />
+    <Content Include="Sources\fonts\SinkinSans\SinkinSans-300Light.svg" />
+    <Content Include="Sources\fonts\SinkinSans\SinkinSans-300LightItalic.svg" />
+    <Content Include="Sources\fonts\SinkinSans\SinkinSans-500Medium.svg" />
+    <Content Include="Sources\fonts\SinkinSans\SinkinSans-600SemiBold.svg" />
+    <Content Include="Sources\index-debug.html" />
+    <Content Include="Sources\index.css" />
+    <Content Include="Sources\fonts.css" />
+    <Content Include="Sources\index.html" />
+    <Content Include="Sources\raphael.js" />
+    <Content Include="web.config" />
+  </ItemGroup>
+  <ItemGroup>
+    <TypeScriptCompile Include="..\..\..\dist\preview release\babylon.d.ts">
+      <Link>babylon.d.ts</Link>
+    </TypeScriptCompile>
+    <TypeScriptCompile Include="actionsbuilder.actionNode.ts" />
+    <TypeScriptCompile Include="actionsbuilder.contextMenu.ts" />
+    <TypeScriptCompile Include="actionsbuilder.list.ts" />
+    <TypeScriptCompile Include="actionsbuilder.main.ts" />
+    <TypeScriptCompile Include="actionsbuilder.parameters.ts" />
+    <TypeScriptCompile Include="actionsbuilder.toolbar.ts" />
+    <TypeScriptCompile Include="actionsbuilder.ts" />
+    <TypeScriptCompile Include="actionsbuilder.utils.ts" />
+    <TypeScriptCompile Include="actionsbuilder.viewer.ts" />
+    <TypeScriptCompile Include="raphaeljs.d.ts" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="package.json" />
+    <Content Include="Sources\fonts\SinkinSans\SinkinSans-300Light.eot" />
+    <Content Include="Sources\fonts\SinkinSans\SinkinSans-300Light.otf" />
+    <Content Include="Sources\fonts\SinkinSans\SinkinSans-300Light.ttf" />
+    <Content Include="Sources\fonts\SinkinSans\SinkinSans-300Light.woff" />
+    <Content Include="Sources\fonts\SinkinSans\SinkinSans-300LightItalic.eot" />
+    <Content Include="Sources\fonts\SinkinSans\SinkinSans-300LightItalic.otf" />
+    <Content Include="Sources\fonts\SinkinSans\SinkinSans-300LightItalic.ttf" />
+    <Content Include="Sources\fonts\SinkinSans\SinkinSans-300LightItalic.woff" />
+    <Content Include="Sources\fonts\SinkinSans\SinkinSans-500Medium.eot" />
+    <Content Include="Sources\fonts\SinkinSans\SinkinSans-500Medium.otf" />
+    <Content Include="Sources\fonts\SinkinSans\SinkinSans-500Medium.ttf" />
+    <Content Include="Sources\fonts\SinkinSans\SinkinSans-500Medium.woff" />
+    <Content Include="Sources\fonts\SinkinSans\SinkinSans-600SemiBold.eot" />
+    <Content Include="Sources\fonts\SinkinSans\SinkinSans-600SemiBold.otf" />
+    <Content Include="Sources\fonts\SinkinSans\SinkinSans-600SemiBold.ttf" />
+    <Content Include="Sources\fonts\SinkinSans\SinkinSans-600SemiBold.woff" />
+    <None Include="web.Debug.config">
+      <DependentUpon>web.config</DependentUpon>
+    </None>
+    <None Include="web.Release.config">
+      <DependentUpon>web.config</DependentUpon>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+  </ItemGroup>
+  <ItemGroup>
+    <Folder Include="Properties\" />
+  </ItemGroup>
+  <PropertyGroup>
+    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">12.0</VisualStudioVersion>
+  </PropertyGroup>
+  <PropertyGroup>
+    <RootNamespace>ActionsBuilder</RootNamespace>
+  </PropertyGroup>
+  <PropertyGroup>
+    <RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
+  </PropertyGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\WebApplications\Microsoft.WebApplication.targets" Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\WebApplications\Microsoft.WebApplication.targets')" />
+  <ProjectExtensions>
+    <VisualStudio>
+      <FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
+        <WebProjectProperties>
+          <UseIIS>False</UseIIS>
+          <AutoAssignPort>True</AutoAssignPort>
+          <DevelopmentServerPort>51472</DevelopmentServerPort>
+          <DevelopmentServerVPath>/</DevelopmentServerVPath>
+          <IISUrl>http://localhost:51472/</IISUrl>
+          <NTLMAuthentication>False</NTLMAuthentication>
+          <UseCustomServer>False</UseCustomServer>
+          <CustomServerUrl>
+          </CustomServerUrl>
+          <SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
+        </WebProjectProperties>
+      </FlavorProperties>
+    </VisualStudio>
+  </ProjectExtensions>
+  <PropertyGroup Condition="'$(Configuration)' == 'Debug'">
+    <TypeScriptRemoveComments>false</TypeScriptRemoveComments>
+    <TypeScriptSourceMap>true</TypeScriptSourceMap>
+    <TypeScriptCompileOnSaveEnabled>True</TypeScriptCompileOnSaveEnabled>
+    <OutputPath>..\..\..\..\..\..\..\Program Files\Autodesk\3ds Max 2013\bin\assemblies\BabylonActionsBuilder\</OutputPath>
+    <TypeScriptOutDir>Sources\</TypeScriptOutDir>
+    <TypeScriptGeneratesDeclarations>False</TypeScriptGeneratesDeclarations>
+    <TypeScriptTarget>ES5</TypeScriptTarget>
+    <TypeScriptSourceRoot>$(SolutionDir)ActionsBuilder\</TypeScriptSourceRoot>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)' == 'Release'">
+    <TypeScriptRemoveComments>true</TypeScriptRemoveComments>
+    <TypeScriptSourceMap>false</TypeScriptSourceMap>
+  </PropertyGroup>
+  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.targets" Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.targets')" />
+  <PropertyGroup>
+    <PostBuildEvent>copy "$(SolutionDir)..\..\dist\preview release\babylon.max.js" "$(SolutionDir)ActionsBuilder\Sources\babylon.max.js"
+if $(ConfigurationName) == Release gulp</PostBuildEvent>
+  </PropertyGroup>
+</Project>

+ 0 - 42
Exporters/3ds Max/ActionsBuilder/README.md

@@ -1,42 +0,0 @@
-Babylon.js Actions Builder
-==========
-
-The Actions Builder is a part of the 3ds Max plugin ([Max2Babylon](https://github.com/BabylonJS/Babylon.js/tree/master/Exporters/3ds%20Max))
-that allows to build actions without any line of code.
-
-Tutorial and informations about the Actions Builder [here](https://medium.com/babylon-js/actions-builder-b05e72aa541a)
-
-Built files are located in "./Sources"
-
-# Install and Build files
-
-### Install dependencies:
-```
-npm install
-```
-
-### Build Actions Builder:
-```
-gulp
-```
-
-### Build JS files from their respective TS files:
-```
-gulp debug
-```
-
-### Build on save:
-```
-gulp watch
-```
-
-### Update gulpfile.js to add your own files:
-```
-var files = [
-    // Files
-    ...
-    "file1.js",
-    "file2.js",
-    ...
-];
-```

+ 86 - 86
Exporters/3ds Max/ActionsBuilder/Sources/actionsbuilder.actionNode.js

@@ -1,87 +1,87 @@
-var ActionsBuilder;
-(function (ActionsBuilder) {
-    var Node = (function () {
-        function Node() {
-            this.rect = null;
-            this.text = null;
-            this.line = null;
-            this.detached = false;
-            this.minimized = false;
-        }
-        /**
-        * Returns if the point (x, y) is inside the text or rect
-        * @param x: the x position of the point
-        * @param y: the y position of the point
-        */
-        Node.prototype.isPointInside = function (x, y) {
-            return this.rect.isPointInside(x, y) || this.text.isPointInside(x, y);
-        };
-        return Node;
-    })();
-    ActionsBuilder.Node = Node;
-    var Action = (function () {
-        /**
-        * Constructor
-        * @param node: The associated node to draw in the viewer
-        */
-        function Action(node) {
-            this.parent = null;
-            this.children = new Array();
-            this.name = "";
-            this.type = ActionsBuilder.Type.OBJECT;
-            this.properties = new Array();
-            this.propertiesResults = new Array();
-            this.combineArray = null;
-            this.hub = null;
-            this.combineAction = null;
-            this.node = node;
-        }
-        /*
-        * Removes a combined action from the combine array
-        * @param action: the action to remove
-        */
-        Action.prototype.removeCombinedAction = function (action) {
-            if (action === null || this.combineArray === null) {
-                return false;
-            }
-            var index = this.combineArray.indexOf(action);
-            if (index !== -1) {
-                this.combineArray.splice(index, 1);
-            }
-            return false;
-        };
-        /*
-        * Adds a child
-        * @param child: the action to add as child
-        */
-        Action.prototype.addChild = function (child) {
-            if (child === null) {
-                return false;
-            }
-            this.children.push(child);
-            child.parent = this;
-            return true;
-        };
-        /*
-        * Removes the given action to children
-        * @param child: the child to remove
-        */
-        Action.prototype.removeChild = function (child) {
-            var indice = this.children.indexOf(child);
-            if (indice !== -1) {
-                this.children.splice(indice, 1);
-                return true;
-            }
-            return false;
-        };
-        /*
-        * Clears the children's array
-        */
-        Action.prototype.clearChildren = function () {
-            this.children = new Array();
-        };
-        return Action;
-    })();
-    ActionsBuilder.Action = Action;
-})(ActionsBuilder || (ActionsBuilder = {}));
+var ActionsBuilder;
+(function (ActionsBuilder) {
+    var Node = (function () {
+        function Node() {
+            this.rect = null;
+            this.text = null;
+            this.line = null;
+            this.detached = false;
+            this.minimized = false;
+        }
+        /**
+        * Returns if the point (x, y) is inside the text or rect
+        * @param x: the x position of the point
+        * @param y: the y position of the point
+        */
+        Node.prototype.isPointInside = function (x, y) {
+            return this.rect.isPointInside(x, y) || this.text.isPointInside(x, y);
+        };
+        return Node;
+    }());
+    ActionsBuilder.Node = Node;
+    var Action = (function () {
+        /**
+        * Constructor
+        * @param node: The associated node to draw in the viewer
+        */
+        function Action(node) {
+            this.parent = null;
+            this.children = new Array();
+            this.name = "";
+            this.type = ActionsBuilder.Type.OBJECT;
+            this.properties = new Array();
+            this.propertiesResults = new Array();
+            this.combineArray = null;
+            this.hub = null;
+            this.combineAction = null;
+            this.node = node;
+        }
+        /*
+        * Removes a combined action from the combine array
+        * @param action: the action to remove
+        */
+        Action.prototype.removeCombinedAction = function (action) {
+            if (action === null || this.combineArray === null) {
+                return false;
+            }
+            var index = this.combineArray.indexOf(action);
+            if (index !== -1) {
+                this.combineArray.splice(index, 1);
+            }
+            return false;
+        };
+        /*
+        * Adds a child
+        * @param child: the action to add as child
+        */
+        Action.prototype.addChild = function (child) {
+            if (child === null) {
+                return false;
+            }
+            this.children.push(child);
+            child.parent = this;
+            return true;
+        };
+        /*
+        * Removes the given action to children
+        * @param child: the child to remove
+        */
+        Action.prototype.removeChild = function (child) {
+            var indice = this.children.indexOf(child);
+            if (indice !== -1) {
+                this.children.splice(indice, 1);
+                return true;
+            }
+            return false;
+        };
+        /*
+        * Clears the children's array
+        */
+        Action.prototype.clearChildren = function () {
+            this.children = new Array();
+        };
+        return Action;
+    }());
+    ActionsBuilder.Action = Action;
+})(ActionsBuilder || (ActionsBuilder = {}));
 //# sourceMappingURL=actionsbuilder.actionNode.js.map

+ 118 - 118
Exporters/3ds Max/ActionsBuilder/Sources/actionsbuilder.contextMenu.js

@@ -1,119 +1,119 @@
-var ActionsBuilder;
-(function (ActionsBuilder) {
-    var ContextMenu = (function () {
-        /*
-        * Constructor
-        * @param viewer: the graph viewer
-        */
-        function ContextMenu(viewer) {
-            this.showing = false;
-            this.savedColor = Raphael.rgb(255, 255, 255);
-            this.overColor = Raphael.rgb(140, 200, 230);
-            this._viewer = null;
-            this.elements = [
-                { text: "Reduce", node: null, action: "onReduce" },
-                { text: "Delete", node: null, action: "onRemoveNode" },
-                { text: "Delete branch", node: null, action: "onRemoveBranch" },
-                { text: "Connect / Disconnect", node: null, action: "onDetachAction" },
-                { text: "Copy", node: null, action: "onCopyStructure" },
-                { text: "Paste", node: null, action: "onPasteStructure" },
-                // Add other elements here
-                { text: "", node: null, action: null } // Color separator (top)
-            ];
-            // Members
-            this._viewer = viewer;
-            // Configure
-            this.attachControl(this._viewer.paper.canvas);
-        }
-        ContextMenu.prototype.attachControl = function (element) {
-            var _this = this;
-            var onClick = function (event) {
-                var x = _this._viewer.mousex;
-                var y = _this._viewer.mousey;
-                // Remove all context menu nodes, and run action if selected
-                if (_this.showing) {
-                    for (var i = 0; i < _this.elements.length; i++) {
-                        var element = _this.elements[i];
-                        if (element.action && element.node.rect.isPointInside(x, y)) {
-                            _this._viewer.utils[element.action]();
-                            _this._viewer.update();
-                        }
-                        element.node.rect.remove();
-                        element.node.text.remove();
-                    }
-                }
-                _this.showing = false;
-            };
-            var onMouseMove = function (event) {
-                // Override context menu's node color if mouse is inside
-                if (_this.showing) {
-                    for (var i = 0; i < _this.elements.length; i++) {
-                        var element = _this.elements[i];
-                        if (element.text === "")
-                            continue;
-                        var x = _this._viewer.mousex;
-                        var y = _this._viewer.mousey;
-                        if (element.node.rect.isPointInside(x, y)) {
-                            element.node.rect.attr("fill", _this.overColor);
-                        }
-                        else {
-                            element.node.rect.attr("fill", _this.savedColor);
-                        }
-                    }
-                }
-            };
-            var onRightClick = function (event) {
-                var x = _this._viewer.mousex;
-                var y = _this._viewer.mousey;
-                _this._viewer.onClick(event);
-                // Set selected node
-                var result = _this._viewer.traverseGraph(null, x, y, true);
-                if (result.hit) {
-                }
-                // Properly draw the context menu on the screen
-                if (y + (ActionsBuilder.Viewer.NODE_HEIGHT * _this.elements.length) > _this._viewer.viewerElement.offsetHeight + _this._viewer.viewerElement.scrollTop) {
-                    y = (ActionsBuilder.Viewer.NODE_HEIGHT * _this.elements.length);
-                }
-                if (x + ActionsBuilder.Viewer.NODE_WIDTH > _this._viewer.viewerElement.offsetWidth + _this._viewer.viewerElement.scrollLeft) {
-                    x -= ActionsBuilder.Viewer.NODE_WIDTH;
-                }
-                if (!_this.showing) {
-                    if (_this._viewer.selectedNode === null)
-                        return;
-                    // Create elements
-                    var yOffset = 10;
-                    for (var i = 0; i < _this.elements.length - 1; i++) {
-                        var element = _this.elements[i];
-                        element.node = _this._viewer._createNode(element.text, ActionsBuilder.Type.OBJECT, true);
-                        element.node.rect.attr("fill", Raphael.rgb(216, 216, 216));
-                        element.node.rect.attr("x", x);
-                        element.node.rect.attr("y", y + yOffset);
-                        element.node.text.attr("x", x + 5);
-                        element.node.text.attr("y", y + yOffset + element.node.rect.attr("height") / 2);
-                        yOffset += ActionsBuilder.Viewer.NODE_HEIGHT;
-                    }
-                    // Color separator
-                    var separator = _this.elements[_this.elements.length - 1];
-                    separator.node = _this._viewer._createNode("", ActionsBuilder.Type.OBJECT, true);
-                    separator.node.rect.attr("fill", _this._viewer.getNodeColor(_this._viewer.selectedNode.type, _this._viewer.selectedNode.node.detached));
-                    separator.node.rect.attr("x", x);
-                    separator.node.rect.attr("y", y);
-                    separator.node.rect.attr("height", 10);
-                    // Finish
-                    _this.showing = true;
-                }
-                else {
-                    onClick(event);
-                    onRightClick(event);
-                }
-                window.event.returnValue = false;
-            };
-            document.addEventListener("click", onClick);
-            document.addEventListener("mousemove", onMouseMove);
-            element.addEventListener("contextmenu", onRightClick);
-        };
-        return ContextMenu;
-    })();
-    ActionsBuilder.ContextMenu = ContextMenu;
-})(ActionsBuilder || (ActionsBuilder = {}));
+var ActionsBuilder;
+(function (ActionsBuilder) {
+    var ContextMenu = (function () {
+        /*
+        * Constructor
+        * @param viewer: the graph viewer
+        */
+        function ContextMenu(viewer) {
+            this.showing = false;
+            this.savedColor = Raphael.rgb(255, 255, 255);
+            this.overColor = Raphael.rgb(140, 200, 230);
+            this._viewer = null;
+            this.elements = [
+                { text: "Reduce", node: null, action: "onReduce" },
+                { text: "Delete", node: null, action: "onRemoveNode" },
+                { text: "Delete branch", node: null, action: "onRemoveBranch" },
+                { text: "Connect / Disconnect", node: null, action: "onDetachAction" },
+                { text: "Copy", node: null, action: "onCopyStructure" },
+                { text: "Paste", node: null, action: "onPasteStructure" },
+                // Add other elements here
+                { text: "", node: null, action: null } // Color separator (top)
+            ];
+            // Members
+            this._viewer = viewer;
+            // Configure
+            this.attachControl(this._viewer.paper.canvas);
+        }
+        ContextMenu.prototype.attachControl = function (element) {
+            var _this = this;
+            var onClick = function (event) {
+                var x = _this._viewer.mousex;
+                var y = _this._viewer.mousey;
+                // Remove all context menu nodes, and run action if selected
+                if (_this.showing) {
+                    for (var i = 0; i < _this.elements.length; i++) {
+                        var element = _this.elements[i];
+                        if (element.action && element.node.rect.isPointInside(x, y)) {
+                            _this._viewer.utils[element.action]();
+                            _this._viewer.update();
+                        }
+                        element.node.rect.remove();
+                        element.node.text.remove();
+                    }
+                }
+                _this.showing = false;
+            };
+            var onMouseMove = function (event) {
+                // Override context menu's node color if mouse is inside
+                if (_this.showing) {
+                    for (var i = 0; i < _this.elements.length; i++) {
+                        var element = _this.elements[i];
+                        if (element.text === "")
+                            continue;
+                        var x = _this._viewer.mousex;
+                        var y = _this._viewer.mousey;
+                        if (element.node.rect.isPointInside(x, y)) {
+                            element.node.rect.attr("fill", _this.overColor);
+                        }
+                        else {
+                            element.node.rect.attr("fill", _this.savedColor);
+                        }
+                    }
+                }
+            };
+            var onRightClick = function (event) {
+                var x = _this._viewer.mousex;
+                var y = _this._viewer.mousey;
+                _this._viewer.onClick(event);
+                // Set selected node
+                var result = _this._viewer.traverseGraph(null, x, y, true);
+                if (result.hit) {
+                }
+                // Properly draw the context menu on the screen
+                if (y + (ActionsBuilder.Viewer.NODE_HEIGHT * _this.elements.length) > _this._viewer.viewerElement.offsetHeight + _this._viewer.viewerElement.scrollTop) {
+                    y = (ActionsBuilder.Viewer.NODE_HEIGHT * _this.elements.length);
+                }
+                if (x + ActionsBuilder.Viewer.NODE_WIDTH > _this._viewer.viewerElement.offsetWidth + _this._viewer.viewerElement.scrollLeft) {
+                    x -= ActionsBuilder.Viewer.NODE_WIDTH;
+                }
+                if (!_this.showing) {
+                    if (_this._viewer.selectedNode === null)
+                        return;
+                    // Create elements
+                    var yOffset = 10;
+                    for (var i = 0; i < _this.elements.length - 1; i++) {
+                        var element = _this.elements[i];
+                        element.node = _this._viewer._createNode(element.text, ActionsBuilder.Type.OBJECT, true);
+                        element.node.rect.attr("fill", Raphael.rgb(216, 216, 216));
+                        element.node.rect.attr("x", x);
+                        element.node.rect.attr("y", y + yOffset);
+                        element.node.text.attr("x", x + 5);
+                        element.node.text.attr("y", y + yOffset + element.node.rect.attr("height") / 2);
+                        yOffset += ActionsBuilder.Viewer.NODE_HEIGHT;
+                    }
+                    // Color separator
+                    var separator = _this.elements[_this.elements.length - 1];
+                    separator.node = _this._viewer._createNode("", ActionsBuilder.Type.OBJECT, true);
+                    separator.node.rect.attr("fill", _this._viewer.getNodeColor(_this._viewer.selectedNode.type, _this._viewer.selectedNode.node.detached));
+                    separator.node.rect.attr("x", x);
+                    separator.node.rect.attr("y", y);
+                    separator.node.rect.attr("height", 10);
+                    // Finish
+                    _this.showing = true;
+                }
+                else {
+                    onClick(event);
+                    onRightClick(event);
+                }
+                window.event.returnValue = false;
+            };
+            document.addEventListener("click", onClick);
+            document.addEventListener("mousemove", onMouseMove);
+            element.addEventListener("contextmenu", onRightClick);
+        };
+        return ContextMenu;
+    }());
+    ActionsBuilder.ContextMenu = ContextMenu;
+})(ActionsBuilder || (ActionsBuilder = {}));
 //# sourceMappingURL=actionsbuilder.contextMenu.js.map

+ 351 - 351
Exporters/3ds Max/ActionsBuilder/Sources/actionsbuilder.js

@@ -1,352 +1,352 @@
-var ActionsBuilder;
-(function (ActionsBuilder) {
-    /**
-    * Defines static types
-    */
-    var Type = (function () {
-        function Type() {
-        }
-        Object.defineProperty(Type, "TRIGGER", {
-            get: function () {
-                return Type._TRIGGER;
-            },
-            enumerable: true,
-            configurable: true
-        });
-        Object.defineProperty(Type, "ACTION", {
-            get: function () {
-                return Type._ACTION;
-            },
-            enumerable: true,
-            configurable: true
-        });
-        Object.defineProperty(Type, "FLOW_CONTROL", {
-            get: function () {
-                return Type._FLOW_CONTROL;
-            },
-            enumerable: true,
-            configurable: true
-        });
-        Object.defineProperty(Type, "OBJECT", {
-            get: function () {
-                return Type._OBJECT;
-            },
-            enumerable: true,
-            configurable: true
-        });
-        Object.defineProperty(Type, "SCENE", {
-            get: function () {
-                return Type._SCENE;
-            },
-            enumerable: true,
-            configurable: true
-        });
-        Type._TRIGGER = 0;
-        Type._ACTION = 1;
-        Type._FLOW_CONTROL = 2;
-        Type._OBJECT = 3;
-        Type._SCENE = 4;
-        return Type;
-    })();
-    ActionsBuilder.Type = Type;
-    /*
-    * Defines the BABYLON.JS elements
-    */
-    var SceneElements = (function () {
-        function SceneElements() {
-        }
-        Object.defineProperty(SceneElements, "ENGINE", {
-            get: function () {
-                return SceneElements._ENGINE;
-            },
-            enumerable: true,
-            configurable: true
-        });
-        Object.defineProperty(SceneElements, "SCENE", {
-            get: function () {
-                return SceneElements._SCENE;
-            },
-            enumerable: true,
-            configurable: true
-        });
-        Object.defineProperty(SceneElements, "MESH", {
-            get: function () {
-                return SceneElements._MESH;
-            },
-            enumerable: true,
-            configurable: true
-        });
-        Object.defineProperty(SceneElements, "LIGHT", {
-            get: function () {
-                return SceneElements._LIGHT;
-            },
-            enumerable: true,
-            configurable: true
-        });
-        Object.defineProperty(SceneElements, "CAMERA", {
-            get: function () {
-                return SceneElements._CAMERA;
-            },
-            enumerable: true,
-            configurable: true
-        });
-        Object.defineProperty(SceneElements, "MESHES", {
-            get: function () {
-                return SceneElements._MESHES;
-            },
-            enumerable: true,
-            configurable: true
-        });
-        Object.defineProperty(SceneElements, "LIGHTS", {
-            get: function () {
-                return SceneElements._LIGHTS;
-            },
-            enumerable: true,
-            configurable: true
-        });
-        Object.defineProperty(SceneElements, "CAMERAS", {
-            get: function () {
-                return SceneElements._CAMERAS;
-            },
-            enumerable: true,
-            configurable: true
-        });
-        Object.defineProperty(SceneElements, "SOUNDS", {
-            get: function () {
-                return SceneElements._SOUNDS;
-            },
-            enumerable: true,
-            configurable: true
-        });
-        Object.defineProperty(SceneElements, "MESH_PROPERTIES", {
-            get: function () {
-                return SceneElements._MESH_PROPERTIES;
-            },
-            enumerable: true,
-            configurable: true
-        });
-        Object.defineProperty(SceneElements, "LIGHT_PROPERTIES", {
-            get: function () {
-                return SceneElements._LIGHT_PROPERTIES;
-            },
-            enumerable: true,
-            configurable: true
-        });
-        Object.defineProperty(SceneElements, "CAMERA_PROPERTIES", {
-            get: function () {
-                return SceneElements._CAMERA_PROPERTIES;
-            },
-            enumerable: true,
-            configurable: true
-        });
-        Object.defineProperty(SceneElements, "SCENE_PROPERTIES", {
-            get: function () {
-                return SceneElements._SCENE_PROPERTIES;
-            },
-            enumerable: true,
-            configurable: true
-        });
-        Object.defineProperty(SceneElements, "TYPES", {
-            get: function () {
-                return SceneElements._TYPES;
-            },
-            enumerable: true,
-            configurable: true
-        });
-        Object.defineProperty(SceneElements, "OPERATORS", {
-            get: function () {
-                return SceneElements._OPERATORS;
-            },
-            enumerable: true,
-            configurable: true
-        });
-        /*
-        * Methods
-        */
-        SceneElements.GetInstanceOf = function (object) {
-            if (object === null || object === undefined) {
-                return "";
-            }
-            return object.constructor.toString().match(/function (\w*)/)[1];
-        };
-        SceneElements.TestInstanceOf = function (object, propertyName) {
-            if (object === null || object.constructor === null) {
-                return false;
-            }
-            if (propertyName.length > 0 && propertyName[0] === "_")
-                return false;
-            var name = SceneElements.GetInstanceOf(object);
-            for (var i = 0; i < SceneElements.TYPES.length; i++) {
-                if (name === SceneElements.TYPES[i]) {
-                    return true;
-                }
-            }
-            return false;
-        };
-        /*
-        * BabylonJS objects
-        */
-        SceneElements._ENGINE = new BABYLON.Engine(document.getElementById("RenderCanvasID"));
-        SceneElements._SCENE = new BABYLON.Scene(SceneElements.ENGINE);
-        SceneElements._MESH = new BABYLON.Mesh("mesh", SceneElements._SCENE);
-        SceneElements._LIGHT = new BABYLON.Light("light", SceneElements._SCENE);
-        SceneElements._CAMERA = new BABYLON.Camera("camera", BABYLON.Vector3.Zero(), SceneElements._SCENE);
-        /*
-        * Objects names
-        */
-        SceneElements._MESHES = new Array();
-        SceneElements._LIGHTS = new Array();
-        SceneElements._CAMERAS = new Array();
-        SceneElements._SOUNDS = new Array();
-        /*
-        * Properties
-        */
-        SceneElements._MESH_PROPERTIES = new Array();
-        SceneElements._LIGHT_PROPERTIES = new Array();
-        SceneElements._CAMERA_PROPERTIES = new Array();
-        SceneElements._SCENE_PROPERTIES = new Array();
-        /*
-        * Types
-        */
-        SceneElements._TYPES = new Array();
-        /*
-        * Operators
-        */
-        SceneElements._OPERATORS = new Array();
-        return SceneElements;
-    })();
-    ActionsBuilder.SceneElements = SceneElements;
-    // Functions
-    var specialTypes = [
-        "StandardMaterial"
-    ];
-    SceneElements.MESH.material = new BABYLON.StandardMaterial("material", SceneElements.SCENE);
-    var addSpecialType = function (object, properties, thing) {
-        for (var specialThing in object[thing]) {
-            if (object[thing].hasOwnProperty(specialThing) && SceneElements.TestInstanceOf(object[thing][specialThing], specialThing)) {
-                properties.push(thing + "." + specialThing);
-            }
-        }
-    };
-    // Configure types
-    SceneElements.TYPES.push("Color3");
-    SceneElements.TYPES.push("Boolean");
-    SceneElements.TYPES.push("Number");
-    SceneElements.TYPES.push("Vector2");
-    SceneElements.TYPES.push("Vector3");
-    SceneElements.TYPES.push("String");
-    // Configure operators
-    SceneElements.OPERATORS.push("IsEqual");
-    SceneElements.OPERATORS.push("IsDifferent");
-    SceneElements.OPERATORS.push("IsGreater");
-    SceneElements.OPERATORS.push("IsLesser");
-    // Configure properties
-    for (var thing in SceneElements.MESH) {
-        var instance = SceneElements.GetInstanceOf(SceneElements.MESH[thing]);
-        if (SceneElements.MESH.hasOwnProperty(thing)) {
-            if (specialTypes.indexOf(instance) !== -1) {
-                addSpecialType(SceneElements.MESH, SceneElements.MESH_PROPERTIES, thing);
-            }
-            else if (SceneElements.TestInstanceOf(SceneElements.MESH[thing], thing)) {
-                SceneElements.MESH_PROPERTIES.push(thing);
-            }
-        }
-    }
-    for (var thing in SceneElements.LIGHT) {
-        if (SceneElements.LIGHT.hasOwnProperty(thing) && SceneElements.TestInstanceOf(SceneElements.LIGHT[thing], thing)) {
-            SceneElements.LIGHT_PROPERTIES.push(thing);
-        }
-    }
-    for (var thing in SceneElements.CAMERA) {
-        if (SceneElements.CAMERA.hasOwnProperty(thing) && SceneElements.TestInstanceOf(SceneElements.CAMERA[thing], thing)) {
-            SceneElements.CAMERA_PROPERTIES.push(thing);
-        }
-    }
-    for (var thing in SceneElements.SCENE) {
-        if (SceneElements.SCENE.hasOwnProperty(thing) && SceneElements.TestInstanceOf(SceneElements.SCENE[thing], thing)) {
-            SceneElements.SCENE_PROPERTIES.push(thing);
-        }
-    }
-    /**
-    * Actions Builder elements (triggers, actions & flow controls) that are
-    * arrays of Element
-    */
-    var Elements = (function () {
-        function Elements() {
-        }
-        Object.defineProperty(Elements, "TRIGGERS", {
-            get: function () {
-                return Elements._TRIGGERS;
-            },
-            enumerable: true,
-            configurable: true
-        });
-        Object.defineProperty(Elements, "ACTIONS", {
-            get: function () {
-                return Elements._ACTIONS;
-            },
-            enumerable: true,
-            configurable: true
-        });
-        Object.defineProperty(Elements, "FLOW_CONTROLS", {
-            get: function () {
-                return Elements._FLOW_CONTROLS;
-            },
-            enumerable: true,
-            configurable: true
-        });
-        Elements.GetElementFromName = function (name) {
-            for (var i = 0; i < Elements.TRIGGERS.length; i++) {
-                if (Elements.TRIGGERS[i].name === name) {
-                    return Elements._TRIGGERS[i];
-                }
-            }
-            for (var i = 0; i < Elements.ACTIONS.length; i++) {
-                if (Elements.ACTIONS[i].name === name) {
-                    return Elements._ACTIONS[i];
-                }
-            }
-            for (var i = 0; i < Elements.FLOW_CONTROLS.length; i++) {
-                if (Elements.FLOW_CONTROLS[i].name === name) {
-                    return Elements._FLOW_CONTROLS[i];
-                }
-            }
-            return null;
-        };
-        Elements._TRIGGERS = new Array();
-        Elements._ACTIONS = new Array();
-        Elements._FLOW_CONTROLS = new Array();
-        return Elements;
-    })();
-    ActionsBuilder.Elements = Elements;
-    // Configure triggers
-    Elements.TRIGGERS.push({ name: "OnPickTrigger", text: "pick", properties: [], description: "When the user picks the edited mesh" });
-    Elements.TRIGGERS.push({ name: "OnLeftPickTrigger", text: "left pick", properties: [], description: "When the user picks the edited mesh using the left click" });
-    Elements.TRIGGERS.push({ name: "OnRightPickTrigger", text: "right pick", properties: [], description: "When the user picks the edited mesh using the right click" });
-    Elements.TRIGGERS.push({ name: "OnCenterPickTrigger", text: "center pick", properties: [], description: "When the user picks the edited mesh using the click of the mouse wheel" });
-    Elements.TRIGGERS.push({ name: "OnPointerOverTrigger", text: "pointer over", properties: [], description: "When the user's mouse is over the edited mesh" });
-    Elements.TRIGGERS.push({ name: "OnPointerOutTrigger", text: "pointer out", properties: [], description: "When the user's mouse is out of the edited mesh" });
-    Elements.TRIGGERS.push({ name: "OnEveryFrameTrigger", text: "every frame", properties: [], description: "This trigger is called each frame (only on scene)" });
-    Elements.TRIGGERS.push({ name: "OnIntersectionEnterTrigger", text: "intersection enter", properties: [{ targetType: "MeshProperties", text: "parameter", value: "Object name?" }], description: "When the edited mesh intersects the another mesh predefined in the options" });
-    Elements.TRIGGERS.push({ name: "OnIntersectionExitTrigger", text: "intersection exit", properties: [{ targetType: "MeshProperties", text: "parameter", value: "Object name?" }], description: "When the edited mesh exits intersection with the another mesh predefined in the options" });
-    Elements.TRIGGERS.push({ name: "OnKeyDownTrigger", text: "key down", properties: [{ targetType: null, text: "parameter:", value: "a" }], description: "When the user pressed a key (enter the key character, example: \"r\")" });
-    Elements.TRIGGERS.push({ name: "OnKeyUpTrigger", text: "key up", properties: [{ targetType: null, text: "parameter:", value: "a" }], description: "When the user unpressed a key (enter the key character, example: \"p\")" });
-    // Configure actions
-    Elements.ACTIONS.push({ name: "SwitchBooleanAction", text: "switch boolean", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "propertyPath", value: "" }], description: "Switches the boolean value of a given parameter of the target object: true to false, or false to true" });
-    Elements.ACTIONS.push({ name: "SetStateAction", text: "set state", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "value", value: "" }], description: "Sets a new state value for the target object (example: \"off\" or \"on\")" });
-    Elements.ACTIONS.push({ name: "SetValueAction", text: "set value", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "propertyPath", value: "" }, { text: "value", value: "" }], description: "Sets a new value to the specified parameter of the target object (example: position.x to 0.0)" });
-    Elements.ACTIONS.push({ name: "SetParentAction", text: "set parent", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "parent", value: "" }], description: "Sets the new parent of the target object (example: a mesh or a light)" });
-    Elements.ACTIONS.push({ name: "IncrementValueAction", text: "increment value", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "propertyPath", value: "" }, { text: "value", value: "" }], description: "Increments the value of the given parameter of the target object. The value can be negative. (example: increment position.x of 5.0)" });
-    Elements.ACTIONS.push({ name: "PlayAnimationAction", text: "play animation", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "from", value: "0" }, { text: "to", value: "150" }, { text: "loop", value: "false" }], description: "Plays an animation of the target object. Specify the start frame, the end frame and if the animation should loop." });
-    Elements.ACTIONS.push({ name: "StopAnimationAction", text: "stop animation", properties: [{ targetType: "MeshProperties", text: "target", value: "" }], description: "Stops the animations of the target object." });
-    Elements.ACTIONS.push({ name: "DoNothingAction", text: "do nothing", properties: [], description: "Does nothing, can be used to balance/equilibrate the actions graph." });
-    Elements.ACTIONS.push({ name: "InterpolateValueAction", text: "interpolate value", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "propertyPath", value: "" }, { text: "value", value: "0" }, { text: "duration", value: "1000" }, { text: "stopOtherAnimations", value: "false" }], description: "Creates an animation (key frames) that animates the target object by interpolating the given parameter of the target value." });
-    Elements.ACTIONS.push({ name: "PlaySoundAction", text: "play sound", properties: [{ text: "sound", value: "" }], description: "Plays the specified sound." });
-    Elements.ACTIONS.push({ name: "StopSoundAction", text: "stop sound", properties: [{ text: "sound", value: "" }], description: "Stops the specified sound." });
-    Elements.ACTIONS.push({ name: "CombineAction", text: "combine", properties: [], description: "Special action that combines multiple actions. The combined actions are executed at the same time. Drag'n'drop the new actions inside to combine actions." });
-    // Configure flow control
-    Elements.FLOW_CONTROLS.push({ name: "ValueCondition", text: "value condition", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "propertyPath", value: "" }, { text: "value", value: "" }, { text: "operator", value: SceneElements.OPERATORS[0] }], description: "A condition checking if a given value is equal, different, lesser or greater than the given parameter of the target object" });
-    Elements.FLOW_CONTROLS.push({ name: "StateCondition", text: "state condition", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "value", value: "" }], description: "A condition checking if the target object's state is equal to the given state. See \"set state\" action to set a state to an object." });
-    Elements.FLOW_CONTROLS.push({ name: "Hub", text: "hub", properties: [], description: "The hub is internally used by the Combine Action. It allows to add children to the Combine Action" });
-})(ActionsBuilder || (ActionsBuilder = {}));
+var ActionsBuilder;
+(function (ActionsBuilder) {
+    /**
+    * Defines static types
+    */
+    var Type = (function () {
+        function Type() {
+        }
+        Object.defineProperty(Type, "TRIGGER", {
+            get: function () {
+                return Type._TRIGGER;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(Type, "ACTION", {
+            get: function () {
+                return Type._ACTION;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(Type, "FLOW_CONTROL", {
+            get: function () {
+                return Type._FLOW_CONTROL;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(Type, "OBJECT", {
+            get: function () {
+                return Type._OBJECT;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(Type, "SCENE", {
+            get: function () {
+                return Type._SCENE;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        return Type;
+    }());
+    Type._TRIGGER = 0;
+    Type._ACTION = 1;
+    Type._FLOW_CONTROL = 2;
+    Type._OBJECT = 3;
+    Type._SCENE = 4;
+    ActionsBuilder.Type = Type;
+    /*
+    * Defines the BABYLON.JS elements
+    */
+    var SceneElements = (function () {
+        function SceneElements() {
+        }
+        Object.defineProperty(SceneElements, "ENGINE", {
+            get: function () {
+                return SceneElements._ENGINE;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(SceneElements, "SCENE", {
+            get: function () {
+                return SceneElements._SCENE;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(SceneElements, "MESH", {
+            get: function () {
+                return SceneElements._MESH;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(SceneElements, "LIGHT", {
+            get: function () {
+                return SceneElements._LIGHT;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(SceneElements, "CAMERA", {
+            get: function () {
+                return SceneElements._CAMERA;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(SceneElements, "MESHES", {
+            get: function () {
+                return SceneElements._MESHES;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(SceneElements, "LIGHTS", {
+            get: function () {
+                return SceneElements._LIGHTS;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(SceneElements, "CAMERAS", {
+            get: function () {
+                return SceneElements._CAMERAS;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(SceneElements, "SOUNDS", {
+            get: function () {
+                return SceneElements._SOUNDS;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(SceneElements, "MESH_PROPERTIES", {
+            get: function () {
+                return SceneElements._MESH_PROPERTIES;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(SceneElements, "LIGHT_PROPERTIES", {
+            get: function () {
+                return SceneElements._LIGHT_PROPERTIES;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(SceneElements, "CAMERA_PROPERTIES", {
+            get: function () {
+                return SceneElements._CAMERA_PROPERTIES;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(SceneElements, "SCENE_PROPERTIES", {
+            get: function () {
+                return SceneElements._SCENE_PROPERTIES;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(SceneElements, "TYPES", {
+            get: function () {
+                return SceneElements._TYPES;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(SceneElements, "OPERATORS", {
+            get: function () {
+                return SceneElements._OPERATORS;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        /*
+        * Methods
+        */
+        SceneElements.GetInstanceOf = function (object) {
+            if (object === null || object === undefined) {
+                return "";
+            }
+            return object.constructor.toString().match(/function (\w*)/)[1];
+        };
+        SceneElements.TestInstanceOf = function (object, propertyName) {
+            if (object === null || object.constructor === null) {
+                return false;
+            }
+            if (propertyName.length > 0 && propertyName[0] === "_")
+                return false;
+            var name = SceneElements.GetInstanceOf(object);
+            for (var i = 0; i < SceneElements.TYPES.length; i++) {
+                if (name === SceneElements.TYPES[i]) {
+                    return true;
+                }
+            }
+            return false;
+        };
+        return SceneElements;
+    }());
+    /*
+    * BabylonJS objects
+    */
+    SceneElements._ENGINE = new BABYLON.Engine(document.getElementById("RenderCanvasID"));
+    SceneElements._SCENE = new BABYLON.Scene(SceneElements.ENGINE);
+    SceneElements._MESH = new BABYLON.Mesh("mesh", SceneElements._SCENE);
+    SceneElements._LIGHT = new BABYLON.Light("light", SceneElements._SCENE);
+    SceneElements._CAMERA = new BABYLON.Camera("camera", BABYLON.Vector3.Zero(), SceneElements._SCENE);
+    /*
+    * Objects names
+    */
+    SceneElements._MESHES = new Array();
+    SceneElements._LIGHTS = new Array();
+    SceneElements._CAMERAS = new Array();
+    SceneElements._SOUNDS = new Array();
+    /*
+    * Properties
+    */
+    SceneElements._MESH_PROPERTIES = new Array();
+    SceneElements._LIGHT_PROPERTIES = new Array();
+    SceneElements._CAMERA_PROPERTIES = new Array();
+    SceneElements._SCENE_PROPERTIES = new Array();
+    /*
+    * Types
+    */
+    SceneElements._TYPES = new Array();
+    /*
+    * Operators
+    */
+    SceneElements._OPERATORS = new Array();
+    ActionsBuilder.SceneElements = SceneElements;
+    // Functions
+    var specialTypes = [
+        "StandardMaterial"
+    ];
+    SceneElements.MESH.material = new BABYLON.StandardMaterial("material", SceneElements.SCENE);
+    var addSpecialType = function (object, properties, thing) {
+        for (var specialThing in object[thing]) {
+            if (object[thing].hasOwnProperty(specialThing) && SceneElements.TestInstanceOf(object[thing][specialThing], specialThing)) {
+                properties.push(thing + "." + specialThing);
+            }
+        }
+    };
+    // Configure types
+    SceneElements.TYPES.push("Color3");
+    SceneElements.TYPES.push("Boolean");
+    SceneElements.TYPES.push("Number");
+    SceneElements.TYPES.push("Vector2");
+    SceneElements.TYPES.push("Vector3");
+    SceneElements.TYPES.push("String");
+    // Configure operators
+    SceneElements.OPERATORS.push("IsEqual");
+    SceneElements.OPERATORS.push("IsDifferent");
+    SceneElements.OPERATORS.push("IsGreater");
+    SceneElements.OPERATORS.push("IsLesser");
+    // Configure properties
+    for (var thing in SceneElements.MESH) {
+        var instance = SceneElements.GetInstanceOf(SceneElements.MESH[thing]);
+        if (SceneElements.MESH.hasOwnProperty(thing)) {
+            if (specialTypes.indexOf(instance) !== -1) {
+                addSpecialType(SceneElements.MESH, SceneElements.MESH_PROPERTIES, thing);
+            }
+            else if (SceneElements.TestInstanceOf(SceneElements.MESH[thing], thing)) {
+                SceneElements.MESH_PROPERTIES.push(thing);
+            }
+        }
+    }
+    for (var thing in SceneElements.LIGHT) {
+        if (SceneElements.LIGHT.hasOwnProperty(thing) && SceneElements.TestInstanceOf(SceneElements.LIGHT[thing], thing)) {
+            SceneElements.LIGHT_PROPERTIES.push(thing);
+        }
+    }
+    for (var thing in SceneElements.CAMERA) {
+        if (SceneElements.CAMERA.hasOwnProperty(thing) && SceneElements.TestInstanceOf(SceneElements.CAMERA[thing], thing)) {
+            SceneElements.CAMERA_PROPERTIES.push(thing);
+        }
+    }
+    for (var thing in SceneElements.SCENE) {
+        if (SceneElements.SCENE.hasOwnProperty(thing) && SceneElements.TestInstanceOf(SceneElements.SCENE[thing], thing)) {
+            SceneElements.SCENE_PROPERTIES.push(thing);
+        }
+    }
+    /**
+    * Actions Builder elements (triggers, actions & flow controls) that are
+    * arrays of Element
+    */
+    var Elements = (function () {
+        function Elements() {
+        }
+        Object.defineProperty(Elements, "TRIGGERS", {
+            get: function () {
+                return Elements._TRIGGERS;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(Elements, "ACTIONS", {
+            get: function () {
+                return Elements._ACTIONS;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(Elements, "FLOW_CONTROLS", {
+            get: function () {
+                return Elements._FLOW_CONTROLS;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Elements.GetElementFromName = function (name) {
+            for (var i = 0; i < Elements.TRIGGERS.length; i++) {
+                if (Elements.TRIGGERS[i].name === name) {
+                    return Elements._TRIGGERS[i];
+                }
+            }
+            for (var i = 0; i < Elements.ACTIONS.length; i++) {
+                if (Elements.ACTIONS[i].name === name) {
+                    return Elements._ACTIONS[i];
+                }
+            }
+            for (var i = 0; i < Elements.FLOW_CONTROLS.length; i++) {
+                if (Elements.FLOW_CONTROLS[i].name === name) {
+                    return Elements._FLOW_CONTROLS[i];
+                }
+            }
+            return null;
+        };
+        return Elements;
+    }());
+    Elements._TRIGGERS = new Array();
+    Elements._ACTIONS = new Array();
+    Elements._FLOW_CONTROLS = new Array();
+    ActionsBuilder.Elements = Elements;
+    // Configure triggers
+    Elements.TRIGGERS.push({ name: "OnPickTrigger", text: "pick", properties: [], description: "When the user picks the edited mesh" });
+    Elements.TRIGGERS.push({ name: "OnLeftPickTrigger", text: "left pick", properties: [], description: "When the user picks the edited mesh using the left click" });
+    Elements.TRIGGERS.push({ name: "OnRightPickTrigger", text: "right pick", properties: [], description: "When the user picks the edited mesh using the right click" });
+    Elements.TRIGGERS.push({ name: "OnCenterPickTrigger", text: "center pick", properties: [], description: "When the user picks the edited mesh using the click of the mouse wheel" });
+    Elements.TRIGGERS.push({ name: "OnPointerOverTrigger", text: "pointer over", properties: [], description: "When the user's mouse is over the edited mesh" });
+    Elements.TRIGGERS.push({ name: "OnPointerOutTrigger", text: "pointer out", properties: [], description: "When the user's mouse is out of the edited mesh" });
+    Elements.TRIGGERS.push({ name: "OnEveryFrameTrigger", text: "every frame", properties: [], description: "This trigger is called each frame (only on scene)" });
+    Elements.TRIGGERS.push({ name: "OnIntersectionEnterTrigger", text: "intersection enter", properties: [{ targetType: "MeshProperties", text: "parameter", value: "Object name?" }], description: "When the edited mesh intersects the another mesh predefined in the options" });
+    Elements.TRIGGERS.push({ name: "OnIntersectionExitTrigger", text: "intersection exit", properties: [{ targetType: "MeshProperties", text: "parameter", value: "Object name?" }], description: "When the edited mesh exits intersection with the another mesh predefined in the options" });
+    Elements.TRIGGERS.push({ name: "OnKeyDownTrigger", text: "key down", properties: [{ targetType: null, text: "parameter", value: "a" }], description: "When the user pressed a key (enter the key character, example: \"r\")" });
+    Elements.TRIGGERS.push({ name: "OnKeyUpTrigger", text: "key up", properties: [{ targetType: null, text: "parameter", value: "a" }], description: "When the user unpressed a key (enter the key character, example: \"p\")" });
+    // Configure actions
+    Elements.ACTIONS.push({ name: "SwitchBooleanAction", text: "switch boolean", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "propertyPath", value: "" }], description: "Switches the boolean value of a given parameter of the target object: true to false, or false to true" });
+    Elements.ACTIONS.push({ name: "SetStateAction", text: "set state", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "value", value: "" }], description: "Sets a new state value for the target object (example: \"off\" or \"on\")" });
+    Elements.ACTIONS.push({ name: "SetValueAction", text: "set value", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "propertyPath", value: "" }, { text: "value", value: "" }], description: "Sets a new value to the specified parameter of the target object (example: position.x to 0.0)" });
+    Elements.ACTIONS.push({ name: "SetParentAction", text: "set parent", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "parent", value: "" }], description: "Sets the new parent of the target object (example: a mesh or a light)" });
+    Elements.ACTIONS.push({ name: "IncrementValueAction", text: "increment value", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "propertyPath", value: "" }, { text: "value", value: "" }], description: "Increments the value of the given parameter of the target object. The value can be negative. (example: increment position.x of 5.0)" });
+    Elements.ACTIONS.push({ name: "PlayAnimationAction", text: "play animation", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "from", value: "0" }, { text: "to", value: "150" }, { text: "loop", value: "false" }], description: "Plays an animation of the target object. Specify the start frame, the end frame and if the animation should loop." });
+    Elements.ACTIONS.push({ name: "StopAnimationAction", text: "stop animation", properties: [{ targetType: "MeshProperties", text: "target", value: "" }], description: "Stops the animations of the target object." });
+    Elements.ACTIONS.push({ name: "DoNothingAction", text: "do nothing", properties: [], description: "Does nothing, can be used to balance/equilibrate the actions graph." });
+    Elements.ACTIONS.push({ name: "InterpolateValueAction", text: "interpolate value", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "propertyPath", value: "" }, { text: "value", value: "0" }, { text: "duration", value: "1000" }, { text: "stopOtherAnimations", value: "false" }], description: "Creates an animation (key frames) that animates the target object by interpolating the given parameter of the target value." });
+    Elements.ACTIONS.push({ name: "PlaySoundAction", text: "play sound", properties: [{ text: "sound", value: "" }], description: "Plays the specified sound." });
+    Elements.ACTIONS.push({ name: "StopSoundAction", text: "stop sound", properties: [{ text: "sound", value: "" }], description: "Stops the specified sound." });
+    Elements.ACTIONS.push({ name: "CombineAction", text: "combine", properties: [], description: "Special action that combines multiple actions. The combined actions are executed at the same time. Drag'n'drop the new actions inside to combine actions." });
+    // Configure flow control
+    Elements.FLOW_CONTROLS.push({ name: "ValueCondition", text: "value condition", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "propertyPath", value: "" }, { text: "value", value: "" }, { text: "operator", value: SceneElements.OPERATORS[0] }], description: "A condition checking if a given value is equal, different, lesser or greater than the given parameter of the target object" });
+    Elements.FLOW_CONTROLS.push({ name: "StateCondition", text: "state condition", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "value", value: "" }], description: "A condition checking if the target object's state is equal to the given state. See \"set state\" action to set a state to an object." });
+    Elements.FLOW_CONTROLS.push({ name: "Hub", text: "hub", properties: [], description: "The hub is internally used by the Combine Action. It allows to add children to the Combine Action" });
+})(ActionsBuilder || (ActionsBuilder = {}));
 //# sourceMappingURL=actionsbuilder.js.map

+ 255 - 255
Exporters/3ds Max/ActionsBuilder/Sources/actionsbuilder.list.js

@@ -1,256 +1,256 @@
-var ActionsBuilder;
-(function (ActionsBuilder) {
-    var ListElement = (function () {
-        function ListElement() {
-            this.rect = null;
-            this.text = null;
-            this.name = "";
-            this.type = ActionsBuilder.Type.TRIGGER;
-            this.element = null;
-        }
-        return ListElement;
-    })();
-    ActionsBuilder.ListElement = ListElement;
-    var List = (function () {
-        /**
-        * Constructor
-        */
-        function List(viewer) {
-            var _this = this;
-            this._listElements = new Array();
-            // Get HTML elements
-            this.listElement = document.getElementById("ListsElementID");
-            this.triggersElement = document.getElementById("TriggersListID");
-            this.actionsElement = document.getElementById("ActionsListID");
-            this.flowControlsElement = document.getElementById("FlowActionsListID");
-            this._parentContainer = document.getElementById("ParentContainerID");
-            // Configure this
-            this._viewer = viewer;
-            // Create elements (lists)
-            this.triggersList = Raphael("TriggersListID", (25 * screen.width) / 100, 400);
-            this.actionsList = Raphael("ActionsListID", (25 * screen.width) / 100, 400);
-            this.flowControlsList = Raphael("FlowActionsListID", (25 * screen.width) / 100, 400);
-            // Manage events
-            window.addEventListener("resize", function (event) {
-                _this.onResize(event);
-            });
-        }
-        Object.defineProperty(List, "ELEMENT_HEIGHT", {
-            get: function () {
-                return 25;
-            },
-            enumerable: true,
-            configurable: true
-        });
-        /**
-        * Resize event that resizes the list element dynamically
-        * @param event: the resize event
-        */
-        List.prototype.onResize = function (event) {
-            var tools = document.getElementById("ToolsButtonsID");
-            this.listElement.style.height = window.innerHeight - tools.getBoundingClientRect().height - 25 + "px";
-            var listElementWidth = this.listElement.getBoundingClientRect().width;
-            for (var i = 0; i < this._listElements.length; i++) {
-                var rect = this._listElements[i].rect;
-                rect.attr("width", listElementWidth - 40);
-            }
-            this.triggersList.setSize(listElementWidth, this.triggersList.height);
-            this.actionsList.setSize(listElementWidth, this.triggersList.height);
-            this.flowControlsList.setSize(listElementWidth, this.triggersList.height);
-        };
-        List.prototype.createListsElements = function () {
-            var excludedTriggers = [6, 9, 10];
-            var yPosition = 10;
-            var textColor = Raphael.rgb(61, 72, 76);
-            var whiteColor = Raphael.rgb(255, 255, 255);
-            var configureTitle = function (listElement, rectColor) {
-                listElement.text.attr("x", 15);
-                listElement.rect.attr("fill", rectColor);
-                listElement.text.attr("font-family", "Sinkin Sans Medium");
-                listElement.text.attr("font-size", "11");
-            };
-            // Create triggers
-            var triggers = this._createListElement(this.triggersList, yPosition, "TRIGGERS", ActionsBuilder.Type.TRIGGER, whiteColor, false);
-            yPosition += List.ELEMENT_HEIGHT;
-            configureTitle(triggers, Raphael.rgb(41, 129, 255));
-            for (var i = 0; i < ActionsBuilder.Elements.TRIGGERS.length; i++) {
-                var element = ActionsBuilder.Elements.TRIGGERS[i];
-                if (this._viewer.root.type === ActionsBuilder.Type.OBJECT && excludedTriggers.indexOf(i) !== -1) {
-                    continue;
-                }
-                else if (this._viewer.root.type === ActionsBuilder.Type.SCENE && excludedTriggers.indexOf(i) === -1) {
-                    continue;
-                }
-                var trigger = this._createListElement(this.triggersList, yPosition, element.text, ActionsBuilder.Type.TRIGGER, textColor, true, element);
-                trigger.rect.attr("fill", Raphael.rgb(133, 154, 185));
-                yPosition += List.ELEMENT_HEIGHT;
-            }
-            yPosition += List.ELEMENT_HEIGHT;
-            this.triggersElement.style.height = this.triggersList.canvas.style.height = yPosition + "px";
-            this._createCollapseAnimation(this.triggersList, this.triggersElement, triggers, yPosition);
-            // Create actions
-            yPosition = 10;
-            var actions = this._createListElement(this.actionsList, yPosition, "ACTIONS", ActionsBuilder.Type.ACTION, textColor, false);
-            yPosition += List.ELEMENT_HEIGHT;
-            configureTitle(actions, Raphael.rgb(255, 220, 42));
-            for (var i = 0; i < ActionsBuilder.Elements.ACTIONS.length; i++) {
-                var element = ActionsBuilder.Elements.ACTIONS[i];
-                var action = this._createListElement(this.actionsList, yPosition, element.text, ActionsBuilder.Type.ACTION, textColor, true, element);
-                action.rect.attr("fill", Raphael.rgb(182, 185, 132));
-                yPosition += List.ELEMENT_HEIGHT;
-            }
-            yPosition += List.ELEMENT_HEIGHT;
-            this.actionsElement.style.height = this.actionsList.canvas.style.height = yPosition + "px";
-            this._createCollapseAnimation(this.actionsList, this.actionsElement, actions, yPosition);
-            // Create flow controls
-            yPosition = 10;
-            var flowControls = this._createListElement(this.flowControlsList, yPosition, "FLOW CONTROLS", ActionsBuilder.Type.FLOW_CONTROL, whiteColor, false);
-            yPosition += List.ELEMENT_HEIGHT;
-            configureTitle(flowControls, Raphael.rgb(255, 41, 53));
-            for (var i = 0; i < ActionsBuilder.Elements.FLOW_CONTROLS.length - 1; i++) {
-                var element = ActionsBuilder.Elements.FLOW_CONTROLS[i];
-                var flowControl = this._createListElement(this.flowControlsList, yPosition, element.text, ActionsBuilder.Type.FLOW_CONTROL, textColor, true, element);
-                flowControl.rect.attr("fill", Raphael.rgb(185, 132, 140));
-                yPosition += List.ELEMENT_HEIGHT;
-            }
-            yPosition += List.ELEMENT_HEIGHT;
-            this.flowControlsElement.style.height = this.flowControlsList.canvas.style.height = yPosition + "px";
-            this._createCollapseAnimation(this.flowControlsList, this.flowControlsElement, flowControls, yPosition);
-        };
-        /**
-        * Clears the list of elements and removes the elements
-        */
-        List.prototype.clearLists = function () {
-            for (var i = 0; i < this._listElements.length; i++) {
-                this._removeListElement(this._listElements[i]);
-            }
-            this._listElements.splice(0, this._listElements.length - 1);
-        };
-        /**
-        * Sets the color theme of the lists
-        * @param color: the theme color
-        */
-        List.prototype.setColorTheme = function (color) {
-            this.triggersList.canvas.style.backgroundColor = color;
-            this.actionsList.canvas.style.backgroundColor = color;
-            this.flowControlsList.canvas.style.backgroundColor = color;
-        };
-        /**
-        * Creates a list element
-        * @param paper: the Raphael.js paper
-        * @param yPosition: the y position of the element
-        * @param text: the element text
-        * @param type: the element type (trigger, action, flow control)
-        * @param textColor: the text color
-        * @param drag: if the element should be drag'n'dropped
-        */
-        List.prototype._createListElement = function (paper, yPosition, text, type, textColor, drag, element) {
-            var object = new ListElement();
-            object.rect = paper.rect(10, yPosition, 300, List.ELEMENT_HEIGHT);
-            object.text = paper.text(30, yPosition + object.rect.attr("height") / 2, text);
-            object.text.attr("fill", textColor);
-            object.text.attr("text-anchor", "start");
-            object.text.attr("font-size", "12");
-            object.text.attr("text-anchor", "start");
-            object.text.attr("font-family", "Sinkin Sans Light");
-            if (drag) {
-                this._createListElementAnimation(object);
-            }
-            object.type = type;
-            object.element = element;
-            this._listElements.push(object);
-            return object;
-        };
-        /**
-        * Removes a list element
-        * @param element: the element to remove
-        */
-        List.prototype._removeListElement = function (element) {
-            element.rect.remove();
-            element.text.remove();
-        };
-        /*
-        * Creates the collapse animation of a list
-        * @param paper: the list paper
-        * @param htmlElement: the list div container
-        * @param element: the list element to click on
-        * @param expandedHeight: the height when the list is expanded
-        */
-        List.prototype._createCollapseAnimation = function (paper, htmlElement, element, expandedHeight) {
-            var onClick = function (event) {
-                var height = htmlElement.style.height;
-                if (height === expandedHeight + "px") {
-                    htmlElement.style.height = paper.canvas.style.height = 35 + "px";
-                }
-                else {
-                    htmlElement.style.height = paper.canvas.style.height = expandedHeight + "px";
-                }
-            };
-            element.rect.click(onClick);
-        };
-        /*
-        * Creates the animation of a list element
-        * @param element: the list element to animate
-        */
-        List.prototype._createListElementAnimation = function (element) {
-            var _this = this;
-            var onMove = function (dx, dy, x, y) { };
-            var onStart = function (x, y, event) {
-                _this._parentContainer.style.cursor = "copy";
-                element.rect.animate({
-                    x: -10,
-                    opacity: 0.25
-                }, 500, ">");
-                element.text.animate({
-                    x: 10,
-                    opacity: 0.25
-                }, 500, ">");
-            };
-            var onEnd = function (event) {
-                _this._parentContainer.style.cursor = "default";
-                element.rect.animate({
-                    x: 10,
-                    opacity: 1.0
-                }, 500, "<");
-                element.text.animate({
-                    x: 30,
-                    opacity: 1.0
-                }, 500, "<");
-                var dragResult = _this._viewer.traverseGraph(null, _this._viewer.mousex, _this._viewer.mousey, false);
-                if (dragResult.hit) {
-                    if (element.type === ActionsBuilder.Type.TRIGGER && dragResult.action !== _this._viewer.root) {
-                        alert("Triggers can be dragged only on the root node (the mesh)");
-                        return;
-                    }
-                    if (element.type === ActionsBuilder.Type.ACTION && dragResult.action === _this._viewer.root) {
-                        alert("Please add a trigger before.");
-                        return;
-                    }
-                    //if (element.type === Type.FLOW_CONTROL && (dragResult.action === this._viewer.root || (dragResult.action.type === Type.FLOW_CONTROL && dragResult.action.parent.hub === null))) {
-                    if (element.type === ActionsBuilder.Type.FLOW_CONTROL && dragResult.action === _this._viewer.root) {
-                        return;
-                    }
-                    if (element.type === ActionsBuilder.Type.FLOW_CONTROL && dragResult.action.combineArray !== null) {
-                        alert("A condition cannot be handled by a Combine Action.");
-                        return;
-                    }
-                    if ((element.type === ActionsBuilder.Type.FLOW_CONTROL || element.type === ActionsBuilder.Type.ACTION) && dragResult.action.type === ActionsBuilder.Type.TRIGGER && dragResult.action.children.length > 0) {
-                        alert("Triggers can have only one child. Please add another trigger of same type.");
-                        return;
-                    }
-                    if (!(dragResult.action.combineArray !== null) && dragResult.action.children.length > 0 && dragResult.action.type !== ActionsBuilder.Type.TRIGGER && dragResult.action !== _this._viewer.root) {
-                        alert("An action can have only one child.");
-                        return;
-                    }
-                    _this._viewer.addAction(dragResult.action, element.type, element.element);
-                    _this._viewer.update();
-                }
-            };
-            element.rect.drag(onMove, onStart, onEnd);
-            element.text.drag(onMove, onStart, onEnd);
-        };
-        return List;
-    })();
-    ActionsBuilder.List = List;
-})(ActionsBuilder || (ActionsBuilder = {}));
+var ActionsBuilder;
+(function (ActionsBuilder) {
+    var ListElement = (function () {
+        function ListElement() {
+            this.rect = null;
+            this.text = null;
+            this.name = "";
+            this.type = ActionsBuilder.Type.TRIGGER;
+            this.element = null;
+        }
+        return ListElement;
+    }());
+    ActionsBuilder.ListElement = ListElement;
+    var List = (function () {
+        /**
+        * Constructor
+        */
+        function List(viewer) {
+            var _this = this;
+            this._listElements = new Array();
+            // Get HTML elements
+            this.listElement = document.getElementById("ListsElementID");
+            this.triggersElement = document.getElementById("TriggersListID");
+            this.actionsElement = document.getElementById("ActionsListID");
+            this.flowControlsElement = document.getElementById("FlowActionsListID");
+            this._parentContainer = document.getElementById("ParentContainerID");
+            // Configure this
+            this._viewer = viewer;
+            // Create elements (lists)
+            this.triggersList = Raphael("TriggersListID", (25 * screen.width) / 100, 400);
+            this.actionsList = Raphael("ActionsListID", (25 * screen.width) / 100, 400);
+            this.flowControlsList = Raphael("FlowActionsListID", (25 * screen.width) / 100, 400);
+            // Manage events
+            window.addEventListener("resize", function (event) {
+                _this.onResize(event);
+            });
+        }
+        Object.defineProperty(List, "ELEMENT_HEIGHT", {
+            get: function () {
+                return 25;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        /**
+        * Resize event that resizes the list element dynamically
+        * @param event: the resize event
+        */
+        List.prototype.onResize = function (event) {
+            var tools = document.getElementById("ToolsButtonsID");
+            this.listElement.style.height = window.innerHeight - tools.getBoundingClientRect().height - 25 + "px";
+            var listElementWidth = this.listElement.getBoundingClientRect().width;
+            for (var i = 0; i < this._listElements.length; i++) {
+                var rect = this._listElements[i].rect;
+                rect.attr("width", listElementWidth - 40);
+            }
+            this.triggersList.setSize(listElementWidth, this.triggersList.height);
+            this.actionsList.setSize(listElementWidth, this.triggersList.height);
+            this.flowControlsList.setSize(listElementWidth, this.triggersList.height);
+        };
+        List.prototype.createListsElements = function () {
+            var excludedTriggers = [6, 9, 10];
+            var yPosition = 10;
+            var textColor = Raphael.rgb(61, 72, 76);
+            var whiteColor = Raphael.rgb(255, 255, 255);
+            var configureTitle = function (listElement, rectColor) {
+                listElement.text.attr("x", 15);
+                listElement.rect.attr("fill", rectColor);
+                listElement.text.attr("font-family", "Sinkin Sans Medium");
+                listElement.text.attr("font-size", "11");
+            };
+            // Create triggers
+            var triggers = this._createListElement(this.triggersList, yPosition, "TRIGGERS", ActionsBuilder.Type.TRIGGER, whiteColor, false);
+            yPosition += List.ELEMENT_HEIGHT;
+            configureTitle(triggers, Raphael.rgb(41, 129, 255));
+            for (var i = 0; i < ActionsBuilder.Elements.TRIGGERS.length; i++) {
+                var element = ActionsBuilder.Elements.TRIGGERS[i];
+                if (this._viewer.root.type === ActionsBuilder.Type.OBJECT && excludedTriggers.indexOf(i) !== -1) {
+                    continue;
+                }
+                else if (this._viewer.root.type === ActionsBuilder.Type.SCENE && excludedTriggers.indexOf(i) === -1) {
+                    continue;
+                }
+                var trigger = this._createListElement(this.triggersList, yPosition, element.text, ActionsBuilder.Type.TRIGGER, textColor, true, element);
+                trigger.rect.attr("fill", Raphael.rgb(133, 154, 185));
+                yPosition += List.ELEMENT_HEIGHT;
+            }
+            yPosition += List.ELEMENT_HEIGHT;
+            this.triggersElement.style.height = this.triggersList.canvas.style.height = yPosition + "px";
+            this._createCollapseAnimation(this.triggersList, this.triggersElement, triggers, yPosition);
+            // Create actions
+            yPosition = 10;
+            var actions = this._createListElement(this.actionsList, yPosition, "ACTIONS", ActionsBuilder.Type.ACTION, textColor, false);
+            yPosition += List.ELEMENT_HEIGHT;
+            configureTitle(actions, Raphael.rgb(255, 220, 42));
+            for (var i = 0; i < ActionsBuilder.Elements.ACTIONS.length; i++) {
+                var element = ActionsBuilder.Elements.ACTIONS[i];
+                var action = this._createListElement(this.actionsList, yPosition, element.text, ActionsBuilder.Type.ACTION, textColor, true, element);
+                action.rect.attr("fill", Raphael.rgb(182, 185, 132));
+                yPosition += List.ELEMENT_HEIGHT;
+            }
+            yPosition += List.ELEMENT_HEIGHT;
+            this.actionsElement.style.height = this.actionsList.canvas.style.height = yPosition + "px";
+            this._createCollapseAnimation(this.actionsList, this.actionsElement, actions, yPosition);
+            // Create flow controls
+            yPosition = 10;
+            var flowControls = this._createListElement(this.flowControlsList, yPosition, "FLOW CONTROLS", ActionsBuilder.Type.FLOW_CONTROL, whiteColor, false);
+            yPosition += List.ELEMENT_HEIGHT;
+            configureTitle(flowControls, Raphael.rgb(255, 41, 53));
+            for (var i = 0; i < ActionsBuilder.Elements.FLOW_CONTROLS.length - 1; i++) {
+                var element = ActionsBuilder.Elements.FLOW_CONTROLS[i];
+                var flowControl = this._createListElement(this.flowControlsList, yPosition, element.text, ActionsBuilder.Type.FLOW_CONTROL, textColor, true, element);
+                flowControl.rect.attr("fill", Raphael.rgb(185, 132, 140));
+                yPosition += List.ELEMENT_HEIGHT;
+            }
+            yPosition += List.ELEMENT_HEIGHT;
+            this.flowControlsElement.style.height = this.flowControlsList.canvas.style.height = yPosition + "px";
+            this._createCollapseAnimation(this.flowControlsList, this.flowControlsElement, flowControls, yPosition);
+        };
+        /**
+        * Clears the list of elements and removes the elements
+        */
+        List.prototype.clearLists = function () {
+            for (var i = 0; i < this._listElements.length; i++) {
+                this._removeListElement(this._listElements[i]);
+            }
+            this._listElements.splice(0, this._listElements.length - 1);
+        };
+        /**
+        * Sets the color theme of the lists
+        * @param color: the theme color
+        */
+        List.prototype.setColorTheme = function (color) {
+            this.triggersList.canvas.style.backgroundColor = color;
+            this.actionsList.canvas.style.backgroundColor = color;
+            this.flowControlsList.canvas.style.backgroundColor = color;
+        };
+        /**
+        * Creates a list element
+        * @param paper: the Raphael.js paper
+        * @param yPosition: the y position of the element
+        * @param text: the element text
+        * @param type: the element type (trigger, action, flow control)
+        * @param textColor: the text color
+        * @param drag: if the element should be drag'n'dropped
+        */
+        List.prototype._createListElement = function (paper, yPosition, text, type, textColor, drag, element) {
+            var object = new ListElement();
+            object.rect = paper.rect(10, yPosition, 300, List.ELEMENT_HEIGHT);
+            object.text = paper.text(30, yPosition + object.rect.attr("height") / 2, text);
+            object.text.attr("fill", textColor);
+            object.text.attr("text-anchor", "start");
+            object.text.attr("font-size", "12");
+            object.text.attr("text-anchor", "start");
+            object.text.attr("font-family", "Sinkin Sans Light");
+            if (drag) {
+                this._createListElementAnimation(object);
+            }
+            object.type = type;
+            object.element = element;
+            this._listElements.push(object);
+            return object;
+        };
+        /**
+        * Removes a list element
+        * @param element: the element to remove
+        */
+        List.prototype._removeListElement = function (element) {
+            element.rect.remove();
+            element.text.remove();
+        };
+        /*
+        * Creates the collapse animation of a list
+        * @param paper: the list paper
+        * @param htmlElement: the list div container
+        * @param element: the list element to click on
+        * @param expandedHeight: the height when the list is expanded
+        */
+        List.prototype._createCollapseAnimation = function (paper, htmlElement, element, expandedHeight) {
+            var onClick = function (event) {
+                var height = htmlElement.style.height;
+                if (height === expandedHeight + "px") {
+                    htmlElement.style.height = paper.canvas.style.height = 35 + "px";
+                }
+                else {
+                    htmlElement.style.height = paper.canvas.style.height = expandedHeight + "px";
+                }
+            };
+            element.rect.click(onClick);
+        };
+        /*
+        * Creates the animation of a list element
+        * @param element: the list element to animate
+        */
+        List.prototype._createListElementAnimation = function (element) {
+            var _this = this;
+            var onMove = function (dx, dy, x, y) { };
+            var onStart = function (x, y, event) {
+                _this._parentContainer.style.cursor = "copy";
+                element.rect.animate({
+                    x: -10,
+                    opacity: 0.25
+                }, 500, ">");
+                element.text.animate({
+                    x: 10,
+                    opacity: 0.25
+                }, 500, ">");
+            };
+            var onEnd = function (event) {
+                _this._parentContainer.style.cursor = "default";
+                element.rect.animate({
+                    x: 10,
+                    opacity: 1.0
+                }, 500, "<");
+                element.text.animate({
+                    x: 30,
+                    opacity: 1.0
+                }, 500, "<");
+                var dragResult = _this._viewer.traverseGraph(null, _this._viewer.mousex, _this._viewer.mousey, false);
+                if (dragResult.hit) {
+                    if (element.type === ActionsBuilder.Type.TRIGGER && dragResult.action !== _this._viewer.root) {
+                        alert("Triggers can be dragged only on the root node (the mesh)");
+                        return;
+                    }
+                    if (element.type === ActionsBuilder.Type.ACTION && dragResult.action === _this._viewer.root) {
+                        alert("Please add a trigger before.");
+                        return;
+                    }
+                    //if (element.type === Type.FLOW_CONTROL && (dragResult.action === this._viewer.root || (dragResult.action.type === Type.FLOW_CONTROL && dragResult.action.parent.hub === null))) {
+                    if (element.type === ActionsBuilder.Type.FLOW_CONTROL && dragResult.action === _this._viewer.root) {
+                        return;
+                    }
+                    if (element.type === ActionsBuilder.Type.FLOW_CONTROL && dragResult.action.combineArray !== null) {
+                        alert("A condition cannot be handled by a Combine Action.");
+                        return;
+                    }
+                    if ((element.type === ActionsBuilder.Type.FLOW_CONTROL || element.type === ActionsBuilder.Type.ACTION) && dragResult.action.type === ActionsBuilder.Type.TRIGGER && dragResult.action.children.length > 0) {
+                        alert("Triggers can have only one child. Please add another trigger of same type.");
+                        return;
+                    }
+                    if (!(dragResult.action.combineArray !== null) && dragResult.action.children.length > 0 && dragResult.action.type !== ActionsBuilder.Type.TRIGGER && dragResult.action !== _this._viewer.root) {
+                        alert("An action can have only one child.");
+                        return;
+                    }
+                    _this._viewer.addAction(dragResult.action, element.type, element.element);
+                    _this._viewer.update();
+                }
+            };
+            element.rect.drag(onMove, onStart, onEnd);
+            element.text.drag(onMove, onStart, onEnd);
+        };
+        return List;
+    }());
+    ActionsBuilder.List = List;
+})(ActionsBuilder || (ActionsBuilder = {}));
 //# sourceMappingURL=actionsbuilder.list.js.map

+ 107 - 101
Exporters/3ds Max/ActionsBuilder/Sources/actionsbuilder.main.js

@@ -1,102 +1,108 @@
-/*
-Global functions called by the plugins (3ds Max, etc.)
-*/
-// Elements
-var list = null;
-var viewer = null;
-var actionsBuilderJsonInput = document.getElementById("ActionsBuilderJSON");
-this.createJSON = function () {
-    var structure = viewer.utils.createJSON(viewer.root);
-    var asText = JSON.stringify(structure);
-    actionsBuilderJsonInput.value = asText;
-    console.log(asText);
-};
-this.loadFromJSON = function () {
-    var json = actionsBuilderJsonInput.value;
-    if (json !== "") {
-        var structure = JSON.parse(json);
-        viewer.utils.loadFromJSON(structure, null);
-    }
-};
-this.updateObjectName = function () {
-    var element = document.getElementById("ActionsBuilderObjectName");
-    var name = element.value;
-    viewer.objectName = name;
-    if (viewer.root.type === ActionsBuilder.Type.OBJECT) {
-        name += " - Mesh";
-    }
-    else {
-        name += " - Scene";
-    }
-    viewer.root.node.text.attr("text", name);
-};
-this.resetList = function () {
-    list.clearLists();
-    list.createListsElements();
-};
-this.setMeshesNames = function () {
-    var args = [];
-    for (var _i = 0; _i < arguments.length; _i++) {
-        args[_i - 0] = arguments[_i];
-    }
-    for (var i = 0; i < args.length; i++) {
-        ActionsBuilder.SceneElements.MESHES.push(args[i]);
-    }
-};
-this.setLightsNames = function () {
-    var args = [];
-    for (var _i = 0; _i < arguments.length; _i++) {
-        args[_i - 0] = arguments[_i];
-    }
-    for (var i = 0; i < args.length; i++) {
-        ActionsBuilder.SceneElements.LIGHTS.push(args[i]);
-    }
-};
-this.setCamerasNames = function () {
-    var args = [];
-    for (var _i = 0; _i < arguments.length; _i++) {
-        args[_i - 0] = arguments[_i];
-    }
-    for (var i = 0; i < args.length; i++) {
-        ActionsBuilder.SceneElements.CAMERAS.push(args[i]);
-    }
-};
-this.setSoundsNames = function () {
-    var args = [];
-    for (var _i = 0; _i < arguments.length; _i++) {
-        args[_i - 0] = arguments[_i];
-    }
-    for (var i = 0; i < args.length; i++) {
-        var sound = args[i];
-        if (sound !== "" && ActionsBuilder.SceneElements.SOUNDS.indexOf(sound) === -1) {
-            ActionsBuilder.SceneElements.SOUNDS.push(args[i]);
-        }
-    }
-};
-this.hideButtons = function () {
-    // Empty
-};
-this.setIsObject = function () {
-    viewer.root.type = ActionsBuilder.Type.OBJECT;
-};
-this.setIsScene = function () {
-    viewer.root.type = ActionsBuilder.Type.SCENE;
-};
-this.run = function () {
-    // Configure viewer
-    viewer = new ActionsBuilder.Viewer(ActionsBuilder.Type.OBJECT);
-    viewer.setColorTheme("-ms-linear-gradient(top, rgba(38, 38, 38,1) 0%, rgba(125, 126, 125, 1) 100%)");
-    viewer.setColorTheme("linear-gradient(top, rgba(38, 38, 38,1) 0%, rgba(125, 126, 125, 1) 100%)");
-    viewer.setColorTheme("-webkit-linear-gradient(top, rgba(38, 38, 38,1) 0%, rgba(125, 126, 125, 1) 100%)");
-    viewer.setColorTheme("-o-linear-gradient(top, rgba(38, 38, 38,1) 0%, rgba(125, 126, 125, 1) 100%)");
-    viewer.onResize();
-    viewer.update();
-    // Configure list
-    list = new ActionsBuilder.List(viewer);
-    list.setColorTheme("rgb(64, 64, 64)");
-    list.createListsElements();
-    list.onResize();
-    // 3ds Max fix
-    viewer.onResize();
-};
+/*
+Global functions called by the plugins (3ds Max, etc.)
+*/
+// Elements
+var list = null;
+var viewer = null;
+var actionsBuilderJsonInput = document.getElementById("ActionsBuilderJSON");
+this.getList = function () {
+    return list;
+};
+this.getViewer = function () {
+    return viewer;
+};
+this.createJSON = function () {
+    var structure = viewer.utils.createJSON(viewer.root);
+    var asText = JSON.stringify(structure);
+    actionsBuilderJsonInput.value = asText;
+    console.log(asText);
+};
+this.loadFromJSON = function () {
+    var json = actionsBuilderJsonInput.value;
+    if (json !== "") {
+        var structure = JSON.parse(json);
+        viewer.utils.loadFromJSON(structure, null);
+    }
+};
+this.updateObjectName = function () {
+    var element = document.getElementById("ActionsBuilderObjectName");
+    var name = element.value;
+    viewer.objectName = name;
+    if (viewer.root.type === ActionsBuilder.Type.OBJECT) {
+        name += " - Mesh";
+    }
+    else {
+        name += " - Scene";
+    }
+    viewer.root.node.text.attr("text", name);
+};
+this.resetList = function () {
+    list.clearLists();
+    list.createListsElements();
+};
+this.setMeshesNames = function () {
+    var args = [];
+    for (var _i = 0; _i < arguments.length; _i++) {
+        args[_i] = arguments[_i];
+    }
+    for (var i = 0; i < args.length; i++) {
+        ActionsBuilder.SceneElements.MESHES.push(args[i]);
+    }
+};
+this.setLightsNames = function () {
+    var args = [];
+    for (var _i = 0; _i < arguments.length; _i++) {
+        args[_i] = arguments[_i];
+    }
+    for (var i = 0; i < args.length; i++) {
+        ActionsBuilder.SceneElements.LIGHTS.push(args[i]);
+    }
+};
+this.setCamerasNames = function () {
+    var args = [];
+    for (var _i = 0; _i < arguments.length; _i++) {
+        args[_i] = arguments[_i];
+    }
+    for (var i = 0; i < args.length; i++) {
+        ActionsBuilder.SceneElements.CAMERAS.push(args[i]);
+    }
+};
+this.setSoundsNames = function () {
+    var args = [];
+    for (var _i = 0; _i < arguments.length; _i++) {
+        args[_i] = arguments[_i];
+    }
+    for (var i = 0; i < args.length; i++) {
+        var sound = args[i];
+        if (sound !== "" && ActionsBuilder.SceneElements.SOUNDS.indexOf(sound) === -1) {
+            ActionsBuilder.SceneElements.SOUNDS.push(args[i]);
+        }
+    }
+};
+this.hideButtons = function () {
+    // Empty
+};
+this.setIsObject = function () {
+    viewer.root.type = ActionsBuilder.Type.OBJECT;
+};
+this.setIsScene = function () {
+    viewer.root.type = ActionsBuilder.Type.SCENE;
+};
+this.run = function () {
+    // Configure viewer
+    viewer = new ActionsBuilder.Viewer(ActionsBuilder.Type.OBJECT);
+    viewer.setColorTheme("-ms-linear-gradient(top, rgba(38, 38, 38,1) 0%, rgba(125, 126, 125, 1) 100%)");
+    viewer.setColorTheme("linear-gradient(top, rgba(38, 38, 38,1) 0%, rgba(125, 126, 125, 1) 100%)");
+    viewer.setColorTheme("-webkit-linear-gradient(top, rgba(38, 38, 38,1) 0%, rgba(125, 126, 125, 1) 100%)");
+    viewer.setColorTheme("-o-linear-gradient(top, rgba(38, 38, 38,1) 0%, rgba(125, 126, 125, 1) 100%)");
+    viewer.onResize();
+    viewer.update();
+    // Configure list
+    list = new ActionsBuilder.List(viewer);
+    list.setColorTheme("rgb(64, 64, 64)");
+    list.createListsElements();
+    list.onResize();
+    // 3ds Max fix
+    viewer.onResize();
+};
 //# sourceMappingURL=actionsbuilder.main.js.map

+ 111 - 110
Exporters/3ds Max/ActionsBuilder/Sources/actionsbuilder.max.js

@@ -17,7 +17,7 @@ var ActionsBuilder;
             return this.rect.isPointInside(x, y) || this.text.isPointInside(x, y);
         };
         return Node;
-    })();
+    }());
     ActionsBuilder.Node = Node;
     var Action = (function () {
         /**
@@ -81,7 +81,7 @@ var ActionsBuilder;
             this.children = new Array();
         };
         return Action;
-    })();
+    }());
     ActionsBuilder.Action = Action;
 })(ActionsBuilder || (ActionsBuilder = {}));
 var ActionsBuilder;
@@ -199,7 +199,7 @@ var ActionsBuilder;
             element.addEventListener("contextmenu", onRightClick);
         };
         return ContextMenu;
-    })();
+    }());
     ActionsBuilder.ContextMenu = ContextMenu;
 })(ActionsBuilder || (ActionsBuilder = {}));
 var ActionsBuilder;
@@ -213,7 +213,7 @@ var ActionsBuilder;
             this.element = null;
         }
         return ListElement;
-    })();
+    }());
     ActionsBuilder.ListElement = ListElement;
     var List = (function () {
         /**
@@ -454,7 +454,7 @@ var ActionsBuilder;
             element.text.drag(onMove, onStart, onEnd);
         };
         return List;
-    })();
+    }());
     ActionsBuilder.List = List;
 })(ActionsBuilder || (ActionsBuilder = {}));
 /*
@@ -464,6 +464,12 @@ Global functions called by the plugins (3ds Max, etc.)
 var list = null;
 var viewer = null;
 var actionsBuilderJsonInput = document.getElementById("ActionsBuilderJSON");
+this.getList = function () {
+    return list;
+};
+this.getViewer = function () {
+    return viewer;
+};
 this.createJSON = function () {
     var structure = viewer.utils.createJSON(viewer.root);
     var asText = JSON.stringify(structure);
@@ -496,7 +502,7 @@ this.resetList = function () {
 this.setMeshesNames = function () {
     var args = [];
     for (var _i = 0; _i < arguments.length; _i++) {
-        args[_i - 0] = arguments[_i];
+        args[_i] = arguments[_i];
     }
     for (var i = 0; i < args.length; i++) {
         ActionsBuilder.SceneElements.MESHES.push(args[i]);
@@ -505,7 +511,7 @@ this.setMeshesNames = function () {
 this.setLightsNames = function () {
     var args = [];
     for (var _i = 0; _i < arguments.length; _i++) {
-        args[_i - 0] = arguments[_i];
+        args[_i] = arguments[_i];
     }
     for (var i = 0; i < args.length; i++) {
         ActionsBuilder.SceneElements.LIGHTS.push(args[i]);
@@ -514,7 +520,7 @@ this.setLightsNames = function () {
 this.setCamerasNames = function () {
     var args = [];
     for (var _i = 0; _i < arguments.length; _i++) {
-        args[_i - 0] = arguments[_i];
+        args[_i] = arguments[_i];
     }
     for (var i = 0; i < args.length; i++) {
         ActionsBuilder.SceneElements.CAMERAS.push(args[i]);
@@ -523,7 +529,7 @@ this.setCamerasNames = function () {
 this.setSoundsNames = function () {
     var args = [];
     for (var _i = 0; _i < arguments.length; _i++) {
-        args[_i - 0] = arguments[_i];
+        args[_i] = arguments[_i];
     }
     for (var i = 0; i < args.length; i++) {
         var sound = args[i];
@@ -627,20 +633,30 @@ var ActionsBuilder;
                 parameterName.className = "ParametersElementTitleClass";
                 this.parametersContainer.appendChild(parameterName);
                 if (properties[i].text === "parameter" || properties[i].text === "target" || properties[i].text === "parent") {
-                    // Create target select element
-                    targetParameterSelect = document.createElement("select");
-                    targetParameterSelect.className = "ParametersElementSelectClass";
-                    this.parametersContainer.appendChild(targetParameterSelect);
-                    // Create target name select element
-                    targetParameterNameSelect = document.createElement("select");
-                    targetParameterNameSelect.className = "ParametersElementSelectClass";
-                    this.parametersContainer.appendChild(targetParameterNameSelect);
-                    // Events and configure
-                    (this._parameterTargetChanged(targetParameterSelect, targetParameterNameSelect, propertyPathSelect, propertyPathOptionalSelect, i))(null);
-                    targetParameterSelect.value = propertiesResults[i].targetType;
-                    targetParameterNameSelect.value = propertiesResults[i].value;
-                    targetParameterSelect.onchange = this._parameterTargetChanged(targetParameterSelect, targetParameterNameSelect, propertyPathSelect, propertyPathOptionalSelect, i);
-                    targetParameterNameSelect.onchange = this._parameterTargetNameChanged(targetParameterSelect, targetParameterNameSelect, i);
+                    if (properties[i].targetType === null) {
+                        var parameterInput = document.createElement("input");
+                        parameterInput.value = propertiesResults[i].value;
+                        parameterInput.className = "ParametersElementInputClass";
+                        this.parametersContainer.appendChild(parameterInput);
+                        // Configure event
+                        parameterInput.onkeyup = this._propertyInputChanged(parameterInput, i);
+                    }
+                    else {
+                        // Create target select element
+                        targetParameterSelect = document.createElement("select");
+                        targetParameterSelect.className = "ParametersElementSelectClass";
+                        this.parametersContainer.appendChild(targetParameterSelect);
+                        // Create target name select element
+                        targetParameterNameSelect = document.createElement("select");
+                        targetParameterNameSelect.className = "ParametersElementSelectClass";
+                        this.parametersContainer.appendChild(targetParameterNameSelect);
+                        // Events and configure
+                        (this._parameterTargetChanged(targetParameterSelect, targetParameterNameSelect, propertyPathSelect, propertyPathOptionalSelect, i))(null);
+                        targetParameterSelect.value = propertiesResults[i].targetType;
+                        targetParameterNameSelect.value = propertiesResults[i].value;
+                        targetParameterSelect.onchange = this._parameterTargetChanged(targetParameterSelect, targetParameterNameSelect, propertyPathSelect, propertyPathOptionalSelect, i);
+                        targetParameterNameSelect.onchange = this._parameterTargetNameChanged(targetParameterSelect, targetParameterNameSelect, i);
+                    }
                 }
                 else if (properties[i].text === "propertyPath") {
                     propertyPathIndice = i;
@@ -670,7 +686,7 @@ var ActionsBuilder;
                         }
                         this._fillAdditionalPropertyPath(targetParameterSelect, propertyPathSelect, propertyPathOptionalSelect);
                         propertyPathOptionalSelect.value = property[property.length - 1];
-                        if (propertyPathOptionalSelect.options.length === 0 || propertyPathOptionalSelect.options[0].text === "") {
+                        if (propertyPathOptionalSelect.options.length === 0 || propertyPathOptionalSelect.options[0].textContent === "") {
                             this._viewer.utils.setElementVisible(propertyPathOptionalSelect, false);
                         }
                     }
@@ -757,7 +773,7 @@ var ActionsBuilder;
                     for (var i = 0; i < values.length; i++) {
                         var option = document.createElement("option");
                         option.value = option.text = values[i];
-                        booleanSelect.options.add(option);
+                        booleanSelect.add(option);
                     }
                 }
                 else {
@@ -777,7 +793,7 @@ var ActionsBuilder;
                     for (var i = 0; i < ActionsBuilder.SceneElements.SOUNDS.length; i++) {
                         var option = document.createElement("option");
                         option.value = option.text = ActionsBuilder.SceneElements.SOUNDS[i];
-                        soundSelect.options.add(option);
+                        soundSelect.add(option);
                     }
                     _this._sortList(soundSelect);
                 }
@@ -798,7 +814,8 @@ var ActionsBuilder;
                     for (var i = 0; i < ActionsBuilder.SceneElements.OPERATORS.length; i++) {
                         var option = document.createElement("option");
                         option.value = option.text = ActionsBuilder.SceneElements.OPERATORS[i];
-                        conditionOperatorSelect.options.add(option);
+                        //conditionOperatorSelect.options.add(option);
+                        conditionOperatorSelect.add(option);
                     }
                 }
                 else {
@@ -834,7 +851,7 @@ var ActionsBuilder;
                         for (var i = 0; i < properties.length; i++) {
                             var option = document.createElement("option");
                             option.value = option.text = properties[i];
-                            propertyPathSelect.options.add(option);
+                            propertyPathSelect.add(option);
                         }
                     }
                 }
@@ -892,11 +909,11 @@ var ActionsBuilder;
                 if (index !== -1) {
                     var option = document.createElement("option");
                     option.value = option.text = thing;
-                    additionalPropertyPathSelect.options.add(option);
+                    additionalPropertyPathSelect.add(option);
                     emptyOption.text += thing + ", ";
                 }
             }
-            if (additionalPropertyPathSelect.options.length === 0 || additionalPropertyPathSelect.options[0].text === "") {
+            if (additionalPropertyPathSelect.options.length === 0 || additionalPropertyPathSelect.options[0].textContent === "") {
                 this._viewer.utils.setElementVisible(additionalPropertyPathSelect, false);
             }
             else {
@@ -945,7 +962,7 @@ var ActionsBuilder;
                         var option = document.createElement("option");
                         option.text = options[i].text;
                         option.value = options[i].targetType;
-                        targetParameterSelect.options.add(option);
+                        targetParameterSelect.add(option);
                     }
                     targetParameterSelect.value = _this._action.propertiesResults[indice].targetType;
                 }
@@ -969,7 +986,7 @@ var ActionsBuilder;
                     for (var i = 0; i < targetParameterProperties.length; i++) {
                         var option = document.createElement("option");
                         option.text = option.value = targetParameterProperties[i];
-                        targetParameterNameSelect.options.add(option);
+                        targetParameterNameSelect.add(option);
                     }
                 }
                 targetParameterNameSelect.value = _this._action.propertiesResults[indice].value;
@@ -1101,11 +1118,11 @@ var ActionsBuilder;
                 return a.innerHTML.localeCompare(b.innerHTML);
             });
             for (var i = 0; i < options.length; i++) {
-                element.options.add(options[i]);
+                element.add(options[i]);
             }
         };
         return Parameters;
-    })();
+    }());
     ActionsBuilder.Parameters = Parameters;
 })(ActionsBuilder || (ActionsBuilder = {}));
 var ActionsBuilder;
@@ -1190,7 +1207,7 @@ var ActionsBuilder;
             this.saveActionGraphElement.style.display = draw ? "block" : "none";
         };
         return Toolbar;
-    })();
+    }());
     ActionsBuilder.Toolbar = Toolbar;
 })(ActionsBuilder || (ActionsBuilder = {}));
 var ActionsBuilder;
@@ -1236,13 +1253,13 @@ var ActionsBuilder;
             enumerable: true,
             configurable: true
         });
-        Type._TRIGGER = 0;
-        Type._ACTION = 1;
-        Type._FLOW_CONTROL = 2;
-        Type._OBJECT = 3;
-        Type._SCENE = 4;
         return Type;
-    })();
+    }());
+    Type._TRIGGER = 0;
+    Type._ACTION = 1;
+    Type._FLOW_CONTROL = 2;
+    Type._OBJECT = 3;
+    Type._SCENE = 4;
     ActionsBuilder.Type = Type;
     /*
     * Defines the BABYLON.JS elements
@@ -1378,38 +1395,38 @@ var ActionsBuilder;
             }
             return false;
         };
-        /*
-        * BabylonJS objects
-        */
-        SceneElements._ENGINE = new BABYLON.Engine(document.getElementById("RenderCanvasID"));
-        SceneElements._SCENE = new BABYLON.Scene(SceneElements.ENGINE);
-        SceneElements._MESH = new BABYLON.Mesh("mesh", SceneElements._SCENE);
-        SceneElements._LIGHT = new BABYLON.Light("light", SceneElements._SCENE);
-        SceneElements._CAMERA = new BABYLON.Camera("camera", BABYLON.Vector3.Zero(), SceneElements._SCENE);
-        /*
-        * Objects names
-        */
-        SceneElements._MESHES = new Array();
-        SceneElements._LIGHTS = new Array();
-        SceneElements._CAMERAS = new Array();
-        SceneElements._SOUNDS = new Array();
-        /*
-        * Properties
-        */
-        SceneElements._MESH_PROPERTIES = new Array();
-        SceneElements._LIGHT_PROPERTIES = new Array();
-        SceneElements._CAMERA_PROPERTIES = new Array();
-        SceneElements._SCENE_PROPERTIES = new Array();
-        /*
-        * Types
-        */
-        SceneElements._TYPES = new Array();
-        /*
-        * Operators
-        */
-        SceneElements._OPERATORS = new Array();
         return SceneElements;
-    })();
+    }());
+    /*
+    * BabylonJS objects
+    */
+    SceneElements._ENGINE = new BABYLON.Engine(document.getElementById("RenderCanvasID"));
+    SceneElements._SCENE = new BABYLON.Scene(SceneElements.ENGINE);
+    SceneElements._MESH = new BABYLON.Mesh("mesh", SceneElements._SCENE);
+    SceneElements._LIGHT = new BABYLON.Light("light", SceneElements._SCENE);
+    SceneElements._CAMERA = new BABYLON.Camera("camera", BABYLON.Vector3.Zero(), SceneElements._SCENE);
+    /*
+    * Objects names
+    */
+    SceneElements._MESHES = new Array();
+    SceneElements._LIGHTS = new Array();
+    SceneElements._CAMERAS = new Array();
+    SceneElements._SOUNDS = new Array();
+    /*
+    * Properties
+    */
+    SceneElements._MESH_PROPERTIES = new Array();
+    SceneElements._LIGHT_PROPERTIES = new Array();
+    SceneElements._CAMERA_PROPERTIES = new Array();
+    SceneElements._SCENE_PROPERTIES = new Array();
+    /*
+    * Types
+    */
+    SceneElements._TYPES = new Array();
+    /*
+    * Operators
+    */
+    SceneElements._OPERATORS = new Array();
     ActionsBuilder.SceneElements = SceneElements;
     // Functions
     var specialTypes = [
@@ -1508,11 +1525,11 @@ var ActionsBuilder;
             }
             return null;
         };
-        Elements._TRIGGERS = new Array();
-        Elements._ACTIONS = new Array();
-        Elements._FLOW_CONTROLS = new Array();
         return Elements;
-    })();
+    }());
+    Elements._TRIGGERS = new Array();
+    Elements._ACTIONS = new Array();
+    Elements._FLOW_CONTROLS = new Array();
     ActionsBuilder.Elements = Elements;
     // Configure triggers
     Elements.TRIGGERS.push({ name: "OnPickTrigger", text: "pick", properties: [], description: "When the user picks the edited mesh" });
@@ -1524,8 +1541,8 @@ var ActionsBuilder;
     Elements.TRIGGERS.push({ name: "OnEveryFrameTrigger", text: "every frame", properties: [], description: "This trigger is called each frame (only on scene)" });
     Elements.TRIGGERS.push({ name: "OnIntersectionEnterTrigger", text: "intersection enter", properties: [{ targetType: "MeshProperties", text: "parameter", value: "Object name?" }], description: "When the edited mesh intersects the another mesh predefined in the options" });
     Elements.TRIGGERS.push({ name: "OnIntersectionExitTrigger", text: "intersection exit", properties: [{ targetType: "MeshProperties", text: "parameter", value: "Object name?" }], description: "When the edited mesh exits intersection with the another mesh predefined in the options" });
-    Elements.TRIGGERS.push({ name: "OnKeyDownTrigger", text: "key down", properties: [{ targetType: null, text: "parameter:", value: "a" }], description: "When the user pressed a key (enter the key character, example: \"r\")" });
-    Elements.TRIGGERS.push({ name: "OnKeyUpTrigger", text: "key up", properties: [{ targetType: null, text: "parameter:", value: "a" }], description: "When the user unpressed a key (enter the key character, example: \"p\")" });
+    Elements.TRIGGERS.push({ name: "OnKeyDownTrigger", text: "key down", properties: [{ targetType: null, text: "parameter", value: "a" }], description: "When the user pressed a key (enter the key character, example: \"r\")" });
+    Elements.TRIGGERS.push({ name: "OnKeyUpTrigger", text: "key up", properties: [{ targetType: null, text: "parameter", value: "a" }], description: "When the user unpressed a key (enter the key character, example: \"p\")" });
     // Configure actions
     Elements.ACTIONS.push({ name: "SwitchBooleanAction", text: "switch boolean", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "propertyPath", value: "" }], description: "Switches the boolean value of a given parameter of the target object: true to false, or false to true" });
     Elements.ACTIONS.push({ name: "SetStateAction", text: "set state", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "value", value: "" }], description: "Sets a new state value for the target object (example: \"off\" or \"on\")" });
@@ -1974,7 +1991,7 @@ var ActionsBuilder;
             element.style.display = visible ? "block" : "none";
         };
         return Utils;
-    })();
+    }());
     ActionsBuilder.Utils = Utils;
 })(ActionsBuilder || (ActionsBuilder = {}));
 var ActionsBuilder;
@@ -2114,19 +2131,11 @@ var ActionsBuilder;
                 return Raphael.rgb(96, 122, 14);
             }
             switch (type) {
-                case ActionsBuilder.Type.TRIGGER:
-                    return Raphael.rgb(133, 154, 185);
-                    break;
-                case ActionsBuilder.Type.ACTION:
-                    return Raphael.rgb(182, 185, 132);
-                    break;
-                case ActionsBuilder.Type.FLOW_CONTROL:
-                    return Raphael.rgb(185, 132, 140);
-                    break;
+                case ActionsBuilder.Type.TRIGGER: return Raphael.rgb(133, 154, 185);
+                case ActionsBuilder.Type.ACTION: return Raphael.rgb(182, 185, 132);
+                case ActionsBuilder.Type.FLOW_CONTROL: return Raphael.rgb(185, 132, 140);
                 case ActionsBuilder.Type.OBJECT:
-                case ActionsBuilder.Type.SCENE:
-                    return Raphael.rgb(255, 255, 255);
-                    break;
+                case ActionsBuilder.Type.SCENE: return Raphael.rgb(255, 255, 255);
                 default: break;
             }
             return null;
@@ -2141,19 +2150,11 @@ var ActionsBuilder;
                 return Raphael.rgb(96, 122, 14);
             }
             switch (type) {
-                case ActionsBuilder.Type.TRIGGER:
-                    return Raphael.rgb(41, 129, 255);
-                    break;
-                case ActionsBuilder.Type.ACTION:
-                    return Raphael.rgb(255, 220, 42);
-                    break;
-                case ActionsBuilder.Type.FLOW_CONTROL:
-                    return Raphael.rgb(255, 41, 53);
-                    break;
+                case ActionsBuilder.Type.TRIGGER: return Raphael.rgb(41, 129, 255);
+                case ActionsBuilder.Type.ACTION: return Raphael.rgb(255, 220, 42);
+                case ActionsBuilder.Type.FLOW_CONTROL: return Raphael.rgb(255, 41, 53);
                 case ActionsBuilder.Type.OBJECT:
-                case ActionsBuilder.Type.SCENE:
-                    return Raphael.rgb(255, 255, 255);
-                    break;
+                case ActionsBuilder.Type.SCENE: return Raphael.rgb(255, 255, 255);
                 default: break;
             }
             return null;
@@ -2614,13 +2615,13 @@ var ActionsBuilder;
             node.rect.drag(onMove, onStart, onEnd);
             node.text.drag(onMove, onStart, onEnd);
         };
-        // Statics
-        Viewer._NODE_WIDTH = 150;
-        Viewer._NODE_HEIGHT = 25;
-        Viewer._NODE_MINIMIZE_WIDTH = 50;
-        Viewer._VERTICAL_OFFSET = 70;
-        Viewer._DEFAULT_INFO_MESSAGE = "Select or add a node to customize actions";
         return Viewer;
-    })();
+    }());
+    // Statics
+    Viewer._NODE_WIDTH = 150;
+    Viewer._NODE_HEIGHT = 25;
+    Viewer._NODE_MINIMIZE_WIDTH = 50;
+    Viewer._VERTICAL_OFFSET = 70;
+    Viewer._DEFAULT_INFO_MESSAGE = "Select or add a node to customize actions";
     ActionsBuilder.Viewer = Viewer;
 })(ActionsBuilder || (ActionsBuilder = {}));

File diff suppressed because it is too large
+ 561 - 550
Exporters/3ds Max/ActionsBuilder/Sources/actionsbuilder.parameters.js


+ 85 - 85
Exporters/3ds Max/ActionsBuilder/Sources/actionsbuilder.toolbar.js

@@ -1,86 +1,86 @@
-var ActionsBuilder;
-(function (ActionsBuilder) {
-    var Toolbar = (function () {
-        function Toolbar(viewer) {
-            var _this = this;
-            // Get HTML elements
-            this.toolbarElement = document.getElementById("ToolbarElementID");
-            // Configure this
-            this._viewer = viewer;
-            // Manage events
-            window.addEventListener("resize", function (event) {
-                _this.onResize();
-            });
-            // Bottom toolbar
-            document.getElementById("ViewerDeZoomID").addEventListener("click", function (event) {
-                if (_this._viewer.zoom > 0.1) {
-                    _this._viewer.zoom -= 0.1;
-                }
-                _this._viewer.update();
-            });
-            document.getElementById("ViewerZoomID").addEventListener("click", function (event) {
-                if (_this._viewer.zoom < 1.0) {
-                    _this._viewer.zoom += 0.1;
-                }
-                _this._viewer.update();
-            });
-            document.getElementById("ViewerReconnectAll").addEventListener("click", function (event) {
-                for (var i = 0; i < _this._viewer.root.children.length; i++) {
-                    _this._viewer.selectedNode = _this._viewer.root.children[i];
-                    _this._viewer.utils.onDetachAction(false, true);
-                }
-                _this._viewer.update();
-                _this._viewer.selectedNode = null;
-            });
-            document.getElementById("ViewerDisconnectAll").addEventListener("click", function (event) {
-                for (var i = 0; i < _this._viewer.root.children.length; i++) {
-                    _this._viewer.selectedNode = _this._viewer.root.children[i];
-                    _this._viewer.utils.onDetachAction(true, false);
-                }
-                _this._viewer.update();
-                _this._viewer.selectedNode = null;
-            });
-            document.getElementById("ViewerReduceAll").addEventListener("click", function (event) {
-                for (var i = 0; i < _this._viewer.root.children.length; i++) {
-                    _this._viewer.selectedNode = _this._viewer.root.children[i];
-                    _this._viewer.utils.onReduceAll(false);
-                }
-                _this._viewer.update();
-                _this._viewer.selectedNode = null;
-            });
-            document.getElementById("ViewerExpandAll").addEventListener("click", function (event) {
-                for (var i = 0; i < _this._viewer.root.children.length; i++) {
-                    _this._viewer.selectedNode = _this._viewer.root.children[i];
-                    _this._viewer.utils.onReduceAll(true);
-                }
-                _this._viewer.update();
-                _this._viewer.selectedNode = null;
-            });
-            // Top toolbar
-            this.saveActionGraphElement = document.getElementById("ToolsButtonIDSaveActionGraph");
-            this.drawSaveActionGraphButton(false);
-            document.getElementById("ResetActionGraphID").addEventListener("click", function (event) {
-                if (confirm("Are you sure?")) {
-                    for (var i = 0; i < _this._viewer.root.children.length; i++) {
-                        _this._viewer.selectedNode = _this._viewer.root.children[i];
-                        _this._viewer.utils.onRemoveBranch();
-                    }
-                    _this._viewer.update();
-                    _this._viewer.selectedNode = null;
-                }
-            });
-            document.getElementById("TestActionGraphID").addEventListener("click", function (event) {
-                _this._viewer.utils.onTestGraph();
-            });
-        }
-        Toolbar.prototype.onResize = function () {
-            this.toolbarElement.style.top = this._viewer.viewerElement.clientHeight + 20 + "px";
-        };
-        Toolbar.prototype.drawSaveActionGraphButton = function (draw) {
-            this.saveActionGraphElement.style.display = draw ? "block" : "none";
-        };
-        return Toolbar;
-    })();
-    ActionsBuilder.Toolbar = Toolbar;
-})(ActionsBuilder || (ActionsBuilder = {}));
+var ActionsBuilder;
+(function (ActionsBuilder) {
+    var Toolbar = (function () {
+        function Toolbar(viewer) {
+            var _this = this;
+            // Get HTML elements
+            this.toolbarElement = document.getElementById("ToolbarElementID");
+            // Configure this
+            this._viewer = viewer;
+            // Manage events
+            window.addEventListener("resize", function (event) {
+                _this.onResize();
+            });
+            // Bottom toolbar
+            document.getElementById("ViewerDeZoomID").addEventListener("click", function (event) {
+                if (_this._viewer.zoom > 0.1) {
+                    _this._viewer.zoom -= 0.1;
+                }
+                _this._viewer.update();
+            });
+            document.getElementById("ViewerZoomID").addEventListener("click", function (event) {
+                if (_this._viewer.zoom < 1.0) {
+                    _this._viewer.zoom += 0.1;
+                }
+                _this._viewer.update();
+            });
+            document.getElementById("ViewerReconnectAll").addEventListener("click", function (event) {
+                for (var i = 0; i < _this._viewer.root.children.length; i++) {
+                    _this._viewer.selectedNode = _this._viewer.root.children[i];
+                    _this._viewer.utils.onDetachAction(false, true);
+                }
+                _this._viewer.update();
+                _this._viewer.selectedNode = null;
+            });
+            document.getElementById("ViewerDisconnectAll").addEventListener("click", function (event) {
+                for (var i = 0; i < _this._viewer.root.children.length; i++) {
+                    _this._viewer.selectedNode = _this._viewer.root.children[i];
+                    _this._viewer.utils.onDetachAction(true, false);
+                }
+                _this._viewer.update();
+                _this._viewer.selectedNode = null;
+            });
+            document.getElementById("ViewerReduceAll").addEventListener("click", function (event) {
+                for (var i = 0; i < _this._viewer.root.children.length; i++) {
+                    _this._viewer.selectedNode = _this._viewer.root.children[i];
+                    _this._viewer.utils.onReduceAll(false);
+                }
+                _this._viewer.update();
+                _this._viewer.selectedNode = null;
+            });
+            document.getElementById("ViewerExpandAll").addEventListener("click", function (event) {
+                for (var i = 0; i < _this._viewer.root.children.length; i++) {
+                    _this._viewer.selectedNode = _this._viewer.root.children[i];
+                    _this._viewer.utils.onReduceAll(true);
+                }
+                _this._viewer.update();
+                _this._viewer.selectedNode = null;
+            });
+            // Top toolbar
+            this.saveActionGraphElement = document.getElementById("ToolsButtonIDSaveActionGraph");
+            this.drawSaveActionGraphButton(false);
+            document.getElementById("ResetActionGraphID").addEventListener("click", function (event) {
+                if (confirm("Are you sure?")) {
+                    for (var i = 0; i < _this._viewer.root.children.length; i++) {
+                        _this._viewer.selectedNode = _this._viewer.root.children[i];
+                        _this._viewer.utils.onRemoveBranch();
+                    }
+                    _this._viewer.update();
+                    _this._viewer.selectedNode = null;
+                }
+            });
+            document.getElementById("TestActionGraphID").addEventListener("click", function (event) {
+                _this._viewer.utils.onTestGraph();
+            });
+        }
+        Toolbar.prototype.onResize = function () {
+            this.toolbarElement.style.top = this._viewer.viewerElement.clientHeight + 20 + "px";
+        };
+        Toolbar.prototype.drawSaveActionGraphButton = function (draw) {
+            this.saveActionGraphElement.style.display = draw ? "block" : "none";
+        };
+        return Toolbar;
+    }());
+    ActionsBuilder.Toolbar = Toolbar;
+})(ActionsBuilder || (ActionsBuilder = {}));
 //# sourceMappingURL=actionsbuilder.toolbar.js.map

+ 433 - 433
Exporters/3ds Max/ActionsBuilder/Sources/actionsbuilder.utils.js

@@ -1,434 +1,434 @@
-var ActionsBuilder;
-(function (ActionsBuilder) {
-    var Utils = (function () {
-        /*
-        * Constructor
-        * @param viewer: the viewer instance
-        */
-        function Utils(viewer) {
-            // Members
-            this.copiedStructure = null;
-            // Configure this
-            this._viewer = viewer;
-        }
-        /*
-        * Tests the graph and reports errors
-        */
-        Utils.prototype.onTestGraph = function () {
-            var _this = this;
-            if (this._viewer.root.children.length === 0) {
-                alert("Please add at least a Trigger and an Action to test the graph");
-            }
-            var onTestTarget = function (targetType, target) {
-                var targetExists = false;
-                var array = _this._viewer.parameters._getTargetFromType(targetType);
-                if (array === null) {
-                    return targetExists;
-                }
-                for (var i = 0; i < array.length; i++) {
-                    if (array[i] === target) {
-                        targetExists = true;
-                        break;
-                    }
-                }
-                return targetExists;
-            };
-            var onNodeError = function (action) {
-                var node = action.node;
-                node.rect.attr("fill", Raphael.rgb(255, 0, 0));
-                return false;
-            };
-            var onTestAction = function (action) {
-                console.log("Testing " + action.name);
-                if (action.combineArray !== null) {
-                    var foundError = false;
-                    for (var i = 0; i < action.combineArray.length; i++) {
-                        if (!onTestAction(action.combineArray[i])) {
-                            foundError = true;
-                        }
-                    }
-                    if (foundError) {
-                        return false;
-                    }
-                }
-                else {
-                    // Test properties
-                    var properties = action.properties;
-                    var propertiesResults = action.propertiesResults;
-                    if (properties !== null) {
-                        var object = null;
-                        var propertyPath = null;
-                        for (var i = 0; i < properties.length; i++) {
-                            // Target
-                            if (properties[i].text === "target" || properties[i].text === "parent") {
-                                object = _this._viewer.parameters._getObjectFromType(properties[i].targetType);
-                                var targetExists = onTestTarget(propertiesResults[i].targetType, propertiesResults[i].value);
-                                if (!targetExists) {
-                                    return onNodeError(action);
-                                }
-                            }
-                            else if (properties[i].text === "propertyPath") {
-                                var property = propertiesResults[i].value;
-                                var effectiveProperty = object;
-                                var p = property.split(".");
-                                for (var j = 0; j < p.length && effectiveProperty !== undefined; j++) {
-                                    effectiveProperty = effectiveProperty[p[j]];
-                                }
-                                if (effectiveProperty === undefined) {
-                                    return onNodeError(action);
-                                }
-                                else {
-                                    propertyPath = effectiveProperty;
-                                }
-                            }
-                            else if (properties[i].text == "value" && propertyPath != null) {
-                                var value = propertiesResults[i].value;
-                                if (!isNaN(propertyPath)) {
-                                    var num = parseFloat(value);
-                                    if (isNaN(num) || value === "") {
-                                        return onNodeError(action);
-                                    }
-                                }
-                            }
-                        }
-                    }
-                    var foundError = false;
-                    for (var i = 0; i < action.children.length; i++) {
-                        if (!onTestAction(action.children[i])) {
-                            foundError = true;
-                        }
-                    }
-                    return !foundError;
-                }
-            };
-            var root = this._viewer.root;
-            var foundError = false;
-            for (var i = 0; i < root.children.length; i++) {
-                var trigger = root.children[i];
-                var properties = trigger.properties;
-                // Test properties of trigger (parameter)
-                if (properties !== null && properties.length > 0) {
-                    // Only one property
-                    var parameter = trigger.propertiesResults[0].value;
-                    if (properties[0].targetType !== null) {
-                        // Intersection trigger
-                        if (!onTestTarget("MeshProperties", parameter)) {
-                            foundError = onNodeError(trigger);
-                        }
-                    }
-                    else {
-                        // Key trigger
-                        if (!parameter.match(/[a-z]/)) {
-                            foundError = onNodeError(trigger);
-                        }
-                    }
-                }
-                for (var j = 0; j < trigger.children.length; j++) {
-                    var child = trigger.children[j];
-                    var result = onTestAction(child);
-                    if (!result) {
-                        foundError = true;
-                    }
-                }
-            }
-            if (foundError) {
-                alert("Found error(s). the red nodes contain the error.");
-            }
-            else {
-                alert("No error found.");
-            }
-        };
-        /*
-        * Recursively reduce/expand nodes
-        */
-        Utils.prototype.onReduceAll = function (forceExpand) {
-            if (forceExpand === void 0) { forceExpand = false; }
-            if (this._viewer.selectedNode === null) {
-                return;
-            }
-            var action = this._viewer.selectedNode;
-            if (action.combineArray !== null) {
-                for (var i = 0; i < action.combineArray.length; i++) {
-                    this._viewer.selectedNode = action.combineArray[i];
-                    this.onReduce(forceExpand, !forceExpand);
-                }
-            }
-            else {
-                this.onReduce(forceExpand, !forceExpand);
-            }
-            for (var i = 0; i < action.children.length; i++) {
-                this._viewer.selectedNode = action.children[i];
-                this.onReduceAll(forceExpand);
-            }
-        };
-        /*
-        * Reduces the selected node
-        */
-        Utils.prototype.onReduce = function (forceExpand, forceReduce) {
-            if (forceExpand === void 0) { forceExpand = false; }
-            if (forceReduce === void 0) { forceReduce = false; }
-            if (this._viewer.selectedNode === null) {
-                return;
-            }
-            var node = this._viewer.selectedNode.node;
-            node.rect.stop(node.rect.animation);
-            // Set minimized
-            if (forceExpand === true) {
-                node.minimized = false;
-            }
-            else if (forceReduce === true) {
-                node.minimized = true;
-            }
-            else {
-                node.minimized = !node.minimized;
-            }
-            // Set size
-            if (node.minimized) {
-                node.text.hide();
-                node.rect.attr("width", ActionsBuilder.Viewer.NODE_MINIMIZED_WIDTH * this._viewer.zoom);
-            }
-            else {
-                node.text.show();
-                node.rect.attr("width", ActionsBuilder.Viewer.NODE_WIDTH * this._viewer.zoom);
-            }
-        };
-        /*
-        * Detaches the selected action
-        */
-        Utils.prototype.onDetachAction = function (forceDetach, forceAttach) {
-            var _this = this;
-            if (forceDetach === void 0) { forceDetach = false; }
-            if (forceAttach === void 0) { forceAttach = false; }
-            if (this._viewer.selectedNode === null) {
-                return;
-            }
-            var action = this._viewer.selectedNode;
-            if (forceDetach === true) {
-                action.node.detached = true;
-            }
-            else if (forceAttach === true) {
-                action.node.detached = false;
-            }
-            else {
-                action.node.detached = !action.node.detached;
-            }
-            var onSetColor = function (root, detached) {
-                var rootNode = root.node;
-                rootNode.rect.attr("fill", _this._viewer.getNodeColor(root.type, detached));
-                if (root.combineArray !== null) {
-                    for (var i = 0; i < root.combineArray.length; i++) {
-                        var combineNode = root.combineArray[i].node;
-                        combineNode.rect.attr("fill", _this._viewer.getNodeColor(root.combineArray[i].type, detached));
-                    }
-                }
-                for (var i = 0; i < root.children.length; i++) {
-                    onSetColor(root.children[i], detached);
-                }
-            };
-            onSetColor(action, action.node.detached);
-        };
-        /*
-        * Removes the selected node
-        */
-        Utils.prototype.onRemoveNode = function () {
-            if (this._viewer.selectedNode === null) {
-                return;
-            }
-            var action = this._viewer.selectedNode;
-            var parent = action.parent;
-            // If trigger, remove branch
-            if (action.type === ActionsBuilder.Type.TRIGGER) {
-                this.onRemoveBranch();
-                return;
-            }
-            // If it is a combine hub
-            if (action.type === ActionsBuilder.Type.FLOW_CONTROL && parent !== null && parent.combineArray !== null) {
-                action = parent;
-                parent = action.parent;
-            }
-            // Remove
-            if (parent !== null && parent.combineArray !== null) {
-                parent.removeCombinedAction(action);
-                if (parent.combineArray.length === 0) {
-                    parent.node.text.attr("text", "combine");
-                }
-            }
-            else {
-                if (action.combineArray !== null) {
-                    action.removeChild(action.hub);
-                }
-                action.parent.removeChild(action);
-            }
-            if (action.combineArray !== null) {
-                this._viewer.removeAction(action.hub, false);
-            }
-            this._viewer.removeAction(action, false);
-            // Finish
-            this._viewer.update();
-            this._viewer.parameters.clearParameters();
-            this._viewer.selectedNode = null;
-        };
-        /*
-        * Removes a branch starting from the selected node
-        */
-        Utils.prototype.onRemoveBranch = function () {
-            if (this._viewer.selectedNode === null) {
-                return;
-            }
-            if (this._viewer.selectedNode === this._viewer.root) {
-                alert("Cannot remove the root node");
-                return;
-            }
-            var action = this._viewer.selectedNode;
-            var parent = action.parent;
-            // If combine
-            if (action.parent !== null && action.parent.combineArray !== null) {
-                action = parent;
-                parent = action.parent;
-            }
-            // Remove
-            if (action.combineArray !== null) {
-                action.removeChild(action.hub);
-            }
-            action.parent.removeChild(action);
-            this._viewer.removeAction(action, true);
-            // Finish
-            this._viewer.update();
-            this._viewer.parameters.clearParameters();
-            this._viewer.selectedNode = null;
-        };
-        /*
-        * Copies the selected structure
-        */
-        Utils.prototype.onCopyStructure = function () {
-            if (this._viewer.selectedNode === null) {
-                return;
-            }
-            var structure = this.createJSON(this._viewer.selectedNode);
-            var asText = JSON.stringify(structure);
-            if (window.clipboardData !== undefined) {
-                window.clipboardData.setData("text", asText);
-            }
-            else {
-                this.copiedStructure = asText;
-            }
-        };
-        /*
-        * Pastes the graph structure previously copied
-        */
-        Utils.prototype.onPasteStructure = function () {
-            if (this._viewer.selectedNode === null) {
-                return;
-            }
-            var asText = (window.clipboardData !== undefined) ? window.clipboardData.getData("text") : this.copiedStructure;
-            var isJson = asText.length > 0 && asText[0] == "{" && asText[asText.length - 1] == "}";
-            var structure = JSON.parse(asText);
-            var action = this._viewer.selectedNode;
-            if (structure.type === ActionsBuilder.Type.TRIGGER && action !== this._viewer.root) {
-                alert("You can't paste a trigger if the selected node isn't the root object");
-                return;
-            }
-            if (structure.type !== ActionsBuilder.Type.TRIGGER && action === this._viewer.root) {
-                alert("You can't paste an action or condition if the selected node is the root object");
-                return;
-            }
-            this.loadFromJSON(structure, action);
-            this._viewer.update();
-        };
-        /*
-        * Loads a graph from JSON
-        * @pram graph: the graph structure
-        * @param startAction: the action to start load
-        */
-        Utils.prototype.loadFromJSON = function (graph, startAction) {
-            var _this = this;
-            // If startNode is null, means it replaces all the graph
-            // If not, it comes from a copy/paste
-            if (startAction === null) {
-                for (var i = 0; i < this._viewer.root.children.length; i++) {
-                    this._viewer.removeAction(this._viewer.root.children[i], true);
-                }
-                this._viewer.root.clearChildren();
-            }
-            var load = function (root, parent, detached, combine) {
-                if (parent === null) {
-                    parent = _this._viewer.root;
-                }
-                var newAction = null;
-                if (root.type !== ActionsBuilder.Type.OBJECT && root.type !== ActionsBuilder.Type.SCENE) {
-                    var action = _this._viewer.addAction(parent, root.type, ActionsBuilder.Elements.GetElementFromName(root.name));
-                    for (var i = 0; i < root.properties.length; i++) {
-                        var targetType = root.properties[i].targetType;
-                        if (targetType === undefined) {
-                            targetType = "MeshProperties"; // Default is mesh properties
-                        }
-                        action.propertiesResults[i] = { value: root.properties[i].value, targetType: targetType };
-                    }
-                    var node = action.node;
-                    node.detached = root.detached;
-                    if (detached) {
-                        node.rect.attr("fill", _this._viewer.getNodeColor(action.type, detached));
-                    }
-                    // If combine array
-                    if (root.combine !== undefined) {
-                        for (var i = 0; i < root.combine.length; i++) {
-                            load(root.combine[i], action, detached, true);
-                        }
-                    }
-                    if (!combine) {
-                        parent = parent.children[parent.children.length - 1];
-                    }
-                }
-                for (var i = 0; i < root.children.length; i++) {
-                    load(root.children[i], newAction !== null && newAction.combineArray !== null ? newAction.hub : parent, root.detached, false);
-                }
-            };
-            // Finish
-            load(graph, startAction, false, false);
-            this._viewer.update();
-        };
-        /*
-        * Creates a JSON object starting from a root action
-        * @param root: the root action
-        */
-        Utils.prototype.createJSON = function (root) {
-            var action = {
-                type: root.type,
-                name: root.name,
-                detached: root.node.detached,
-                children: new Array(),
-                combine: new Array(),
-                properties: new Array()
-            };
-            // Set properties
-            for (var i = 0; i < root.properties.length; i++) {
-                action.properties.push({
-                    name: root.properties[i].text,
-                    value: root.propertiesResults[i].value,
-                    targetType: root.propertiesResults[i].targetType
-                });
-            }
-            // If combine
-            if (root.combineArray !== null) {
-                for (var i = 0; i < root.combineArray.length; i++) {
-                    var combinedAction = root.combineArray[i];
-                    action.combine.push(this.createJSON(combinedAction));
-                }
-                root = root.children[0]; // Hub
-            }
-            for (var i = 0; i < root.children.length; i++) {
-                action.children.push(this.createJSON(root.children[i]));
-            }
-            return action;
-        };
-        /*
-        *
-        */
-        Utils.prototype.setElementVisible = function (element, visible) {
-            element.style.display = visible ? "block" : "none";
-        };
-        return Utils;
-    })();
-    ActionsBuilder.Utils = Utils;
-})(ActionsBuilder || (ActionsBuilder = {}));
+var ActionsBuilder;
+(function (ActionsBuilder) {
+    var Utils = (function () {
+        /*
+        * Constructor
+        * @param viewer: the viewer instance
+        */
+        function Utils(viewer) {
+            // Members
+            this.copiedStructure = null;
+            // Configure this
+            this._viewer = viewer;
+        }
+        /*
+        * Tests the graph and reports errors
+        */
+        Utils.prototype.onTestGraph = function () {
+            var _this = this;
+            if (this._viewer.root.children.length === 0) {
+                alert("Please add at least a Trigger and an Action to test the graph");
+            }
+            var onTestTarget = function (targetType, target) {
+                var targetExists = false;
+                var array = _this._viewer.parameters._getTargetFromType(targetType);
+                if (array === null) {
+                    return targetExists;
+                }
+                for (var i = 0; i < array.length; i++) {
+                    if (array[i] === target) {
+                        targetExists = true;
+                        break;
+                    }
+                }
+                return targetExists;
+            };
+            var onNodeError = function (action) {
+                var node = action.node;
+                node.rect.attr("fill", Raphael.rgb(255, 0, 0));
+                return false;
+            };
+            var onTestAction = function (action) {
+                console.log("Testing " + action.name);
+                if (action.combineArray !== null) {
+                    var foundError = false;
+                    for (var i = 0; i < action.combineArray.length; i++) {
+                        if (!onTestAction(action.combineArray[i])) {
+                            foundError = true;
+                        }
+                    }
+                    if (foundError) {
+                        return false;
+                    }
+                }
+                else {
+                    // Test properties
+                    var properties = action.properties;
+                    var propertiesResults = action.propertiesResults;
+                    if (properties !== null) {
+                        var object = null;
+                        var propertyPath = null;
+                        for (var i = 0; i < properties.length; i++) {
+                            // Target
+                            if (properties[i].text === "target" || properties[i].text === "parent") {
+                                object = _this._viewer.parameters._getObjectFromType(properties[i].targetType);
+                                var targetExists = onTestTarget(propertiesResults[i].targetType, propertiesResults[i].value);
+                                if (!targetExists) {
+                                    return onNodeError(action);
+                                }
+                            }
+                            else if (properties[i].text === "propertyPath") {
+                                var property = propertiesResults[i].value;
+                                var effectiveProperty = object;
+                                var p = property.split(".");
+                                for (var j = 0; j < p.length && effectiveProperty !== undefined; j++) {
+                                    effectiveProperty = effectiveProperty[p[j]];
+                                }
+                                if (effectiveProperty === undefined) {
+                                    return onNodeError(action);
+                                }
+                                else {
+                                    propertyPath = effectiveProperty;
+                                }
+                            }
+                            else if (properties[i].text == "value" && propertyPath != null) {
+                                var value = propertiesResults[i].value;
+                                if (!isNaN(propertyPath)) {
+                                    var num = parseFloat(value);
+                                    if (isNaN(num) || value === "") {
+                                        return onNodeError(action);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    var foundError = false;
+                    for (var i = 0; i < action.children.length; i++) {
+                        if (!onTestAction(action.children[i])) {
+                            foundError = true;
+                        }
+                    }
+                    return !foundError;
+                }
+            };
+            var root = this._viewer.root;
+            var foundError = false;
+            for (var i = 0; i < root.children.length; i++) {
+                var trigger = root.children[i];
+                var properties = trigger.properties;
+                // Test properties of trigger (parameter)
+                if (properties !== null && properties.length > 0) {
+                    // Only one property
+                    var parameter = trigger.propertiesResults[0].value;
+                    if (properties[0].targetType !== null) {
+                        // Intersection trigger
+                        if (!onTestTarget("MeshProperties", parameter)) {
+                            foundError = onNodeError(trigger);
+                        }
+                    }
+                    else {
+                        // Key trigger
+                        if (!parameter.match(/[a-z]/)) {
+                            foundError = onNodeError(trigger);
+                        }
+                    }
+                }
+                for (var j = 0; j < trigger.children.length; j++) {
+                    var child = trigger.children[j];
+                    var result = onTestAction(child);
+                    if (!result) {
+                        foundError = true;
+                    }
+                }
+            }
+            if (foundError) {
+                alert("Found error(s). the red nodes contain the error.");
+            }
+            else {
+                alert("No error found.");
+            }
+        };
+        /*
+        * Recursively reduce/expand nodes
+        */
+        Utils.prototype.onReduceAll = function (forceExpand) {
+            if (forceExpand === void 0) { forceExpand = false; }
+            if (this._viewer.selectedNode === null) {
+                return;
+            }
+            var action = this._viewer.selectedNode;
+            if (action.combineArray !== null) {
+                for (var i = 0; i < action.combineArray.length; i++) {
+                    this._viewer.selectedNode = action.combineArray[i];
+                    this.onReduce(forceExpand, !forceExpand);
+                }
+            }
+            else {
+                this.onReduce(forceExpand, !forceExpand);
+            }
+            for (var i = 0; i < action.children.length; i++) {
+                this._viewer.selectedNode = action.children[i];
+                this.onReduceAll(forceExpand);
+            }
+        };
+        /*
+        * Reduces the selected node
+        */
+        Utils.prototype.onReduce = function (forceExpand, forceReduce) {
+            if (forceExpand === void 0) { forceExpand = false; }
+            if (forceReduce === void 0) { forceReduce = false; }
+            if (this._viewer.selectedNode === null) {
+                return;
+            }
+            var node = this._viewer.selectedNode.node;
+            node.rect.stop(node.rect.animation);
+            // Set minimized
+            if (forceExpand === true) {
+                node.minimized = false;
+            }
+            else if (forceReduce === true) {
+                node.minimized = true;
+            }
+            else {
+                node.minimized = !node.minimized;
+            }
+            // Set size
+            if (node.minimized) {
+                node.text.hide();
+                node.rect.attr("width", ActionsBuilder.Viewer.NODE_MINIMIZED_WIDTH * this._viewer.zoom);
+            }
+            else {
+                node.text.show();
+                node.rect.attr("width", ActionsBuilder.Viewer.NODE_WIDTH * this._viewer.zoom);
+            }
+        };
+        /*
+        * Detaches the selected action
+        */
+        Utils.prototype.onDetachAction = function (forceDetach, forceAttach) {
+            var _this = this;
+            if (forceDetach === void 0) { forceDetach = false; }
+            if (forceAttach === void 0) { forceAttach = false; }
+            if (this._viewer.selectedNode === null) {
+                return;
+            }
+            var action = this._viewer.selectedNode;
+            if (forceDetach === true) {
+                action.node.detached = true;
+            }
+            else if (forceAttach === true) {
+                action.node.detached = false;
+            }
+            else {
+                action.node.detached = !action.node.detached;
+            }
+            var onSetColor = function (root, detached) {
+                var rootNode = root.node;
+                rootNode.rect.attr("fill", _this._viewer.getNodeColor(root.type, detached));
+                if (root.combineArray !== null) {
+                    for (var i = 0; i < root.combineArray.length; i++) {
+                        var combineNode = root.combineArray[i].node;
+                        combineNode.rect.attr("fill", _this._viewer.getNodeColor(root.combineArray[i].type, detached));
+                    }
+                }
+                for (var i = 0; i < root.children.length; i++) {
+                    onSetColor(root.children[i], detached);
+                }
+            };
+            onSetColor(action, action.node.detached);
+        };
+        /*
+        * Removes the selected node
+        */
+        Utils.prototype.onRemoveNode = function () {
+            if (this._viewer.selectedNode === null) {
+                return;
+            }
+            var action = this._viewer.selectedNode;
+            var parent = action.parent;
+            // If trigger, remove branch
+            if (action.type === ActionsBuilder.Type.TRIGGER) {
+                this.onRemoveBranch();
+                return;
+            }
+            // If it is a combine hub
+            if (action.type === ActionsBuilder.Type.FLOW_CONTROL && parent !== null && parent.combineArray !== null) {
+                action = parent;
+                parent = action.parent;
+            }
+            // Remove
+            if (parent !== null && parent.combineArray !== null) {
+                parent.removeCombinedAction(action);
+                if (parent.combineArray.length === 0) {
+                    parent.node.text.attr("text", "combine");
+                }
+            }
+            else {
+                if (action.combineArray !== null) {
+                    action.removeChild(action.hub);
+                }
+                action.parent.removeChild(action);
+            }
+            if (action.combineArray !== null) {
+                this._viewer.removeAction(action.hub, false);
+            }
+            this._viewer.removeAction(action, false);
+            // Finish
+            this._viewer.update();
+            this._viewer.parameters.clearParameters();
+            this._viewer.selectedNode = null;
+        };
+        /*
+        * Removes a branch starting from the selected node
+        */
+        Utils.prototype.onRemoveBranch = function () {
+            if (this._viewer.selectedNode === null) {
+                return;
+            }
+            if (this._viewer.selectedNode === this._viewer.root) {
+                alert("Cannot remove the root node");
+                return;
+            }
+            var action = this._viewer.selectedNode;
+            var parent = action.parent;
+            // If combine
+            if (action.parent !== null && action.parent.combineArray !== null) {
+                action = parent;
+                parent = action.parent;
+            }
+            // Remove
+            if (action.combineArray !== null) {
+                action.removeChild(action.hub);
+            }
+            action.parent.removeChild(action);
+            this._viewer.removeAction(action, true);
+            // Finish
+            this._viewer.update();
+            this._viewer.parameters.clearParameters();
+            this._viewer.selectedNode = null;
+        };
+        /*
+        * Copies the selected structure
+        */
+        Utils.prototype.onCopyStructure = function () {
+            if (this._viewer.selectedNode === null) {
+                return;
+            }
+            var structure = this.createJSON(this._viewer.selectedNode);
+            var asText = JSON.stringify(structure);
+            if (window.clipboardData !== undefined) {
+                window.clipboardData.setData("text", asText);
+            }
+            else {
+                this.copiedStructure = asText;
+            }
+        };
+        /*
+        * Pastes the graph structure previously copied
+        */
+        Utils.prototype.onPasteStructure = function () {
+            if (this._viewer.selectedNode === null) {
+                return;
+            }
+            var asText = (window.clipboardData !== undefined) ? window.clipboardData.getData("text") : this.copiedStructure;
+            var isJson = asText.length > 0 && asText[0] == "{" && asText[asText.length - 1] == "}";
+            var structure = JSON.parse(asText);
+            var action = this._viewer.selectedNode;
+            if (structure.type === ActionsBuilder.Type.TRIGGER && action !== this._viewer.root) {
+                alert("You can't paste a trigger if the selected node isn't the root object");
+                return;
+            }
+            if (structure.type !== ActionsBuilder.Type.TRIGGER && action === this._viewer.root) {
+                alert("You can't paste an action or condition if the selected node is the root object");
+                return;
+            }
+            this.loadFromJSON(structure, action);
+            this._viewer.update();
+        };
+        /*
+        * Loads a graph from JSON
+        * @pram graph: the graph structure
+        * @param startAction: the action to start load
+        */
+        Utils.prototype.loadFromJSON = function (graph, startAction) {
+            var _this = this;
+            // If startNode is null, means it replaces all the graph
+            // If not, it comes from a copy/paste
+            if (startAction === null) {
+                for (var i = 0; i < this._viewer.root.children.length; i++) {
+                    this._viewer.removeAction(this._viewer.root.children[i], true);
+                }
+                this._viewer.root.clearChildren();
+            }
+            var load = function (root, parent, detached, combine) {
+                if (parent === null) {
+                    parent = _this._viewer.root;
+                }
+                var newAction = null;
+                if (root.type !== ActionsBuilder.Type.OBJECT && root.type !== ActionsBuilder.Type.SCENE) {
+                    var action = _this._viewer.addAction(parent, root.type, ActionsBuilder.Elements.GetElementFromName(root.name));
+                    for (var i = 0; i < root.properties.length; i++) {
+                        var targetType = root.properties[i].targetType;
+                        if (targetType === undefined) {
+                            targetType = "MeshProperties"; // Default is mesh properties
+                        }
+                        action.propertiesResults[i] = { value: root.properties[i].value, targetType: targetType };
+                    }
+                    var node = action.node;
+                    node.detached = root.detached;
+                    if (detached) {
+                        node.rect.attr("fill", _this._viewer.getNodeColor(action.type, detached));
+                    }
+                    // If combine array
+                    if (root.combine !== undefined) {
+                        for (var i = 0; i < root.combine.length; i++) {
+                            load(root.combine[i], action, detached, true);
+                        }
+                    }
+                    if (!combine) {
+                        parent = parent.children[parent.children.length - 1];
+                    }
+                }
+                for (var i = 0; i < root.children.length; i++) {
+                    load(root.children[i], newAction !== null && newAction.combineArray !== null ? newAction.hub : parent, root.detached, false);
+                }
+            };
+            // Finish
+            load(graph, startAction, false, false);
+            this._viewer.update();
+        };
+        /*
+        * Creates a JSON object starting from a root action
+        * @param root: the root action
+        */
+        Utils.prototype.createJSON = function (root) {
+            var action = {
+                type: root.type,
+                name: root.name,
+                detached: root.node.detached,
+                children: new Array(),
+                combine: new Array(),
+                properties: new Array()
+            };
+            // Set properties
+            for (var i = 0; i < root.properties.length; i++) {
+                action.properties.push({
+                    name: root.properties[i].text,
+                    value: root.propertiesResults[i].value,
+                    targetType: root.propertiesResults[i].targetType
+                });
+            }
+            // If combine
+            if (root.combineArray !== null) {
+                for (var i = 0; i < root.combineArray.length; i++) {
+                    var combinedAction = root.combineArray[i];
+                    action.combine.push(this.createJSON(combinedAction));
+                }
+                root = root.children[0]; // Hub
+            }
+            for (var i = 0; i < root.children.length; i++) {
+                action.children.push(this.createJSON(root.children[i]));
+            }
+            return action;
+        };
+        /*
+        *
+        */
+        Utils.prototype.setElementVisible = function (element, visible) {
+            element.style.display = visible ? "block" : "none";
+        };
+        return Utils;
+    }());
+    ActionsBuilder.Utils = Utils;
+})(ActionsBuilder || (ActionsBuilder = {}));
 //# sourceMappingURL=actionsbuilder.utils.js.map

File diff suppressed because it is too large
+ 631 - 647
Exporters/3ds Max/ActionsBuilder/Sources/actionsbuilder.viewer.js


File diff suppressed because it is too large
+ 47131 - 24102
Exporters/3ds Max/ActionsBuilder/Sources/babylon.max.js


+ 0 - 48
Exporters/3ds Max/ActionsBuilder/Sources/fonts/SinkinSans/SinkinSans_NOTICE.txt

@@ -1,48 +0,0 @@
-
-=== SINKIN SANS 100 THIN ===
-=== SINKIN SANS 100 THIN ITALIC ===
-=== SINKIN SANS 200 X LIGHT ===
-=== SINKIN SANS 200 X LIGHT ITALIC ===
-=== SINKIN SANS 300 LIGHT ===
-=== SINKIN SANS 300 LIGHT ITALIC ===
-=== SINKIN SANS 400 REGULAR ===
-=== SINKIN SANS 400 ITALIC ===
-=== SINKIN SANS 500 MEDIUM ===
-=== SINKIN SANS 500 MEDIUM ITALIC ===
-=== SINKIN SANS 600 SEMIBOLD ===
-=== SINKIN SANS 600 SEMIBOLD ITALIC ===
-=== SINKIN SANS 700 BOLD ===
-=== SINKIN SANS 700 BOLD ITALIC ===
-=== SINKIN SANS 800 BLACK ===
-=== SINKIN SANS 800 BLACK ITALIC ===
-=== SINKIN SANS 900 X BLACK ===
-=== SINKIN SANS 900 X BLACK ITALIC ===
-
-Keith Bates / K-Type © 2014 (version 1.1)
-www.k-type.com  -  info@k-type.com
-
-SINKIN SANS is a simple, pleasantly proportioned sans serif with tiny, inconspicuous notches that sink into verticals at the intersections of strokes adding highlights to congested corners. The incisions make right angles appear sharper and improve definition in more intricate glyphs. Although the nicks are barely noticeable they add emphasis to outlines and give a lift to shady nooks.
-
-------------------------------------------------
-
-== Licence Information ==
-
-All weights of SINKIN SANS are totally free for commercial and personal use as desktop and web fonts. For @font-face users, a link to www.k-type.com somewhere on your site is requested, elsewhere a credit to K-Type is appreciated.
-
-You can freely distribute and modify SINKIN SANS provided the original copyright, license information and details of any modifications are included. SINKIN SANS is gifted 'as is', without warranty. SINKIN SANS is a trademark of K-Type. Licensed under the Apache License, Version 2.0
-
-http://www.apache.org/licenses/LICENSE-2.0.html
-
-------------------------------------------------
-
-== Installing Fonts ==
-
-Fonts are placed in your operating system's Fonts folder and will be made available to all the applications or programs you use.
-
-= Windows =
-Put the .ttf or .otf font file into C:\Windows\Fonts, or right-click on the font files > Install
-
-= Mac =
-Put the .ttf or .otf font file into /Library/Fonts
-
-------------------------------------------------

File diff suppressed because it is too large
+ 97 - 94
Exporters/3ds Max/ActionsBuilder/Sources/index-debug.html


+ 191 - 191
Exporters/3ds Max/ActionsBuilder/Sources/index.css

@@ -1,191 +1,191 @@
-html, body {
-  width: 100%;
-  height: 100%;
-
-  max-width: 100%;
-  max-height: 100%;
-
-  /*background: rgb(64, 64, 64);*/
-
-  overflow: hidden;
-  font-family: "Sinkin Sans Light";
-}
-
-* {
-  position: relative;
-}
-
-#ParentContainerID {
-    height: 100%;
-    width: 100%;
-
-    max-height: 100%;
-    max-width: 100%;
-
-    display: inline-block;
-}
-
-#ListsElementID {
-    width: 25%;
-    height: 100%;
-    
-    max-width: 25%;
-    max-height: 100%;
-
-    background: rgb(64, 64, 64);
-
-    float: left;
-    overflow-y: scroll;
-    overflow-x: hidden;
-}
-
-#GraphContainerID {
-    width: 50%;
-    max-width: 50%;
-
-    float: left;
-    position: relative;
-}
-
-#GraphElementID {
-    position: absolute;
-
-    width: 100%;
-    height: 100%;
-
-    overflow-y: auto;
-    overflow-x: auto;
-
-    max-width: 100%;
-    max-height: 100%;
-}
-
-#ToolbarElementID {
-    position: absolute;
-
-    width: 100%;
-    height: 45px;
-
-    max-width: 100%;
-    max-height: 42px;
-
-    float: left;
-    background: rgb(0, 0, 0);
-
-    vertical-align: middle;
-}
-
-#ToolbarElementID li {
-    color: white;
-    margin-left: 2em;
-    margin-top: 1em;
-}
-
-#ParametersContainerID {
-    width: 25%;
-    height: 100%;
-
-    max-width: 25%;
-    max-height: 100%;
-
-    float: right;
-    overflow-y: auto;
-}
-
-#ParametersElementID {
-    width: 100%;
-    max-width: 100%;
-
-    background: rgb(32, 32, 32);
-    overflow: auto;
-}
-
-#ParametersHelpElementID {
-    background: rgb(0, 0, 0);
-
-    font-family: "Sinkin Sans Light";
-    font-size: 12px;
-    font-style: italic;
-
-    text-align: center;
-    text-anchor: middle;
-    color: white;
-}
-
-.ParametersElementNodeClass {
-    font-size: 11px;
-    height: 25px;
-    margin-top: 10px;
-    border: 1px solid white;
-
-    text-align: center;
-
-    margin-left: auto;
-    margin-right: auto;
-    width: 90%;
-}
-.ParametersElementNodeTextClass {
-    width: 100%;
-    height: 100%;
-
-    vertical-align: middle;
-    line-height: 25px;
-}
-.ParametersElementSeparatorClass {
-    width: 90%;
-}
-.ParametersElementTitleClass {
-    margin-left: 3em;
-    display: block;
-    color: white;
-    font-size: 11px;
-}
-.ParametersElementSelectClass {
-    margin-top: 15px;
-
-    width: 80%;
-    height: 25px;
-
-    display: block;
-    font-size: 11px;
-    margin-left: 3em;
-}
-.ParametersElementInputClass {
-    margin-top: 15px;
-
-    width: 80%;
-    height: 15px;
-
-    display: block;
-    font-size: 11px;
-    margin-left: 3em;
-}
-
-/*
-UL & LI (toolbar & top buttons)
-*/
-#ToolsButtonsID {
-    position: relative;
-
-    width: 100%;
-    height: 25px;
-
-    max-width: 100%;
-    max-height: 25px;
-}
-
-ul {
-  padding-left: 1em;
-  margin-bottom: 0.5em;
-  margin-top: 0.0em;
-}
-ul li {
-  list-style-type: none;
-  display: inline-block;
-  margin-right: 3em;
-  cursor: pointer;
-  font-size: 12px;
-}
-ul li:last-child {
-  margin-right: 0;
-}
+html, body {
+  width: 100%;
+  height: 100%;
+
+  max-width: 100%;
+  max-height: 100%;
+
+  /*background: rgb(64, 64, 64);*/
+
+  overflow: hidden;
+  font-family: "Sinkin Sans Light";
+}
+
+* {
+  position: relative;
+}
+
+#ParentContainerID {
+    height: 100%;
+    width: 100%;
+
+    max-height: 100%;
+    max-width: 100%;
+
+    display: inline-block;
+}
+
+#ListsElementID {
+    width: 25%;
+    height: 100%;
+    
+    max-width: 25%;
+    max-height: 100%;
+
+    background: rgb(64, 64, 64);
+
+    float: left;
+    overflow-y: scroll;
+    overflow-x: hidden;
+}
+
+#GraphContainerID {
+    width: 50%;
+    max-width: 50%;
+
+    float: left;
+    position: relative;
+}
+
+#GraphElementID {
+    position: absolute;
+
+    width: 100%;
+    height: 100%;
+
+    overflow-y: auto;
+    overflow-x: auto;
+
+    max-width: 100%;
+    max-height: 100%;
+}
+
+#ToolbarElementID {
+    position: absolute;
+
+    width: 100%;
+    height: 45px;
+
+    max-width: 100%;
+    max-height: 42px;
+
+    float: left;
+    background: rgb(0, 0, 0);
+
+    vertical-align: middle;
+}
+
+#ToolbarElementID li {
+    color: white;
+    margin-left: 2em;
+    margin-top: 1em;
+}
+
+#ParametersContainerID {
+    width: 25%;
+    height: 100%;
+
+    max-width: 25%;
+    max-height: 100%;
+
+    float: right;
+    overflow-y: auto;
+}
+
+#ParametersElementID {
+    width: 100%;
+    max-width: 100%;
+
+    background: rgb(32, 32, 32);
+    overflow: auto;
+}
+
+#ParametersHelpElementID {
+    background: rgb(0, 0, 0);
+
+    font-family: "Sinkin Sans Light";
+    font-size: 12px;
+    font-style: italic;
+
+    text-align: center;
+    text-anchor: middle;
+    color: white;
+}
+
+.ParametersElementNodeClass {
+    font-size: 11px;
+    height: 25px;
+    margin-top: 10px;
+    border: 1px solid white;
+
+    text-align: center;
+
+    margin-left: auto;
+    margin-right: auto;
+    width: 90%;
+}
+.ParametersElementNodeTextClass {
+    width: 100%;
+    height: 100%;
+
+    vertical-align: middle;
+    line-height: 25px;
+}
+.ParametersElementSeparatorClass {
+    width: 90%;
+}
+.ParametersElementTitleClass {
+    margin-left: 3em;
+    display: block;
+    color: white;
+    font-size: 11px;
+}
+.ParametersElementSelectClass {
+    margin-top: 15px;
+
+    width: 80%;
+    height: 25px;
+
+    display: block;
+    font-size: 11px;
+    margin-left: 3em;
+}
+.ParametersElementInputClass {
+    margin-top: 15px;
+
+    width: 80%;
+    height: 15px;
+
+    display: block;
+    font-size: 11px;
+    margin-left: 3em;
+}
+
+/*
+UL & LI (toolbar & top buttons)
+*/
+#ToolsButtonsID {
+    position: relative;
+
+    width: 100%;
+    height: 25px;
+
+    max-width: 100%;
+    max-height: 25px;
+}
+
+ul {
+  padding-left: 1em;
+  margin-bottom: 0.5em;
+  margin-top: 0.0em;
+}
+ul li {
+  list-style-type: none;
+  display: inline-block;
+  margin-right: 3em;
+  cursor: pointer;
+  font-size: 12px;
+}
+ul li:last-child {
+  margin-right: 0;
+}

+ 72 - 72
Exporters/3ds Max/ActionsBuilder/Sources/index.html

@@ -1,72 +1,72 @@
-<!-- saved from url=(0014)about:internet -->
-<!DOCTYPE html>
-<html xmlns="http://www.w3.org/1999/xhtml">
-
-<head>
-    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
-    <title>Actions Builder</title>
-
-    <!-- CSS FILES -->
-    <link href="./index.css" rel="stylesheet" />
-    <link href="./fonts.css" rel="stylesheet" />
-
-</head>
-
-<body>
-
-    <!-- PARENT CONTAINER -->
-    <div id="ParentContainerID">
-
-        <ul id="ToolsButtonsID">
-            <li id="ToolsButtonIDSaveActionGraph">save action graph</li>
-            <li id="ResetActionGraphID">reset action graph</li>
-            <li id="TestActionGraphID">test action graph</li>
-        </ul>
-
-        <!-- LIST CONTAINER -->
-        <div id="ListsElementID">
-            <div id="TriggersListID"></div>
-            <div id="ActionsListID"></div>
-            <div id="FlowActionsListID"></div>
-        </div>
-
-        <!-- GRAPH CONTAINER -->
-        <div id="GraphContainerID">
-            <div id="GraphElementID"></div>
-
-            <div id="ToolbarElementID">
-                <ul>
-                    <li id="ViewerReduceAll">reduce all</li>
-                    <li id="ViewerExpandAll">expand all</li>
-                    <li id="ViewerDisconnectAll">disconnect all</li>
-                    <li id="ViewerReconnectAll">reconnect all</li>
-                    <li class="border" style="width: 15px; text-align: center" id="ViewerDeZoomID"> - </li>
-                    <li class="border" style="width: 15px; text-align: center" id="ViewerZoomID"> + </li>
-                </ul>
-            </div>
-        </div>
-
-        <!-- PARAMETERS CONTAINER -->
-        <div id="ParametersContainerID">
-            <div id="ParametersElementID"></div>
-            <div id="ParametersHelpElementID"></div>
-        </div>
-
-    </div>
-
-    <canvas id="RenderCanvasID" style="display:none;"></canvas>
-    <input id="ActionsBuilderObjectName" type="hidden" />
-    <input id="ActionsBuilderJSON" type="hidden" />
-
-    <!-- JS FILES -->
-    <script src="raphael.js" type="text/javascript"></script>
-    <script src="babylon.max.js" type="text/javascript"></script>
-    <script src="actionsbuilder.max.js" type="text/javascript"></script>
-
-    <script type="text/javascript">
-        run();
-    </script>
-
-</body>
-
-</html>
+<!-- saved from url=(0014)about:internet -->
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml">
+
+<head>
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+    <title>Actions Builder</title>
+
+    <!-- CSS FILES -->
+    <link href="./index.css" rel="stylesheet" />
+    <link href="./fonts.css" rel="stylesheet" />
+
+</head>
+
+<body>
+
+    <!-- PARENT CONTAINER -->
+    <div id="ParentContainerID">
+
+        <ul id="ToolsButtonsID">
+            <li id="ToolsButtonIDSaveActionGraph">save action graph</li>
+            <li id="ResetActionGraphID">reset action graph</li>
+            <li id="TestActionGraphID">test action graph</li>
+        </ul>
+
+        <!-- LIST CONTAINER -->
+        <div id="ListsElementID">
+            <div id="TriggersListID"></div>
+            <div id="ActionsListID"></div>
+            <div id="FlowActionsListID"></div>
+        </div>
+
+        <!-- GRAPH CONTAINER -->
+        <div id="GraphContainerID">
+            <div id="GraphElementID"></div>
+
+            <div id="ToolbarElementID">
+                <ul>
+                    <li id="ViewerReduceAll">reduce all</li>
+                    <li id="ViewerExpandAll">expand all</li>
+                    <li id="ViewerDisconnectAll">disconnect all</li>
+                    <li id="ViewerReconnectAll">reconnect all</li>
+                    <li class="border" style="width: 15px; text-align: center" id="ViewerDeZoomID"> - </li>
+                    <li class="border" style="width: 15px; text-align: center" id="ViewerZoomID"> + </li>
+                </ul>
+            </div>
+        </div>
+
+        <!-- PARAMETERS CONTAINER -->
+        <div id="ParametersContainerID">
+            <div id="ParametersElementID"></div>
+            <div id="ParametersHelpElementID"></div>
+        </div>
+
+    </div>
+
+    <canvas id="RenderCanvasID" style="display:none;"></canvas>
+    <input id="ActionsBuilderObjectName" type="hidden" />
+    <input id="ActionsBuilderJSON" type="hidden" />
+
+    <!-- JS FILES -->
+    <script src="raphael.js" type="text/javascript"></script>
+    <script src="babylon.max.js" type="text/javascript"></script>
+    <script src="actionsbuilder.max.js" type="text/javascript"></script>
+
+    <script type="text/javascript">
+        run();
+    </script>
+
+</body>
+
+</html>

+ 62 - 0
Exporters/3ds Max/ActionsBuilder/actionsbuilder.actionNode.js

@@ -0,0 +1,62 @@
+var ActionsBuilder;
+(function (ActionsBuilder) {
+    var Node = (function () {
+        function Node() {
+            this.rect = null;
+            this.text = null;
+            this.line = null;
+            this.detached = false;
+            this.minimized = false;
+        }
+        Node.prototype.isPointInside = function (x, y) {
+            return this.rect.isPointInside(x, y) || this.text.isPointInside(x, y);
+        };
+        return Node;
+    })();
+    ActionsBuilder.Node = Node;
+    var Action = (function () {
+        function Action(node) {
+            this.parent = null;
+            this.children = new Array();
+            this.name = "";
+            this.type = ActionsBuilder.Type.OBJECT;
+            this.properties = new Array();
+            this.propertiesResults = new Array();
+            this.combineArray = null;
+            this.hub = null;
+            this.combineAction = null;
+            this.node = node;
+        }
+        Action.prototype.removeCombinedAction = function (action) {
+            if (action === null || this.combineArray === null) {
+                return false;
+            }
+            var index = this.combineArray.indexOf(action);
+            if (index !== -1) {
+                this.combineArray.splice(index, 1);
+            }
+            return false;
+        };
+        Action.prototype.addChild = function (child) {
+            if (child === null) {
+                return false;
+            }
+            this.children.push(child);
+            child.parent = this;
+            return true;
+        };
+        Action.prototype.removeChild = function (child) {
+            var indice = this.children.indexOf(child);
+            if (indice !== -1) {
+                this.children.splice(indice, 1);
+                return true;
+            }
+            return false;
+        };
+        Action.prototype.clearChildren = function () {
+            this.children = new Array();
+        };
+        return Action;
+    })();
+    ActionsBuilder.Action = Action;
+})(ActionsBuilder || (ActionsBuilder = {}));

+ 100 - 100
Exporters/3ds Max/ActionsBuilder/actionsbuilder.actionNode.ts

@@ -1,101 +1,101 @@
-module ActionsBuilder {
-    export class Node {
-        public rect: Rect = null;
-        public text: Text = null;
-        public line: Path = null;
-
-        public detached: boolean = false;
-        public minimized: boolean = false;
-
-        constructor()
-        { }
-
-        /**
-        * Returns if the point (x, y) is inside the text or rect
-        * @param x: the x position of the point
-        * @param y: the y position of the point
-        */
-        public isPointInside(x: number, y: number): boolean {
-            return this.rect.isPointInside(x, y) || this.text.isPointInside(x, y);
-        }
-    }
-
-    export class Action {
-        public node: Node;
-        public parent: Action = null;
-        public children: Array<Action> = new Array<Action>();
-
-        public name: string = "";
-        public type: number = Type.OBJECT;
-
-        public properties: Array<ElementProperty> = new Array<ElementProperty>();
-        public propertiesResults: Array<ElementPropertyResult> = new Array<ElementPropertyResult>();
-
-        public combineArray: Array<Action> = null;
-        public hub: Action = null;
-        public combineAction: Action = null;
-
-        /**
-        * Constructor
-        * @param node: The associated node to draw in the viewer
-        */
-        constructor(node: Node) {
-            this.node = node;
-        }
-        
-        /*
-        * Removes a combined action from the combine array
-        * @param action: the action to remove
-        */
-        public removeCombinedAction(action: Action): boolean {
-            if (action === null || this.combineArray === null) {
-                return false;
-            }
-
-            var index = this.combineArray.indexOf(action);
-            if (index !== -1) {
-                this.combineArray.splice(index, 1);
-            }
-
-            return false;
-        }
-
-        /*
-        * Adds a child
-        * @param child: the action to add as child
-        */
-        public addChild(child: Action): boolean {
-            if (child === null) {
-                return false;
-            }
-
-            this.children.push(child);
-            child.parent = this;
-
-            return true;
-        }
-
-        /*
-        * Removes the given action to children
-        * @param child: the child to remove
-        */
-        public removeChild(child: Action): boolean {
-            var indice = this.children.indexOf(child);
-
-            if (indice !== -1) {
-                this.children.splice(indice, 1);
-                return true;
-            }
-
-            return false;
-        }
-
-        /*
-        * Clears the children's array
-        */
-        public clearChildren(): void {
-            this.children = new Array<Action>();
-        }
-
-    }
+module ActionsBuilder {
+    export class Node {
+        public rect: Rect = null;
+        public text: Text = null;
+        public line: Path = null;
+
+        public detached: boolean = false;
+        public minimized: boolean = false;
+
+        constructor()
+        { }
+
+        /**
+        * Returns if the point (x, y) is inside the text or rect
+        * @param x: the x position of the point
+        * @param y: the y position of the point
+        */
+        public isPointInside(x: number, y: number): boolean {
+            return this.rect.isPointInside(x, y) || this.text.isPointInside(x, y);
+        }
+    }
+
+    export class Action {
+        public node: Node;
+        public parent: Action = null;
+        public children: Array<Action> = new Array<Action>();
+
+        public name: string = "";
+        public type: number = Type.OBJECT;
+
+        public properties: Array<ElementProperty> = new Array<ElementProperty>();
+        public propertiesResults: Array<ElementPropertyResult> = new Array<ElementPropertyResult>();
+
+        public combineArray: Array<Action> = null;
+        public hub: Action = null;
+        public combineAction: Action = null;
+
+        /**
+        * Constructor
+        * @param node: The associated node to draw in the viewer
+        */
+        constructor(node: Node) {
+            this.node = node;
+        }
+        
+        /*
+        * Removes a combined action from the combine array
+        * @param action: the action to remove
+        */
+        public removeCombinedAction(action: Action): boolean {
+            if (action === null || this.combineArray === null) {
+                return false;
+            }
+
+            var index = this.combineArray.indexOf(action);
+            if (index !== -1) {
+                this.combineArray.splice(index, 1);
+            }
+
+            return false;
+        }
+
+        /*
+        * Adds a child
+        * @param child: the action to add as child
+        */
+        public addChild(child: Action): boolean {
+            if (child === null) {
+                return false;
+            }
+
+            this.children.push(child);
+            child.parent = this;
+
+            return true;
+        }
+
+        /*
+        * Removes the given action to children
+        * @param child: the child to remove
+        */
+        public removeChild(child: Action): boolean {
+            var indice = this.children.indexOf(child);
+
+            if (indice !== -1) {
+                this.children.splice(indice, 1);
+                return true;
+            }
+
+            return false;
+        }
+
+        /*
+        * Clears the children's array
+        */
+        public clearChildren(): void {
+            this.children = new Array<Action>();
+        }
+
+    }
 }

+ 104 - 0
Exporters/3ds Max/ActionsBuilder/actionsbuilder.contextMenu.js

@@ -0,0 +1,104 @@
+var ActionsBuilder;
+(function (ActionsBuilder) {
+    var ContextMenu = (function () {
+        function ContextMenu(viewer) {
+            this.showing = false;
+            this.savedColor = Raphael.rgb(255, 255, 255);
+            this.overColor = Raphael.rgb(140, 200, 230);
+            this._viewer = null;
+            this.elements = [
+                { text: "Reduce", node: null, action: "onReduce" },
+                { text: "Delete", node: null, action: "onRemoveNode" },
+                { text: "Delete branch", node: null, action: "onRemoveBranch" },
+                { text: "Connect / Disconnect", node: null, action: "onDetachAction" },
+                { text: "Copy", node: null, action: "onCopyStructure" },
+                { text: "Paste", node: null, action: "onPasteStructure" },
+                { text: "", node: null, action: null }
+            ];
+            this._viewer = viewer;
+            this.attachControl(this._viewer.paper.canvas);
+        }
+        ContextMenu.prototype.attachControl = function (element) {
+            var _this = this;
+            var onClick = function (event) {
+                var x = _this._viewer.mousex;
+                var y = _this._viewer.mousey;
+                if (_this.showing) {
+                    for (var i = 0; i < _this.elements.length; i++) {
+                        var element = _this.elements[i];
+                        if (element.action && element.node.rect.isPointInside(x, y)) {
+                            _this._viewer.utils[element.action]();
+                            _this._viewer.update();
+                        }
+                        element.node.rect.remove();
+                        element.node.text.remove();
+                    }
+                }
+                _this.showing = false;
+            };
+            var onMouseMove = function (event) {
+                if (_this.showing) {
+                    for (var i = 0; i < _this.elements.length; i++) {
+                        var element = _this.elements[i];
+                        if (element.text === "")
+                            continue;
+                        var x = _this._viewer.mousex;
+                        var y = _this._viewer.mousey;
+                        if (element.node.rect.isPointInside(x, y)) {
+                            element.node.rect.attr("fill", _this.overColor);
+                        }
+                        else {
+                            element.node.rect.attr("fill", _this.savedColor);
+                        }
+                    }
+                }
+            };
+            var onRightClick = function (event) {
+                var x = _this._viewer.mousex;
+                var y = _this._viewer.mousey;
+                _this._viewer.onClick(event);
+                var result = _this._viewer.traverseGraph(null, x, y, true);
+                if (result.hit) {
+                }
+                if (y + (ActionsBuilder.Viewer.NODE_HEIGHT * _this.elements.length) > _this._viewer.viewerElement.offsetHeight + _this._viewer.viewerElement.scrollTop) {
+                    y = (ActionsBuilder.Viewer.NODE_HEIGHT * _this.elements.length);
+                }
+                if (x + ActionsBuilder.Viewer.NODE_WIDTH > _this._viewer.viewerElement.offsetWidth + _this._viewer.viewerElement.scrollLeft) {
+                    x -= ActionsBuilder.Viewer.NODE_WIDTH;
+                }
+                if (!_this.showing) {
+                    if (_this._viewer.selectedNode === null)
+                        return;
+                    var yOffset = 10;
+                    for (var i = 0; i < _this.elements.length - 1; i++) {
+                        var element = _this.elements[i];
+                        element.node = _this._viewer._createNode(element.text, ActionsBuilder.Type.OBJECT, true);
+                        element.node.rect.attr("fill", Raphael.rgb(216, 216, 216));
+                        element.node.rect.attr("x", x);
+                        element.node.rect.attr("y", y + yOffset);
+                        element.node.text.attr("x", x + 5);
+                        element.node.text.attr("y", y + yOffset + element.node.rect.attr("height") / 2);
+                        yOffset += ActionsBuilder.Viewer.NODE_HEIGHT;
+                    }
+                    var separator = _this.elements[_this.elements.length - 1];
+                    separator.node = _this._viewer._createNode("", ActionsBuilder.Type.OBJECT, true);
+                    separator.node.rect.attr("fill", _this._viewer.getNodeColor(_this._viewer.selectedNode.type, _this._viewer.selectedNode.node.detached));
+                    separator.node.rect.attr("x", x);
+                    separator.node.rect.attr("y", y);
+                    separator.node.rect.attr("height", 10);
+                    _this.showing = true;
+                }
+                else {
+                    onClick(event);
+                    onRightClick(event);
+                }
+                window.event.returnValue = false;
+            };
+            document.addEventListener("click", onClick);
+            document.addEventListener("mousemove", onMouseMove);
+            element.addEventListener("contextmenu", onRightClick);
+        };
+        return ContextMenu;
+    })();
+    ActionsBuilder.ContextMenu = ContextMenu;
+})(ActionsBuilder || (ActionsBuilder = {}));

+ 148 - 148
Exporters/3ds Max/ActionsBuilder/actionsbuilder.contextMenu.ts

@@ -1,149 +1,149 @@
-module ActionsBuilder {
-
-    export interface ContextMenuElement {
-        text: string;
-        node: Node;
-        action: string;
-    }
-
-    export class ContextMenu {
-        public showing: boolean = false;
-        public savedColor: RaphaelColor = Raphael.rgb(255, 255, 255);
-        public overColor: RaphaelColor = Raphael.rgb(140, 200, 230);
-
-        private _viewer: Viewer = null;
-        private elements: Array<ContextMenuElement> = [
-            { text: "Reduce", node: null, action: "onReduce" },
-            { text: "Delete", node: null, action: "onRemoveNode" },
-            { text: "Delete branch", node: null, action: "onRemoveBranch" },
-            { text: "Connect / Disconnect", node: null, action: "onDetachAction" },
-            { text: "Copy", node: null, action: "onCopyStructure" },
-            { text: "Paste", node: null, action: "onPasteStructure" },
-            // Add other elements here
-            { text: "", node: null, action: null } // Color separator (top)
-        ];
-
-        /*
-        * Constructor
-        * @param viewer: the graph viewer
-        */
-        constructor(viewer: Viewer) {
-            // Members
-            this._viewer = viewer;
-
-            // Configure
-            this.attachControl(this._viewer.paper.canvas);
-        }
-
-        public attachControl(element: HTMLElement): void {
-            var onClick = (event: MouseEvent) => {
-                var x = this._viewer.mousex;
-                var y = this._viewer.mousey;
-
-                // Remove all context menu nodes, and run action if selected
-                if (this.showing) {
-                    for (var i = 0; i < this.elements.length; i++) {
-                        var element = this.elements[i];
-
-                        if (element.action && element.node.rect.isPointInside(x, y)) {
-                            this._viewer.utils[element.action]();
-                            this._viewer.update();
-                        }
-
-                        element.node.rect.remove();
-                        element.node.text.remove();
-                    }
-                }
-                this.showing = false;
-            };
-
-            var onMouseMove = (event: MouseEvent) => {
-                // Override context menu's node color if mouse is inside
-                if (this.showing) {
-                    for (var i = 0; i < this.elements.length; i++) {
-                        var element = this.elements[i];
-
-                        if (element.text === "")
-                            continue;
-
-                        var x = this._viewer.mousex;
-                        var y = this._viewer.mousey;
-
-                        if (element.node.rect.isPointInside(x, y)) {
-                            element.node.rect.attr("fill", this.overColor);
-                        }
-                        else {
-                            element.node.rect.attr("fill", this.savedColor);
-                        }
-                    }
-                }
-            };
-
-            var onRightClick = (event: MouseEvent) => {
-                var x = this._viewer.mousex;
-                var y = this._viewer.mousey;
-
-                this._viewer.onClick(event);
-
-                // Set selected node
-                var result = this._viewer.traverseGraph(null, x, y, true);
-                if (result.hit) {
-                    //this._viewer.selectedNode = result.element;
-                }
-
-                // Properly draw the context menu on the screen
-                if (y + (Viewer.NODE_HEIGHT * this.elements.length) > this._viewer.viewerElement.offsetHeight + this._viewer.viewerElement.scrollTop) {
-                    y = (Viewer.NODE_HEIGHT * this.elements.length);
-                }
-                if (x + Viewer.NODE_WIDTH > this._viewer.viewerElement.offsetWidth + this._viewer.viewerElement.scrollLeft) {
-                    x -= Viewer.NODE_WIDTH;
-                }
-
-                if (!this.showing) {
-                    if (this._viewer.selectedNode === null)
-                        return;
-
-                    // Create elements
-                    var yOffset = 10;
-
-                    for (var i = 0; i < this.elements.length - 1; i++) {
-                        var element = this.elements[i];
-
-                        element.node = this._viewer._createNode(element.text, Type.OBJECT, true);
-                        element.node.rect.attr("fill", Raphael.rgb(216, 216, 216));
-
-                        element.node.rect.attr("x", x);
-                        element.node.rect.attr("y", y + yOffset);
-
-                        element.node.text.attr("x", x + 5);
-                        element.node.text.attr("y", y + yOffset + element.node.rect.attr("height") / 2);
-
-                        yOffset += Viewer.NODE_HEIGHT;
-                    }
-
-                    // Color separator
-                    var separator = this.elements[this.elements.length - 1];
-                    separator.node = this._viewer._createNode("", Type.OBJECT, true);
-                    separator.node.rect.attr("fill", this._viewer.getNodeColor(this._viewer.selectedNode.type, this._viewer.selectedNode.node.detached));
-
-                    separator.node.rect.attr("x", x);
-                    separator.node.rect.attr("y", y);
-                    separator.node.rect.attr("height", 10);
-
-                    // Finish
-                    this.showing = true;
-                }
-                else {
-                    onClick(event);
-                    onRightClick(event);
-                }
-
-                window.event.returnValue = false;
-            };
-
-            document.addEventListener("click", onClick);
-            document.addEventListener("mousemove", onMouseMove);
-            element.addEventListener("contextmenu", onRightClick);
-        }
-    }
+module ActionsBuilder {
+
+    export interface ContextMenuElement {
+        text: string;
+        node: Node;
+        action: string;
+    }
+
+    export class ContextMenu {
+        public showing: boolean = false;
+        public savedColor: RaphaelColor = Raphael.rgb(255, 255, 255);
+        public overColor: RaphaelColor = Raphael.rgb(140, 200, 230);
+
+        private _viewer: Viewer = null;
+        private elements: Array<ContextMenuElement> = [
+            { text: "Reduce", node: null, action: "onReduce" },
+            { text: "Delete", node: null, action: "onRemoveNode" },
+            { text: "Delete branch", node: null, action: "onRemoveBranch" },
+            { text: "Connect / Disconnect", node: null, action: "onDetachAction" },
+            { text: "Copy", node: null, action: "onCopyStructure" },
+            { text: "Paste", node: null, action: "onPasteStructure" },
+            // Add other elements here
+            { text: "", node: null, action: null } // Color separator (top)
+        ];
+
+        /*
+        * Constructor
+        * @param viewer: the graph viewer
+        */
+        constructor(viewer: Viewer) {
+            // Members
+            this._viewer = viewer;
+
+            // Configure
+            this.attachControl(this._viewer.paper.canvas);
+        }
+
+        public attachControl(element: HTMLElement): void {
+            var onClick = (event: MouseEvent) => {
+                var x = this._viewer.mousex;
+                var y = this._viewer.mousey;
+
+                // Remove all context menu nodes, and run action if selected
+                if (this.showing) {
+                    for (var i = 0; i < this.elements.length; i++) {
+                        var element = this.elements[i];
+
+                        if (element.action && element.node.rect.isPointInside(x, y)) {
+                            this._viewer.utils[element.action]();
+                            this._viewer.update();
+                        }
+
+                        element.node.rect.remove();
+                        element.node.text.remove();
+                    }
+                }
+                this.showing = false;
+            };
+
+            var onMouseMove = (event: MouseEvent) => {
+                // Override context menu's node color if mouse is inside
+                if (this.showing) {
+                    for (var i = 0; i < this.elements.length; i++) {
+                        var element = this.elements[i];
+
+                        if (element.text === "")
+                            continue;
+
+                        var x = this._viewer.mousex;
+                        var y = this._viewer.mousey;
+
+                        if (element.node.rect.isPointInside(x, y)) {
+                            element.node.rect.attr("fill", this.overColor);
+                        }
+                        else {
+                            element.node.rect.attr("fill", this.savedColor);
+                        }
+                    }
+                }
+            };
+
+            var onRightClick = (event: MouseEvent) => {
+                var x = this._viewer.mousex;
+                var y = this._viewer.mousey;
+
+                this._viewer.onClick(event);
+
+                // Set selected node
+                var result = this._viewer.traverseGraph(null, x, y, true);
+                if (result.hit) {
+                    //this._viewer.selectedNode = result.element;
+                }
+
+                // Properly draw the context menu on the screen
+                if (y + (Viewer.NODE_HEIGHT * this.elements.length) > this._viewer.viewerElement.offsetHeight + this._viewer.viewerElement.scrollTop) {
+                    y = (Viewer.NODE_HEIGHT * this.elements.length);
+                }
+                if (x + Viewer.NODE_WIDTH > this._viewer.viewerElement.offsetWidth + this._viewer.viewerElement.scrollLeft) {
+                    x -= Viewer.NODE_WIDTH;
+                }
+
+                if (!this.showing) {
+                    if (this._viewer.selectedNode === null)
+                        return;
+
+                    // Create elements
+                    var yOffset = 10;
+
+                    for (var i = 0; i < this.elements.length - 1; i++) {
+                        var element = this.elements[i];
+
+                        element.node = this._viewer._createNode(element.text, Type.OBJECT, true);
+                        element.node.rect.attr("fill", Raphael.rgb(216, 216, 216));
+
+                        element.node.rect.attr("x", x);
+                        element.node.rect.attr("y", y + yOffset);
+
+                        element.node.text.attr("x", x + 5);
+                        element.node.text.attr("y", y + yOffset + element.node.rect.attr("height") / 2);
+
+                        yOffset += Viewer.NODE_HEIGHT;
+                    }
+
+                    // Color separator
+                    var separator = this.elements[this.elements.length - 1];
+                    separator.node = this._viewer._createNode("", Type.OBJECT, true);
+                    separator.node.rect.attr("fill", this._viewer.getNodeColor(this._viewer.selectedNode.type, this._viewer.selectedNode.node.detached));
+
+                    separator.node.rect.attr("x", x);
+                    separator.node.rect.attr("y", y);
+                    separator.node.rect.attr("height", 10);
+
+                    // Finish
+                    this.showing = true;
+                }
+                else {
+                    onClick(event);
+                    onRightClick(event);
+                }
+
+                window.event.returnValue = false;
+            };
+
+            document.addEventListener("click", onClick);
+            document.addEventListener("mousemove", onMouseMove);
+            element.addEventListener("contextmenu", onRightClick);
+        }
+    }
 } 

+ 316 - 0
Exporters/3ds Max/ActionsBuilder/actionsbuilder.js

@@ -0,0 +1,316 @@
+var ActionsBuilder;
+(function (ActionsBuilder) {
+    var Type = (function () {
+        function Type() {
+        }
+        Object.defineProperty(Type, "TRIGGER", {
+            get: function () {
+                return Type._TRIGGER;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(Type, "ACTION", {
+            get: function () {
+                return Type._ACTION;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(Type, "FLOW_CONTROL", {
+            get: function () {
+                return Type._FLOW_CONTROL;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(Type, "OBJECT", {
+            get: function () {
+                return Type._OBJECT;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(Type, "SCENE", {
+            get: function () {
+                return Type._SCENE;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Type._TRIGGER = 0;
+        Type._ACTION = 1;
+        Type._FLOW_CONTROL = 2;
+        Type._OBJECT = 3;
+        Type._SCENE = 4;
+        return Type;
+    })();
+    ActionsBuilder.Type = Type;
+    var SceneElements = (function () {
+        function SceneElements() {
+        }
+        Object.defineProperty(SceneElements, "ENGINE", {
+            get: function () {
+                return SceneElements._ENGINE;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(SceneElements, "SCENE", {
+            get: function () {
+                return SceneElements._SCENE;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(SceneElements, "MESH", {
+            get: function () {
+                return SceneElements._MESH;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(SceneElements, "LIGHT", {
+            get: function () {
+                return SceneElements._LIGHT;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(SceneElements, "CAMERA", {
+            get: function () {
+                return SceneElements._CAMERA;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(SceneElements, "MESHES", {
+            get: function () {
+                return SceneElements._MESHES;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(SceneElements, "LIGHTS", {
+            get: function () {
+                return SceneElements._LIGHTS;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(SceneElements, "CAMERAS", {
+            get: function () {
+                return SceneElements._CAMERAS;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(SceneElements, "SOUNDS", {
+            get: function () {
+                return SceneElements._SOUNDS;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(SceneElements, "MESH_PROPERTIES", {
+            get: function () {
+                return SceneElements._MESH_PROPERTIES;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(SceneElements, "LIGHT_PROPERTIES", {
+            get: function () {
+                return SceneElements._LIGHT_PROPERTIES;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(SceneElements, "CAMERA_PROPERTIES", {
+            get: function () {
+                return SceneElements._CAMERA_PROPERTIES;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(SceneElements, "SCENE_PROPERTIES", {
+            get: function () {
+                return SceneElements._SCENE_PROPERTIES;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(SceneElements, "TYPES", {
+            get: function () {
+                return SceneElements._TYPES;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(SceneElements, "OPERATORS", {
+            get: function () {
+                return SceneElements._OPERATORS;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        SceneElements.GetInstanceOf = function (object) {
+            if (object === null || object === undefined) {
+                return "";
+            }
+            return object.constructor.toString().match(/function (\w*)/)[1];
+        };
+        SceneElements.TestInstanceOf = function (object, propertyName) {
+            if (object === null || object.constructor === null) {
+                return false;
+            }
+            if (propertyName.length > 0 && propertyName[0] === "_")
+                return false;
+            var name = SceneElements.GetInstanceOf(object);
+            for (var i = 0; i < SceneElements.TYPES.length; i++) {
+                if (name === SceneElements.TYPES[i]) {
+                    return true;
+                }
+            }
+            return false;
+        };
+        SceneElements._ENGINE = new BABYLON.Engine(document.getElementById("RenderCanvasID"));
+        SceneElements._SCENE = new BABYLON.Scene(SceneElements.ENGINE);
+        SceneElements._MESH = new BABYLON.Mesh("mesh", SceneElements._SCENE);
+        SceneElements._LIGHT = new BABYLON.Light("light", SceneElements._SCENE);
+        SceneElements._CAMERA = new BABYLON.Camera("camera", BABYLON.Vector3.Zero(), SceneElements._SCENE);
+        SceneElements._MESHES = new Array();
+        SceneElements._LIGHTS = new Array();
+        SceneElements._CAMERAS = new Array();
+        SceneElements._SOUNDS = new Array();
+        SceneElements._MESH_PROPERTIES = new Array();
+        SceneElements._LIGHT_PROPERTIES = new Array();
+        SceneElements._CAMERA_PROPERTIES = new Array();
+        SceneElements._SCENE_PROPERTIES = new Array();
+        SceneElements._TYPES = new Array();
+        SceneElements._OPERATORS = new Array();
+        return SceneElements;
+    })();
+    ActionsBuilder.SceneElements = SceneElements;
+    var specialTypes = [
+        "StandardMaterial"
+    ];
+    SceneElements.MESH.material = new BABYLON.StandardMaterial("material", SceneElements.SCENE);
+    var addSpecialType = function (object, properties, thing) {
+        for (var specialThing in object[thing]) {
+            if (object[thing].hasOwnProperty(specialThing) && SceneElements.TestInstanceOf(object[thing][specialThing], specialThing)) {
+                properties.push(thing + "." + specialThing);
+            }
+        }
+    };
+    SceneElements.TYPES.push("Color3");
+    SceneElements.TYPES.push("Boolean");
+    SceneElements.TYPES.push("Number");
+    SceneElements.TYPES.push("Vector2");
+    SceneElements.TYPES.push("Vector3");
+    SceneElements.TYPES.push("String");
+    SceneElements.OPERATORS.push("IsEqual");
+    SceneElements.OPERATORS.push("IsDifferent");
+    SceneElements.OPERATORS.push("IsGreater");
+    SceneElements.OPERATORS.push("IsLesser");
+    for (var thing in SceneElements.MESH) {
+        var instance = SceneElements.GetInstanceOf(SceneElements.MESH[thing]);
+        if (SceneElements.MESH.hasOwnProperty(thing)) {
+            if (specialTypes.indexOf(instance) !== -1) {
+                addSpecialType(SceneElements.MESH, SceneElements.MESH_PROPERTIES, thing);
+            }
+            else if (SceneElements.TestInstanceOf(SceneElements.MESH[thing], thing)) {
+                SceneElements.MESH_PROPERTIES.push(thing);
+            }
+        }
+    }
+    for (var thing in SceneElements.LIGHT) {
+        if (SceneElements.LIGHT.hasOwnProperty(thing) && SceneElements.TestInstanceOf(SceneElements.LIGHT[thing], thing)) {
+            SceneElements.LIGHT_PROPERTIES.push(thing);
+        }
+    }
+    for (var thing in SceneElements.CAMERA) {
+        if (SceneElements.CAMERA.hasOwnProperty(thing) && SceneElements.TestInstanceOf(SceneElements.CAMERA[thing], thing)) {
+            SceneElements.CAMERA_PROPERTIES.push(thing);
+        }
+    }
+    for (var thing in SceneElements.SCENE) {
+        if (SceneElements.SCENE.hasOwnProperty(thing) && SceneElements.TestInstanceOf(SceneElements.SCENE[thing], thing)) {
+            SceneElements.SCENE_PROPERTIES.push(thing);
+        }
+    }
+    var Elements = (function () {
+        function Elements() {
+        }
+        Object.defineProperty(Elements, "TRIGGERS", {
+            get: function () {
+                return Elements._TRIGGERS;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(Elements, "ACTIONS", {
+            get: function () {
+                return Elements._ACTIONS;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(Elements, "FLOW_CONTROLS", {
+            get: function () {
+                return Elements._FLOW_CONTROLS;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Elements.GetElementFromName = function (name) {
+            for (var i = 0; i < Elements.TRIGGERS.length; i++) {
+                if (Elements.TRIGGERS[i].name === name) {
+                    return Elements._TRIGGERS[i];
+                }
+            }
+            for (var i = 0; i < Elements.ACTIONS.length; i++) {
+                if (Elements.ACTIONS[i].name === name) {
+                    return Elements._ACTIONS[i];
+                }
+            }
+            for (var i = 0; i < Elements.FLOW_CONTROLS.length; i++) {
+                if (Elements.FLOW_CONTROLS[i].name === name) {
+                    return Elements._FLOW_CONTROLS[i];
+                }
+            }
+            return null;
+        };
+        Elements._TRIGGERS = new Array();
+        Elements._ACTIONS = new Array();
+        Elements._FLOW_CONTROLS = new Array();
+        return Elements;
+    })();
+    ActionsBuilder.Elements = Elements;
+    Elements.TRIGGERS.push({ name: "OnPickTrigger", text: "pick", properties: [], description: "When the user picks the edited mesh" });
+    Elements.TRIGGERS.push({ name: "OnLeftPickTrigger", text: "left pick", properties: [], description: "When the user picks the edited mesh using the left click" });
+    Elements.TRIGGERS.push({ name: "OnRightPickTrigger", text: "right pick", properties: [], description: "When the user picks the edited mesh using the right click" });
+    Elements.TRIGGERS.push({ name: "OnCenterPickTrigger", text: "center pick", properties: [], description: "When the user picks the edited mesh using the click of the mouse wheel" });
+    Elements.TRIGGERS.push({ name: "OnPointerOverTrigger", text: "pointer over", properties: [], description: "When the user's mouse is over the edited mesh" });
+    Elements.TRIGGERS.push({ name: "OnPointerOutTrigger", text: "pointer out", properties: [], description: "When the user's mouse is out of the edited mesh" });
+    Elements.TRIGGERS.push({ name: "OnEveryFrameTrigger", text: "every frame", properties: [], description: "This trigger is called each frame (only on scene)" });
+    Elements.TRIGGERS.push({ name: "OnIntersectionEnterTrigger", text: "intersection enter", properties: [{ targetType: "MeshProperties", text: "parameter", value: "Object name?" }], description: "When the edited mesh intersects the another mesh predefined in the options" });
+    Elements.TRIGGERS.push({ name: "OnIntersectionExitTrigger", text: "intersection exit", properties: [{ targetType: "MeshProperties", text: "parameter", value: "Object name?" }], description: "When the edited mesh exits intersection with the another mesh predefined in the options" });
+    Elements.TRIGGERS.push({ name: "OnKeyDownTrigger", text: "key down", properties: [{ targetType: null, text: "parameter:", value: "a" }], description: "When the user pressed a key (enter the key character, example: \"r\")" });
+    Elements.TRIGGERS.push({ name: "OnKeyUpTrigger", text: "key up", properties: [{ targetType: null, text: "parameter:", value: "a" }], description: "When the user unpressed a key (enter the key character, example: \"p\")" });
+    Elements.ACTIONS.push({ name: "SwitchBooleanAction", text: "switch boolean", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "propertyPath", value: "" }], description: "Switches the boolean value of a given parameter of the target object: true to false, or false to true" });
+    Elements.ACTIONS.push({ name: "SetStateAction", text: "set state", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "value", value: "" }], description: "Sets a new state value for the target object (example: \"off\" or \"on\")" });
+    Elements.ACTIONS.push({ name: "SetValueAction", text: "set value", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "propertyPath", value: "" }, { text: "value", value: "" }], description: "Sets a new value to the specified parameter of the target object (example: position.x to 0.0)" });
+    Elements.ACTIONS.push({ name: "SetParentAction", text: "set parent", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "parent", value: "" }], description: "Sets the new parent of the target object (example: a mesh or a light)" });
+    Elements.ACTIONS.push({ name: "IncrementValueAction", text: "increment value", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "propertyPath", value: "" }, { text: "value", value: "" }], description: "Increments the value of the given parameter of the target object. The value can be negative. (example: increment position.x of 5.0)" });
+    Elements.ACTIONS.push({ name: "PlayAnimationAction", text: "play animation", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "from", value: "0" }, { text: "to", value: "150" }, { text: "loop", value: "false" }], description: "Plays an animation of the target object. Specify the start frame, the end frame and if the animation should loop." });
+    Elements.ACTIONS.push({ name: "StopAnimationAction", text: "stop animation", properties: [{ targetType: "MeshProperties", text: "target", value: "" }], description: "Stops the animations of the target object." });
+    Elements.ACTIONS.push({ name: "DoNothingAction", text: "do nothing", properties: [], description: "Does nothing, can be used to balance/equilibrate the actions graph." });
+    Elements.ACTIONS.push({ name: "InterpolateValueAction", text: "interpolate value", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "propertyPath", value: "" }, { text: "value", value: "0" }, { text: "duration", value: "1000" }, { text: "stopOtherAnimations", value: "false" }], description: "Creates an animation (key frames) that animates the target object by interpolating the given parameter of the target value." });
+    Elements.ACTIONS.push({ name: "PlaySoundAction", text: "play sound", properties: [{ text: "sound", value: "" }], description: "Plays the specified sound." });
+    Elements.ACTIONS.push({ name: "StopSoundAction", text: "stop sound", properties: [{ text: "sound", value: "" }], description: "Stops the specified sound." });
+    Elements.ACTIONS.push({ name: "CombineAction", text: "combine", properties: [], description: "Special action that combines multiple actions. The combined actions are executed at the same time. Drag'n'drop the new actions inside to combine actions." });
+    Elements.FLOW_CONTROLS.push({ name: "ValueCondition", text: "value condition", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "propertyPath", value: "" }, { text: "value", value: "" }, { text: "operator", value: SceneElements.OPERATORS[0] }], description: "A condition checking if a given value is equal, different, lesser or greater than the given parameter of the target object" });
+    Elements.FLOW_CONTROLS.push({ name: "StateCondition", text: "state condition", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "value", value: "" }], description: "A condition checking if the target object's state is equal to the given state. See \"set state\" action to set a state to an object." });
+    Elements.FLOW_CONTROLS.push({ name: "Hub", text: "hub", properties: [], description: "The hub is internally used by the Combine Action. It allows to add children to the Combine Action" });
+})(ActionsBuilder || (ActionsBuilder = {}));

+ 209 - 0
Exporters/3ds Max/ActionsBuilder/actionsbuilder.list.js

@@ -0,0 +1,209 @@
+var ActionsBuilder;
+(function (ActionsBuilder) {
+    var ListElement = (function () {
+        function ListElement() {
+            this.rect = null;
+            this.text = null;
+            this.name = "";
+            this.type = ActionsBuilder.Type.TRIGGER;
+            this.element = null;
+        }
+        return ListElement;
+    })();
+    ActionsBuilder.ListElement = ListElement;
+    var List = (function () {
+        function List(viewer) {
+            var _this = this;
+            this._listElements = new Array();
+            this.listElement = document.getElementById("ListsElementID");
+            this.triggersElement = document.getElementById("TriggersListID");
+            this.actionsElement = document.getElementById("ActionsListID");
+            this.flowControlsElement = document.getElementById("FlowActionsListID");
+            this._parentContainer = document.getElementById("ParentContainerID");
+            this._viewer = viewer;
+            this.triggersList = Raphael("TriggersListID", (25 * screen.width) / 100, 400);
+            this.actionsList = Raphael("ActionsListID", (25 * screen.width) / 100, 400);
+            this.flowControlsList = Raphael("FlowActionsListID", (25 * screen.width) / 100, 400);
+            window.addEventListener("resize", function (event) {
+                _this.onResize(event);
+            });
+        }
+        Object.defineProperty(List, "ELEMENT_HEIGHT", {
+            get: function () {
+                return 25;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        List.prototype.onResize = function (event) {
+            var tools = document.getElementById("ToolsButtonsID");
+            this.listElement.style.height = window.innerHeight - tools.getBoundingClientRect().height - 25 + "px";
+            var listElementWidth = this.listElement.getBoundingClientRect().width;
+            for (var i = 0; i < this._listElements.length; i++) {
+                var rect = this._listElements[i].rect;
+                rect.attr("width", listElementWidth - 40);
+            }
+            this.triggersList.setSize(listElementWidth, this.triggersList.height);
+            this.actionsList.setSize(listElementWidth, this.triggersList.height);
+            this.flowControlsList.setSize(listElementWidth, this.triggersList.height);
+        };
+        List.prototype.createListsElements = function () {
+            var excludedTriggers = [6, 9, 10];
+            var yPosition = 10;
+            var textColor = Raphael.rgb(61, 72, 76);
+            var whiteColor = Raphael.rgb(255, 255, 255);
+            var configureTitle = function (listElement, rectColor) {
+                listElement.text.attr("x", 15);
+                listElement.rect.attr("fill", rectColor);
+                listElement.text.attr("font-family", "Sinkin Sans Medium");
+                listElement.text.attr("font-size", "11");
+            };
+            var triggers = this._createListElement(this.triggersList, yPosition, "TRIGGERS", ActionsBuilder.Type.TRIGGER, whiteColor, false);
+            yPosition += List.ELEMENT_HEIGHT;
+            configureTitle(triggers, Raphael.rgb(41, 129, 255));
+            for (var i = 0; i < ActionsBuilder.Elements.TRIGGERS.length; i++) {
+                var element = ActionsBuilder.Elements.TRIGGERS[i];
+                if (this._viewer.root.type === ActionsBuilder.Type.OBJECT && excludedTriggers.indexOf(i) !== -1) {
+                    continue;
+                }
+                else if (this._viewer.root.type === ActionsBuilder.Type.SCENE && excludedTriggers.indexOf(i) === -1) {
+                    continue;
+                }
+                var trigger = this._createListElement(this.triggersList, yPosition, element.text, ActionsBuilder.Type.TRIGGER, textColor, true, element);
+                trigger.rect.attr("fill", Raphael.rgb(133, 154, 185));
+                yPosition += List.ELEMENT_HEIGHT;
+            }
+            yPosition += List.ELEMENT_HEIGHT;
+            this.triggersElement.style.height = this.triggersList.canvas.style.height = yPosition + "px";
+            this._createCollapseAnimation(this.triggersList, this.triggersElement, triggers, yPosition);
+            yPosition = 10;
+            var actions = this._createListElement(this.actionsList, yPosition, "ACTIONS", ActionsBuilder.Type.ACTION, textColor, false);
+            yPosition += List.ELEMENT_HEIGHT;
+            configureTitle(actions, Raphael.rgb(255, 220, 42));
+            for (var i = 0; i < ActionsBuilder.Elements.ACTIONS.length; i++) {
+                var element = ActionsBuilder.Elements.ACTIONS[i];
+                var action = this._createListElement(this.actionsList, yPosition, element.text, ActionsBuilder.Type.ACTION, textColor, true, element);
+                action.rect.attr("fill", Raphael.rgb(182, 185, 132));
+                yPosition += List.ELEMENT_HEIGHT;
+            }
+            yPosition += List.ELEMENT_HEIGHT;
+            this.actionsElement.style.height = this.actionsList.canvas.style.height = yPosition + "px";
+            this._createCollapseAnimation(this.actionsList, this.actionsElement, actions, yPosition);
+            yPosition = 10;
+            var flowControls = this._createListElement(this.flowControlsList, yPosition, "FLOW CONTROLS", ActionsBuilder.Type.FLOW_CONTROL, whiteColor, false);
+            yPosition += List.ELEMENT_HEIGHT;
+            configureTitle(flowControls, Raphael.rgb(255, 41, 53));
+            for (var i = 0; i < ActionsBuilder.Elements.FLOW_CONTROLS.length - 1; i++) {
+                var element = ActionsBuilder.Elements.FLOW_CONTROLS[i];
+                var flowControl = this._createListElement(this.flowControlsList, yPosition, element.text, ActionsBuilder.Type.FLOW_CONTROL, textColor, true, element);
+                flowControl.rect.attr("fill", Raphael.rgb(185, 132, 140));
+                yPosition += List.ELEMENT_HEIGHT;
+            }
+            yPosition += List.ELEMENT_HEIGHT;
+            this.flowControlsElement.style.height = this.flowControlsList.canvas.style.height = yPosition + "px";
+            this._createCollapseAnimation(this.flowControlsList, this.flowControlsElement, flowControls, yPosition);
+        };
+        List.prototype.clearLists = function () {
+            for (var i = 0; i < this._listElements.length; i++) {
+                this._removeListElement(this._listElements[i]);
+            }
+            this._listElements.splice(0, this._listElements.length - 1);
+        };
+        List.prototype.setColorTheme = function (color) {
+            this.triggersList.canvas.style.backgroundColor = color;
+            this.actionsList.canvas.style.backgroundColor = color;
+            this.flowControlsList.canvas.style.backgroundColor = color;
+        };
+        List.prototype._createListElement = function (paper, yPosition, text, type, textColor, drag, element) {
+            var object = new ListElement();
+            object.rect = paper.rect(10, yPosition, 300, List.ELEMENT_HEIGHT);
+            object.text = paper.text(30, yPosition + object.rect.attr("height") / 2, text);
+            object.text.attr("fill", textColor);
+            object.text.attr("text-anchor", "start");
+            object.text.attr("font-size", "12");
+            object.text.attr("text-anchor", "start");
+            object.text.attr("font-family", "Sinkin Sans Light");
+            if (drag) {
+                this._createListElementAnimation(object);
+            }
+            object.type = type;
+            object.element = element;
+            this._listElements.push(object);
+            return object;
+        };
+        List.prototype._removeListElement = function (element) {
+            element.rect.remove();
+            element.text.remove();
+        };
+        List.prototype._createCollapseAnimation = function (paper, htmlElement, element, expandedHeight) {
+            var onClick = function (event) {
+                var height = htmlElement.style.height;
+                if (height === expandedHeight + "px") {
+                    htmlElement.style.height = paper.canvas.style.height = 35 + "px";
+                }
+                else {
+                    htmlElement.style.height = paper.canvas.style.height = expandedHeight + "px";
+                }
+            };
+            element.rect.click(onClick);
+        };
+        List.prototype._createListElementAnimation = function (element) {
+            var _this = this;
+            var onMove = function (dx, dy, x, y) { };
+            var onStart = function (x, y, event) {
+                _this._parentContainer.style.cursor = "copy";
+                element.rect.animate({
+                    x: -10,
+                    opacity: 0.25
+                }, 500, ">");
+                element.text.animate({
+                    x: 10,
+                    opacity: 0.25
+                }, 500, ">");
+            };
+            var onEnd = function (event) {
+                _this._parentContainer.style.cursor = "default";
+                element.rect.animate({
+                    x: 10,
+                    opacity: 1.0
+                }, 500, "<");
+                element.text.animate({
+                    x: 30,
+                    opacity: 1.0
+                }, 500, "<");
+                var dragResult = _this._viewer.traverseGraph(null, _this._viewer.mousex, _this._viewer.mousey, false);
+                if (dragResult.hit) {
+                    if (element.type === ActionsBuilder.Type.TRIGGER && dragResult.action !== _this._viewer.root) {
+                        alert("Triggers can be dragged only on the root node (the mesh)");
+                        return;
+                    }
+                    if (element.type === ActionsBuilder.Type.ACTION && dragResult.action === _this._viewer.root) {
+                        alert("Please add a trigger before.");
+                        return;
+                    }
+                    if (element.type === ActionsBuilder.Type.FLOW_CONTROL && dragResult.action === _this._viewer.root) {
+                        return;
+                    }
+                    if (element.type === ActionsBuilder.Type.FLOW_CONTROL && dragResult.action.combineArray !== null) {
+                        alert("A condition cannot be handled by a Combine Action.");
+                        return;
+                    }
+                    if ((element.type === ActionsBuilder.Type.FLOW_CONTROL || element.type === ActionsBuilder.Type.ACTION) && dragResult.action.type === ActionsBuilder.Type.TRIGGER && dragResult.action.children.length > 0) {
+                        alert("Triggers can have only one child. Please add another trigger of same type.");
+                        return;
+                    }
+                    if (!(dragResult.action.combineArray !== null) && dragResult.action.children.length > 0 && dragResult.action.type !== ActionsBuilder.Type.TRIGGER && dragResult.action !== _this._viewer.root) {
+                        alert("An action can have only one child.");
+                        return;
+                    }
+                    _this._viewer.addAction(dragResult.action, element.type, element.element);
+                    _this._viewer.update();
+                }
+            };
+            element.rect.drag(onMove, onStart, onEnd);
+            element.text.drag(onMove, onStart, onEnd);
+        };
+        return List;
+    })();
+    ActionsBuilder.List = List;
+})(ActionsBuilder || (ActionsBuilder = {}));

+ 305 - 305
Exporters/3ds Max/ActionsBuilder/actionsbuilder.list.ts

@@ -1,306 +1,306 @@
-module ActionsBuilder {
-    export class ListElement {
-        public rect: Rect = null;
-        public text: Text = null;
-        public name: string = "";
-        public type: number = Type.TRIGGER;
-        public element: Element = null;
-    }
-
-    export class List {
-        public listElement: HTMLElement;
-        public triggersElement: HTMLElement;
-        public actionsElement: HTMLElement;
-        public flowControlsElement: HTMLElement;
-
-        public triggersList: Paper;
-        public actionsList: Paper;
-        public flowControlsList: Paper;
-
-        private _parentContainer: HTMLElement;
-        private _listElements: Array<ListElement> = new Array<ListElement>();
-        private _viewer: Viewer;
-
-        public static get ELEMENT_HEIGHT(): number {
-            return 25;
-        }
-
-        /**
-        * Constructor
-        */
-        constructor(viewer: Viewer) {
-            // Get HTML elements
-            this.listElement = document.getElementById("ListsElementID");
-            this.triggersElement = document.getElementById("TriggersListID");
-            this.actionsElement = document.getElementById("ActionsListID");
-            this.flowControlsElement = document.getElementById("FlowActionsListID");
-            this._parentContainer = document.getElementById("ParentContainerID");
-
-            // Configure this
-            this._viewer = viewer;
-
-            // Create elements (lists)
-            this.triggersList = Raphael("TriggersListID", (25 * screen.width) / 100, 400);
-            this.actionsList = Raphael("ActionsListID", (25 * screen.width) / 100, 400);
-            this.flowControlsList = Raphael("FlowActionsListID", (25 * screen.width) / 100, 400);
-
-            // Manage events
-            window.addEventListener("resize", (event: Event) => {
-                this.onResize(event);
-            });
-        }
-
-        /**
-        * Resize event that resizes the list element dynamically
-        * @param event: the resize event
-        */
-        public onResize(event?: Event): void {
-            var tools = document.getElementById("ToolsButtonsID");
-            this.listElement.style.height = window.innerHeight - tools.getBoundingClientRect().height - 25 + "px";
-
-            var listElementWidth = this.listElement.getBoundingClientRect().width;
-            for (var i = 0; i < this._listElements.length; i++) {
-                var rect = this._listElements[i].rect;
-                rect.attr("width", listElementWidth - 40);
-            }
-
-            this.triggersList.setSize(listElementWidth, this.triggersList.height);
-            this.actionsList.setSize(listElementWidth, this.triggersList.height);
-            this.flowControlsList.setSize(listElementWidth, this.triggersList.height);
-
-        }
-
-        public createListsElements(): void {
-            var excludedTriggers = [6, 9, 10];
-            var yPosition = 10;
-            var textColor = Raphael.rgb(61, 72, 76);
-            var whiteColor = Raphael.rgb(255, 255, 255);
-
-            var configureTitle = (listElement: ListElement, rectColor: RaphaelColor) => {
-                listElement.text.attr("x", 15);
-                listElement.rect.attr("fill", rectColor);
-                listElement.text.attr("font-family", "Sinkin Sans Medium");
-                listElement.text.attr("font-size", "11");
-            };
-
-            // Create triggers
-            var triggers = this._createListElement(this.triggersList, yPosition, "TRIGGERS", Type.TRIGGER, whiteColor, false);
-            yPosition += List.ELEMENT_HEIGHT;
-            configureTitle(triggers, Raphael.rgb(41, 129, 255));
-
-            for (var i = 0; i < Elements.TRIGGERS.length; i++) {
-                var element: any = Elements.TRIGGERS[i];
-
-                if (this._viewer.root.type === Type.OBJECT && excludedTriggers.indexOf(i) !== -1) {
-                    continue;
-                }
-                else if (this._viewer.root.type === Type.SCENE && excludedTriggers.indexOf(i) === -1) {
-                    continue;
-                }
-
-                var trigger = this._createListElement(this.triggersList, yPosition, element.text, Type.TRIGGER, textColor, true, element);
-
-                trigger.rect.attr("fill", Raphael.rgb(133, 154, 185));
-                yPosition += List.ELEMENT_HEIGHT;
-            }
-
-            yPosition += List.ELEMENT_HEIGHT;
-            this.triggersElement.style.height = this.triggersList.canvas.style.height = yPosition + "px";
-            this._createCollapseAnimation(this.triggersList, this.triggersElement, triggers, yPosition);
-
-            // Create actions
-            yPosition = 10;
-            var actions = this._createListElement(this.actionsList, yPosition, "ACTIONS", Type.ACTION, textColor, false);
-            yPosition += List.ELEMENT_HEIGHT;
-            configureTitle(actions, Raphael.rgb(255, 220, 42));
-
-            for (var i = 0; i < Elements.ACTIONS.length; i++) {
-                var element: any = Elements.ACTIONS[i];
-                var action = this._createListElement(this.actionsList, yPosition, element.text, Type.ACTION, textColor, true, element);
-
-                action.rect.attr("fill", Raphael.rgb(182, 185, 132));
-                yPosition += List.ELEMENT_HEIGHT;
-            }
-
-            yPosition += List.ELEMENT_HEIGHT;
-            this.actionsElement.style.height = this.actionsList.canvas.style.height = yPosition + "px";
-            this._createCollapseAnimation(this.actionsList, this.actionsElement, actions, yPosition);
-
-            // Create flow controls
-            yPosition = 10;
-            var flowControls = this._createListElement(this.flowControlsList, yPosition, "FLOW CONTROLS", Type.FLOW_CONTROL, whiteColor, false);
-            yPosition += List.ELEMENT_HEIGHT;
-            configureTitle(flowControls, Raphael.rgb(255, 41, 53));
-
-            for (var i = 0; i < Elements.FLOW_CONTROLS.length - 1; i++) {
-                var element: any = Elements.FLOW_CONTROLS[i];
-                var flowControl = this._createListElement(this.flowControlsList, yPosition, element.text, Type.FLOW_CONTROL, textColor, true, element);
-
-                flowControl.rect.attr("fill", Raphael.rgb(185, 132, 140));
-                yPosition += List.ELEMENT_HEIGHT;
-            }
-
-            yPosition += List.ELEMENT_HEIGHT;
-            this.flowControlsElement.style.height = this.flowControlsList.canvas.style.height = yPosition + "px";
-            this._createCollapseAnimation(this.flowControlsList, this.flowControlsElement, flowControls, yPosition);
-        }
-
-        /**
-        * Clears the list of elements and removes the elements
-        */
-        public clearLists(): void {
-            for (var i = 0; i < this._listElements.length; i++) {
-                this._removeListElement(this._listElements[i]);
-            }
-            this._listElements.splice(0, this._listElements.length - 1);
-        }
-
-        /**
-        * Sets the color theme of the lists
-        * @param color: the theme color
-        */
-        public setColorTheme(color: string): void {
-            this.triggersList.canvas.style.backgroundColor = color;
-            this.actionsList.canvas.style.backgroundColor = color;
-            this.flowControlsList.canvas.style.backgroundColor = color;
-        }
-
-        /**
-        * Creates a list element
-        * @param paper: the Raphael.js paper
-        * @param yPosition: the y position of the element
-        * @param text: the element text
-        * @param type: the element type (trigger, action, flow control)
-        * @param textColor: the text color
-        * @param drag: if the element should be drag'n'dropped
-        */
-        private _createListElement(paper: Paper, yPosition: number, text: string, type: number,
-                                   textColor: RaphaelColor, drag: boolean, element?: Element): ListElement
-        {
-            var object = new ListElement();
-
-            object.rect = paper.rect(10, yPosition, 300, List.ELEMENT_HEIGHT);
-
-            object.text = paper.text(30, yPosition + object.rect.attr("height") / 2, text);
-            object.text.attr("fill", textColor);
-            object.text.attr("text-anchor", "start");
-            object.text.attr("font-size", "12");
-            object.text.attr("text-anchor", "start");
-            object.text.attr("font-family", "Sinkin Sans Light");
-
-            if (drag) {
-                this._createListElementAnimation(object);
-            }
-
-            object.type = type;
-            object.element = element;
-
-            this._listElements.push(object);
-            return object;
-        }
-
-        /**
-        * Removes a list element
-        * @param element: the element to remove
-        */
-        private _removeListElement(element: ListElement): void {
-            element.rect.remove();
-            element.text.remove();
-        }
-
-        /*
-        * Creates the collapse animation of a list
-        * @param paper: the list paper
-        * @param htmlElement: the list div container
-        * @param element: the list element to click on
-        * @param expandedHeight: the height when the list is expanded
-        */
-        private _createCollapseAnimation(paper: Paper, htmlElement: HTMLElement, element: ListElement, expandedHeight: number): void {
-            var onClick = (event: MouseEvent) => {
-                var height = htmlElement.style.height;
-                if (height === expandedHeight + "px") {
-                    htmlElement.style.height = paper.canvas.style.height = 35 + "px";
-                }
-                else {
-                    htmlElement.style.height = paper.canvas.style.height = expandedHeight + "px";
-                }
-            };
-
-            element.rect.click(onClick);
-        }
-
-        /*
-        * Creates the animation of a list element
-        * @param element: the list element to animate
-        */
-        private _createListElementAnimation(element: ListElement): void {
-            var onMove = (dx: number, dy: number, x: number, y: number) =>
-            { };
-
-            var onStart = (x: number, y: number, event: MouseEvent) => {
-                this._parentContainer.style.cursor = "copy";
-                element.rect.animate({
-                    x: -10,
-                    opacity: 0.25
-                }, 500, ">");
-                element.text.animate({
-                    x: 10,
-                    opacity: 0.25
-                }, 500, ">");
-            };
-
-            var onEnd = (event: MouseEvent) => {
-                this._parentContainer.style.cursor = "default";
-                element.rect.animate({
-                    x: 10,
-                    opacity: 1.0
-                }, 500, "<");
-                element.text.animate({
-                    x: 30,
-                    opacity: 1.0
-                }, 500, "<");
-
-                var dragResult = this._viewer.traverseGraph(null, this._viewer.mousex, this._viewer.mousey, false);
-
-                if (dragResult.hit) {
-                    if (element.type === Type.TRIGGER && dragResult.action !== this._viewer.root) {
-                        alert("Triggers can be dragged only on the root node (the mesh)");
-                        return;
-                    }
-
-                    if (element.type === Type.ACTION && dragResult.action === this._viewer.root) {
-                        alert("Please add a trigger before.");
-                        return;
-                    }
-
-                    //if (element.type === Type.FLOW_CONTROL && (dragResult.action === this._viewer.root || (dragResult.action.type === Type.FLOW_CONTROL && dragResult.action.parent.hub === null))) {
-                    if (element.type === Type.FLOW_CONTROL && dragResult.action === this._viewer.root) {
-                        return;
-                    }
-
-                    if (element.type === Type.FLOW_CONTROL && dragResult.action.combineArray !== null) {
-                        alert("A condition cannot be handled by a Combine Action.");
-                        return;
-                    }
-
-                    if ((element.type === Type.FLOW_CONTROL || element.type === Type.ACTION) && dragResult.action.type === Type.TRIGGER && dragResult.action.children.length > 0) {
-                        alert("Triggers can have only one child. Please add another trigger of same type.");
-                        return;
-                    }
-
-                    if (!(dragResult.action.combineArray !== null) && dragResult.action.children.length > 0 && dragResult.action.type !== Type.TRIGGER && dragResult.action !== this._viewer.root) {
-                        alert("An action can have only one child.");
-                        return;
-                    }
-
-                    this._viewer.addAction(dragResult.action, element.type, element.element);
-                    this._viewer.update();
-                }
-            };
-
-            element.rect.drag(onMove, onStart, onEnd);
-            element.text.drag(onMove, onStart, onEnd);
-        }
-
-    }
+module ActionsBuilder {
+    export class ListElement {
+        public rect: Rect = null;
+        public text: Text = null;
+        public name: string = "";
+        public type: number = Type.TRIGGER;
+        public element: Element = null;
+    }
+
+    export class List {
+        public listElement: HTMLElement;
+        public triggersElement: HTMLElement;
+        public actionsElement: HTMLElement;
+        public flowControlsElement: HTMLElement;
+
+        public triggersList: Paper;
+        public actionsList: Paper;
+        public flowControlsList: Paper;
+
+        private _parentContainer: HTMLElement;
+        private _listElements: Array<ListElement> = new Array<ListElement>();
+        private _viewer: Viewer;
+
+        public static get ELEMENT_HEIGHT(): number {
+            return 25;
+        }
+
+        /**
+        * Constructor
+        */
+        constructor(viewer: Viewer) {
+            // Get HTML elements
+            this.listElement = document.getElementById("ListsElementID");
+            this.triggersElement = document.getElementById("TriggersListID");
+            this.actionsElement = document.getElementById("ActionsListID");
+            this.flowControlsElement = document.getElementById("FlowActionsListID");
+            this._parentContainer = document.getElementById("ParentContainerID");
+
+            // Configure this
+            this._viewer = viewer;
+
+            // Create elements (lists)
+            this.triggersList = Raphael("TriggersListID", (25 * screen.width) / 100, 400);
+            this.actionsList = Raphael("ActionsListID", (25 * screen.width) / 100, 400);
+            this.flowControlsList = Raphael("FlowActionsListID", (25 * screen.width) / 100, 400);
+
+            // Manage events
+            window.addEventListener("resize", (event: Event) => {
+                this.onResize(event);
+            });
+        }
+
+        /**
+        * Resize event that resizes the list element dynamically
+        * @param event: the resize event
+        */
+        public onResize(event?: Event): void {
+            var tools = document.getElementById("ToolsButtonsID");
+            this.listElement.style.height = window.innerHeight - tools.getBoundingClientRect().height - 25 + "px";
+
+            var listElementWidth = this.listElement.getBoundingClientRect().width;
+            for (var i = 0; i < this._listElements.length; i++) {
+                var rect = this._listElements[i].rect;
+                rect.attr("width", listElementWidth - 40);
+            }
+
+            this.triggersList.setSize(listElementWidth, this.triggersList.height);
+            this.actionsList.setSize(listElementWidth, this.triggersList.height);
+            this.flowControlsList.setSize(listElementWidth, this.triggersList.height);
+
+        }
+
+        public createListsElements(): void {
+            var excludedTriggers = [6, 9, 10];
+            var yPosition = 10;
+            var textColor = Raphael.rgb(61, 72, 76);
+            var whiteColor = Raphael.rgb(255, 255, 255);
+
+            var configureTitle = (listElement: ListElement, rectColor: RaphaelColor) => {
+                listElement.text.attr("x", 15);
+                listElement.rect.attr("fill", rectColor);
+                listElement.text.attr("font-family", "Sinkin Sans Medium");
+                listElement.text.attr("font-size", "11");
+            };
+
+            // Create triggers
+            var triggers = this._createListElement(this.triggersList, yPosition, "TRIGGERS", Type.TRIGGER, whiteColor, false);
+            yPosition += List.ELEMENT_HEIGHT;
+            configureTitle(triggers, Raphael.rgb(41, 129, 255));
+
+            for (var i = 0; i < Elements.TRIGGERS.length; i++) {
+                var element: any = Elements.TRIGGERS[i];
+
+                if (this._viewer.root.type === Type.OBJECT && excludedTriggers.indexOf(i) !== -1) {
+                    continue;
+                }
+                else if (this._viewer.root.type === Type.SCENE && excludedTriggers.indexOf(i) === -1) {
+                    continue;
+                }
+
+                var trigger = this._createListElement(this.triggersList, yPosition, element.text, Type.TRIGGER, textColor, true, element);
+
+                trigger.rect.attr("fill", Raphael.rgb(133, 154, 185));
+                yPosition += List.ELEMENT_HEIGHT;
+            }
+
+            yPosition += List.ELEMENT_HEIGHT;
+            this.triggersElement.style.height = this.triggersList.canvas.style.height = yPosition + "px";
+            this._createCollapseAnimation(this.triggersList, this.triggersElement, triggers, yPosition);
+
+            // Create actions
+            yPosition = 10;
+            var actions = this._createListElement(this.actionsList, yPosition, "ACTIONS", Type.ACTION, textColor, false);
+            yPosition += List.ELEMENT_HEIGHT;
+            configureTitle(actions, Raphael.rgb(255, 220, 42));
+
+            for (var i = 0; i < Elements.ACTIONS.length; i++) {
+                var element: any = Elements.ACTIONS[i];
+                var action = this._createListElement(this.actionsList, yPosition, element.text, Type.ACTION, textColor, true, element);
+
+                action.rect.attr("fill", Raphael.rgb(182, 185, 132));
+                yPosition += List.ELEMENT_HEIGHT;
+            }
+
+            yPosition += List.ELEMENT_HEIGHT;
+            this.actionsElement.style.height = this.actionsList.canvas.style.height = yPosition + "px";
+            this._createCollapseAnimation(this.actionsList, this.actionsElement, actions, yPosition);
+
+            // Create flow controls
+            yPosition = 10;
+            var flowControls = this._createListElement(this.flowControlsList, yPosition, "FLOW CONTROLS", Type.FLOW_CONTROL, whiteColor, false);
+            yPosition += List.ELEMENT_HEIGHT;
+            configureTitle(flowControls, Raphael.rgb(255, 41, 53));
+
+            for (var i = 0; i < Elements.FLOW_CONTROLS.length - 1; i++) {
+                var element: any = Elements.FLOW_CONTROLS[i];
+                var flowControl = this._createListElement(this.flowControlsList, yPosition, element.text, Type.FLOW_CONTROL, textColor, true, element);
+
+                flowControl.rect.attr("fill", Raphael.rgb(185, 132, 140));
+                yPosition += List.ELEMENT_HEIGHT;
+            }
+
+            yPosition += List.ELEMENT_HEIGHT;
+            this.flowControlsElement.style.height = this.flowControlsList.canvas.style.height = yPosition + "px";
+            this._createCollapseAnimation(this.flowControlsList, this.flowControlsElement, flowControls, yPosition);
+        }
+
+        /**
+        * Clears the list of elements and removes the elements
+        */
+        public clearLists(): void {
+            for (var i = 0; i < this._listElements.length; i++) {
+                this._removeListElement(this._listElements[i]);
+            }
+            this._listElements.splice(0, this._listElements.length - 1);
+        }
+
+        /**
+        * Sets the color theme of the lists
+        * @param color: the theme color
+        */
+        public setColorTheme(color: string): void {
+            this.triggersList.canvas.style.backgroundColor = color;
+            this.actionsList.canvas.style.backgroundColor = color;
+            this.flowControlsList.canvas.style.backgroundColor = color;
+        }
+
+        /**
+        * Creates a list element
+        * @param paper: the Raphael.js paper
+        * @param yPosition: the y position of the element
+        * @param text: the element text
+        * @param type: the element type (trigger, action, flow control)
+        * @param textColor: the text color
+        * @param drag: if the element should be drag'n'dropped
+        */
+        private _createListElement(paper: Paper, yPosition: number, text: string, type: number,
+                                   textColor: RaphaelColor, drag: boolean, element?: Element): ListElement
+        {
+            var object = new ListElement();
+
+            object.rect = paper.rect(10, yPosition, 300, List.ELEMENT_HEIGHT);
+
+            object.text = paper.text(30, yPosition + object.rect.attr("height") / 2, text);
+            object.text.attr("fill", textColor);
+            object.text.attr("text-anchor", "start");
+            object.text.attr("font-size", "12");
+            object.text.attr("text-anchor", "start");
+            object.text.attr("font-family", "Sinkin Sans Light");
+
+            if (drag) {
+                this._createListElementAnimation(object);
+            }
+
+            object.type = type;
+            object.element = element;
+
+            this._listElements.push(object);
+            return object;
+        }
+
+        /**
+        * Removes a list element
+        * @param element: the element to remove
+        */
+        private _removeListElement(element: ListElement): void {
+            element.rect.remove();
+            element.text.remove();
+        }
+
+        /*
+        * Creates the collapse animation of a list
+        * @param paper: the list paper
+        * @param htmlElement: the list div container
+        * @param element: the list element to click on
+        * @param expandedHeight: the height when the list is expanded
+        */
+        private _createCollapseAnimation(paper: Paper, htmlElement: HTMLElement, element: ListElement, expandedHeight: number): void {
+            var onClick = (event: MouseEvent) => {
+                var height = htmlElement.style.height;
+                if (height === expandedHeight + "px") {
+                    htmlElement.style.height = paper.canvas.style.height = 35 + "px";
+                }
+                else {
+                    htmlElement.style.height = paper.canvas.style.height = expandedHeight + "px";
+                }
+            };
+
+            element.rect.click(onClick);
+        }
+
+        /*
+        * Creates the animation of a list element
+        * @param element: the list element to animate
+        */
+        private _createListElementAnimation(element: ListElement): void {
+            var onMove = (dx: number, dy: number, x: number, y: number) =>
+            { };
+
+            var onStart = (x: number, y: number, event: MouseEvent) => {
+                this._parentContainer.style.cursor = "copy";
+                element.rect.animate({
+                    x: -10,
+                    opacity: 0.25
+                }, 500, ">");
+                element.text.animate({
+                    x: 10,
+                    opacity: 0.25
+                }, 500, ">");
+            };
+
+            var onEnd = (event: MouseEvent) => {
+                this._parentContainer.style.cursor = "default";
+                element.rect.animate({
+                    x: 10,
+                    opacity: 1.0
+                }, 500, "<");
+                element.text.animate({
+                    x: 30,
+                    opacity: 1.0
+                }, 500, "<");
+
+                var dragResult = this._viewer.traverseGraph(null, this._viewer.mousex, this._viewer.mousey, false);
+
+                if (dragResult.hit) {
+                    if (element.type === Type.TRIGGER && dragResult.action !== this._viewer.root) {
+                        alert("Triggers can be dragged only on the root node (the mesh)");
+                        return;
+                    }
+
+                    if (element.type === Type.ACTION && dragResult.action === this._viewer.root) {
+                        alert("Please add a trigger before.");
+                        return;
+                    }
+
+                    //if (element.type === Type.FLOW_CONTROL && (dragResult.action === this._viewer.root || (dragResult.action.type === Type.FLOW_CONTROL && dragResult.action.parent.hub === null))) {
+                    if (element.type === Type.FLOW_CONTROL && dragResult.action === this._viewer.root) {
+                        return;
+                    }
+
+                    if (element.type === Type.FLOW_CONTROL && dragResult.action.combineArray !== null) {
+                        alert("A condition cannot be handled by a Combine Action.");
+                        return;
+                    }
+
+                    if ((element.type === Type.FLOW_CONTROL || element.type === Type.ACTION) && dragResult.action.type === Type.TRIGGER && dragResult.action.children.length > 0) {
+                        alert("Triggers can have only one child. Please add another trigger of same type.");
+                        return;
+                    }
+
+                    if (!(dragResult.action.combineArray !== null) && dragResult.action.children.length > 0 && dragResult.action.type !== Type.TRIGGER && dragResult.action !== this._viewer.root) {
+                        alert("An action can have only one child.");
+                        return;
+                    }
+
+                    this._viewer.addAction(dragResult.action, element.type, element.element);
+                    this._viewer.update();
+                }
+            };
+
+            element.rect.drag(onMove, onStart, onEnd);
+            element.text.drag(onMove, onStart, onEnd);
+        }
+
+    }
 }

+ 96 - 0
Exporters/3ds Max/ActionsBuilder/actionsbuilder.main.js

@@ -0,0 +1,96 @@
+/*
+Global functions called by the plugins (3ds Max, etc.)
+*/
+var list = null;
+var viewer = null;
+var actionsBuilderJsonInput = document.getElementById("ActionsBuilderJSON");
+this.createJSON = function () {
+    var structure = viewer.utils.createJSON(viewer.root);
+    var asText = JSON.stringify(structure);
+    actionsBuilderJsonInput.value = asText;
+    console.log(asText);
+};
+this.loadFromJSON = function () {
+    var json = actionsBuilderJsonInput.value;
+    if (json !== "") {
+        var structure = JSON.parse(json);
+        viewer.utils.loadFromJSON(structure, null);
+    }
+};
+this.updateObjectName = function () {
+    var element = document.getElementById("ActionsBuilderObjectName");
+    var name = element.value;
+    viewer.objectName = name;
+    if (viewer.root.type === ActionsBuilder.Type.OBJECT) {
+        name += " - Mesh";
+    }
+    else {
+        name += " - Scene";
+    }
+    viewer.root.node.text.attr("text", name);
+};
+this.resetList = function () {
+    list.clearLists();
+    list.createListsElements();
+};
+this.setMeshesNames = function () {
+    var args = [];
+    for (var _i = 0; _i < arguments.length; _i++) {
+        args[_i - 0] = arguments[_i];
+    }
+    for (var i = 0; i < args.length; i++) {
+        ActionsBuilder.SceneElements.MESHES.push(args[i]);
+    }
+};
+this.setLightsNames = function () {
+    var args = [];
+    for (var _i = 0; _i < arguments.length; _i++) {
+        args[_i - 0] = arguments[_i];
+    }
+    for (var i = 0; i < args.length; i++) {
+        ActionsBuilder.SceneElements.LIGHTS.push(args[i]);
+    }
+};
+this.setCamerasNames = function () {
+    var args = [];
+    for (var _i = 0; _i < arguments.length; _i++) {
+        args[_i - 0] = arguments[_i];
+    }
+    for (var i = 0; i < args.length; i++) {
+        ActionsBuilder.SceneElements.CAMERAS.push(args[i]);
+    }
+};
+this.setSoundsNames = function () {
+    var args = [];
+    for (var _i = 0; _i < arguments.length; _i++) {
+        args[_i - 0] = arguments[_i];
+    }
+    for (var i = 0; i < args.length; i++) {
+        var sound = args[i];
+        if (sound !== "" && ActionsBuilder.SceneElements.SOUNDS.indexOf(sound) === -1) {
+            ActionsBuilder.SceneElements.SOUNDS.push(args[i]);
+        }
+    }
+};
+this.hideButtons = function () {
+};
+this.setIsObject = function () {
+    viewer.root.type = ActionsBuilder.Type.OBJECT;
+};
+this.setIsScene = function () {
+    viewer.root.type = ActionsBuilder.Type.SCENE;
+};
+this.run = function () {
+    viewer = new ActionsBuilder.Viewer(ActionsBuilder.Type.OBJECT);
+    viewer.setColorTheme("-ms-linear-gradient(top, rgba(38, 38, 38,1) 0%, rgba(125, 126, 125, 1) 100%)");
+    viewer.setColorTheme("linear-gradient(top, rgba(38, 38, 38,1) 0%, rgba(125, 126, 125, 1) 100%)");
+    viewer.setColorTheme("-webkit-linear-gradient(top, rgba(38, 38, 38,1) 0%, rgba(125, 126, 125, 1) 100%)");
+    viewer.setColorTheme("-o-linear-gradient(top, rgba(38, 38, 38,1) 0%, rgba(125, 126, 125, 1) 100%)");
+    viewer.onResize();
+    viewer.update();
+    list = new ActionsBuilder.List(viewer);
+    list.setColorTheme("rgb(64, 64, 64)");
+    list.createListsElements();
+    list.onResize();
+    viewer.onResize();
+};

+ 115 - 106
Exporters/3ds Max/ActionsBuilder/actionsbuilder.main.ts

@@ -1,109 +1,118 @@
-/*
-Global functions called by the plugins (3ds Max, etc.)
-*/
-
-// Elements
-
-var list: ActionsBuilder.List = null;
-var viewer: ActionsBuilder.Viewer = null;
-
-var actionsBuilderJsonInput: HTMLInputElement = <HTMLInputElement>document.getElementById("ActionsBuilderJSON");
-
-this.createJSON = () => {
-    var structure = viewer.utils.createJSON(viewer.root);
-    var asText = JSON.stringify(structure);
-    actionsBuilderJsonInput.value = asText;
-    console.log(asText);
-};
-
-this.loadFromJSON = () => {
-    var json = actionsBuilderJsonInput.value;
-    if (json !== "") {
-        var structure = JSON.parse(json);
-        viewer.utils.loadFromJSON(structure, null);
-    }
-};
-
-this.updateObjectName = () => {
-    var element = <HTMLInputElement>document.getElementById("ActionsBuilderObjectName");
-    var name = element.value;
-
-    viewer.objectName = name;
-
-    if (viewer.root.type === ActionsBuilder.Type.OBJECT) {
-        name += " - Mesh";
-    }
-    else {
-        name += " - Scene";
-    }
-
-    viewer.root.node.text.attr("text", name);
-};
-
-this.resetList = () => {
-    list.clearLists();
-    list.createListsElements();
-};
-
-this.setMeshesNames = (...args: string[]) => {
-    for (var i = 0; i < args.length; i++) {
-        ActionsBuilder.SceneElements.MESHES.push(args[i]);
-    }
-};
-
-this.setLightsNames = (...args: string[]) => {
-    for (var i = 0; i < args.length; i++) {
-        ActionsBuilder.SceneElements.LIGHTS.push(args[i]);
-    }
+/*
+Global functions called by the plugins (3ds Max, etc.)
+*/
+
+// Elements
+
+var list: ActionsBuilder.List = null;
+var viewer: ActionsBuilder.Viewer = null;
+
+var actionsBuilderJsonInput: HTMLInputElement = <HTMLInputElement>document.getElementById("ActionsBuilderJSON");
+
+this.getList = () => {
+    return list;
 };
 
-this.setCamerasNames = (...args: string[]) => {
-    for (var i = 0; i < args.length; i++) {
-        ActionsBuilder.SceneElements.CAMERAS.push(args[i]);
-    }
-};
-
-this.setSoundsNames = (...args: string[]) => {
-    for (var i = 0; i < args.length; i++) {
-        var sound = args[i];
-
-        if (sound !== "" && ActionsBuilder.SceneElements.SOUNDS.indexOf(sound) === -1) {
-            ActionsBuilder.SceneElements.SOUNDS.push(args[i]);
-        }
-    }
-};
-
-this.hideButtons = () => {
-    // Empty
-};
-
-this.setIsObject = () => {
-    viewer.root.type = ActionsBuilder.Type.OBJECT;
-};
-
-this.setIsScene = () => {
-    viewer.root.type = ActionsBuilder.Type.SCENE;
-};
-
-this.run = () => {
-    // Configure viewer
-    viewer = new ActionsBuilder.Viewer(ActionsBuilder.Type.OBJECT);
-
-    viewer.setColorTheme("-ms-linear-gradient(top, rgba(38, 38, 38,1) 0%, rgba(125, 126, 125, 1) 100%)");
-    viewer.setColorTheme("linear-gradient(top, rgba(38, 38, 38,1) 0%, rgba(125, 126, 125, 1) 100%)");
-    viewer.setColorTheme("-webkit-linear-gradient(top, rgba(38, 38, 38,1) 0%, rgba(125, 126, 125, 1) 100%)");
-    viewer.setColorTheme("-o-linear-gradient(top, rgba(38, 38, 38,1) 0%, rgba(125, 126, 125, 1) 100%)");
-
-    viewer.onResize();
-    viewer.update();
-
-    // Configure list
-    list = new ActionsBuilder.List(viewer);
-    list.setColorTheme("rgb(64, 64, 64)");
-
-    list.createListsElements();
-    list.onResize();
-
-    // 3ds Max fix
-    viewer.onResize();
+this.getViewer = () => {
+    return viewer;
 };
+
+
+this.createJSON = () => {
+    var structure = viewer.utils.createJSON(viewer.root);
+    var asText = JSON.stringify(structure);
+    actionsBuilderJsonInput.value = asText;
+    console.log(asText);
+};
+
+this.loadFromJSON = () => {
+    var json = actionsBuilderJsonInput.value;
+    if (json !== "") {
+        var structure = JSON.parse(json);
+        viewer.utils.loadFromJSON(structure, null);
+    }
+};
+
+this.updateObjectName = () => {
+    var element = <HTMLInputElement>document.getElementById("ActionsBuilderObjectName");
+    var name = element.value;
+
+    viewer.objectName = name;
+
+    if (viewer.root.type === ActionsBuilder.Type.OBJECT) {
+        name += " - Mesh";
+    }
+    else {
+        name += " - Scene";
+    }
+
+    viewer.root.node.text.attr("text", name);
+};
+
+this.resetList = () => {
+    list.clearLists();
+    list.createListsElements();
+};
+
+this.setMeshesNames = (...args: string[]) => {
+    for (var i = 0; i < args.length; i++) {
+        ActionsBuilder.SceneElements.MESHES.push(args[i]);
+    }
+};
+
+this.setLightsNames = (...args: string[]) => {
+    for (var i = 0; i < args.length; i++) {
+        ActionsBuilder.SceneElements.LIGHTS.push(args[i]);
+    }
+};
+
+this.setCamerasNames = (...args: string[]) => {
+    for (var i = 0; i < args.length; i++) {
+        ActionsBuilder.SceneElements.CAMERAS.push(args[i]);
+    }
+};
+
+this.setSoundsNames = (...args: string[]) => {
+    for (var i = 0; i < args.length; i++) {
+        var sound = args[i];
+
+        if (sound !== "" && ActionsBuilder.SceneElements.SOUNDS.indexOf(sound) === -1) {
+            ActionsBuilder.SceneElements.SOUNDS.push(args[i]);
+        }
+    }
+};
+
+this.hideButtons = () => {
+    // Empty
+};
+
+this.setIsObject = () => {
+    viewer.root.type = ActionsBuilder.Type.OBJECT;
+};
+
+this.setIsScene = () => {
+    viewer.root.type = ActionsBuilder.Type.SCENE;
+};
+
+this.run = () => {
+    // Configure viewer
+    viewer = new ActionsBuilder.Viewer(ActionsBuilder.Type.OBJECT);
+
+    viewer.setColorTheme("-ms-linear-gradient(top, rgba(38, 38, 38,1) 0%, rgba(125, 126, 125, 1) 100%)");
+    viewer.setColorTheme("linear-gradient(top, rgba(38, 38, 38,1) 0%, rgba(125, 126, 125, 1) 100%)");
+    viewer.setColorTheme("-webkit-linear-gradient(top, rgba(38, 38, 38,1) 0%, rgba(125, 126, 125, 1) 100%)");
+    viewer.setColorTheme("-o-linear-gradient(top, rgba(38, 38, 38,1) 0%, rgba(125, 126, 125, 1) 100%)");
+
+    viewer.onResize();
+    viewer.update();
+
+    // Configure list
+    list = new ActionsBuilder.List(viewer);
+    list.setColorTheme("rgb(64, 64, 64)");
+
+    list.createListsElements();
+    list.onResize();
+
+    // 3ds Max fix
+    viewer.onResize();
+};

+ 440 - 0
Exporters/3ds Max/ActionsBuilder/actionsbuilder.parameters.js

@@ -0,0 +1,440 @@
+var ActionsBuilder;
+(function (ActionsBuilder) {
+    var Parameters = (function () {
+        function Parameters(viewer) {
+            var _this = this;
+            this._action = null;
+            this.parametersContainer = document.getElementById("ParametersElementID");
+            this.parametersHelpElement = document.getElementById("ParametersHelpElementID");
+            this._viewer = viewer;
+            window.addEventListener("resize", function (event) {
+                _this.onResize(event);
+            });
+        }
+        Parameters.prototype.clearParameters = function () {
+            if (this.parametersContainer.children === null) {
+                return;
+            }
+            while (this.parametersContainer.children.length > 0) {
+                this.parametersContainer.removeChild(this.parametersContainer.firstChild);
+            }
+        };
+        Parameters.prototype.createParameters = function (action) {
+            this._action = action;
+            this.clearParameters();
+            if (action === null) {
+                return;
+            }
+            this._createHelpSection(action);
+            this._createNodeSection(action);
+            var properties = action.properties;
+            var propertiesResults = action.propertiesResults;
+            var targetParameterSelect = null;
+            var targetParameterNameSelect = null;
+            var propertyPathSelect = null;
+            var propertyPathOptionalSelect = null;
+            var booleanSelect = null;
+            var propertyInput = null;
+            var propertyPathIndice = -1;
+            if (properties.length === 0) {
+                return;
+            }
+            for (var i = 0; i < properties.length; i++) {
+                var separator = document.createElement("hr");
+                separator.noShade = true;
+                separator.className = "ParametersElementSeparatorClass";
+                this.parametersContainer.appendChild(separator);
+                var parameterName = document.createElement("a");
+                parameterName.text = properties[i].text;
+                parameterName.className = "ParametersElementTitleClass";
+                this.parametersContainer.appendChild(parameterName);
+                if (properties[i].text === "parameter" || properties[i].text === "target" || properties[i].text === "parent") {
+                    targetParameterSelect = document.createElement("select");
+                    targetParameterSelect.className = "ParametersElementSelectClass";
+                    this.parametersContainer.appendChild(targetParameterSelect);
+                    targetParameterNameSelect = document.createElement("select");
+                    targetParameterNameSelect.className = "ParametersElementSelectClass";
+                    this.parametersContainer.appendChild(targetParameterNameSelect);
+                    (this._parameterTargetChanged(targetParameterSelect, targetParameterNameSelect, propertyPathSelect, propertyPathOptionalSelect, i))(null);
+                    targetParameterSelect.value = propertiesResults[i].targetType;
+                    targetParameterNameSelect.value = propertiesResults[i].value;
+                    targetParameterSelect.onchange = this._parameterTargetChanged(targetParameterSelect, targetParameterNameSelect, propertyPathSelect, propertyPathOptionalSelect, i);
+                    targetParameterNameSelect.onchange = this._parameterTargetNameChanged(targetParameterSelect, targetParameterNameSelect, i);
+                }
+                else if (properties[i].text === "propertyPath") {
+                    propertyPathIndice = i;
+                    propertyPathSelect = document.createElement("select");
+                    propertyPathSelect.className = "ParametersElementSelectClass";
+                    this.parametersContainer.appendChild(propertyPathSelect);
+                    propertyPathOptionalSelect = document.createElement("select");
+                    propertyPathOptionalSelect.className = "ParametersElementSelectClass";
+                    this.parametersContainer.appendChild(propertyPathOptionalSelect);
+                    (this._propertyPathSelectChanged(targetParameterSelect, propertyPathSelect, propertyPathOptionalSelect, null, null, i))(null);
+                    var property = this._action.propertiesResults[i].value.split(".");
+                    if (property.length > 0) {
+                        if (property.length === 1) {
+                            propertyPathSelect.value = property[0];
+                        }
+                        else {
+                            var completePropertyPath = "";
+                            for (var j = 0; j < property.length - 1; j++) {
+                                completePropertyPath += property[j];
+                                completePropertyPath += (j === property.length - 2) ? "" : ".";
+                            }
+                            propertyPathSelect.value = completePropertyPath;
+                            this._viewer.utils.setElementVisible(propertyPathOptionalSelect, true);
+                        }
+                        this._fillAdditionalPropertyPath(targetParameterSelect, propertyPathSelect, propertyPathOptionalSelect);
+                        propertyPathOptionalSelect.value = property[property.length - 1];
+                        if (propertyPathOptionalSelect.options.length === 0 || propertyPathOptionalSelect.options[0].text === "") {
+                            this._viewer.utils.setElementVisible(propertyPathOptionalSelect, false);
+                        }
+                    }
+                    targetParameterSelect.onchange = this._parameterTargetChanged(targetParameterSelect, targetParameterNameSelect, propertyPathSelect, propertyPathOptionalSelect, i - 1);
+                    propertyPathSelect.onchange = this._propertyPathSelectChanged(targetParameterSelect, propertyPathSelect, propertyPathOptionalSelect, null, null, i);
+                    propertyPathOptionalSelect.onchange = this._additionalPropertyPathSelectChanged(propertyPathSelect, propertyPathOptionalSelect, i);
+                }
+                else if (properties[i].text === "operator") {
+                    var conditionOperatorSelect = document.createElement("select");
+                    conditionOperatorSelect.className = "ParametersElementSelectClass";
+                    this.parametersContainer.appendChild(conditionOperatorSelect);
+                    (this._conditionOperatorSelectChanged(conditionOperatorSelect, i))(null);
+                    conditionOperatorSelect.value = propertiesResults[i].value;
+                    conditionOperatorSelect.onchange = this._conditionOperatorSelectChanged(conditionOperatorSelect, i);
+                }
+                else if (properties[i].text === "sound") {
+                    var soundSelect = document.createElement("select");
+                    soundSelect.className = "ParametersElementSelectClass";
+                    this.parametersContainer.appendChild(soundSelect);
+                    (this._soundSelectChanged(soundSelect, i))(null);
+                    soundSelect.value = propertiesResults[i].value;
+                    soundSelect.onchange = this._soundSelectChanged(soundSelect, i);
+                }
+                else {
+                    var isBoolean = propertiesResults[i].value === "true" || propertiesResults[i].value === "false";
+                    var object = this._getObjectFromType(targetParameterSelect.value);
+                    if (object !== null) {
+                        var property = this._action.propertiesResults[i - 1].value.split(".");
+                        for (var j = 0; j < property.length && object !== undefined; j++) {
+                            object = object[property[j]];
+                            if (j === property.length - 1) {
+                                isBoolean = isBoolean || typeof object === "boolean";
+                            }
+                        }
+                    }
+                    booleanSelect = document.createElement("select");
+                    booleanSelect.className = "ParametersElementSelectClass";
+                    this.parametersContainer.appendChild(booleanSelect);
+                    (this._booleanSelectChanged(booleanSelect, i))(null);
+                    booleanSelect.value = propertiesResults[i].value;
+                    booleanSelect.onchange = this._booleanSelectChanged(booleanSelect, i);
+                    propertyInput = document.createElement("input");
+                    propertyInput.value = propertiesResults[i].value;
+                    propertyInput.className = "ParametersElementInputClass";
+                    this.parametersContainer.appendChild(propertyInput);
+                    propertyInput.onkeyup = this._propertyInputChanged(propertyInput, i);
+                    if (propertyPathIndice !== -1 && properties[i].text === "value") {
+                        propertyPathSelect.onchange = this._propertyPathSelectChanged(targetParameterSelect, propertyPathSelect, propertyPathOptionalSelect, booleanSelect, propertyInput, propertyPathIndice);
+                    }
+                    if (isBoolean) {
+                        this._viewer.utils.setElementVisible(booleanSelect, true);
+                        this._viewer.utils.setElementVisible(propertyInput, false);
+                    }
+                    else {
+                        this._viewer.utils.setElementVisible(booleanSelect, false);
+                        this._viewer.utils.setElementVisible(propertyInput, true);
+                    }
+                }
+            }
+        };
+        Parameters.prototype.onResize = function (event) {
+            var tools = document.getElementById("ToolsButtonsID");
+            this.parametersContainer.style.height = window.innerHeight - tools.getBoundingClientRect().height - 25 - 200 + "px";
+            this.parametersHelpElement.style.height = 200 + "px";
+        };
+        Parameters.prototype._booleanSelectChanged = function (booleanSelect, indice) {
+            var _this = this;
+            return function (ev) {
+                if (booleanSelect.options.length === 0) {
+                    var values = ["true", "false"];
+                    for (var i = 0; i < values.length; i++) {
+                        var option = document.createElement("option");
+                        option.value = option.text = values[i];
+                        booleanSelect.options.add(option);
+                    }
+                }
+                else {
+                    _this._action.propertiesResults[indice].value = booleanSelect.value;
+                }
+            };
+        };
+        Parameters.prototype._soundSelectChanged = function (soundSelect, indice) {
+            var _this = this;
+            return function (ev) {
+                if (soundSelect.options.length === 0) {
+                    for (var i = 0; i < ActionsBuilder.SceneElements.SOUNDS.length; i++) {
+                        var option = document.createElement("option");
+                        option.value = option.text = ActionsBuilder.SceneElements.SOUNDS[i];
+                        soundSelect.options.add(option);
+                    }
+                    _this._sortList(soundSelect);
+                }
+                else {
+                    _this._action.propertiesResults[indice].value = soundSelect.value;
+                }
+            };
+        };
+        Parameters.prototype._conditionOperatorSelectChanged = function (conditionOperatorSelect, indice) {
+            var _this = this;
+            return function (ev) {
+                if (conditionOperatorSelect.options.length === 0) {
+                    for (var i = 0; i < ActionsBuilder.SceneElements.OPERATORS.length; i++) {
+                        var option = document.createElement("option");
+                        option.value = option.text = ActionsBuilder.SceneElements.OPERATORS[i];
+                        conditionOperatorSelect.options.add(option);
+                    }
+                }
+                else {
+                    _this._action.propertiesResults[indice].value = conditionOperatorSelect.value;
+                }
+            };
+        };
+        Parameters.prototype._propertyInputChanged = function (propertyInput, indice) {
+            var _this = this;
+            return function (ev) {
+                _this._action.propertiesResults[indice].value = propertyInput.value;
+            };
+        };
+        Parameters.prototype._propertyPathSelectChanged = function (targetParameterSelect, propertyPathSelect, additionalPropertyPathSelect, booleanSelect, propertyInput, indice) {
+            var _this = this;
+            return function (event) {
+                if (propertyPathSelect.options.length === 0) {
+                    var properties = _this._getPropertiesFromType(targetParameterSelect.value);
+                    if (properties !== null) {
+                        for (var i = 0; i < properties.length; i++) {
+                            var option = document.createElement("option");
+                            option.value = option.text = properties[i];
+                            propertyPathSelect.options.add(option);
+                        }
+                    }
+                }
+                else {
+                    _this._action.propertiesResults[indice].value = propertyPathSelect.value;
+                    if (booleanSelect !== null && propertyInput !== null) {
+                        var object = _this._getObjectFromType(targetParameterSelect.value);
+                        var isBoolean = false;
+                        if (object !== null) {
+                            var property = _this._action.propertiesResults[indice].value.split(".");
+                            for (var j = 0; j < property.length; j++) {
+                                object = object[property[j]];
+                                if (j === property.length - 1) {
+                                    isBoolean = isBoolean || typeof object === "boolean";
+                                }
+                            }
+                        }
+                        if (isBoolean) {
+                            _this._viewer.utils.setElementVisible(booleanSelect, true);
+                            _this._viewer.utils.setElementVisible(propertyInput, false);
+                        }
+                        else {
+                            _this._viewer.utils.setElementVisible(booleanSelect, false);
+                            _this._viewer.utils.setElementVisible(propertyInput, true);
+                        }
+                    }
+                }
+                _this._fillAdditionalPropertyPath(targetParameterSelect, propertyPathSelect, additionalPropertyPathSelect);
+                _this._sortList(propertyPathSelect);
+            };
+        };
+        Parameters.prototype._fillAdditionalPropertyPath = function (targetParameterSelect, propertyPathSelect, additionalPropertyPathSelect) {
+            additionalPropertyPathSelect.options.length = 0;
+            var object = this._getObjectFromType(targetParameterSelect.value);
+            if (object !== null) {
+                var propertyPath = propertyPathSelect.value.split(".");
+                for (var i = 0; i < propertyPath.length; i++) {
+                    object = object[propertyPath[i]];
+                }
+            }
+            if (object === null || object === undefined || (typeof (object)).toLowerCase() === "string") {
+                this._viewer.utils.setElementVisible(additionalPropertyPathSelect, false);
+                return;
+            }
+            var emptyOption = document.createElement("option");
+            emptyOption.value = emptyOption.text = "";
+            additionalPropertyPathSelect.add(emptyOption);
+            for (var thing in object) {
+                var type = ActionsBuilder.SceneElements.GetInstanceOf(object[thing]);
+                var index = ActionsBuilder.SceneElements.TYPES.indexOf(type);
+                if (index !== -1) {
+                    var option = document.createElement("option");
+                    option.value = option.text = thing;
+                    additionalPropertyPathSelect.options.add(option);
+                    emptyOption.text += thing + ", ";
+                }
+            }
+            if (additionalPropertyPathSelect.options.length === 0 || additionalPropertyPathSelect.options[0].text === "") {
+                this._viewer.utils.setElementVisible(additionalPropertyPathSelect, false);
+            }
+            else {
+                this._viewer.utils.setElementVisible(additionalPropertyPathSelect, true);
+            }
+        };
+        Parameters.prototype._additionalPropertyPathSelectChanged = function (propertyPathSelect, additionalPropertyPathSelect, indice) {
+            var _this = this;
+            return function (event) {
+                var property = propertyPathSelect.value;
+                var additionalProperty = additionalPropertyPathSelect.value;
+                if (additionalProperty !== "") {
+                    property += ".";
+                    property += additionalPropertyPathSelect.value;
+                }
+                _this._action.propertiesResults[indice].value = property;
+            };
+        };
+        Parameters.prototype._parameterTargetChanged = function (targetParameterSelect, targetParameterNameSelect, propertyPathSelect, additionalPropertyPathSelect, indice) {
+            var _this = this;
+            return function (event) {
+                if (targetParameterSelect.options.length === 0) {
+                    var options = [
+                        { text: "Mesh", targetType: "MeshProperties" },
+                        { text: "Light", targetType: "LightProperties" },
+                        { text: "Camera", targetType: "CameraProperties" },
+                        { text: "Scene", targetType: "SceneProperties" }
+                    ];
+                    targetParameterSelect.options.length = 0;
+                    for (var i = 0; i < options.length; i++) {
+                        var option = document.createElement("option");
+                        option.text = options[i].text;
+                        option.value = options[i].targetType;
+                        targetParameterSelect.options.add(option);
+                    }
+                    targetParameterSelect.value = _this._action.propertiesResults[indice].targetType;
+                }
+                else {
+                    _this._action.propertiesResults[indice].targetType = targetParameterSelect.value;
+                    var names = _this._getListFromType(targetParameterSelect.value);
+                    if (names !== null && names.length > 0) {
+                        _this._action.propertiesResults[indice].value = names[0];
+                    }
+                    else {
+                        _this._action.propertiesResults[indice].value = "";
+                    }
+                    if (propertyPathSelect !== null) {
+                        _this._action.propertiesResults[indice + 1].value = "";
+                    }
+                }
+                var targetParameterProperties = _this._getTargetFromType(targetParameterSelect.value);
+                targetParameterNameSelect.options.length = 0;
+                if (targetParameterProperties !== null) {
+                    for (var i = 0; i < targetParameterProperties.length; i++) {
+                        var option = document.createElement("option");
+                        option.text = option.value = targetParameterProperties[i];
+                        targetParameterNameSelect.options.add(option);
+                    }
+                }
+                targetParameterNameSelect.value = _this._action.propertiesResults[indice].value;
+                if (propertyPathSelect !== null) {
+                    propertyPathSelect.options.length = 0;
+                    additionalPropertyPathSelect.options.length = 0;
+                    _this._propertyPathSelectChanged(targetParameterSelect, propertyPathSelect, additionalPropertyPathSelect, null, null, indice + 1)(null);
+                }
+                _this._sortList(targetParameterNameSelect);
+                _this._sortList(targetParameterSelect);
+            };
+        };
+        Parameters.prototype._parameterTargetNameChanged = function (targetParameterSelect, targetParameterNameSelect, indice) {
+            var _this = this;
+            return function (event) {
+                _this._action.propertiesResults[indice].value = targetParameterNameSelect.value;
+            };
+        };
+        Parameters.prototype._getTargetFromType = function (type) {
+            if (type === "MeshProperties" || type === "Mesh") {
+                return ActionsBuilder.SceneElements.MESHES;
+            }
+            if (type === "LightProperties" || type === "Light") {
+                return ActionsBuilder.SceneElements.LIGHTS;
+            }
+            if (type === "CameraProperties" || type === "Camera") {
+                return ActionsBuilder.SceneElements.CAMERAS;
+            }
+            return null;
+        };
+        Parameters.prototype._getPropertiesFromType = function (type) {
+            if (type === "MeshProperties" || type === "Mesh") {
+                return ActionsBuilder.SceneElements.MESH_PROPERTIES;
+            }
+            if (type === "LightProperties" || type === "Light") {
+                return ActionsBuilder.SceneElements.LIGHT_PROPERTIES;
+            }
+            if (type === "CameraProperties" || type === "Camera") {
+                return ActionsBuilder.SceneElements.CAMERA_PROPERTIES;
+            }
+            if (type === "SceneProperties" || type === "Scene") {
+                return ActionsBuilder.SceneElements.SCENE_PROPERTIES;
+            }
+            return null;
+        };
+        Parameters.prototype._getListFromType = function (type) {
+            if (type === "MeshProperties" || type === "Mesh") {
+                return ActionsBuilder.SceneElements.MESHES;
+            }
+            if (type === "LightProperties" || type === "Light") {
+                return ActionsBuilder.SceneElements.LIGHTS;
+            }
+            if (type === "CameraProperties" || type === "Camera") {
+                return ActionsBuilder.SceneElements.CAMERAS;
+            }
+            return null;
+        };
+        Parameters.prototype._getObjectFromType = function (type) {
+            if (type === "MeshProperties" || type === "Mesh") {
+                this._currentObject = ActionsBuilder.SceneElements.MESH;
+                return ActionsBuilder.SceneElements.MESH;
+            }
+            if (type === "LightProperties" || type === "Light") {
+                this._currentObject = ActionsBuilder.SceneElements.LIGHT;
+                return ActionsBuilder.SceneElements.LIGHT;
+            }
+            if (type === "CameraProperties" || type === "Camera") {
+                this._currentObject = ActionsBuilder.SceneElements.CAMERA;
+                return ActionsBuilder.SceneElements.CAMERA;
+            }
+            if (type === "SceneProperties" || type === "Scene") {
+                this._currentObject = ActionsBuilder.SceneElements.SCENE;
+                return ActionsBuilder.SceneElements.SCENE;
+            }
+            return null;
+        };
+        Parameters.prototype._createNodeSection = function (action) {
+            var element = document.createElement("div");
+            element.style.background = this._viewer.getSelectedNodeColor(action.type, action.node.detached);
+            element.className = "ParametersElementNodeClass";
+            var text = document.createElement("a");
+            text.text = action.name;
+            text.className = "ParametersElementNodeTextClass";
+            element.appendChild(text);
+            this.parametersContainer.appendChild(element);
+        };
+        Parameters.prototype._createHelpSection = function (action) {
+            var element = ActionsBuilder.Elements.GetElementFromName(action.name);
+            if (element !== null) {
+                this.parametersHelpElement.textContent = element.description;
+            }
+        };
+        Parameters.prototype._sortList = function (element) {
+            var options = [];
+            for (var i = element.options.length - 1; i >= 0; i--) {
+                options.push(element.removeChild(element.options[i]));
+            }
+            options.sort(function (a, b) {
+                return a.innerHTML.localeCompare(b.innerHTML);
+            });
+            for (var i = 0; i < options.length; i++) {
+                element.options.add(options[i]);
+            }
+        };
+        return Parameters;
+    })();
+    ActionsBuilder.Parameters = Parameters;
+})(ActionsBuilder || (ActionsBuilder = {}));

File diff suppressed because it is too large
+ 649 - 637
Exporters/3ds Max/ActionsBuilder/actionsbuilder.parameters.ts


+ 80 - 0
Exporters/3ds Max/ActionsBuilder/actionsbuilder.toolbar.js

@@ -0,0 +1,80 @@
+var ActionsBuilder;
+(function (ActionsBuilder) {
+    var Toolbar = (function () {
+        function Toolbar(viewer) {
+            var _this = this;
+            this.toolbarElement = document.getElementById("ToolbarElementID");
+            this._viewer = viewer;
+            window.addEventListener("resize", function (event) {
+                _this.onResize();
+            });
+            document.getElementById("ViewerDeZoomID").addEventListener("click", function (event) {
+                if (_this._viewer.zoom > 0.1) {
+                    _this._viewer.zoom -= 0.1;
+                }
+                _this._viewer.update();
+            });
+            document.getElementById("ViewerZoomID").addEventListener("click", function (event) {
+                if (_this._viewer.zoom < 1.0) {
+                    _this._viewer.zoom += 0.1;
+                }
+                _this._viewer.update();
+            });
+            document.getElementById("ViewerReconnectAll").addEventListener("click", function (event) {
+                for (var i = 0; i < _this._viewer.root.children.length; i++) {
+                    _this._viewer.selectedNode = _this._viewer.root.children[i];
+                    _this._viewer.utils.onDetachAction(false, true);
+                }
+                _this._viewer.update();
+                _this._viewer.selectedNode = null;
+            });
+            document.getElementById("ViewerDisconnectAll").addEventListener("click", function (event) {
+                for (var i = 0; i < _this._viewer.root.children.length; i++) {
+                    _this._viewer.selectedNode = _this._viewer.root.children[i];
+                    _this._viewer.utils.onDetachAction(true, false);
+                }
+                _this._viewer.update();
+                _this._viewer.selectedNode = null;
+            });
+            document.getElementById("ViewerReduceAll").addEventListener("click", function (event) {
+                for (var i = 0; i < _this._viewer.root.children.length; i++) {
+                    _this._viewer.selectedNode = _this._viewer.root.children[i];
+                    _this._viewer.utils.onReduceAll(false);
+                }
+                _this._viewer.update();
+                _this._viewer.selectedNode = null;
+            });
+            document.getElementById("ViewerExpandAll").addEventListener("click", function (event) {
+                for (var i = 0; i < _this._viewer.root.children.length; i++) {
+                    _this._viewer.selectedNode = _this._viewer.root.children[i];
+                    _this._viewer.utils.onReduceAll(true);
+                }
+                _this._viewer.update();
+                _this._viewer.selectedNode = null;
+            });
+            this.saveActionGraphElement = document.getElementById("ToolsButtonIDSaveActionGraph");
+            this.drawSaveActionGraphButton(false);
+            document.getElementById("ResetActionGraphID").addEventListener("click", function (event) {
+                if (confirm("Are you sure?")) {
+                    for (var i = 0; i < _this._viewer.root.children.length; i++) {
+                        _this._viewer.selectedNode = _this._viewer.root.children[i];
+                        _this._viewer.utils.onRemoveBranch();
+                    }
+                    _this._viewer.update();
+                    _this._viewer.selectedNode = null;
+                }
+            });
+            document.getElementById("TestActionGraphID").addEventListener("click", function (event) {
+                _this._viewer.utils.onTestGraph();
+            });
+        }
+        Toolbar.prototype.onResize = function () {
+            this.toolbarElement.style.top = this._viewer.viewerElement.clientHeight + 20 + "px";
+        };
+        Toolbar.prototype.drawSaveActionGraphButton = function (draw) {
+            this.saveActionGraphElement.style.display = draw ? "block" : "none";
+        };
+        return Toolbar;
+    })();
+    ActionsBuilder.Toolbar = Toolbar;
+})(ActionsBuilder || (ActionsBuilder = {}));

+ 93 - 93
Exporters/3ds Max/ActionsBuilder/actionsbuilder.toolbar.ts

@@ -1,94 +1,94 @@
-module ActionsBuilder {
-    export class Toolbar {
-        public toolbarElement: HTMLElement;
-        public saveActionGraphElement: HTMLElement;
-
-        private _viewer: Viewer;
-
-        constructor(viewer: Viewer) {
-            // Get HTML elements
-            this.toolbarElement = document.getElementById("ToolbarElementID");
-
-            // Configure this
-            this._viewer = viewer;
-
-            // Manage events
-            window.addEventListener("resize", (event: Event) => {
-                this.onResize();
-            });
-
-            // Bottom toolbar
-            document.getElementById("ViewerDeZoomID").addEventListener("click", (event: MouseEvent) => {
-                if (this._viewer.zoom > 0.1) {
-                    this._viewer.zoom -= 0.1;
-                }
-                this._viewer.update();
-            });
-            document.getElementById("ViewerZoomID").addEventListener("click", (event: MouseEvent) => {
-                if (this._viewer.zoom < 1.0) {
-                    this._viewer.zoom += 0.1;
-                }
-                this._viewer.update();
-            });
-            document.getElementById("ViewerReconnectAll").addEventListener("click", (event: MouseEvent) => {
-                for (var i = 0; i < this._viewer.root.children.length; i++) {
-                    this._viewer.selectedNode = this._viewer.root.children[i];
-                    this._viewer.utils.onDetachAction(false, true);
-                }
-                this._viewer.update();
-                this._viewer.selectedNode = null;
-            });
-            document.getElementById("ViewerDisconnectAll").addEventListener("click", (event: MouseEvent) => {
-                for (var i = 0; i < this._viewer.root.children.length; i++) {
-                    this._viewer.selectedNode = this._viewer.root.children[i];
-                    this._viewer.utils.onDetachAction(true, false);
-                }
-                this._viewer.update();
-                this._viewer.selectedNode = null;
-            });
-            document.getElementById("ViewerReduceAll").addEventListener("click", (event: MouseEvent) => {
-                for (var i = 0; i < this._viewer.root.children.length; i++) {
-                    this._viewer.selectedNode = this._viewer.root.children[i];
-                    this._viewer.utils.onReduceAll(false);
-                }
-                this._viewer.update();
-                this._viewer.selectedNode = null;
-            });
-            document.getElementById("ViewerExpandAll").addEventListener("click", (event: MouseEvent) => {
-                for (var i = 0; i < this._viewer.root.children.length; i++) {
-                    this._viewer.selectedNode = this._viewer.root.children[i];
-                    this._viewer.utils.onReduceAll(true);
-                }
-                this._viewer.update();
-                this._viewer.selectedNode = null;
-            });
-
-            // Top toolbar
-            this.saveActionGraphElement = document.getElementById("ToolsButtonIDSaveActionGraph");
-            this.drawSaveActionGraphButton(false);
-
-            document.getElementById("ResetActionGraphID").addEventListener("click", (event: MouseEvent) => {
-                if (confirm("Are you sure?")) {
-                    for (var i = 0; i < this._viewer.root.children.length; i++) {
-                        this._viewer.selectedNode = this._viewer.root.children[i];
-                        this._viewer.utils.onRemoveBranch();
-                    }
-                    this._viewer.update();
-                    this._viewer.selectedNode = null;
-                }
-            });
-            document.getElementById("TestActionGraphID").addEventListener("click", (event: MouseEvent) => {
-                this._viewer.utils.onTestGraph();
-            });
-        }
-
-        public onResize(): void {
-            this.toolbarElement.style.top = this._viewer.viewerElement.clientHeight + 20 + "px";
-        }
-
-        public drawSaveActionGraphButton(draw: boolean) {
-            this.saveActionGraphElement.style.display = draw ? "block" : "none";
-        }
-    }
-}
+module ActionsBuilder {
+    export class Toolbar {
+        public toolbarElement: HTMLElement;
+        public saveActionGraphElement: HTMLElement;
+
+        private _viewer: Viewer;
+
+        constructor(viewer: Viewer) {
+            // Get HTML elements
+            this.toolbarElement = document.getElementById("ToolbarElementID");
+
+            // Configure this
+            this._viewer = viewer;
+
+            // Manage events
+            window.addEventListener("resize", (event: Event) => {
+                this.onResize();
+            });
+
+            // Bottom toolbar
+            document.getElementById("ViewerDeZoomID").addEventListener("click", (event: MouseEvent) => {
+                if (this._viewer.zoom > 0.1) {
+                    this._viewer.zoom -= 0.1;
+                }
+                this._viewer.update();
+            });
+            document.getElementById("ViewerZoomID").addEventListener("click", (event: MouseEvent) => {
+                if (this._viewer.zoom < 1.0) {
+                    this._viewer.zoom += 0.1;
+                }
+                this._viewer.update();
+            });
+            document.getElementById("ViewerReconnectAll").addEventListener("click", (event: MouseEvent) => {
+                for (var i = 0; i < this._viewer.root.children.length; i++) {
+                    this._viewer.selectedNode = this._viewer.root.children[i];
+                    this._viewer.utils.onDetachAction(false, true);
+                }
+                this._viewer.update();
+                this._viewer.selectedNode = null;
+            });
+            document.getElementById("ViewerDisconnectAll").addEventListener("click", (event: MouseEvent) => {
+                for (var i = 0; i < this._viewer.root.children.length; i++) {
+                    this._viewer.selectedNode = this._viewer.root.children[i];
+                    this._viewer.utils.onDetachAction(true, false);
+                }
+                this._viewer.update();
+                this._viewer.selectedNode = null;
+            });
+            document.getElementById("ViewerReduceAll").addEventListener("click", (event: MouseEvent) => {
+                for (var i = 0; i < this._viewer.root.children.length; i++) {
+                    this._viewer.selectedNode = this._viewer.root.children[i];
+                    this._viewer.utils.onReduceAll(false);
+                }
+                this._viewer.update();
+                this._viewer.selectedNode = null;
+            });
+            document.getElementById("ViewerExpandAll").addEventListener("click", (event: MouseEvent) => {
+                for (var i = 0; i < this._viewer.root.children.length; i++) {
+                    this._viewer.selectedNode = this._viewer.root.children[i];
+                    this._viewer.utils.onReduceAll(true);
+                }
+                this._viewer.update();
+                this._viewer.selectedNode = null;
+            });
+
+            // Top toolbar
+            this.saveActionGraphElement = document.getElementById("ToolsButtonIDSaveActionGraph");
+            this.drawSaveActionGraphButton(false);
+
+            document.getElementById("ResetActionGraphID").addEventListener("click", (event: MouseEvent) => {
+                if (confirm("Are you sure?")) {
+                    for (var i = 0; i < this._viewer.root.children.length; i++) {
+                        this._viewer.selectedNode = this._viewer.root.children[i];
+                        this._viewer.utils.onRemoveBranch();
+                    }
+                    this._viewer.update();
+                    this._viewer.selectedNode = null;
+                }
+            });
+            document.getElementById("TestActionGraphID").addEventListener("click", (event: MouseEvent) => {
+                this._viewer.utils.onTestGraph();
+            });
+        }
+
+        public onResize(): void {
+            this.toolbarElement.style.top = this._viewer.viewerElement.clientHeight + 20 + "px";
+        }
+
+        public drawSaveActionGraphButton(draw: boolean) {
+            this.saveActionGraphElement.style.display = draw ? "block" : "none";
+        }
+    }
+}
  

+ 326 - 326
Exporters/3ds Max/ActionsBuilder/actionsbuilder.ts

@@ -1,326 +1,326 @@
-module ActionsBuilder {
-
-    /**
-    * Defines static types
-    */
-    export class Type {
-        private static _TRIGGER = 0;
-        private static _ACTION = 1;
-        private static _FLOW_CONTROL = 2;
-        private static _OBJECT = 3;
-        private static _SCENE = 4;
-
-        public static get TRIGGER(): number {
-            return Type._TRIGGER;
-        }
-
-        public static get ACTION(): number {
-            return Type._ACTION;
-        }
-
-        public static get FLOW_CONTROL(): number {
-            return Type._FLOW_CONTROL;
-        }
-
-        public static get OBJECT(): number {
-            return Type._OBJECT;
-        }
-
-        public static get SCENE(): number {
-            return Type._SCENE;
-        }
-    }
-
-    /*
-    * Defines the BABYLON.JS elements
-    */
-    export class SceneElements {
-        /*
-        * BabylonJS objects
-        */
-        private static _ENGINE: BABYLON.Engine = new BABYLON.Engine(<HTMLCanvasElement>document.getElementById("RenderCanvasID"));
-        private static _SCENE: BABYLON.Scene = new BABYLON.Scene(SceneElements.ENGINE);
-        private static _MESH: BABYLON.Mesh = new BABYLON.Mesh("mesh", SceneElements._SCENE);
-        private static _LIGHT: BABYLON.Light = new BABYLON.Light("light", SceneElements._SCENE);
-        private static _CAMERA: BABYLON.Camera = new BABYLON.Camera("camera", BABYLON.Vector3.Zero(), SceneElements._SCENE);
-
-        public static get ENGINE(): BABYLON.Engine {
-            return SceneElements._ENGINE;
-        }
-
-        public static get SCENE(): BABYLON.Scene {
-            return SceneElements._SCENE;
-        }
-
-        public static get MESH(): BABYLON.Mesh {
-            return SceneElements._MESH;
-        }
-
-        public static get LIGHT(): BABYLON.Light {
-            return SceneElements._LIGHT;
-        }
-
-        public static get CAMERA(): BABYLON.Camera {
-            return SceneElements._CAMERA;
-        }
-
-        /*
-        * Objects names
-        */
-        private static _MESHES = new Array<string>();
-        private static _LIGHTS = new Array<string>();
-        private static _CAMERAS = new Array<string>();
-        private static _SOUNDS = new Array<string>();
-
-        public static get MESHES(): Array<string> {
-            return SceneElements._MESHES;
-        }
-
-        public static get LIGHTS(): Array<string> {
-            return SceneElements._LIGHTS;
-        }
-
-        public static get CAMERAS(): Array<string> {
-            return SceneElements._CAMERAS;
-        }
-
-        public static get SOUNDS(): Array<string> {
-            return SceneElements._SOUNDS;
-        }
-
-        /*
-        * Properties
-        */
-        private static _MESH_PROPERTIES = new Array<string>();
-        private static _LIGHT_PROPERTIES = new Array<string>();
-        private static _CAMERA_PROPERTIES = new Array<string>();
-        private static _SCENE_PROPERTIES = new Array<string>();
-
-        public static get MESH_PROPERTIES(): Array<string> {
-            return SceneElements._MESH_PROPERTIES;
-        }
-
-        public static get LIGHT_PROPERTIES(): Array<string> {
-            return SceneElements._LIGHT_PROPERTIES;
-        }
-
-        public static get CAMERA_PROPERTIES(): Array<string> {
-            return SceneElements._CAMERA_PROPERTIES;
-        }
-
-        public static get SCENE_PROPERTIES(): Array<string> {
-            return SceneElements._SCENE_PROPERTIES;
-        }
-
-        /*
-        * Types
-        */
-        private static _TYPES = new Array<string>();
-
-        public static get TYPES(): Array<string> {
-            return SceneElements._TYPES;
-        }
-
-        /*
-        * Operators
-        */
-        private static _OPERATORS = new Array<string>();
-
-        public static get OPERATORS(): Array<string> {
-            return SceneElements._OPERATORS;
-        }
-
-        /*
-        * Methods
-        */
-        public static GetInstanceOf(object: Object): string {
-            if (object === null || object === undefined) {
-                return "";
-            }
-            return object.constructor.toString().match(/function (\w*)/)[1];
-        }
-
-        public static TestInstanceOf (object: Object, propertyName: string): boolean {
-            if (object === null || object.constructor === null) {
-                return false;
-            }
-
-            if (propertyName.length > 0 && propertyName[0] === "_")
-                return false;
-
-            var name = SceneElements.GetInstanceOf(object);
-
-            for (var i = 0; i < SceneElements.TYPES.length; i++) {
-                if (name === SceneElements.TYPES[i]) {
-                    return true;
-                }
-            }
-
-            return false;
-        }
-    }
-
-    // Functions
-    var specialTypes = [
-        "StandardMaterial"
-    ];
-    SceneElements.MESH.material = new BABYLON.StandardMaterial("material", SceneElements.SCENE);
-
-    var addSpecialType = (object: any, properties: Array<string>, thing: string) => {
-        for (var specialThing in object[thing]) {
-            if (object[thing].hasOwnProperty(specialThing) && SceneElements.TestInstanceOf(object[thing][specialThing], specialThing)) {
-                properties.push(thing + "." + specialThing);
-            }
-        }
-    };
-
-    // Configure types
-    SceneElements.TYPES.push("Color3");
-    SceneElements.TYPES.push("Boolean");
-    SceneElements.TYPES.push("Number");
-    SceneElements.TYPES.push("Vector2");
-    SceneElements.TYPES.push("Vector3");
-    SceneElements.TYPES.push("String");
-
-    // Configure operators
-    SceneElements.OPERATORS.push("IsEqual");
-    SceneElements.OPERATORS.push("IsDifferent");
-    SceneElements.OPERATORS.push("IsGreater");
-    SceneElements.OPERATORS.push("IsLesser");
-
-    // Configure properties
-    for (var thing in SceneElements.MESH) {
-        var instance = SceneElements.GetInstanceOf(SceneElements.MESH[thing]);
-
-        if (SceneElements.MESH.hasOwnProperty(thing)) {
-            if (specialTypes.indexOf(instance) !== -1) {
-                addSpecialType(SceneElements.MESH, SceneElements.MESH_PROPERTIES, thing);
-            }
-            else if (SceneElements.TestInstanceOf(SceneElements.MESH[thing], thing)) {
-                SceneElements.MESH_PROPERTIES.push(thing);
-            }
-        }
-    }
-
-    for (var thing in SceneElements.LIGHT) {
-        if (SceneElements.LIGHT.hasOwnProperty(thing) && SceneElements.TestInstanceOf(SceneElements.LIGHT[thing], thing)) {
-            SceneElements.LIGHT_PROPERTIES.push(thing);
-        }
-    }
-
-    for (var thing in SceneElements.CAMERA) {
-        if (SceneElements.CAMERA.hasOwnProperty(thing) && SceneElements.TestInstanceOf(SceneElements.CAMERA[thing], thing)) {
-            SceneElements.CAMERA_PROPERTIES.push(thing);
-        }
-    }
-
-    for (var thing in SceneElements.SCENE) {
-        if (SceneElements.SCENE.hasOwnProperty(thing) && SceneElements.TestInstanceOf(SceneElements.SCENE[thing], thing)) {
-            SceneElements.SCENE_PROPERTIES.push(thing);
-        }
-    }
-
-    /**
-    * Defines an element property
-    */
-    export interface ElementProperty {
-        targetType?: string;
-        text: string;
-        value: string;
-    }
-
-    /**
-    * Defines an element property result
-    */
-    export interface ElementPropertyResult {
-        targetType?: string;
-        value: string;
-    }
-
-    /**
-    * Generic element, has a name, a text to draw, a description
-    * and a list of properties (ElementProperty)
-    */
-    export interface Element {
-        name: string;
-        text: string;
-        properties: Array<ElementProperty>;
-        description: string;
-    }
-
-    /**
-    * Actions Builder elements (triggers, actions & flow controls) that are
-    * arrays of Element
-    */
-    export class Elements {
-        private static _TRIGGERS = new Array<Element>();
-        private static _ACTIONS = new Array<Element>();
-        private static _FLOW_CONTROLS = new Array<Element>();
-
-        public static get TRIGGERS(): Array<Element> {
-            return Elements._TRIGGERS;
-        }
-
-        public static get ACTIONS(): Array<Element> {
-            return Elements._ACTIONS;
-        }
-
-        public static get FLOW_CONTROLS(): Array<Element> {
-            return Elements._FLOW_CONTROLS;
-        }
-
-        public static GetElementFromName(name: string): Element {
-            for (var i = 0; i < Elements.TRIGGERS.length; i++) {
-                if (Elements.TRIGGERS[i].name === name) {
-                    return Elements._TRIGGERS[i];
-                }
-            }
-
-            for (var i = 0; i < Elements.ACTIONS.length; i++) {
-                if (Elements.ACTIONS[i].name === name) {
-                    return Elements._ACTIONS[i];
-                }
-            }
-
-            for (var i = 0; i < Elements.FLOW_CONTROLS.length; i++) {
-                if (Elements.FLOW_CONTROLS[i].name === name) {
-                    return Elements._FLOW_CONTROLS[i];
-                }
-            }
-
-            return null;
-        }
-    }
-
-    // Configure triggers
-    Elements.TRIGGERS.push({ name: "OnPickTrigger", text: "pick", properties: [], description: "When the user picks the edited mesh" });
-    Elements.TRIGGERS.push({ name: "OnLeftPickTrigger", text: "left pick", properties: [], description: "When the user picks the edited mesh using the left click" });
-    Elements.TRIGGERS.push({ name: "OnRightPickTrigger", text: "right pick", properties: [], description: "When the user picks the edited mesh using the right click" });
-    Elements.TRIGGERS.push({ name: "OnCenterPickTrigger", text: "center pick", properties: [], description: "When the user picks the edited mesh using the click of the mouse wheel" });
-    Elements.TRIGGERS.push({ name: "OnPointerOverTrigger", text: "pointer over", properties: [], description: "When the user's mouse is over the edited mesh" });
-    Elements.TRIGGERS.push({ name: "OnPointerOutTrigger", text: "pointer out", properties: [], description: "When the user's mouse is out of the edited mesh" });
-    Elements.TRIGGERS.push({ name: "OnEveryFrameTrigger", text: "every frame", properties: [], description: "This trigger is called each frame (only on scene)" });
-    Elements.TRIGGERS.push({ name: "OnIntersectionEnterTrigger", text: "intersection enter", properties: [{ targetType: "MeshProperties", text: "parameter", value: "Object name?" }], description: "When the edited mesh intersects the another mesh predefined in the options" });
-    Elements.TRIGGERS.push({ name: "OnIntersectionExitTrigger", text: "intersection exit", properties: [{ targetType: "MeshProperties", text: "parameter", value: "Object name?" }], description: "When the edited mesh exits intersection with the another mesh predefined in the options" });
-    Elements.TRIGGERS.push({ name: "OnKeyDownTrigger", text: "key down", properties: [{ targetType: null, text: "parameter:", value: "a" }], description: "When the user pressed a key (enter the key character, example: \"r\")" });
-    Elements.TRIGGERS.push({ name: "OnKeyUpTrigger", text: "key up", properties: [{ targetType: null, text: "parameter:", value: "a" }], description: "When the user unpressed a key (enter the key character, example: \"p\")" });
-
-    // Configure actions
-    Elements.ACTIONS.push({ name: "SwitchBooleanAction", text: "switch boolean", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "propertyPath", value: "" }], description: "Switches the boolean value of a given parameter of the target object: true to false, or false to true" });
-    Elements.ACTIONS.push({ name: "SetStateAction", text: "set state", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "value", value: "" }], description: "Sets a new state value for the target object (example: \"off\" or \"on\")" });
-    Elements.ACTIONS.push({ name: "SetValueAction", text: "set value", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "propertyPath", value: "" }, { text: "value", value: "" }], description: "Sets a new value to the specified parameter of the target object (example: position.x to 0.0)" });
-    Elements.ACTIONS.push({ name: "SetParentAction", text: "set parent", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "parent", value: "" }], description: "Sets the new parent of the target object (example: a mesh or a light)" });
-    Elements.ACTIONS.push({ name: "IncrementValueAction", text: "increment value", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "propertyPath", value: "" }, { text: "value", value: "" }], description: "Increments the value of the given parameter of the target object. The value can be negative. (example: increment position.x of 5.0)" });
-    Elements.ACTIONS.push({ name: "PlayAnimationAction", text: "play animation", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "from", value: "0" }, { text: "to", value: "150" }, { text: "loop", value: "false" }], description: "Plays an animation of the target object. Specify the start frame, the end frame and if the animation should loop." });
-    Elements.ACTIONS.push({ name: "StopAnimationAction", text: "stop animation", properties: [{ targetType: "MeshProperties", text: "target", value: "" }], description: "Stops the animations of the target object." });
-    Elements.ACTIONS.push({ name: "DoNothingAction", text: "do nothing", properties: [], description: "Does nothing, can be used to balance/equilibrate the actions graph." });
-    Elements.ACTIONS.push({ name: "InterpolateValueAction", text: "interpolate value", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "propertyPath", value: "" }, { text: "value", value: "0" }, { text: "duration", value: "1000" }, { text: "stopOtherAnimations", value: "false" }], description: "Creates an animation (key frames) that animates the target object by interpolating the given parameter of the target value." });
-    Elements.ACTIONS.push({ name: "PlaySoundAction", text: "play sound", properties: [{ text: "sound", value: "" }], description: "Plays the specified sound." });
-    Elements.ACTIONS.push({ name: "StopSoundAction", text: "stop sound", properties: [{ text: "sound", value: "" }], description: "Stops the specified sound." });
-    Elements.ACTIONS.push({ name: "CombineAction", text: "combine", properties: [], description: "Special action that combines multiple actions. The combined actions are executed at the same time. Drag'n'drop the new actions inside to combine actions." });
-
-    // Configure flow control
-    Elements.FLOW_CONTROLS.push({ name: "ValueCondition", text: "value condition", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "propertyPath", value: "" }, { text: "value", value: "" }, { text: "operator", value: SceneElements.OPERATORS[0] }], description: "A condition checking if a given value is equal, different, lesser or greater than the given parameter of the target object" });
-    Elements.FLOW_CONTROLS.push({ name: "StateCondition", text: "state condition", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "value", value: "" }], description: "A condition checking if the target object's state is equal to the given state. See \"set state\" action to set a state to an object." });
-    Elements.FLOW_CONTROLS.push({ name: "Hub", text: "hub", properties: [], description: "The hub is internally used by the Combine Action. It allows to add children to the Combine Action" });
-}
+module ActionsBuilder {
+
+    /**
+    * Defines static types
+    */
+    export class Type {
+        private static _TRIGGER = 0;
+        private static _ACTION = 1;
+        private static _FLOW_CONTROL = 2;
+        private static _OBJECT = 3;
+        private static _SCENE = 4;
+
+        public static get TRIGGER(): number {
+            return Type._TRIGGER;
+        }
+
+        public static get ACTION(): number {
+            return Type._ACTION;
+        }
+
+        public static get FLOW_CONTROL(): number {
+            return Type._FLOW_CONTROL;
+        }
+
+        public static get OBJECT(): number {
+            return Type._OBJECT;
+        }
+
+        public static get SCENE(): number {
+            return Type._SCENE;
+        }
+    }
+
+    /*
+    * Defines the BABYLON.JS elements
+    */
+    export class SceneElements {
+        /*
+        * BabylonJS objects
+        */
+        private static _ENGINE: BABYLON.Engine = new BABYLON.Engine(<HTMLCanvasElement>document.getElementById("RenderCanvasID"));
+        private static _SCENE: BABYLON.Scene = new BABYLON.Scene(SceneElements.ENGINE);
+        private static _MESH: BABYLON.Mesh = new BABYLON.Mesh("mesh", SceneElements._SCENE);
+        private static _LIGHT: BABYLON.Light = new BABYLON.Light("light", SceneElements._SCENE);
+        private static _CAMERA: BABYLON.Camera = new BABYLON.Camera("camera", BABYLON.Vector3.Zero(), SceneElements._SCENE);
+
+        public static get ENGINE(): BABYLON.Engine {
+            return SceneElements._ENGINE;
+        }
+
+        public static get SCENE(): BABYLON.Scene {
+            return SceneElements._SCENE;
+        }
+
+        public static get MESH(): BABYLON.Mesh {
+            return SceneElements._MESH;
+        }
+
+        public static get LIGHT(): BABYLON.Light {
+            return SceneElements._LIGHT;
+        }
+
+        public static get CAMERA(): BABYLON.Camera {
+            return SceneElements._CAMERA;
+        }
+
+        /*
+        * Objects names
+        */
+        private static _MESHES = new Array<string>();
+        private static _LIGHTS = new Array<string>();
+        private static _CAMERAS = new Array<string>();
+        private static _SOUNDS = new Array<string>();
+
+        public static get MESHES(): Array<string> {
+            return SceneElements._MESHES;
+        }
+
+        public static get LIGHTS(): Array<string> {
+            return SceneElements._LIGHTS;
+        }
+
+        public static get CAMERAS(): Array<string> {
+            return SceneElements._CAMERAS;
+        }
+
+        public static get SOUNDS(): Array<string> {
+            return SceneElements._SOUNDS;
+        }
+
+        /*
+        * Properties
+        */
+        private static _MESH_PROPERTIES = new Array<string>();
+        private static _LIGHT_PROPERTIES = new Array<string>();
+        private static _CAMERA_PROPERTIES = new Array<string>();
+        private static _SCENE_PROPERTIES = new Array<string>();
+
+        public static get MESH_PROPERTIES(): Array<string> {
+            return SceneElements._MESH_PROPERTIES;
+        }
+
+        public static get LIGHT_PROPERTIES(): Array<string> {
+            return SceneElements._LIGHT_PROPERTIES;
+        }
+
+        public static get CAMERA_PROPERTIES(): Array<string> {
+            return SceneElements._CAMERA_PROPERTIES;
+        }
+
+        public static get SCENE_PROPERTIES(): Array<string> {
+            return SceneElements._SCENE_PROPERTIES;
+        }
+
+        /*
+        * Types
+        */
+        private static _TYPES = new Array<string>();
+
+        public static get TYPES(): Array<string> {
+            return SceneElements._TYPES;
+        }
+
+        /*
+        * Operators
+        */
+        private static _OPERATORS = new Array<string>();
+
+        public static get OPERATORS(): Array<string> {
+            return SceneElements._OPERATORS;
+        }
+
+        /*
+        * Methods
+        */
+        public static GetInstanceOf(object: Object): string {
+            if (object === null || object === undefined) {
+                return "";
+            }
+            return object.constructor.toString().match(/function (\w*)/)[1];
+        }
+
+        public static TestInstanceOf (object: Object, propertyName: string): boolean {
+            if (object === null || object.constructor === null) {
+                return false;
+            }
+
+            if (propertyName.length > 0 && propertyName[0] === "_")
+                return false;
+
+            var name = SceneElements.GetInstanceOf(object);
+
+            for (var i = 0; i < SceneElements.TYPES.length; i++) {
+                if (name === SceneElements.TYPES[i]) {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+    }
+
+    // Functions
+    var specialTypes = [
+        "StandardMaterial"
+    ];
+    SceneElements.MESH.material = new BABYLON.StandardMaterial("material", SceneElements.SCENE);
+
+    var addSpecialType = (object: any, properties: Array<string>, thing: string) => {
+        for (var specialThing in object[thing]) {
+            if (object[thing].hasOwnProperty(specialThing) && SceneElements.TestInstanceOf(object[thing][specialThing], specialThing)) {
+                properties.push(thing + "." + specialThing);
+            }
+        }
+    };
+
+    // Configure types
+    SceneElements.TYPES.push("Color3");
+    SceneElements.TYPES.push("Boolean");
+    SceneElements.TYPES.push("Number");
+    SceneElements.TYPES.push("Vector2");
+    SceneElements.TYPES.push("Vector3");
+    SceneElements.TYPES.push("String");
+
+    // Configure operators
+    SceneElements.OPERATORS.push("IsEqual");
+    SceneElements.OPERATORS.push("IsDifferent");
+    SceneElements.OPERATORS.push("IsGreater");
+    SceneElements.OPERATORS.push("IsLesser");
+
+    // Configure properties
+    for (var thing in SceneElements.MESH) {
+        var instance = SceneElements.GetInstanceOf(SceneElements.MESH[thing]);
+
+        if (SceneElements.MESH.hasOwnProperty(thing)) {
+            if (specialTypes.indexOf(instance) !== -1) {
+                addSpecialType(SceneElements.MESH, SceneElements.MESH_PROPERTIES, thing);
+            }
+            else if (SceneElements.TestInstanceOf(SceneElements.MESH[thing], thing)) {
+                SceneElements.MESH_PROPERTIES.push(thing);
+            }
+        }
+    }
+
+    for (var thing in SceneElements.LIGHT) {
+        if (SceneElements.LIGHT.hasOwnProperty(thing) && SceneElements.TestInstanceOf(SceneElements.LIGHT[thing], thing)) {
+            SceneElements.LIGHT_PROPERTIES.push(thing);
+        }
+    }
+
+    for (var thing in SceneElements.CAMERA) {
+        if (SceneElements.CAMERA.hasOwnProperty(thing) && SceneElements.TestInstanceOf(SceneElements.CAMERA[thing], thing)) {
+            SceneElements.CAMERA_PROPERTIES.push(thing);
+        }
+    }
+
+    for (var thing in SceneElements.SCENE) {
+        if (SceneElements.SCENE.hasOwnProperty(thing) && SceneElements.TestInstanceOf(SceneElements.SCENE[thing], thing)) {
+            SceneElements.SCENE_PROPERTIES.push(thing);
+        }
+    }
+
+    /**
+    * Defines an element property
+    */
+    export interface ElementProperty {
+        targetType?: string;
+        text: string;
+        value: string;
+    }
+
+    /**
+    * Defines an element property result
+    */
+    export interface ElementPropertyResult {
+        targetType?: string;
+        value: string;
+    }
+
+    /**
+    * Generic element, has a name, a text to draw, a description
+    * and a list of properties (ElementProperty)
+    */
+    export interface Element {
+        name: string;
+        text: string;
+        properties: Array<ElementProperty>;
+        description: string;
+    }
+
+    /**
+    * Actions Builder elements (triggers, actions & flow controls) that are
+    * arrays of Element
+    */
+    export class Elements {
+        private static _TRIGGERS = new Array<Element>();
+        private static _ACTIONS = new Array<Element>();
+        private static _FLOW_CONTROLS = new Array<Element>();
+
+        public static get TRIGGERS(): Array<Element> {
+            return Elements._TRIGGERS;
+        }
+
+        public static get ACTIONS(): Array<Element> {
+            return Elements._ACTIONS;
+        }
+
+        public static get FLOW_CONTROLS(): Array<Element> {
+            return Elements._FLOW_CONTROLS;
+        }
+
+        public static GetElementFromName(name: string): Element {
+            for (var i = 0; i < Elements.TRIGGERS.length; i++) {
+                if (Elements.TRIGGERS[i].name === name) {
+                    return Elements._TRIGGERS[i];
+                }
+            }
+
+            for (var i = 0; i < Elements.ACTIONS.length; i++) {
+                if (Elements.ACTIONS[i].name === name) {
+                    return Elements._ACTIONS[i];
+                }
+            }
+
+            for (var i = 0; i < Elements.FLOW_CONTROLS.length; i++) {
+                if (Elements.FLOW_CONTROLS[i].name === name) {
+                    return Elements._FLOW_CONTROLS[i];
+                }
+            }
+
+            return null;
+        }
+    }
+
+    // Configure triggers
+    Elements.TRIGGERS.push({ name: "OnPickTrigger", text: "pick", properties: [], description: "When the user picks the edited mesh" });
+    Elements.TRIGGERS.push({ name: "OnLeftPickTrigger", text: "left pick", properties: [], description: "When the user picks the edited mesh using the left click" });
+    Elements.TRIGGERS.push({ name: "OnRightPickTrigger", text: "right pick", properties: [], description: "When the user picks the edited mesh using the right click" });
+    Elements.TRIGGERS.push({ name: "OnCenterPickTrigger", text: "center pick", properties: [], description: "When the user picks the edited mesh using the click of the mouse wheel" });
+    Elements.TRIGGERS.push({ name: "OnPointerOverTrigger", text: "pointer over", properties: [], description: "When the user's mouse is over the edited mesh" });
+    Elements.TRIGGERS.push({ name: "OnPointerOutTrigger", text: "pointer out", properties: [], description: "When the user's mouse is out of the edited mesh" });
+    Elements.TRIGGERS.push({ name: "OnEveryFrameTrigger", text: "every frame", properties: [], description: "This trigger is called each frame (only on scene)" });
+    Elements.TRIGGERS.push({ name: "OnIntersectionEnterTrigger", text: "intersection enter", properties: [{ targetType: "MeshProperties", text: "parameter", value: "Object name?" }], description: "When the edited mesh intersects the another mesh predefined in the options" });
+    Elements.TRIGGERS.push({ name: "OnIntersectionExitTrigger", text: "intersection exit", properties: [{ targetType: "MeshProperties", text: "parameter", value: "Object name?" }], description: "When the edited mesh exits intersection with the another mesh predefined in the options" });
+    Elements.TRIGGERS.push({ name: "OnKeyDownTrigger", text: "key down", properties: [{ targetType: null, text: "parameter", value: "a" }], description: "When the user pressed a key (enter the key character, example: \"r\")" });
+    Elements.TRIGGERS.push({ name: "OnKeyUpTrigger", text: "key up", properties: [{ targetType: null, text: "parameter", value: "a" }], description: "When the user unpressed a key (enter the key character, example: \"p\")" });
+
+    // Configure actions
+    Elements.ACTIONS.push({ name: "SwitchBooleanAction", text: "switch boolean", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "propertyPath", value: "" }], description: "Switches the boolean value of a given parameter of the target object: true to false, or false to true" });
+    Elements.ACTIONS.push({ name: "SetStateAction", text: "set state", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "value", value: "" }], description: "Sets a new state value for the target object (example: \"off\" or \"on\")" });
+    Elements.ACTIONS.push({ name: "SetValueAction", text: "set value", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "propertyPath", value: "" }, { text: "value", value: "" }], description: "Sets a new value to the specified parameter of the target object (example: position.x to 0.0)" });
+    Elements.ACTIONS.push({ name: "SetParentAction", text: "set parent", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "parent", value: "" }], description: "Sets the new parent of the target object (example: a mesh or a light)" });
+    Elements.ACTIONS.push({ name: "IncrementValueAction", text: "increment value", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "propertyPath", value: "" }, { text: "value", value: "" }], description: "Increments the value of the given parameter of the target object. The value can be negative. (example: increment position.x of 5.0)" });
+    Elements.ACTIONS.push({ name: "PlayAnimationAction", text: "play animation", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "from", value: "0" }, { text: "to", value: "150" }, { text: "loop", value: "false" }], description: "Plays an animation of the target object. Specify the start frame, the end frame and if the animation should loop." });
+    Elements.ACTIONS.push({ name: "StopAnimationAction", text: "stop animation", properties: [{ targetType: "MeshProperties", text: "target", value: "" }], description: "Stops the animations of the target object." });
+    Elements.ACTIONS.push({ name: "DoNothingAction", text: "do nothing", properties: [], description: "Does nothing, can be used to balance/equilibrate the actions graph." });
+    Elements.ACTIONS.push({ name: "InterpolateValueAction", text: "interpolate value", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "propertyPath", value: "" }, { text: "value", value: "0" }, { text: "duration", value: "1000" }, { text: "stopOtherAnimations", value: "false" }], description: "Creates an animation (key frames) that animates the target object by interpolating the given parameter of the target value." });
+    Elements.ACTIONS.push({ name: "PlaySoundAction", text: "play sound", properties: [{ text: "sound", value: "" }], description: "Plays the specified sound." });
+    Elements.ACTIONS.push({ name: "StopSoundAction", text: "stop sound", properties: [{ text: "sound", value: "" }], description: "Stops the specified sound." });
+    Elements.ACTIONS.push({ name: "CombineAction", text: "combine", properties: [], description: "Special action that combines multiple actions. The combined actions are executed at the same time. Drag'n'drop the new actions inside to combine actions." });
+
+    // Configure flow control
+    Elements.FLOW_CONTROLS.push({ name: "ValueCondition", text: "value condition", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "propertyPath", value: "" }, { text: "value", value: "" }, { text: "operator", value: SceneElements.OPERATORS[0] }], description: "A condition checking if a given value is equal, different, lesser or greater than the given parameter of the target object" });
+    Elements.FLOW_CONTROLS.push({ name: "StateCondition", text: "state condition", properties: [{ targetType: "MeshProperties", text: "target", value: "" }, { text: "value", value: "" }], description: "A condition checking if the target object's state is equal to the given state. See \"set state\" action to set a state to an object." });
+    Elements.FLOW_CONTROLS.push({ name: "Hub", text: "hub", properties: [], description: "The hub is internally used by the Combine Action. It allows to add children to the Combine Action" });
+}

+ 370 - 0
Exporters/3ds Max/ActionsBuilder/actionsbuilder.utils.js

@@ -0,0 +1,370 @@
+var ActionsBuilder;
+(function (ActionsBuilder) {
+    var Utils = (function () {
+        function Utils(viewer) {
+            this.copiedStructure = null;
+            this._viewer = viewer;
+        }
+        Utils.prototype.onTestGraph = function () {
+            var _this = this;
+            if (this._viewer.root.children.length === 0) {
+                alert("Please add at least a Trigger and an Action to test the graph");
+            }
+            var onTestTarget = function (targetType, target) {
+                var targetExists = false;
+                var array = _this._viewer.parameters._getTargetFromType(targetType);
+                if (array === null) {
+                    return targetExists;
+                }
+                for (var i = 0; i < array.length; i++) {
+                    if (array[i] === target) {
+                        targetExists = true;
+                        break;
+                    }
+                }
+                return targetExists;
+            };
+            var onNodeError = function (action) {
+                var node = action.node;
+                node.rect.attr("fill", Raphael.rgb(255, 0, 0));
+                return false;
+            };
+            var onTestAction = function (action) {
+                console.log("Testing " + action.name);
+                if (action.combineArray !== null) {
+                    var foundError = false;
+                    for (var i = 0; i < action.combineArray.length; i++) {
+                        if (!onTestAction(action.combineArray[i])) {
+                            foundError = true;
+                        }
+                    }
+                    if (foundError) {
+                        return false;
+                    }
+                }
+                else {
+                    var properties = action.properties;
+                    var propertiesResults = action.propertiesResults;
+                    if (properties !== null) {
+                        var object = null;
+                        var propertyPath = null;
+                        for (var i = 0; i < properties.length; i++) {
+                            if (properties[i].text === "target" || properties[i].text === "parent") {
+                                object = _this._viewer.parameters._getObjectFromType(properties[i].targetType);
+                                var targetExists = onTestTarget(propertiesResults[i].targetType, propertiesResults[i].value);
+                                if (!targetExists) {
+                                    return onNodeError(action);
+                                }
+                            }
+                            else if (properties[i].text === "propertyPath") {
+                                var property = propertiesResults[i].value;
+                                var effectiveProperty = object;
+                                var p = property.split(".");
+                                for (var j = 0; j < p.length && effectiveProperty !== undefined; j++) {
+                                    effectiveProperty = effectiveProperty[p[j]];
+                                }
+                                if (effectiveProperty === undefined) {
+                                    return onNodeError(action);
+                                }
+                                else {
+                                    propertyPath = effectiveProperty;
+                                }
+                            }
+                            else if (properties[i].text == "value" && propertyPath != null) {
+                                var value = propertiesResults[i].value;
+                                if (!isNaN(propertyPath)) {
+                                    var num = parseFloat(value);
+                                    if (isNaN(num) || value === "") {
+                                        return onNodeError(action);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    var foundError = false;
+                    for (var i = 0; i < action.children.length; i++) {
+                        if (!onTestAction(action.children[i])) {
+                            foundError = true;
+                        }
+                    }
+                    return !foundError;
+                }
+            };
+            var root = this._viewer.root;
+            var foundError = false;
+            for (var i = 0; i < root.children.length; i++) {
+                var trigger = root.children[i];
+                var properties = trigger.properties;
+                if (properties !== null && properties.length > 0) {
+                    var parameter = trigger.propertiesResults[0].value;
+                    if (properties[0].targetType !== null) {
+                        if (!onTestTarget("MeshProperties", parameter)) {
+                            foundError = onNodeError(trigger);
+                        }
+                    }
+                    else {
+                        if (!parameter.match(/[a-z]/)) {
+                            foundError = onNodeError(trigger);
+                        }
+                    }
+                }
+                for (var j = 0; j < trigger.children.length; j++) {
+                    var child = trigger.children[j];
+                    var result = onTestAction(child);
+                    if (!result) {
+                        foundError = true;
+                    }
+                }
+            }
+            if (foundError) {
+                alert("Found error(s). the red nodes contain the error.");
+            }
+            else {
+                alert("No error found.");
+            }
+        };
+        Utils.prototype.onReduceAll = function (forceExpand) {
+            if (forceExpand === void 0) { forceExpand = false; }
+            if (this._viewer.selectedNode === null) {
+                return;
+            }
+            var action = this._viewer.selectedNode;
+            if (action.combineArray !== null) {
+                for (var i = 0; i < action.combineArray.length; i++) {
+                    this._viewer.selectedNode = action.combineArray[i];
+                    this.onReduce(forceExpand, !forceExpand);
+                }
+            }
+            else {
+                this.onReduce(forceExpand, !forceExpand);
+            }
+            for (var i = 0; i < action.children.length; i++) {
+                this._viewer.selectedNode = action.children[i];
+                this.onReduceAll(forceExpand);
+            }
+        };
+        Utils.prototype.onReduce = function (forceExpand, forceReduce) {
+            if (forceExpand === void 0) { forceExpand = false; }
+            if (forceReduce === void 0) { forceReduce = false; }
+            if (this._viewer.selectedNode === null) {
+                return;
+            }
+            var node = this._viewer.selectedNode.node;
+            node.rect.stop(node.rect.animation);
+            if (forceExpand === true) {
+                node.minimized = false;
+            }
+            else if (forceReduce === true) {
+                node.minimized = true;
+            }
+            else {
+                node.minimized = !node.minimized;
+            }
+            if (node.minimized) {
+                node.text.hide();
+                node.rect.attr("width", ActionsBuilder.Viewer.NODE_MINIMIZED_WIDTH * this._viewer.zoom);
+            }
+            else {
+                node.text.show();
+                node.rect.attr("width", ActionsBuilder.Viewer.NODE_WIDTH * this._viewer.zoom);
+            }
+        };
+        Utils.prototype.onDetachAction = function (forceDetach, forceAttach) {
+            var _this = this;
+            if (forceDetach === void 0) { forceDetach = false; }
+            if (forceAttach === void 0) { forceAttach = false; }
+            if (this._viewer.selectedNode === null) {
+                return;
+            }
+            var action = this._viewer.selectedNode;
+            if (forceDetach === true) {
+                action.node.detached = true;
+            }
+            else if (forceAttach === true) {
+                action.node.detached = false;
+            }
+            else {
+                action.node.detached = !action.node.detached;
+            }
+            var onSetColor = function (root, detached) {
+                var rootNode = root.node;
+                rootNode.rect.attr("fill", _this._viewer.getNodeColor(root.type, detached));
+                if (root.combineArray !== null) {
+                    for (var i = 0; i < root.combineArray.length; i++) {
+                        var combineNode = root.combineArray[i].node;
+                        combineNode.rect.attr("fill", _this._viewer.getNodeColor(root.combineArray[i].type, detached));
+                    }
+                }
+                for (var i = 0; i < root.children.length; i++) {
+                    onSetColor(root.children[i], detached);
+                }
+            };
+            onSetColor(action, action.node.detached);
+        };
+        Utils.prototype.onRemoveNode = function () {
+            if (this._viewer.selectedNode === null) {
+                return;
+            }
+            var action = this._viewer.selectedNode;
+            var parent = action.parent;
+            if (action.type === ActionsBuilder.Type.TRIGGER) {
+                this.onRemoveBranch();
+                return;
+            }
+            if (action.type === ActionsBuilder.Type.FLOW_CONTROL && parent !== null && parent.combineArray !== null) {
+                action = parent;
+                parent = action.parent;
+            }
+            if (parent !== null && parent.combineArray !== null) {
+                parent.removeCombinedAction(action);
+                if (parent.combineArray.length === 0) {
+                    parent.node.text.attr("text", "combine");
+                }
+            }
+            else {
+                if (action.combineArray !== null) {
+                    action.removeChild(action.hub);
+                }
+                action.parent.removeChild(action);
+            }
+            if (action.combineArray !== null) {
+                this._viewer.removeAction(action.hub, false);
+            }
+            this._viewer.removeAction(action, false);
+            this._viewer.update();
+            this._viewer.parameters.clearParameters();
+            this._viewer.selectedNode = null;
+        };
+        Utils.prototype.onRemoveBranch = function () {
+            if (this._viewer.selectedNode === null) {
+                return;
+            }
+            if (this._viewer.selectedNode === this._viewer.root) {
+                alert("Cannot remove the root node");
+                return;
+            }
+            var action = this._viewer.selectedNode;
+            var parent = action.parent;
+            if (action.parent !== null && action.parent.combineArray !== null) {
+                action = parent;
+                parent = action.parent;
+            }
+            if (action.combineArray !== null) {
+                action.removeChild(action.hub);
+            }
+            action.parent.removeChild(action);
+            this._viewer.removeAction(action, true);
+            this._viewer.update();
+            this._viewer.parameters.clearParameters();
+            this._viewer.selectedNode = null;
+        };
+        Utils.prototype.onCopyStructure = function () {
+            if (this._viewer.selectedNode === null) {
+                return;
+            }
+            var structure = this.createJSON(this._viewer.selectedNode);
+            var asText = JSON.stringify(structure);
+            if (window.clipboardData !== undefined) {
+                window.clipboardData.setData("text", asText);
+            }
+            else {
+                this.copiedStructure = asText;
+            }
+        };
+        Utils.prototype.onPasteStructure = function () {
+            if (this._viewer.selectedNode === null) {
+                return;
+            }
+            var asText = (window.clipboardData !== undefined) ? window.clipboardData.getData("text") : this.copiedStructure;
+            var isJson = asText.length > 0 && asText[0] == "{" && asText[asText.length - 1] == "}";
+            var structure = JSON.parse(asText);
+            var action = this._viewer.selectedNode;
+            if (structure.type === ActionsBuilder.Type.TRIGGER && action !== this._viewer.root) {
+                alert("You can't paste a trigger if the selected node isn't the root object");
+                return;
+            }
+            if (structure.type !== ActionsBuilder.Type.TRIGGER && action === this._viewer.root) {
+                alert("You can't paste an action or condition if the selected node is the root object");
+                return;
+            }
+            this.loadFromJSON(structure, action);
+            this._viewer.update();
+        };
+        Utils.prototype.loadFromJSON = function (graph, startAction) {
+            var _this = this;
+            if (startAction === null) {
+                for (var i = 0; i < this._viewer.root.children.length; i++) {
+                    this._viewer.removeAction(this._viewer.root.children[i], true);
+                }
+                this._viewer.root.clearChildren();
+            }
+            var load = function (root, parent, detached, combine) {
+                if (parent === null) {
+                    parent = _this._viewer.root;
+                }
+                var newAction = null;
+                if (root.type !== ActionsBuilder.Type.OBJECT && root.type !== ActionsBuilder.Type.SCENE) {
+                    var action = _this._viewer.addAction(parent, root.type, ActionsBuilder.Elements.GetElementFromName(root.name));
+                    for (var i = 0; i < root.properties.length; i++) {
+                        var targetType = root.properties[i].targetType;
+                        if (targetType === undefined) {
+                            targetType = "MeshProperties";
+                        }
+                        action.propertiesResults[i] = { value: root.properties[i].value, targetType: targetType };
+                    }
+                    var node = action.node;
+                    node.detached = root.detached;
+                    if (detached) {
+                        node.rect.attr("fill", _this._viewer.getNodeColor(action.type, detached));
+                    }
+                    if (root.combine !== undefined) {
+                        for (var i = 0; i < root.combine.length; i++) {
+                            load(root.combine[i], action, detached, true);
+                        }
+                    }
+                    if (!combine) {
+                        parent = parent.children[parent.children.length - 1];
+                    }
+                }
+                for (var i = 0; i < root.children.length; i++) {
+                    load(root.children[i], newAction !== null && newAction.combineArray !== null ? newAction.hub : parent, root.detached, false);
+                }
+            };
+            load(graph, startAction, false, false);
+            this._viewer.update();
+        };
+        Utils.prototype.createJSON = function (root) {
+            var action = {
+                type: root.type,
+                name: root.name,
+                detached: root.node.detached,
+                children: new Array(),
+                combine: new Array(),
+                properties: new Array()
+            };
+            for (var i = 0; i < root.properties.length; i++) {
+                action.properties.push({
+                    name: root.properties[i].text,
+                    value: root.propertiesResults[i].value,
+                    targetType: root.propertiesResults[i].targetType
+                });
+            }
+            if (root.combineArray !== null) {
+                for (var i = 0; i < root.combineArray.length; i++) {
+                    var combinedAction = root.combineArray[i];
+                    action.combine.push(this.createJSON(combinedAction));
+                }
+                root = root.children[0];
+            }
+            for (var i = 0; i < root.children.length; i++) {
+                action.children.push(this.createJSON(root.children[i]));
+            }
+            return action;
+        };
+        Utils.prototype.setElementVisible = function (element, visible) {
+            element.style.display = visible ? "block" : "none";
+        };
+        return Utils;
+    })();
+    ActionsBuilder.Utils = Utils;
+})(ActionsBuilder || (ActionsBuilder = {}));

File diff suppressed because it is too large
+ 526 - 526
Exporters/3ds Max/ActionsBuilder/actionsbuilder.utils.ts


+ 539 - 0
Exporters/3ds Max/ActionsBuilder/actionsbuilder.viewer.js

@@ -0,0 +1,539 @@
+var ActionsBuilder;
+(function (ActionsBuilder) {
+    var Viewer = (function () {
+        function Viewer(type) {
+            var _this = this;
+            this.objectName = "Unnamed Object";
+            this.zoom = 1.0;
+            this._firstUpdate = true;
+            this.viewerContainer = document.getElementById("GraphContainerID");
+            this.viewerElement = document.getElementById("GraphElementID");
+            this.paper = Raphael("GraphElementID", screen.width, screen.height);
+            this.root = this.addAction(null, type, { name: this.objectName, text: this.objectName, properties: [], description: "" });
+            this.selectedNode = null;
+            window.addEventListener("resize", function (event) {
+                _this.onResize(event);
+            });
+            window.addEventListener("mousemove", function (event) {
+                _this.onMove(event);
+            });
+            this.paper.canvas.addEventListener("click", function (event) {
+                _this.onClick(event);
+            });
+            this._toolbar = new ActionsBuilder.Toolbar(this);
+            this._contextMenu = new ActionsBuilder.ContextMenu(this);
+            this.parameters = new ActionsBuilder.Parameters(this);
+            this.utils = new ActionsBuilder.Utils(this);
+            this.parameters.parametersHelpElement.textContent = Viewer._DEFAULT_INFO_MESSAGE;
+            this.onResize(null);
+        }
+        Object.defineProperty(Viewer, "NODE_WIDTH", {
+            get: function () {
+                return Viewer._NODE_WIDTH;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(Viewer, "NODE_HEIGHT", {
+            get: function () {
+                return Viewer._NODE_HEIGHT;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(Viewer, "NODE_MINIMIZED_WIDTH", {
+            get: function () {
+                return Viewer._NODE_MINIMIZE_WIDTH;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(Viewer, "VERTICAL_OFFSET", {
+            get: function () {
+                return Viewer._VERTICAL_OFFSET;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Viewer.prototype.onResize = function (event) {
+            var tools = document.getElementById("ToolsButtonsID");
+            this.viewerContainer.style.height = window.innerHeight - tools.getBoundingClientRect().height - 25 - 50 + "px";
+            this.viewerElement.style.height = window.innerHeight - tools.getBoundingClientRect().height - 25 - 50 + "px";
+            this.parameters.onResize();
+            this._toolbar.onResize();
+            if (this.paper.height < window.innerHeight) {
+                this.paper.setSize(this.paper.width, window.innerHeight);
+            }
+            if (this._firstUpdate) {
+                this.viewerElement.scrollLeft = ((this.viewerElement.scrollWidth / 2) - (this.viewerElement.getBoundingClientRect().width / 2));
+                this._firstUpdate = false;
+            }
+        };
+        Viewer.prototype.onMove = function (event) {
+            this.mousex = event.clientX - this.paper.canvas.getBoundingClientRect().left;
+            this.mousey = event.clientY - this.paper.canvas.getBoundingClientRect().top;
+        };
+        Viewer.prototype.onClick = function (event) {
+            if (this._contextMenu.showing) {
+                return;
+            }
+            if (this.selectedNode !== null) {
+                var node = this.selectedNode.node;
+                node.rect.attr("fill", this.getNodeColor(this.selectedNode.type, node.detached));
+            }
+            var result = this.traverseGraph(null, this.mousex, this.mousey, true);
+            if (result.hit) {
+                this.selectedNode = result.action;
+                var node = this.selectedNode.node;
+                node.rect.attr("fill", this.getSelectedNodeColor(this.selectedNode.type, node.detached));
+            }
+            else {
+                this.selectedNode = null;
+                this.parameters.clearParameters();
+                this.parameters.parametersHelpElement.textContent = Viewer._DEFAULT_INFO_MESSAGE;
+            }
+        };
+        Viewer.prototype.setColorTheme = function (color) {
+            this.paper.canvas.style.background = color;
+        };
+        Viewer.prototype.getNodeColor = function (type, detached) {
+            if (detached) {
+                return Raphael.rgb(96, 122, 14);
+            }
+            switch (type) {
+                case ActionsBuilder.Type.TRIGGER:
+                    return Raphael.rgb(133, 154, 185);
+                    break;
+                case ActionsBuilder.Type.ACTION:
+                    return Raphael.rgb(182, 185, 132);
+                    break;
+                case ActionsBuilder.Type.FLOW_CONTROL:
+                    return Raphael.rgb(185, 132, 140);
+                    break;
+                case ActionsBuilder.Type.OBJECT:
+                case ActionsBuilder.Type.SCENE:
+                    return Raphael.rgb(255, 255, 255);
+                    break;
+                default: break;
+            }
+            return null;
+        };
+        Viewer.prototype.getSelectedNodeColor = function (type, detached) {
+            if (detached) {
+                return Raphael.rgb(96, 122, 14);
+            }
+            switch (type) {
+                case ActionsBuilder.Type.TRIGGER:
+                    return Raphael.rgb(41, 129, 255);
+                    break;
+                case ActionsBuilder.Type.ACTION:
+                    return Raphael.rgb(255, 220, 42);
+                    break;
+                case ActionsBuilder.Type.FLOW_CONTROL:
+                    return Raphael.rgb(255, 41, 53);
+                    break;
+                case ActionsBuilder.Type.OBJECT:
+                case ActionsBuilder.Type.SCENE:
+                    return Raphael.rgb(255, 255, 255);
+                    break;
+                default: break;
+            }
+            return null;
+        };
+        Viewer.prototype.removeAction = function (action, removeChildren) {
+            if (action.parent !== null && action.parent.hub === action) {
+                this.removeAction(action.parent, false);
+                return;
+            }
+            this.removeNode(action.node);
+            if (action.combineArray !== null) {
+                this.removeNode(action.hub.node);
+                for (var i = 0; i < action.combineArray.length; i++) {
+                    this.removeNode(action.combineArray[i].node);
+                }
+                action.combineArray.length = 0;
+            }
+            if (removeChildren) {
+                for (var i = 0; i < action.children.length; i++) {
+                    this.removeAction(action.children[i], removeChildren);
+                }
+                action.clearChildren();
+            }
+            else {
+                for (var i = 0; i < action.children.length; i++) {
+                    action.parent.addChild(action.children[i]);
+                    action.children[i].parent = action.parent;
+                }
+            }
+        };
+        Viewer.prototype.removeNode = function (node) {
+            node.rect.remove();
+            node.text.remove();
+            if (node.line !== null) {
+                node.line.remove();
+            }
+        };
+        Viewer.prototype.update = function () {
+            var _this = this;
+            this._setActionPosition(this.root, (this.paper.width / 2) - (Viewer.NODE_WIDTH / 2) * this.zoom, 10);
+            var onSetNodeSize = function (node) {
+                node.rect.attr("width", node.minimized ? Viewer.NODE_MINIMIZED_WIDTH : Viewer.NODE_WIDTH * _this.zoom);
+                node.rect.attr("height", Viewer.NODE_HEIGHT * _this.zoom);
+                node.text.attr("font-size", 11 * _this.zoom);
+            };
+            var onSetPositionPass = function (action, yPosition) {
+                var node = action.node;
+                var parent = action.parent !== null ? action.parent : null;
+                if (action.combineArray !== null) {
+                    for (var i = 0; i < action.combineArray.length; i++) {
+                        var combinedNode = action.combineArray[i].node;
+                        onSetNodeSize(combinedNode);
+                    }
+                }
+                onSetNodeSize(node);
+                if (parent) {
+                    var parentx = parent.node.rect.attr("x");
+                    if (parent.combineArray !== null && parent.combineArray.length > 1) {
+                        parentx += parent.node.rect.attr("width") / 2;
+                    }
+                    _this._setActionPosition(action, parentx, yPosition);
+                    _this._setActionLine(action);
+                }
+                var totalSize = 0;
+                for (var i = 0; i < action.children.length; i++) {
+                    var childNode = action.children[i].node;
+                    totalSize += childNode.rect.attr("width");
+                }
+                var nodeWidth = node.rect.attr("width");
+                var startingPositionX = node.rect.attr("x");
+                for (var i = 0; i < action.children.length; i++) {
+                    var childAction = action.children[i];
+                    var childNode = childAction.node;
+                    var newPositionX = startingPositionX;
+                    if (childAction.combineArray !== null && childAction.combineArray.length > 1) {
+                        newPositionX -= (childNode.rect.attr("width") / 2) - nodeWidth / 2;
+                    }
+                    var newPositionY = yPosition + Viewer.VERTICAL_OFFSET * _this.zoom;
+                    onSetPositionPass(childAction, newPositionY);
+                    _this._setActionPosition(childAction, newPositionX, newPositionY);
+                    _this._setActionLine(childAction);
+                }
+            };
+            onSetPositionPass(this.root, 10 * this.zoom);
+            var onGetSizePass = function (action, maxSize) {
+                var mySize = 0;
+                if (action.combineArray !== null) {
+                    for (var i = 0; i < action.combineArray.length; i++) {
+                        mySize += action.combineArray[i].node.rect.attr("width");
+                    }
+                }
+                else {
+                    mySize = action.node.rect.attr("width");
+                }
+                if (mySize > maxSize) {
+                    maxSize = mySize;
+                }
+                for (var i = 0; i < action.children.length; i++) {
+                    maxSize = onGetSizePass(action.children[i], maxSize);
+                }
+                return maxSize;
+            };
+            var onResizeCanvas = function (action) {
+                var node = action.node;
+                var nodex = node.rect.attr("x");
+                var nodey = node.rect.attr("y");
+                if (nodex < 0 || nodex > _this.paper.width) {
+                    _this.paper.setSize(_this.paper.width + 1000, _this.paper.height);
+                    _this._setActionPosition(_this.root, (_this.paper.width / 2) - (Viewer.NODE_WIDTH / 2) * _this.zoom, 10);
+                }
+                if (nodey > _this.paper.height) {
+                    _this.paper.setSize(_this.paper.width, _this.paper.height + 1000);
+                    _this._setActionPosition(_this.root, (_this.paper.width / 2) - (Viewer.NODE_WIDTH / 2) * _this.zoom, 10);
+                }
+            };
+            var widths = new Array();
+            for (var i = 0; i < this.root.children.length; i++) {
+                var trigger = this.root.children[i];
+                var triggerResult = { triggerWidth: onGetSizePass(trigger, 0), childrenWidths: new Array() };
+                if (trigger.children.length > 0) {
+                    triggerResult.triggerWidth = 0;
+                }
+                for (var j = 0; j < trigger.children.length; j++) {
+                    var actionWidth = onGetSizePass(trigger.children[j], 0);
+                    triggerResult.triggerWidth += actionWidth + 15;
+                    triggerResult.childrenWidths.push({
+                        triggerWidth: actionWidth,
+                        childrenWidths: null
+                    });
+                }
+                widths.push(triggerResult);
+            }
+            var onSetNodePosition = function (action, widthArray, isChild) {
+                var actionsCount = action.children.length;
+                var actionsMiddle = actionsCount % 2;
+                var actionsHasMiddle = actionsMiddle !== 0;
+                var actionsLeftOffset = 0;
+                var actionsRightOffset = 0;
+                var actionWidth = action.node.rect.attr("width");
+                if (actionsHasMiddle && actionsCount > 1) {
+                    var middle = Math.floor(actionsCount / 2);
+                    actionsLeftOffset += widthArray[middle].triggerWidth / 2;
+                    actionsRightOffset += widthArray[middle].triggerWidth / 2;
+                }
+                var leftStart = actionsHasMiddle ? Math.floor(actionsCount / 2) - 1 : (actionsCount / 2) - 1;
+                for (var i = leftStart; i >= 0; i--) {
+                    var child = action.children[i];
+                    var node = child.node;
+                    var width = (widthArray[i].triggerWidth) + 15;
+                    _this._setActionPosition(action.children[i], node.rect.attr("x") - actionsLeftOffset - (width / 2), node.rect.attr("y"));
+                    _this._setActionLine(child);
+                    onResizeCanvas(child);
+                    actionsLeftOffset += width;
+                }
+                var rightStart = actionsHasMiddle ? Math.round(actionsCount / 2) : actionsCount / 2;
+                for (var i = rightStart; i < actionsCount; i++) {
+                    var child = action.children[i];
+                    var node = child.node;
+                    var width = (widthArray[i].triggerWidth) + 15;
+                    _this._setActionPosition(action.children[i], node.rect.attr("x") + actionsRightOffset + (width / 2), node.rect.attr("y"));
+                    _this._setActionLine(child);
+                    onResizeCanvas(child);
+                    actionsRightOffset += width;
+                }
+            };
+            onSetNodePosition(this.root, widths, false);
+            for (var i = 0; i < this.root.children.length; i++) {
+                onSetNodePosition(this.root.children[i], widths[i].childrenWidths, true);
+            }
+        };
+        Viewer.prototype.addAction = function (parent, type, element) {
+            var node = this._createNode(element.text, type, parent === null);
+            var action = new ActionsBuilder.Action(node);
+            if (element.name === "CombineAction") {
+                action.combineArray = new Array();
+                var hubElement = ActionsBuilder.Elements.FLOW_CONTROLS[ActionsBuilder.Elements.FLOW_CONTROLS.length - 1];
+                var hub = this.addAction(action, ActionsBuilder.Type.FLOW_CONTROL, hubElement);
+                action.hub = hub;
+                action.addChild(hub);
+                this._createActionAnimation(hub);
+            }
+            action.name = element.name;
+            action.properties = element.properties;
+            action.type = type;
+            for (var i = 0; i < action.properties.length; i++) {
+                action.propertiesResults.push({ targetType: action.properties[i].targetType, value: action.properties[i].value });
+            }
+            if (action.properties !== null && action.properties.length > 0) {
+                if (action.properties[0].text === "target") {
+                    action.propertiesResults[0].value = this.objectName;
+                }
+            }
+            if (parent !== null) {
+                if (parent.combineArray === null) {
+                    parent.addChild(action);
+                }
+                else if (parent.combineArray !== null && action.name !== "Hub") {
+                    parent.combineArray.push(action);
+                    action.parent = parent;
+                    action.combineAction = parent;
+                    parent.node.text.attr("text", "");
+                }
+            }
+            this._createActionAnimation(action);
+            return action;
+        };
+        Viewer.prototype.traverseGraph = function (start, x, y, traverseCombine) {
+            if (start === null)
+                start = this.root;
+            var result = { action: start, hit: true };
+            if (start.node.isPointInside(x, y)) {
+                return result;
+            }
+            for (var i = 0; i < start.children.length; i++) {
+                var action = start.children[i];
+                if (action.node.isPointInside(x, y)) {
+                    result.hit = true;
+                    result.action = start.children[i];
+                    if (traverseCombine && action.combineArray !== null) {
+                        for (var j = 0; j < action.combineArray.length; j++) {
+                            if (action.combineArray[j].node.isPointInside(x, y)) {
+                                result.action = action.combineArray[j];
+                                break;
+                            }
+                        }
+                    }
+                    return result;
+                }
+                result = this.traverseGraph(action, x, y, traverseCombine);
+                if (result.hit) {
+                    return result;
+                }
+            }
+            result.hit = false;
+            result.action = null;
+            return result;
+        };
+        Viewer.prototype._setActionPosition = function (action, x, y) {
+            var node = action.node;
+            var offsetx = node.rect.attr("x") - x;
+            var parent = action.parent;
+            if (parent !== null && parent.combineArray !== null && parent.combineArray.length > 1) {
+                var parentNode = parent.node;
+                x = parentNode.rect.attr("x") + (parent.node.rect.attr("width") / 2) - (node.rect.attr("width") / 2);
+            }
+            node.rect.attr("x", x);
+            node.rect.attr("y", y);
+            var textBBox = node.text.getBBox();
+            var textWidth = 0;
+            if (textBBox !== null && textBBox !== undefined) {
+                textWidth = textBBox.width;
+            }
+            node.text.attr("x", x + node.rect.attr("width") / 2 - textWidth / 2);
+            node.text.attr("y", y + node.rect.attr("height") / 2);
+            if (action.combineArray !== null && action.combineArray.length > 0) {
+                var length = 0;
+                for (var i = 0; i < action.combineArray.length; i++) {
+                    var combinedAction = action.combineArray[i];
+                    var combinedNode = combinedAction.node;
+                    combinedNode.rect.attr("x", node.rect.attr("x") + length);
+                    combinedNode.rect.attr("y", node.rect.attr("y"));
+                    textBBox = combinedNode.text.getBBox();
+                    if (textBBox !== null) {
+                        textWidth = textBBox.width;
+                    }
+                    combinedNode.text.attr("x", combinedNode.rect.attr("x") + combinedNode.rect.attr("width") / 2 - textWidth / 2);
+                    combinedNode.text.attr("y", y + combinedNode.rect.attr("height") / 2);
+                    length += combinedNode.rect.attr("width");
+                }
+                node.rect.attr("width", length);
+            }
+            for (var i = 0; i < action.children.length; i++) {
+                var child = action.children[i];
+                this._setActionPosition(child, child.node.rect.attr("x") - offsetx, y + Viewer.VERTICAL_OFFSET * this.zoom);
+                this._setActionLine(child);
+            }
+        };
+        Viewer.prototype._setActionLine = function (action) {
+            if (action.node.line === null) {
+                return;
+            }
+            var node = action.node;
+            var nodex = node.rect.attr("x");
+            var nodey = node.rect.attr("y");
+            var nodeWidth = node.rect.attr("width");
+            var nodeHeight = node.rect.attr("height");
+            var parent = action.parent.node;
+            var parentx = parent.rect.attr("x");
+            var parenty = parent.rect.attr("y");
+            var parentWidth = parent.rect.attr("width");
+            var parentHeight = parent.rect.attr("height");
+            if (node.detached) {
+                node.line.attr("path", ["M", nodex, nodey, "L", nodex, nodey]);
+                return;
+            }
+            var line1x = nodex + (nodeWidth / 2);
+            var line1y = nodey;
+            var line2y = line1y - (line1y - parenty - parentHeight) / 2;
+            var line3x = parentx + (parentWidth / 2);
+            var line4y = parenty + parentHeight;
+            node.line.attr("path", ["M", line1x, line1y, "L", line1x, line2y, "L", line3x, line2y, "L", line3x, line4y]);
+        };
+        Viewer.prototype._createNode = function (text, type, noLine) {
+            var node = new ActionsBuilder.Node();
+            var color = this.getNodeColor(type, false);
+            node.rect = this.paper.rect(20, 20, Viewer.NODE_WIDTH, Viewer.NODE_HEIGHT, 0);
+            node.rect.attr("fill", color);
+            node.text = this.paper.text(20, 20, text);
+            node.text.attr("font-size", 11);
+            node.text.attr("text-anchor", "start");
+            node.text.attr("font-family", "Sinkin Sans Light");
+            if (!noLine) {
+                node.line = this.paper.path("");
+                node.line.attr("stroke", color);
+            }
+            return node;
+        };
+        Viewer.prototype._createActionAnimation = function (action) {
+            var _this = this;
+            var node = action.node;
+            var finished = true;
+            var nodex = 0;
+            var nodey = 0;
+            var onMove = function (dx, dy, x, y) { };
+            var onStart = function (x, y, event) {
+                if (node.minimized) {
+                    return;
+                }
+                if (finished) {
+                    nodex = node.rect.attr("x");
+                    nodey = node.rect.attr("y");
+                }
+                finished = false;
+                node.rect.animate({
+                    x: node.rect.attr("x") - 10,
+                    y: node.rect.attr("y"),
+                    width: (Viewer.NODE_WIDTH + 20) * _this.zoom,
+                    height: (Viewer.NODE_HEIGHT + 10) * _this.zoom,
+                    opacity: 0.25
+                }, 500, ">");
+            };
+            var onEnd = function (event) {
+                if (!node.minimized) {
+                    node.rect.animate({
+                        x: nodex,
+                        y: nodey,
+                        width: Viewer.NODE_WIDTH * _this.zoom,
+                        height: Viewer.NODE_HEIGHT * _this.zoom,
+                        opacity: 1.0
+                    }, 500, ">", function () { finished = true; });
+                }
+                var dragResult = _this.traverseGraph(null, _this.mousex, _this.mousey, true);
+                if (dragResult.hit && dragResult.action === action || !dragResult.hit) {
+                    _this.parameters.createParameters(action);
+                }
+                else {
+                    if (dragResult.action.children.length > 0 && action.type !== ActionsBuilder.Type.TRIGGER) {
+                        return;
+                    }
+                    if (action.type === ActionsBuilder.Type.TRIGGER && dragResult.action !== _this.root) {
+                        return;
+                    }
+                    if (action.type === ActionsBuilder.Type.ACTION && dragResult.action === _this.root) {
+                        return;
+                    }
+                    if (action.type === ActionsBuilder.Type.FLOW_CONTROL && (dragResult.action === _this.root || dragResult.action.type === ActionsBuilder.Type.FLOW_CONTROL)) {
+                        return;
+                    }
+                    if (action === dragResult.action.parent) {
+                        return;
+                    }
+                    if (action.parent !== null && action.parent.combineArray !== null) {
+                        return;
+                    }
+                    node.rect.stop(node.rect.animation);
+                    node.text.stop(node.text.animation);
+                    node.rect.undrag();
+                    node.text.undrag();
+                    node.rect.attr("opacity", 1.0);
+                    node.rect.attr("width", Viewer.NODE_WIDTH);
+                    node.rect.attr("height", Viewer.NODE_HEIGHT);
+                    if (action.parent !== null) {
+                        action.parent.removeChild(action);
+                        dragResult.action.addChild(action);
+                        _this.update();
+                        _this._createActionAnimation(action);
+                    }
+                }
+            };
+            node.rect.drag(onMove, onStart, onEnd);
+            node.text.drag(onMove, onStart, onEnd);
+        };
+        Viewer._NODE_WIDTH = 150;
+        Viewer._NODE_HEIGHT = 25;
+        Viewer._NODE_MINIMIZE_WIDTH = 50;
+        Viewer._VERTICAL_OFFSET = 70;
+        Viewer._DEFAULT_INFO_MESSAGE = "Select or add a node to customize actions";
+        return Viewer;
+    })();
+    ActionsBuilder.Viewer = Viewer;
+})(ActionsBuilder || (ActionsBuilder = {}));

File diff suppressed because it is too large
+ 772 - 772
Exporters/3ds Max/ActionsBuilder/actionsbuilder.viewer.ts


+ 42 - 42
Exporters/3ds Max/ActionsBuilder/gulpfile.js

@@ -1,42 +1,42 @@
-var gulp = require('gulp');
-var ts = require('gulp-typescript');
-
-var files = [
-    // Files
-    // Equivalent to "./*.ts",
-    "actionsbuilder.actionNode.ts",
-    "actionsbuilder.contextMenu.ts",
-	"actionsbuilder.list.ts",
-    "actionsbuilder.main.ts",
-    "actionsbuilder.parameters.ts",
-    "actionsbuilder.toolbar.ts",
-    "actionsbuilder.ts",
-    "actionsbuilder.utils.ts",
-    "actionsbuilder.viewer.ts",
-    // References
-    "raphaeljs.d.ts",
-    "../../dist/*.d.ts",
-    "../..external references/**/*.d.ts"
-];
-
-gulp.task("default", function () {
-    var result = gulp.src(files)
-		.pipe(ts({
-            target: "ES5",
-		    out: "actionsbuilder.max.js" // Merge
-		}));
-    return result.js.pipe(gulp.dest("./Sources/"));
-});
-
-gulp.task("debug", function () {
-    var result = gulp.src(files)
-		.pipe(ts({
-		    target: "ES5",
-            outDir: "./Sources/"
-		}));
-    return result.js.pipe(gulp.dest("./Sources/"));
-});
-
-gulp.task("watch", function () {
-    gulp.watch(files, ["default"]);
-});
+/// <binding />
+var gulp = require('gulp');
+var ts = require('gulp-typescript');
+
+var files = [
+    // Files
+    // Equivalent to "./*.ts",
+    "actionsbuilder.actionNode.ts",
+    "actionsbuilder.contextMenu.ts",
+	"actionsbuilder.list.ts",
+    "actionsbuilder.main.ts",
+    "actionsbuilder.parameters.ts",
+    "actionsbuilder.toolbar.ts",
+    "actionsbuilder.ts",
+    "actionsbuilder.utils.ts",
+    "actionsbuilder.viewer.ts",
+    // References
+    "raphaeljs.d.ts",
+    "../../../dist/preview release/babylon.d.ts"
+];
+
+gulp.task("default", function () {
+    var result = gulp.src(files)
+		.pipe(ts({
+            target: "ES5",
+		    out: "actionsbuilder.max.js" // Merge
+		}));
+    return result.js.pipe(gulp.dest("./Sources/"));
+});
+
+gulp.task("debug", function () {
+    var result = gulp.src(files)
+		.pipe(ts({
+		    target: "ES5",
+            outDir: "./Sources/"
+		}));
+    return result.js.pipe(gulp.dest("./Sources/"));
+});
+
+gulp.task("watch", function () {
+    gulp.watch(files, ["default"]);
+});

+ 10 - 11
Exporters/3ds Max/ActionsBuilder/package.json

@@ -1,11 +1,10 @@
-{
-  "name": "BabylonJSActionsBuilder",
-  "version": "2.2.0",
-  "description": "",
-  "main": "",
-  "devDependencies": {
-    "gulp": "^3.8.11",
-    "typescript": "~1.5.3",
-    "gulp-typescript": "~2.8.0"
-  }
-}
+{
+  "name": "BabylonJSActionsBuilder",
+  "version": "2.2.0",
+  "description": "",
+  "main": "",
+  "devDependencies": {
+    "gulp": "^3.8.11",
+    "gulp-typescript": "^3.1.4"
+  }
+}

+ 69 - 69
Exporters/3ds Max/ActionsBuilder/raphaeljs.d.ts

@@ -1,69 +1,69 @@
-/*
-Raphael.js declarations
-*/
-
-// Raphael.js bounding box interface
-interface RaphaelBoundingBox {
-    width: number;
-    height: number;
-}
-
-// Raphael.js animation interface
-interface RaphaelAnimation
-{ }
-
-// Raphael.js element interface
-interface RaphaelElement {
-    attr(attribute: string, value?: any): any;
-
-    remove(): void;
-
-    hide(): void;
-    show(): void;
-
-    isPointInside(x: number, y: number): boolean;
-    getBBox(): RaphaelBoundingBox;
-
-    animate(attributes: any, time: number, type: string, callback?: () => void): void;
-    stop(animation: RaphaelAnimation);
-    animation: RaphaelAnimation;
-
-    click(onClick: (event: MouseEvent) => void);
-    drag(onMove: (dx: number, dy: number, x: number, y: number) => void, onStart: (x: number, y: number, event: MouseEvent) => void, onEnd: (event: MouseEvent) => void): void;
-    undrag(): void;
-}
-
-// Raphael.js rect interface
-interface Rect extends RaphaelElement
-{ }
-
-// Raphael.js text interface
-interface Text extends RaphaelElement
-{ }
-
-// Raphael.js path interface
-interface Path extends RaphaelElement
-{ }
-
-// Raphael.js rgb interface
-interface RaphaelColor
-{ }
-
-// Raphael.js paper interface
-interface Paper {
-    canvas: HTMLCanvasElement;
-
-    width: number;
-    height: number;
-    setSize(width: number, height: number);
-
-    rect(x: number, y: number, width: number, height: number, r?: number): Rect;
-    text(x: number, y: number, text: string): Text;
-    path(pathString: string);
-}
-
-// Raphael.js
-declare var Raphael: {
-    (containerID: string, width: number, height: number): Paper;
-    rgb(r: number, g: number, b: number): RaphaelColor;
-}
+/*
+Raphael.js declarations
+*/
+
+// Raphael.js bounding box interface
+interface RaphaelBoundingBox {
+    width: number;
+    height: number;
+}
+
+// Raphael.js animation interface
+interface RaphaelAnimation
+{ }
+
+// Raphael.js element interface
+interface RaphaelElement {
+    attr(attribute: string, value?: any): any;
+
+    remove(): void;
+
+    hide(): void;
+    show(): void;
+
+    isPointInside(x: number, y: number): boolean;
+    getBBox(): RaphaelBoundingBox;
+
+    animate(attributes: any, time: number, type: string, callback?: () => void): void;
+    stop(animation: RaphaelAnimation);
+    animation: RaphaelAnimation;
+
+    click(onClick: (event: MouseEvent) => void);
+    drag(onMove: (dx: number, dy: number, x: number, y: number) => void, onStart: (x: number, y: number, event: MouseEvent) => void, onEnd: (event: MouseEvent) => void): void;
+    undrag(): void;
+}
+
+// Raphael.js rect interface
+interface Rect extends RaphaelElement
+{ }
+
+// Raphael.js text interface
+interface Text extends RaphaelElement
+{ }
+
+// Raphael.js path interface
+interface Path extends RaphaelElement
+{ }
+
+// Raphael.js rgb interface
+interface RaphaelColor
+{ }
+
+// Raphael.js paper interface
+interface Paper {
+    canvas: HTMLCanvasElement;
+
+    width: number;
+    height: number;
+    setSize(width: number, height: number);
+
+    rect(x: number, y: number, width: number, height: number, r?: number): Rect;
+    text(x: number, y: number, text: string): Text;
+    path(pathString: string);
+}
+
+// Raphael.js
+declare var Raphael: {
+    (containerID: string, width: number, height: number): Paper;
+    rgb(r: number, g: number, b: number): RaphaelColor;
+}

+ 31 - 0
Exporters/3ds Max/ActionsBuilder/web.Debug.config

@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Pour plus d'informations sur l'utilisation de la transformation web.config, consultez la page http://go.microsoft.com/fwlink/?LinkId=125889 -->
+
+<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
+  <!--
+    Dans l'exemple ci-dessous, la transformation "SetAttributes" changera la valeur de 
+    "connectionString" afin d'utiliser "ReleaseSQLServer" uniquement lorsque le localisateur "Match" 
+    trouve un attribut "name" qui a une valeur "MyDB".
+    
+    <connectionStrings>
+      <add name="MyDB" 
+        connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True" 
+        xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
+    </connectionStrings>
+  -->
+  <system.web>
+    <!--
+      
+      Dans l'exemple ci-dessous, la transformation "Replace" remplacera toute la section 
+      <customErrors>  de votre fichier web.config.
+      Dans la mesure où il n'y a qu'une section customErrors sous le 
+      nœud <system.web>, il n'est pas nécessaire d'utiliser l'attribut "xdt:Locator".
+      
+      <customErrors defaultRedirect="GenericError.htm"
+        mode="RemoteOnly" xdt:Transform="Replace">
+        <error statusCode="500" redirect="InternalError.htm"/>
+      </customErrors>
+    -->
+  </system.web>
+</configuration>

+ 32 - 0
Exporters/3ds Max/ActionsBuilder/web.Release.config

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Pour plus d'informations sur l'utilisation de la transformation web.config, consultez la page http://go.microsoft.com/fwlink/?LinkId=125889 -->
+
+<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
+  <!--
+    Dans l'exemple ci-dessous, la transformation "SetAttributes" changera la valeur de 
+    "connectionString" afin d'utiliser "ReleaseSQLServer" uniquement lorsque le localisateur "Match" 
+    trouve un attribut "name" qui a une valeur "MyDB".
+    
+    <connectionStrings>
+      <add name="MyDB" 
+        connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True" 
+        xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
+    </connectionStrings>
+  -->
+  <system.web>
+    <compilation xdt:Transform="RemoveAttributes(debug)" />
+    <!--
+      
+      Dans l'exemple ci-dessous, la transformation "Replace" remplacera toute la section 
+      <customErrors>  de votre fichier web.config.
+      Dans la mesure où il n'y a qu'une section customErrors sous le 
+      nœud <system.web>, il n'est pas nécessaire d'utiliser l'attribut "xdt:Locator".
+      
+      <customErrors defaultRedirect="GenericError.htm"
+        mode="RemoteOnly" xdt:Transform="Replace">
+        <error statusCode="500" redirect="InternalError.htm"/>
+      </customErrors>
+    -->
+  </system.web>
+</configuration>

+ 11 - 0
Exporters/3ds Max/ActionsBuilder/web.config

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Pour plus d'informations sur la configuration de votre application ASP.NET, visitez
+  http://go.microsoft.com/fwlink/?LinkId=169433
+  -->
+<configuration>
+  <system.web>
+    <compilation debug="true" targetFramework="4.5" />
+    <httpRuntime targetFramework="4.5" />
+  </system.web>
+</configuration>

+ 3 - 0
Exporters/3ds Max/BabylonExport.Entities/BabylonAbstractMesh.cs

@@ -38,6 +38,9 @@ namespace BabylonExport.Entities
         [DataMember]
         public bool autoAnimateLoop { get; set; }
 
+        [DataMember]
+        public string parentId { get; set; }
+
         public BabylonAbstractMesh()
         {
             position = new[] { 0f, 0f, 0f };

+ 17 - 0
Exporters/3ds Max/BabylonExport.Entities/BabylonExport.Entities.csproj

@@ -17,6 +17,8 @@
     <SccProvider>SAK</SccProvider>
     <TargetFrameworkProfile>
     </TargetFrameworkProfile>
+    <NuGetPackageImportStamp>
+    </NuGetPackageImportStamp>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>
@@ -38,9 +40,14 @@
     <Prefer32Bit>false</Prefer32Bit>
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="SharpDX">
+      <HintPath>$(SharpDXPackageBinDir)\SharpDX.dll</HintPath>
+    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
+    <Reference Include="System.Drawing" />
     <Reference Include="System.Runtime.Serialization" />
+    <Reference Include="System.Windows.Forms" />
     <Reference Include="System.Xml.Linq" />
     <Reference Include="System.Data.DataSetExtensions" />
     <Reference Include="System.Data" />
@@ -74,7 +81,17 @@
     <Compile Include="BabylonVector3.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <Import Project="..\packages\SharpDX.2.6.3\build\SharpDX.targets" Condition="Exists('..\packages\SharpDX.2.6.3\build\SharpDX.targets')" />
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('..\packages\SharpDX.2.6.3\build\SharpDX.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\SharpDX.2.6.3\build\SharpDX.targets'))" />
+  </Target>
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.
   <Target Name="BeforeBuild">

+ 0 - 3
Exporters/3ds Max/BabylonExport.Entities/BabylonMesh.cs

@@ -9,9 +9,6 @@ namespace BabylonExport.Entities
         public string id { get; set; }
 
         [DataMember]
-        public string parentId { get; set; }
-
-        [DataMember]
         public string materialId { get; set; }
 
         [DataMember]

+ 3 - 3
Exporters/3ds Max/BabylonExport.Entities/packages.config

@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="SharpDX" version="2.6.3" targetFramework="net40" />
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="SharpDX" version="2.6.3" targetFramework="net35" />
 </packages>

+ 66 - 0
Exporters/3ds Max/BabylonFileConverter/BabylonFileConverter.csproj

@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{A6B76356-1D1C-4C82-8199-A6406DA85A95}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>BabylonFileConverter</RootNamespace>
+    <AssemblyName>BabylonFileConverter</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <SccProjectName>SAK</SccProjectName>
+    <SccLocalPath>SAK</SccLocalPath>
+    <SccAuxPath>SAK</SccAuxPath>
+    <SccProvider>SAK</SccProvider>
+    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
+    <RestorePackages>true</RestorePackages>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+      <HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="BinaryConverter.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>

+ 374 - 0
Exporters/3ds Max/BabylonFileConverter/BinaryConverter.cs

@@ -0,0 +1,374 @@
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BabylonFileConverter
+{
+    public static class BinaryConverter
+    {
+        public enum DataType { Int32, Float };
+
+        public static void Convert(string srcFilename, string dstPath, Action<string> onMessage, Action<string> onError)
+        {
+            try
+            {
+                if (!Directory.Exists(dstPath))
+                    Directory.CreateDirectory(dstPath);
+
+                string srcPath = Path.GetDirectoryName(srcFilename);
+                string dstFilename = Path.Combine(dstPath, Path.GetFileNameWithoutExtension(srcFilename) + ".binary.babylon");
+
+                dynamic scene;
+
+                // Loading
+                onMessage("Loading " + srcFilename);
+
+                using (var streamReader = new StreamReader(srcFilename))
+                {
+                    using (var reader = new JsonTextReader(streamReader))
+                    {
+                        scene = JObject.Load(reader);
+                    }
+                }
+
+                // Marking scene
+                string objName = scene.name;
+
+                if (string.IsNullOrEmpty(objName))
+                    objName = Path.GetFileNameWithoutExtension(srcFilename);
+
+                var atDot = objName.IndexOf(".incremental");
+                if (atDot > 0)
+                    objName = objName.Substring(0, atDot);
+
+                scene["autoClear"] = true;
+                scene["useDelayedTextureLoading"] = true;
+
+                var doNotDelayLoadingForGeometries = new List<string>();
+
+                // Parsing meshes
+                var meshes = (JArray)scene.meshes;
+                foreach (dynamic mesh in meshes)
+                {
+                    if (mesh.checkCollisions.Value) // Do not delay load collisions object
+                    {
+                        if (mesh.geometryId != null)
+                            doNotDelayLoadingForGeometries.Add(mesh.geometryId.Value);
+                        continue;
+                    }
+
+                    Extract(srcPath, dstPath, objName, mesh, true);
+                }
+
+
+                // Parsing vertexData
+                var geometries = scene.geometries;
+                if (geometries != null)
+                {
+                    var vertexData = (JArray)geometries.vertexData;
+                    foreach (dynamic geometry in vertexData)
+                    {
+                        var id = geometry.id.Value;
+
+                        if (doNotDelayLoadingForGeometries.Any(g => g == id))
+                            continue;
+
+                        Extract(srcPath, dstPath, objName, geometry, false);
+                    }
+                }
+
+                // Saving                
+                onMessage("Saving " + dstFilename);
+                string json = scene.ToString(Formatting.Indented);
+
+                using (var writer = new StreamWriter(WebUtility.UrlDecode(dstFilename)))
+                {
+                    writer.Write(json);
+                }
+            }
+            catch (Exception ex)
+            {
+                onError(ex.Message);
+            }
+        }
+
+
+        static void Extract(string srcPath, string dstPath, string objName, dynamic meshObj, bool isMesh)
+        {
+            string dstFilename = meshObj.delayLoadingFile;
+            string dstExt = (isMesh ? ".babylonbinarymeshdata" : ".babylonbinarygeometrydata");
+
+            if (!string.IsNullOrEmpty(dstFilename))
+            {
+                string filename = WebUtility.UrlDecode(Path.Combine(srcPath, (string)meshObj.delayLoadingFile));
+
+                using (var streamReader = new StreamReader(filename))
+                {
+                    using (var reader = new JsonTextReader(streamReader))
+                    {
+                        var meshData = JObject.Load(reader);
+                        meshObj.positions = meshData["positions"];
+                        meshObj.normals = meshData["normals"];
+                        meshObj.indices = meshData["indices"];
+                        meshObj.uvs = meshData["uvs"];
+                        meshObj.uvs2 = meshData["uvs2"];
+                        meshObj.colors = meshData["colors"];
+                        meshObj.matricesIndices = meshData["matricesIndices"];
+                        meshObj.matricesWeights = meshData["matricesWeights"];
+                        meshObj.subMeshes = meshData["subMeshes"];
+                    }
+                }
+            }
+
+            if (meshObj.positions == null || meshObj.positions.Count == 0 
+                || meshObj.normals == null || meshObj.normals.Count == 0
+                || meshObj.indices == null || meshObj.indices.Count == 0)
+                return;
+
+            ComputeBoundingBox(meshObj);
+
+            string meshName = meshObj.name.ToString();
+            meshName = meshName.Trim();
+            if (meshName.Length > 40)
+                meshName = meshName.Substring(0, 40);
+
+            if (isMesh && !string.IsNullOrEmpty(meshName))
+                dstFilename = objName + "." + meshName + "." + meshObj.id.ToString() + dstExt;
+            else
+                dstFilename = objName + meshObj.id.ToString() + dstExt;
+
+            dstFilename = dstFilename.Replace("+", "_").Replace(" ", "_").Replace("/", "_").Replace("\\", "_").Replace(":", "_");
+
+            meshObj.delayLoadingFile = WebUtility.UrlEncode(dstFilename);
+
+            var binaryInfo = new JObject();
+
+            using (var stream = File.Open(WebUtility.UrlDecode(Path.Combine(dstPath, dstFilename)), FileMode.Create))
+            {
+                var writer = new BinaryWriter(stream);
+
+                if (meshObj.positions != null && meshObj.positions.Count > 0)
+                {
+                    var attrData = new JObject();
+                    attrData["count"] = meshObj.positions.Count;
+                    attrData["stride"] = 3;
+                    attrData["offset"] = stream.Length;
+                    attrData["dataType"] = (int)DataType.Float;
+
+                    binaryInfo["positionsAttrDesc"] = attrData;
+
+                    for (int x = 0; x < meshObj.positions.Count; x++)
+                        writer.Write((float)meshObj.positions[x]);
+
+                    meshObj.positions = null;
+                }
+
+
+                if (meshObj.colors != null && meshObj.colors.Count > 0)
+                {
+                    var attrData = new JObject();
+                    attrData["count"] = meshObj.colors.Count;
+                    attrData["stride"] = 3;
+                    attrData["offset"] = stream.Length;
+                    attrData["dataType"] = (int)DataType.Float;
+
+                    binaryInfo["colorsAttrDesc"] = attrData;
+
+                    for (int x = 0; x < meshObj.colors.Count; x++)
+                        writer.Write((float)meshObj.colors[x]);
+
+                    meshObj["hasColors"] = true;
+                    meshObj.colors = null;
+                }
+
+
+                if (meshObj.normals != null && meshObj.normals.Count > 0)
+                {
+                    var attrData = new JObject();
+                    attrData["count"] = meshObj.normals.Count;
+                    attrData["stride"] = 3;
+                    attrData["offset"] = stream.Length;
+                    attrData["dataType"] = (int)DataType.Float;
+
+                    binaryInfo["normalsAttrDesc"] = attrData;
+
+                    for (int x = 0; x < meshObj.normals.Count; x++)
+                        writer.Write((float)meshObj.normals[x]);
+
+                    meshObj.normals = null;
+                }
+
+
+                if (meshObj.uvs != null && meshObj.uvs.Count > 0)
+                {
+                    var attrData = new JObject();
+                    attrData["count"] = meshObj.uvs.Count;
+                    attrData["stride"] = 2;
+                    attrData["offset"] = stream.Length;
+                    attrData["dataType"] = (int)DataType.Float;
+
+                    binaryInfo["uvsAttrDesc"] = attrData;
+
+                    for (int x = 0; x < meshObj.uvs.Count; x++)
+                        writer.Write((float)meshObj.uvs[x]);
+
+                    meshObj["hasUVs"] = true;
+                    meshObj.uvs = null;
+                }
+
+
+                if (meshObj.uvs2 != null && meshObj.uvs2.Count > 0)
+                {
+                    var attrData = new JObject();
+                    attrData["count"] = meshObj.uvs2.Count;
+                    attrData["stride"] = 2;
+                    attrData["offset"] = stream.Length;
+                    attrData["dataType"] = (int)DataType.Float;
+
+                    binaryInfo["uvs2AttrDesc"] = attrData;
+
+                    for (int x = 0; x < meshObj.uvs2.Count; x++)
+                        writer.Write((float)meshObj.uvs2[x]);
+
+                    meshObj["hasUVs2"] = true;
+                    meshObj.uvs2 = null;
+                }
+
+
+                if (meshObj.indices != null && meshObj.indices.Count > 0)
+                {
+                    var attrData = new JObject();
+                    attrData["count"] = meshObj.indices.Count;
+                    attrData["stride"] = 1;
+                    attrData["offset"] = stream.Length;
+                    attrData["dataType"] = (int)DataType.Int32;
+
+                    binaryInfo["indicesAttrDesc"] = attrData;
+
+                    for (int x = 0; x < meshObj.indices.Count; x++)
+                        writer.Write((int)meshObj.indices[x]);
+
+                    meshObj.indices = null;
+                }
+
+
+                if (meshObj.matricesIndices != null && meshObj.matricesIndices.Count > 0)
+                {
+                    var attrData = new JObject();
+                    attrData["count"] = meshObj.matricesIndices.Count;
+                    attrData["stride"] = 1;
+                    attrData["offset"] = stream.Length;
+                    attrData["dataType"] = (int)DataType.Int32;
+
+                    binaryInfo["matricesIndicesAttrDesc"] = attrData;
+
+                    for (int x = 0; x < meshObj.matricesIndices.Count; x++)
+                        writer.Write((int)meshObj.matricesIndices[x]);
+
+                    meshObj["hasMatricesIndices"] = true;
+                    meshObj.matricesIndices = null;
+                }
+
+
+                if (meshObj.matricesWeights != null && meshObj.matricesWeights.Count > 0)
+                {
+                    var attrData = new JObject();
+                    attrData["count"] = meshObj.matricesWeights.Count;
+                    attrData["stride"] = 2;
+                    attrData["offset"] = stream.Length;
+                    attrData["dataType"] = (int)DataType.Float;
+
+                    binaryInfo["matricesWeightsAttrDesc"] = attrData;
+
+                    for (int x = 0; x < meshObj.matricesWeights.Count; x++)
+                        writer.Write((float)meshObj.matricesWeights[x]);
+
+                    meshObj["hasMatricesWeights"] = true;
+                    meshObj.matricesWeights = null;
+                }
+
+
+                if (isMesh && meshObj.subMeshes != null && meshObj.subMeshes.Count > 0)
+                {
+                    var attrData = new JObject();
+                    attrData["count"] = meshObj.subMeshes.Count;
+                    attrData["stride"] = 5;
+                    attrData["offset"] = stream.Length;
+                    attrData["dataType"] = (int)DataType.Int32;
+
+                    binaryInfo["subMeshesAttrDesc"] = attrData;
+
+                    var smData = new int[5];
+
+                    for (int x = 0; x < meshObj.subMeshes.Count; x++)
+                    {
+                        smData[0] = meshObj.subMeshes[x].materialIndex;
+                        smData[1] = meshObj.subMeshes[x].verticesStart;
+                        smData[2] = meshObj.subMeshes[x].verticesCount;
+                        smData[3] = meshObj.subMeshes[x].indexStart;
+                        smData[4] = meshObj.subMeshes[x].indexCount;
+
+                        for (int y = 0; y < smData.Length; y++)
+                            writer.Write(smData[y]);
+                    }
+
+                    meshObj.subMeshes = null;
+                }
+            }
+
+            meshObj["_binaryInfo"] = binaryInfo;
+        }
+
+
+        static void ComputeBoundingBox(dynamic meshOrGeometry)
+        {
+            // Compute bounding boxes
+            var positions = ((JArray)meshOrGeometry.positions).Select(v => v.Value<float>()).ToArray();
+            var minimum = new[] { float.MaxValue, float.MaxValue, float.MaxValue };
+            var maximum = new[] { float.MinValue, float.MinValue, float.MinValue };
+
+            for (var index = 0; index < positions.Length; index += 3)
+            {
+                var x = positions[index];
+                var y = positions[index + 1];
+                var z = positions[index + 2];
+
+                if (x < minimum[0])
+                {
+                    minimum[0] = x;
+                }
+                if (x > maximum[0])
+                {
+                    maximum[0] = x;
+                }
+
+                if (y < minimum[1])
+                {
+                    minimum[1] = y;
+                }
+                if (y > maximum[1])
+                {
+                    maximum[1] = y;
+                }
+
+                if (z < minimum[2])
+                {
+                    minimum[2] = z;
+                }
+                if (z > maximum[2])
+                {
+                    maximum[2] = z;
+                }
+            }
+
+            meshOrGeometry["boundingBoxMinimum"] = new JArray(minimum);
+            meshOrGeometry["boundingBoxMaximum"] = new JArray(maximum);
+        }
+    }
+}

+ 36 - 0
Exporters/3ds Max/BabylonFileConverter/Properties/AssemblyInfo.cs

@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("BabylonFileConverter")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("BabylonFileConverter")]
+[assembly: AssemblyCopyright("Copyright ©  2015")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("f54d9455-96c3-4e01-bb67-9213d8975373")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 4 - 0
Exporters/3ds Max/BabylonFileConverter/packages.config

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
+</packages>

BIN
Exporters/3ds Max/Max2Babylon-0.5.0.zip


+ 223 - 34
Exporters/3ds Max/Max2Babylon.sln

@@ -1,34 +1,223 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2013
-VisualStudioVersion = 12.0.30501.0
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Max2Babylon", "Max2Babylon\Max2Babylon.csproj", "{DD7C931A-8FAF-4318-BB74-71DC858CC489}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BabylonExport.Entities", "BabylonExport.Entities\BabylonExport.Entities.csproj", "{6150965A-658C-4263-89AD-4F980EB0675D}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Max2Babylon2015", "Max2Babylon\2015\Max2Babylon2015.csproj", "{DD7C931A-8FAF-4318-BB74-71DC858CC400}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Any CPU = Debug|Any CPU
-		Release|Any CPU = Release|Any CPU
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{DD7C931A-8FAF-4318-BB74-71DC858CC489}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{DD7C931A-8FAF-4318-BB74-71DC858CC489}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{DD7C931A-8FAF-4318-BB74-71DC858CC489}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{DD7C931A-8FAF-4318-BB74-71DC858CC489}.Release|Any CPU.Build.0 = Release|Any CPU
-		{6150965A-658C-4263-89AD-4F980EB0675D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{6150965A-658C-4263-89AD-4F980EB0675D}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{6150965A-658C-4263-89AD-4F980EB0675D}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{6150965A-658C-4263-89AD-4F980EB0675D}.Release|Any CPU.Build.0 = Release|Any CPU
-		{DD7C931A-8FAF-4318-BB74-71DC858CC400}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{DD7C931A-8FAF-4318-BB74-71DC858CC400}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{DD7C931A-8FAF-4318-BB74-71DC858CC400}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{DD7C931A-8FAF-4318-BB74-71DC858CC400}.Release|Any CPU.Build.0 = Release|Any CPU
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-EndGlobal
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3ds Max", "3ds Max", "{2139CC27-1C89-49C8-95AC-7715ACBADC1F}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BabylonExport.Entities", "BabylonExport.Entities\BabylonExport.Entities.csproj", "{6150965A-658C-4263-89AD-4F980EB0675D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Max2Babylon", "Max2Babylon\Max2Babylon.csproj", "{DD7C931A-8FAF-4318-BB74-71DC858CC489}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Max2Babylon2015", "Max2Babylon\2015\Max2Babylon2015.csproj", "{DD7C931A-8FAF-4318-BB74-71DC858CC400}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BabylonFileConverter", "BabylonFileConverter\BabylonFileConverter.csproj", "{A6B76356-1D1C-4C82-8199-A6406DA85A95}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ActionsBuilder", "ActionsBuilder\ActionsBuilder.csproj", "{293A754C-3D80-42FB-99D8-7C9386CD297E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Max2Babylon2017", "Max2Babylon\2017\Max2Babylon2017.csproj", "{2F49C726-A1F8-40D4-859F-1355949608DC}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Debug|ARM = Debug|ARM
+		Debug|Mixed Platforms = Debug|Mixed Platforms
+		Debug|Win32 = Debug|Win32
+		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
+		Profile|Any CPU = Profile|Any CPU
+		Profile|ARM = Profile|ARM
+		Profile|Mixed Platforms = Profile|Mixed Platforms
+		Profile|Win32 = Profile|Win32
+		Profile|x64 = Profile|x64
+		Profile|x86 = Profile|x86
+		Release|Any CPU = Release|Any CPU
+		Release|ARM = Release|ARM
+		Release|Mixed Platforms = Release|Mixed Platforms
+		Release|Win32 = Release|Win32
+		Release|x64 = Release|x64
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{6150965A-658C-4263-89AD-4F980EB0675D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{6150965A-658C-4263-89AD-4F980EB0675D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{6150965A-658C-4263-89AD-4F980EB0675D}.Debug|ARM.ActiveCfg = Debug|Any CPU
+		{6150965A-658C-4263-89AD-4F980EB0675D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+		{6150965A-658C-4263-89AD-4F980EB0675D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+		{6150965A-658C-4263-89AD-4F980EB0675D}.Debug|Win32.ActiveCfg = Debug|Any CPU
+		{6150965A-658C-4263-89AD-4F980EB0675D}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{6150965A-658C-4263-89AD-4F980EB0675D}.Debug|x64.Build.0 = Debug|Any CPU
+		{6150965A-658C-4263-89AD-4F980EB0675D}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{6150965A-658C-4263-89AD-4F980EB0675D}.Profile|Any CPU.ActiveCfg = Release|Any CPU
+		{6150965A-658C-4263-89AD-4F980EB0675D}.Profile|Any CPU.Build.0 = Release|Any CPU
+		{6150965A-658C-4263-89AD-4F980EB0675D}.Profile|ARM.ActiveCfg = Release|Any CPU
+		{6150965A-658C-4263-89AD-4F980EB0675D}.Profile|Mixed Platforms.ActiveCfg = Release|Any CPU
+		{6150965A-658C-4263-89AD-4F980EB0675D}.Profile|Mixed Platforms.Build.0 = Release|Any CPU
+		{6150965A-658C-4263-89AD-4F980EB0675D}.Profile|Win32.ActiveCfg = Release|Any CPU
+		{6150965A-658C-4263-89AD-4F980EB0675D}.Profile|x64.ActiveCfg = Release|Any CPU
+		{6150965A-658C-4263-89AD-4F980EB0675D}.Profile|x86.ActiveCfg = Release|Any CPU
+		{6150965A-658C-4263-89AD-4F980EB0675D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{6150965A-658C-4263-89AD-4F980EB0675D}.Release|Any CPU.Build.0 = Release|Any CPU
+		{6150965A-658C-4263-89AD-4F980EB0675D}.Release|ARM.ActiveCfg = Release|Any CPU
+		{6150965A-658C-4263-89AD-4F980EB0675D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+		{6150965A-658C-4263-89AD-4F980EB0675D}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+		{6150965A-658C-4263-89AD-4F980EB0675D}.Release|Win32.ActiveCfg = Release|Any CPU
+		{6150965A-658C-4263-89AD-4F980EB0675D}.Release|x64.ActiveCfg = Release|Any CPU
+		{6150965A-658C-4263-89AD-4F980EB0675D}.Release|x86.ActiveCfg = Release|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC489}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC489}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC489}.Debug|ARM.ActiveCfg = Debug|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC489}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC489}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC489}.Debug|Win32.ActiveCfg = Debug|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC489}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC489}.Debug|x64.Build.0 = Debug|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC489}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC489}.Profile|Any CPU.ActiveCfg = Release|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC489}.Profile|Any CPU.Build.0 = Release|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC489}.Profile|ARM.ActiveCfg = Release|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC489}.Profile|Mixed Platforms.ActiveCfg = Release|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC489}.Profile|Mixed Platforms.Build.0 = Release|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC489}.Profile|Win32.ActiveCfg = Release|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC489}.Profile|x64.ActiveCfg = Release|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC489}.Profile|x86.ActiveCfg = Release|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC489}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC489}.Release|Any CPU.Build.0 = Release|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC489}.Release|ARM.ActiveCfg = Release|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC489}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC489}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC489}.Release|Win32.ActiveCfg = Release|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC489}.Release|x64.ActiveCfg = Release|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC489}.Release|x86.ActiveCfg = Release|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC400}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC400}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC400}.Debug|ARM.ActiveCfg = Debug|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC400}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC400}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC400}.Debug|Win32.ActiveCfg = Debug|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC400}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC400}.Debug|x64.Build.0 = Debug|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC400}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC400}.Profile|Any CPU.ActiveCfg = Release|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC400}.Profile|Any CPU.Build.0 = Release|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC400}.Profile|ARM.ActiveCfg = Release|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC400}.Profile|Mixed Platforms.ActiveCfg = Release|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC400}.Profile|Mixed Platforms.Build.0 = Release|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC400}.Profile|Win32.ActiveCfg = Release|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC400}.Profile|x64.ActiveCfg = Release|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC400}.Profile|x86.ActiveCfg = Release|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC400}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC400}.Release|Any CPU.Build.0 = Release|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC400}.Release|ARM.ActiveCfg = Release|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC400}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC400}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC400}.Release|Win32.ActiveCfg = Release|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC400}.Release|x64.ActiveCfg = Release|Any CPU
+		{DD7C931A-8FAF-4318-BB74-71DC858CC400}.Release|x86.ActiveCfg = Release|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Debug|ARM.ActiveCfg = Debug|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Debug|ARM.Build.0 = Debug|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Debug|Win32.ActiveCfg = Debug|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Debug|Win32.Build.0 = Debug|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Debug|x64.Build.0 = Debug|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Debug|x86.Build.0 = Debug|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Profile|Any CPU.ActiveCfg = Release|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Profile|Any CPU.Build.0 = Release|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Profile|ARM.ActiveCfg = Release|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Profile|ARM.Build.0 = Release|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Profile|Mixed Platforms.ActiveCfg = Release|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Profile|Mixed Platforms.Build.0 = Release|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Profile|Win32.ActiveCfg = Release|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Profile|Win32.Build.0 = Release|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Profile|x64.ActiveCfg = Release|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Profile|x64.Build.0 = Release|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Profile|x86.ActiveCfg = Release|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Profile|x86.Build.0 = Release|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Release|Any CPU.Build.0 = Release|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Release|ARM.ActiveCfg = Release|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Release|ARM.Build.0 = Release|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Release|Win32.ActiveCfg = Release|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Release|Win32.Build.0 = Release|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Release|x64.ActiveCfg = Release|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Release|x64.Build.0 = Release|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Release|x86.ActiveCfg = Release|Any CPU
+		{A6B76356-1D1C-4C82-8199-A6406DA85A95}.Release|x86.Build.0 = Release|Any CPU
+		{293A754C-3D80-42FB-99D8-7C9386CD297E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{293A754C-3D80-42FB-99D8-7C9386CD297E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{293A754C-3D80-42FB-99D8-7C9386CD297E}.Debug|ARM.ActiveCfg = Debug|Any CPU
+		{293A754C-3D80-42FB-99D8-7C9386CD297E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+		{293A754C-3D80-42FB-99D8-7C9386CD297E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+		{293A754C-3D80-42FB-99D8-7C9386CD297E}.Debug|Win32.ActiveCfg = Debug|Any CPU
+		{293A754C-3D80-42FB-99D8-7C9386CD297E}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{293A754C-3D80-42FB-99D8-7C9386CD297E}.Debug|x64.Build.0 = Debug|Any CPU
+		{293A754C-3D80-42FB-99D8-7C9386CD297E}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{293A754C-3D80-42FB-99D8-7C9386CD297E}.Profile|Any CPU.ActiveCfg = Debug|Any CPU
+		{293A754C-3D80-42FB-99D8-7C9386CD297E}.Profile|Any CPU.Build.0 = Debug|Any CPU
+		{293A754C-3D80-42FB-99D8-7C9386CD297E}.Profile|ARM.ActiveCfg = Debug|Any CPU
+		{293A754C-3D80-42FB-99D8-7C9386CD297E}.Profile|Mixed Platforms.ActiveCfg = Debug|Any CPU
+		{293A754C-3D80-42FB-99D8-7C9386CD297E}.Profile|Mixed Platforms.Build.0 = Debug|Any CPU
+		{293A754C-3D80-42FB-99D8-7C9386CD297E}.Profile|Win32.ActiveCfg = Debug|Any CPU
+		{293A754C-3D80-42FB-99D8-7C9386CD297E}.Profile|x64.ActiveCfg = Debug|Any CPU
+		{293A754C-3D80-42FB-99D8-7C9386CD297E}.Profile|x86.ActiveCfg = Debug|Any CPU
+		{293A754C-3D80-42FB-99D8-7C9386CD297E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{293A754C-3D80-42FB-99D8-7C9386CD297E}.Release|Any CPU.Build.0 = Release|Any CPU
+		{293A754C-3D80-42FB-99D8-7C9386CD297E}.Release|ARM.ActiveCfg = Release|Any CPU
+		{293A754C-3D80-42FB-99D8-7C9386CD297E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+		{293A754C-3D80-42FB-99D8-7C9386CD297E}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+		{293A754C-3D80-42FB-99D8-7C9386CD297E}.Release|Win32.ActiveCfg = Release|Any CPU
+		{293A754C-3D80-42FB-99D8-7C9386CD297E}.Release|x64.ActiveCfg = Release|Any CPU
+		{293A754C-3D80-42FB-99D8-7C9386CD297E}.Release|x86.ActiveCfg = Release|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Debug|ARM.ActiveCfg = Debug|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Debug|ARM.Build.0 = Debug|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Debug|Win32.ActiveCfg = Debug|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Debug|Win32.Build.0 = Debug|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Debug|x64.Build.0 = Debug|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Debug|x86.Build.0 = Debug|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Profile|Any CPU.ActiveCfg = Release|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Profile|Any CPU.Build.0 = Release|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Profile|ARM.ActiveCfg = Release|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Profile|ARM.Build.0 = Release|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Profile|Mixed Platforms.ActiveCfg = Release|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Profile|Mixed Platforms.Build.0 = Release|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Profile|Win32.ActiveCfg = Release|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Profile|Win32.Build.0 = Release|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Profile|x64.ActiveCfg = Release|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Profile|x64.Build.0 = Release|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Profile|x86.ActiveCfg = Release|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Profile|x86.Build.0 = Release|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Release|Any CPU.Build.0 = Release|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Release|ARM.ActiveCfg = Release|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Release|ARM.Build.0 = Release|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Release|Win32.ActiveCfg = Release|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Release|Win32.Build.0 = Release|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Release|x64.ActiveCfg = Release|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Release|x64.Build.0 = Release|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Release|x86.ActiveCfg = Release|Any CPU
+		{2F49C726-A1F8-40D4-859F-1355949608DC}.Release|x86.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(NestedProjects) = preSolution
+		{DD7C931A-8FAF-4318-BB74-71DC858CC489} = {2139CC27-1C89-49C8-95AC-7715ACBADC1F}
+		{DD7C931A-8FAF-4318-BB74-71DC858CC400} = {2139CC27-1C89-49C8-95AC-7715ACBADC1F}
+		{2F49C726-A1F8-40D4-859F-1355949608DC} = {2139CC27-1C89-49C8-95AC-7715ACBADC1F}
+	EndGlobalSection
+EndGlobal

+ 273 - 293
Exporters/3ds Max/Max2Babylon/2015/Max2Babylon2015.csproj

@@ -1,294 +1,274 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{DD7C931A-8FAF-4318-BB74-71DC858CC400}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Max2Babylon</RootNamespace>
-    <AssemblyName>Max2Babylon</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-    <TargetFrameworkProfile />
-    <SccProjectName>SAK</SccProjectName>
-    <SccLocalPath>SAK</SccLocalPath>
-    <SccAuxPath>SAK</SccAuxPath>
-    <SccProvider>SAK</SccProvider>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
-    <RestorePackages>true</RestorePackages>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>C:\Program Files\Autodesk\3ds Max 2015\bin\assemblies\</OutputPath>
-    <DefineConstants>TRACE;DEBUG;MAX2015</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <Prefer32Bit>false</Prefer32Bit>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>C:\Program Files\Autodesk\3ds Max 2013\bin\assemblies\</OutputPath>
-    <DefineConstants>TRACE;MAX2015</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <Prefer32Bit>false</Prefer32Bit>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="Autodesk.Max, Version=17.0.630.0, Culture=neutral, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\..\..\..\..\Repos\Babylon.js\Exporters\3ds Max\Max2Babylon\2015\Refs\Autodesk.Max.dll</HintPath>
-    </Reference>
-    <Reference Include="BabylonFileConverter, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\Refs\BabylonFileConverter.dll</HintPath>
-    </Reference>
-    <Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\..\packages\Newtonsoft.Json.6.0.7\lib\net45\Newtonsoft.Json.dll</HintPath>
-    </Reference>
-    <Reference Include="SharpDX, Version=2.4.2.0, Culture=neutral, PublicKeyToken=627a3d6d1956f55a, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\..\BabylonExport.Core\Refs\SharpDX.dll</HintPath>
-    </Reference>
-    <Reference Include="System" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Drawing" />
-    <Reference Include="System.Runtime.Serialization" />
-    <Reference Include="System.Web" />
-    <Reference Include="System.Windows.Forms" />
-    <Reference Include="System.Data.DataSetExtensions" />
-    <Reference Include="Microsoft.CSharp" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="..\BabylonActionCallback.cs">
-      <Link>BabylonActionCallback.cs</Link>
-    </Compile>
-    <Compile Include="..\BabylonExportActionItem.cs">
-      <Link>BabylonExportActionItem.cs</Link>
-    </Compile>
-    <Compile Include="..\BabylonPropertiesActionItem.cs">
-      <Link>BabylonPropertiesActionItem.cs</Link>
-    </Compile>
-    <Compile Include="..\Descriptor.cs">
-      <Link>Descriptor.cs</Link>
-    </Compile>
-    <Compile Include="..\Exporter\ActionBuilder\BabylonActionsBuilderActionItem.cs">
-      <Link>Exporter\ActionBuilder\BabylonActionsBuilderActionItem.cs</Link>
-    </Compile>
-    <Compile Include="..\Exporter\ActionBuilder\BabylonExporter.Action.cs">
-      <Link>Exporter\ActionBuilder\BabylonExporter.Action.cs</Link>
-    </Compile>
-    <Compile Include="..\Exporter\BabylonExporter.Animation.cs">
-      <Link>Exporter\BabylonExporter.Animation.cs</Link>
-    </Compile>
-    <Compile Include="..\Exporter\BabylonExporter.Camera.cs">
-      <Link>Exporter\BabylonExporter.Camera.cs</Link>
-    </Compile>
-    <Compile Include="..\Exporter\BabylonExporter.cs">
-      <Link>Exporter\BabylonExporter.cs</Link>
-    </Compile>
-    <Compile Include="..\Exporter\BabylonExporter.Light.cs">
-      <Link>Exporter\BabylonExporter.Light.cs</Link>
-    </Compile>
-    <Compile Include="..\Exporter\BabylonExporter.Material.cs">
-      <Link>Exporter\BabylonExporter.Material.cs</Link>
-    </Compile>
-    <Compile Include="..\Exporter\BabylonExporter.Mesh.cs">
-      <Link>Exporter\BabylonExporter.Mesh.cs</Link>
-    </Compile>
-    <Compile Include="..\Exporter\BabylonExporter.ShadowGenerator.cs">
-      <Link>Exporter\BabylonExporter.ShadowGenerator.cs</Link>
-    </Compile>
-    <Compile Include="..\Exporter\BabylonExporter.Skeleton.cs">
-      <Link>Exporter\BabylonExporter.Skeleton.cs</Link>
-    </Compile>
-    <Compile Include="..\Exporter\BabylonExporter.Texture.cs">
-      <Link>Exporter\BabylonExporter.Texture.cs</Link>
-    </Compile>
-    <Compile Include="..\Exporter\GlobalVertex.cs">
-      <Link>Exporter\GlobalVertex.cs</Link>
-    </Compile>
-    <Compile Include="..\Forms\ActionsBuilderForm.cs">
-      <Link>Forms\ActionsBuilderForm.cs</Link>
-      <SubType>Form</SubType>
-    </Compile>
-    <Compile Include="..\Forms\ActionsBuilderForm.designer.cs">
-      <Link>Forms\ActionsBuilderForm.designer.cs</Link>
-      <DependentUpon>ActionsBuilderForm.cs</DependentUpon>
-    </Compile>
-    <Compile Include="..\Forms\CameraPropertiesForm.cs">
-      <Link>Forms\CameraPropertiesForm.cs</Link>
-      <SubType>Form</SubType>
-    </Compile>
-    <Compile Include="..\Forms\CameraPropertiesForm.Designer.cs">
-      <Link>Forms\CameraPropertiesForm.Designer.cs</Link>
-      <DependentUpon>CameraPropertiesForm.cs</DependentUpon>
-    </Compile>
-    <Compile Include="..\Forms\ExporterForm.cs">
-      <Link>Forms\ExporterForm.cs</Link>
-      <SubType>Form</SubType>
-    </Compile>
-    <Compile Include="..\Forms\ExporterForm.Designer.cs">
-      <Link>Forms\ExporterForm.Designer.cs</Link>
-      <DependentUpon>ExporterForm.cs</DependentUpon>
-    </Compile>
-    <Compile Include="..\Forms\LightPropertiesForm.cs">
-      <Link>Forms\LightPropertiesForm.cs</Link>
-      <SubType>Form</SubType>
-    </Compile>
-    <Compile Include="..\Forms\LightPropertiesForm.Designer.cs">
-      <Link>Forms\LightPropertiesForm.Designer.cs</Link>
-      <DependentUpon>LightPropertiesForm.cs</DependentUpon>
-    </Compile>
-    <Compile Include="..\Forms\ObjectPropertiesForm.cs">
-      <Link>Forms\ObjectPropertiesForm.cs</Link>
-      <SubType>Form</SubType>
-    </Compile>
-    <Compile Include="..\Forms\ObjectPropertiesForm.Designer.cs">
-      <Link>Forms\ObjectPropertiesForm.Designer.cs</Link>
-      <DependentUpon>ObjectPropertiesForm.cs</DependentUpon>
-    </Compile>
-    <Compile Include="..\Forms\ScenePropertiesForm.cs">
-      <Link>Forms\ScenePropertiesForm.cs</Link>
-      <SubType>Form</SubType>
-    </Compile>
-    <Compile Include="..\Forms\ScenePropertiesForm.Designer.cs">
-      <Link>Forms\ScenePropertiesForm.Designer.cs</Link>
-      <DependentUpon>ScenePropertiesForm.cs</DependentUpon>
-    </Compile>
-    <Compile Include="..\Forms\Vector3Control.cs">
-      <Link>Forms\Vector3Control.cs</Link>
-      <SubType>UserControl</SubType>
-    </Compile>
-    <Compile Include="..\Forms\Vector3Control.Designer.cs">
-      <Link>Forms\Vector3Control.Designer.cs</Link>
-      <DependentUpon>Vector3Control.cs</DependentUpon>
-    </Compile>
-    <Compile Include="..\GlobalUtility.cs">
-      <Link>GlobalUtility.cs</Link>
-    </Compile>
-    <Compile Include="..\JsonTextWriterOptimized.cs">
-      <Link>JsonTextWriterOptimized.cs</Link>
-    </Compile>
-    <Compile Include="..\Loader.cs">
-      <Link>Loader.cs</Link>
-    </Compile>
-    <Compile Include="..\Tools\Tools.cs">
-      <Link>Tools\Tools.cs</Link>
-    </Compile>
-    <Compile Include="..\Tools\VNormal.cs">
-      <Link>Tools\VNormal.cs</Link>
-    </Compile>
-    <Compile Include="..\Tools\WebServer.cs">
-      <Link>Tools\WebServer.cs</Link>
-    </Compile>
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="Properties\Resources.Designer.cs">
-      <AutoGen>True</AutoGen>
-      <DesignTime>True</DesignTime>
-      <DependentUpon>Resources.resx</DependentUpon>
-    </Compile>
-  </ItemGroup>
-  <ItemGroup>
-    <Content Include="..\Exporter\ActionBuilder\ActionsBuilder\action.js">
-      <Link>Exporter\ActionBuilder\ActionsBuilder\action.js</Link>
-    </Content>
-    <Content Include="..\Exporter\ActionBuilder\ActionsBuilder\actionkinds.js">
-      <Link>Exporter\ActionBuilder\ActionsBuilder\actionkinds.js</Link>
-    </Content>
-    <Content Include="..\Exporter\ActionBuilder\ActionsBuilder\contextmenu.js">
-      <Link>Exporter\ActionBuilder\ActionsBuilder\contextmenu.js</Link>
-    </Content>
-    <Content Include="..\Exporter\ActionBuilder\ActionsBuilder\fonts.css">
-      <Link>Exporter\ActionBuilder\ActionsBuilder\fonts.css</Link>
-    </Content>
-    <Content Include="..\Exporter\ActionBuilder\ActionsBuilder\index.css">
-      <Link>Exporter\ActionBuilder\ActionsBuilder\index.css</Link>
-    </Content>
-    <Content Include="..\Exporter\ActionBuilder\ActionsBuilder\index.html">
-      <Link>Exporter\ActionBuilder\ActionsBuilder\index.html</Link>
-    </Content>
-    <Content Include="..\Exporter\ActionBuilder\ActionsBuilder\list.js">
-      <Link>Exporter\ActionBuilder\ActionsBuilder\list.js</Link>
-    </Content>
-    <Content Include="..\Exporter\ActionBuilder\ActionsBuilder\parametersManager.js">
-      <Link>Exporter\ActionBuilder\ActionsBuilder\parametersManager.js</Link>
-    </Content>
-    <Content Include="..\Exporter\ActionBuilder\ActionsBuilder\raphael.js">
-      <Link>Exporter\ActionBuilder\ActionsBuilder\raphael.js</Link>
-    </Content>
-    <Content Include="..\Exporter\ActionBuilder\ActionsBuilder\utils.js">
-      <Link>Exporter\ActionBuilder\ActionsBuilder\utils.js</Link>
-    </Content>
-    <Content Include="..\Exporter\ActionBuilder\ActionsBuilder\viewer.js">
-      <Link>Exporter\ActionBuilder\ActionsBuilder\viewer.js</Link>
-    </Content>
-    <Content Include="..\Exporter\ActionBuilder\ActionsBuilder\viewsertoolbar.js">
-      <Link>Exporter\ActionBuilder\ActionsBuilder\viewsertoolbar.js</Link>
-    </Content>
-    <Content Include="Refs\Autodesk.Max.dll" />
-  </ItemGroup>
-  <ItemGroup>
-    <EmbeddedResource Include="..\Forms\ActionsBuilderForm.resx">
-      <Link>Forms\ActionsBuilderForm.resx</Link>
-      <DependentUpon>ActionsBuilderForm.cs</DependentUpon>
-    </EmbeddedResource>
-    <EmbeddedResource Include="..\Forms\CameraPropertiesForm.resx">
-      <Link>Forms\CameraPropertiesForm.resx</Link>
-      <DependentUpon>CameraPropertiesForm.cs</DependentUpon>
-    </EmbeddedResource>
-    <EmbeddedResource Include="..\Forms\ExporterForm.resx">
-      <Link>Forms\ExporterForm.resx</Link>
-      <DependentUpon>ExporterForm.cs</DependentUpon>
-    </EmbeddedResource>
-    <EmbeddedResource Include="..\Forms\LightPropertiesForm.resx">
-      <Link>Forms\LightPropertiesForm.resx</Link>
-      <DependentUpon>LightPropertiesForm.cs</DependentUpon>
-    </EmbeddedResource>
-    <EmbeddedResource Include="..\Forms\ObjectPropertiesForm.resx">
-      <Link>Forms\ObjectPropertiesForm.resx</Link>
-      <DependentUpon>ObjectPropertiesForm.cs</DependentUpon>
-    </EmbeddedResource>
-    <EmbeddedResource Include="..\Forms\ScenePropertiesForm.resx">
-      <Link>Forms\ScenePropertiesForm.resx</Link>
-      <DependentUpon>ScenePropertiesForm.cs</DependentUpon>
-    </EmbeddedResource>
-    <EmbeddedResource Include="..\Forms\Vector3Control.resx">
-      <Link>Forms\Vector3Control.resx</Link>
-      <DependentUpon>Vector3Control.cs</DependentUpon>
-    </EmbeddedResource>
-    <EmbeddedResource Include="Properties\Resources.resx">
-      <Generator>ResXFileCodeGenerator</Generator>
-      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
-    </EmbeddedResource>
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\..\BabylonExport.Entities\BabylonExport.Entities.csproj">
-      <Project>{6150965a-658c-4263-89ad-4f980eb0675d}</Project>
-      <Name>BabylonExport.Entities</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <PropertyGroup>
-    <PostBuildEvent>mkdir "$(OutDir)BabylonActionsBuilder"
-mkdir "$(OutDir)BabylonActionsBuilder\fonts\SinkinSans"
-copy "$(SolutionDir)Max2Babylon\Exporter\ActionBuilder\ActionsBuilder\" "$(OutDir)BabylonActionsBuilder\"
-copy "$(SolutionDir)Max2Babylon\Exporter\ActionBuilder\ActionsBuilder\fonts\SinkinSans" "$(OutDir)BabylonActionsBuilder\fonts\SinkinSans"
-copy "$(SolutionDir)babylon.max.js" "$(OutDir)BabylonActionsBuilder\babylon.max.js"</PostBuildEvent>
-  </PropertyGroup>
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{DD7C931A-8FAF-4318-BB74-71DC858CC400}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Max2Babylon</RootNamespace>
+    <AssemblyName>Max2Babylon</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <TargetFrameworkProfile />
+    <SccProjectName>SAK</SccProjectName>
+    <SccLocalPath>SAK</SccLocalPath>
+    <SccAuxPath>SAK</SccAuxPath>
+    <SccProvider>SAK</SccProvider>
+    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
+    <RestorePackages>true</RestorePackages>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>C:\Program Files\Autodesk\3ds Max 2016\bin\assemblies\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;MAX2015</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Prefer32Bit>false</Prefer32Bit>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>C:\Program Files\Autodesk\3ds Max 2013\bin\assemblies\</OutputPath>
+    <DefineConstants>TRACE;MAX2015</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Autodesk.Max, Version=17.0.630.0, Culture=neutral, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\..\Repos\Babylon.js\Exporters\3ds Max\Max2Babylon\2015\Refs\Autodesk.Max.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="SharpDX, Version=3.1.1.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\SharpDX.3.1.1\lib\net45\SharpDX.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="SharpDX.Mathematics, Version=3.1.1.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\SharpDX.Mathematics.3.1.1\lib\net45\SharpDX.Mathematics.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Runtime.Serialization" />
+    <Reference Include="System.Web" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="..\BabylonActionCallback.cs">
+      <Link>BabylonActionCallback.cs</Link>
+    </Compile>
+    <Compile Include="..\BabylonExportActionItem.cs">
+      <Link>BabylonExportActionItem.cs</Link>
+    </Compile>
+    <Compile Include="..\BabylonPropertiesActionItem.cs">
+      <Link>BabylonPropertiesActionItem.cs</Link>
+    </Compile>
+    <Compile Include="..\Descriptor.cs">
+      <Link>Descriptor.cs</Link>
+    </Compile>
+    <Compile Include="..\Exporter\ActionBuilder\BabylonActionsBuilderActionItem.cs">
+      <Link>Exporter\ActionBuilder\BabylonActionsBuilderActionItem.cs</Link>
+    </Compile>
+    <Compile Include="..\Exporter\ActionBuilder\BabylonExporter.Action.cs">
+      <Link>Exporter\ActionBuilder\BabylonExporter.Action.cs</Link>
+    </Compile>
+    <Compile Include="..\Exporter\BabylonExporter.Animation.cs">
+      <Link>Exporter\BabylonExporter.Animation.cs</Link>
+    </Compile>
+    <Compile Include="..\Exporter\BabylonExporter.Camera.cs">
+      <Link>Exporter\BabylonExporter.Camera.cs</Link>
+    </Compile>
+    <Compile Include="..\Exporter\BabylonExporter.cs">
+      <Link>Exporter\BabylonExporter.cs</Link>
+    </Compile>
+    <Compile Include="..\Exporter\BabylonExporter.Light.cs">
+      <Link>Exporter\BabylonExporter.Light.cs</Link>
+    </Compile>
+    <Compile Include="..\Exporter\BabylonExporter.Material.cs">
+      <Link>Exporter\BabylonExporter.Material.cs</Link>
+    </Compile>
+    <Compile Include="..\Exporter\BabylonExporter.Mesh.cs">
+      <Link>Exporter\BabylonExporter.Mesh.cs</Link>
+    </Compile>
+    <Compile Include="..\Exporter\BabylonExporter.ShadowGenerator.cs">
+      <Link>Exporter\BabylonExporter.ShadowGenerator.cs</Link>
+    </Compile>
+    <Compile Include="..\Exporter\BabylonExporter.Skeleton.cs">
+      <Link>Exporter\BabylonExporter.Skeleton.cs</Link>
+    </Compile>
+    <Compile Include="..\Exporter\BabylonExporter.Texture.cs">
+      <Link>Exporter\BabylonExporter.Texture.cs</Link>
+    </Compile>
+    <Compile Include="..\Exporter\GlobalVertex.cs">
+      <Link>Exporter\GlobalVertex.cs</Link>
+    </Compile>
+    <Compile Include="..\Forms\ActionsBuilderForm.cs">
+      <Link>Forms\ActionsBuilderForm.cs</Link>
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="..\Forms\ActionsBuilderForm.designer.cs">
+      <Link>Forms\ActionsBuilderForm.designer.cs</Link>
+      <DependentUpon>ActionsBuilderForm.cs</DependentUpon>
+    </Compile>
+    <Compile Include="..\Forms\CameraPropertiesForm.cs">
+      <Link>Forms\CameraPropertiesForm.cs</Link>
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="..\Forms\CameraPropertiesForm.Designer.cs">
+      <Link>Forms\CameraPropertiesForm.Designer.cs</Link>
+      <DependentUpon>CameraPropertiesForm.cs</DependentUpon>
+    </Compile>
+    <Compile Include="..\Forms\ExporterForm.cs">
+      <Link>Forms\ExporterForm.cs</Link>
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="..\Forms\ExporterForm.Designer.cs">
+      <Link>Forms\ExporterForm.Designer.cs</Link>
+      <DependentUpon>ExporterForm.cs</DependentUpon>
+    </Compile>
+    <Compile Include="..\Forms\LightPropertiesForm.cs">
+      <Link>Forms\LightPropertiesForm.cs</Link>
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="..\Forms\LightPropertiesForm.Designer.cs">
+      <Link>Forms\LightPropertiesForm.Designer.cs</Link>
+      <DependentUpon>LightPropertiesForm.cs</DependentUpon>
+    </Compile>
+    <Compile Include="..\Forms\ObjectPropertiesForm.cs">
+      <Link>Forms\ObjectPropertiesForm.cs</Link>
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="..\Forms\ObjectPropertiesForm.Designer.cs">
+      <Link>Forms\ObjectPropertiesForm.Designer.cs</Link>
+      <DependentUpon>ObjectPropertiesForm.cs</DependentUpon>
+    </Compile>
+    <Compile Include="..\Forms\ScenePropertiesForm.cs">
+      <Link>Forms\ScenePropertiesForm.cs</Link>
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="..\Forms\ScenePropertiesForm.Designer.cs">
+      <Link>Forms\ScenePropertiesForm.Designer.cs</Link>
+      <DependentUpon>ScenePropertiesForm.cs</DependentUpon>
+    </Compile>
+    <Compile Include="..\Forms\Vector3Control.cs">
+      <Link>Forms\Vector3Control.cs</Link>
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="..\Forms\Vector3Control.Designer.cs">
+      <Link>Forms\Vector3Control.Designer.cs</Link>
+      <DependentUpon>Vector3Control.cs</DependentUpon>
+    </Compile>
+    <Compile Include="..\GlobalUtility.cs">
+      <Link>GlobalUtility.cs</Link>
+    </Compile>
+    <Compile Include="..\JsonTextWriterOptimized.cs">
+      <Link>JsonTextWriterOptimized.cs</Link>
+    </Compile>
+    <Compile Include="..\Loader.cs">
+      <Link>Loader.cs</Link>
+    </Compile>
+    <Compile Include="..\Tools\Tools.cs">
+      <Link>Tools\Tools.cs</Link>
+    </Compile>
+    <Compile Include="..\Tools\VNormal.cs">
+      <Link>Tools\VNormal.cs</Link>
+    </Compile>
+    <Compile Include="..\Tools\WebServer.cs">
+      <Link>Tools\WebServer.cs</Link>
+    </Compile>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Properties\Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>Resources.resx</DependentUpon>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="Refs\Autodesk.Max.dll" />
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="..\Forms\ActionsBuilderForm.resx">
+      <Link>Forms\ActionsBuilderForm.resx</Link>
+      <DependentUpon>ActionsBuilderForm.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="..\Forms\CameraPropertiesForm.resx">
+      <Link>Forms\CameraPropertiesForm.resx</Link>
+      <DependentUpon>CameraPropertiesForm.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="..\Forms\ExporterForm.resx">
+      <Link>Forms\ExporterForm.resx</Link>
+      <DependentUpon>ExporterForm.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="..\Forms\LightPropertiesForm.resx">
+      <Link>Forms\LightPropertiesForm.resx</Link>
+      <DependentUpon>LightPropertiesForm.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="..\Forms\ObjectPropertiesForm.resx">
+      <Link>Forms\ObjectPropertiesForm.resx</Link>
+      <DependentUpon>ObjectPropertiesForm.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="..\Forms\ScenePropertiesForm.resx">
+      <Link>Forms\ScenePropertiesForm.resx</Link>
+      <DependentUpon>ScenePropertiesForm.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="..\Forms\Vector3Control.resx">
+      <Link>Forms\Vector3Control.resx</Link>
+      <DependentUpon>Vector3Control.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="Properties\Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+    </EmbeddedResource>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\BabylonExport.Entities\BabylonExport.Entities.csproj">
+      <Project>{6150965a-658c-4263-89ad-4f980eb0675d}</Project>
+      <Name>BabylonExport.Entities</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\BabylonFileConverter\BabylonFileConverter.csproj">
+      <Project>{a6b76356-1d1c-4c82-8199-a6406da85a95}</Project>
+      <Name>BabylonFileConverter</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <WCFMetadata Include="Service References\" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup>
+    <PostBuildEvent>mkdir "$(OutDir)BabylonActionsBuilder"
+mkdir "$(OutDir)BabylonActionsBuilder\fonts"
+mkdir "$(OutDir)BabylonActionsBuilder\fonts\SinkinSans"
+copy "$(SolutionDir)ActionsBuilder\Sources\fonts.css" "$(OutDir)BabylonActionsBuilder\fonts.css"
+copy "$(SolutionDir)ActionsBuilder\Sources\index.css" "$(OutDir)BabylonActionsBuilder\index.css"
+copy "$(SolutionDir)ActionsBuilder\Sources\index.html" "$(OutDir)BabylonActionsBuilder\index.html"
+copy "$(SolutionDir)ActionsBuilder\Sources\actionsbuilder.max.js" "$(OutDir)BabylonActionsBuilder\actionsbuilder.max.js"
+copy "$(SolutionDir)ActionsBuilder\Sources\raphael.js" "$(OutDir)BabylonActionsBuilder\raphael.js"
+copy "$(SolutionDir)babylon.max.js" "$(OutDir)BabylonActionsBuilder\babylon.max.js"
+copy "$(SolutionDir)ActionsBuilder\Sources\fonts\SinkinSans\" "$(OutDir)BabylonActionsBuilder\fonts\SinkinSans\"</PostBuildEvent>
+  </PropertyGroup>
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
 </Project>

+ 36 - 36
Exporters/3ds Max/Max2Babylon/2015/Properties/AssemblyInfo.cs

@@ -1,36 +1,36 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following 
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("Max2Babylon")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Max2Babylon")]
-[assembly: AssemblyCopyright("Copyright ©  2014")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible 
-// to COM components.  If you need to access a type in this assembly from 
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("2d621b1c-3661-49bd-8dd3-4c5de51fce94")]
-
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version 
-//      Build Number
-//      Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers 
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Max2Babylon")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Max2Babylon")]
+[assembly: AssemblyCopyright("Copyright ©  2014")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("2d621b1c-3661-49bd-8dd3-4c5de51fce94")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 63 - 63
Exporters/3ds Max/Max2Babylon/2015/Properties/Resources.Designer.cs

@@ -1,63 +1,63 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated by a tool.
-//     Runtime Version:4.0.30319.34014
-//
-//     Changes to this file may cause incorrect behavior and will be lost if
-//     the code is regenerated.
-// </auto-generated>
-//------------------------------------------------------------------------------
-
-namespace Max2Babylon.Properties {
-    using System;
-    
-    
-    /// <summary>
-    ///   A strongly-typed resource class, for looking up localized strings, etc.
-    /// </summary>
-    // This class was auto-generated by the StronglyTypedResourceBuilder
-    // class via a tool like ResGen or Visual Studio.
-    // To add or remove a member, edit your .ResX file then rerun ResGen
-    // with the /str option, or rebuild your VS project.
-    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
-    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
-    internal class Resources {
-        
-        private static global::System.Resources.ResourceManager resourceMan;
-        
-        private static global::System.Globalization.CultureInfo resourceCulture;
-        
-        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
-        internal Resources() {
-        }
-        
-        /// <summary>
-        ///   Returns the cached ResourceManager instance used by this class.
-        /// </summary>
-        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
-        internal static global::System.Resources.ResourceManager ResourceManager {
-            get {
-                if (object.ReferenceEquals(resourceMan, null)) {
-                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Max2Babylon.Properties.Resources", typeof(Resources).Assembly);
-                    resourceMan = temp;
-                }
-                return resourceMan;
-            }
-        }
-        
-        /// <summary>
-        ///   Overrides the current thread's CurrentUICulture property for all
-        ///   resource lookups using this strongly typed resource class.
-        /// </summary>
-        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
-        internal static global::System.Globalization.CultureInfo Culture {
-            get {
-                return resourceCulture;
-            }
-            set {
-                resourceCulture = value;
-            }
-        }
-    }
-}
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.34014
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Max2Babylon.Properties {
+    using System;
+    
+    
+    /// <summary>
+    ///   A strongly-typed resource class, for looking up localized strings, etc.
+    /// </summary>
+    // This class was auto-generated by the StronglyTypedResourceBuilder
+    // class via a tool like ResGen or Visual Studio.
+    // To add or remove a member, edit your .ResX file then rerun ResGen
+    // with the /str option, or rebuild your VS project.
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources() {
+        }
+        
+        /// <summary>
+        ///   Returns the cached ResourceManager instance used by this class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if (object.ReferenceEquals(resourceMan, null)) {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Max2Babylon.Properties.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+        
+        /// <summary>
+        ///   Overrides the current thread's CurrentUICulture property for all
+        ///   resource lookups using this strongly typed resource class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+    }
+}

+ 119 - 119
Exporters/3ds Max/Max2Babylon/2015/Properties/Resources.resx

@@ -1,120 +1,120 @@
-<?xml version="1.0" encoding="utf-8"?>
-<root>
-  <!-- 
-    Microsoft ResX Schema 
-    
-    Version 2.0
-    
-    The primary goals of this format is to allow a simple XML format 
-    that is mostly human readable. The generation and parsing of the 
-    various data types are done through the TypeConverter classes 
-    associated with the data types.
-    
-    Example:
-    
-    ... ado.net/XML headers & schema ...
-    <resheader name="resmimetype">text/microsoft-resx</resheader>
-    <resheader name="version">2.0</resheader>
-    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
-    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
-    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
-    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
-    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
-        <value>[base64 mime encoded serialized .NET Framework object]</value>
-    </data>
-    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
-        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
-        <comment>This is a comment</comment>
-    </data>
-                
-    There are any number of "resheader" rows that contain simple 
-    name/value pairs.
-    
-    Each data row contains a name, and value. The row also contains a 
-    type or mimetype. Type corresponds to a .NET class that support 
-    text/value conversion through the TypeConverter architecture. 
-    Classes that don't support this are serialized and stored with the 
-    mimetype set.
-    
-    The mimetype is used for serialized objects, and tells the 
-    ResXResourceReader how to depersist the object. This is currently not 
-    extensible. For a given mimetype the value must be set accordingly:
-    
-    Note - application/x-microsoft.net.object.binary.base64 is the format 
-    that the ResXResourceWriter will generate, however the reader can 
-    read any of the formats listed below.
-    
-    mimetype: application/x-microsoft.net.object.binary.base64
-    value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
-            : and then encoded with base64 encoding.
-    
-    mimetype: application/x-microsoft.net.object.soap.base64
-    value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
-            : and then encoded with base64 encoding.
-
-    mimetype: application/x-microsoft.net.object.bytearray.base64
-    value   : The object must be serialized into a byte array 
-            : using a System.ComponentModel.TypeConverter
-            : and then encoded with base64 encoding.
-    -->
-  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
-    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
-    <xsd:element name="root" msdata:IsDataSet="true">
-      <xsd:complexType>
-        <xsd:choice maxOccurs="unbounded">
-          <xsd:element name="metadata">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" />
-              </xsd:sequence>
-              <xsd:attribute name="name" use="required" type="xsd:string" />
-              <xsd:attribute name="type" type="xsd:string" />
-              <xsd:attribute name="mimetype" type="xsd:string" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="assembly">
-            <xsd:complexType>
-              <xsd:attribute name="alias" type="xsd:string" />
-              <xsd:attribute name="name" type="xsd:string" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="data">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
-              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
-              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="resheader">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" />
-            </xsd:complexType>
-          </xsd:element>
-        </xsd:choice>
-      </xsd:complexType>
-    </xsd:element>
-  </xsd:schema>
-  <resheader name="resmimetype">
-    <value>text/microsoft-resx</value>
-  </resheader>
-  <resheader name="version">
-    <value>2.0</value>
-  </resheader>
-  <resheader name="reader">
-    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-  <resheader name="writer">
-    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
 </root>

+ 6 - 0
Exporters/3ds Max/Max2Babylon/2015/packages.config

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
+  <package id="SharpDX" version="3.1.1" targetFramework="net45" />
+  <package id="SharpDX.Mathematics" version="3.1.1" targetFramework="net45" />
+</packages>

+ 9 - 12
Exporters/3ds Max/Max2Babylon/2017/Max2Babylon2017.csproj

@@ -45,13 +45,17 @@
       <HintPath>..\..\..\..\..\Repos\Babylon.js\Exporters\3ds Max\Max2Babylon\2015\Refs\Autodesk.Max.dll</HintPath>
       <Private>False</Private>
     </Reference>
-    <Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+    <Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
       <Private>True</Private>
     </Reference>
-    <Reference Include="SharpDX, Version=2.4.2.0, Culture=neutral, PublicKeyToken=627a3d6d1956f55a, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\..\BabylonExport.Core\Refs\SharpDX.dll</HintPath>
+    <Reference Include="SharpDX, Version=3.1.1.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\SharpDX.3.1.1\lib\net45\SharpDX.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="SharpDX.Mathematics, Version=3.1.1.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\SharpDX.Mathematics.3.1.1\lib\net45\SharpDX.Mathematics.dll</HintPath>
+      <Private>True</Private>
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
@@ -248,13 +252,6 @@
     <None Include="packages.config" />
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
-  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
-    <PropertyGroup>
-      <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
-    </PropertyGroup>
-    <Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
-  </Target>
   <PropertyGroup>
     <PostBuildEvent>mkdir "$(OutDir)BabylonActionsBuilder"
 mkdir "$(OutDir)BabylonActionsBuilder\fonts"

+ 6 - 0
Exporters/3ds Max/Max2Babylon/2017/packages.config

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
+  <package id="SharpDX" version="3.1.1" targetFramework="net45" />
+  <package id="SharpDX.Mathematics" version="3.1.1" targetFramework="net45" />
+</packages>

+ 0 - 80
Exporters/3ds Max/Max2Babylon/BabylonActionsBuilderActionItem.cs

@@ -1,80 +0,0 @@
-using Autodesk.Max;
-using ActionItem = Autodesk.Max.Plugins.ActionItem;
-
-namespace Max2Babylon
-{
-    public class BabylonActionsBuilderActionItem : ActionItem
-    {
-        public override bool ExecuteAction()
-        {
-            if (Loader.Core.SelNodeCount > 1)
-            {
-                Loader.Core.PushPrompt("Actions Builder only supports one Node");
-            }
-            else
-            {
-                IINode node = null;
-                SClass_ID type;
-
-                if (Loader.Core.SelNodeCount == 0)
-                    type = SClass_ID.Scene;
-                else
-                {
-                    node = Loader.Core.GetSelNode(0);
-                    type = node.ObjectRef.Eval(0).Obj.SuperClassID;
-                }
-
-                if (type == SClass_ID.Geomobject || type == SClass_ID.Light || type == SClass_ID.Camera || type == SClass_ID.Scene)
-                {
-                    using (var ab = new ActionsBuilderForm())
-                    {
-                        // Just show dialog
-                        ab.ShowDialog();
-                    }
-                }
-            }
-
-            return true;
-        }
-
-        public override int Id_
-        {
-            get { return 2; }
-        }
-
-        public override string ButtonText
-        {
-            get { return "Babylon Actions Builder"; }
-        }
-
-        public override string MenuText
-        {
-            get { return "Babylon Actions Builder"; }
-        }
-
-        public override string DescriptionText
-        {
-            get { return "UI graph to build custom actions on selected object"; }
-        }
-
-        public override string CategoryText
-        {
-            get { return "Babylon"; }
-        }
-
-        public override bool IsChecked_
-        {
-            get { return false; }
-        }
-
-        public override bool IsItemVisible
-        {
-            get { return true; }
-        }
-
-        public override bool IsEnabled_
-        {
-            get { return true; }
-        }
-    }
-}

+ 95 - 95
Exporters/3ds Max/Max2Babylon/Exporter/ActionBuilder/BabylonActionsBuilderActionItem.cs

@@ -1,95 +1,95 @@
-using Autodesk.Max;
-using System.Windows.Forms;
-using ActionItem = Autodesk.Max.Plugins.ActionItem;
-
-namespace Max2Babylon
-{
-    public class BabylonActionsBuilderActionItem : ActionItem
-    {
-        private ActionsBuilderForm _form = null;
-
-        public override bool ExecuteAction()
-        {
-            if (Loader.Core.SelNodeCount > 1)
-            {
-                Loader.Core.PushPrompt("Actions Builder only supports one Node");
-            }
-            else
-            {
-                IINode node = null;
-                SClass_ID type;
-
-                if (Loader.Core.SelNodeCount == 0)
-                    type = SClass_ID.Scene;
-                else
-                {
-                    node = Loader.Core.GetSelNode(0);
-                    type = node.ObjectRef.Eval(0).Obj.SuperClassID;
-                }
-
-                if (type == SClass_ID.Geomobject || type == SClass_ID.Scene)
-                {
-                    if (_form == null)
-                        _form = new ActionsBuilderForm(this);
-
-                    _form.WindowState = FormWindowState.Maximized;
-
-                    _form.ShowDialog();
-                    //Application.Run(_form);
-
-                }
-            }
-
-            return true;
-        }
-
-        public void Close()
-        {
-            if (_form == null)
-                return;
-
-            _form.Dispose();
-            _form = null;
-        }
-
-        public override int Id_
-        {
-            get { return 2; }
-        }
-
-        public override string ButtonText
-        {
-            get { return "Babylon Actions Builder"; }
-        }
-
-        public override string MenuText
-        {
-            get { return "Babylon Actions Builder"; }
-        }
-
-        public override string DescriptionText
-        {
-            get { return "UI graph to build custom actions on selected object"; }
-        }
-
-        public override string CategoryText
-        {
-            get { return "Babylon"; }
-        }
-
-        public override bool IsChecked_
-        {
-            get { return false; }
-        }
-
-        public override bool IsItemVisible
-        {
-            get { return true; }
-        }
-
-        public override bool IsEnabled_
-        {
-            get { return true; }
-        }
-    }
-}
+using Autodesk.Max;
+using System.Windows.Forms;
+using ActionItem = Autodesk.Max.Plugins.ActionItem;
+
+namespace Max2Babylon
+{
+    public class BabylonActionsBuilderActionItem : ActionItem
+    {
+        private ActionsBuilderForm _form = null;
+
+        public override bool ExecuteAction()
+        {
+            if (Loader.Core.SelNodeCount > 1)
+            {
+                Loader.Core.PushPrompt("Actions Builder only supports one Node");
+            }
+            else
+            {
+                IINode node = null;
+                SClass_ID type;
+
+                if (Loader.Core.SelNodeCount == 0)
+                    type = SClass_ID.Scene;
+                else
+                {
+                    node = Loader.Core.GetSelNode(0);
+                    type = node.ObjectRef.Eval(0).Obj.SuperClassID;
+                }
+
+                if (type == SClass_ID.Geomobject || type == SClass_ID.Scene)
+                {
+                    if (_form == null)
+                        _form = new ActionsBuilderForm(this);
+
+                    _form.WindowState = FormWindowState.Maximized;
+
+                    _form.ShowDialog();
+                    //Application.Run(_form);
+
+                }
+            }
+
+            return true;
+        }
+
+        public void Close()
+        {
+            if (_form == null)
+                return;
+
+            _form.Dispose();
+            _form = null;
+        }
+
+        public override int Id_
+        {
+            get { return 2; }
+        }
+
+        public override string ButtonText
+        {
+            get { return "Babylon Actions Builder"; }
+        }
+
+        public override string MenuText
+        {
+            get { return "Babylon Actions Builder"; }
+        }
+
+        public override string DescriptionText
+        {
+            get { return "UI graph to build custom actions on selected object"; }
+        }
+
+        public override string CategoryText
+        {
+            get { return "Babylon"; }
+        }
+
+        public override bool IsChecked_
+        {
+            get { return false; }
+        }
+
+        public override bool IsItemVisible
+        {
+            get { return true; }
+        }
+
+        public override bool IsEnabled_
+        {
+            get { return true; }
+        }
+    }
+}

+ 27 - 27
Exporters/3ds Max/Max2Babylon/Exporter/ActionBuilder/BabylonExporter.Action.cs

@@ -1,27 +1,27 @@
-using System;
-using System.Collections.Generic;
-using Newtonsoft.Json;
-using Autodesk.Max;
-using BabylonExport.Entities;
-
-namespace Max2Babylon
-{
-    partial class BabylonExporter
-    {
-        private BabylonActions ExportNodeAction(IIGameNode node)
-        {
-            string prop;
-            if (node != null)
-                prop = node.MaxNode.GetStringProperty("babylon_actionsbuilder", "");
-            else
-                prop = Loader.Core.RootNode.GetStringProperty("babylon_actionsbuilder", "");
-
-            if (String.IsNullOrEmpty(prop))
-                return null;
-
-            var result = JsonConvert.DeserializeObject<BabylonActions>(prop);
-
-            return result;
-        }
-    }
-}
+using System;
+using System.Collections.Generic;
+using Newtonsoft.Json;
+using Autodesk.Max;
+using BabylonExport.Entities;
+
+namespace Max2Babylon
+{
+    partial class BabylonExporter
+    {
+        private BabylonActions ExportNodeAction(IIGameNode node)
+        {
+            string prop;
+            if (node != null)
+                prop = node.MaxNode.GetStringProperty("babylon_actionsbuilder", "");
+            else
+                prop = Loader.Core.RootNode.GetStringProperty("babylon_actionsbuilder", "");
+
+            if (String.IsNullOrEmpty(prop))
+                return null;
+
+            var result = JsonConvert.DeserializeObject<BabylonActions>(prop);
+
+            return result;
+        }
+    }
+}

+ 5 - 0
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Mesh.cs

@@ -490,6 +490,11 @@ namespace Max2Babylon
                     }
 
                     instance.scaling = new[] { instanceScale.X, instanceScale.Y, instanceScale.Z };
+
+                    if (instanceGameNode.NodeParent != null)
+                    {
+                        instance.parentId = GetParentID(instanceGameNode.NodeParent, babylonScene, scene);
+                    }
                 }
                 var instanceAnimations = new List<BabylonAnimation>();
                 GenerateCoordinatesAnimations(meshNode, instanceAnimations);

+ 208 - 187
Exporters/3ds Max/Max2Babylon/Max2Babylon.csproj

@@ -1,188 +1,209 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{DD7C931A-8FAF-4318-BB74-71DC858CC489}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Max2Babylon</RootNamespace>
-    <AssemblyName>Max2Babylon</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-    <TargetFrameworkProfile />
-    <SccProjectName>SAK</SccProjectName>
-    <SccLocalPath>SAK</SccLocalPath>
-    <SccAuxPath>SAK</SccAuxPath>
-    <SccProvider>SAK</SccProvider>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
-    <NuGetPackageImportStamp>eeea6a2c</NuGetPackageImportStamp>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>C:\Program Files\Autodesk\3ds Max 2013\bin\assemblies\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <Prefer32Bit>false</Prefer32Bit>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>C:\Program Files\Autodesk\3ds Max 2013\bin\assemblies\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <Prefer32Bit>false</Prefer32Bit>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="Autodesk.Max, Version=15.6.164.0, Culture=neutral, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>Refs\Autodesk.Max.dll</HintPath>
-      <Private>False</Private>
-    </Reference>
-    <Reference Include="BabylonFileConverter">
-      <HintPath>Refs\BabylonFileConverter.dll</HintPath>
-    </Reference>
-    <Reference Include="Newtonsoft.Json">
-      <HintPath>..\packages\Newtonsoft.Json.6.0.6\lib\net45\Newtonsoft.Json.dll</HintPath>
-    </Reference>
-    <Reference Include="SharpDX, Version=2.4.2.0, Culture=neutral, PublicKeyToken=627a3d6d1956f55a, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>$(SharpDXPackageBinDir)\SharpDX.dll</HintPath>
-    </Reference>
-    <Reference Include="System" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Drawing" />
-    <Reference Include="System.Runtime.Serialization" />
-    <Reference Include="System.Web" />
-    <Reference Include="System.Windows.Forms" />
-    <Reference Include="System.Data.DataSetExtensions" />
-    <Reference Include="Microsoft.CSharp" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="BabylonActionCallback.cs" />
-    <Compile Include="BabylonPropertiesActionItem.cs" />
-    <Compile Include="Exporter\BabylonExporter.Skeleton.cs" />
-    <Compile Include="Forms\LightPropertiesForm.cs">
-      <SubType>Form</SubType>
-    </Compile>
-    <Compile Include="Forms\LightPropertiesForm.Designer.cs">
-      <DependentUpon>LightPropertiesForm.cs</DependentUpon>
-    </Compile>
-    <Compile Include="Exporter\BabylonExporter.Animation.cs" />
-    <Compile Include="Exporter\BabylonExporter.ShadowGenerator.cs" />
-    <Compile Include="Forms\CameraPropertiesForm.cs">
-      <SubType>Form</SubType>
-    </Compile>
-    <Compile Include="Forms\CameraPropertiesForm.Designer.cs">
-      <DependentUpon>CameraPropertiesForm.cs</DependentUpon>
-    </Compile>
-    <Compile Include="Descriptor.cs">
-      <SubType>Code</SubType>
-    </Compile>
-    <Compile Include="Forms\ExporterForm.cs">
-      <SubType>Form</SubType>
-    </Compile>
-    <Compile Include="Forms\ExporterForm.Designer.cs">
-      <DependentUpon>ExporterForm.cs</DependentUpon>
-    </Compile>
-    <Compile Include="Exporter\BabylonExporter.Texture.cs" />
-    <Compile Include="Exporter\BabylonExporter.Material.cs" />
-    <Compile Include="Exporter\BabylonExporter.Light.cs" />
-    <Compile Include="Exporter\BabylonExporter.cs" />
-    <Compile Include="Exporter\BabylonExporter.Camera.cs" />
-    <Compile Include="Exporter\BabylonExporter.Mesh.cs" />
-    <Compile Include="Exporter\GlobalVertex.cs" />
-    <Compile Include="GlobalUtility.cs" />
-    <Compile Include="JsonTextWriterOptimized.cs" />
-    <Compile Include="Loader.cs" />
-    <Compile Include="BabylonExportActionItem.cs" />
-    <Compile Include="Forms\ObjectPropertiesForm.cs">
-      <SubType>Form</SubType>
-    </Compile>
-    <Compile Include="Forms\ObjectPropertiesForm.Designer.cs">
-      <DependentUpon>ObjectPropertiesForm.cs</DependentUpon>
-    </Compile>
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="Properties\Resources.Designer.cs">
-      <AutoGen>True</AutoGen>
-      <DesignTime>True</DesignTime>
-      <DependentUpon>Resources.resx</DependentUpon>
-    </Compile>
-    <Compile Include="Forms\ScenePropertiesForm.cs">
-      <SubType>Form</SubType>
-    </Compile>
-    <Compile Include="Forms\ScenePropertiesForm.Designer.cs">
-      <DependentUpon>ScenePropertiesForm.cs</DependentUpon>
-    </Compile>
-    <Compile Include="Tools\Tools.cs" />
-    <Compile Include="Forms\Vector3Control.cs">
-      <SubType>UserControl</SubType>
-    </Compile>
-    <Compile Include="Forms\Vector3Control.Designer.cs">
-      <DependentUpon>Vector3Control.cs</DependentUpon>
-    </Compile>
-    <Compile Include="Tools\VNormal.cs" />
-    <Compile Include="Tools\WebServer.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <Content Include="Refs\Autodesk.Max.dll" />
-    <Content Include="Refs\BabylonFileConverter.dll" />
-  </ItemGroup>
-  <ItemGroup>
-    <EmbeddedResource Include="Forms\LightPropertiesForm.resx">
-      <DependentUpon>LightPropertiesForm.cs</DependentUpon>
-    </EmbeddedResource>
-    <EmbeddedResource Include="Forms\CameraPropertiesForm.resx">
-      <DependentUpon>CameraPropertiesForm.cs</DependentUpon>
-    </EmbeddedResource>
-    <EmbeddedResource Include="Forms\ExporterForm.resx">
-      <DependentUpon>ExporterForm.cs</DependentUpon>
-    </EmbeddedResource>
-    <EmbeddedResource Include="Forms\ObjectPropertiesForm.resx">
-      <DependentUpon>ObjectPropertiesForm.cs</DependentUpon>
-    </EmbeddedResource>
-    <EmbeddedResource Include="Properties\Resources.resx">
-      <Generator>ResXFileCodeGenerator</Generator>
-      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
-    </EmbeddedResource>
-    <EmbeddedResource Include="Forms\ScenePropertiesForm.resx">
-      <DependentUpon>ScenePropertiesForm.cs</DependentUpon>
-    </EmbeddedResource>
-    <EmbeddedResource Include="Forms\Vector3Control.resx">
-      <DependentUpon>Vector3Control.cs</DependentUpon>
-    </EmbeddedResource>
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\BabylonExport.Entities\BabylonExport.Entities.csproj">
-      <Project>{6150965a-658c-4263-89ad-4f980eb0675d}</Project>
-      <Name>BabylonExport.Entities</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="packages.config" />
-  </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <Import Project="..\packages\SharpDX.2.6.3\build\SharpDX.targets" Condition="Exists('..\packages\SharpDX.2.6.3\build\SharpDX.targets')" />
-  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
-    <PropertyGroup>
-      <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
-    </PropertyGroup>
-    <Error Condition="!Exists('..\packages\SharpDX.2.6.3\build\SharpDX.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\SharpDX.2.6.3\build\SharpDX.targets'))" />
-  </Target>
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{DD7C931A-8FAF-4318-BB74-71DC858CC489}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Max2Babylon</RootNamespace>
+    <AssemblyName>Max2Babylon</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <TargetFrameworkProfile />
+    <SccProjectName>SAK</SccProjectName>
+    <SccLocalPath>SAK</SccLocalPath>
+    <SccAuxPath>SAK</SccAuxPath>
+    <SccProvider>SAK</SccProvider>
+    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
+    <RestorePackages>true</RestorePackages>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>c:\Program Files\Autodesk\3ds Max 2013\bin\assemblies\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Prefer32Bit>false</Prefer32Bit>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>C:\Program Files\Autodesk\3ds Max 2013\bin\assemblies\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Prefer32Bit>false</Prefer32Bit>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Autodesk.Max, Version=15.6.164.0, Culture=neutral, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>Refs\Autodesk.Max.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="Newtonsoft.Json">
+      <HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="SharpDX">
+      <HintPath>..\packages\SharpDX.3.1.1\lib\net45\SharpDX.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="SharpDX.Mathematics">
+      <HintPath>..\packages\SharpDX.Mathematics.3.1.1\lib\net45\SharpDX.Mathematics.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Runtime.Serialization" />
+    <Reference Include="System.Web" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="BabylonActionCallback.cs" />
+    <Compile Include="Exporter\ActionBuilder\BabylonActionsBuilderActionItem.cs" />
+    <Compile Include="BabylonPropertiesActionItem.cs" />
+    <Compile Include="Exporter\ActionBuilder\BabylonExporter.Action.cs" />
+    <Compile Include="Exporter\BabylonExporter.Skeleton.cs" />
+    <Compile Include="Forms\ActionsBuilderForm.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="Forms\ActionsBuilderForm.Designer.cs">
+      <DependentUpon>ActionsBuilderForm.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Forms\LightPropertiesForm.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="Forms\LightPropertiesForm.Designer.cs">
+      <DependentUpon>LightPropertiesForm.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Exporter\BabylonExporter.Animation.cs" />
+    <Compile Include="Exporter\BabylonExporter.ShadowGenerator.cs" />
+    <Compile Include="Forms\CameraPropertiesForm.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="Forms\CameraPropertiesForm.Designer.cs">
+      <DependentUpon>CameraPropertiesForm.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Descriptor.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Forms\ExporterForm.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="Forms\ExporterForm.Designer.cs">
+      <DependentUpon>ExporterForm.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Exporter\BabylonExporter.Texture.cs" />
+    <Compile Include="Exporter\BabylonExporter.Material.cs" />
+    <Compile Include="Exporter\BabylonExporter.Light.cs" />
+    <Compile Include="Exporter\BabylonExporter.cs" />
+    <Compile Include="Exporter\BabylonExporter.Camera.cs" />
+    <Compile Include="Exporter\BabylonExporter.Mesh.cs" />
+    <Compile Include="Exporter\GlobalVertex.cs" />
+    <Compile Include="GlobalUtility.cs" />
+    <Compile Include="JsonTextWriterOptimized.cs" />
+    <Compile Include="Loader.cs" />
+    <Compile Include="BabylonExportActionItem.cs" />
+    <Compile Include="Forms\ObjectPropertiesForm.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="Forms\ObjectPropertiesForm.Designer.cs">
+      <DependentUpon>ObjectPropertiesForm.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Properties\Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>Resources.resx</DependentUpon>
+    </Compile>
+    <Compile Include="Forms\ScenePropertiesForm.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="Forms\ScenePropertiesForm.Designer.cs">
+      <DependentUpon>ScenePropertiesForm.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Tools\Tools.cs" />
+    <Compile Include="Forms\Vector3Control.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Forms\Vector3Control.Designer.cs">
+      <DependentUpon>Vector3Control.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Tools\VNormal.cs" />
+    <Compile Include="Tools\WebServer.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="Refs\Autodesk.Max.dll" />
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="Forms\ActionsBuilderForm.resx">
+      <DependentUpon>ActionsBuilderForm.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="Forms\LightPropertiesForm.resx">
+      <DependentUpon>LightPropertiesForm.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="Forms\CameraPropertiesForm.resx">
+      <DependentUpon>CameraPropertiesForm.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="Forms\ExporterForm.resx">
+      <DependentUpon>ExporterForm.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="Forms\ObjectPropertiesForm.resx">
+      <DependentUpon>ObjectPropertiesForm.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="Properties\Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+    </EmbeddedResource>
+    <EmbeddedResource Include="Forms\ScenePropertiesForm.resx">
+      <DependentUpon>ScenePropertiesForm.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="Forms\Vector3Control.resx">
+      <DependentUpon>Vector3Control.cs</DependentUpon>
+    </EmbeddedResource>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\BabylonExport.Entities\BabylonExport.Entities.csproj">
+      <Project>{6150965a-658c-4263-89ad-4f980eb0675d}</Project>
+      <Name>BabylonExport.Entities</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\BabylonFileConverter\BabylonFileConverter.csproj">
+      <Project>{a6b76356-1d1c-4c82-8199-a6406da85a95}</Project>
+      <Name>BabylonFileConverter</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup>
+    <PostBuildEvent>mkdir "$(OutDir)BabylonActionsBuilder"
+mkdir "$(OutDir)BabylonActionsBuilder\fonts"
+mkdir "$(OutDir)BabylonActionsBuilder\fonts\SinkinSans"
+copy "$(SolutionDir)ActionsBuilder\Sources\fonts.css" "$(OutDir)BabylonActionsBuilder\fonts.css"
+copy "$(SolutionDir)ActionsBuilder\Sources\index.css" "$(OutDir)BabylonActionsBuilder\index.css"
+copy "$(SolutionDir)ActionsBuilder\Sources\index.html" "$(OutDir)BabylonActionsBuilder\index.html"
+copy "$(SolutionDir)ActionsBuilder\Sources\actionsbuilder.max.js" "$(OutDir)BabylonActionsBuilder\actionsbuilder.max.js"
+copy "$(SolutionDir)ActionsBuilder\Sources\raphael.js" "$(OutDir)BabylonActionsBuilder\raphael.js"
+copy "$(SolutionDir)babylon.max.js" "$(OutDir)BabylonActionsBuilder\babylon.max.js"
+copy "$(SolutionDir)ActionsBuilder\Sources\fonts\SinkinSans\" "$(OutDir)BabylonActionsBuilder\fonts\SinkinSans\"</PostBuildEvent>
+  </PropertyGroup>
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
 </Project>

+ 36 - 36
Exporters/3ds Max/Max2Babylon/Properties/AssemblyInfo.cs

@@ -1,36 +1,36 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following 
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("Max2Babylon")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Max2Babylon")]
-[assembly: AssemblyCopyright("Copyright ©  2014")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible 
-// to COM components.  If you need to access a type in this assembly from 
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("2d621b1c-3661-49bd-8dd3-4c5de51fce94")]
-
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version 
-//      Build Number
-//      Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers 
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Max2Babylon")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Max2Babylon")]
+[assembly: AssemblyCopyright("Copyright ©  2014")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("2d621b1c-3661-49bd-8dd3-4c5de51fce94")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 63 - 63
Exporters/3ds Max/Max2Babylon/Properties/Resources.Designer.cs

@@ -1,63 +1,63 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated by a tool.
-//     Runtime Version:4.0.30319.34014
-//
-//     Changes to this file may cause incorrect behavior and will be lost if
-//     the code is regenerated.
-// </auto-generated>
-//------------------------------------------------------------------------------
-
-namespace Max2Babylon.Properties {
-    using System;
-    
-    
-    /// <summary>
-    ///   A strongly-typed resource class, for looking up localized strings, etc.
-    /// </summary>
-    // This class was auto-generated by the StronglyTypedResourceBuilder
-    // class via a tool like ResGen or Visual Studio.
-    // To add or remove a member, edit your .ResX file then rerun ResGen
-    // with the /str option, or rebuild your VS project.
-    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
-    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
-    internal class Resources {
-        
-        private static global::System.Resources.ResourceManager resourceMan;
-        
-        private static global::System.Globalization.CultureInfo resourceCulture;
-        
-        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
-        internal Resources() {
-        }
-        
-        /// <summary>
-        ///   Returns the cached ResourceManager instance used by this class.
-        /// </summary>
-        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
-        internal static global::System.Resources.ResourceManager ResourceManager {
-            get {
-                if (object.ReferenceEquals(resourceMan, null)) {
-                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Max2Babylon.Properties.Resources", typeof(Resources).Assembly);
-                    resourceMan = temp;
-                }
-                return resourceMan;
-            }
-        }
-        
-        /// <summary>
-        ///   Overrides the current thread's CurrentUICulture property for all
-        ///   resource lookups using this strongly typed resource class.
-        /// </summary>
-        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
-        internal static global::System.Globalization.CultureInfo Culture {
-            get {
-                return resourceCulture;
-            }
-            set {
-                resourceCulture = value;
-            }
-        }
-    }
-}
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.34014
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Max2Babylon.Properties {
+    using System;
+    
+    
+    /// <summary>
+    ///   A strongly-typed resource class, for looking up localized strings, etc.
+    /// </summary>
+    // This class was auto-generated by the StronglyTypedResourceBuilder
+    // class via a tool like ResGen or Visual Studio.
+    // To add or remove a member, edit your .ResX file then rerun ResGen
+    // with the /str option, or rebuild your VS project.
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources() {
+        }
+        
+        /// <summary>
+        ///   Returns the cached ResourceManager instance used by this class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if (object.ReferenceEquals(resourceMan, null)) {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Max2Babylon.Properties.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+        
+        /// <summary>
+        ///   Overrides the current thread's CurrentUICulture property for all
+        ///   resource lookups using this strongly typed resource class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+    }
+}

+ 119 - 119
Exporters/3ds Max/Max2Babylon/Properties/Resources.resx

@@ -1,120 +1,120 @@
-<?xml version="1.0" encoding="utf-8"?>
-<root>
-  <!-- 
-    Microsoft ResX Schema 
-    
-    Version 2.0
-    
-    The primary goals of this format is to allow a simple XML format 
-    that is mostly human readable. The generation and parsing of the 
-    various data types are done through the TypeConverter classes 
-    associated with the data types.
-    
-    Example:
-    
-    ... ado.net/XML headers & schema ...
-    <resheader name="resmimetype">text/microsoft-resx</resheader>
-    <resheader name="version">2.0</resheader>
-    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
-    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
-    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
-    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
-    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
-        <value>[base64 mime encoded serialized .NET Framework object]</value>
-    </data>
-    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
-        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
-        <comment>This is a comment</comment>
-    </data>
-                
-    There are any number of "resheader" rows that contain simple 
-    name/value pairs.
-    
-    Each data row contains a name, and value. The row also contains a 
-    type or mimetype. Type corresponds to a .NET class that support 
-    text/value conversion through the TypeConverter architecture. 
-    Classes that don't support this are serialized and stored with the 
-    mimetype set.
-    
-    The mimetype is used for serialized objects, and tells the 
-    ResXResourceReader how to depersist the object. This is currently not 
-    extensible. For a given mimetype the value must be set accordingly:
-    
-    Note - application/x-microsoft.net.object.binary.base64 is the format 
-    that the ResXResourceWriter will generate, however the reader can 
-    read any of the formats listed below.
-    
-    mimetype: application/x-microsoft.net.object.binary.base64
-    value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
-            : and then encoded with base64 encoding.
-    
-    mimetype: application/x-microsoft.net.object.soap.base64
-    value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
-            : and then encoded with base64 encoding.
-
-    mimetype: application/x-microsoft.net.object.bytearray.base64
-    value   : The object must be serialized into a byte array 
-            : using a System.ComponentModel.TypeConverter
-            : and then encoded with base64 encoding.
-    -->
-  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
-    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
-    <xsd:element name="root" msdata:IsDataSet="true">
-      <xsd:complexType>
-        <xsd:choice maxOccurs="unbounded">
-          <xsd:element name="metadata">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" />
-              </xsd:sequence>
-              <xsd:attribute name="name" use="required" type="xsd:string" />
-              <xsd:attribute name="type" type="xsd:string" />
-              <xsd:attribute name="mimetype" type="xsd:string" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="assembly">
-            <xsd:complexType>
-              <xsd:attribute name="alias" type="xsd:string" />
-              <xsd:attribute name="name" type="xsd:string" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="data">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
-              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
-              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="resheader">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" />
-            </xsd:complexType>
-          </xsd:element>
-        </xsd:choice>
-      </xsd:complexType>
-    </xsd:element>
-  </xsd:schema>
-  <resheader name="resmimetype">
-    <value>text/microsoft-resx</value>
-  </resheader>
-  <resheader name="version">
-    <value>2.0</value>
-  </resheader>
-  <resheader name="reader">
-    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-  <resheader name="writer">
-    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
 </root>

BIN
Exporters/3ds Max/Max2Babylon/Refs/BabylonFileConverter.dll


BIN
Exporters/3ds Max/Max2Babylon/Refs/Newtonsoft.Json.dll


BIN
Exporters/3ds Max/Max2Babylon/Refs/SharpDX.dll


+ 1 - 0
Exporters/3ds Max/Max2Babylon/Tools/WebServer.cs

@@ -21,6 +21,7 @@ namespace Max2Babylon
     <script type='text/javascript' src='http://www.babylonjs.com/oimo.js'></script>
     <script type='text/javascript' src='http://www.babylonjs.com/cannon.js'></script>
     <script type='text/javascript' src='http://www.babylonjs.com/babylon.js'></script>
+    <script type='text/javascript' src='http://www.babylonjs.com/babylon.inspector.bundle.js'></script>
     <style type='text/css'>
         html, body, div, canvas {
             width: 100%;

+ 5 - 3
Exporters/3ds Max/Max2Babylon/packages.config

@@ -1,4 +1,6 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="Newtonsoft.Json" version="6.0.7" targetFramework="net45" />
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
+  <package id="SharpDX" version="3.1.1" targetFramework="net45" />
+  <package id="SharpDX.Mathematics" version="3.1.1" targetFramework="net45" />
 </packages>

BIN
Exporters/3ds Max/Refs/Autodesk.Max.dll


File diff suppressed because it is too large
+ 8 - 8
dist/preview release/babylon.core.js


File diff suppressed because it is too large
+ 3251 - 3054
dist/preview release/babylon.d.ts


File diff suppressed because it is too large
+ 9 - 9
dist/preview release/babylon.js


File diff suppressed because it is too large
+ 208 - 9
dist/preview release/babylon.max.js


File diff suppressed because it is too large
+ 14868 - 0
dist/preview release/babylon.module.d.ts


File diff suppressed because it is too large
+ 8 - 8
dist/preview release/babylon.noworker.js