Quellcode durchsuchen

Moving to beta
First release of Unity 5 exporter

David Catuhe vor 10 Jahren
Ursprung
Commit
c54ced8cd0

+ 10 - 1
Babylon/Cameras/babylon.followCamera.js

@@ -22,7 +22,16 @@ var BABYLON;
         FollowCamera.prototype.follow = function (cameraTarget) {
             if (!cameraTarget)
                 return;
-            var radians = this.getRadians(this.rotationOffset) + cameraTarget.rotation.y;
+            var yRotation;
+            if (cameraTarget.rotationQuaternion) {
+                var rotMatrix = new BABYLON.Matrix();
+                cameraTarget.rotationQuaternion.toRotationMatrix(rotMatrix);
+                yRotation = Math.atan2(rotMatrix.m[8], rotMatrix.m[10]);
+            }
+            else {
+                yRotation = cameraTarget.rotation.y;
+            }
+            var radians = this.getRadians(this.rotationOffset) + yRotation;
             var targetX = cameraTarget.position.x + Math.sin(radians) * this.radius;
             var targetZ = cameraTarget.position.z + Math.cos(radians) * this.radius;
             var dx = targetX - this.position.x;

+ 1 - 1
Babylon/Cameras/babylon.followCamera.ts

@@ -60,4 +60,4 @@
             this.follow(this.target);
         }
     }
-} 
+} 

BIN
Exporters/Unity 5/Unity3D2Babylon/BabylonExport.Entities.dll


+ 23 - 0
Exporters/Unity 5/Unity3D2Babylon/ExportationOptions.cs

@@ -0,0 +1,23 @@
+using System;
+using UnityEngine;
+
+namespace Unity3D2Babylon
+{
+    public class ExportationOptions
+    {
+        public string DefaultFolder { get; set; }
+        public float ReflectionDefaultLevel { get; set; }
+        public bool ExportCollisions { get; set; }
+        public SerializableVector3 CameraEllipsoid { get; set; }
+        public SerializableVector3 Gravity { get; set; }
+
+        public ExportationOptions()
+        {
+            DefaultFolder = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
+            ReflectionDefaultLevel = 0.3f;
+            ExportCollisions = false;
+            CameraEllipsoid = new Vector3(0.5f, 1.0f, 0.5f);
+            Gravity = new Vector3(0, -0.9f, 0);
+        }
+    }
+}

+ 137 - 0
Exporters/Unity 5/Unity3D2Babylon/ExporterWindow.cs

@@ -0,0 +1,137 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using JsonFx;
+using UnityEditor;
+using UnityEngine;
+using JsonFx.Json;
+
+namespace Unity3D2Babylon
+{
+    public class ExporterWindow : EditorWindow
+    {
+        private static readonly List<string> logs = new List<string>();
+        Vector2 scrollPos;
+
+        ExportationOptions exportationOptions;
+
+        public static void ReportProgress(float value, string message = "")
+        {
+            EditorUtility.DisplayProgressBar("Babylon.js", message, value);
+
+            if (!string.IsNullOrEmpty(message))
+            {
+                logs.Add(message);
+            }
+        }
+
+        public static void ShowMessage(string message, string title = "Babylon.js")
+        {
+            EditorUtility.DisplayDialog(title, message, "OK");
+        }
+
+        [MenuItem("BabylonJS/Export to .babylon")]
+        public static void Init()
+        {
+            var window = (ExporterWindow)GetWindow(typeof(ExporterWindow));
+            window.Initialize();
+        }
+
+        void Initialize()
+        {
+            title = "Babylon.js";
+        }
+
+        void OnGUI()
+        {
+            if (exportationOptions == null)
+            {
+                exportationOptions = new ExportationOptions();
+
+                if (File.Exists("Unity3D2Babylon.ini"))
+                {
+                    var readText = File.ReadAllText("Unity3D2Babylon.ini");
+                    var jsReader = new JsonReader();
+                    exportationOptions = jsReader.Read<ExportationOptions>(readText);
+                }
+            }
+
+            GUILayout.Label("Exportation options", EditorStyles.boldLabel);
+            exportationOptions.ReflectionDefaultLevel = EditorGUILayout.Slider("Reflection default level", exportationOptions.ReflectionDefaultLevel, 0, 1.0f);
+
+            GUILayout.Label("Collisions options", EditorStyles.boldLabel);
+            exportationOptions.ExportCollisions = EditorGUILayout.Toggle("Collisions", exportationOptions.ExportCollisions);
+            exportationOptions.CameraEllipsoid = EditorGUILayout.Vector3Field("Camera's Ellipsoid:", exportationOptions.CameraEllipsoid);
+            exportationOptions.Gravity = EditorGUILayout.Vector3Field("Gravity:", exportationOptions.Gravity);
+
+            EditorGUILayout.Space();
+            EditorGUILayout.Space();
+
+            if (GUILayout.Button("Export"))
+            {
+                Export();
+            }
+
+            EditorGUILayout.Space();
+
+            scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
+
+            foreach (var log in logs)
+            {
+                var bold = log.StartsWith("*");
+
+                GUILayout.Label(bold ? log.Remove(0, 1) : log, bold ? (EditorStyles.boldLabel) : EditorStyles.label);
+            }
+            EditorGUILayout.EndScrollView();
+
+            Repaint();
+        }
+
+        public void Export()
+        {
+            try
+            {
+                int pos = EditorApplication.currentScene.LastIndexOf("/", StringComparison.Ordinal);
+                string sceneName = EditorApplication.currentScene.Substring(pos + 1);
+
+                exportationOptions.DefaultFolder = EditorUtility.SaveFolderPanel("Please select a folder", exportationOptions.DefaultFolder, "");
+
+                if (string.IsNullOrEmpty(exportationOptions.DefaultFolder))
+                {
+                    return;
+                }
+
+                Stopwatch watch = new Stopwatch();
+
+                watch.Start();
+
+                var jsWriter = new JsonWriter();                
+                File.WriteAllText("Unity3D2Babylon.ini", jsWriter.Write(exportationOptions));
+                logs.Clear();
+
+                ReportProgress(0);
+
+                var sceneBuilder = new SceneBuilder(exportationOptions.DefaultFolder, sceneName, exportationOptions);
+
+                sceneBuilder.ConvertFromUnity();
+
+                ReportProgress(1, "Generating output file");
+                sceneBuilder.WriteToBabylonFile();
+
+                watch.Stop();
+                ReportProgress(1, string.Format("Exportation done in {0:0.00}s", watch.Elapsed.TotalSeconds));
+                EditorUtility.ClearProgressBar();
+
+                sceneBuilder.GenerateStatus(logs);
+
+                ShowMessage("Exportation done");
+            }
+            catch (Exception ex)
+            {
+                EditorUtility.ClearProgressBar();
+                ShowMessage("A problem occurred: " + ex.Message + ex.StackTrace, "Error");
+            }
+        }
+    }
+}

