Example #1
0
        public void LoadFrom(Level level, int index)
        {
            DLF_IO_INTER inter = level.ArxLevelNative.DLF.inters[index];

            name = ArxIOHelper.GetString(inter.name);

            string interPath = name.ToLowerInvariant();
            int    graphPos  = interPath.IndexOf("graph");

            interPath = interPath.Substring(graphPos);
            int lastDot = interPath.LastIndexOf('.');

            interPath = interPath.Substring(0, lastDot);

            var ftlPath = Path.Combine(EditorSettings.DataDir, "game", ArxIOHelper.ArxPathToPlatformPath(interPath + ".ftl"));

            if (File.Exists(ftlPath))
            {
                FTL_IO ftl = new FTL_IO();
                using (var fs = new FileStream(ftlPath, FileMode.Open, FileAccess.Read))
                    using (var unp = FTL_IO.EnsureUnpacked(fs))
                    {
                        ftl.ReadFrom(unp);
                    }

                var mesh = ftl.CreateMesh();
                var mf   = gameObject.AddComponent <MeshFilter>();
                mf.sharedMesh = mesh;
                var mr = gameObject.AddComponent <MeshRenderer>();
                mr.sharedMaterial = MaterialsDatabase.TEST;
            }

            //depending on what the path is load item, npc, fix, camera or marker
            if (interPath.Contains("items"))
            {
            }
            else if (interPath.Contains("npc"))
            {
            }
            else if (interPath.Contains("fix"))
            {
            }
            else if (interPath.Contains("camera"))
            {
            }
            else if (interPath.Contains("marker"))
            {
            }

            transform.localPosition    = inter.pos.ToVector3();
            transform.localEulerAngles = inter.angle.ToEuler();
        }
        static void SaveMesh(Level level)
        {
            // create texture containers

            HashSet <string> uniqueTexturePaths = new HashSet <string>();

            foreach (var kv in level.EditableLevelMesh.MaterialMeshes)
            {
                if (kv.Value.PrimitiveCount > 0) //only add if we have primitives for this material
                {
                    //TODO: remove that later
                    //var texPath = kv.Key.TexturePath.Replace(EditorSettings.DataDir, "");
                    uniqueTexturePaths.Add(kv.Key.TexturePath);
                }
            }

            var fts = level.ArxLevelNative.FTS;

            fts.textureContainers = new ArxNative.IO.FTS.FTS_IO_TEXTURE_CONTAINER[uniqueTexturePaths.Count];
            int i = 1; //nothing speaks against just using a normal index for tc, i dont know why they ever used random ints, has to be 1 based
            Dictionary <string, int> texPathToTc = new Dictionary <string, int>();

            foreach (var path in uniqueTexturePaths)
            {
                int index   = i++;
                var texPath = path.Replace(EditorSettings.DataDir, "");
                fts.textureContainers[index - 1].fic = ArxIOHelper.GetBytes(texPath, 256);
                texPathToTc[path] = fts.textureContainers[index - 1].tc = index;
            }

            //create cells
            int sizex = fts.sceneHeader.sizex;
            int sizez = fts.sceneHeader.sizez;

            LevelCell[] cells = new LevelCell[sizex * sizez];
            for (int z = 0, index = 0; z < sizez; z++)
            {
                for (int x = 0; x < sizex; x++, index++)
                {
                    //int index = ArxIOHelper.XZToCellIndex(x, z, sizex, sizez);
                    var cell = new LevelCell(x, z);
                    cells[index] = cell;
                }
            }

            //add primitives to cells
            Vector2Int maxPos = new Vector2Int(sizex - 1, sizez - 1); //if clamp is inclusive we have to sub 1

            foreach (var kv in level.EditableLevelMesh.MaterialMeshes)
            {
                foreach (var prim in kv.Value.Primitives)
                {
                    var cellpos = GetPrimitiveCellPos(prim);
                    cellpos.Clamp(Vector2Int.zero, maxPos);
                    var cell = cells[ArxIOHelper.XZToCellIndex(cellpos.x, cellpos.y, sizex, sizez)];
                    cell.AddPrimitive(kv.Key, prim);
                }
            }

            List <FTS_IO_EP_DATA>[] roomPolyDatas = new List <FTS_IO_EP_DATA> [fts.rooms.Length];
            for (i = 0; i < fts.rooms.Length; ++i)
            {
                roomPolyDatas[i] = new List <FTS_IO_EP_DATA>();
            }

            List <uint> lightColors = new List <uint>();

            //put primitves into polys in their cells
            for (int z = 0, index = 0; z < sizez; z++)
            {
                for (int x = 0; x < sizex; x++, index++)
                {
                    //int index = ArxIOHelper.XZToCellIndex(x, z, sizex, sizez);
                    var myCell  = cells[index];
                    var ftsCell = fts.cells[index];
                    ftsCell.sceneInfo.nbpoly = myCell.primitives.Count;
                    ftsCell.polygons         = new FTS_IO_EERIEPOLY[myCell.primitives.Count];
                    for (i = 0; i < myCell.primitives.Count; i++)
                    {
                        var tup  = myCell.primitives[i];
                        var mat  = tup.Item1;
                        var prim = tup.Item2;
                        var poly = new FTS_IO_EERIEPOLY();
                        //copy data over
                        poly.area  = prim.area;
                        poly.norm  = new SavedVec3(prim.norm);
                        poly.norm2 = new SavedVec3(prim.norm2);
                        poly.paddy = prim.paddy;
                        poly.room  = prim.room;
                        poly.type  = prim.polyType; //this is completely ignoring mat polytype atm, but it should be sync with prim type anyway

                        if (poly.room >= 0)
                        {
                            var polyData = new FTS_IO_EP_DATA();
                            polyData.cell_x = (short)x;
                            polyData.cell_z = (short)z;
                            polyData.idx    = (short)i;
                            roomPolyDatas[poly.room].Add(polyData);
                        }

                        //copy vertices
                        poly.vertices = new ArxNative.IO.FTS.FTS_IO_VERTEX[4];
                        poly.normals  = new SavedVec3[4];
                        for (int j = 0; j < 4; j++) //always save all 4 vertices regardless of if its a triangle or quad
                        {
                            var vert    = prim.vertices[j];
                            var natVert = new ArxNative.IO.FTS.FTS_IO_VERTEX();
                            natVert.posX = vert.position.x;
                            natVert.posY = vert.position.y;
                            natVert.posZ = vert.position.z;

                            natVert.texU    = vert.uv.x;
                            natVert.texV    = 1 - vert.uv.y;
                            poly.normals[j] = new SavedVec3(vert.normal);

                            poly.vertices[j] = natVert;
                        }

                        lightColors.Add(ArxIOHelper.ToBGRA(prim.vertices[0].color));
                        lightColors.Add(ArxIOHelper.ToBGRA(prim.vertices[1].color));
                        lightColors.Add(ArxIOHelper.ToBGRA(prim.vertices[2].color));
                        if (poly.type.HasFlag(ArxNative.PolyType.QUAD))
                        {
                            lightColors.Add(ArxIOHelper.ToBGRA(prim.vertices[3].color));
                        }


                        //set material stuff
                        poly.tex      = texPathToTc[mat.TexturePath];//keyerrors should not be possible on this
                        poly.transval = mat.TransVal;
                        //polytype is set from primitive

                        ftsCell.polygons[i] = poly;
                    }
                    fts.cells[index] = ftsCell;
                }
            }

            for (i = 0; i < fts.rooms.Length; i++)
            {
                fts.rooms[i].polygons = roomPolyDatas[i].ToArray();
            }

            //update llf
            var llf = level.ArxLevelNative.LLF;

            llf.lightingHeader.numLights = lightColors.Count;
            llf.lightColors = lightColors.ToArray();
            //below does the same as toArray, just wondering if toArray is faster or manually assigning it

            /*
             * llf.lightColors = new uint[lightColors.Count];
             * for (i = 0; i < lightColors.Count; i++)
             * {
             *  llf.lightColors[i] = lightColors[i];
             * }
             */
        }
