Пример #1
0
        public override GameObject LoadObject(string path, Mission mission)
        {
            GameObject rootObject = LoadCachedObject(path);

            if (rootObject == null)
            {
                rootObject = new GameObject(path);
            }
            else
            {
                return(rootObject);
            }

            Stream fs;

            try
            {
                fs = GameAPI.instance.fileSystem.GetStreamFromPath(path);
            }
            catch (Exception ex)
            {
                GameObject.DestroyImmediate(rootObject);
                Debug.LogWarning(ex.ToString());
                return(null);
            }

            using (BinaryReader reader = new BinaryReader(fs))
            {
                var modelLoader = new MafiaFormats.Reader4DS();
                var model       = modelLoader.loadModel(reader);
                fs.Close();

                if (model == null)
                {
                    return(null);
                }

                var meshId = 0;

                var children = new List <KeyValuePair <int, Transform> >();

                foreach (var mafiaMesh in model.meshes)
                {
                    var child      = new GameObject(mafiaMesh.meshName, typeof(MeshFilter));
                    var meshFilter = child.GetComponent <MeshFilter>();

                    StoreReference(mission, child.name, child);

                    children.Add(new KeyValuePair <int, Transform>(mafiaMesh.parentID, child.transform));

                    if (mafiaMesh.meshType == MafiaFormats.MeshType.Joint)
                    {
                        var bone = child.AddComponent <Bone>();
                        bone.data = mafiaMesh.joint;
                        continue;
                    }
                    else if (mafiaMesh.meshType == MafiaFormats.MeshType.Collision)
                    {
                        Material[] temp;
                        child.AddComponent <MeshCollider>().sharedMesh = GenerateMesh(mafiaMesh, child, mafiaMesh.standard.lods[0], model, out temp);
                        continue;
                    }
                    else if (mafiaMesh.meshType == MafiaFormats.MeshType.Sector)
                    {
                        // NOTE: Set up dummy data for this sector.
                        MafiaFormats.Scene2BINLoader.Object dummySectorData = new MafiaFormats.Scene2BINLoader.Object();
                        dummySectorData.type = MafiaFormats.Scene2BINLoader.ObjectType.Sector;
                        var objDef = child.AddComponent <ObjectDefinition>();
                        objDef.data = dummySectorData;
                        objDef.sectorBounds.SetMinMax(mafiaMesh.sector.minBox, mafiaMesh.sector.maxBox);
                        objDef.Init();
                        continue;
                    }
                    else if (mafiaMesh.meshType != MafiaFormats.MeshType.Standard)
                    {
                        continue;
                    }

                    if (mafiaMesh.standard.instanced != 0)
                    {
                        continue;
                    }

                    var def = child.AddComponent <ModelDefinition>();
                    def.model = model;
                    def.mesh  = mafiaMesh;

                    Material[] materials;

                    switch (mafiaMesh.visualMeshType)
                    {
                    case MafiaFormats.VisualMeshType.Standard:
                    {
                        // TODO build up more lods
                        if (mafiaMesh.standard.lods.Count > 0)
                        {
                            var meshRenderer = child.AddComponent <MeshRenderer>();
                            meshFilter.mesh                = GenerateMesh(mafiaMesh, child, mafiaMesh.standard.lods[0], model, out materials);
                            meshRenderer.materials         = materials;
                            meshRenderer.shadowCastingMode = ShadowCastingMode.TwoSided;

                            // Handle special textures
                            foreach (var m in meshRenderer.sharedMaterials)
                            {
                                var name = m.GetTexture("_MainTex")?.name;

                                if (IsTextureGlow(name))
                                {
                                    var glowTexture = (Texture2D)Resources.Load("Flares/" + Path.GetFileNameWithoutExtension(name));

                                    m.shader = Shader.Find("Unlit/Transparent");
                                    m.SetTexture("_MainTex", glowTexture);

                                    break;
                                }
                            }
                        }
                        else
                        {
                            continue;
                        }
                    }
                    break;

                    case MafiaFormats.VisualMeshType.Single_Mesh:
                    {
                        var meshRenderer = child.AddComponent <SkinnedMeshRenderer>();
                        meshFilter.mesh                = GenerateMesh(mafiaMesh, child, mafiaMesh.singleMesh.standard.lods[0], model, out materials);
                        meshRenderer.materials         = materials;
                        meshRenderer.sharedMesh        = meshFilter.sharedMesh;
                        meshRenderer.shadowCastingMode = ShadowCastingMode.TwoSided;
                    }
                    break;

                    case MafiaFormats.VisualMeshType.Single_Morph:
                    {
                        var meshRenderer = child.AddComponent <SkinnedMeshRenderer>();
                        meshFilter.mesh                = GenerateMesh(mafiaMesh, child, mafiaMesh.singleMorph.singleMesh.standard.lods[0], model, out materials);
                        meshRenderer.materials         = materials;
                        meshRenderer.sharedMesh        = meshFilter.sharedMesh;
                        meshRenderer.shadowCastingMode = ShadowCastingMode.TwoSided;
                    }
                    break;

                    case MafiaFormats.VisualMeshType.Billboard:
                    {
                        // TODO build up more lods
                        var standard = mafiaMesh.billboard.standard;

                        if (standard.lods.Count > 0)
                        {
                            //NOTE: (DavoSK) Add our custom billboard here
                            child.AddComponent <CustomBillboard>();

                            var meshRenderer = child.AddComponent <MeshRenderer>();

                            meshFilter.mesh                = GenerateMesh(mafiaMesh, child, standard.lods[0], model, out materials);
                            meshRenderer.materials         = materials;
                            meshRenderer.shadowCastingMode = ShadowCastingMode.TwoSided;

                            // Handle special textures
                            foreach (var m in meshRenderer.sharedMaterials)
                            {
                                var name = m.GetTexture("_MainTex")?.name;

                                if (IsTextureGlow(name))
                                {
                                    var glowTexture = (Texture2D)Resources.Load("Flares/" + Path.GetFileNameWithoutExtension(name));

                                    m.shader = Shader.Find("Unlit/Transparent");
                                    m.SetTexture("_MainTex", glowTexture);

                                    break;
                                }
                            }
                        }
                        else
                        {
                            continue;
                        }
                    }
                    break;

                    case MafiaFormats.VisualMeshType.Glow:
                    {
                        List <string> usedMaps = new List <string>();

                        foreach (var g in mafiaMesh.glow.glowData)
                        {
                            if (g.materialID - 1 >= model.materials.Count)
                            {
                                continue;
                            }

                            var matID = g.materialID - 1;

                            var mat     = model.materials[matID];
                            var mapName = mat.diffuseMapName;

                            if (usedMaps.Contains(mapName))
                            {
                                continue;
                            }

                            foreach (var m in model.meshes)
                            {
                                if (m.standard.lods == null)
                                {
                                    continue;
                                }

                                if (m.standard.lods.Count < 1)
                                {
                                    continue;
                                }

                                bool used = false;

                                foreach (var gr in m.standard.lods[0].faceGroups)
                                {
                                    if (gr.materialID == matID)
                                    {
                                        GenerateGlow(mapName, rootObject, m.pos);

                                        used = true;
                                        break;
                                    }
                                }

                                if (used == true)
                                {
                                    break;
                                }
                            }

                            usedMaps.Add(mapName);
                        }
                    }
                    break;

                    // TODO add more visual types

                    default: continue;
                    }

                    def.modelName = Path.GetFileName(path);

                    meshId++;
                }

                for (int i = 0; i < children.Count; i++)
                {
                    var parentId  = children[i].Key;
                    var mafiaMesh = model.meshes[i];

                    if (parentId > 0)
                    {
                        children[i].Value.parent = children[parentId - 1].Value;
                    }
                    else
                    {
                        children[i].Value.parent = rootObject.transform;
                    }

                    children[i].Value.localPosition = mafiaMesh.pos;
                    children[i].Value.localRotation = mafiaMesh.rot;
                    children[i].Value.localScale    = mafiaMesh.scale;
                }

                // NOTE(zaklaus): Do some extra work if this is a skinned mesh
                var baseObject = rootObject.transform.Find("base");

                if (baseObject != null)
                {
                    var skinnedMesh = baseObject.GetComponent <SkinnedMeshRenderer>();

                    if (skinnedMesh != null)
                    {
                        var def = baseObject.GetComponent <ModelDefinition>();
                        MafiaFormats.SingleMesh data;

                        if (def.mesh.visualMeshType == MafiaFormats.VisualMeshType.Single_Mesh)
                        {
                            data = def.mesh.singleMesh;
                        }
                        else
                        {
                            data = def.mesh.singleMorph.singleMesh;
                        }

                        var boneData  = data.LODs[0];
                        var bones     = new List <Bone>(skinnedMesh.GetComponentsInChildren <Bone>());
                        var boneArray = new Transform[bones.Count];

                        foreach (var b in bones)
                        {
                            boneArray[b.data.boneID] = b.transform;
                        }

                        /* TODO: var boneTransforms = new List<Transform>(boneArray); */
                        var bindPoses   = new Matrix4x4[bones.Count];
                        var boneWeights = new BoneWeight[skinnedMesh.sharedMesh.vertexCount];

                        skinnedMesh.bones = boneArray;

                        int skipVertices = 0;//(int)boneData.nonWeightedVertCount;

                        for (int i = 0; i < boneData.bones.Count; i++)
                        {
                            bindPoses[i] = boneData.bones[i].transform;

                            for (int j = 0; j < boneData.bones[i].oneWeightedVertCount; j++)
                            {
                                boneWeights[skipVertices + j].boneIndex0 = i;
                                boneWeights[skipVertices + j].weight0    = 1f;
                                boneWeights[skipVertices + j].boneIndex1 = (int)boneData.bones[i].boneID;
                                boneWeights[skipVertices + j].weight1    = 0f;
                            }

                            skipVertices += (int)boneData.bones[i].oneWeightedVertCount;

                            for (int j = 0; j < boneData.bones[i].weights.Count; j++)
                            {
                                boneWeights[skipVertices + j].boneIndex0 = i;
                                boneWeights[skipVertices + j].weight0    = boneData.bones[i].weights[j];
                                boneWeights[skipVertices + j].boneIndex1 = (int)boneData.bones[i].boneID;
                                boneWeights[skipVertices + j].weight1    = 1f - boneData.bones[i].weights[j];
                            }

                            skipVertices += boneData.bones[i].weights.Count;
                        }

                        skinnedMesh.sharedMesh.bindposes   = bindPoses;
                        skinnedMesh.sharedMesh.boneWeights = boneWeights;
                    }
                }

                children.Clear();
            }

            StoreCachedObject(path, rootObject);

            return(rootObject);
        }