BIN
Exporters/Unity 5/Unity3D2Babylon/Ionic.Zip.dll


BIN
Exporters/Unity 5/Unity3D2Babylon/JsonFx.Json.dll


BIN
Exporters/Unity 5/Unity3D2Babylon/JsonFx.dll


+ 143 - 0
Exporters/Unity 5/Unity3D2Babylon/SceneBuilder.Animations.cs

@@ -0,0 +1,143 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using BabylonExport.Entities;
+using UnityEditor;
+using UnityEditor.Animations;
+using UnityEngine;
+
+namespace Unity3D2Babylon
+{
+    partial class SceneBuilder
+    {
+        private static void ExportAnimations(Transform transform, BabylonIAnimatable animatable)
+        {
+            var animator = transform.gameObject.GetComponent<Animator>();
+            if (animator != null)
+            {
+                AnimatorController ac = animator.runtimeAnimatorController as AnimatorController;
+                if (ac == null)
+                {
+                    return;
+                }
+                var layer = ac.layers[0];
+                if (layer == null)
+                {
+                    return;
+                }
+                AnimatorStateMachine sm = layer.stateMachine;
+                if (sm.states.Length > 0)
+                {
+                    var state = sm.states[0].state; // We only support the first one
+                    AnimationClip clip = state.motion as AnimationClip;
+                    if (clip != null)
+                    {
+                        ExportAnimationClip(clip, true, animatable);
+                    }
+                }
+            }
+            else
+            {
+                var animation = transform.gameObject.GetComponent<Animation>();
+                if (animation != null && animation.clip != null)
+                {
+                    ExportAnimationClip(animation.clip, animation.playAutomatically, animatable);
+                }
+            }
+        }
+
+        private static bool IsRotationQuaternionAnimated(BabylonIAnimatable animatable)
+        {
+            if (animatable.animations == null)
+            {
+                return false;
+            }
+
+            return animatable.animations.Any(animation => animation.property.Contains("rotationQuaternion"));
+        }
+
+        private static void ExportAnimationClip(AnimationClip clip, bool autoPlay, BabylonIAnimatable animatable)
+        {
+            var curveBindings = AnimationUtility.GetCurveBindings(clip);
+
+            var animations = new List<BabylonAnimation>();
+
+            var maxFrame = 0;
+
+            foreach (var binding in curveBindings)
+            {
+                var curve = AnimationUtility.GetEditorCurve(clip, binding);
+                string property;
+
+                switch (binding.propertyName)
+                {
+                    case "m_LocalPosition.x":
+                        property = "position.x";
+                        break;
+                    case "m_LocalPosition.y":
+                        property = "position.y";
+                        break;
+                    case "m_LocalPosition.z":
+                        property = "position.z";
+                        break;
+
+                    case "m_LocalRotation.x":
+                        property = "rotationQuaternion.x";
+                        break;
+                    case "m_LocalRotation.y":
+                        property = "rotationQuaternion.y";
+                        break;
+                    case "m_LocalRotation.z":
+                        property = "rotationQuaternion.z";
+                        break;
+                    case "m_LocalRotation.w":
+                        property = "rotationQuaternion.w";
+                        break;
+
+                    case "m_LocalScale.x":
+                        property = "scaling.x";
+                        break;
+                    case "m_LocalScale.y":
+                        property = "scaling.y";
+                        break;
+                    case "m_LocalScale.z":
+                        property = "scaling.z";
+                        break;
+                    default:
+                        continue;
+                }
+
+                var babylonAnimation = new BabylonAnimation
+                {
+                    dataType = (int)BabylonAnimation.DataType.Float,
+                    name = property + " animation",
+                    keys = curve.keys.Select(keyFrame => new BabylonAnimationKey
+                    {
+                        frame = (int)(keyFrame.time * clip.frameRate),
+                        values = new[] { keyFrame.value }
+                    }).ToArray(),
+                    framePerSecond = (int)clip.frameRate,
+                    loopBehavior = (int)BabylonAnimation.LoopBehavior.Cycle,
+                    property = property
+                };
+
+                maxFrame = Math.Max(babylonAnimation.keys.Last().frame, maxFrame);
+
+                animations.Add(babylonAnimation);
+            }
+
+            if (animations.Count > 0)
+            {
+                animatable.animations = animations.ToArray();
+                if (autoPlay)
+                {
+                    animatable.autoAnimate = true;
+                    animatable.autoAnimateFrom = 0;
+                    animatable.autoAnimateTo = maxFrame;
+                    animatable.autoAnimateLoop = clip.isLooping;
+                }
+            }
+        }
+    }
+}

