public override void OnInspectorGUI()
    {
        DrawDefaultInspector();

        MultiTextureMaterial mat = (MultiTextureMaterial)target;

        mat.textureIndex = EditorGUILayout.Popup(mat.textureIndex, mat.textureNames);
    }
Example #2
0
        private void CreateUnityMesh()
        {
            for (uint i = 0; i < num_sprites; i++)
            {
                Mesh      meshUnity = new Mesh();
                Vector3[] vertices  = new Vector3[4];
                vertices[0] = new Vector3(-sprites[i].size.x / 2f, -sprites[i].size.y / 2f, 0);
                vertices[1] = new Vector3(sprites[i].size.x / 2f, -sprites[i].size.y / 2f, 0);
                vertices[2] = new Vector3(-sprites[i].size.x / 2f, sprites[i].size.y / 2f, 0);
                vertices[3] = new Vector3(sprites[i].size.x / 2f, sprites[i].size.y / 2f, 0);
                Vector3[] normals = new Vector3[4];
                normals[0] = Vector3.forward;
                normals[1] = Vector3.forward;
                normals[2] = Vector3.forward;
                normals[3] = Vector3.forward;
                Vector2[] uvs = new Vector2[4];
                uvs[0] = new Vector2(0, 0);
                uvs[1] = new Vector2(1, 0);
                uvs[2] = new Vector2(0, 1);
                uvs[3] = new Vector2(1, 1);
                int[] triangles = new int[] { 0, 2, 1, 1, 2, 3 };

                meshUnity.vertices  = vertices;
                meshUnity.normals   = normals;
                meshUnity.triangles = triangles;
                meshUnity.uv        = uvs;


                GameObject spr_gao = new GameObject(name + " - Sprite " + i);
                spr_gao.transform.SetParent(gao.transform);
                MeshFilter mf = spr_gao.AddComponent <MeshFilter>();
                mf.mesh = meshUnity;
                MeshRenderer mr = spr_gao.AddComponent <MeshRenderer>();
                if (sprites[i].r3mat != null)
                {
                    Material unityMat       = sprites[i].r3mat.Material;
                    bool     receiveShadows = (sprites[i].r3mat.properties & VisualMaterial.property_receiveShadows) != 0;
                    //if (num_uvMaps > 1) unityMat.SetFloat("_UVSec", 50f);
                    //if (r3mat.Material.GetColor("_EmissionColor") != Color.black) print("Mesh with emission: " + name);
                    mr.material = unityMat;
                    if (!receiveShadows)
                    {
                        mr.receiveShadows = false;
                    }
                    if (sprites[i].r3mat.off_animTextures.Count > 0)
                    {
                        MultiTextureMaterial mtmat = mr.gameObject.AddComponent <MultiTextureMaterial>();
                        mtmat.r3mat = sprites[i].r3mat;
                        mtmat.mat   = mr.material;
                    }
                }
                if (sprites[i].r3mat != null)
                {
                    mr.material = sprites[i].r3mat.Material;
                }
            }
        }
