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
            {
                return(null);
            }

            using (var reader = new BinaryReader(fs))
            {
                var sceneLoader = new MafiaFormats.Scene2BINLoader();
                lastLoader = sceneLoader;

                sceneLoader.Load(reader);
                fs.Close();

                // TODO: Check if refs are null, clear then
                ModelGenerator.cachedTextures.Clear();

                var objects = new List <KeyValuePair <GameObject, MafiaFormats.Scene2BINLoader.Object> >();

                var backdrop = new GameObject("Backdrop sector");
                backdrop.transform.parent = rootObject.transform;
                StoreReference(mission, backdrop.name, backdrop);

                foreach (var obj in sceneLoader.objects)
                {
                    AddNewObject(objects, mission, obj);
                }

                // Handle special cases of objects loaded by external source
                foreach (var obj in sceneLoader.externalObjects)
                {
                    var go = BaseGenerator.FetchCacheReference(mission, obj.Value.name)?.gameObject;

                    if (go != null)
                    {
                        var specialObjDef = go.GetComponent <ObjectDefinition>();

                        if (specialObjDef == null)
                        {
                            specialObjDef = go.AddComponent <ObjectDefinition>();
                        }

                        specialObjDef.data = obj.Value;

                        specialObjDef.Init();
                    }
                    // Seems like object acts on its own, add it anyway
                    else
                    {
                        AddNewObject(objects, mission, obj);
                    }
                }

                var primary = FetchReference(mission, "Primary sector");

                if (primary == null)
                {
                    primary = new GameObject("Primary Sector");
                }

                var objDef          = primary.AddComponent <ObjectDefinition>();
                var dummySectorData = new MafiaFormats.Scene2BINLoader.Object();
                dummySectorData.type     = MafiaFormats.Scene2BINLoader.ObjectType.Sector;
                objDef.data              = dummySectorData;
                primary.transform.parent = rootObject.transform;

                objects = objects.OrderByDescending(x => x.Value.isPatch).ToList();

                foreach (var obj in objects)
                {
                    var newObject = obj.Key;

                    if (obj.Value.isPatch)
                    {
                        var searchName  = obj.Value.name;
                        var redefObject = FindParent(mission, searchName, null);

                        if (redefObject != null)
                        {
                            if (obj.Value.isParentPatched && obj.Value.parentName != null)
                            {
                                var parent = FindParent(mission, obj.Value.parentName);

                                if (parent != null)
                                {
                                    redefObject.transform.parent = parent.transform;
                                }
                            }

                            if (obj.Value.isPositionPatched)
                            {
                                redefObject.transform.localPosition = obj.Value.pos;
                            }

                            /* if (obj.Value.isPosition2Patched)
                             *  redefObject.transform.position = obj.Value.pos2; */

                            if (obj.Value.isRotationPatched)
                            {
                                redefObject.transform.localRotation = obj.Value.rot;
                            }

                            if (obj.Value.isScalePatched)
                            {
                                redefObject.transform.localScale = obj.Value.scale;
                            }

                            redefObject.SetActive(!obj.Value.isHidden);

                            GameObject.DestroyImmediate(newObject, true);
                            continue;
                        }
                    }

                    newObject.transform.parent = FindParent(mission, obj.Value.parentName, rootObject).transform;

                    newObject.transform.localPosition = obj.Value.pos;
                    newObject.transform.localRotation = obj.Value.rot;
                    newObject.transform.localScale    = obj.Value.scale;

                    newObject.SetActive(!obj.Value.isHidden);

                    var specObject = newObject.AddComponent <ObjectDefinition>();
                    specObject.data = obj.Value;
                    specObject.Init();
                }
            }

            // NOTE(zaklaus): Hardcode 'Primary sector' scale to (1,1,1)
            var primarySector = GameObject.Find("Primary sector");

            if (primarySector != null)
            {
                primarySector.transform.localScale = new Vector3(1, 1, 1);
            }

            //StoreChachedObject(path, rootObject);

            return(rootObject);
        }