+ 48 - 0
Exporters/Unity 5/Unity3D2Babylon/SceneBuilder.Cameras.cs

@@ -0,0 +1,48 @@
+using System;
+using BabylonExport.Entities;
+using UnityEngine;
+
+namespace Unity3D2Babylon
+{
+    partial class SceneBuilder
+    {
+        private void ConvertUnityCameraToBabylon(Camera camera, float progress)
+        {
+            ExporterWindow.ReportProgress(progress, "Exporting camera: " + camera.name);
+
+            BabylonCamera babylonCamera = new BabylonCamera
+            {
+                name = camera.name,
+                id = GetID(camera.gameObject),
+                fov = camera.fieldOfView*(float) Math.PI/180,
+                minZ = camera.nearClipPlane,
+                maxZ = camera.farClipPlane,
+                parentId = GetParentID(camera.transform),
+                position = camera.transform.localPosition.ToFloat()
+            };
+
+            var target = new Vector3(0, 0, 1);
+            var transformedTarget = camera.transform.TransformDirection(target);
+            babylonCamera.target = (camera.transform.position + transformedTarget).ToFloat();
+
+            babylonScene.CamerasList.Add(babylonCamera);
+
+            if (Camera.main == camera)
+            {
+                babylonScene.activeCameraID = babylonCamera.id;
+                babylonScene.clearColor = camera.backgroundColor.ToFloat();
+            }
+
+            // Animations
+            ExportAnimations(camera.transform, babylonCamera);
+
+            // Collisions
+            if (exportationOptions.ExportCollisions)
+            {
+                babylonCamera.checkCollisions = true;
+                babylonCamera.applyGravity = true;
+                babylonCamera.ellipsoid = exportationOptions.CameraEllipsoid.ToFloat();
+            }
+        }
+    }
+}

+ 97 - 0
Exporters/Unity 5/Unity3D2Babylon/SceneBuilder.Lights.cs

@@ -0,0 +1,97 @@
+using System;
+using System.Collections.Generic;
+using BabylonExport.Entities;
+using UnityEngine;
+using UnityEngine.Rendering;
+
+namespace Unity3D2Babylon
+{
+    partial class SceneBuilder
+    {
+        private void GenerateShadowsGenerator(Light light)
+        {
+            var generator = new BabylonShadowGenerator
+            {
+                lightId = GetID(light.gameObject),
+                usePoissonSampling = light.shadows == LightShadows.Soft,
+                mapSize = 256 + 256 * QualitySettings.GetQualityLevel(),
+                bias = light.shadowBias / 10.0f
+            };
+
+            var renderList = new List<string>();
+            foreach (var gameObject in gameObjects)
+            {
+                var meshFilter = gameObject.GetComponent<MeshFilter>();
+                var renderer = gameObject.GetComponent<Renderer>();
+                if (meshFilter != null && renderer.shadowCastingMode != ShadowCastingMode.Off)
+                {
+                    renderList.Add(GetID(gameObject));
+                    continue;
+                }
+
+                var skinnedMesh = gameObject.GetComponent<SkinnedMeshRenderer>();
+                if (skinnedMesh != null && renderer.shadowCastingMode != ShadowCastingMode.Off)
+                {
+                    renderList.Add(GetID(gameObject));
+                }
+            }
+
+            generator.renderList = renderList.ToArray();
+
+            babylonScene.ShadowGeneratorsList.Add(generator);
+        }
+
+        private void ConvertUnityLightToBabylon(Light light, float progress)
+        {
+            ExporterWindow.ReportProgress(progress, "Exporting light: " + light.name);
+
+            BabylonLight babylonLight = new BabylonLight
+            {
+                name = light.name,
+                id = GetID(light.gameObject),
+                parentId = GetParentID(light.transform)
+            };
+            
+            switch (light.type)
+            {
+                case LightType.Spot:
+                    babylonLight.type = 2;
+                    break;
+                case LightType.Directional:
+                    babylonLight.type = 1;
+                    break;
+                case LightType.Point:
+                    babylonLight.type = 0;
+                    babylonLight.range = light.range;
+                    break;
+                case LightType.Area:
+                    // TODO
+                    break;
+            }
+
+            babylonLight.position = light.transform.localPosition.ToFloat();
+
+            var direction = new Vector3(0, 0, 1);
+            var transformedDirection = light.transform.TransformDirection(direction);
+            babylonLight.direction = transformedDirection.ToFloat();
+
+            babylonLight.diffuse = light.color.ToFloat();
+
+            babylonLight.intensity = light.intensity;
+
+            babylonLight.angle = light.spotAngle * (float)Math.PI / 180;
+            babylonLight.exponent = 1.0f;
+
+            babylonScene.LightsList.Add(babylonLight);
+
+            // Animations
+            ExportAnimations(light.transform, babylonLight);
+
+            // Shadows
+            if ((light.type == LightType.Directional || light.type == LightType.Spot) && light.shadows != LightShadows.None)
+            {
+                GenerateShadowsGenerator(light);
+            }
+        }
+    }
+}

+ 284 - 0
Exporters/Unity 5/Unity3D2Babylon/SceneBuilder.Materials.cs