Example #3
0
        static void LoadMesh(Level lvl)
        {
            int       loadedPolys = 0;
            Stopwatch sw          = new Stopwatch();

            sw.Start();

            int lightIndex = 0;
            var fts        = lvl.ArxLevelNative.FTS;
            Dictionary <int, int> tcToIndex = new Dictionary <int, int>();

            //texture indices
            for (int i = 0; i < fts.textureContainers.Length; i++)
            {
                tcToIndex[fts.textureContainers[i].tc] = i;
            }

            //TODO: use external placeholder texture so it can be set to 0 on export
            var notFoundMaterialKey = new EditorMaterial(EditorSettings.DataDir + "graph\\interface\\misc\\default[icon].bmp", PolyType.GLOW, 0);

            for (int c = 0; c < fts.cells.Length; c++)
            {
                var cell = fts.cells[c];
                loadedPolys += cell.polygons.Length;
                for (int p = 0; p < cell.polygons.Length; p++)
                {
                    var poly = cell.polygons[p];

                    var matKey = notFoundMaterialKey;
                    if (tcToIndex.TryGetValue(poly.tex, out int textureIndex))
                    {
                        string texArxPath = ArxIOHelper.GetString(fts.textureContainers[textureIndex].fic);
                        string texPath    = TextureDatabase.GetRealTexturePath(EditorSettings.DataDir + texArxPath);
                        matKey = new EditorMaterial(texPath, poly.type, poly.transval); //TODO: speed up by using a pool of some sort?
                    }

                    MaterialMesh mm = lvl.EditableLevelMesh.GetMaterialMesh(matKey);

                    EditablePrimitiveInfo prim = new EditablePrimitiveInfo
                    {
                        polyType = poly.type,
                        norm     = poly.norm.ToVector3(),
                        norm2    = poly.norm2.ToVector3(),
                        area     = poly.area,
                        room     = poly.room,
                        paddy    = poly.paddy
                    };
                    int vertCount = prim.VertexCount;
                    for (int i = 0; i < vertCount; i++)
                    {
                        var vert = poly.vertices[i];
                        prim.vertices[i] = new EditableVertexInfo(new Vector3(vert.posX, vert.posY, vert.posZ),
                                                                  new Vector2(vert.texU, 1 - vert.texV),
                                                                  poly.normals[i].ToVector3(),
                                                                  ArxIOHelper.FromBGRA(lvl.ArxLevelNative.LLF.lightColors[lightIndex++]));
                    }

                    if (prim.IsTriangle)
                    {
                        //load 4th vertex manually as it has no lighting value and would break lighting otherwise
                        var lastVert = poly.vertices[3];
                        prim.vertices[3] = new EditableVertexInfo(new Vector3(lastVert.posX, lastVert.posY, lastVert.posZ),
                                                                  new Vector2(lastVert.texU, 1 - lastVert.texV),
                                                                  poly.normals[3].ToVector3(),
                                                                  Color.white);
                    }

                    mm.AddPrimitive(prim);
                }
            }

            foreach (var kv in lvl.EditableLevelMesh.MaterialMeshes)
            {
                kv.Value.UpdateMesh();
            }
            UnityEngine.Debug.Log("total load time: " + sw.Elapsed);
            UnityEngine.Debug.Log("Loaded polys: " + loadedPolys);
        }