Example #3
0
        private void CreateUnityMesh()
        {
            /*if (mesh.bones != null) {
             *  for (int j = 0; j < mesh.bones.num_bones; j++) {
             *      Transform b = mesh.bones.bones[j];
             *      b.transform.SetParent(gao.transform);
             *      mesh.bones.bindPoses[j] = mesh.bones.bones[j].worldToLocalMatrix * gao.transform.localToWorldMatrix;
             *  }
             * }*/
            VisualMaterial.Hint materialHints = Mesh.lookAtMode != 0 ? VisualMaterial.Hint.Billboard : VisualMaterial.Hint.None;
            //VisualMaterial.Hint materialHints = VisualMaterial.Hint.None;
            uint num_textures = 0;

            if (visualMaterial != null)
            {
                num_textures = visualMaterial.num_textures;
            }

            long num_triangles_main = ((num_connected_vertices > 2 ? num_connected_vertices - 2 : 0) + num_disconnected_triangles) * (backfaceCulling ? 1 : 2);
            uint triangle_size      = 3 * (uint)(backfaceCulling ? 1 : 2);
            uint triangles_index    = 0;

            if (num_triangles_main > 0)
            {
                Vector3[]    new_vertices    = new Vector3[num_mapping_entries];
                Vector3[]    new_normals     = new Vector3[num_mapping_entries];
                Vector4[][]  new_uvs         = new Vector4[num_textures + (vertexColors != null ? 1 : 0)][]; // Thanks to Unity we can only store the blend weights as a third component of the UVs
                BoneWeight[] new_boneWeights = Mesh.bones != null ? new BoneWeight[num_mapping_entries] : null;
                for (int um = 0; um < num_textures; um++)
                {
                    new_uvs[um] = new Vector4[num_mapping_entries];
                }
                if (vertexColors != null)
                {
                    new_uvs[num_textures] = new Vector4[num_mapping_entries];
                    for (int i = 0; i < num_mapping_entries; i++)
                    {
                        new_uvs[num_textures][i] = new Vector4(vertexColors[i].r, vertexColors[i].g, vertexColors[i].b, vertexColors[i].a);
                    }
                }
                for (int j = 0; j < num_mapping_entries; j++)
                {
                    new_vertices[j] = Mesh.vertices[mapping_vertices[j]];
                    if (Mesh.normals != null)
                    {
                        new_normals[j] = Mesh.normals[mapping_vertices[j]];
                    }
                    if (new_boneWeights != null)
                    {
                        new_boneWeights[j] = Mesh.bones.weights[mapping_vertices[j]];
                    }
                    for (int um = 0; um < num_textures; um++)
                    {
                        uint uvMap = (uint)visualMaterial.textures[um].uvFunction % num_uvMaps;
                        //MapLoader.Loader.print(visualMaterial.textures[um].uvFunction + " - " + num_uvMaps);
                        new_uvs[um][j] = uvs[mapping_uvs[uvMap][j]];
                        if (Mesh.blendWeights != null && Mesh.blendWeights[visualMaterial.textures[um].blendIndex] != null)
                        {
                            if (um == 0)
                            {
                                materialHints |= VisualMaterial.Hint.Transparent;
                            }
                            new_uvs[um][j].z = Mesh.blendWeights[visualMaterial.textures[um].blendIndex][mapping_vertices[j]];
                        }
                        else
                        {
                            new_uvs[um][j].z = 1;
                        }
                    }
                }
                int[] triangles = new int[num_triangles_main * triangle_size];
                if (num_connected_vertices > 2)
                {
                    for (int j = 0; j < num_connected_vertices - 2; j++, triangles_index += triangle_size)
                    {
                        if (j % 2 == 0)
                        {
                            triangles[triangles_index + 0] = connected_vertices[j + 0];
                            triangles[triangles_index + 1] = connected_vertices[j + 2];
                            triangles[triangles_index + 2] = connected_vertices[j + 1];
                        }
                        else
                        {
                            triangles[triangles_index + 0] = connected_vertices[j + 0];
                            triangles[triangles_index + 1] = connected_vertices[j + 1];
                            triangles[triangles_index + 2] = connected_vertices[j + 2];
                        }
                        if (!backfaceCulling)
                        {
                            triangles[triangles_index + 3] = triangles[triangles_index + 0];
                            triangles[triangles_index + 4] = triangles[triangles_index + 2];
                            triangles[triangles_index + 5] = triangles[triangles_index + 1];
                        }
                    }
                }
                if (num_connected_vertices < 2)
                {
                    num_connected_vertices = 0;
                }
                if (num_disconnected_triangles > 0)
                {
                    //print("Loading disconnected triangles at " + String.Format("0x{0:X}", fs.Position));
                    for (int j = 0; j < num_disconnected_triangles; j++, triangles_index += triangle_size)
                    {
                        triangles[triangles_index + 0] = disconnected_triangles[(j * 3) + 0];
                        triangles[triangles_index + 2] = disconnected_triangles[(j * 3) + 1];
                        triangles[triangles_index + 1] = disconnected_triangles[(j * 3) + 2];
                        if (!backfaceCulling)
                        {
                            triangles[triangles_index + 3] = triangles[triangles_index + 0];
                            triangles[triangles_index + 4] = triangles[triangles_index + 2];
                            triangles[triangles_index + 5] = triangles[triangles_index + 1];
                        }
                    }
                }
                if (mesh_main == null)
                {
                    mesh_main          = new Mesh();
                    mesh_main.vertices = new_vertices;
                    if (Mesh.normals != null)
                    {
                        mesh_main.normals = new_normals;
                    }
                    mesh_main.triangles = triangles;
                    if (new_boneWeights != null)
                    {
                        mesh_main.boneWeights = new_boneWeights;
                        mesh_main.bindposes   = Mesh.bones.bindPoses;
                    }
                    for (int i = 0; i < new_uvs.Length; i++)
                    {
                        mesh_main.SetUVs(i, new_uvs[i].ToList());
                    }
                }
                else
                {
                    mesh_main = CopyMesh(mesh_main);
                }
                if (new_boneWeights != null)
                {
                    mr_main              = gao.AddComponent <SkinnedMeshRenderer>();
                    s_mr_main            = (SkinnedMeshRenderer)mr_main;
                    s_mr_main.bones      = Mesh.bones.bones;
                    s_mr_main.rootBone   = Mesh.bones.bones[0];
                    s_mr_main.sharedMesh = CopyMesh(mesh_main);

                    BoxCollider bc = gao.AddComponent <BoxCollider>();
                    bc.center = s_mr_main.bounds.center;
                    bc.size   = s_mr_main.bounds.size;
                }
                else
                {
                    MeshFilter mf = gao.AddComponent <MeshFilter>();
                    mf.sharedMesh = mesh_main;
                    mr_main       = gao.AddComponent <MeshRenderer>();
                    MeshCollider mc = gao.AddComponent <MeshCollider>();
                    mc.isTrigger  = false;
                    mc.sharedMesh = mesh_main;
                }
            }
            if (num_disconnected_triangles_spe > 0)
            {
                Vector3[]    new_vertices_spe    = new Vector3[num_disconnected_triangles_spe * 3];
                Vector3[]    new_normals_spe     = new Vector3[num_disconnected_triangles_spe * 3];
                Vector3[][]  new_uvs_spe         = new Vector3[num_textures][];
                BoneWeight[] new_boneWeights_spe = Mesh.bones != null ? new BoneWeight[num_disconnected_triangles_spe * 3] : null;
                for (int um = 0; um < num_textures; um++)
                {
                    new_uvs_spe[um] = new Vector3[num_disconnected_triangles_spe * 3];
                }
                int[] triangles_spe = new int[num_disconnected_triangles_spe * triangle_size];
                triangles_index = 0;
                for (int um = 0; um < num_textures; um++)
                {
                    for (int j = 0; j < num_disconnected_triangles_spe * 3; j++)
                    {
                        uint uvMap = (uint)visualMaterial.textures[um].uvFunction % num_uvMaps;
                        if (uvs != null)
                        {
                            new_uvs_spe[um][j] = uvs[mapping_uvs_spe[uvMap][j]];
                        }
                        new_uvs_spe[um][j].z = 1;

                        /*int i0 = reader.ReadInt16(), m0 = (j * 3) + 0; // Old index, mapped index
                         * int i1 = reader.ReadInt16(), m1 = (j * 3) + 1;
                         * int i2 = reader.ReadInt16(), m2 = (j * 3) + 2;
                         * new_uvs_spe[um][m0] = uvs[i0];
                         * new_uvs_spe[um][m1] = uvs[i1];
                         * new_uvs_spe[um][m2] = uvs[i2];*/
                    }
                }
                //print("Loading disconnected triangles at " + String.Format("0x{0:X}", fs.Position));
                for (int j = 0; j < num_disconnected_triangles_spe; j++, triangles_index += triangle_size)
                {
                    int i0 = disconnected_triangles_spe[(j * 3) + 0], m0 = (j * 3) + 0; // Old index, mapped index
                    int i1 = disconnected_triangles_spe[(j * 3) + 1], m1 = (j * 3) + 1;
                    int i2 = disconnected_triangles_spe[(j * 3) + 2], m2 = (j * 3) + 2;

                    new_vertices_spe[m0] = Mesh.vertices[i0];
                    new_vertices_spe[m1] = Mesh.vertices[i1];
                    new_vertices_spe[m2] = Mesh.vertices[i2];

                    if (Mesh.normals != null)
                    {
                        new_normals_spe[m0] = Mesh.normals[i0];
                        new_normals_spe[m1] = Mesh.normals[i1];
                        new_normals_spe[m2] = Mesh.normals[i2];
                    }

                    if (new_boneWeights_spe != null)
                    {
                        new_boneWeights_spe[m0] = Mesh.bones.weights[i0];
                        new_boneWeights_spe[m1] = Mesh.bones.weights[i1];
                        new_boneWeights_spe[m2] = Mesh.bones.weights[i2];
                    }
                    if (Mesh.blendWeights != null)
                    {
                        for (int um = 0; um < num_textures; um++)
                        {
                            if (Mesh.blendWeights[visualMaterial.textures[um].blendIndex] != null)
                            {
                                if (um == 0)
                                {
                                    materialHints |= VisualMaterial.Hint.Transparent;
                                }
                                new_uvs_spe[um][m0].z = Mesh.blendWeights[visualMaterial.textures[um].blendIndex][i0];
                                new_uvs_spe[um][m1].z = Mesh.blendWeights[visualMaterial.textures[um].blendIndex][i1];
                                new_uvs_spe[um][m2].z = Mesh.blendWeights[visualMaterial.textures[um].blendIndex][i2];
                            }
                        }
                    }
                    triangles_spe[triangles_index + 0] = m0;
                    triangles_spe[triangles_index + 1] = m2;
                    triangles_spe[triangles_index + 2] = m1;
                    if (!backfaceCulling)
                    {
                        triangles_spe[triangles_index + 3] = triangles_spe[triangles_index + 0];
                        triangles_spe[triangles_index + 4] = triangles_spe[triangles_index + 2];
                        triangles_spe[triangles_index + 5] = triangles_spe[triangles_index + 1];
                    }
                }
                //if (mr_main == null) {
                GameObject gao_spe = (mr_main == null ? gao : new GameObject("[SPE]"));
                if (gao_spe != gao)
                {
                    gao_spe.transform.SetParent(gao.transform);
                }
                else
                {
                    gao.name = "[SPE] " + gao.name;
                }
                if (mesh_spe == null)
                {
                    mesh_spe           = new Mesh();
                    mesh_spe.vertices  = new_vertices_spe;
                    mesh_spe.normals   = new_normals_spe;
                    mesh_spe.triangles = triangles_spe;
                    if (new_boneWeights_spe != null)
                    {
                        mesh_spe.boneWeights = new_boneWeights_spe;
                        mesh_spe.bindposes   = Mesh.bones.bindPoses;
                    }
                    for (int i = 0; i < num_textures; i++)
                    {
                        mesh_spe.SetUVs(i, new_uvs_spe[i].ToList());
                    }
                }
                else
                {
                    mesh_spe = CopyMesh(mesh_spe);
                }
                //mesh.SetUVs(0, new_uvs_spe.ToList());
                /*mesh.uv = new_uvs_spe;*/
                if (new_boneWeights_spe != null)
                {
                    mr_spe              = gao_spe.AddComponent <SkinnedMeshRenderer>();
                    s_mr_spe            = (SkinnedMeshRenderer)mr_spe;
                    s_mr_spe.bones      = Mesh.bones.bones;
                    s_mr_spe.rootBone   = Mesh.bones.bones[0];
                    s_mr_spe.sharedMesh = CopyMesh(mesh_spe);

                    BoxCollider bc = gao_spe.AddComponent <BoxCollider>();
                    bc.center = s_mr_spe.bounds.center;
                    bc.size   = s_mr_spe.bounds.size;
                }
                else
                {
                    MeshFilter mf = gao_spe.AddComponent <MeshFilter>();
                    mf.sharedMesh = mesh_spe;
                    mr_spe        = gao_spe.AddComponent <MeshRenderer>();
                    MeshCollider mc = gao_spe.AddComponent <MeshCollider>();
                    mc.isTrigger  = false;
                    mc.sharedMesh = mesh_spe;
                }
                //}
            }
            if (visualMaterial != null)
            {
                //gao.name += " " + visualMaterial.offset + " - " + (visualMaterial.textures.Count > 0 ? visualMaterial.textures[0].offset.ToString() : "NULL" );
                Material unityMat = visualMaterial.GetMaterial(materialHints);
                if (vertexColors != null & unityMat != null)
                {
                    unityMat.SetVector("_Tex2Params", new Vector4(60, 0, 0, 0));
                }
                bool receiveShadows = (visualMaterial.properties & VisualMaterial.property_receiveShadows) != 0;
                bool scroll         = visualMaterial.ScrollingEnabled;

                /*if (num_uvMaps > 1) {
                 *  unityMat.SetFloat("_UVSec", 1f);
                 * } else if (scroll) {
                 *  for (int i = num_uvMaps; i < visualMaterial.textures.Count; i++) {
                 *      if (visualMaterial.textures[i].ScrollingEnabled) {
                 *          unityMat.SetFloat("_UVSec", 1f);
                 *          break;
                 *      }
                 *  }
                 * }*/
                //if (r3mat.Material.GetColor("_EmissionColor") != Color.black) print("Mesh with emission: " + name);
                if (mr_main != null)
                {
                    mr_main.sharedMaterial = unityMat;
                    //mr_main.UpdateGIMaterials();
                    if (!receiveShadows)
                    {
                        mr_main.receiveShadows = false;
                    }
                    if (visualMaterial.animTextures.Count > 0)
                    {
                        MultiTextureMaterial mtmat = mr_main.gameObject.AddComponent <MultiTextureMaterial>();
                        mtmat.visMat = visualMaterial;
                        mtmat.mat    = mr_main.sharedMaterial;
                    }

                    /*if (scroll) {
                     *  ScrollingTexture scrollComponent = mr_main.gameObject.AddComponent<ScrollingTexture>();
                     *  scrollComponent.visMat = visualMaterial;
                     *  scrollComponent.mat = mr_main.material;
                     * }*/
                }
                if (mr_spe != null)
                {
                    mr_spe.sharedMaterial = unityMat;
                    //mr_spe.UpdateGIMaterials();
                    if (!receiveShadows)
                    {
                        mr_spe.receiveShadows = false;
                    }
                    if (visualMaterial.animTextures.Count > 0)
                    {
                        MultiTextureMaterial mtmat = mr_spe.gameObject.AddComponent <MultiTextureMaterial>();
                        mtmat.visMat = visualMaterial;
                        mtmat.mat    = mr_spe.sharedMaterial;
                    }

                    /*if (scroll) {
                     *  ScrollingTexture scrollComponent = mr_spe.gameObject.AddComponent<ScrollingTexture>();
                     *  scrollComponent.visMat = visualMaterial;
                     *  scrollComponent.mat = mr_spe.material;
                     * }*/
                }
            }
        }