@@ -0,0 +1,284 @@
+using System;
+using System.IO;
+using BabylonExport.Entities;
+using UnityEditor;
+using UnityEngine;
+
+namespace Unity3D2Babylon
+{
+    partial class SceneBuilder
+    {
+        private void CopyTextureCube(string texturePath, Cubemap cubemap, BabylonTexture babylonTexture)
+        {
+            if (!babylonScene.AddTextureCube(texturePath))
+            {
+                return;
+            }
+
+            try
+            {
+                foreach (CubemapFace face in Enum.GetValues(typeof(CubemapFace)))
+                {
+                    var faceTexturePath = Path.Combine(babylonScene.OutputPath, Path.GetFileNameWithoutExtension(texturePath));
+
+                    switch (face)
+                    {
+                        case CubemapFace.PositiveX:
+                            faceTexturePath += "_px.jpg";
+                            break;
+                        case CubemapFace.NegativeX:
+                            faceTexturePath += "_nx.jpg";
+                            break;
+                        case CubemapFace.PositiveY:
+                            faceTexturePath += "_py.jpg";
+                            break;
+                        case CubemapFace.NegativeY:
+                            faceTexturePath += "_ny.jpg";
+                            break;
+                        case CubemapFace.PositiveZ:
+                            faceTexturePath += "_pz.jpg";
+                            break;
+                        case CubemapFace.NegativeZ:
+                            faceTexturePath += "_nz.jpg";
+                            break;
+                    }
+
+                    var tempTexture = new Texture2D(cubemap.width, cubemap.height, cubemap.format, false);
+
+                    tempTexture.SetPixels(cubemap.GetPixels(face));
+                    tempTexture.Apply();
+
+                    File.WriteAllBytes(faceTexturePath, tempTexture.EncodeToJPG());
+                }
+
+            }
+            catch (Exception ex)
+            {
+                Debug.LogException(ex);
+            }
+
+            var textureName = Path.GetFileNameWithoutExtension(texturePath);
+            babylonTexture.name = textureName;
+            babylonTexture.isCube = true;
+            babylonTexture.level = exportationOptions.ReflectionDefaultLevel;
+            babylonTexture.coordinatesMode = 3;
+        }
+
+        private void CopyTexture(string texturePath, Texture2D texture2D, BabylonTexture babylonTexture)
+        {
+            bool needToDelete = false;
+            var useJPG = !texture2D.alphaIsTransparency;
+
+            // Convert unsupported file extensions
+            if (texturePath.EndsWith(".psd") || texturePath.EndsWith(".tif") || texturePath.EndsWith(".exr"))
+            {
+                try
+                {
+                    // Change texture import settings to be able to read texture data
+                    var textureImporter = AssetImporter.GetAtPath(texturePath) as TextureImporter;
+                    var previousIsReadable = textureImporter.isReadable;
+                    var previousNormalMap = textureImporter.normalmap;
+                    var previousLightmap = textureImporter.lightmap;
+                    var previousConvertToNormalmap = textureImporter.convertToNormalmap;
+                    var previousTextureType = textureImporter.textureType;
+                    var previousGrayscaleToAlpha = textureImporter.grayscaleToAlpha;
+                    textureImporter.textureType = TextureImporterType.Advanced;
+                    textureImporter.isReadable = true;
+                    textureImporter.lightmap = false;
+                    textureImporter.normalmap = false;
+                    textureImporter.convertToNormalmap = false;
+                    textureImporter.grayscaleToAlpha = false;
+
+                    AssetDatabase.ImportAsset(texturePath);
+
+                    texturePath = Path.Combine(Path.GetTempPath(), Path.GetFileName(texturePath));
+                    var extension = useJPG ? ".jpg" : ".png";
+                    texturePath = texturePath.Replace(".psd", extension).Replace(".tif", extension).Replace(".exr", extension);
+
+                    var tempTexture = new Texture2D(texture2D.width, texture2D.height, TextureFormat.ARGB32, false);
+
+                    tempTexture.SetPixels32(texture2D.GetPixels32());
+                    tempTexture.Apply();
+
+                    File.WriteAllBytes(texturePath, useJPG ? tempTexture.EncodeToJPG() : tempTexture.EncodeToPNG());
+
+                    needToDelete = true;
+
+                    // Restore
+                    textureImporter.isReadable = previousIsReadable;
+                    textureImporter.normalmap = previousNormalMap;
+                    textureImporter.lightmap = previousLightmap;
+                    textureImporter.convertToNormalmap = previousConvertToNormalmap;
+                    textureImporter.textureType = previousTextureType;
+                    textureImporter.grayscaleToAlpha = previousGrayscaleToAlpha;
+                   
+                    AssetDatabase.ImportAsset(texturePath, ImportAssetOptions.ForceUpdate);
+                }
+                catch (Exception ex)
+                {
+                    Debug.LogException(ex);
+                }
+            }
+
+            var textureName = Path.GetFileName(texturePath);
+            babylonTexture.name = textureName;
+            babylonScene.AddTexture(texturePath);
+
+            if (needToDelete)
+            {
+                File.Delete(texturePath);
+            }
+        }
+
+        private BabylonMaterial DumpMaterial(Material material, Renderer renderer)
+        {
+            if (!materialsDictionary.ContainsKey(material.name))
+            {
+                var bMat = new BabylonMaterial
+                {
+                    name = material.name,
+                    id = Guid.NewGuid().ToString(),
+                    diffuse = new float[4],
+                    specular = new float[4]
+                };
+
+                bMat.diffuse[0] = 1.0f;
+                bMat.diffuse[1] = 1.0f;
+                bMat.diffuse[2] = 1.0f;
+                bMat.diffuse[3] = 1.0f;
+
+                if (material.HasProperty("_Color"))
+                {
+                    bMat.diffuse = material.color.ToFloat();
+                }
+
+                if (material.HasProperty("_SpecColor"))
+                {
+                    var specColor = material.GetColor("_SpecColor");
+                    bMat.specular = specColor.ToFloat();
+                }
+
+                if (material.HasProperty("_Shininess"))
+                {
+                    var specShininess = material.GetFloat("_Shininess");
+                    bMat.specularPower = specShininess * 128;
+                }
+
+                if (material.HasProperty("_Emission"))
+                {
+                    var emissiveColor = material.GetColor("_Emission");
+                    bMat.emissive = emissiveColor.ToFloat();
+                }
+
+                if (material.mainTexture)
+                {
+                    var mainTexturePath = AssetDatabase.GetAssetPath(material.mainTexture);
+                    bMat.diffuseTexture = new BabylonTexture
+                    {
+                        uScale = material.mainTextureScale.x,
+                        vScale = material.mainTextureScale.y,
+                        uOffset = material.mainTextureOffset.x,
+                        vOffset = material.mainTextureOffset.y
+                    };
+
+                    var mainTexture2D = material.mainTexture as Texture2D;
+
+                    CopyTexture(mainTexturePath, mainTexture2D, bMat.diffuseTexture);
+
+                    var alphaCuttOff = 0f;
+
+                    if (material.HasProperty("_Cutoff"))
+                    {
+                        alphaCuttOff = material.GetFloat("_Cutoff");
+                    }
+
+                    if ((mainTexture2D && mainTexture2D.alphaIsTransparency) || alphaCuttOff > 0)
+                    {
+                        bMat.diffuseTexture.hasAlpha = true;
+                        bMat.backFaceCulling = false;
+                    }
+
+                    bMat.diffuse[0] = 1.0f;
+                    bMat.diffuse[1] = 1.0f;
+                    bMat.diffuse[2] = 1.0f;
+                    bMat.diffuse[3] = 1.0f;
+                }
+
+                bMat.bumpTexture = DumpTextureFromMaterial(material, "_BumpMap");
+                bMat.emissiveTexture = DumpTextureFromMaterial(material, "_Illum");
+                bMat.ambientTexture = DumpTextureFromMaterial(material, "_LightMap");
+                bMat.reflectionTexture = DumpTextureFromMaterial(material, "_Cube");
+
+                //if (bMat.ambientTexture == null && renderer.lightmapIndex >= 0 && renderer.lightmapIndex != 255 && LightmapSettings.lightmaps.Length > renderer.lightmapIndex)
+                //{
+                //    var lightmap = LightmapSettings.lightmaps[renderer.lightmapIndex].lightmapFar;
+                //    bMat.ambientTexture = DumpTexture(lightmap);
+                //    bMat.ambientTexture.coordinatesIndex = 1;
+
+                //    bMat.ambientTexture.uScale = renderer.lightmapTilingOffset.x;
+                //    bMat.ambientTexture.vScale = renderer.lightmapTilingOffset.y;
+
+                //    bMat.ambientTexture.uOffset = renderer.lightmapTilingOffset.z;
+                //    bMat.ambientTexture.vOffset = renderer.lightmapTilingOffset.w;
+                //}
+
+                materialsDictionary.Add(bMat.name, bMat);
+                return bMat;
+            }
+
+            return materialsDictionary[material.name];
+        }
+
+        private BabylonTexture DumpTextureFromMaterial(Material material, string name)
+        {
+            if (!material.HasProperty(name))
+            {
+                return null;
+            }
+
+            var texture = material.GetTexture(name);
+            return DumpTexture(texture, material, name);
+        }
+
+        private BabylonTexture DumpTexture(Texture texture, Material material = null, string name = "")
+        {
+            if (texture == null)
+            {
+                return null;
+            }
+            var texturePath = AssetDatabase.GetAssetPath(texture);
+            var textureName = Path.GetFileName(texturePath);
+            var babylonTexture = new BabylonTexture { name = textureName };
+
+            if (material != null)
+            {
+                var textureScale = material.GetTextureScale(name);
+                babylonTexture.uScale = textureScale.x;
+                babylonTexture.vScale = textureScale.y;
+
+                var textureOffset = material.GetTextureOffset(name);
+                babylonTexture.uOffset = textureOffset.x;
+                babylonTexture.vOffset = textureOffset.y;
+            }
+
+            var texture2D = texture as Texture2D;
+
+            if (texture2D)
+            {
+                babylonTexture.hasAlpha = texture2D.alphaIsTransparency;
+
+                CopyTexture(texturePath, texture2D, babylonTexture);
+            }
+            else
+            {
+                var cubemap = texture as Cubemap;
+                if (cubemap != null)
+                {
+                    CopyTextureCube(texturePath, cubemap, babylonTexture);
+                }
+            }
+
+            return babylonTexture;
+        }
+    }
+}

