FreeTrainの進化系を目指す
マウスポインタ位置の地形ポリゴンを検出できるようにした。
| @@ -63,6 +63,14 @@ | ||
| 63 | 63 | public override string ToString() { |
| 64 | 64 | return "PointF3D("+X+","+Y+","+Z+")"; |
| 65 | 65 | } |
| 66 | + | |
| 67 | + Point3D Ceiling() { | |
| 68 | + return new Point3D((int)Math.Ceiling(X), (int)Math.Ceiling(Y), (int)Math.Ceiling(Z)); | |
| 69 | + } | |
| 70 | + | |
| 71 | + Point3D Floor() { | |
| 72 | + return new Point3D((int)Math.Floor(X), (int)Math.Floor(Y), (int)Math.Floor(Z)); | |
| 73 | + } | |
| 66 | 74 | } |
| 67 | 75 | |
| 68 | 76 | /// <summary> |
| @@ -264,9 +264,9 @@ | ||
| 264 | 264 | } |
| 265 | 265 | |
| 266 | 266 | public UInt32 HitTestAt(int vx, int vy) { |
| 267 | - XnaColor xc = GetWorkPixelAt(vx, vy, 1); | |
| 268 | - Debug.WriteLine("mouse=" + xc); | |
| 269 | - return xc.PackedValue&0xffffff; | |
| 267 | + XnaColor xc = GetWorkPixelAt(vx, vy, (int)RenderOutput.ObjKeyMap); | |
| 268 | + //Debug.WriteLine("mouse=" + xc); | |
| 269 | + return xc.PackedValue; | |
| 270 | 270 | } |
| 271 | 271 | #endregion |
| 272 | 272 |
| @@ -113,7 +113,7 @@ | ||
| 113 | 113 | try { |
| 114 | 114 | return hmap[x, y].GetPieces(viewupper); |
| 115 | 115 | } catch (IndexOutOfRangeException) { |
| 116 | - Debug.WriteLine("x="+x+", y="+y+", map="+hmap.GetUpperBound(0)+","+hmap.GetUpperBound(1)); | |
| 116 | + Debug.WriteLine("The location (" + x + ", y=" + y + ") is OUTSIDE of the map{ size:(" + hmap.GetUpperBound(0) + "," + hmap.GetUpperBound(1)+")}"); | |
| 117 | 117 | return NullEnumerator(); |
| 118 | 118 | } |
| 119 | 119 | } |
| @@ -9,6 +9,7 @@ | ||
| 9 | 9 | using System.Diagnostics; |
| 10 | 10 | using Geocon = nft.core.geometry.GeometricConstants; |
| 11 | 11 | using nft.core.game; |
| 12 | +using nft.core.view; | |
| 12 | 13 | |
| 13 | 14 | namespace nft.impl.view |
| 14 | 15 | { |
| @@ -16,19 +17,24 @@ | ||
| 16 | 17 | { |
| 17 | 18 | public delegate void TerrainPlateModifier(ITerrainPlate plate, ITerrainMap map, int x, int y, TerrainPieceTemplate.TerrainPolygonSet tpset); |
| 18 | 19 | |
| 19 | - CoordinationUtil cdUtil = null; | |
| 20 | - Scaler scaler; | |
| 21 | - InterCardinalDirection upperDir; | |
| 20 | + internal const int TrMk_Ground = 0; | |
| 21 | + internal const int TrMk_CliffLeft = 1; | |
| 22 | + internal const int TrMk_CliffRight = 2; | |
| 23 | + internal const int TrMk_CliffDiag = 3; | |
| 22 | 24 | |
| 25 | + internal CoordinationUtil cdUtil = null; | |
| 26 | + internal Scaler scaler; | |
| 27 | + internal InterCardinalDirection upperDir; | |
| 28 | + | |
| 23 | 29 | IApparentAssignor apparents; |
| 24 | - GameImpl game; | |
| 25 | - ISurface surface; | |
| 30 | + internal GameImpl game; | |
| 31 | + internal ISurface surface; | |
| 26 | 32 | Point viewpos; |
| 27 | 33 | int voffset; |
| 28 | 34 | |
| 29 | 35 | public SceneBuilder(GameImpl g) { |
| 30 | 36 | this.game = g; |
| 31 | - SetViewFactor(new ViewFactor(InterCardinalDirection.NORTHEAST)); | |
| 37 | + SetViewFactor(new ViewFactor(InterCardinalDirection.NORTHEAST, ZoomScale.x2)); | |
| 32 | 38 | } |
| 33 | 39 | |
| 34 | 40 | public SceneBuilder(GameImpl g, ISurface s) : this(g){ |
| @@ -83,6 +89,19 @@ | ||
| 83 | 89 | viewpos = p; |
| 84 | 90 | } |
| 85 | 91 | |
| 92 | + private bool CheckMarker(Point uv, int typecode, ref ITerrainPlate plate) { | |
| 93 | + if (marker0 != null && marker0.Same(uv, typecode)) { | |
| 94 | + //Debug.WriteLine("Hit("+x+","+y+")"); | |
| 95 | + PointF3D pmk = plate.Location; | |
| 96 | + pmk.Z += 0.5f; | |
| 97 | + plate.Location = pmk; | |
| 98 | + plate.Effect = GraphicManagerEx.GraphicManager.GetFilterByUsage(); | |
| 99 | + return true; | |
| 100 | + } else { | |
| 101 | + return false; | |
| 102 | + } | |
| 103 | + } | |
| 104 | + | |
| 86 | 105 | Stopwatch watch0 = new Stopwatch(); |
| 87 | 106 | int xxx = 0; |
| 88 | 107 | public IEnumerator<I3DObject> GetEnumerator() { |
| @@ -117,12 +136,8 @@ | ||
| 117 | 136 | plate.Location = new PointF3D(pv.VX, pv.VY, pv.VZ); |
| 118 | 137 | watch0.Stop(); |
| 119 | 138 | yield return plate; |
| 120 | - if (marker0 != null && marker0.Same(uv, tpset)) { | |
| 139 | + if (CheckMarker(uv, TrMk_Ground, ref plate)) { | |
| 121 | 140 | //Debug.WriteLine("Hit("+x+","+y+")"); |
| 122 | - PointF3D pmk = plate.Location; | |
| 123 | - pmk.Z += 0.5f; | |
| 124 | - plate.Location = pmk; | |
| 125 | - plate.Effect = GraphicManagerEx.GraphicManager.GetFilterByUsage(); | |
| 126 | 141 | yield return plate; |
| 127 | 142 | } |
| 128 | 143 | } |
| @@ -142,6 +157,9 @@ | ||
| 142 | 157 | plate = apparents.DefaultCliffTexture.Get(cp, hgap, pv); |
| 143 | 158 | plate.Location = new PointF3D(pv.VX, pv.VY, pvz); |
| 144 | 159 | yield return plate; |
| 160 | + if (CheckMarker(uv, TrMk_CliffLeft, ref plate)) { | |
| 161 | + yield return plate; | |
| 162 | + } | |
| 145 | 163 | } |
| 146 | 164 | } |
| 147 | 165 | if (dside != ViewDirection8.RIGHT && cdUtil.IsRightCliffVisible(map, l, out hgap)) { |
| @@ -158,6 +176,9 @@ | ||
| 158 | 176 | plate = apparents.DefaultCliffTexture.Get(cp, hgap, pv); |
| 159 | 177 | plate.Location = new PointF3D(pv.VX, pv.VY, pvz); |
| 160 | 178 | yield return plate; |
| 179 | + if (CheckMarker(uv, TrMk_CliffRight, ref plate)) { | |
| 180 | + yield return plate; | |
| 181 | + } | |
| 161 | 182 | } |
| 162 | 183 | } |
| 163 | 184 | } else { |
| @@ -175,6 +196,9 @@ | ||
| 175 | 196 | plate = apparents.DefaultCliffTexture.Get(cp, hgap, pv); |
| 176 | 197 | plate.Location = new PointF3D(pv.VX, pv.VY, pvz); |
| 177 | 198 | yield return plate; |
| 199 | + if (CheckMarker(uv, TrMk_CliffDiag, ref plate)) { | |
| 200 | + yield return plate; | |
| 201 | + } | |
| 178 | 202 | } |
| 179 | 203 | } |
| 180 | 204 | } |
| @@ -219,13 +243,23 @@ | ||
| 219 | 243 | #endif |
| 220 | 244 | for (int h = hmin; h <= hmax; h++) { |
| 221 | 245 | for (int w = wmin; w <= wmax; w++) { |
| 222 | - yield return ViewToIsometricPlane(w, h); | |
| 246 | + yield return ViewGridToIsometricPlane(w, h); | |
| 223 | 247 | } |
| 224 | 248 | } |
| 225 | 249 | } |
| 226 | 250 | |
| 227 | 251 | // view grid (cell sized) to isometric grid |
| 252 | + internal protected Point ViewGridToIsometricPlane(int vx, int vy) { | |
| 253 | + int v2 = vy / 2; | |
| 254 | + int x = v2 - vx + (vy & 1); | |
| 255 | + int y = v2 + vx; | |
| 256 | + return new Point(x, y); | |
| 257 | + } | |
| 258 | + | |
| 259 | + // view pixel pos to isometric grid | |
| 228 | 260 | internal protected Point ViewToIsometricPlane(int vx, int vy) { |
| 261 | + vx = (vx / Geocon.UnitWidthPixel) / 2; | |
| 262 | + vy = (vy / Geocon.HalfOf_UnitWidthPixel) - 10; | |
| 229 | 263 | int v2 = vy / 2; |
| 230 | 264 | int x = v2 - vx + (vy & 1); |
| 231 | 265 | int y = v2 + vx; |
| @@ -232,7 +266,6 @@ | ||
| 232 | 266 | return new Point(x, y); |
| 233 | 267 | } |
| 234 | 268 | |
| 235 | - | |
| 236 | 269 | // isometric grid to view positon (in pixel). |
| 237 | 270 | internal protected Point IsometricGridToView(int isx, int isy) { |
| 238 | 271 | int x = (isy - isx)/2; |
| @@ -240,7 +273,24 @@ | ||
| 240 | 273 | return new Point(x * Geocon.UnitWidthPixel, y * Geocon.HalfOf_UnitWidthPixel); |
| 241 | 274 | } |
| 242 | 275 | |
| 276 | + protected Point WorldPosToGrid(PointF3D p3d) { | |
| 277 | + int isx = (int)Math.Floor(p3d.X / Geocon.UnitWidthPixel); | |
| 278 | + int isy = (int)Math.Floor(p3d.Y / Geocon.UnitWidthPixel); | |
| 279 | + int d = (int)Math.Ceiling(p3d.Z / Geocon.HalfOf_UnitWidthPixel); | |
| 280 | + return new Point(isx - d, isy - d); | |
| 281 | + } | |
| 282 | + | |
| 243 | 283 | public object GetObjectAt(Point spos) { |
| 284 | + ITerrainPolygon pol; | |
| 285 | + PointF3D p3dv; | |
| 286 | + if (DrawIndexUtil.ResolveTerrain(this, spos, out pol, out p3dv)) { | |
| 287 | + | |
| 288 | + return pol; | |
| 289 | + } | |
| 290 | + return null; | |
| 291 | + } | |
| 292 | + | |
| 293 | + public object GetObjectAt_old(Point spos) { | |
| 244 | 294 | PointF3D p3d = surface.ToWorldPosition(spos); |
| 245 | 295 | #if DEBUG |
| 246 | 296 | Debug.Write("mouse(" + spos.X + "," + spos.Y + ")"); |
| @@ -297,18 +347,29 @@ | ||
| 297 | 347 | class TerrainMarker |
| 298 | 348 | { |
| 299 | 349 | int x, y; |
| 300 | - ushort id; | |
| 350 | + int code; | |
| 301 | 351 | bool trianglehit; |
| 352 | + public TerrainMarker(Point pt, int typecode, bool inner_triangle) { | |
| 353 | + this.x = pt.X; | |
| 354 | + this.y = pt.Y; | |
| 355 | + this.code = typecode; | |
| 356 | + this.trianglehit = inner_triangle; | |
| 357 | + } | |
| 302 | 358 | public TerrainMarker(Point pt, TerrainPieceTemplate.TerrainPolygonSet tpset, bool inner_triangle) { |
| 303 | 359 | this.x = pt.X; |
| 304 | 360 | this.y = pt.Y; |
| 305 | - this.id = tpset.Ground.ID; | |
| 361 | + this.code = -1; | |
| 306 | 362 | this.trianglehit = inner_triangle; |
| 307 | 363 | } |
| 308 | - public bool Same(Point pt, TerrainPieceTemplate.TerrainPolygonSet tpset) { | |
| 309 | - return pt.X == x && pt.Y == y && tpset.Ground.ID == id; | |
| 364 | + public bool Same(Point pt, int typecode) { | |
| 365 | + return pt.X == x && pt.Y == y && this.code == typecode; | |
| 310 | 366 | } |
| 311 | 367 | } |
| 368 | + | |
| 369 | + internal void CreateMarker(int gx, int gy, int tpcode) { | |
| 370 | + marker0 = new TerrainMarker(new Point(gx, gy), tpcode, true); | |
| 371 | + } | |
| 372 | + | |
| 312 | 373 | TerrainMarker marker0; |
| 313 | 374 | protected bool HitTest(Point iso_p, Point vw_p, out object ret){ |
| 314 | 375 | //Debug.Write("HitTest at="+iso_p); |
| @@ -0,0 +1,163 @@ | ||
| 1 | +using System; | |
| 2 | +using System.Collections.Generic; | |
| 3 | +using System.Text; | |
| 4 | +using nft.core.geometry; | |
| 5 | +using System.Drawing; | |
| 6 | +using nft.framework.drawing; | |
| 7 | +using nft.impl.game; | |
| 8 | +using Geocon = nft.core.geometry.GeometricConstants; | |
| 9 | +using System.Diagnostics; | |
| 10 | + | |
| 11 | +namespace nft.impl.view { | |
| 12 | + public class DrawIndexUtil { | |
| 13 | + private const UInt32 IndexForUnknown = 0xffffffff; | |
| 14 | + private const UInt32 TypeMask = 0xf0000000; | |
| 15 | + private const UInt32 ValueMask = 0x0fffffff; | |
| 16 | + private const UInt32 Mask_GroundPolygon = 0x80000000; | |
| 17 | + private const UInt32 Mask_GroundPolygon2 = 0xa0000000; | |
| 18 | + private const UInt32 Mask_CliffPolygon = 0xc0000000; | |
| 19 | + private const UInt32 Mask_CliffPolygon_L = 0xc0000000; | |
| 20 | + private const UInt32 Mask_CliffPolygon_R = 0xe0000000; | |
| 21 | + private const UInt32 Mask_CliffPolygon_D = 0xf0000000; | |
| 22 | + private static UInt32[] cliffMaskMap; | |
| 23 | + | |
| 24 | + static DrawIndexUtil() { | |
| 25 | + cliffMaskMap = new UInt32[Enum.GetValues(typeof(CliffPolygon.CliffSide)).Length]; | |
| 26 | + cliffMaskMap[(int)CliffPolygon.CliffSide.Left] = Mask_CliffPolygon_L; | |
| 27 | + cliffMaskMap[(int)CliffPolygon.CliffSide.Right] = Mask_CliffPolygon_R; | |
| 28 | + cliffMaskMap[(int)CliffPolygon.CliffSide.Diagonal] = Mask_CliffPolygon_D; | |
| 29 | + } | |
| 30 | + | |
| 31 | + public static UInt32 GetIndexForTerrain(Point3DV pos, ITerrainPolygon polygon) { | |
| 32 | + if (polygon is GroundPolygon) { | |
| 33 | + return GetIndexForGroundPolygon((GroundPolygon)polygon, pos); | |
| 34 | + } else if (polygon is CliffPolygon) { | |
| 35 | + return GetIndexForCliffPolygon((CliffPolygon)polygon, pos); | |
| 36 | + } | |
| 37 | + return IndexForUnknown; | |
| 38 | + } | |
| 39 | + | |
| 40 | + public static UInt32 GetIndexForGroundPolygon(GroundPolygon polygon, Point3DV pos) { | |
| 41 | + bool b = polygon.DiagonalSide == ViewDirection8.FRONT || polygon.DiagonalSide == ViewDirection8.LEFT; | |
| 42 | + UInt32 idx = (UInt32)(pos.VX + pos.VY + (b ? Mask_GroundPolygon2 : Mask_GroundPolygon)); | |
| 43 | + return idx; | |
| 44 | + } | |
| 45 | + | |
| 46 | + public static UInt32 GetIndexForCliffPolygon(CliffPolygon polygon, Point3DV pos) { | |
| 47 | + UInt32 idx = (UInt32)(pos.VX + pos.VY + cliffMaskMap[(int)polygon._Side]); | |
| 48 | + return idx; | |
| 49 | + } | |
| 50 | + | |
| 51 | + | |
| 52 | + internal static bool ResolveTerrain(SceneBuilder sb, Point mousePos, out ITerrainPolygon pol, out PointF3D p3dv) { | |
| 53 | + pol = null; | |
| 54 | + //mousePos.Y++; | |
| 55 | + Debug.Write("ResolveTerrain: mouse=(" + mousePos.X + "," + mousePos.Y + ")"); | |
| 56 | + p3dv = sb.surface.ToWorldPosition(mousePos); | |
| 57 | + UInt32 idx = sb.surface.HitTestAt(mousePos.X, mousePos.Y); | |
| 58 | + TerrainMapImpl map = sb.game.TerrainMap; | |
| 59 | + if (AdjustPointForGround(ref p3dv, idx)) { | |
| 60 | + int gx = (int)Math.Round(p3dv.X / Geocon.UnitWidthPixel); | |
| 61 | + int gy = (int)Math.Round(p3dv.Y / Geocon.UnitWidthPixel); | |
| 62 | + Debug.Write("->(" + p3dv.X + "," + p3dv.Y + ") : grid[" + gx + "," + gy + "]"); | |
| 63 | + foreach (ITerrainPiece p in map[gx, gy, sb.upperDir]) { | |
| 64 | + TerrainPieceTemplate.TerrainPolygonSet tpset = p.Template.GetPolygons(sb.upperDir); | |
| 65 | + if (tpset.Ground.IsVisible) { | |
| 66 | + Point rep = sb.surface.ToScreenPosition(p3dv); | |
| 67 | + int xoff = mousePos.X - rep.X; | |
| 68 | + int yoff = mousePos.Y - rep.Y; | |
| 69 | + //Debug.Write("!"); | |
| 70 | + if (TerrainUtil.IsInnerPoint2D(tpset.Ground.GetVerticis(sb.scaler), new Point(xoff, yoff))) { | |
| 71 | + pol = tpset.Ground; | |
| 72 | + Debug.WriteLine(": Ground hit 1 off(" + xoff + ", yoff=" + yoff + ")"); | |
| 73 | + break; | |
| 74 | + } else if (pol == null) { | |
| 75 | + Debug.WriteLine(": Ground hit 2 off(" + xoff + ", yoff=" + yoff + ")"); | |
| 76 | + pol = tpset.Ground; | |
| 77 | + } | |
| 78 | + } | |
| 79 | + sb.CreateMarker(gx, gy, SceneBuilder.TrMk_Ground); | |
| 80 | + } | |
| 81 | + Debug.WriteLineIf(pol == null, "WTF!?"); | |
| 82 | + return pol != null; | |
| 83 | + } else if (AdjustPointForCliff(ref p3dv, idx)) { | |
| 84 | + int gx = (int)Math.Round(p3dv.X / Geocon.UnitWidthPixel); | |
| 85 | + int gy = (int)Math.Round(p3dv.Y / Geocon.UnitWidthPixel); | |
| 86 | + Debug.Write("->(" + p3dv.X + "," + p3dv.Y + ") : grid[" + gx + "," + gy + "]"); | |
| 87 | + foreach (ITerrainPiece p in map[gx, gy, sb.upperDir]) { | |
| 88 | + //if (p.BaseHeight < p3dv.Z) continue; | |
| 89 | + TerrainPieceTemplate.TerrainPolygonSet tpset = p.Template.GetPolygons(sb.upperDir); | |
| 90 | + UInt32 testval = (idx & Mask_CliffPolygon_D); | |
| 91 | + if (testval == Mask_CliffPolygon_D) { | |
| 92 | + Debug.WriteLine(": Cliff(Diagonal)"); | |
| 93 | + pol = tpset.CliffDiagonal; | |
| 94 | + sb.CreateMarker(gx, gy, SceneBuilder.TrMk_CliffDiag); | |
| 95 | + } else if (testval == Mask_CliffPolygon_R) { | |
| 96 | + Debug.WriteLine(": Cliff(Right)"); | |
| 97 | + pol = tpset.CliffRight; | |
| 98 | + sb.CreateMarker(gx, gy, SceneBuilder.TrMk_CliffRight); | |
| 99 | + } else { | |
| 100 | + Debug.WriteLine(": Cliff(Left)"); | |
| 101 | + pol = tpset.CliffLeft; | |
| 102 | + sb.CreateMarker(gx, gy, SceneBuilder.TrMk_CliffLeft); | |
| 103 | + } | |
| 104 | + } | |
| 105 | + Debug.WriteLineIf(pol == null, "WTF2!?"); | |
| 106 | + return pol != null; | |
| 107 | + } | |
| 108 | + Debug.WriteLine("--"); | |
| 109 | + return false; | |
| 110 | + } | |
| 111 | + | |
| 112 | + internal static bool AdjustPointForCliff(ref PointF3D p3dv, UInt32 idx) { | |
| 113 | + if ((idx & Mask_CliffPolygon) == Mask_CliffPolygon) { | |
| 114 | + AdjustPoint(ref p3dv, ValueMask & idx); | |
| 115 | + return true; | |
| 116 | + } else { | |
| 117 | + return false; | |
| 118 | + } | |
| 119 | + } | |
| 120 | + | |
| 121 | + internal static bool AdjustPointForGround(ref PointF3D p3dv, UInt32 idx) { | |
| 122 | + UInt32 test = (idx & TypeMask); | |
| 123 | + if (test == Mask_GroundPolygon || test == Mask_GroundPolygon2) { | |
| 124 | + AdjustPoint(ref p3dv, ValueMask & idx); | |
| 125 | + return true; | |
| 126 | + } else { | |
| 127 | + return false; | |
| 128 | + } | |
| 129 | + } | |
| 130 | + | |
| 131 | + private static void AdjustPoint(ref PointF3D p3dv, UInt32 idxval) { | |
| 132 | + float diff = p3dv.X + p3dv.Y - idxval; | |
| 133 | + p3dv.Z = diff; | |
| 134 | + diff = diff/2.0f; | |
| 135 | + float x = p3dv.X - diff; | |
| 136 | + float y = p3dv.Y - diff; | |
| 137 | + if (x < 0) { | |
| 138 | + p3dv.Z -= x * 2; | |
| 139 | + x = 0; | |
| 140 | + } | |
| 141 | + if (y < 0) { | |
| 142 | + p3dv.Z -= y * 2; | |
| 143 | + y = 0; | |
| 144 | + } | |
| 145 | + int ix = (int)Math.Floor(x); | |
| 146 | + int iy = (int)Math.Floor(y); | |
| 147 | + int v2 = ix + iy; | |
| 148 | + p3dv.X = ix; | |
| 149 | + p3dv.Y = iy; | |
| 150 | + //Debug.Write(" [check idxval-v2=" + (idxval - v2) + ", fx=" + x + ", ix=" + ix + ", fy=" + y + ", iy=" + iy + "]"); | |
| 151 | + if (idxval != v2) { | |
| 152 | + /* | |
| 153 | + float w = (x - ix) / Geocon.UnitWidthPixel; | |
| 154 | + if (w > 0.5f) { | |
| 155 | + p3dv.X += 1; | |
| 156 | + } else { | |
| 157 | + p3dv.Y += 1; | |
| 158 | + } | |
| 159 | + */ | |
| 160 | + } | |
| 161 | + } | |
| 162 | + } | |
| 163 | +} |
| @@ -11,6 +11,7 @@ | ||
| 11 | 11 | using System.Windows.Forms; |
| 12 | 12 | using nft.framework.plugin; |
| 13 | 13 | using nft.core; |
| 14 | +using nft.impl.view; | |
| 14 | 15 | |
| 15 | 16 | namespace nft.contributions.terrain { |
| 16 | 17 | public interface IGroundPlateSet { |
| @@ -73,7 +74,7 @@ | ||
| 73 | 74 | holder = Add(key, templ); |
| 74 | 75 | } |
| 75 | 76 | templ = holder.AddRef(); |
| 76 | - UInt32 idkey = (UInt32)(hint.VX + hint.VY+0x800000); | |
| 77 | + UInt32 idkey = DrawIndexUtil.GetIndexForTerrain(hint, polygon); | |
| 77 | 78 | return GraphicManager.CreateTerrainPlate(idkey, templ); |
| 78 | 79 | } |
| 79 | 80 |
| @@ -138,7 +139,7 @@ | ||
| 138 | 139 | holder = Add(key, templ); |
| 139 | 140 | } |
| 140 | 141 | templ = holder.AddRef(); |
| 141 | - UInt32 idkey = (UInt32)(hint.VX + hint.VY); | |
| 142 | + UInt32 idkey = DrawIndexUtil.GetIndexForCliffPolygon(polygon, hint); | |
| 142 | 143 | return GraphicManager.CreateTerrainPlate(idkey, templ); |
| 143 | 144 | } |
| 144 | 145 |
| @@ -12,7 +12,7 @@ | ||
| 12 | 12 | namespace nft.core.geometry { |
| 13 | 13 | public class CliffPolygon : ITerrainPolygon, ISerializable { |
| 14 | 14 | [Flags] |
| 15 | - public enum Side { Undefined = 0, Right = 0x01, Left = 0x02, Diagonal = 0x03 } | |
| 15 | + public enum CliffSide { Undefined = 0, Right = 0x01, Left = 0x02, Diagonal = 0x03 } | |
| 16 | 16 | |
| 17 | 17 | static Dictionary<ushort, CliffPolygon> stock = new Dictionary<ushort, CliffPolygon>(256); |
| 18 | 18 | static CliffPolygon[] fillers = new CliffPolygon[4]; |
| @@ -58,9 +58,9 @@ | ||
| 58 | 58 | registerRectPattern(-1, p2, p1); |
| 59 | 59 | } |
| 60 | 60 | } |
| 61 | - fillers[(int)Side.Left] = CreateFillerPattern(-1, 0); | |
| 62 | - fillers[(int)Side.Right] = CreateFillerPattern(0, -1); | |
| 63 | - fillers[(int)Side.Diagonal] = CreateFillerPattern(-1, -1); | |
| 61 | + fillers[(int)CliffSide.Left] = CreateFillerPattern(-1, 0); | |
| 62 | + fillers[(int)CliffSide.Right] = CreateFillerPattern(0, -1); | |
| 63 | + fillers[(int)CliffSide.Diagonal] = CreateFillerPattern(-1, -1); | |
| 64 | 64 | } |
| 65 | 65 | |
| 66 | 66 | /// <summary> |
| @@ -75,13 +75,13 @@ | ||
| 75 | 75 | private static void registerTriPattern(int near, int left, int right) { |
| 76 | 76 | ushort id = PrivateMakePolygonID(near, left, right); |
| 77 | 77 | int hp = Geocon.UnitHeightPixel; |
| 78 | - Side s = Side.Undefined; | |
| 78 | + CliffSide s = CliffSide.Undefined; | |
| 79 | 79 | if (!stock.ContainsKey(id)) { |
| 80 | 80 | Point3D[] pt = new Point3D[3]; |
| 81 | 81 | int idx = 0; |
| 82 | 82 | int id2 = 0; |
| 83 | 83 | if (left >= 0) { |
| 84 | - s |= Side.Left; | |
| 84 | + s |= CliffSide.Left; | |
| 85 | 85 | pt[idx++] = new Point3D(0, Geocon.UnitWidthPixel, left * hp); |
| 86 | 86 | if (left > 0) { |
| 87 | 87 | id2 = idx; |
| @@ -96,7 +96,7 @@ | ||
| 96 | 96 | } |
| 97 | 97 | } |
| 98 | 98 | if (right >= 0) { |
| 99 | - s |= Side.Right; | |
| 99 | + s |= CliffSide.Right; | |
| 100 | 100 | pt[idx++] = new Point3D(Geocon.UnitWidthPixel, 0, right * hp); |
| 101 | 101 | if (right > 0) { |
| 102 | 102 | id2 = idx; |
| @@ -122,12 +122,12 @@ | ||
| 122 | 122 | private static void registerRectPattern(int near, int left, int right) { |
| 123 | 123 | ushort id = PrivateMakePolygonID(near, left, right); |
| 124 | 124 | int hp = Geocon.UnitHeightPixel; |
| 125 | - Side s = Side.Undefined; | |
| 125 | + CliffSide s = CliffSide.Undefined; | |
| 126 | 126 | if (!stock.ContainsKey(id)) { |
| 127 | 127 | Point3D[] pt = new Point3D[6]; |
| 128 | 128 | int idx = 0; |
| 129 | 129 | if (left >= 0) { |
| 130 | - s |= Side.Left; | |
| 130 | + s |= CliffSide.Left; | |
| 131 | 131 | pt[idx++] = new Point3D(0, Geocon.UnitWidthPixel, left * hp); |
| 132 | 132 | pt[idx] = new Point3D(0, Geocon.UnitWidthPixel, 0); |
| 133 | 133 | idx += 2; |
| @@ -138,7 +138,7 @@ | ||
| 138 | 138 | idx += 2; |
| 139 | 139 | } |
| 140 | 140 | if (right >= 0) { |
| 141 | - s |= Side.Right; | |
| 141 | + s |= CliffSide.Right; | |
| 142 | 142 | pt[idx++] = new Point3D(Geocon.UnitWidthPixel, 0, right * hp); |
| 143 | 143 | pt[idx] = new Point3D(Geocon.UnitWidthPixel, 0, 0); |
| 144 | 144 | idx += 2; |
| @@ -159,13 +159,13 @@ | ||
| 159 | 159 | /// <param name="right"></param> |
| 160 | 160 | /// <param name="far"></param> |
| 161 | 161 | private static CliffPolygon CreateFillerPattern(int bl_left, int bl_right) { |
| 162 | - Side s = Side.Undefined; | |
| 162 | + CliffSide s = CliffSide.Undefined; | |
| 163 | 163 | const int hmax = 0x7fffffff; |
| 164 | 164 | Point3D[] pt = new Point3D[6]; |
| 165 | 165 | int idx = 0; |
| 166 | 166 | |
| 167 | 167 | if (bl_left != 0) { |
| 168 | - s |= Side.Left; | |
| 168 | + s |= CliffSide.Left; | |
| 169 | 169 | pt[idx++] = new Point3D(0, Geocon.UnitWidthPixel, hmax); |
| 170 | 170 | pt[idx] = new Point3D(0, Geocon.UnitWidthPixel, 0); |
| 171 | 171 | idx += 2; |
| @@ -176,7 +176,7 @@ | ||
| 176 | 176 | idx += 2; |
| 177 | 177 | } |
| 178 | 178 | if (bl_right != 0) { |
| 179 | - s |= Side.Right; | |
| 179 | + s |= CliffSide.Right; | |
| 180 | 180 | pt[idx++] = new Point3D(Geocon.UnitWidthPixel, 0, hmax); |
| 181 | 181 | pt[idx] = new Point3D(Geocon.UnitWidthPixel, 0, 0); |
| 182 | 182 | idx += 2; |
| @@ -250,7 +250,7 @@ | ||
| 250 | 250 | protected Point[] verticis; |
| 251 | 251 | protected Point3D[] verticis3d; |
| 252 | 252 | protected Rectangle bounds; |
| 253 | - protected Side side; | |
| 253 | + protected CliffSide side; | |
| 254 | 254 | /// <summary> |
| 255 | 255 | /// Determined by surface normal angle between the sun light. 255 is maximum. |
| 256 | 256 | /// Visible surface has positive value, effected at least by environment light. |
| @@ -258,7 +258,7 @@ | ||
| 258 | 258 | /// </summary> |
| 259 | 259 | public readonly float Brightness; |
| 260 | 260 | |
| 261 | - protected CliffPolygon(ushort id, Point3D[] pts, Side s) { | |
| 261 | + protected CliffPolygon(ushort id, Point3D[] pts, CliffSide s) { | |
| 262 | 262 | this.id = id; |
| 263 | 263 | this.verticis3d = pts; |
| 264 | 264 | this.side = s; |
| @@ -276,6 +276,12 @@ | ||
| 276 | 276 | Brightness = (float)l; |
| 277 | 277 | } |
| 278 | 278 | |
| 279 | + public CliffSide _Side { | |
| 280 | + get { | |
| 281 | + return side; | |
| 282 | + } | |
| 283 | + } | |
| 284 | + | |
| 279 | 285 | #region ITerrainPolygon メンバ |
| 280 | 286 | |
| 281 | 287 | public ushort ID { |
| @@ -390,7 +396,7 @@ | ||
| 390 | 396 | return (ushort)((height & 0x03ff)<<2 + (bl_left & 0x02) + (bl_right & 0x01)); |
| 391 | 397 | } |
| 392 | 398 | |
| 393 | - private static ushort PrivateMakeFillerID(int height, Side side) { | |
| 399 | + private static ushort PrivateMakeFillerID(int height, CliffSide side) { | |
| 394 | 400 | return (ushort)(((height & 0x03ff)<<2) + side); |
| 395 | 401 | } |
| 396 | 402 |