private BabylonMesh ConvertUnityEmptyObjectToBabylon(GameObject gameObject, ref UnityMetaData metaData, ref List<BabylonExport.Entities.BabylonParticleSystem> particleSystems, ref List<UnityFlareSystem> lensFlares, ref string componentTags, BabylonMesh collisionMesh = null, Collider collider = null) { BabylonMesh babylonMesh = new BabylonMesh { name = gameObject.name, id = GetID(gameObject) }; metaData.type = "Game"; if (!String.IsNullOrEmpty(componentTags)) { babylonMesh.tags = componentTags; } 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(); babylonMesh.isVisible = false; babylonMesh.visibility = 0; babylonMesh.checkCollisions = false; // Collision mesh (No detail mesh fallback) string collisionMeshId = null; if (collider != null && collisionMesh != null) { collisionMeshId = collisionMesh.id; collisionMesh.parentId = babylonMesh.id; collisionMesh.visibility = collider.isTrigger ? 0.25f : 0.5f; collisionMesh.checkCollisions = (exportationOptions.ExportCollisions && collider.isTrigger == false); } metaData.properties["collisionMeshId"] = collisionMeshId; babylonMesh.metadata = metaData; babylonScene.MeshesList.Add(babylonMesh); // Animations ExportAnimations(transform, babylonMesh); if (IsRotationQuaternionAnimated(babylonMesh)) { babylonMesh.rotationQuaternion = transform.localRotation.ToFloat(); } // Lens Flares ParseLensFlares(gameObject, babylonMesh.id, ref lensFlares); // Particles Systems ParseParticleSystems(gameObject, babylonMesh.id, ref particleSystems); return babylonMesh; }
public virtual void OnExportGameObject(ref Unity3D2Babylon.ExportationOptions exportOptions, ref GameObject unityGameObject, ref UnityMetaData metaData, ref BabylonScene sceneBuilder, string outputPath) { }
private BabylonMesh ConvertUnityTerrainToBabylon(Terrain terrain, GameObject gameObject, float progress, ref UnityMetaData metaData, ref List<BabylonExport.Entities.BabylonParticleSystem> particleSystems, ref List<UnityFlareSystem> lensFlares, ref string componentTags) { ExporterWindow.ReportProgress(progress, "Exporting terrain: " + gameObject.name); var transform = gameObject.transform; float[] position = transform.localPosition.ToFloat(); float[] rotation = new float[3]; rotation[0] = transform.localRotation.eulerAngles.x * (float)Math.PI / 180; rotation[1] = transform.localRotation.eulerAngles.y * (float)Math.PI / 180; rotation[2] = transform.localRotation.eulerAngles.z * (float)Math.PI / 180; float[] scaling = transform.localScale.ToFloat(); BabylonMesh babylonMesh = new BabylonMesh { name = gameObject.name, id = GetID(gameObject) }; metaData.type = "Terrain"; if (!String.IsNullOrEmpty(componentTags)) { babylonMesh.tags = componentTags; } babylonMesh.tags += " [TERRAIN]"; if (!String.IsNullOrEmpty(babylonMesh.tags)) { babylonMesh.tags = babylonMesh.tags.Trim(); } babylonMesh.parentId = GetParentID(transform); babylonMesh.position = Vector3.zero.ToFloat(); babylonMesh.rotation = rotation; babylonMesh.scaling = scaling; babylonMesh.isVisible = true; babylonMesh.visibility = 1; babylonMesh.checkCollisions = false; metaData.properties["collisionMeshId"] = null; var generator = gameObject.GetComponent<BabylonTerrainGenerator>(); if (generator != null && terrain != null) { // TODO: Terrain tree information object treeInstances = null; object treePrototypes = null; // Terrain metadata infomation Vector3 terrainSize = terrain.terrainData.size; metaData.properties.Add("width", terrainSize.x); metaData.properties.Add("length", terrainSize.z); metaData.properties.Add("height", terrainSize.y); metaData.properties.Add("position", position); metaData.properties.Add("rotation", rotation); metaData.properties.Add("scaling", scaling); metaData.properties.Add("thickness", terrain.terrainData.thickness); metaData.properties.Add("detailWidth", terrain.terrainData.detailWidth); metaData.properties.Add("detailHeight", terrain.terrainData.detailHeight); metaData.properties.Add("heightmapWidth", terrain.terrainData.heightmapWidth); metaData.properties.Add("heightmapHeight", terrain.terrainData.heightmapHeight); metaData.properties.Add("wavingGrassAmount", terrain.terrainData.wavingGrassAmount); metaData.properties.Add("wavingGrassSpeed", terrain.terrainData.wavingGrassSpeed); metaData.properties.Add("wavingGrassStrength", terrain.terrainData.wavingGrassStrength); metaData.properties.Add("wavingGrassTint", terrain.terrainData.wavingGrassTint.ToFloat()); metaData.properties.Add("treeInstanceCount", terrain.terrainData.treeInstanceCount); metaData.properties.Add("treeInstances", treeInstances); metaData.properties.Add("treePrototypes", treePrototypes); metaData.properties.Add("physicsState", generator.physicsActive); metaData.properties.Add("physicsMass", generator.physicsMass); metaData.properties.Add("physicsFriction", generator.physicsFriction); metaData.properties.Add("physicsRestitution", generator.physicsRestitution); metaData.properties.Add("physicsImpostor", (int)generator.physicsImpostor); metaData.properties.Add("groundTessellation", generator.groundTessellation); // Generate detailed mesh ExporterWindow.ReportProgress(progress, "Generating terrain mesh: " + gameObject.name); BabylonTerrainData terrainMeshData = Unity3D2Babylon.Tools.CreateTerrainData(terrain.terrainData, (int)generator.terrainResolution, transform.localPosition, true); Tools.GenerateBabylonMeshTerrainData(terrainMeshData, babylonMesh, false, babylonScene, transform); if (generator.surfaceMaterial != null) { babylonMesh.materialId = DumpMaterial(generator.surfaceMaterial, terrain.lightmapIndex, terrain.lightmapScaleOffset, generator.coordinatesIndex).id; } // Generate collision heightmap var terrainCollider = gameObject.GetComponent<TerrainCollider>(); if (terrainCollider != null && terrainCollider.enabled) { ExporterWindow.ReportProgress(progress, "Generating terrain heightmap: " + gameObject.name); float minheight = float.MaxValue; float maxheight = float.MinValue; int hwidth = terrain.terrainData.heightmapWidth; int hheight = terrain.terrainData.heightmapHeight; float[,] rawHeights = terrain.terrainData.GetHeights(0, 0, hwidth, hheight); Texture2D heightMap = new Texture2D(hwidth, hheight, TextureFormat.ARGB32, false); for (int y = 0; y < hheight; y++) { for (int x = 0; x < hwidth; x++) { float inverted = rawHeights[y, x]; minheight = Mathf.Min(minheight, inverted); maxheight = Mathf.Max(maxheight, inverted); } } List<Color32> pixels = new List<Color32>(); for (int y = 0; y < hheight; y++) { for (int x = 0; x < hwidth; x++) { float inverted = rawHeights[y, x]; if (generator.heightmapStrength > 0) { float threadhold = minheight + generator.floorThreashold; if (inverted > threadhold) { inverted += (generator.heightmapStrength / 10.0f); } } byte[] packed = BitConverter.GetBytes(inverted); if (packed != null && packed.Length >= 4) { pixels.Add(new Color32(packed[0], packed[1], packed[2], packed[3])); } } } heightMap.SetPixels32(pixels.ToArray()); heightMap.Apply(); byte[] heightmapBytes = heightMap.EncodeToPNG(); metaData.properties.Add("heightmapBase64", ("data:image/png;base64," + Convert.ToBase64String(heightmapBytes))); } } else { UnityEngine.Debug.LogWarning("No valid terrain or generator found for: " + gameObject.name); } babylonMesh.metadata = metaData; babylonScene.MeshesList.Add(babylonMesh); SceneBuilder.Metadata.properties["hasTerrainMeshes"] = true; // Animations ExportAnimations(transform, babylonMesh); if (IsRotationQuaternionAnimated(babylonMesh)) { babylonMesh.rotationQuaternion = transform.localRotation.ToFloat(); } // Lens Flares ParseLensFlares(gameObject, babylonMesh.id, ref lensFlares); // Particles Systems ParseParticleSystems(gameObject, babylonMesh.id, ref particleSystems); return babylonMesh; }
private BabylonMesh ConvertUnityMeshToBabylon(Mesh mesh, Transform transform, GameObject gameObject, float progress, ref UnityMetaData metaData, ref List<BabylonExport.Entities.BabylonParticleSystem> particleSystems, ref List<UnityFlareSystem> lensFlares, ref string componentTags, BabylonMesh collisionMesh = null, Collider collider = null) { BabylonMesh babylonMesh = new BabylonMesh(); metaData.type = "Mesh"; if (!String.IsNullOrEmpty(componentTags)) { babylonMesh.tags = componentTags; } ExporterWindow.ReportProgress(progress, "Exporting mesh: " + gameObject.name); babylonMesh.name = gameObject.name; babylonMesh.id = GetID(transform.gameObject); var renderer = gameObject.GetComponent<Renderer>(); if (renderer != null) { 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.checkCollisions = false; // Collision mesh (With detail mesh fallback) string collisionMeshId = null; if (collider != null) { if (collisionMesh != null) { collisionMeshId = collisionMesh.id; collisionMesh.parentId = babylonMesh.id; collisionMesh.visibility = collider.isTrigger ? 0.25f : 0.5f; collisionMesh.checkCollisions = (exportationOptions.ExportCollisions && collider.isTrigger == false); } else { babylonMesh.checkCollisions = exportationOptions.ExportCollisions; } } metaData.properties["collisionMeshId"] = collisionMeshId; if (mesh != null) { Tools.GenerateBabylonMeshData(mesh, babylonMesh, babylonScene, transform); int index = 0; if (mesh.boneWeights.Length == mesh.vertexCount) { babylonMesh.matricesIndices = new int[mesh.vertexCount]; babylonMesh.matricesWeights = new float[mesh.vertexCount * 4]; index = 0; foreach (BoneWeight bw in mesh.boneWeights) { babylonMesh.matricesIndices[index] = (bw.boneIndex3 << 24) | (bw.boneIndex2 << 16) | (bw.boneIndex1 << 8) | bw.boneIndex0; babylonMesh.matricesWeights[index * 4 + 0] = bw.weight0; babylonMesh.matricesWeights[index * 4 + 1] = bw.weight1; babylonMesh.matricesWeights[index * 4 + 2] = bw.weight2; babylonMesh.matricesWeights[index * 4 + 3] = bw.weight3; var totalWeight = bw.weight0 + bw.weight1 + bw.weight2 + bw.weight3; if (Mathf.Abs(totalWeight - 1.0f) > 0.01f) { throw new Exception("Total bone weights is not normalized for: " + mesh); } index++; } } index = 0; if (renderer != null && renderer.sharedMaterial != null) { // Validate Multi Materials if (mesh.subMeshCount > 1) { BabylonMultiMaterial bMultiMat; string multiMatName = ""; for (int i = 0; i < renderer.sharedMaterials.Length; i++) { multiMatName += renderer.sharedMaterials[i].name; } if (!multiMatDictionary.ContainsKey(multiMatName)) { bMultiMat = new BabylonMultiMaterial { materials = new string[mesh.subMeshCount], id = Guid.NewGuid().ToString(), name = multiMatName }; for (int i = 0; i < renderer.sharedMaterials.Length; i++) { var sharedMaterial = renderer.sharedMaterials[i]; BabylonMaterial babylonMaterial; babylonMaterial = DumpMaterial(sharedMaterial, renderer.lightmapIndex, renderer.lightmapScaleOffset); bMultiMat.materials[i] = babylonMaterial.id; } if (mesh.subMeshCount > 1) { multiMatDictionary.Add(bMultiMat.name, bMultiMat); } } else { bMultiMat = multiMatDictionary[multiMatName]; } 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.lightmapIndex, renderer.lightmapScaleOffset).id; } } babylonMesh.metadata = metaData; babylonScene.MeshesList.Add(babylonMesh); // Animations ExportAnimations(transform, babylonMesh); if (IsRotationQuaternionAnimated(babylonMesh)) { babylonMesh.rotationQuaternion = transform.localRotation.ToFloat(); } // Lens Flares ParseLensFlares(gameObject, babylonMesh.id, ref lensFlares); // Particles Systems ParseParticleSystems(gameObject, babylonMesh.id, ref particleSystems); // Babylon Physics if (exportationOptions.ExportPhysics) { var physics = gameObject.GetComponent<BabylonPhysicsState>(); if (physics != null) { babylonMesh.physicsMass = physics.mass; babylonMesh.physicsFriction = physics.friction; babylonMesh.physicsRestitution = physics.restitution; babylonMesh.physicsImpostor = (int)physics.imposter; } } } return babylonMesh; }
public void ConvertFromUnity() { ExporterWindow.ReportProgress(0, "Starting 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; } // Create scene metadata SceneBuilder.Metadata = new SceneMetaData(); // Parse all scene game objects var index = 0; var itemsCount = gameObjects.Length; var particleSystems = new List<BabylonExport.Entities.BabylonParticleSystem>(); var lensFlareSystems = new List<UnityFlareSystem>(); ExporterWindow.ReportProgress(0, "Exporting game objects from scene..."); babylonScene.physicsEngine = (exportationOptions.DefaultPhysicsEngine == 1) ? "oimo" : "cannon"; try { bool foundController = false; foreach (var gameObject in gameObjects) { var progress = ((float)index / itemsCount); index++; // Unity metadata var metaData = new UnityMetaData(); metaData.objectId = GetID(gameObject); metaData.objectName = gameObject.name; metaData.tagName = gameObject.tag; metaData.layerIndex = gameObject.layer; metaData.layerName = LayerMask.LayerToName(gameObject.layer); // Export hooking var exportObject = gameObject; var exportOptions = exportationOptions; BabylonScene sceneBuilder = babylonScene; if (SceneController != null) { SceneController.OnExportGameObject(ref exportOptions, ref exportObject, ref metaData, ref sceneBuilder, OutputPath); } // Components tags string componentTags = String.Empty; if (!String.IsNullOrEmpty(gameObject.tag) && !gameObject.tag.Equals("Untagged", StringComparison.OrdinalIgnoreCase)) { componentTags = gameObject.tag; } // Navigation area metaData.areaIndex = -1; bool navigationStatic = GameObjectUtility.AreStaticEditorFlagsSet(gameObject, StaticEditorFlags.NavigationStatic); if (navigationStatic) { metaData.areaIndex = GameObjectUtility.GetNavMeshArea(gameObject); } // Navigation agent metaData.navAgent = null; var navigationAgent = gameObject.GetComponent<NavMeshAgent>(); if (navigationAgent != null) { componentTags += " [NAVAGENT]"; Dictionary<string, object> agentInfo = new Dictionary<string, object>(); agentInfo.Add("name", navigationAgent.name); agentInfo.Add("radius", navigationAgent.radius); agentInfo.Add("height", navigationAgent.height); agentInfo.Add("speed", navigationAgent.speed); agentInfo.Add("acceleration", navigationAgent.acceleration); agentInfo.Add("angularSpeed", navigationAgent.angularSpeed); agentInfo.Add("areaMask", navigationAgent.areaMask); agentInfo.Add("autoBraking", navigationAgent.autoBraking); agentInfo.Add("autoTraverseOffMeshLink", navigationAgent.autoTraverseOffMeshLink); agentInfo.Add("avoidancePriority", navigationAgent.avoidancePriority); agentInfo.Add("baseOffset", navigationAgent.baseOffset); agentInfo.Add("obstacleAvoidanceType", navigationAgent.obstacleAvoidanceType.ToString()); agentInfo.Add("stoppingDistance", navigationAgent.stoppingDistance); metaData.navAgent = agentInfo; } // Navigation link metaData.meshLink = null; var navigationLink = gameObject.GetComponent<OffMeshLink>(); if (navigationLink != null) { componentTags += " [MESHLINK]"; Dictionary<string, object> linkInfo = new Dictionary<string, object>(); linkInfo.Add("name", navigationLink.name); linkInfo.Add("activated", navigationLink.activated); linkInfo.Add("area", navigationLink.area); linkInfo.Add("autoUpdatePositions", navigationLink.autoUpdatePositions); linkInfo.Add("biDirectional", navigationLink.biDirectional); linkInfo.Add("costOverride", navigationLink.costOverride); linkInfo.Add("occupied", navigationLink.occupied); linkInfo.Add("start", GetTransformPropertyValue(navigationLink.startTransform)); linkInfo.Add("end", GetTransformPropertyValue(navigationLink.endTransform)); metaData.meshLink = linkInfo; } // Navigation obstacle metaData.meshObstacle = null; var navigationObstacle = gameObject.GetComponent<NavMeshObstacle>(); if (navigationObstacle != null) { componentTags += " [MESHOBSTACLE]"; Dictionary<string, object> obstacleInfo = new Dictionary<string, object>(); obstacleInfo.Add("name", navigationObstacle.name); obstacleInfo.Add("carving", navigationObstacle.carving); obstacleInfo.Add("carveOnlyStationary", navigationObstacle.carveOnlyStationary); obstacleInfo.Add("carvingMoveThreshold", navigationObstacle.carvingMoveThreshold); obstacleInfo.Add("carvingTimeToStationary", navigationObstacle.carvingTimeToStationary); obstacleInfo.Add("shape", navigationObstacle.shape.ToString()); obstacleInfo.Add("radius", navigationObstacle.radius); obstacleInfo.Add("center", navigationObstacle.center.ToFloat()); obstacleInfo.Add("size", navigationObstacle.size.ToFloat()); metaData.meshObstacle = obstacleInfo; } // Tags component var tagsComponent = gameObject.GetComponent<BabylonTagsComponent>(); if (tagsComponent != null) { if (!String.IsNullOrEmpty(tagsComponent.babylonTags)) { componentTags += (" " + tagsComponent.babylonTags); } } // Script components var gameComponents = gameObject.GetComponents<BabylonScriptComponent>(); if (gameComponents != null) { var components = new List<object>(); foreach (var gameComponent in gameComponents) { Type componentType = gameComponent.GetType(); string componentName = componentType.FullName; var component = new UnityScriptComponent(); MonoScript componentScript = MonoScript.FromMonoBehaviour(gameComponent); component.order = MonoImporter.GetExecutionOrder(componentScript); component.name = componentName; component.klass = gameComponent.babylonClass; component.update = (gameComponent.updateOption == BabylonTickOptions.EnableTick); component.controller = (gameComponent is BabylonSceneController); if (component.controller == true) { component.order = -1; if (foundController == false) { foundController = true; componentTags += " [CONTROLLER]"; object userInterface = null; BabylonSceneController scx = (gameComponent as BabylonSceneController); EmbeddedAsset guiAsset = scx.sceneOptions.graphicUserInterface; if (guiAsset != null && scx.sceneOptions.userInterfaceMode != BabylonGuiMode.None) { userInterface = GetEmbeddedAssetPropertyValue(guiAsset); } SceneBuilder.Metadata.properties.Add("autoDraw", scx.sceneOptions.autoDrawInterface); SceneBuilder.Metadata.properties.Add("interfaceMode", scx.sceneOptions.userInterfaceMode.ToString()); SceneBuilder.Metadata.properties.Add("userInterface", userInterface); SceneBuilder.Metadata.properties.Add("controllerPresent", true); SceneBuilder.Metadata.properties.Add("controllerObjectId", metaData.objectId); } else { Debug.LogError("Duplicate scene controller detected: " + component.name); } } FieldInfo[] componentFields = componentType.GetFields(); if (componentFields != null) { foreach (var componentField in componentFields) { var componentAttribute = (BabylonPropertyAttribute)Attribute.GetCustomAttribute(componentField, typeof(BabylonPropertyAttribute)); if (componentAttribute != null && componentField.Name != "babylonClass") { component.properties.Add(componentField.Name, GetComponentPropertyValue(componentField, gameComponent)); } } } gameComponent.OnExportProperties(ref exportOptions, ref exportObject, ref component.properties, OutputPath); components.Add(component); } if (components.Count > 0) { metaData.components = components; } } // Format tags if (!String.IsNullOrEmpty(componentTags)) { componentTags = componentTags.Trim(); } // Audio sources var audioComponents = gameObject.GetComponents<BabylonAudioSource>(); if (audioComponents != null) { foreach (var item in audioComponents) { if (item != null && item.exportAudio && item.sound != null) { string soundPath = AssetDatabase.GetAssetPath(item.sound); if (!String.IsNullOrEmpty(soundPath)) { string soundName = Path.GetFileName(soundPath).Replace(" ", ""); string outputFile = Path.Combine(OutputPath, soundName); if (File.Exists(soundPath)) { File.Copy(soundPath, outputFile, true); var sound = new BabylonSound(); sound.name = soundName; sound.volume = item.options.volume; sound.playbackRate = item.options.playbackRate; sound.autoplay = item.options.autoplay; sound.loop = item.options.loop; sound.soundTrackId = item.options.soundTrackId; sound.spatialSound = item.options.spatialSound; sound.position = item.options.position.ToFloat(); sound.refDistance = item.options.refDistance; sound.rolloffFactor = item.options.rolloffFactor; sound.maxDistance = item.options.maxDistance; sound.distanceModel = item.options.distanceModel; sound.panningModel = item.options.panningModel; sound.isDirectional = item.options.isDirectional; sound.coneInnerAngle = item.options.coneInnerAngle; sound.coneOuterAngle = item.options.coneOuterAngle; sound.coneOuterGain = item.options.coneOuterGain; sound.localDirectionToMesh = item.options.directionToMesh.ToFloat(); babylonScene.SoundsList.Add(sound); } else { Debug.LogError("Fail to locate audio file: " + soundPath); } } else { Debug.LogError("Null audio clip path for: " + item.sound.name); } } } } // Terrain meshes var terrainMesh = gameObject.GetComponent<Terrain>(); if (terrainMesh != null) { ConvertUnityTerrainToBabylon(terrainMesh, gameObject, progress, ref metaData, ref particleSystems, ref lensFlareSystems, ref componentTags); continue; } // Collision meshes BabylonMesh collisionMesh = null; var collider = gameObject.GetComponent<Collider>(); if (collider != null) { if (collider.enabled) { int segments = 12; BabylonColliderDetail detail = (BabylonColliderDetail)exportationOptions.DefaultColliderDetail; var collisionData = new UnityMetaData(); collisionData.objectId = Guid.NewGuid().ToString(); collisionData.objectName = gameObject.name + "_Metadata"; if (collider is MeshCollider) { var meshCollider = collider as MeshCollider; collisionMesh = new BabylonMesh(); collisionMesh.tags = "[MESHCOLLIDER]"; // Generate Mesh Collider Geometry if(!meshCollider.sharedMesh) { UnityEngine.Debug.LogWarning(meshCollider.gameObject+" has a Mesh Collider component without a mesh"); } else { Tools.GenerateBabylonMeshData(meshCollider.sharedMesh, collisionMesh); } collisionMesh.position = Vector3.zero.ToFloat(); collisionMesh.rotation = Vector3.zero.ToFloat(); float factorX = 1f, factorY = 1f, factorZ = 1f; if (meshCollider.inflateMesh && meshCollider.skinWidth > 0f) { Vector3 localScale = gameObject.transform.localScale; factorX += (meshCollider.skinWidth / localScale.x); factorY += (meshCollider.skinWidth / localScale.y); factorZ += (meshCollider.skinWidth / localScale.z); } collisionMesh.scaling = new Vector3(factorX, factorY, factorZ).ToFloat(); // Export Mesh Collider Metadata collisionData.tagName = "MeshCollider"; collisionData.properties.Add("type", "Mesh"); collisionData.properties.Add("convex", meshCollider.convex); collisionData.properties.Add("inflateMesh", meshCollider.inflateMesh); collisionData.properties.Add("skinWidth", meshCollider.skinWidth); } else if (collider is CapsuleCollider) { var capsuleCollider = collider as CapsuleCollider; collisionMesh = new BabylonMesh(); collisionMesh.tags = "[CAPSULECOLLIDER]"; switch (detail) { case BabylonColliderDetail.FullResolution: segments = 48; break; case BabylonColliderDetail.HighResolution: segments = 32; break; case BabylonColliderDetail.MediumResolution: segments = 24; break; case BabylonColliderDetail.LowResolution: segments = 12; break; case BabylonColliderDetail.VeryLowResolution: segments = 8; break; case BabylonColliderDetail.MinimumResolution: segments = 6; break; default: segments = 12; break; } // Generate Capsule Collider Geometry Mesh capsuleMesh = Tools.CreateCapsuleMesh(capsuleCollider.height, capsuleCollider.radius, segments); Tools.GenerateBabylonMeshData(capsuleMesh, collisionMesh); collisionMesh.position = new float[3]; collisionMesh.position[0] = capsuleCollider.center.x; collisionMesh.position[1] = capsuleCollider.center.y; collisionMesh.position[2] = capsuleCollider.center.z; collisionMesh.rotation = new float[3]; collisionMesh.rotation[0] = (capsuleCollider.direction == 2) ? 90f * (float)Math.PI / 180f : 0f; collisionMesh.rotation[1] = 0f; collisionMesh.rotation[2] = (capsuleCollider.direction == 0) ? 90f * (float)Math.PI / 180f : 0f; collisionMesh.scaling = new Vector3(1, 1, 1).ToFloat(); // Export Capsule Collider Metadata collisionData.tagName = "CapsuleCollider"; collisionData.properties.Add("type", "Capsule"); collisionData.properties.Add("center", capsuleCollider.center.ToFloat()); collisionData.properties.Add("radius", capsuleCollider.radius); collisionData.properties.Add("height", capsuleCollider.height); collisionData.properties.Add("direction", capsuleCollider.direction); } else if (collider is SphereCollider) { var sphereCollider = collider as SphereCollider; collisionMesh = new BabylonMesh(); collisionMesh.tags = "[SPHERECOLLIDER]"; switch (detail) { case BabylonColliderDetail.FullResolution: segments = 48; break; case BabylonColliderDetail.HighResolution: segments = 32; break; case BabylonColliderDetail.MediumResolution: segments = 24; break; case BabylonColliderDetail.LowResolution: segments = 12; break; case BabylonColliderDetail.VeryLowResolution: segments = 8; break; case BabylonColliderDetail.MinimumResolution: segments = 6; break; default: segments = 12; break; } // Generate Sphere Collider Geometry Mesh sphereMesh = Tools.CreateSphereMesh(sphereCollider.radius, segments); Tools.GenerateBabylonMeshData(sphereMesh, collisionMesh); collisionMesh.position = new float[3]; collisionMesh.position[0] = sphereCollider.center.x; collisionMesh.position[1] = sphereCollider.center.y; collisionMesh.position[2] = sphereCollider.center.z; collisionMesh.rotation = Vector3.zero.ToFloat(); collisionMesh.scaling = new Vector3(1f, 1f, 1f).ToFloat(); // Export Sphere Collider Metadata collisionData.tagName = "SphereCollider"; collisionData.properties.Add("type", "Sphere"); collisionData.properties.Add("center", sphereCollider.center.ToFloat()); collisionData.properties.Add("radius", sphereCollider.radius); } else if (collider is WheelCollider) { var wheelCollider = collider as WheelCollider; collisionMesh = new BabylonMesh(); collisionMesh.tags = "[WHEELCOLLIDER]"; switch (detail) { case BabylonColliderDetail.FullResolution: segments = 128; break; case BabylonColliderDetail.HighResolution: segments = 64; break; case BabylonColliderDetail.MediumResolution: segments = 48; break; case BabylonColliderDetail.LowResolution: segments = 32; break; case BabylonColliderDetail.VeryLowResolution: segments = 24; break; case BabylonColliderDetail.MinimumResolution: segments = 16; break; default: segments = 32; break; } // Generate Wheel Collider Geometry Mesh wheelMesh = Tools.CreateWheelMesh(wheelCollider.suspensionDistance, wheelCollider.radius, segments); Tools.GenerateBabylonMeshData(wheelMesh, collisionMesh); collisionMesh.position = new float[3]; collisionMesh.position[0] = wheelCollider.center.x; collisionMesh.position[1] = wheelCollider.center.y; collisionMesh.position[2] = wheelCollider.center.z; collisionMesh.rotation = new float[3]; collisionMesh.rotation[0] = 0f; collisionMesh.rotation[1] = 0f; collisionMesh.rotation[2] = 90f * (float)Math.PI / 180; collisionMesh.scaling = new Vector3(1f, 1f, 1f).ToFloat(); // Export Wheel Collider Metadata collisionData.tagName = "WheelCollider"; collisionData.properties.Add("type", "Wheel"); collisionData.properties.Add("center", wheelCollider.center.ToFloat()); collisionData.properties.Add("radius", wheelCollider.radius); } else if (collider is BoxCollider) { var boxCollider = collider as BoxCollider; collisionMesh = new BabylonMesh(); collisionMesh.tags = "[BOXCOLLIDER]"; // Generate Box Collider Geometry Mesh boxMesh = Tools.CreateBoxMesh(boxCollider.size.x, boxCollider.size.y, boxCollider.size.z); Tools.GenerateBabylonMeshData(boxMesh, collisionMesh); collisionMesh.position = new float[3]; collisionMesh.position[0] = boxCollider.center.x; collisionMesh.position[1] = boxCollider.center.y; collisionMesh.position[2] = boxCollider.center.z; collisionMesh.rotation = Vector3.zero.ToFloat(); collisionMesh.scaling = new Vector3(1f, 1f, 1f).ToFloat(); // Export Box Collider Metadata collisionData.tagName = "BoxCollider"; collisionData.properties.Add("type", "Box"); collisionData.properties.Add("center", boxCollider.center.ToFloat()); collisionData.properties.Add("size", boxCollider.size.ToFloat()); } if (collisionMesh != null) { collisionMesh.id = Guid.NewGuid().ToString(); collisionMesh.name = gameObject.name + "_Collider"; // Default Check Collisions False collisionMesh.checkCollisions = false; collisionMesh.isVisible = false; collisionData.properties.Add("parrentId", metaData.objectId); collisionData.properties.Add("transform", GetTransformPropertyValue(gameObject.transform)); collisionMesh.metadata = collisionData; babylonScene.MeshesList.Add(collisionMesh); SceneBuilder.Metadata.properties["hasCollisionMeshes"] = true; } } } // Static meshes var meshFilter = gameObject.GetComponent<MeshFilter>(); if (meshFilter != null) { ConvertUnityMeshToBabylon(meshFilter.sharedMesh, meshFilter.transform, gameObject, progress, ref metaData, ref particleSystems, ref lensFlareSystems, ref componentTags, collisionMesh, collider); continue; } // Skinned meshes var skinnedMesh = gameObject.GetComponent<SkinnedMeshRenderer>(); if (skinnedMesh != null) { var babylonMesh = ConvertUnityMeshToBabylon(skinnedMesh.sharedMesh, skinnedMesh.transform, gameObject, progress, ref metaData, ref particleSystems, ref lensFlareSystems, ref componentTags, collisionMesh, collider); var skeleton = ConvertUnitySkeletonToBabylon(skinnedMesh.bones, skinnedMesh.sharedMesh.bindposes, skinnedMesh.transform, gameObject, progress); babylonMesh.skeletonId = skeleton.id; ExportSkeletonAnimation(skinnedMesh, babylonMesh, skeleton); continue; } // Scene lights var light = gameObject.GetComponent<Light>(); if (light != null) { ConvertUnityLightToBabylon(light, gameObject, progress, ref metaData, ref particleSystems, ref lensFlareSystems, ref componentTags); continue; } // Scene cameras var camera = gameObject.GetComponent<Camera>(); if (camera != null) { ConvertUnityCameraToBabylon(camera, gameObject, progress, ref metaData, ref particleSystems, ref lensFlareSystems, ref componentTags); if (SceneController != null && SceneController.skyboxOptions.exportSkybox) { ConvertUnitySkyboxToBabylon(camera, progress); } continue; } // Empty objects ConvertUnityEmptyObjectToBabylon(gameObject, ref metaData, ref particleSystems, ref lensFlareSystems, ref componentTags, collisionMesh, collider); } // 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.workerCollisions = exportationOptions.WorkerCollisions; if (SceneController != null) { babylonScene.gravity = SceneController.sceneOptions.defaultGravity.ToFloat(); } } // Babylon Physics if (exportationOptions.ExportPhysics) { babylonScene.physicsEnabled = true; if (SceneController != null) { babylonScene.physicsGravity = SceneController.sceneOptions.defaultGravity.ToFloat(); } } // Scene Controller if (SceneController != null) { Color ambientColor = SceneController.sceneOptions.ambientColor; float ambientLevel = SceneController.lightingOptions.lightLevel; Color ambientSpecular = SceneController.lightingOptions.specularColor; babylonScene.autoClear = SceneController.sceneOptions.autoClear; int fogmode = 0; if (RenderSettings.fog) { switch (RenderSettings.fogMode) { case FogMode.Exponential: fogmode = 1; break; case FogMode.ExponentialSquared: fogmode = 2; break; case FogMode.Linear: fogmode = 3; break; } } babylonScene.fogMode = fogmode; babylonScene.fogDensity = RenderSettings.fogDensity; babylonScene.fogColor = RenderSettings.fogColor.ToFloat(); babylonScene.fogStart = RenderSettings.fogStartDistance; babylonScene.fogEnd = RenderSettings.fogEndDistance; if (exportationOptions.DefaultLightmapMode != (int)BabylonLightmapMode.FullLightBaking && SceneController.lightingOptions.lightMode == BabylonAmbientLighting.UnityAmbientLighting) { var ambientLight = new BabylonLight { name = "Ambient Light", id = Guid.NewGuid().ToString(), parentId = null, metadata = null, position = null, exponent = 1.0f, angle = 0.0f, type = 3 }; var ambientDirection = new Vector3(0.0f, 1.0f, 0.0f); Color ambientDiffuse = (RenderSettings.ambientMode == UnityEngine.Rendering.AmbientMode.Skybox) ? RenderSettings.ambientSkyColor : RenderSettings.ambientLight; ambientLight.intensity = RenderSettings.ambientIntensity * ambientLevel; ambientLight.direction = ambientDirection.ToFloat(); ; ambientLight.diffuse = ambientDiffuse.ToFloat(); ambientLight.specular = ambientSpecular.ToFloat(); ambientLight.groundColor = RenderSettings.ambientGroundColor.ToFloat(); babylonScene.ambientColor = ambientColor.ToFloat(); babylonScene.LightsList.Add(ambientLight); ExporterWindow.ReportProgress(0, "Exporting ambient light intensity at: " + ambientLight.intensity.ToString()); } if (SceneController.sceneOptions.navigationMesh == BabylonNavigationMesh.EnableNavigation) { ExporterWindow.ReportProgress(0, "Parsing scene navigation mesh..."); NavMeshTriangulation triangulatedNavMesh = NavMesh.CalculateTriangulation(); if (triangulatedNavMesh.vertices != null && triangulatedNavMesh.vertices.Length > 0 && triangulatedNavMesh.indices != null && triangulatedNavMesh.indices.Length > 0) { int vertexCount = triangulatedNavMesh.vertices.Length; if (vertexCount <= SceneBuilder.MAX_VERTEX_COUNT) { ExporterWindow.ReportProgress(0, "Generating navigation mesh vertices: " + vertexCount.ToString()); var navData = new UnityMetaData(); navData.type = "NavMesh"; navData.objectId = Guid.NewGuid().ToString(); navData.objectName = "Navigation_Mesh"; var areaTable = new List<object>(); string[] areaNavigation = GameObjectUtility.GetNavMeshAreaNames(); foreach (string areaName in areaNavigation) { var bag = new Dictionary<string, object>(); int areaIndex = NavMesh.GetAreaFromName(areaName); float areaCost = NavMesh.GetAreaCost(areaIndex); bag.Add("index", areaIndex); bag.Add("area", areaName); bag.Add("cost", areaCost); areaTable.Add(bag); } navData.properties.Add("table", areaTable); navData.properties.Add("areas", triangulatedNavMesh.areas); Mesh mesh = new Mesh(); mesh.name = "sceneNavigationMesh"; mesh.vertices = triangulatedNavMesh.vertices; mesh.triangles = triangulatedNavMesh.indices; mesh.RecalculateNormals(); BabylonMesh babylonMesh = new BabylonMesh(); babylonMesh.tags = "[NAVMESH]"; babylonMesh.metadata = navData; babylonMesh.name = mesh.name; babylonMesh.id = Guid.NewGuid().ToString(); babylonMesh.parentId = null; babylonMesh.position = Vector3.zero.ToFloat(); babylonMesh.rotation = Vector3.zero.ToFloat(); babylonMesh.scaling = new Vector3(1, 1, 1).ToFloat(); babylonMesh.isVisible = false; babylonMesh.visibility = 0.75f; babylonMesh.checkCollisions = false; Tools.GenerateBabylonMeshData(mesh, babylonMesh); babylonScene.MeshesList.Add(babylonMesh); SceneBuilder.Metadata.properties["hasNavigationMesh"] = true; } else { UnityEngine.Debug.LogError("Navigation mesh exceeds max (65000) vertex limit: " + vertexCount.ToString()); } } } if (SceneController.sceneOptions.particleSystems) { if (particleSystems != null && particleSystems.Count > 0) { babylonScene.particleSystems = particleSystems.ToArray(); } } if (SceneController.sceneOptions.lensFlareSystems) { if (lensFlareSystems != null && lensFlareSystems.Count > 0) { var lfs_buffer = new List<BabylonLensFlareSystem>(); foreach (var ulfs in lensFlareSystems) { var lfs = new BabylonLensFlareSystem(); lfs.borderLimit = ulfs.borderLimit; lfs.emitterId = ulfs.emitterId; var lfx = new List<BabylonLensFlare>(); foreach (var ulf in ulfs.lensFlares) { var lf = new BabylonLensFlare(); lf.textureName = ulf.textureName; lf.position = ulf.position; lf.color = ulf.color; lf.size = ulf.size; lfx.Add(lf); } lfs.flares = lfx.ToArray(); lfs_buffer.Add(lfs); } babylonScene.lensFlareSystems = lfs_buffer.ToArray(); } } } } catch (Exception ex) { Debug.LogException(ex); } finally { babylonScene.metadata = SceneBuilder.Metadata; } }
private void ConvertUnityCameraToBabylon(Camera camera, GameObject gameObject, float progress, ref UnityMetaData metaData, ref List<BabylonExport.Entities.BabylonParticleSystem> particleSystems, ref List<UnityFlareSystem> lensFlares, ref string componentTags) { ExporterWindow.ReportProgress(progress, "Exporting camera: " + camera.name); BabylonUniversalCamera babylonCamera = new BabylonUniversalCamera { 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() }; metaData.type = "Camera"; metaData.properties.Add("hdr", camera.hdr); metaData.properties.Add("clearFlags", camera.clearFlags.ToString()); metaData.properties.Add("cullingMask", camera.cullingMask); metaData.properties.Add("stereoEnabled", camera.stereoEnabled); metaData.properties.Add("isOrthographic", camera.orthographic); metaData.properties.Add("useOcclusionCulling", camera.useOcclusionCulling); babylonCamera.tags = componentTags; var target = new Vector3(0, 0, 1); var transformedTarget = camera.transform.TransformDirection(target); babylonCamera.target = (camera.transform.position + transformedTarget).ToFloat(); babylonCamera.isStereoscopicSideBySide = camera.stereoEnabled; if (camera.orthographic) { float vert = camera.orthographicSize; float horz = vert * exportationOptions.DefaultAspectRatio; babylonCamera.orthoTop = vert; babylonCamera.orthoBottom = -vert; babylonCamera.orthoLeft = -horz; babylonCamera.orthoRight = horz; babylonCamera.mode = 1; } else { babylonCamera.mode = 0; } babylonCamera.metadata = metaData; 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; if (SceneController != null) { babylonCamera.applyGravity = (SceneController.sceneOptions.defaultGravity.y == 0 && SceneController.sceneOptions.defaultGravity.y == 0 && SceneController.sceneOptions.defaultGravity.z == 0) ? false : true; babylonCamera.ellipsoid = SceneController.sceneOptions.cameraEllipsoid.ToFloat(); } } // Lens Flares ParseLensFlares(gameObject, babylonCamera.id, ref lensFlares); // Particles Systems ParseParticleSystems(gameObject, babylonCamera.id, ref particleSystems); }
private void ConvertUnityLightToBabylon(Light light, GameObject gameObject, float progress, ref UnityMetaData metaData, ref List<BabylonExport.Entities.BabylonParticleSystem> particleSystems, ref List<UnityFlareSystem> lensFlares, ref string componentTags) { // No Inactive Or Baking Lights if (light.isActiveAndEnabled == false || light.type == LightType.Area || light.lightmappingMode == LightmappingMode.Baked) return; ExporterWindow.ReportProgress(progress, "Exporting light: " + light.name); BabylonLight babylonLight = new BabylonLight { name = light.name, id = GetID(light.gameObject), parentId = GetParentID(light.transform) }; metaData.type = "Light"; babylonLight.tags = componentTags; switch (light.type) { case LightType.Point: babylonLight.type = 0; babylonLight.range = light.range; break; case LightType.Directional: babylonLight.type = 1; break; case LightType.Spot: babylonLight.type = 2; break; } babylonLight.position = light.transform.localPosition.ToFloat(); var direction = new Vector3(0, 0, 1); var transformedDirection = light.transform.TransformDirection(direction); transformedDirection[0] += exportationOptions.LightRotationOffset.X; transformedDirection[1] += exportationOptions.LightRotationOffset.Y; transformedDirection[2] += exportationOptions.LightRotationOffset.Z; babylonLight.direction = transformedDirection.ToFloat(); babylonLight.diffuse = light.color.ToFloat(); babylonLight.intensity = light.intensity * exportationOptions.LightIntensityFactor; babylonLight.angle = light.spotAngle * (float)Math.PI / 180; babylonLight.exponent = 1.0f; babylonLight.metadata = metaData; babylonScene.LightsList.Add(babylonLight); // Animations ExportAnimations(light.transform, babylonLight); // Lens Flares ParseLensFlares(gameObject, babylonLight.id, ref lensFlares); // Particles Systems ParseParticleSystems(gameObject, babylonLight.id, ref particleSystems); // Shadow Maps if (exportationOptions.ExportShadows) { if ((light.type == LightType.Directional || light.type == LightType.Spot) && light.shadows != LightShadows.None) { GenerateShadowsGenerator(light, progress); } } }