+ 208 - 0
Exporters/Unity 5/Unity3D2Babylon/SceneBuilder.Meshes.cs

@@ -0,0 +1,208 @@
+using System;
+using BabylonExport.Entities;
+using UnityEngine;
+
+namespace Unity3D2Babylon
+{
+    partial class SceneBuilder
+    {
+        private void ConvertUnityEmptyObjectToBabylon(GameObject gameObject)
+        {
+            BabylonMesh babylonMesh = new BabylonMesh { name = gameObject.name, id = GetID(gameObject) };
+
+            var transform = gameObject.transform;
+
+            babylonMesh.parentId = GetParentID(transform);
+
+            babylonMesh.position = transform.localPosition.ToFloat();
+
+            babylonMesh.rotation = new float[3];
+            babylonMesh.rotation[0] = transform.localRotation.eulerAngles.x * (float)Math.PI / 180;
+            babylonMesh.rotation[1] = transform.localRotation.eulerAngles.y * (float)Math.PI / 180;
+            babylonMesh.rotation[2] = transform.localRotation.eulerAngles.z * (float)Math.PI / 180;
+
+            babylonMesh.scaling = transform.localScale.ToFloat();
+
+            babylonScene.MeshesList.Add(babylonMesh);
+
+            // Animations
+            ExportAnimations(transform, babylonMesh);
+
+            if (IsRotationQuaternionAnimated(babylonMesh))
+            {
+                babylonMesh.rotationQuaternion = transform.localRotation.ToFloat();
+            }
+        }
+
+        private void ConvertUnityMeshToBabylon(Mesh mesh, Transform transform, GameObject gameObject, float progress)
+        {
+            BabylonMesh babylonMesh = new BabylonMesh();
+            var renderer = gameObject.GetComponent<Renderer>();
+
+            ExporterWindow.ReportProgress(progress, "Exporting mesh: " + mesh.name);
+
+            babylonMesh.name = mesh.name;
+            babylonMesh.id = GetID(transform.gameObject);
+            babylonMesh.receiveShadows = renderer.receiveShadows;
+
+            babylonMesh.parentId = GetParentID(transform);
+
+            babylonMesh.position = transform.localPosition.ToFloat();
+
+            babylonMesh.rotation = new float[3];
+            babylonMesh.rotation[0] = transform.localRotation.eulerAngles.x * (float)Math.PI / 180;
+            babylonMesh.rotation[1] = transform.localRotation.eulerAngles.y * (float)Math.PI / 180;
+            babylonMesh.rotation[2] = transform.localRotation.eulerAngles.z * (float)Math.PI / 180;
+
+            babylonMesh.scaling = transform.localScale.ToFloat();
+
+            babylonMesh.positions = new float[mesh.vertexCount * 3];
+
+            for (int i = 0; i < mesh.vertices.Length; i++)
+            {
+                babylonMesh.positions[i * 3] = mesh.vertices[i].x;
+                babylonMesh.positions[(i * 3) + 1] = mesh.vertices[i].y;
+                babylonMesh.positions[(i * 3) + 2] = mesh.vertices[i].z;
+
+                // Computing world extends
+                var worldPosition = transform.TransformPoint(mesh.vertices[i]);
+
+                if (worldPosition.x > babylonScene.MaxVector.X)
+                {
+                    babylonScene.MaxVector.X = worldPosition.x;
+                }
+                if (worldPosition.y > babylonScene.MaxVector.Y)
+                {
+                    babylonScene.MaxVector.Y = worldPosition.y;
+                }
+                if (worldPosition.z > babylonScene.MaxVector.Z)
+                {
+                    babylonScene.MaxVector.Z = worldPosition.z;
+                }
+
+                if (worldPosition.x < babylonScene.MinVector.X)
+                {
+                    babylonScene.MinVector.X = worldPosition.x;
+                }
+                if (worldPosition.y < babylonScene.MinVector.Y)
+                {
+                    babylonScene.MinVector.Y = worldPosition.y;
+                }
+                if (worldPosition.z < babylonScene.MinVector.Z)
+                {
+                    babylonScene.MinVector.Z = worldPosition.z;
+                }
+            }
+
+            babylonMesh.normals = new float[mesh.vertexCount * 3];
+
+            for (int i = 0; i < mesh.normals.Length; i++)
+            {
+                babylonMesh.normals[i * 3] = mesh.normals[i].x;
+                babylonMesh.normals[(i * 3) + 1] = mesh.normals[i].y;
+                babylonMesh.normals[(i * 3) + 2] = mesh.normals[i].z;
+            }
+
+            babylonMesh.uvs = new float[mesh.vertexCount * 2];
+
+            for (int i = 0; i < mesh.uv.Length; i++)
+            {
+                babylonMesh.uvs[i * 2] = mesh.uv[i].x;
+                babylonMesh.uvs[(i * 2) + 1] = mesh.uv[i].y;
+            }
+
+            if (mesh.uv2 != null)
+            {
+                babylonMesh.uvs2 = new float[mesh.vertexCount * 2];
+
+                for (int i = 0; i < mesh.uv2.Length; i++)
+                {
+                    babylonMesh.uvs2[i * 2] = mesh.uv2[i].x;
+                    babylonMesh.uvs2[(i * 2) + 1] = mesh.uv2[i].y;
+                }
+            }
+
+            babylonMesh.indices = new int[mesh.triangles.Length];
+
+            for (int i = 0; i < mesh.triangles.Length; i += 3)
+            {
+                babylonMesh.indices[i] = mesh.triangles[i + 2];
+                babylonMesh.indices[i + 1] = mesh.triangles[i + 1];
+                babylonMesh.indices[i + 2] = mesh.triangles[i];
+            }
+
+            if (mesh.subMeshCount > 1) // Multimaterials
+            {
+                BabylonMultiMaterial bMultiMat;
+                if (!multiMatDictionary.ContainsKey(renderer.sharedMaterial.name))
+                {
+                    bMultiMat = new BabylonMultiMaterial
+                    {
+                        materials = new string[mesh.subMeshCount],
+                        id = Guid.NewGuid().ToString(),
+                        name = renderer.sharedMaterial.name
+                    };
+
+                    for (int i = 0; i < renderer.sharedMaterials.Length; i++)
+                    {
+                        var bMat = DumpMaterial(renderer.sharedMaterials[i], renderer);
+                        bMultiMat.materials[i] = bMat.id;
+                    }
+                    if (mesh.subMeshCount > 1)
+                    {
+                        multiMatDictionary.Add(bMultiMat.name, bMultiMat);
+                    }
+                }
+                else
+                {
+                    bMultiMat = multiMatDictionary[renderer.sharedMaterial.name];
+                }
+
+                babylonMesh.materialId = bMultiMat.id;
+                babylonMesh.subMeshes = new BabylonSubMesh[mesh.subMeshCount];
+
+                var offset = 0;
+                for (int materialIndex = 0; materialIndex < mesh.subMeshCount; materialIndex++)
+                {
+                    var unityTriangles = mesh.GetTriangles(materialIndex);
+
+                    babylonMesh.subMeshes[materialIndex] = new BabylonSubMesh
+                    {
+                        verticesStart = 0,
+                        verticesCount = mesh.vertexCount,
+                        materialIndex = materialIndex,
+                        indexStart = offset,
+                        indexCount = unityTriangles.Length
+                    };
+
+                    offset += unityTriangles.Length;
+                }
+            }
+            else
+            {
+                babylonMesh.materialId = DumpMaterial(renderer.sharedMaterial, renderer).id;
+            }
+
+            babylonScene.MeshesList.Add(babylonMesh);
+
+            // Animations
+            ExportAnimations(transform, babylonMesh);
+
+            if (IsRotationQuaternionAnimated(babylonMesh))
+            {
+                babylonMesh.rotationQuaternion = transform.localRotation.ToFloat();
+            }
+
+            // Collisions
+            if (exportationOptions.ExportCollisions)
+            {
+                var collider = gameObject.GetComponent<Collider>();
+
+                if (collider != null)
+                {
+                    babylonMesh.checkCollisions = true;
+                }
+            }
+        }
+    }
+}