Example #4
0
    void UpdateAnimations()
    {
        if (cont.LoadState == Controller.State.Finished)
        {
            /*if(MapLoader.Loader.visualMaterials != null) {
             *      for (int i = 0; i < MapLoader.Loader.visualMaterials.Count; i++) {
             *              VisualMaterial vm = MapLoader.Loader.visualMaterials[i];
             *              if (vm.animTextures.Count > 0 && !vm.IsLockedAnimatedTexture) {
             *                      vm.currentAnimTexture %= vm.animTextures.Count;
             *                      vm.animTextures[vm.currentAnimTexture].currentTime += updateCounter * modifier;
             *                      while (vm.animTextures[vm.currentAnimTexture].currentTime > vm.animTextures[vm.currentAnimTexture].time) {
             *                              float rest = vm.animTextures[vm.currentAnimTexture].currentTime - vm.animTextures[vm.currentAnimTexture].time;
             *                              vm.animTextures[vm.currentAnimTexture].currentTime = 0;
             *                              if (vm.animTextures[vm.currentAnimTexture].time <= 0) break;
             *                              vm.currentAnimTexture = (vm.currentAnimTexture + 1) % vm.animTextures.Count;
             *                              vm.animTextures[vm.currentAnimTexture].currentTime = rest;
             *                      }
             *              }
             *      }
             * }*/
            for (int i = 0; i < materials.Count; i++)
            {
                MultiTextureMaterial mtm = materials[i];
                if (mtm != null)
                {
                    if (mtm.visMat != null)
                    {
                        VisualMaterial vm = mtm.visMat;
                        if (vm.animTextures.Count > 0 && !vm.IsLockedAnimatedTexture)
                        {
                            vm.currentAnimTexture %= vm.animTextures.Count;
                            vm.animTextures[vm.currentAnimTexture].currentTime += updateCounter * modifier;
                            float time = vm.animTextures[vm.currentAnimTexture].time;
                            if (!UnitySettings.IsRaymapGame && time <= 0)
                            {
                                time = defaultTime;
                            }
                            while (vm.animTextures[vm.currentAnimTexture].currentTime > time)
                            {
                                time = vm.animTextures[vm.currentAnimTexture].time;
                                if (!UnitySettings.IsRaymapGame && time <= 0)
                                {
                                    time = defaultTime;
                                }

                                float rest = vm.animTextures[vm.currentAnimTexture].currentTime - time;
                                vm.animTextures[vm.currentAnimTexture].currentTime = 0;
                                if (time <= 0)
                                {
                                    break;
                                }
                                vm.currentAnimTexture = (vm.currentAnimTexture + 1) % vm.animTextures.Count;
                                vm.animTextures[vm.currentAnimTexture].currentTime = rest;
                            }
                        }
                    }
                    else if (mtm.visMatROM != null)
                    {
                        OpenSpace.ROM.VisualMaterial vm = mtm.visMatROM;
                        if (vm.num_textures > 0)                          // && !vm.IsLockedAnimatedTexture) {
                        {
                            mtm.CurrentTextureROM     %= vm.num_textures;
                            mtm.CurrentTextureROMTime += updateCounter * modifier;
                            float animTime = vm.textures.Value.vmTex[mtm.CurrentTextureROM].time / 30f;
                            while (mtm.CurrentTextureROMTime > animTime)
                            {
                                float rest = mtm.CurrentTextureROMTime - animTime;
                                //mtm.CurrentTextureROMTime = 0;
                                if (animTime <= 0)
                                {
                                    break;
                                }
                                mtm.CurrentTextureROM     = (mtm.CurrentTextureROM + 1) % vm.num_textures;
                                mtm.CurrentTextureROMTime = rest;
                                animTime = vm.textures.Value.vmTex[mtm.CurrentTextureROM].time / 30f;
                            }
                        }
                    }
                }
            }
            materials.RemoveAll(m => m == null || m.gameObject == null);
        }
    }