Exemple #2
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);
        }
Exemple #3
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
            {
                return(null);
            }

            using (var reader = new BinaryReader(fs))
            {
                var sceneLoader = new MafiaFormats.Scene2BINLoader();
                lastLoader = sceneLoader;

                sceneLoader.Load(reader);
                fs.Close();

                // TODO: Check if refs are null, clear then
                ModelGenerator.cachedTextures.Clear();

                var objects = new List <KeyValuePair <GameObject, MafiaFormats.Scene2BINLoader.Object> >();

                var backdrop = new GameObject("Backdrop sector");
                backdrop.transform.parent = rootObject.transform;
                StoreReference(mission, backdrop.name, backdrop);

                foreach (var obj in sceneLoader.objects)
                {
                    GameObject newObject;

                    if (obj.Value.modelName == null || (obj.Value.type != MafiaFormats.Scene2BINLoader.ObjectType.Model && obj.Value.specialType == 0))
                    {
                        newObject = new GameObject();
                    }
                    else
                    {
                        newObject = GameAPI.instance.modelGenerator.LoadObject(Path.Combine("models", obj.Value.modelName), null);
                    }

                    if (newObject == null)
                    {
                        continue;
                    }

                    newObject.name = obj.Value.name;

                    StoreReference(mission, newObject.name, newObject);

                    newObject.transform.localPosition = obj.Value.pos;
                    newObject.transform.localRotation = obj.Value.rot;
                    newObject.transform.localScale    = obj.Value.scale;

                    objects.Add(new KeyValuePair <GameObject, MafiaFormats.Scene2BINLoader.Object>(newObject, obj.Value));
                }

                var primary         = FetchReference(mission, "Primary sector");
                var objDef          = primary.AddComponent <ObjectDefinition>();
                var dummySectorData = new MafiaFormats.Scene2BINLoader.Object();
                dummySectorData.type     = MafiaFormats.Scene2BINLoader.ObjectType.Sector;
                objDef.data              = dummySectorData;
                primary.transform.parent = rootObject.transform;

                foreach (var obj in objects)
                {
                    var newObject = obj.Key;

                    if (obj.Value.isPatch)
                    {
                        var searchName  = obj.Value.name.Replace(".", "/");
                        var redefObject = GameObject.Find(searchName);

                        if (redefObject != null)
                        {
                            if (obj.Value.isParentPatched && obj.Value.parentName != null)
                            {
                                var parent = FindParent(mission, obj.Value.parentName);

                                if (parent != null)
                                {
                                    redefObject.transform.parent = parent.transform;
                                }
                            }

                            if (obj.Value.isPositionPatched)
                            {
                                redefObject.transform.localPosition = obj.Value.pos;
                            }

                            /* if (obj.Value.isPosition2Patched)
                             *  redefObject.transform.position = obj.Value.pos2; */

                            if (obj.Value.isRotationPatched)
                            {
                                redefObject.transform.localRotation = obj.Value.rot;
                            }

                            if (obj.Value.isScalePatched)
                            {
                                redefObject.transform.localScale = obj.Value.scale;
                            }

                            redefObject.SetActive(!obj.Value.isHidden);

                            GameObject.DestroyImmediate(newObject, true);
                            continue;
                        }
                    }

                    newObject.transform.parent = FindParent(mission, obj.Value.parentName, rootObject).transform;

                    newObject.transform.localPosition = obj.Value.pos;
                    newObject.transform.localRotation = obj.Value.rot;
                    newObject.transform.localScale    = obj.Value.scale;

                    var specObject = newObject.AddComponent <ObjectDefinition>();
                    specObject.data = obj.Value;
                    specObject.Init();
                }
            }

            // NOTE(zaklaus): Hardcode 'Primary sector' scale to (1,1,1)
            var primarySector = GameObject.Find("Primary sector");

            if (primarySector != null)
            {
                primarySector.transform.localScale = new Vector3(1, 1, 1);
            }

            StoreChachedObject(path, rootObject);

            return(rootObject);
        }