+ 169 - 0
Exporters/Unity 5/Unity3D2Babylon/SceneBuilder.cs

@@ -0,0 +1,169 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using BabylonExport.Entities;
+using JsonFx.Json;
+using UnityEngine;
+using Object = UnityEngine.Object;
+using JsonFx.Serialization;
+using JsonFx.Serialization.Resolvers;
+
+namespace Unity3D2Babylon
+{
+    public partial class SceneBuilder
+    {
+        public string OutputPath { get; private set; }
+        public string SceneName { get; private set; }
+
+        readonly Dictionary<string, BabylonMaterial> materialsDictionary;
+        readonly Dictionary<string, BabylonMultiMaterial> multiMatDictionary;
+
+        readonly Dictionary<int, string> uniqueGuids;
+
+        readonly BabylonScene babylonScene;
+        GameObject[] gameObjects;
+
+        readonly ExportationOptions exportationOptions;
+
+        public SceneBuilder(string outputPath, string sceneName, ExportationOptions exportationOptions)
+        {
+            OutputPath = outputPath;
+            SceneName = string.IsNullOrEmpty(sceneName) ? "scene" : sceneName;
+
+            materialsDictionary = new Dictionary<string, BabylonMaterial>();
+            multiMatDictionary = new Dictionary<string, BabylonMultiMaterial>();
+            uniqueGuids = new Dictionary<int, string>();
+
+            babylonScene = new BabylonScene(OutputPath);
+
+            this.exportationOptions = exportationOptions;
+        }
+
+        public void WriteToBabylonFile()
+        {
+            babylonScene.Prepare();
+
+            var outputFile = Path.Combine(OutputPath, SceneName + ".babylon");
+
+            var jsWriter = new JsonWriter(new DataWriterSettings(new DataContractResolverStrategy()));
+            string babylonJSformat = jsWriter.Write(babylonScene);
+            using (var sw = new StreamWriter(outputFile))
+            {
+                sw.Write(babylonJSformat);
+                sw.Close();
+            }
+        }
+
+        public void GenerateStatus(List<string> logs)
+        {
+            var initialLog = new List<string>
+            {
+                "*Exportation Status:",
+                babylonScene.meshes.Length + " mesh(es)",
+                babylonScene.lights.Length + " light(s)",
+                babylonScene.cameras.Length + " camera(s)",
+                babylonScene.materials.Length + " material(s)",
+                babylonScene.multiMaterials.Length + " multi-material(s)",
+                "",
+                "*Log:"
+            };
+
+            logs.InsertRange(0, initialLog);
+        }
+
+        string GetParentID(Transform transform)
+        {
+            if (transform.parent == null)
+            {
+                return null;
+            }
+
+            return GetID(transform.parent.gameObject);
+        }
+
+        string GetID(GameObject gameObject)
+        {
+            var key = gameObject.GetInstanceID();
+
+            if (!uniqueGuids.ContainsKey(key))
+            {
+                uniqueGuids[key] = Guid.NewGuid().ToString();
+            }
+
+            return uniqueGuids[key];
+        }
+
+        public void ConvertFromUnity()
+        {
+            ExporterWindow.ReportProgress(0, "Starting Babylon.js exportation process...");
+
+            gameObjects = Object.FindObjectsOfType(typeof(GameObject)) as GameObject[];
+
+            if (gameObjects.Length == 0)
+            {
+                ExporterWindow.ShowMessage("No gameobject! - Please add at least a gameobject to export");
+                return;
+            }
+
+            var itemsCount = gameObjects.Length;
+
+            var index = 0;
+            foreach (var gameObject in gameObjects)
+            {
+                var progress = ((float)index / itemsCount);
+                index++;
+                // Static meshes
+                var meshFilter = gameObject.GetComponent<MeshFilter>();
+                if (meshFilter != null)
+                {                    
+                    ConvertUnityMeshToBabylon(meshFilter.sharedMesh, meshFilter.transform, gameObject, progress);
+                    continue;
+                }
+
+                // Skinned meshes
+                var skinnedMesh = gameObject.GetComponent<SkinnedMeshRenderer>();
+                if (skinnedMesh != null)
+                {
+                    ConvertUnityMeshToBabylon(skinnedMesh.sharedMesh, skinnedMesh.transform, gameObject, progress);
+                    continue;
+                }
+
+                // Light
+                var light = gameObject.GetComponent<Light>();
+                if (light != null)
+                {
+                    ConvertUnityLightToBabylon(light, progress);
+                    continue;
+                }
+
+                // Camera
+                var camera = gameObject.GetComponent<Camera>();
+                if (camera != null)
+                {
+                    ConvertUnityCameraToBabylon(camera, progress);
+                    continue;
+                }
+
+                // Empty
+                ConvertUnityEmptyObjectToBabylon(gameObject);
+            }
+
+            // Materials
+            foreach (var mat in materialsDictionary)
+            {
+                babylonScene.MaterialsList.Add(mat.Value);
+            }
+
+            foreach (var multiMat in multiMatDictionary)
+            {
+                babylonScene.MultiMaterialsList.Add(multiMat.Value);
+            }
+
+            // Collisions
+            if (exportationOptions.ExportCollisions)
+            {
+                babylonScene.gravity = exportationOptions.Gravity.ToFloat();
+            }
+        }     
+    }
+}