Example #5
0
 public void Register(MultiTextureMaterial mat)
 {
     materials.Add(mat);
 }
Example #6
0
        private void CreateUnityMesh()
        {
            for (uint i = 0; i < num_sprites; i++)
            {
                bool       mirrorX = false;
                bool       mirrorY = false;
                GameObject spr_gao = new GameObject("SpriteElement" + i);
                spr_gao.transform.SetParent(gao.transform);
                MeshFilter   mf = spr_gao.AddComponent <MeshFilter>();
                MeshRenderer mr = spr_gao.AddComponent <MeshRenderer>();
                BoxCollider  bc = spr_gao.AddComponent <BoxCollider>();
                bc.size       = new Vector3(0, sprites[i].info_scale.y * 2, sprites[i].info_scale.x * 2);
                spr_gao.layer = LayerMask.NameToLayer("Visual");
                if (sprites[i].visualMaterial != null)
                {
                    if (Controller.Settings.game != Settings.Game.R2Revolution &&
                        sprites[i].visualMaterial.textures != null &&
                        sprites[i].visualMaterial.textures.Count > 0)
                    {
                        TextureInfo mainTex = sprites[i].visualMaterial.textures[0].texture;

                        if (mainTex != null && mainTex.IsMirrorX)
                        {
                            mirrorX = true;
                        }
                        if (mainTex != null && mainTex.IsMirrorY)
                        {
                            mirrorY = true;
                        }
                    }
                    //Material unityMat = sprites[i].visualMaterial.MaterialBillboard;
                    Material unityMat       = sprites[i].visualMaterial.GetMaterial(VisualMaterial.Hint.Billboard);
                    bool     receiveShadows = (sprites[i].visualMaterial.properties & VisualMaterial.property_receiveShadows) != 0;
                    //if (num_uvMaps > 1) unityMat.SetFloat("_UVSec", 50f);
                    //if (r3mat.Material.GetColor("_EmissionColor") != Color.black) print("Mesh with emission: " + name);
                    mr.sharedMaterial = unityMat;

                    /*mr.material.SetFloat("_ScaleX", sprites[i].info_scale.x);
                    *  mr.material.SetFloat("_ScaleY", sprites[i].info_scale.y);*/
                    if (!receiveShadows)
                    {
                        mr.receiveShadows = false;
                    }
                    if (sprites[i].visualMaterial.animTextures.Count > 0)
                    {
                        MultiTextureMaterial mtmat = mr.gameObject.AddComponent <MultiTextureMaterial>();
                        mtmat.visMat = sprites[i].visualMaterial;
                        mtmat.mat    = mr.sharedMaterial;
                    }
                }
                else
                {
                    Material  transMat = new Material(Controller.VisualMaterialManager.baseTransparentMaterial);
                    Texture2D tex      = new Texture2D(1, 1);
                    tex.SetPixel(0, 0, new Color(0, 0, 0, 0));
                    transMat.SetTexture("_Tex0", tex);
                    mr.sharedMaterial = transMat;
                }
                if (sprites[i].meshUnity == null)
                {
                    sprites[i].meshUnity = new Mesh();
                    Vector3[] vertices = new Vector3[4];
                    vertices[0] = new Vector3(0, -sprites[i].info_scale.y, -sprites[i].info_scale.x);
                    vertices[1] = new Vector3(0, -sprites[i].info_scale.y, sprites[i].info_scale.x);
                    vertices[2] = new Vector3(0, sprites[i].info_scale.y, -sprites[i].info_scale.x);
                    vertices[3] = new Vector3(0, sprites[i].info_scale.y, sprites[i].info_scale.x);
                    Vector3[] normals = new Vector3[4];
                    normals[0] = Vector3.forward;
                    normals[1] = Vector3.forward;
                    normals[2] = Vector3.forward;
                    normals[3] = Vector3.forward;
                    Vector3[] uvs = new Vector3[4];
                    uvs[0] = new Vector3(0, 0 - (mirrorY ? 1 : 0), 1);
                    uvs[1] = new Vector3(1 + (mirrorX ? 1 : 0), 0 - (mirrorY ? 1 : 0), 1);
                    uvs[2] = new Vector3(0, 1, 1);
                    uvs[3] = new Vector3(1 + (mirrorX ? 1 : 0), 1, 1);
                    int[] triangles = new int[] { 0, 2, 1, 1, 2, 3 };

                    sprites[i].meshUnity.vertices  = vertices;
                    sprites[i].meshUnity.normals   = normals;
                    sprites[i].meshUnity.triangles = triangles;
                    sprites[i].meshUnity.SetUVs(0, uvs.ToList());
                }


                mf.sharedMesh = sprites[i].meshUnity;
            }
        }
Example #7
0
        public Material GetMaterial(Hint hints, GameObject gao = null)
        {
            Material mat;
            bool     billboard = (hints & Hint.Billboard) == Hint.Billboard;

            if (textures.Value != null && num_textures > 0)
            {
                TextureInfo texInfo = textures.Value.vmTex[0].texRef.Value.texInfo;
                if (texInfo.RenderTransparent || texInfo.RenderWater1 || texInfo.RenderWater2)
                {
                    if (texInfo.AlphaIsTransparency || texInfo.RenderWater1 || texInfo.RenderWater2)
                    {
                        mat = new Material(MapLoader.Loader.baseTransparentMaterial);
                    }
                    else
                    {
                        mat = new Material(MapLoader.Loader.baseLightMaterial);
                    }
                }
                else
                {
                    mat = new Material(MapLoader.Loader.baseMaterial);
                }
                mat.SetInt("_NumTextures", 1);
                string textureName = "_Tex0";
                mat.SetTexture(textureName, textures.Value.vmTex[0].texRef.Value.texInfo.Value.Texture);
                mat.SetVector(textureName + "Params", new Vector4(0,
                                                                  (scrollSpeedX != 0 || scrollSpeedY != 0) ? 1f : 0f,
                                                                  0f, 0f));
                mat.SetVector(textureName + "Params2", new Vector4(
                                  0f, 0f, ScrollX, ScrollY));
            }
            else
            {
                mat = new Material(MapLoader.Loader.baseMaterial);
            }
            Vector4 ambient, diffuse;

            if (Settings.s.platform == Settings.Platform.N64)
            {
                ambient = new Vector4(0.25f, 0.25f, 0.25f, 1f);
                diffuse = new Vector4(r / 255f, g / 255f, b / 255f, a / 255f);
            }
            else
            {
                ambient = ParseColorRGBA5551(ambientCoef) + new Vector4(0.25f, 0.25f, 0.25f, 1f);
                diffuse = ParseColorRGBA5551(diffuseCoef) + new Vector4(0, 0, 0, 1f);
            }
            mat.SetVector("_AmbientCoef", ambient);
            mat.SetVector("_DiffuseCoef", diffuse);
            if (billboard)
            {
                mat.SetFloat("_Billboard", 1f);
            }
            if (gao != null && num_textures > 1)
            {
                MultiTextureMaterial mtmat = gao.AddComponent <MultiTextureMaterial>();
                mtmat.visMatROM = this;
                mtmat.mat       = mat;
            }
            return(mat);
        }
