/// <summary> /// LOADER THREAD /// loads the sprites of a given sector to the faceSprites Dictionary /// </summary> /// <param name="sectorID"></param> public static void loadSprites(int sectorID) { int totalStatics = 0; //Just for info int totalStaticsSingle = 0; //Just for info UOReader.FacetSector fs = UOFacetManager.getSector(sectorID); for (int x = 0; x < fs.tiles.Length; ++x) { for (int y = 0; y < fs.tiles[x].Length; ++y) { if (fs.tiles[x][y].staticsCount <= 0) { continue; } for (int i = 0; i < fs.tiles[x][y].statics.Length; ++i) { facetStatic_t st = fs.tiles[x][y].statics[i]; if (!facetSprites.ContainsKey(st.graphic)) { facetSprites.Add(st.graphic, new UOStatic(st.graphic)); totalStaticsSingle++; } totalStatics++; } } } UOConsole.Debug("LOADER: instanced {0} statics, based on {1} uniques.", totalStatics, totalStaticsSingle); return; }
public static FacetSector readSector(BinaryReader r) { FacetSector fs = new FacetSector(); fs.facetID = r.ReadByte(); fs.sectorID = r.ReadUInt16(); for (int x = 0; x < 64; ++x) { fs.tiles[x] = new facetTile_t[64]; for (int y = 0; y < 64; ++y) { fs.tiles[x][y].z = r.ReadSByte(); fs.tiles[x][y].landtileGraphic = r.ReadUInt16(); fs.tiles[x][y].delimitersCount = r.ReadByte(); if (fs.tiles[x][y].delimitersCount > 0) { fs.tiles[x][y].delimiters = new facetDelimiter_t[fs.tiles[x][y].delimitersCount]; for (int i = 0; i < fs.tiles[x][y].delimitersCount; ++i) { fs.tiles[x][y].delimiters[i].direction = r.ReadByte(); if (fs.tiles[x][y].delimiters[i].direction < 8) { fs.tiles[x][y].delimiters[i].z = r.ReadSByte(); fs.tiles[x][y].delimiters[i].graphic = r.ReadUInt32(); } } } fs.tiles[x][y].staticsCount = r.ReadByte(); if (fs.tiles[x][y].staticsCount > 0) { fs.tiles[x][y].statics = new facetStatic_t[fs.tiles[x][y].staticsCount]; for (int i = 0; i < fs.tiles[x][y].staticsCount; ++i) { fs.tiles[x][y].statics[i].graphic = r.ReadUInt32(); fs.tiles[x][y].statics[i].z = r.ReadSByte(); fs.tiles[x][y].statics[i].color = r.ReadUInt32(); } } } } return fs; }
public static FacetSector readSector(BinaryReader r) { FacetSector fs = new FacetSector(); fs.facetID = r.ReadByte(); fs.sectorID = r.ReadUInt16(); for (int x = 0; x < 64; ++x) { fs.tiles[x] = new facetTile_t[64]; for (int y = 0; y < 64; ++y) { fs.tiles[x][y].z = r.ReadSByte(); fs.tiles[x][y].landtileGraphic = r.ReadUInt16(); fs.tiles[x][y].delimitersCount = r.ReadByte(); if (fs.tiles[x][y].delimitersCount > 0) { fs.tiles[x][y].delimiters = new facetDelimiter_t[fs.tiles[x][y].delimitersCount]; for (int i = 0; i < fs.tiles[x][y].delimitersCount; ++i) { fs.tiles[x][y].delimiters[i].direction = r.ReadByte(); if (fs.tiles[x][y].delimiters[i].direction < 8) { fs.tiles[x][y].delimiters[i].z = r.ReadSByte(); fs.tiles[x][y].delimiters[i].graphic = r.ReadUInt32(); } } } fs.tiles[x][y].staticsCount = r.ReadByte(); if (fs.tiles[x][y].staticsCount > 0) { fs.tiles[x][y].statics = new facetStatic_t[fs.tiles[x][y].staticsCount]; for (int i = 0; i < fs.tiles[x][y].staticsCount; ++i) { fs.tiles[x][y].statics[i].graphic = r.ReadUInt32(); fs.tiles[x][y].statics[i].z = r.ReadSByte(); fs.tiles[x][y].statics[i].color = r.ReadUInt32(); } } } } return(fs); }
/// <summary> /// MAIN THREAD /// This function loads a sector and puts the resulting terrain mesh into a GameObject /// </summary> /// <param name="sectorID"></param> /// <returns></returns> public static GameObject buildTerrain(int sectorID) { GameObject terrain = new GameObject("terrain" + sectorID); MeshFilter mf = (MeshFilter)terrain.AddComponent(typeof(MeshFilter)); MeshRenderer mr = (MeshRenderer)terrain.AddComponent(typeof(MeshRenderer)); //MeshCollider mc = (MeshCollider)terrain.AddComponent(typeof(MeshCollider)); //Load a facet sector UOReader.FacetSector sec = UOFacetManager.getSector(sectorID); //Set the data to a mesh Mesh mesh = new Mesh(); UOFacetManager.facetSectorMesh m = UOFacetManager.buildTerrainMesh(sec); //Copy values from the specific class.... i tried using directly a mesh but didn't worked.. mesh.vertices = m.vertices; mesh.triangles = m.triangles; mesh.normals = m.normals; mesh.uv = m.uvs; int i = 0; mesh.subMeshCount = m.subMeshes.Values.Count; UOConsole.Fatal("terrain: {0} subMeshes", mesh.subMeshCount); foreach (uint k in m.subMeshes.Keys) { //UOConsole.Fatal(string.Format("idx {0} texture {1} count: {2}", i, k, m.subMeshes[k].Count)); mesh.SetTriangles(m.subMeshes[k].ToArray(), i++); } mf.mesh = mesh; mr.materials = m.materials.ToArray(); float sq = Mathf.Sqrt(2.0f); terrain.transform.Rotate(0, 0, -45.0f); terrain.transform.localScale *= 1 / sq; terrain.transform.localScale /= 1.6525f; //Moving from 100pixel based to 64pixel based return(terrain); }
/// <summary> /// MAIN THREAD /// load the already cached sprites into GameObjects. /// This function ignores not-yet loaded sprites. /// </summary> public void loadObjects(Position p) { UOReader.FacetSector fs = UOFacetManager.getSector(sectorID); int worldY = (fs.sectorID % 64) * 64; int worldX = (fs.sectorID / 64) * 64; //Check if the block does not exit yet if (statics[fs.sectorID] == null) { statics[fs.sectorID] = new GameObject(fs.sectorID.ToString() + " statics"); statics[fs.sectorID].transform.parent = theMap.transform; terrains[fs.sectorID] = buildTerrain(fs.sectorID); terrains[fs.sectorID].transform.parent = theMap.transform; } bool needsAnotherRun = false; //Wheter the SectorLoader thread has not finished yet. for (int x = 0; x < fs.tiles.Length; ++x) { for (int y = 0; y < fs.tiles[x].Length; ++y) { if (Mathf.Abs(worldX + x - p.x) > UPDATE_RANGE || Mathf.Abs(worldY + y - p.y) > UPDATE_RANGE) { needsAnotherRun = true; continue; } if (fs.tiles[x][y].staticsCount <= 0) { continue; } if (goArray[x, y] == null) { goArray[x, y] = new GameObject[fs.tiles[x][y].statics.Length]; } for (int i = 0; i < fs.tiles[x][y].statics.Length; ++i) { facetStatic_t st = fs.tiles[x][y].statics[i]; if (facetSprites.ContainsKey(st.graphic)) { if (goArray[x, y][i] == null) { UOStatic si = facetSprites[st.graphic] as UOStatic; if (si == null) { facetSprites.Remove(st.graphic); UOConsole.Fatal("UPDATE: Removing {0} cause it's null", st.graphic); } goArray[x, y][i] = si.getDrawItem(x, y, st.z, worldX, worldY); goArray[x, y][i].transform.parent = statics[fs.sectorID].transform; } //Else we already have the tile loaded! } else { //We need another run needsAnotherRun = true; } } //End statics } //End y } //End x if (!needsAnotherRun) { fullLoaded = true; UOConsole.Debug("UPDATE: Finished loading {0}", sectorID); } return; }
/// <summary> /// MAIN THREAD -> TODO : Separate loading from GameObjects. /// Build the terrain mesh for the current sectorID /// </summary> /// <param name="fs"></param> /// <returns></returns> private static facetSectorMesh buildTerrainMesh(FacetSector fs) { facetSectorMesh mesh = new facetSectorMesh(); int worldY = (fs.sectorID % 64) * 64; int worldX = (fs.sectorID / 64) * 64; mesh.vertices = new Vector3[4 * (64 * 64)]; mesh.normals = new Vector3[4 * (64 * 64)]; mesh.uvs = new Vector2[4 * 64 * 64]; mesh.triangles = new int[3 * (64 * 64 * 2)]; int flipper = -1; for (int x = 0; x < fs.tiles.Length; ++x) { for (int y = 0; y < fs.tiles[x].Length; ++y) { float z = +fs.tiles[x][y].z * 6 / UOSprite.UOEC_SIZE; int idxVertices = 4 * (x + y * 64); float z0, z1, z2, z3; z0 = z; z1 = z; z2 = z; z3 = z; if(x == 0){ //TODO: take information from other sector delimiters } else if (y == 0) { } else { z0 = (fs.tiles[x - 1][y - 1].z) * 6 / (UOSprite.UOEC_SIZE); z1 = (fs.tiles[x][y - 1].z) * 6 / (UOSprite.UOEC_SIZE); z2 = (fs.tiles[x - 1][y].z) * 6 / (UOSprite.UOEC_SIZE); z3 = (fs.tiles[x][y].z) * 6 / (UOSprite.UOEC_SIZE); } int _x = x + worldX, _y = y + worldY; // 0 1 // | \ | // 2 3 //Vertices mesh.vertices[idxVertices + 0] = new Vector3(_x - z0, flipper * _y + z0, 100 - z0); mesh.vertices[idxVertices + 1] = new Vector3(_x + 1 - z1, flipper * _y + z1, 100 - z1); mesh.vertices[idxVertices + 2] = new Vector3(_x - z2, flipper * (_y + 1) + z2, 100 - z2); mesh.vertices[idxVertices + 3] = new Vector3(_x + 1 - z3, flipper * (_y + 1) + z3, 100 - z3); //Normals mesh.normals[idxVertices + 0] = mesh.normals[idxVertices + 1] = mesh.normals[idxVertices + 2] = mesh.normals[idxVertices + 3] = Vector3.up; //Triangles - Clockwise List<int> subTriangles;// List containin all indices of sametexture uvStatus uvOffset; TextureImageInfo textureInfo = UOResourceManager.getLandtileTextureID(fs.tiles[x][y].landtileGraphic); if (mesh.subMeshes.ContainsKey(textureInfo.textureIDX)) { subTriangles = mesh.subMeshes[textureInfo.textureIDX];//Get the already instanced list uvOffset = mesh.subMeshTextureOffset[textureInfo.textureIDX]; } else { //Create a new list and set it subTriangles = new List<int>(); mesh.subMeshes.Add(textureInfo.textureIDX, subTriangles); //Each subMesh has a material Material mat = UOResourceManager.getResource(textureInfo, ShaderTypes.Terrain).getMaterial(); mesh.materials.Add(mat); // uvOffset = new uvStatus(); uvOffset.u = 0; uvOffset.v = 0; mesh.subMeshTextureOffset[textureInfo.textureIDX] = uvOffset; } //Bottom triangles int offset = idxVertices; subTriangles.Add(offset); subTriangles.Add(offset + 3); subTriangles.Add(offset + 2); //Upper triangles subTriangles.Add(offset); subTriangles.Add(offset + 1); subTriangles.Add(offset + 3); //End Triangles //UVs float us, ue, vs, ve; float texSize = 1.0f / textureInfo.repetition; us = uvOffset.u; ue = uvOffset.u + texSize; vs = uvOffset.v; ve = uvOffset.v + texSize; if (ue > 1.0f) ue -= 1.0f; if (ve > 1.0f) ve -= 1.0f; mesh.uvs[idxVertices + 0] = new Vector2(us, ve); mesh.uvs[idxVertices + 1] = new Vector2(ue, ve); mesh.uvs[idxVertices + 2] = new Vector2(us, vs); mesh.uvs[idxVertices + 3] = new Vector2(ue, vs); //TODO Correct handling //uvOffset.u += texSize; //uvOffset.v += texSize; if (uvOffset.v >= 1.0f) uvOffset.v = 0; if (uvOffset.u >= 1.0f) uvOffset.u = 0; } } return mesh; }