+ 25 - 0
Exporters/Unity 5/Unity3D2Babylon/SerializableVector3.cs

@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using UnityEngine;
+
+namespace Unity3D2Babylon
+{
+    public class SerializableVector3
+    {
+        public float X { get; set; }
+        public float Y { get; set; }
+        public float Z { get; set; }
+
+        public static implicit operator Vector3(SerializableVector3 source)
+        {
+            return new Vector3(source.X, source.Y, source.Z);
+        }
+
+        public static implicit operator SerializableVector3(Vector3 source)
+        {
+            return new SerializableVector3 { X = source.x, Y = source.y, Z = source.z };
+        }
+    }
+}

+ 53 - 0
Exporters/Unity 5/Unity3D2Babylon/Tools.cs

@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using UnityEngine;
+
+namespace Unity3D2Babylon
+{
+    public static class Tools
+    {
+        public static float[] ToFloat(this Color color)
+        {
+            var result = new float[4];
+            result[0] = color.r;
+            result[1] = color.g;
+            result[2] = color.b;
+            result[3] = color.a;
+
+            return result;
+        }
+
+        public static float[] ToFloat(this Vector3 vector3)
+        {
+            var result = new float[3];
+            result[0] = vector3.x;
+            result[1] = vector3.y;
+            result[2] = vector3.z;
+
+            return result;
+        }
+
+        public static float[] ToFloat(this SerializableVector3 vector3)
+        {
+            var result = new float[3];
+            result[0] = vector3.X;
+            result[1] = vector3.Y;
+            result[2] = vector3.Z;
+
+            return result;
+        }
+
+        public static float[] ToFloat(this Quaternion quaternion)
+        {
+            var result = new float[4];
+            result[0] = quaternion.x;
+            result[1] = quaternion.y;
+            result[2] = quaternion.z;
+            result[3] = quaternion.w;
+
+            return result;
+        }
+    }
+}