Example #8
0
        private void CreateUnityMesh()
        {
            /*if (mesh.bones != null) {
             *  for (int j = 0; j < mesh.bones.num_bones; j++) {
             *      Transform b = mesh.bones.bones[j];
             *      b.transform.SetParent(gao.transform);
             *      mesh.bones.bindPoses[j] = mesh.bones.bones[j].worldToLocalMatrix * gao.transform.localToWorldMatrix;
             *  }
             * }*/

            Renderer mr_main = null, mr_spe = null;
            long     num_triangles_main = ((num_connected_vertices > 2 ? num_connected_vertices - 2 : 0) + num_disconnected_triangles) * (backfaceCulling ? 1 : 2);
            uint     triangle_size      = 3 * (uint)(backfaceCulling ? 1 : 2);
            uint     triangles_index    = 0;

            if (num_triangles_main > 0)
            {
                Vector3[]    new_vertices    = new Vector3[num_mapping_entries];
                Vector3[]    new_normals     = new Vector3[num_mapping_entries];
                Vector3[][]  new_uvs         = new Vector3[num_uvMaps][]; // Thanks to Unity we can only store the blend weights as a third component of the UVs
                BoneWeight[] new_boneWeights = mesh.bones != null ? new BoneWeight[num_mapping_entries] : null;
                for (int um = 0; um < num_uvMaps; um++)
                {
                    new_uvs[um] = new Vector3[num_mapping_entries];
                }
                for (int j = 0; j < num_mapping_entries; j++)
                {
                    new_vertices[j] = mesh.vertices[mapping_vertices[j]];
                    new_normals[j]  = mesh.normals[mapping_vertices[j]];
                    if (new_boneWeights != null)
                    {
                        new_boneWeights[j] = mesh.bones.weights[mapping_vertices[j]];
                    }
                    for (int um = 0; um < num_uvMaps; um++)
                    {
                        new_uvs[um][j] = uvs[mapping_uvs[um][j]];
                        if (mesh.blendWeights != null)
                        {
                            new_uvs[um][j].z = mesh.blendWeights[mapping_vertices[j]];
                        }
                    }
                }
                int[] triangles = new int[num_triangles_main * triangle_size];
                if (num_connected_vertices > 2)
                {
                    for (int j = 0; j < num_connected_vertices - 2; j++, triangles_index += triangle_size)
                    {
                        if (j % 2 == 0)
                        {
                            triangles[triangles_index + 0] = connected_vertices[j + 0];
                            triangles[triangles_index + 1] = connected_vertices[j + 2];
                            triangles[triangles_index + 2] = connected_vertices[j + 1];
                        }
                        else
                        {
                            triangles[triangles_index + 0] = connected_vertices[j + 0];
                            triangles[triangles_index + 1] = connected_vertices[j + 1];
                            triangles[triangles_index + 2] = connected_vertices[j + 2];
                        }
                        if (!backfaceCulling)
                        {
                            triangles[triangles_index + 3] = triangles[triangles_index + 0];
                            triangles[triangles_index + 4] = triangles[triangles_index + 2];
                            triangles[triangles_index + 5] = triangles[triangles_index + 1];
                        }
                    }
                }
                if (num_connected_vertices < 2)
                {
                    num_connected_vertices = 0;
                }
                if (num_disconnected_triangles > 0)
                {
                    //print("Loading disconnected triangles at " + String.Format("0x{0:X}", fs.Position));
                    for (int j = 0; j < num_disconnected_triangles; j++, triangles_index += triangle_size)
                    {
                        triangles[triangles_index + 0] = disconnected_triangles[(j * 3) + 0];
                        triangles[triangles_index + 2] = disconnected_triangles[(j * 3) + 1];
                        triangles[triangles_index + 1] = disconnected_triangles[(j * 3) + 2];
                        if (!backfaceCulling)
                        {
                            triangles[triangles_index + 3] = triangles[triangles_index + 0];
                            triangles[triangles_index + 4] = triangles[triangles_index + 2];
                            triangles[triangles_index + 5] = triangles[triangles_index + 1];
                        }
                    }
                }
                mesh_main           = new Mesh();
                mesh_main.vertices  = new_vertices;
                mesh_main.normals   = new_normals;
                mesh_main.triangles = triangles;
                if (new_boneWeights != null)
                {
                    mesh_main.boneWeights = new_boneWeights;
                    mesh_main.bindposes   = mesh.bones.bindPoses;
                }
                for (int i = 0; i < num_uvMaps; i++)
                {
                    mesh_main.SetUVs(i, new_uvs[i].ToList());
                }
                if (new_boneWeights != null)
                {
                    mr_main              = gao.AddComponent <SkinnedMeshRenderer>();
                    s_mr_main            = (SkinnedMeshRenderer)mr_main;
                    s_mr_main.bones      = mesh.bones.bones;
                    s_mr_main.rootBone   = mesh.bones.bones[0];
                    s_mr_main.sharedMesh = CopyMesh(mesh_main);
                }
                else
                {
                    MeshFilter mf = gao.AddComponent <MeshFilter>();
                    mf.mesh = mesh_main;
                    mr_main = gao.AddComponent <MeshRenderer>();
                }
            }
            if (num_disconnected_triangles_spe > 0)
            {
                Vector3[]    new_vertices_spe    = new Vector3[num_disconnected_triangles_spe * 3];
                Vector3[]    new_normals_spe     = new Vector3[num_disconnected_triangles_spe * 3];
                Vector3[][]  new_uvs_spe         = new Vector3[num_uvMaps][];
                BoneWeight[] new_boneWeights_spe = mesh.bones != null ? new BoneWeight[num_disconnected_triangles_spe * 3] : null;
                for (int um = 0; um < num_uvMaps; um++)
                {
                    new_uvs_spe[um] = new Vector3[num_disconnected_triangles_spe * 3];
                }
                int[] triangles_spe = new int[num_disconnected_triangles_spe * triangle_size];
                triangles_index = 0;
                for (int um = 0; um < num_uvMaps; um++)
                {
                    for (int j = 0; j < num_disconnected_triangles_spe * 3; j++)
                    {
                        new_uvs_spe[um][j] = uvs[mapping_uvs_spe[um][j]];

                        /*int i0 = reader.ReadInt16(), m0 = (j * 3) + 0; // Old index, mapped index
                         * int i1 = reader.ReadInt16(), m1 = (j * 3) + 1;
                         * int i2 = reader.ReadInt16(), m2 = (j * 3) + 2;
                         * new_uvs_spe[um][m0] = uvs[i0];
                         * new_uvs_spe[um][m1] = uvs[i1];
                         * new_uvs_spe[um][m2] = uvs[i2];*/
                    }
                }
                //print("Loading disconnected triangles at " + String.Format("0x{0:X}", fs.Position));
                for (int j = 0; j < num_disconnected_triangles_spe; j++, triangles_index += triangle_size)
                {
                    int i0 = disconnected_triangles_spe[(j * 3) + 0], m0 = (j * 3) + 0; // Old index, mapped index
                    int i1 = disconnected_triangles_spe[(j * 3) + 1], m1 = (j * 3) + 1;
                    int i2 = disconnected_triangles_spe[(j * 3) + 2], m2 = (j * 3) + 2;
                    new_vertices_spe[m0] = mesh.vertices[i0];
                    new_vertices_spe[m1] = mesh.vertices[i1];
                    new_vertices_spe[m2] = mesh.vertices[i2];
                    new_normals_spe[m0]  = mesh.normals[i0];
                    new_normals_spe[m1]  = mesh.normals[i1];
                    new_normals_spe[m2]  = mesh.normals[i2];
                    if (new_boneWeights_spe != null)
                    {
                        new_boneWeights_spe[m0] = mesh.bones.weights[i0];
                        new_boneWeights_spe[m1] = mesh.bones.weights[i1];
                        new_boneWeights_spe[m2] = mesh.bones.weights[i2];
                    }
                    if (mesh.blendWeights != null)
                    {
                        for (int um = 0; um < num_uvMaps; um++)
                        {
                            new_uvs_spe[um][m0].z = mesh.blendWeights[i0];
                            new_uvs_spe[um][m1].z = mesh.blendWeights[i1];
                            new_uvs_spe[um][m2].z = mesh.blendWeights[i2];
                        }
                    }
                    triangles_spe[triangles_index + 0] = m0;
                    triangles_spe[triangles_index + 1] = m2;
                    triangles_spe[triangles_index + 2] = m1;
                    if (!backfaceCulling)
                    {
                        triangles_spe[triangles_index + 3] = triangles_spe[triangles_index + 0];
                        triangles_spe[triangles_index + 4] = triangles_spe[triangles_index + 2];
                        triangles_spe[triangles_index + 5] = triangles_spe[triangles_index + 1];
                    }
                }
                //if (mr_main == null) {
                GameObject gao_spe = (mr_main == null ? gao : new GameObject("[SPE] " + name));
                if (gao_spe != gao)
                {
                    gao_spe.transform.SetParent(gao.transform);
                }
                else
                {
                    gao.name = "[SPE] " + gao.name;
                }
                mesh_spe           = new Mesh();
                mesh_spe.vertices  = new_vertices_spe;
                mesh_spe.normals   = new_normals_spe;
                mesh_spe.triangles = triangles_spe;
                if (new_boneWeights_spe != null)
                {
                    mesh_spe.boneWeights = new_boneWeights_spe;
                    mesh_spe.bindposes   = mesh.bones.bindPoses;
                }
                for (int i = 0; i < num_uvMaps; i++)
                {
                    mesh_spe.SetUVs(i, new_uvs_spe[i].ToList());
                }
                //mesh.SetUVs(0, new_uvs_spe.ToList());
                /*mesh.uv = new_uvs_spe;*/
                if (new_boneWeights_spe != null)
                {
                    mr_spe              = gao_spe.AddComponent <SkinnedMeshRenderer>();
                    s_mr_spe            = (SkinnedMeshRenderer)mr_spe;
                    s_mr_spe.bones      = mesh.bones.bones;
                    s_mr_spe.rootBone   = mesh.bones.bones[0];
                    s_mr_spe.sharedMesh = CopyMesh(mesh_spe);
                }
                else
                {
                    MeshFilter mf = gao_spe.AddComponent <MeshFilter>();
                    mf.mesh = mesh_spe;
                    mr_spe  = gao_spe.AddComponent <MeshRenderer>();
                }
                //}
            }
            if (r3mat != null)
            {
                Material unityMat       = r3mat.Material;
                bool     receiveShadows = (r3mat.properties & VisualMaterial.property_receiveShadows) != 0;
                if (num_uvMaps > 1)
                {
                    unityMat.SetFloat("_UVSec", 50f);
                }
                //if (r3mat.Material.GetColor("_EmissionColor") != Color.black) print("Mesh with emission: " + name);
                if (mr_main != null)
                {
                    mr_main.material = unityMat;
                    //mr_main.UpdateGIMaterials();
                    if (!receiveShadows)
                    {
                        mr_main.receiveShadows = false;
                    }
                    if (r3mat.off_animTextures.Count > 0)
                    {
                        MultiTextureMaterial mtmat = mr_main.gameObject.AddComponent <MultiTextureMaterial>();
                        mtmat.r3mat = r3mat;
                        mtmat.mat   = mr_main.material;
                    }
                }
                if (mr_spe != null)
                {
                    mr_spe.material = unityMat;
                    //mr_spe.UpdateGIMaterials();
                    if (!receiveShadows)
                    {
                        mr_spe.receiveShadows = false;
                    }
                    if (r3mat.off_animTextures.Count > 0)
                    {
                        MultiTextureMaterial mtmat = mr_spe.gameObject.AddComponent <MultiTextureMaterial>();
                        mtmat.r3mat = r3mat;
                        mtmat.mat   = mr_spe.material;
                    }
                }
            }
        }
        private void CreateUnityMesh()
        {
            /*if (mesh.bones != null) {
             *  for (int j = 0; j < mesh.bones.num_bones; j++) {
             *      Transform b = mesh.bones.bones[j];
             *      b.transform.SetParent(gao.transform);
             *      mesh.bones.bindPoses[j] = mesh.bones.bones[j].worldToLocalMatrix * gao.transform.localToWorldMatrix;
             *  }
             * }*/
            VisualMaterial.Hint materialHints = geo.lookAtMode != 0 ? VisualMaterial.Hint.Billboard : VisualMaterial.Hint.None;
            //VisualMaterial.Hint materialHints = VisualMaterial.Hint.None;
            uint num_textures = 0;

            if (visualMaterial != null)
            {
                num_textures = visualMaterial.num_textures;
            }

            uint triangle_size = 3 * (uint)(backfaceCulling ? 1 : 2);


            // Create mesh from unoptimized data
            if (num_triangles > 0)
            {
                uint         triangles_index = 0;
                Vector3[]    new_vertices    = new Vector3[num_triangles * 3];
                Vector3[]    new_normals     = new Vector3[num_triangles * 3];
                Vector3[][]  new_uvs         = new Vector3[num_textures][];
                BoneWeight[] new_boneWeights = geo.bones != null ? new BoneWeight[num_triangles * 3] : null;
                for (int um = 0; um < num_textures; um++)
                {
                    new_uvs[um] = new Vector3[num_triangles * 3];
                }
                int[] unityTriangles = new int[num_triangles * triangle_size];
                triangles_index = 0;
                for (int um = 0; um < num_textures; um++)
                {
                    for (int j = 0; j < num_triangles * 3; j++)
                    {
                        uint uvMap = (uint)visualMaterial.textures[um].uvFunction % num_uvMaps;
                        if (uvs != null)
                        {
                            new_uvs[um][j] = uvs[mapping_uvs[uvMap][j] % uvs.Length];                             // modulo because R2 iOS has some corrupt uvs
                            if (MapLoader.Loader.blockyMode && normals != null)
                            {
                                new_uvs[um][j] = uvs[mapping_uvs[uvMap][j - (j % 3)]];
                            }
                        }
                        new_uvs[um][j].z = 1;

                        /*int i0 = reader.ReadInt16(), m0 = (j * 3) + 0; // Old index, mapped index
                         * int i1 = reader.ReadInt16(), m1 = (j * 3) + 1;
                         * int i2 = reader.ReadInt16(), m2 = (j * 3) + 2;
                         * new_uvs_spe[um][m0] = uvs[i0];
                         * new_uvs_spe[um][m1] = uvs[i1];
                         * new_uvs_spe[um][m2] = uvs[i2];*/
                    }
                }
                //print("Loading disconnected triangles at " + String.Format("0x{0:X}", fs.Position));
                for (int j = 0; j < num_triangles; j++, triangles_index += triangle_size)
                {
                    int i0 = triangles[(j * 3) + 0], m0 = (j * 3) + 0;                     // Old index, mapped index
                    int i1 = triangles[(j * 3) + 1], m1 = (j * 3) + 1;
                    int i2 = triangles[(j * 3) + 2], m2 = (j * 3) + 2;
                    if (i1 > geo.vertices.Length)
                    {
                        MapLoader.Loader.print(geo.vertices.Length);
                    }
                    new_vertices[m0] = geo.vertices[i0];
                    new_vertices[m1] = geo.vertices[i1];
                    new_vertices[m2] = geo.vertices[i2];

                    if (geo.normals != null)
                    {
                        new_normals[m0] = geo.normals[i0];
                        new_normals[m1] = geo.normals[i1];
                        new_normals[m2] = geo.normals[i2];
                    }
                    if (MapLoader.Loader.blockyMode && normals != null)
                    {
                        new_normals[m0] = normals[j];
                        new_normals[m1] = normals[j];
                        new_normals[m2] = normals[j];
                    }
                    if (new_boneWeights != null)
                    {
                        new_boneWeights[m0] = geo.bones.weights[i0];
                        new_boneWeights[m1] = geo.bones.weights[i1];
                        new_boneWeights[m2] = geo.bones.weights[i2];
                    }
                    if (geo.blendWeights != null)
                    {
                        for (int um = 0; um < num_textures; um++)
                        {
                            if (geo.blendWeights[visualMaterial.textures[um].blendIndex] != null)
                            {
                                if (um == 0)
                                {
                                    materialHints |= VisualMaterial.Hint.Transparent;
                                }
                                new_uvs[um][m0].z = geo.blendWeights[visualMaterial.textures[um].blendIndex][i0];
                                new_uvs[um][m1].z = geo.blendWeights[visualMaterial.textures[um].blendIndex][i1];
                                new_uvs[um][m2].z = geo.blendWeights[visualMaterial.textures[um].blendIndex][i2];
                            }
                        }
                    }
                    unityTriangles[triangles_index + 0] = m0;
                    unityTriangles[triangles_index + 1] = m2;
                    unityTriangles[triangles_index + 2] = m1;
                    if (!backfaceCulling)
                    {
                        unityTriangles[triangles_index + 3] = unityTriangles[triangles_index + 0];
                        unityTriangles[triangles_index + 4] = unityTriangles[triangles_index + 2];
                        unityTriangles[triangles_index + 5] = unityTriangles[triangles_index + 1];
                    }
                }
                if (unityMesh == null)
                {
                    unityMesh           = new Mesh();
                    unityMesh.vertices  = new_vertices;
                    unityMesh.normals   = new_normals;
                    unityMesh.triangles = unityTriangles;
                    if (new_boneWeights != null)
                    {
                        unityMesh.boneWeights = new_boneWeights;
                        unityMesh.bindposes   = geo.bones.bindPoses;
                    }
                    for (int i = 0; i < num_textures; i++)
                    {
                        unityMesh.SetUVs(i, new_uvs[i].ToList());
                    }
                }
                else
                {
                    unityMesh = CopyMesh(unityMesh);
                }
                //mesh.SetUVs(0, new_uvs_spe.ToList());
                /*mesh.uv = new_uvs_spe;*/
                if (new_boneWeights != null)
                {
                    mr              = gao.AddComponent <SkinnedMeshRenderer>();
                    s_mr            = (SkinnedMeshRenderer)mr;
                    s_mr.bones      = geo.bones.bones;
                    s_mr.rootBone   = geo.bones.bones[0];
                    s_mr.sharedMesh = CopyMesh(unityMesh);

                    BoxCollider bc = gao.AddComponent <BoxCollider>();
                    bc.center = s_mr.bounds.center;
                    bc.size   = s_mr.bounds.size;
                }
                else
                {
                    MeshFilter mf = gao.AddComponent <MeshFilter>();
                    mf.sharedMesh = unityMesh;
                    mr            = gao.AddComponent <MeshRenderer>();
                    MeshCollider mc = gao.AddComponent <MeshCollider>();
                    mc.isTrigger  = false;
                    mc.sharedMesh = unityMesh;
                }
                //}
            }


            // Create mesh from optimized data
            long OPT_num_triangles_total = ((OPT_num_triangleStrip > 2 ? OPT_num_triangleStrip - 2 : 0) + OPT_num_disconnectedTriangles) * (backfaceCulling ? 1 : 2);

            if (OPT_num_triangles_total > 0 && num_triangles <= 0)
            {
                uint         triangles_index = 0;
                Vector3[]    new_vertices    = new Vector3[OPT_num_mapping_entries];
                Vector3[]    new_normals     = new Vector3[OPT_num_mapping_entries];
                Vector4[][]  new_uvs         = new Vector4[num_textures + (vertexColors != null ? 1 : 0)][]; // Thanks to Unity we can only store the blend weights as a third component of the UVs
                BoneWeight[] new_boneWeights = geo.bones != null ? new BoneWeight[OPT_num_mapping_entries] : null;
                for (int um = 0; um < num_textures; um++)
                {
                    new_uvs[um] = new Vector4[OPT_num_mapping_entries];
                }
                if (vertexColors != null)
                {
                    new_uvs[num_textures] = new Vector4[OPT_num_mapping_entries];
                    for (int i = 0; i < OPT_num_mapping_entries; i++)
                    {
                        new_uvs[num_textures][i] = new Vector4(vertexColors[i].r, vertexColors[i].g, vertexColors[i].b, vertexColors[i].a);
                    }
                }
                for (int j = 0; j < OPT_num_mapping_entries; j++)
                {
                    new_vertices[j] = geo.vertices[OPT_mapping_vertices[j]];
                    if (geo.normals != null)
                    {
                        new_normals[j] = geo.normals[OPT_mapping_vertices[j]];
                    }
                    if (new_boneWeights != null)
                    {
                        new_boneWeights[j] = geo.bones.weights[OPT_mapping_vertices[j]];
                    }
                    for (int um = 0; um < num_textures; um++)
                    {
                        uint uvMap = (uint)visualMaterial.textures[um].uvFunction % num_uvMaps;
                        //MapLoader.Loader.print(visualMaterial.textures[um].uvFunction + " - " + num_uvMaps);
                        new_uvs[um][j] = uvs[OPT_mapping_uvs[uvMap][j]];
                        if (geo.blendWeights != null && geo.blendWeights[visualMaterial.textures[um].blendIndex] != null)
                        {
                            if (um == 0)
                            {
                                materialHints |= VisualMaterial.Hint.Transparent;
                            }
                            new_uvs[um][j].z = geo.blendWeights[visualMaterial.textures[um].blendIndex][OPT_mapping_vertices[j]];
                        }
                        else
                        {
                            new_uvs[um][j].z = 1;
                        }
                    }
                }
                int[] unityTriangles = new int[OPT_num_triangles_total * triangle_size];
                if (OPT_num_triangleStrip > 2)
                {
                    for (int j = 0; j < OPT_num_triangleStrip - 2; j++, triangles_index += triangle_size)
                    {
                        if (j % 2 == 0)
                        {
                            unityTriangles[triangles_index + 0] = OPT_triangleStrip[j + 0];
                            unityTriangles[triangles_index + 1] = OPT_triangleStrip[j + 2];
                            unityTriangles[triangles_index + 2] = OPT_triangleStrip[j + 1];
                        }
                        else
                        {
                            unityTriangles[triangles_index + 0] = OPT_triangleStrip[j + 0];
                            unityTriangles[triangles_index + 1] = OPT_triangleStrip[j + 1];
                            unityTriangles[triangles_index + 2] = OPT_triangleStrip[j + 2];
                        }
                        if (!backfaceCulling)
                        {
                            unityTriangles[triangles_index + 3] = unityTriangles[triangles_index + 0];
                            unityTriangles[triangles_index + 4] = unityTriangles[triangles_index + 2];
                            unityTriangles[triangles_index + 5] = unityTriangles[triangles_index + 1];
                        }
                    }
                }
                if (OPT_num_triangleStrip < 2)
                {
                    OPT_num_triangleStrip = 0;
                }
                if (OPT_num_disconnectedTriangles > 0)
                {
                    //print("Loading disconnected triangles at " + String.Format("0x{0:X}", fs.Position));
                    for (int j = 0; j < OPT_num_disconnectedTriangles; j++, triangles_index += triangle_size)
                    {
                        unityTriangles[triangles_index + 0] = OPT_disconnectedTriangles[(j * 3) + 0];
                        unityTriangles[triangles_index + 2] = OPT_disconnectedTriangles[(j * 3) + 1];
                        unityTriangles[triangles_index + 1] = OPT_disconnectedTriangles[(j * 3) + 2];
                        if (!backfaceCulling)
                        {
                            unityTriangles[triangles_index + 3] = unityTriangles[triangles_index + 0];
                            unityTriangles[triangles_index + 4] = unityTriangles[triangles_index + 2];
                            unityTriangles[triangles_index + 5] = unityTriangles[triangles_index + 1];
                        }
                    }
                }
                if (OPT_unityMesh == null)
                {
                    OPT_unityMesh          = new Mesh();
                    OPT_unityMesh.vertices = new_vertices;
                    if (geo.normals != null)
                    {
                        OPT_unityMesh.normals = new_normals;
                    }
                    OPT_unityMesh.triangles = unityTriangles;
                    if (new_boneWeights != null)
                    {
                        OPT_unityMesh.boneWeights = new_boneWeights;
                        OPT_unityMesh.bindposes   = geo.bones.bindPoses;
                    }
                    for (int i = 0; i < new_uvs.Length; i++)
                    {
                        OPT_unityMesh.SetUVs(i, new_uvs[i].ToList());
                    }
                }
                else
                {
                    OPT_unityMesh = CopyMesh(OPT_unityMesh);
                }
                GameObject OPT_gao = (OPT_mr == null ? gao : new GameObject("[Optimized] " + name));
                if (OPT_gao != gao)
                {
                    OPT_gao.transform.SetParent(gao.transform);
                }
                else
                {
                    gao.name = "[Optimized] " + gao.name;
                }
                if (new_boneWeights != null)
                {
                    OPT_mr              = OPT_gao.AddComponent <SkinnedMeshRenderer>();
                    OPT_s_mr            = (SkinnedMeshRenderer)OPT_mr;
                    OPT_s_mr.bones      = geo.bones.bones;
                    OPT_s_mr.rootBone   = geo.bones.bones[0];
                    OPT_s_mr.sharedMesh = CopyMesh(OPT_unityMesh);

                    BoxCollider bc = OPT_gao.AddComponent <BoxCollider>();
                    bc.center = OPT_s_mr.bounds.center;
                    bc.size   = OPT_s_mr.bounds.size;
                }
                else
                {
                    MeshFilter mf = OPT_gao.AddComponent <MeshFilter>();
                    mf.sharedMesh = OPT_unityMesh;
                    OPT_mr        = OPT_gao.AddComponent <MeshRenderer>();
                    MeshCollider mc = OPT_gao.AddComponent <MeshCollider>();
                    mc.isTrigger  = false;
                    mc.sharedMesh = OPT_unityMesh;
                }
            }
            if (visualMaterial != null)
            {
                //gao.name += " " + visualMaterial.offset + " - " + (visualMaterial.textures.Count > 0 ? visualMaterial.textures[0].offset.ToString() : "NULL" );
                Material unityMat = visualMaterial.GetMaterial(materialHints);
                if (vertexColors != null & unityMat != null)
                {
                    unityMat.SetVector("_Tex2Params", new Vector4(60, 0, 0, 0));
                }
                bool receiveShadows = (visualMaterial.properties & VisualMaterial.property_receiveShadows) != 0;
                bool scroll         = visualMaterial.ScrollingEnabled;

                /*if (num_uvMaps > 1) {
                 *  unityMat.SetFloat("_UVSec", 1f);
                 * } else if (scroll) {
                 *  for (int i = num_uvMaps; i < visualMaterial.textures.Count; i++) {
                 *      if (visualMaterial.textures[i].ScrollingEnabled) {
                 *          unityMat.SetFloat("_UVSec", 1f);
                 *          break;
                 *      }
                 *  }
                 * }*/
                //if (r3mat.Material.GetColor("_EmissionColor") != Color.black) print("Mesh with emission: " + name);
                if (OPT_mr != null)
                {
                    OPT_mr.sharedMaterial = unityMat;
                    //mr_main.UpdateGIMaterials();
                    if (!receiveShadows)
                    {
                        OPT_mr.receiveShadows = false;
                    }
                    if (visualMaterial.animTextures.Count > 0)
                    {
                        MultiTextureMaterial mtmat = OPT_mr.gameObject.AddComponent <MultiTextureMaterial>();
                        mtmat.visMat = visualMaterial;
                        mtmat.mat    = OPT_mr.material;
                    }

                    /*if (scroll) {
                     *  ScrollingTexture scrollComponent = mr_main.gameObject.AddComponent<ScrollingTexture>();
                     *  scrollComponent.visMat = visualMaterial;
                     *  scrollComponent.mat = mr_main.material;
                     * }*/
                }
                if (mr != null)
                {
                    mr.sharedMaterial = unityMat;
                    //mr_spe.UpdateGIMaterials();
                    if (!receiveShadows)
                    {
                        mr.receiveShadows = false;
                    }
                    if (visualMaterial.animTextures.Count > 0)
                    {
                        MultiTextureMaterial mtmat = mr.gameObject.AddComponent <MultiTextureMaterial>();
                        mtmat.visMat = visualMaterial;
                        mtmat.mat    = mr.material;
                    }

                    /*if (scroll) {
                     *  ScrollingTexture scrollComponent = mr_spe.gameObject.AddComponent<ScrollingTexture>();
                     *  scrollComponent.visMat = visualMaterial;
                     *  scrollComponent.mat = mr_spe.material;
                     * }*/
                }
            }
        }