public TerrainAlphaMap FindTerrainAlpha(uint pcode, uint tcode, out LandDefs.Rotation rot, out int alphaIdx) { List <TerrainAlphaMap> terrainMaps = null; var baseIdx = 0; // corner tcodes - sw / se / ne / nw if (tcode != 1 && tcode != 2 && tcode != 4 && tcode != 8) { baseIdx = 4; terrainMaps = SideTerrainMaps; // common tcode: 9 } else { terrainMaps = CornerTerrainMaps; // common tcode: 8 } var numTerrains = terrainMaps.Count; var prng = (int)Math.Floor((1379576222 * pcode - 1372186442) * 2.3283064e-10 * numTerrains); if (prng >= numTerrains) { prng = 0; } var alpha = terrainMaps[prng]; alphaIdx = baseIdx + prng; rot = LandDefs.Rotation.Rot0; var i = 0; var alphaCode = alpha.TCode; while (alphaCode != tcode) { // corners: 8 -> 1 -> 2 -> 4 // sides: 9 -> 3 -> 6 -> 12 // west / south / east / north? alphaCode *= 2; if (alphaCode >= 16) { alphaCode -= 15; } if (++i >= 4) { return(null); } } rot = (LandDefs.Rotation)i; if (alpha.Texture == null && alpha.TexGID != 0) { var qdid = new QualifiedDataID(11, alpha.TexGID); alpha.Texture = new ImgTex(DBObj.GetSurfaceTexture(alpha.TexGID)); } return(alpha); }
public uint SelectRot(int x, int y, ref LandDefs.Rotation rot, List <uint> palCode, int size, uint palID, ref int rIndex, bool minimizePal) { var first_tnum = (ulong)(1813693831 * y - x * (1647165151 * y + 1109124029) - 2031889191) * 2.3283064e-10 * LandTex.Count; var tnum = first_tnum; var cur_tnum = first_tnum; LandDefs.Rotation curRot; var jmp = false; do { while (true) { CurTex = (int)first_tnum; if (CheckTerrain(palCode, ref palID)) { break; } if (cur_tnum == first_tnum) { CurTex = 0; rot = LandDefs.Rotation.Rot0; return(palCode[0]); } } var beginRot = GetBeginRotation(x, y, palCode, minimizePal); curRot = beginRot; jmp = false; while (!CheckRot(palCode[(int)curRot], ref rIndex)) { curRot = (LandDefs.Rotation)(((int)curRot + 1) & 3); if (curRot == beginRot) { // y tnum = (tnum + 1) % (ulong)LandTex.Count; cur_tnum = tnum; if (cur_tnum == first_tnum) { CurTex = 0; rot = LandDefs.Rotation.Rot0; return(palCode[0]); } jmp = true; break; } } }while (jmp); rot = curRot; return(palCode[(int)curRot]); }
public bool SelectTerrain(int x, int y, ref uint surfNum, ref LandDefs.Rotation rot, List <uint> palCodes, int size, bool minimizePal) { var palIDs = new List <uint>(); // ?? if (PalShift == null && TexMerge == null) { return(false); } if (PalShift != null) { var rotIdx = (int)rot; var selectRotResult = PalShift.SelectRot(x, y, ref rot, palCodes, size, palIDs[0] /* fixme */, ref rotIdx /* verify */, minimizePal); if (SurfInfo.TryGetValue(selectRotResult, out var surfInfo)) { surfInfo.LCellCount++; surfNum = surfInfo.SurfNum; return(true); } else { // PalShift.MakeNewSurface() // return AddNewSurface() return(false); } } if (TexMerge != null) { var palCode = palCodes[0]; rot = LandDefs.Rotation.Rot0; if (SurfInfo.TryGetValue(palCode, out var surfInfo)) { surfInfo.LCellCount++; surfNum = surfInfo.SurfNum; return(true); } else { var surface = TexMerge.MakeNewSurface(palCode, size); return(AddNewSurface(surface, palCode, ref surfNum)); } } return(false); }
public RoadAlphaMap FindRoadAlpha(uint pcode, uint rcode, out LandDefs.Rotation rot, out int alphaIdx) { rot = LandDefs.Rotation.Rot0; alphaIdx = -1; var numRoadMaps = RoadMaps.Count; if (numRoadMaps == 0) { return(null); } var prng = (int)Math.Floor((1379576222 * pcode - 1372186442) * 2.3283064e-10 * numRoadMaps); for (var i = 0; i < numRoadMaps; i++) { var idx = (i + prng) % numRoadMaps; var alpha = RoadMaps[idx]; rot = LandDefs.Rotation.Rot0; var alphaCode = alpha.RCode; alphaIdx = 5 + idx; for (var j = 0; j < 4; j++) { if (alphaCode == rcode) { rot = (LandDefs.Rotation)j; if (alpha.Texture == null && alpha.RoadTexGID != 0) { alpha.Texture = new ImgTex(DBObj.GetSurfaceTexture(alpha.RoadTexGID)); } return(alpha); } alphaCode *= 2; if (alphaCode >= 16) { alphaCode -= 15; } } } alphaIdx = -1; return(null); }
public static bool Merge(byte[] data, uint texSize, ImgTex texture, LandDefs.Rotation rot, TerrainTex terrainTex) { if (texture == null) { return(false); } var baseTexture = terrainTex.BaseTexture; if (baseTexture != null) { ImgTex.MergeTexture(data, texSize, texSize, baseTexture, terrainTex.TexTiling, texture, rot); return(true); } else if (terrainTex.InitEnd()) { ImgTex.MergeTexture(data, texSize, texSize, terrainTex.BaseTexture, terrainTex.TexTiling, texture, rot); return(true); } return(false); }
public void GetCellRotation(uint landblockID, uint x, uint y, ref bool singleTextureCell, ref uint surfNum, ref LandDefs.Rotation rotation) { var lcoord = LandDefs.blockid_to_lcoord(landblockID); var globalCellX = (int)(lcoord.Value.X + x); var globalCellY = (int)(lcoord.Value.Y + y); // no palette shift // SW / SE / NE / NW var i = (int)(LandDefs.VertexDim * x + y); var terrain = Terrain[i]; var t1 = (terrain & 0x7F) >> 2; var r1 = terrain & 3; var j = (int)(LandDefs.VertexDim * (x + 1) + y); var terrain2 = Terrain[j]; var t2 = (terrain2 & 0x7F) >> 2; var r2 = terrain2 & 3; var terrain3 = Terrain[j + 1]; var t3 = (terrain3 & 0x7F) >> 2; var r3 = terrain3 & 3; var terrain4 = Terrain[i + 1]; var t4 = (terrain4 & 0x7F) >> 2; var r4 = terrain4 & 3; /*Console.WriteLine($"LandblockStruct.GetCellRotation({landblockID:X8}, x:{x}, y:{y})"); * Console.WriteLine($"I1: {i}, I2: {j}, I3: {j+1}, I4: {i+1}"); * if (r1 != 0 || r2 != 0 || r3 != 0 || r4 != 0) * Console.WriteLine($"R1: {r1}, R2: {r2}, R3: {r3}, R4: {r4}"); * Console.WriteLine($"T1: {(LandDefs.TerrainType)t1}, T2: {(LandDefs.TerrainType)t2}, T3: {(LandDefs.TerrainType)t3}, T4: {(LandDefs.TerrainType)t4}");*/ var palCodes = new List <uint>(); palCodes.Add(GetPalCode(r1, r2, r3, r4, t1, t2, t3, t4)); // 0 //palCodes.Add(GetPalCode(r2, r3, r4, r1, t2, t3, t4, t1)); // 270 //palCodes.Add(GetPalCode(r3, r4, r1, r2, t3, t4, t1, t2)); // 180 //palCodes.Add(GetPalCode(r4, r1, r2, r3, t4, t1, t2, t3)); // 90 var singleRoadCell = r1 == r2 && r1 == r3 && r1 == r4; var singleTypeCell = t1 == t2 && t1 == t3 && t1 == t4; singleTextureCell = r1 != 0 ? singleRoadCell : singleRoadCell && singleTypeCell; var regionDesc = DatManager.PortalDat.RegionDesc; var minimizePal = true; LandSurf.Instance.SelectTerrain(globalCellX, globalCellY, ref surfNum, ref rotation, palCodes, 1, minimizePal); }
public static void MergeTexture(byte[] data, uint dest_height, uint dest_width, ImgTex csi_merge_tex, uint tiling, ImgTex alphaMap, LandDefs.Rotation rot) { var imageData = csi_merge_tex.ImageData; var src_height = imageData != null ? imageData.Height : 0; var src_width = imageData != null ? imageData.Width : 0; var alphaData = alphaMap.ImageData; var alpha_width = alphaData != null ? alphaData.Width : 0; var alpha_height = alphaData != null ? alphaData.Height : 0; var alpha_scale = (float)dest_width / alpha_width; var pixelIdx = 0; var stepX = 0; var stepY = 0; switch (rot) { case LandDefs.Rotation.Rot0: pixelIdx = 0; stepX = 1; stepY = src_width; break; case LandDefs.Rotation.Rot90: pixelIdx = src_width - 1; stepX = src_width; stepY = -1; break; case LandDefs.Rotation.Rot180: pixelIdx = src_width * src_height - 1; stepX = -1; stepY = -src_width; break; case LandDefs.Rotation.Rot270: pixelIdx = src_width * (src_height - 1); stepX = -src_width; stepY = -1; break; } // alphaStep handles upscaling / downscaling var alphaStep = 1.0f / alpha_scale; // copy csi_merge_tex into dest buffer (data) Array.Copy(imageData.Data, data, imageData.Data.Length); // start walking the alpha map for (var _alphaY = 0.0f; _alphaY < alpha_height; _alphaY += alphaStep) { var alphaY = (int)Math.Round(_alphaY); for (var _alphaX = 0.0f; _alphaX < alpha_width; _alphaX += alphaStep) { // TODO: handle rotation var alphaX = (int)Math.Round(_alphaX); var idx = (alphaY * alpha_width + alphaX) * 4; var a = alphaData.Data[idx]; data[idx] = a; } } }