Пример #2
0
        public override GameObject LoadObject(string path)
        {
            GameObject rootObject = null;// LoadCachedObject(path);

            if (rootObject == null)
            {
                rootObject = new GameObject(path);
            }
            else
            {
                return(rootObject);
            }

            FileStream fs;

            try
            {
                fs = new FileStream(GameManager.instance.fileSystem.GetPath(path), FileMode.Open);
            }
            catch (Exception ex)
            {
                GameObject.DestroyImmediate(rootObject);
                Debug.LogWarning(ex.ToString());
                return(null);
            }

            using (BinaryReader reader = new BinaryReader(fs))
            {
                var modelLoader = new MafiaFormats.Reader4DS();
                var model       = modelLoader.loadModel(reader);

                var meshId = 0;

                var children = new List <KeyValuePair <int, Transform> >();

                foreach (var mafiaMesh in model.meshes)
                {
                    var child      = new GameObject(mafiaMesh.meshName, typeof(MeshFilter));
                    var meshFilter = child.GetComponent <MeshFilter>();

                    children.Add(new KeyValuePair <int, Transform>(mafiaMesh.parentID, child.transform));

                    if (mafiaMesh.meshType == MafiaFormats.MeshType.Bone)
                    {
                        var bone = child.AddComponent <Bone>();
                        bone.data = mafiaMesh.bone;
                        continue;
                    }
                    else if (mafiaMesh.meshType == MafiaFormats.MeshType.Collision)
                    {
                        Material[] temp;
                        child.AddComponent <MeshCollider>().sharedMesh = GenerateMesh(mafiaMesh, child, mafiaMesh.standard.lods[0], model, out temp);
                        continue;
                    }
                    else if (mafiaMesh.meshType != MafiaFormats.MeshType.Standard)
                    {
                        continue;
                    }

                    if (mafiaMesh.standard.instanced != 0)
                    {
                        continue;
                    }

                    Material[] materials;

                    switch (mafiaMesh.visualMeshType)
                    {
                    case MafiaFormats.VisualMeshType.Standard:
                    {
                        // TODO build up more lods
                        if (mafiaMesh.standard.lods.Count > 0)
                        {
                            var meshRenderer = child.AddComponent <MeshRenderer>();
                            meshFilter.mesh        = GenerateMesh(mafiaMesh, child, mafiaMesh.standard.lods[0], model, out materials);
                            meshRenderer.materials = materials;

                            bool isTwoSided = model.materials.FindAll(x => (x.flags.HasFlag(MafiaFormats.MaterialFlag.Doublesided_Material))).Count > 0;

                            if (isTwoSided)
                            {
                                meshRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.TwoSided;
                            }
                        }
                        else
                        {
                            continue;
                        }
                    }
                    break;

                    case MafiaFormats.VisualMeshType.Single_Mesh:
                    {
                        var meshRenderer = child.AddComponent <SkinnedMeshRenderer>();
                        meshFilter.mesh         = GenerateMesh(mafiaMesh, child, mafiaMesh.singleMesh.standard.lods[0], model, out materials);
                        meshRenderer.materials  = materials;
                        meshRenderer.sharedMesh = meshFilter.sharedMesh;

                        var data = child.AddComponent <SkinnedMeshData>();
                        data.mesh = mafiaMesh.singleMesh;
                    }
                    break;

                    case MafiaFormats.VisualMeshType.Single_Morph:
                    {
                        var meshRenderer = child.AddComponent <SkinnedMeshRenderer>();
                        meshFilter.mesh         = GenerateMesh(mafiaMesh, child, mafiaMesh.singleMorph.singleMesh.standard.lods[0], model, out materials);
                        meshRenderer.materials  = materials;
                        meshRenderer.sharedMesh = meshFilter.sharedMesh;

                        var data = child.AddComponent <SkinnedMeshData>();
                        data.mesh = mafiaMesh.singleMorph.singleMesh;
                    }
                    break;

                    // TODO add more visual types

                    default: continue;
                    }

                    meshId++;
                }

                for (int i = 0; i < children.Count; i++)
                {
                    var parentId  = children[i].Key;
                    var mafiaMesh = model.meshes[i];

                    if (parentId > 0)
                    {
                        children[i].Value.parent = children[parentId - 1].Value;
                    }
                    else
                    {
                        children[i].Value.parent = rootObject.transform;
                    }

                    children[i].Value.localPosition = mafiaMesh.pos;
                    children[i].Value.localRotation = mafiaMesh.rot;
                    children[i].Value.localScale    = mafiaMesh.scale;
                }

                // NOTE(zaklaus): Do some extra work if this is a skinned mesh
                var baseObject = rootObject.transform.Find("base");

                if (baseObject != null)
                {
                    var skinnedMesh = baseObject.GetComponent <SkinnedMeshRenderer>();

                    if (skinnedMesh != null)
                    {
                        var data      = baseObject.GetComponent <SkinnedMeshData>();
                        var boneData  = data.mesh.LODs[0];
                        var bones     = new List <Bone>(skinnedMesh.GetComponentsInChildren <Bone>());
                        var boneArray = new Transform[bones.Count];

                        foreach (var b in bones)
                        {
                            boneArray[b.data.boneID] = b.transform;
                        }

                        var boneTransforms = new List <Transform>(boneArray);
                        var bindPoses      = new Matrix4x4[bones.Count];
                        var boneWeights    = new BoneWeight[skinnedMesh.sharedMesh.vertexCount];

                        skinnedMesh.bones = boneArray;

                        int skipVertices = (int)boneData.nonWeightedVertCount;

                        for (int i = 0; i < boneData.joints.Count; i++)
                        {
                            bindPoses[i] = boneData.joints[i].transform;

                            for (int j = 0; j < boneData.joints[i].oneWeightedVertCount; j++)
                            {
                                boneWeights[skipVertices + j].boneIndex0 = i;
                                boneWeights[skipVertices + j].weight0    = 1f;
                            }

                            skipVertices += (int)boneData.joints[i].oneWeightedVertCount;

                            for (int j = 0; j < boneData.joints[i].weights.Count; j++)
                            {
                                boneWeights[skipVertices + j].boneIndex0 = i;
                                boneWeights[skipVertices + j].weight0    = boneData.joints[i].weights[j];
                                boneWeights[skipVertices + j].boneIndex1 = (int)boneData.joints[i].boneID;
                                boneWeights[skipVertices + j].weight1    = 1f - boneData.joints[i].weights[j];
                            }

                            skipVertices += boneData.joints[i].weights.Count;
                        }

                        skinnedMesh.sharedMesh.bindposes   = bindPoses;
                        skinnedMesh.sharedMesh.boneWeights = boneWeights;
                    }
                }


                children.Clear();
            }

            //StoreChachedObject(path, rootObject);


            fs.Close();

            return(rootObject);
        }