private void ExportMaterial(Material materialNode, BabylonScene babylonScene)
        {
            var name = materialNode._Mtl.Name;
            var id = materialNode.GetGuid().ToString();

            RaiseMessage(name, true);

            if (materialNode.NumSubMaterials > 0)
            {
                var babylonMultimaterial = new BabylonMultiMaterial();
                babylonMultimaterial.name = name;
                babylonMultimaterial.id = id;

                var guids = new List<string>();

                for (var index = 0; index < materialNode.NumSubMaterials; index++)
                {
                    var subMat = materialNode.GetSubMaterial(index) as Material;

                    if (subMat != null)
                    {
                        guids.Add(subMat.GetGuid().ToString());

                        if (!referencedMaterials.Contains(subMat))
                        {
                            referencedMaterials.Add(subMat);
                            ExportMaterial(subMat, babylonScene);
                        }
                    }
                    else
                    {
                        guids.Add(Guid.Empty.ToString());
                    }
                }

                babylonMultimaterial.materials = guids.ToArray();

                babylonScene.MultiMaterialsList.Add(babylonMultimaterial);
                return;
            }


            var babylonMaterial = new BabylonMaterial();
            babylonMaterial.name = name;
            babylonMaterial.id = id;

            babylonMaterial.ambient = materialNode.GetAmbient(0).ToArray();
            babylonMaterial.diffuse = materialNode.GetDiffuse(0).ToArray();
            babylonMaterial.specular = materialNode.GetSpecular(0).Scale(materialNode.GetShinyStrength(0));
            babylonMaterial.specularPower = materialNode.GetShininess(0) * 256;

            babylonMaterial.emissive = materialNode.SelfIlluminationColorOn ? materialNode.GetSelfIllumColor(0).ToArray() : materialNode.GetDiffuse(0).Scale(materialNode.GetSelfIllumination(0));
            babylonMaterial.alpha = 1.0f - materialNode.GetTransparency(0);

            var stdMat = materialNode._Mtl.GetParamBlock(0).Owner as IStdMat2;

            if (stdMat != null)
            {
                // Textures
                babylonMaterial.ambientTexture = ExportTexture(stdMat, 0, babylonScene);    // Ambient
                babylonMaterial.diffuseTexture = ExportTexture(stdMat, 1, babylonScene);    // Diffuse
                babylonMaterial.specularTexture = ExportTexture(stdMat, 2, babylonScene);   // Specular
                babylonMaterial.emissiveTexture = ExportTexture(stdMat, 5, babylonScene);   // Emissive
                babylonMaterial.opacityTexture = ExportTexture(stdMat, 6, babylonScene);    // Opacity
                babylonMaterial.bumpTexture = ExportTexture(stdMat, 8, babylonScene);       // Bump
                babylonMaterial.reflectionTexture = ExportTexture(stdMat, 9, babylonScene); // Reflection

                // Constraints
                if (babylonMaterial.diffuseTexture != null)
                {
                    babylonMaterial.emissive = new [] { 1.0f, 1.0f, 1.0f };
                }

                if (babylonMaterial.emissiveTexture != null)
                {
                    babylonMaterial.emissive = new float[]{0, 0, 0};
                }

                if (babylonMaterial.opacityTexture != null && babylonMaterial.diffuseTexture != null &&
                    babylonMaterial.diffuseTexture.name == babylonMaterial.opacityTexture.name &&
                    babylonMaterial.diffuseTexture.hasAlpha && !babylonMaterial.opacityTexture.getAlphaFromRGB)
                {
                    // This is a alpha testing purpose
                    babylonMaterial.opacityTexture = null;
                    babylonMaterial.diffuseTexture.hasAlpha = true;
                    RaiseWarning("Opacity texture was removed because alpha from diffuse texture can be use instead", true);
                    RaiseWarning("If you do not want this behavior, just set Alpha Source = None on your diffuse texture", true);
                }
            }

            babylonScene.MaterialsList.Add(babylonMaterial);
        }
        private void ExportMaterial(IIGameMaterial materialNode, BabylonScene babylonScene)
        {
            var name = materialNode.MaterialName;
            var id = materialNode.MaxMaterial.GetGuid().ToString();

            RaiseMessage(name, 1);

            if (materialNode.SubMaterialCount > 0)
            {
                var babylonMultimaterial = new BabylonMultiMaterial { name = name, id = id };

                var guids = new List<string>();

                for (var index = 0; index < materialNode.SubMaterialCount; index++)
                {
                    var subMat = materialNode.GetSubMaterial(index);

                    if (subMat != null)
                    {
                        guids.Add(subMat.MaxMaterial.GetGuid().ToString());

                        if (!referencedMaterials.Contains(subMat))
                        {
                            referencedMaterials.Add(subMat);
                            ExportMaterial(subMat, babylonScene);
                        }
                    }
                    else
                    {
                        guids.Add(Guid.Empty.ToString());
                    }
                }

                babylonMultimaterial.materials = guids.ToArray();

                babylonScene.MultiMaterialsList.Add(babylonMultimaterial);
                return;
            }

            var babylonMaterial = new BabylonStandardMaterial
            {
                name = name,
                id = id,
                ambient = materialNode.MaxMaterial.GetAmbient(0, false).ToArray(),
                diffuse = materialNode.MaxMaterial.GetDiffuse(0, false).ToArray(),
                specular = materialNode.MaxMaterial.GetSpecular(0, false).Scale(materialNode.MaxMaterial.GetShinStr(0, false)),
                specularPower = materialNode.MaxMaterial.GetShininess(0, false) * 256,
                emissive =
                    materialNode.MaxMaterial.GetSelfIllumColorOn(0, false)
                        ? materialNode.MaxMaterial.GetSelfIllumColor(0, false).ToArray()
                        : materialNode.MaxMaterial.GetDiffuse(0, false).Scale(materialNode.MaxMaterial.GetSelfIllum(0, false)),
                alpha = 1.0f - materialNode.MaxMaterial.GetXParency(0, false)
            };


            var stdMat = materialNode.MaxMaterial.GetParamBlock(0).Owner as IStdMat2;

            if (stdMat != null)
            {
                babylonMaterial.backFaceCulling = !stdMat.TwoSided;
                babylonMaterial.wireframe = stdMat.Wire;

                // Textures
                BabylonFresnelParameters fresnelParameters;

                babylonMaterial.ambientTexture = ExportTexture(stdMat, 0, out fresnelParameters, babylonScene);                // Ambient
                babylonMaterial.diffuseTexture = ExportTexture(stdMat, 1, out fresnelParameters, babylonScene);                // Diffuse
                if (fresnelParameters != null)
                {
                    babylonMaterial.diffuseFresnelParameters = fresnelParameters;
                }

                babylonMaterial.specularTexture = ExportTexture(stdMat, 2, out fresnelParameters, babylonScene);               // Specular
                babylonMaterial.emissiveTexture = ExportTexture(stdMat, 5, out fresnelParameters, babylonScene);               // Emissive
                if (fresnelParameters != null)
                {
                    babylonMaterial.emissiveFresnelParameters = fresnelParameters;
                    if (babylonMaterial.emissive[0] == 0 &&
                        babylonMaterial.emissive[1] == 0 &&
                        babylonMaterial.emissive[2] == 0 &&
                        babylonMaterial.emissiveTexture == null)
                    {
                        babylonMaterial.emissive = new float[] { 1, 1, 1 };
                    }
                }

                babylonMaterial.opacityTexture = ExportTexture(stdMat, 6, out fresnelParameters, babylonScene, false, true);   // Opacity
                if (fresnelParameters != null)
                {
                    babylonMaterial.opacityFresnelParameters = fresnelParameters;
                    if (babylonMaterial.alpha == 1 &&
                         babylonMaterial.opacityTexture == null)
                    {
                        babylonMaterial.alpha = 0;
                    }
                }

                babylonMaterial.bumpTexture = ExportTexture(stdMat, 8, out fresnelParameters, babylonScene);                   // Bump
                babylonMaterial.reflectionTexture = ExportTexture(stdMat, 9, out fresnelParameters, babylonScene, true);       // Reflection
                if (fresnelParameters != null)
                {
                    if (babylonMaterial.reflectionTexture == null)
                    {
                        RaiseWarning("Fallout cannot be used with reflection channel without a texture", 2);
                    }
                    else
                    {
                        babylonMaterial.reflectionFresnelParameters = fresnelParameters;
                    }
                }

                // Constraints
                if (babylonMaterial.diffuseTexture != null)
                {
                    babylonMaterial.diffuse = new[] { 1.0f, 1.0f, 1.0f };
                }

                if (babylonMaterial.emissiveTexture != null)
                {
                    babylonMaterial.emissive = new float[] { 0, 0, 0 };
                }

                if (babylonMaterial.opacityTexture != null && babylonMaterial.diffuseTexture != null &&
                    babylonMaterial.diffuseTexture.name == babylonMaterial.opacityTexture.name &&
                    babylonMaterial.diffuseTexture.hasAlpha && !babylonMaterial.opacityTexture.getAlphaFromRGB)
                {
                    // This is a alpha testing purpose
                    babylonMaterial.opacityTexture = null;
                    babylonMaterial.diffuseTexture.hasAlpha = true;
                    RaiseWarning("Opacity texture was removed because alpha from diffuse texture can be use instead", 2);
                    RaiseWarning("If you do not want this behavior, just set Alpha Source = None on your diffuse texture", 2);
                }
            }

            babylonScene.MaterialsList.Add(babylonMaterial);
        }
        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: " + gameObject.name);

            babylonMesh.name = gameObject.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;
                }
            }
        }
        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;
        }
Exemple #5
0
 public BabylonMultiMaterial(BabylonMultiMaterial original)
 {
     name      = original.name;
     id        = original.id;
     materials = (string[])original.materials.Clone();
 }