FreeTrainの進化系を目指す
調査ツールの地形ポリゴン表示の回転によるズレ修正
| @@ -208,15 +208,11 @@ | ||
| 208 | 208 | Debug.WriteLine(string.Format("time={0}ms", watch0.ElapsedMilliseconds)); |
| 209 | 209 | } |
| 210 | 210 | |
| 211 | - public IEnumerable<I3DObject> GetTerrainsAt(int gridX, int gridY) { | |
| 211 | + public IEnumerable<I3DObject> GetTerrainsAt(Location l) { | |
| 212 | 212 | // 概ね GetEnumerator() のループ内と同じだが、崖のチェックをしない(必ず描画) |
| 213 | 213 | InterCardinalDirection dir = UpperDirection; |
| 214 | 214 | TerrainMapImpl map = game.TerrainMap; |
| 215 | 215 | Size3D sz = map.Size; |
| 216 | - // terrain assembl loop | |
| 217 | - | |
| 218 | - Point3DV pv = new Point3DV(gridX * Geocon.UnitWidthPixel, gridY * Geocon.UnitWidthPixel, 0); | |
| 219 | - Location l = cdUtil.IsometricGridToLocation(gridX, gridY, 0); | |
| 220 | 216 | int x = l.X; |
| 221 | 217 | int y = l.Y; |
| 222 | 218 | if (x < 0 || y < 0 || x >= sz.sx || y >= sz.sy) { |
| @@ -227,6 +223,8 @@ | ||
| 227 | 223 | if (pair == null) { |
| 228 | 224 | yield break; |
| 229 | 225 | } |
| 226 | + //Point3DV pv = new Point3DV(gridX * Geocon.UnitWidthPixel, gridY * Geocon.UnitWidthPixel, 0); | |
| 227 | + Point3DV pv = cdUtil.LocationToPoint3DV(l); | |
| 230 | 228 | TerrainPiecePair.ArrangedTerrainPieces atp = pair.GetTerrainPieces(UpperDirection); |
| 231 | 229 | ITerrainPlate plate; |
| 232 | 230 | int hgap = 0; |
| @@ -269,21 +267,22 @@ | ||
| 269 | 267 | plate.Location = new PointF3D(pv.VX, pv.VY, pv.VZ); |
| 270 | 268 | yield return plate; |
| 271 | 269 | } |
| 272 | - // Process Diagonal Cliff | |
| 273 | - cp = atp.CliffDiagonal; | |
| 274 | - hgap = atp.BaseHeightDiagonal * Geocon.UnitHeightPixel; | |
| 275 | - pv.VZ = 0; | |
| 276 | - if (cp == null && hgap > 0) { | |
| 277 | - cp = CliffPolygon.DiagonalUnitCliff; | |
| 278 | - hgap -= Geocon.TerrainStepHeightInUnit; | |
| 279 | - pv.VZ -= Geocon.TerrainStepHeightInUnit; | |
| 270 | + if (atp.PolygonSets[0].HorzSplitted) { | |
| 271 | + // Process Diagonal Cliff | |
| 272 | + cp = atp.CliffDiagonal; | |
| 273 | + hgap = atp.BaseHeightDiagonal * Geocon.UnitHeightPixel; | |
| 274 | + pv.VZ = 0; | |
| 275 | + if (cp == null && hgap > 0) { | |
| 276 | + cp = CliffPolygon.DiagonalUnitCliff; | |
| 277 | + hgap -= Geocon.TerrainStepHeightInUnit; | |
| 278 | + pv.VZ -= Geocon.TerrainStepHeightInUnit; | |
| 279 | + } | |
| 280 | + if (cp != null) { | |
| 281 | + plate = apparents.DefaultCliffTexture.Get(cp, hgap, pv); | |
| 282 | + plate.Location = new PointF3D(pv.VX, pv.VY, pv.VZ); | |
| 283 | + yield return plate; | |
| 284 | + } | |
| 280 | 285 | } |
| 281 | - if (cp != null) { | |
| 282 | - plate = apparents.DefaultCliffTexture.Get(cp, hgap, pv); | |
| 283 | - plate.Location = new PointF3D(pv.VX, pv.VY, pv.VZ); | |
| 284 | - yield return plate; | |
| 285 | - } | |
| 286 | - | |
| 287 | 286 | } |
| 288 | 287 | |
| 289 | 288 | System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { |
| @@ -37,6 +37,11 @@ | ||
| 37 | 37 | public int VY; |
| 38 | 38 | public int VZ; |
| 39 | 39 | |
| 40 | + /// <summary> | |
| 41 | + /// Do not called except from CoordinationUtil. | |
| 42 | + /// ビューの回転が考慮されていないので、CoordinationUtil以外から使わないこと | |
| 43 | + /// </summary> | |
| 44 | + /// <param name="src"></param> | |
| 40 | 45 | internal Point3DV(Location src) { |
| 41 | 46 | this.VX = src.X; |
| 42 | 47 | this.VY = src.Y; |
| @@ -49,6 +54,12 @@ | ||
| 49 | 54 | this.VZ = src.VZ; |
| 50 | 55 | } |
| 51 | 56 | |
| 57 | + public Point3DV(Point3D src) { | |
| 58 | + this.VX = src.X; | |
| 59 | + this.VY = src.Y; | |
| 60 | + this.VZ = src.Z; | |
| 61 | + } | |
| 62 | + | |
| 52 | 63 | public Point3DV(int vx, int vy, int vz) { |
| 53 | 64 | this.VX = vx; |
| 54 | 65 | this.VY = vy; |
| @@ -63,6 +74,24 @@ | ||
| 63 | 74 | /// 位置を持たないことを示す特殊な値 |
| 64 | 75 | /// </summary> |
| 65 | 76 | public static readonly Point3DV UNPLACED = new Point3DV(short.MinValue, short.MinValue, short.MinValue); |
| 77 | + | |
| 78 | + #region cast operators for 'nft.framework.drawing' objects. | |
| 79 | + public static implicit operator Point3DV(Point3D p) { | |
| 80 | + return new Point3DV(p); | |
| 81 | + } | |
| 82 | + | |
| 83 | + public static implicit operator Point3D(Point3DV p) { | |
| 84 | + return new Point3D(p.VX, p.VY, p.VZ); | |
| 85 | + } | |
| 86 | + | |
| 87 | + public static implicit operator PointF3D(Point3DV p) { | |
| 88 | + return new PointF3D(p.VX, p.VY, p.VZ); | |
| 89 | + } | |
| 90 | + | |
| 91 | + public static explicit operator Point3DV(PointF3D p) { | |
| 92 | + return new Point3DV((int)p.X, (int)p.Y, (int)p.Z); | |
| 93 | + } | |
| 94 | + #endregion | |
| 66 | 95 | } |
| 67 | 96 | |
| 68 | 97 | public class Rect3DV { |
| @@ -81,6 +110,11 @@ | ||
| 81 | 110 | public int WidthY { get{ return size.VY; } } |
| 82 | 111 | public int Height { get{ return size.VZ; } } |
| 83 | 112 | |
| 113 | + /// <summary> | |
| 114 | + /// Do not called except from CoordinationUtil. | |
| 115 | + /// ビューの回転が考慮されていないので、CoordinationUtil以外から使わないこと | |
| 116 | + /// </summary> | |
| 117 | + /// <param name="src"></param> | |
| 84 | 118 | internal Rect3DV(Rect3D src) { |
| 85 | 119 | this.loc = new Point3DV(src.Location); |
| 86 | 120 | this.size = new Size3DV(src.Size); |
| @@ -57,6 +57,13 @@ | ||
| 57 | 57 | /// </summary> |
| 58 | 58 | public abstract Location IsometricGridToLocation(int vx, int vy, int loc_z); |
| 59 | 59 | |
| 60 | + public Location Point3DVToLocation(Point3DV p) { | |
| 61 | + int ux = p.VX / Geocon.UnitWidthPixel; | |
| 62 | + int uy = p.VY / Geocon.UnitWidthPixel; | |
| 63 | + int uz = p.VZ / Geocon.UnitHeightPixel; | |
| 64 | + return IsometricGridToLocation(ux, uy, uz); | |
| 65 | + } | |
| 66 | + | |
| 60 | 67 | /// <summary> |
| 61 | 68 | /// Converts the quarter view coordinates(p) to world map location(X,Y,locZ). |
| 62 | 69 | /// </summary> |
| @@ -82,6 +89,19 @@ | ||
| 82 | 89 | } |
| 83 | 90 | |
| 84 | 91 | /// <summary> |
| 92 | + /// Converts the world map location(X,Y,Z) to 3D world coordination in pixel (not grid). | |
| 93 | + /// </summary> | |
| 94 | + /// <param name="loc"></param> | |
| 95 | + /// <returns></returns> | |
| 96 | + public Point3DV LocationToPoint3DV(Location loc) { | |
| 97 | + Point3DV p = RotatedForViewAxis(loc); | |
| 98 | + p.VX *= Geocon.UnitWidthPixel; | |
| 99 | + p.VY *= Geocon.UnitWidthPixel; | |
| 100 | + p.VZ *= Geocon.UnitHeightPixel; | |
| 101 | + return p; | |
| 102 | + } | |
| 103 | + | |
| 104 | + /// <summary> | |
| 85 | 105 | /// Converts the rotated world map coordinates(X,Y,Z) to quarter view coordinates(X,Y). |
| 86 | 106 | /// </summary> |
| 87 | 107 | public Point LocationToQuarterXY(Point3DV pt) { |
| @@ -100,7 +120,7 @@ | ||
| 100 | 120 | public abstract PointF LocationToQuarterXY(LocationF loc); |
| 101 | 121 | |
| 102 | 122 | /// <summary> |
| 103 | - /// Rotate 3D Rectangle along the quarter view pseudo axis. | |
| 123 | + /// Rotate 3D Rectangle along the quarter view pseudo axis. result is by grid unit. | |
| 104 | 124 | /// the vertex which point out the Location will re-selected to |
| 105 | 125 | /// the one most nearest to the axis origin (0,0,0); |
| 106 | 126 | /// Y Axis:Increase from bottom right to top left |
| @@ -111,7 +131,7 @@ | ||
| 111 | 131 | public abstract Rect3DV RotatedForViewAxis(Rect3D rect); |
| 112 | 132 | |
| 113 | 133 | /// <summary> |
| 114 | - /// Rotate 3D Location along the quarter view pseudo axis. | |
| 134 | + /// Rotate 3D Location along the quarter view pseudo axis. result is by grid unit. | |
| 115 | 135 | /// coordination will recalced to be an offset from the front vertex of the world rectangle. |
| 116 | 136 | /// Y Axis:Increase from bottom right to top left |
| 117 | 137 | /// X Axis:Increase from bottom left to top right |
| @@ -11,6 +11,7 @@ | ||
| 11 | 11 | using nft.framework.drawing; |
| 12 | 12 | using nft.impl.game; |
| 13 | 13 | using Geocon = nft.core.geometry.GeometricConstants; |
| 14 | +using nft.core.geometry; | |
| 14 | 15 | |
| 15 | 16 | namespace nft.ui.core |
| 16 | 17 | { |
| @@ -53,11 +54,21 @@ | ||
| 53 | 54 | Point pos = args.OriginalEventArgs.Location; |
| 54 | 55 | SelectionInfo si = view.SceneBuilder.GetObjectAt(pos); |
| 55 | 56 | if (si != null) { |
| 56 | - if (si.Polygon != null) { | |
| 57 | - lbStatus.Text = String.Format("HT={0:X6},PID={1:X6}", si.HitTestValue, si.Polygon.ID); | |
| 57 | + StringBuilder sb = new StringBuilder(); | |
| 58 | + sb.AppendLine(String.Format("Location({0},{1}), Height={2}", si.Location.X, si.Location.Y, si.Location.Z)); | |
| 59 | + sb.AppendLine(String.Format("ViewGrid({0:f1},{1:f1},{2:f1})", si.WorldPosition.X / Geocon.UnitWidthPixel, si.WorldPosition.Z / Geocon.UnitWidthPixel, si.WorldPosition.Y / Geocon.UnitHeightPixel)); | |
| 60 | + sb.Append(String.Format("HT={0:X6}", si.HitTestValue)); | |
| 61 | + if (si.TerrainPiece != null) { | |
| 62 | + sb.Append(String.Format(",TID={0:X6}", si.TerrainPiece.Template.ID)); | |
| 63 | + if (si.Polygon != null) { | |
| 64 | + sb.AppendLine(String.Format(",PID={0:X6}", si.Polygon.ID)); | |
| 65 | + } else { | |
| 66 | + sb.AppendLine(); | |
| 67 | + } | |
| 58 | 68 | } else { |
| 59 | - lbStatus.Text = String.Format("HT={0:X6},PID=N/A", si.HitTestValue); | |
| 69 | + sb.AppendLine(",NoTerrain"); | |
| 60 | 70 | } |
| 71 | + lbStatus.Text = sb.ToString(); | |
| 61 | 72 | this.renderViewPanel.Surface.Objects = ToRenderObjects(si); |
| 62 | 73 | } else { |
| 63 | 74 | lbStatus.Text = "N/A"; |
| @@ -66,20 +77,16 @@ | ||
| 66 | 77 | |
| 67 | 78 | protected IEnumerable<I3DObject> ToRenderObjects(SelectionInfo si) { |
| 68 | 79 | if (si.TerrainPiece != null) { |
| 69 | - int x = si.Location.X; | |
| 70 | - int y = si.Location.Y; | |
| 80 | + Point3DV pv = (Point3DV)si.WorldPosition; | |
| 81 | + IEnumerable<I3DObject> terrains = si.SceneBuilder.GetTerrainsAt(si.Location); | |
| 71 | 82 | int h = si.TerrainPiece.BaseHeight * Geocon.UnitHeightPixel; |
| 72 | - IEnumerable<I3DObject> terrains = si.SceneBuilder.GetTerrainsAt(x, y); | |
| 73 | - x *= Geocon.UnitWidthPixel; | |
| 74 | - y *= Geocon.UnitWidthPixel; | |
| 75 | - PointF3D pt; | |
| 83 | + PointF3D pt; | |
| 76 | 84 | foreach (I3DObject obj in terrains) { |
| 77 | 85 | ITerrainPlate p = obj as ITerrainPlate; |
| 78 | 86 | pt = p.Location; |
| 79 | - p.Location = new PointF3D(pt.X - x, pt.Y - y, pt.Z - h); | |
| 87 | + p.Location = new PointF3D(0, 0, pt.Z - h); | |
| 80 | 88 | yield return p; |
| 81 | 89 | } |
| 82 | - | |
| 83 | 90 | } |
| 84 | 91 | yield break; |
| 85 | 92 | } |