+ 68 - 0
Exporters/Unity 5/readme.md

@@ -0,0 +1,68 @@
+Unity 5 to Babylon.js exporter
+==============================
+
+## Installation
+You just need to copy/paste the plugin folder inside your scene folder. Unity 5 will then detect the plugin, compile it and add a "BabylonJS" menu.
+Using this menu you will be able to export the current scene to a .babylon file format.
+
+## Usage
+Just click on the "BabylonJS/Export to .babylon" menu to display the exportation window.
+
+
+* **Cameras**
+ * Name
+ * Position
+ * Target
+ * Fov
+ * Clip start
+ * Clip end
+ * Check collisions
+ * Gravity
+ * Ellipsoid
+ * Animations (position)
+ * **Lights**
+ * Type (Point, directional, Spot)
+ * Name
+ * Position
+ * Direction
+ * Spot angle
+ * Intensity
+ * Diffuse color
+ * Animations (position)
+ * Shadow maps
+* **Materials**
+ * Name
+ * Diffuse color
+ * Specular color
+ * Specular power
+ * Emissive color
+ * Alpha
+ * Backface culling
+ * Diffuse texture
+ * Reflection texture
+ * Emissive texture
+ * Bump texture
+* **Multi-materials**
+ * Name
+ * Child materials
+* **Textures**
+ * Name
+ * Associated file
+ * Use alpha
+ * uOffset / voffset
+ * uScale / uScale
+* **Meshes**
+ * Name
+ * Geometry (Positions & normals)
+ * Position
+ * Rotation
+ * Scaling
+ * Texture coordinates (2 channels)
+ * Check collisions
+ * Receive and cast shadows
+ * Animations (position, rotation, scaling)
+
+
+
+
+

+ 10 - 1
babylon.2.1-alpha.debug.js

@@ -7374,7 +7374,16 @@ var BABYLON;
         FollowCamera.prototype.follow = function (cameraTarget) {
             if (!cameraTarget)
                 return;
-            var radians = this.getRadians(this.rotationOffset) + cameraTarget.rotation.y;
+            var yRotation;
+            if (cameraTarget.rotationQuaternion) {
+                var rotMatrix = new BABYLON.Matrix();
+                cameraTarget.rotationQuaternion.toRotationMatrix(rotMatrix);
+                yRotation = Math.atan2(rotMatrix.m[8], rotMatrix.m[10]);
+            }
+            else {
+                yRotation = cameraTarget.rotation.y;
+            }
+            var radians = this.getRadians(this.rotationOffset) + yRotation;
             var targetX = cameraTarget.position.x + Math.sin(radians) * this.radius;
             var targetZ = cameraTarget.position.z + Math.cos(radians) * this.radius;
             var dx = targetX - this.position.x;

Datei-Diff unterdrückt, da er zu groß ist
+ 7 - 7
babylon.2.1-alpha.js


Datei-Diff unterdrückt, da er zu groß ist
+ 3175 - 3283
babylon.2.1.d.ts