private static void ParseTextures(GND gnd, MemoryStreamReader data) { uint textureCount = data.ReadUInt(); uint texturePathLength = data.ReadUInt(); int[] lookupList = new int[textureCount]; List <string> textures = new List <string>(); for (int i = 0; i < textureCount; i++) { string texture = data.ReadBinaryString(texturePathLength); int pos = textures.IndexOf(texture); if (pos == -1) { textures.Add(texture); pos = textures.Count - 1; } lookupList[i] = pos; } gnd.textures = textures.ToArray(); gnd.textureLookupList = lookupList; }
public static GND Load(MemoryStreamReader data) { string header = data.ReadBinaryString(4); if (!string.Equals(header, GND.Header)) { throw new Exception("GroundLoader.Load: Header (" + header + ") is not \"GRGN\""); } string version = Convert.ToString(data.ReadByte()); string subversion = Convert.ToString(data.ReadByte()); version += "." + subversion; GND gnd = new GND(version); gnd.width = data.ReadUInt(); gnd.height = data.ReadUInt(); gnd.zoom = data.ReadFloat(); ParseTextures(gnd, data); ParseLightmaps(gnd, data); gnd.tiles = ParseTiles(gnd, data); gnd.surfaces = ParseSurfaces(gnd, data); return(gnd); }
private static void ParseLightmaps(GND gnd, MemoryStreamReader data) { uint lightmapCount = data.ReadUInt(); int lightmapWidth = data.ReadInt(); int lightmapHeight = data.ReadInt(); int gridSizeCell = data.ReadInt(); int perCell = lightmapWidth * lightmapHeight * gridSizeCell; if (perCell != 64) { throw new Exception("Non supported lightmap"); } var lightmap = gnd.lightmap = new GND.Lightmap(); lightmap.count = lightmapCount; //lightmap.perCell = perCell; lightmap.data = new byte[lightmapCount][]; for (int i = 0; i < lightmapCount; i++) { lightmap.data[i] = new byte[256]; data.Read(lightmap.data[i], 0, 256); } //data.Read(lightmap.data, 0, lightmap.data.Length); }
protected override void LoadContent() { Batch = new SpriteBatch(GraphicsDevice); font = Content.Load <SpriteFont>("Arial"); view = new Vector2(graphics.GraphicsDevice.Viewport.Width, graphics.GraphicsDevice.Viewport.Height); watch = Stopwatch.StartNew(); GND.GraphicsDevice = GraphicsDevice; Gnd = new GND(@"C:\Dokumente und Einstellungen\Administrator\Desktop\alberta.gnd", @"D:\Spiele\Data Crap\Content_Texture\"); Debug.WriteLine("GND.Read() needed " + watch.ElapsedMilliseconds + " ms"); watch = Stopwatch.StartNew(); Gnd.ExportTextureMap(@"C:\Dokumente und Einstellungen\Administrator\Desktop\alberta.bmp"); Debug.WriteLine("GND.ExportTextureMap() needed " + watch.ElapsedMilliseconds + " ms"); watch = Stopwatch.StartNew(); Gat = new GAT(@"C:\Dokumente und Einstellungen\Administrator\Desktop\alberta.gat"); Debug.WriteLine("GAT.Read() needed " + watch.ElapsedMilliseconds + " ms"); watch.Stop(); timer = new Timer(1000); timer.Elapsed += new ElapsedEventHandler(timer_tick); timer.Enabled = true; }
private static Texture2D CreateTilesColorImage(GND gnd) { byte[] data = new byte[gnd.width * gnd.height * 4]; for (int y = 0; y < gnd.height; y++) { for (int x = 0; x < gnd.width; x++) { var cell = gnd.surfaces[x + y * gnd.width]; // Check tile up if (cell.tileUp > -1) { var color = gnd.tiles[cell.tileUp].color; color.CopyTo(data, (x + y * gnd.width) * 4); } } } Texture2D t = new Texture2D((int)gnd.width, (int)gnd.height, TextureFormat.RGBA32, false); t.LoadRawTextureData(data); t.Apply(); //System.IO.File.WriteAllBytes(Application.dataPath + "/" + MapSelector.CurrentMap + "-TilesColorImage.png", t.EncodeToPNG()); return(t); }
private static Texture2D CreateLightmapImage(GND gnd) { List <byte> image = new List <byte>(); for (int gndY = 0; gndY < gnd.height; gndY++) { for (int lightmapY = 0; lightmapY < 8; lightmapY++) { for (int gndX = 0; gndX < gnd.width; gndX++) { for (int lightmapX = 0; lightmapX < 8; lightmapX++) { byte[] color = GetLightmapColor(gnd, gndX, gndY, lightmapX, lightmapY); byte alpha = GetLightmapBrightness(gnd, gndX, gndY, lightmapX, lightmapY); image.AddRange(color); image.Add(alpha); } } } } Texture2D t = new Texture2D((int)(gnd.width * 8), (int)(gnd.height * 8), TextureFormat.RGBA32, false); t.LoadRawTextureData(image.ToArray()); t.Apply(); //System.IO.File.WriteAllBytes(Application.dataPath + "/" + MapSelector.CurrentMap + "-LightmapImage.png", t.EncodeToPNG()); return(t); }
public IEnumerator Load(string mapname, Action <string, string, object> callback) { Progress = 0; RSW world = LoadWorld(mapname, callback); Altitude altitude = LoadAltitude(mapname, callback); GND ground = LoadGround(mapname, world, callback); yield return(LoadModels(mapname, world.modelDescriptors, callback)); }
private static Vector3[][] GetSmoothNormal(GND gnd) { Vector3 a = new Vector3(); Vector3 b = new Vector3(); Vector3 c = new Vector3(); Vector3 d = new Vector3(); var count = gnd.width * gnd.height; var tmp = new Vector3?[count]; var normals = new Vector3[count][]; var emptyVec = new Vector3(); //calculate normal for each cell for (int y = 0; y < gnd.height; y++) { for (int x = 0; x < gnd.width; x++) { var cell = gnd.surfaces[x + y * gnd.width]; if (cell.tileUp > -1) { a[0] = (x + 0) * 2; a[1] = cell.height[0]; a[2] = (y + 0) * 2; b[0] = (x + 1) * 2; b[1] = cell.height[1]; b[2] = (y + 0) * 2; c[0] = (x + 1) * 2; c[1] = cell.height[3]; c[2] = (y + 1) * 2; d[0] = (x + 0) * 2; d[1] = cell.height[2]; d[2] = (y + 1) * 2; tmp[x + y * gnd.width] = Conversions.CalcNormal(a, b, c, d); } } } //smooth normals for (int y = 0; y < gnd.height; y++) { for (int x = 0; x < gnd.width; x++) { var n = normals[x + y * gnd.width] = new Vector3[] { Vector3.zero, Vector3.zero, Vector3.zero, Vector3.zero }; for (byte i = 0; i < 4; i++) { int b1 = i & 1; int b2 = (i & 2) >> 1; int xor = b1 ^ b2; n[i] += Conversions.safeArrayAccess(tmp, x + y * gnd.width, emptyVec) ?? emptyVec; n[i] += Conversions.safeArrayAccess(tmp, x + 1 * -xor + y * gnd.width, emptyVec) ?? emptyVec; n[i] += Conversions.safeArrayAccess(tmp, x + 1 * -xor + (y + 1 * -b2) * gnd.width, emptyVec) ?? emptyVec; n[i] += Conversions.safeArrayAccess(tmp, x + (y + 1 * -b2) * gnd.width, emptyVec) ?? emptyVec; n[i].Normalize(); } } } return(normals); }
private static GND.Surface[] ParseSurfaces(GND gnd, MemoryStreamReader data) { var count = gnd.width * gnd.height; GND.Surface[] surfaces = new GND.Surface[count]; for (int i = 0; i < count; i++) { var surface = surfaces[i] = new GND.Surface(); surface.height = new Vector4(data.ReadFloat() / 5, data.ReadFloat() / 5, data.ReadFloat() / 5, data.ReadFloat() / 5); surface.tileUp = data.ReadInt(); surface.tileFront = data.ReadInt(); surface.tileRight = data.ReadInt(); } return(surfaces); }
private GND LoadGround(string mapname, RSW world, Action <string, string, object> callback) { string gndPath = "data/" + GetFilePath(WorldLoader.files.gnd); GND ground = FileManager.Load(gndPath) as GND; if (ground == null) { throw new Exception("Could not load gnd for " + mapname); } GND.Mesh compiledGround = GroundLoader.Compile(ground, world.water.level, world.water.waveHeight); LoadGroundTexture(world, compiledGround); Progress += 1; callback.Invoke(mapname, "MAP_GROUND", compiledGround); return(ground); }
public void Load(string mapname, Action <string, string, object> callback) { Progress = 0; // Load RSW string rswPath = "data/" + GetFilePath(mapname); RSW world = FileManager.Load(rswPath) as RSW; if (world == null) { throw new Exception("Could not load rsw for " + mapname); } // Load GAT string gatPath = "data/" + GetFilePath(WorldLoader.files.gat); Altitude altitude = FileManager.Load(gatPath) as Altitude; if (altitude == null) { throw new Exception("Could not load gat for " + mapname); } callback.Invoke(mapname, "MAP_ALTITUDE", altitude); // Load GND string gndPath = "data/" + GetFilePath(WorldLoader.files.gnd); GND ground = FileManager.Load(gndPath) as GND; if (ground == null) { throw new Exception("Could not load gnd for " + mapname); } var compiledGround = GroundLoader.Compile(ground, world.water.level, world.water.waveHeight); LoadGroundTexture(world, compiledGround); callback.Invoke(mapname, "MAP_WORLD", world); callback.Invoke(mapname, "MAP_GROUND", compiledGround); var compiledModels = LoadModels(world.modelDescriptors, ground); callback.Invoke(mapname, "MAP_MODELS", compiledModels); }
private static byte GetLightmapBrightness(GND gnd, int x, int y, int lightmapX, int lightmapY) { if (x < 0 || y < 0 || x >= gnd.width || y >= gnd.height) { return(0); } var cell = gnd.surfaces[x + y * gnd.width]; int tileId = (int)cell.tileUp; if (tileId == -1) { return(0); } var tile = gnd.tiles[tileId]; var lightmap = gnd.lightmap.data[tile.light]; return(lightmap[lightmapX + 8 * lightmapY]); }
private static GND.Tile[] ParseTiles(GND gnd, MemoryStreamReader data) { uint count = data.ReadUInt(); GND.Tile[] tiles = new GND.Tile[count]; var ATLAS_COLS = Math.Round(Math.Sqrt(gnd.textures.Length)); var ATLAS_ROWS = Math.Ceiling(Math.Sqrt(gnd.textures.Length)); var ATLAS_WIDTH = Math.Pow(2, Math.Ceiling(Math.Log(ATLAS_COLS * 258) / Math.Log(2))); var ATLAS_HEIGHT = Math.Pow(2, Math.Ceiling(Math.Log(ATLAS_ROWS * 258) / Math.Log(2))); var ATLAS_FACTOR_U = ATLAS_COLS * 258 / ATLAS_WIDTH; var ATLAS_FACTOR_V = ATLAS_ROWS * 258 / ATLAS_HEIGHT; var ATLAS_PX_U = 1 / 258f; var ATLAS_PX_V = 1 / 258f; for (int i = 0; i < count; i++) { var tile = tiles[i] = new GND.Tile(); tile.textureStart = new Vector4(data.ReadFloat(), data.ReadFloat(), data.ReadFloat(), data.ReadFloat()); tile.textureEnd = new Vector4(data.ReadFloat(), data.ReadFloat(), data.ReadFloat(), data.ReadFloat()); tile.texture = data.ReadUShort(); tile.light = data.ReadUShort(); var r = (byte)data.ReadByte(); var g = (byte)data.ReadByte(); var b = (byte)data.ReadByte(); var a = (byte)data.ReadByte(); tile.color = new byte[] { r, g, b, a }; tile.texture = (ushort)gnd.textureLookupList[tile.texture]; var start = tile.texture % ATLAS_COLS; var end = Math.Floor(tile.texture / ATLAS_COLS); for (int j = 0; j < 4; j++) { tile.textureStart[j] = (float)((start + tile.textureStart[j] * (1 - ATLAS_PX_U * 2) + ATLAS_PX_U) * ATLAS_FACTOR_U / ATLAS_COLS); tile.textureEnd[j] = (float)((end + tile.textureEnd[j] * (1 - ATLAS_PX_V * 2) + ATLAS_PX_V) * ATLAS_FACTOR_V / ATLAS_ROWS); } } return(tiles); }
private static byte[] GetLightmapColor(GND gnd, int x, int y, int lightmapX, int lightmapY) { if (x < 0 || y < 0 || x >= gnd.width || y >= gnd.height) { return(new byte[] { 0, 0, 0 }); } var cell = gnd.surfaces[x + y * gnd.width]; int tileId = (int)cell.tileUp; if (tileId == -1) { return(new byte[] { 0, 0, 0 }); } var tile = gnd.tiles[tileId]; byte[] lightmap = gnd.lightmap.data[tile.light]; bool rasterize = true; if (rasterize) { return(new byte[] { (byte)(lightmap[64 + (lightmapX + 8 * lightmapY) * 3 + 0] >> 4 << 4), (byte)(lightmap[64 + (lightmapX + 8 * lightmapY) * 3 + 1] >> 4 << 4), (byte)(lightmap[64 + (lightmapX + 8 * lightmapY) * 3 + 2] >> 4 << 4) }); } else { return(new byte[] { lightmap[64 + (lightmapX + 8 * lightmapY) * 3 + 0], lightmap[64 + (lightmapX + 8 * lightmapY) * 3 + 1], lightmap[64 + (lightmapX + 8 * lightmapY) * 3 + 2] }); } }
protected override void LoadContent() { Batch = new SpriteBatch( GraphicsDevice ); font = Content.Load<SpriteFont>( "Arial" ); view = new Vector2( graphics.GraphicsDevice.Viewport.Width, graphics.GraphicsDevice.Viewport.Height ); watch = Stopwatch.StartNew(); GND.GraphicsDevice = GraphicsDevice; Gnd = new GND( @"C:\Dokumente und Einstellungen\Administrator\Desktop\alberta.gnd", @"D:\Spiele\Data Crap\Content_Texture\" ); Debug.WriteLine( "GND.Read() needed " + watch.ElapsedMilliseconds + " ms" ); watch = Stopwatch.StartNew(); Gnd.ExportTextureMap( @"C:\Dokumente und Einstellungen\Administrator\Desktop\alberta.bmp" ); Debug.WriteLine( "GND.ExportTextureMap() needed " + watch.ElapsedMilliseconds + " ms" ); watch = Stopwatch.StartNew(); Gat = new GAT( @"C:\Dokumente und Einstellungen\Administrator\Desktop\alberta.gat" ); Debug.WriteLine( "GAT.Read() needed " + watch.ElapsedMilliseconds + " ms" ); watch.Stop(); timer = new Timer( 1000 ); timer.Elapsed += new ElapsedEventHandler( timer_tick ); timer.Enabled = true; }
private List <RSM.CompiledModel> LoadModels(List <RSW.ModelDescriptor> modelDescriptors, GND ground) { FileManager.InitBatch(); //queue list of models to load for (int i = 0; i < modelDescriptors.Count; i++) { var model = modelDescriptors[i]; model.filename = "data/model/" + model.filename; FileManager.Load(model.filename); } //load models FileManager.EndBatch(); //create model instances HashSet <RSM> objectsSet = new HashSet <RSM>(); for (int i = 0; i < modelDescriptors.Count; i++) { RSM model = (RSM)FileManager.Load(modelDescriptors[i].filename); if (model != null) { model.CreateInstance(modelDescriptors[i]); objectsSet.Add(model); } } FileCache.ClearAllWithExt("rsm"); RSM[] objects = new RSM[objectsSet.Count]; objectsSet.CopyTo(objects); var compiledModels = CompileModels(objects); LoadModelsTextures(compiledModels); return(compiledModels); }
public static GND.Mesh Compile(GND gnd, float WATER_LEVEL, float WATER_HEIGHT) { var normals = GetSmoothNormal(gnd); var meshData = new List <float>(); var waterMeshData = new List <float>(); for (int y = 0; y < gnd.height; y++) { for (int x = 0; x < gnd.width; x++) { var cellA = gnd.surfaces[x + y * gnd.width]; var h_a = cellA.height; float lu1 = x / (float)gnd.width; float lu2 = (x + 1) / (float)gnd.width; float lv1 = y / (float)gnd.height; float lv2 = (y + 1) / (float)gnd.height; // Check tile up if (cellA.tileUp > -1) { var tile = gnd.tiles[cellA.tileUp]; // Check if has texture var n = normals[x + y * gnd.width]; meshData.AddRange(new float[] { (x + 0) * 2, h_a[0], (y + 0) * 2, n[0][0], n[0][1], n[0][1], tile.textureStart[0], tile.textureEnd[0], lu1, lv1, (x + 0.5f) / gnd.width, (y + 0.5f) / gnd.height, (x + 1) * 2, h_a[1], (y + 0) * 2, n[1][0], n[1][1], n[1][1], tile.textureStart[1], tile.textureEnd[1], lu2, lv1, (x + 1.5f) / gnd.width, (y + 0.5f) / gnd.height, (x + 1) * 2, h_a[3], (y + 1) * 2, n[2][0], n[2][1], n[2][1], tile.textureStart[3], tile.textureEnd[3], lu2, lv2, (x + 1.5f) / gnd.width, (y + 1.5f) / gnd.height, //(x + 1) * 2, h_a[3], (y + 1) * 2, n[2][0], n[2][1], n[2][1], tile.textureStart[3], tile.textureEnd[3], lu2, lv2, (x + 1.5f) / gnd.width, (y + 1.5f) / gnd.height, (x + 0) * 2, h_a[2], (y + 1) * 2, n[3][0], n[3][1], n[3][1], tile.textureStart[2], tile.textureEnd[2], lu1, lv2, (x + 0.5f) / gnd.width, (y + 1.5f) / gnd.height, //(x + 0) * 2, h_a[0], (y + 0) * 2, n[0][0], n[0][1], n[0][1], tile.textureStart[0], tile.textureEnd[0], lu1, lv1, (x + 0.5f) / gnd.width, (y + 0.5f) / gnd.height }); // Add water only if it's upper than the ground. if (h_a[0] > WATER_LEVEL - WATER_HEIGHT || h_a[1] > WATER_LEVEL - WATER_HEIGHT || h_a[2] > WATER_LEVEL - WATER_HEIGHT || h_a[3] > WATER_LEVEL - WATER_HEIGHT) { float o = 5f; var texx = (x + 1) % o / o; if (texx == 0) { texx = 1; } var texy = (y + 1) % o / o; if (texy == 0) { texy = 1; } waterMeshData.AddRange(new float[] { // vec3 pos | vec2 texcoords (x + 0) * 2, WATER_LEVEL, (y + 0) * 2, (x + 0) % o / o, (y + 0) % o / o, (x + 1) * 2, WATER_LEVEL, (y + 0) * 2, texx, (y + 0) % o / o, (x + 1) * 2, WATER_LEVEL, (y + 1) * 2, texx, texy, //(x + 1) * 2, WATER_LEVEL, (y + 1) * 2, texx, texy, (x + 0) * 2, WATER_LEVEL, (y + 1) * 2, (x + 0) % o / o, texy, //(x + 0) * 2, WATER_LEVEL, (y + 0) * 2, ((x + 0) % 5 / 5), ((y + 0) % 5 / 5) }); } } // Check tile front if (cellA.tileFront > -1 && y + 1 < gnd.height) { var tile = gnd.tiles[cellA.tileFront]; var cellB = gnd.surfaces[x + (y + 1) * gnd.width]; var h_b = cellB.height; meshData.AddRange(new float[] { // vec3 pos | vec3 normals | vec2 texcoords | vec2 lightcoord | vec2 tileCoords (x + 0) * 2, h_b[0], (y + 1) * 2, 0.0f, 0.0f, 1.0f, tile.textureStart[2], tile.textureEnd[2], lu1, lv2, 0, 0, (x + 0) * 2, h_a[2], (y + 1) * 2, 0.0f, 0.0f, 1.0f, tile.textureStart[0], tile.textureEnd[0], lu1, lv1, 0, 0, (x + 1) * 2, h_a[3], (y + 1) * 2, 0.0f, 0.0f, 1.0f, tile.textureStart[1], tile.textureEnd[1], lu2, lv1, 0, 0, (x + 1) * 2, h_b[1], (y + 1) * 2, 0.0f, 0.0f, 1.0f, tile.textureStart[3], tile.textureEnd[3], lu2, lv2, 0, 0, }); } // Check tile right if (cellA.tileRight > -1 && x + 1 < gnd.width) { var tile = gnd.tiles[cellA.tileRight]; var cellB = gnd.surfaces[x + 1 + y * gnd.width]; var h_b = cellB.height; meshData.AddRange(new float[] { // vec3 pos | vec3 normals | vec2 texcoords | vec2 lightcoord | vec2 tileCoords (x + 1) * 2, h_a[1], (y + 0) * 2, 1, 0, 0, tile.textureStart[1], tile.textureEnd[1], lu2, lv1, 0, 0, (x + 1) * 2, h_a[3], (y + 1) * 2, 1, 0, 0, tile.textureStart[0], tile.textureEnd[0], lu1, lv1, 0, 0, (x + 1) * 2, h_b[0], (y + 0) * 2, 1, 0, 0, tile.textureStart[3], tile.textureEnd[3], lu2, lv2, 0, 0, //(x + 1) * 2, h_b[0], (y + 0) * 2, 1.0f, 0.0f, 0.0f, tile.textureStart[3], tile.textureEnd[3], lu2, lv2, 0, 0, (x + 1) * 2, h_b[2], (y + 1) * 2, 1, 0, 0, tile.textureStart[2], tile.textureEnd[2], lu1, lv2, 0, 0, //(x + 1) * 2, h_a[3], (y + 1) * 2, 1.0f, 0.0f, 0.0f, tile.textureStart[0], tile.textureEnd[0], lu1, lv1, 0, 0 }); } } } var mesh = new GND.Mesh(); mesh.width = gnd.width; mesh.height = gnd.height; mesh.textures = gnd.textures; mesh.lightmap = CreateLightmapImage(gnd); mesh.tileColor = CreateTilesColorImage(gnd); //mesh.shadowMap = CreateShadowmapData(gnd); mesh.mesh = meshData.ToArray(); mesh.meshVertCount = meshData.Count / 12; mesh.waterMesh = waterMeshData.ToArray(); mesh.waterVertCount = waterMeshData.Count / 5; return(mesh); }