gwnavruntime/collision/heightfield.h Source File

heightfield.h
Go to the documentation of this file.
1 /*
2 * Copyright 2016 Autodesk, Inc. All rights reserved.
3 * Use of this software is subject to the terms of the Autodesk license agreement and any attachments or Appendices thereto provided at the time of installation or download,
4 * or which otherwise accompanies this software in either electronic or hard copy form, or which is signed by you and accepted by Autodesk.
5 */
6 
7 #pragma once
8 
16 
17 namespace Kaim
18 {
19 
20 class DisplayListManager;
21 class FileOpenerBase;
22 class IndexedMesh;
23 class HeightFieldBlob;
24 
25 typedef Vec2i HeightfieldTilePos;
27 
30 
31 struct HeightFieldConfig
32 {
33  HeightFieldConfig() : m_xAltitudeCount(0), m_yAltitudeCount(0), m_tileSize(0.f) {}
34 
35  KyUInt32 m_xAltitudeCount;
36  KyUInt32 m_yAltitudeCount;
37  KyFloat32 m_tileSize;
38  Vec2f m_origin;
39 };
40 
46 
47 class HeightField : public RefCountBase<HeightField, MemStat_CollisionData>
48 {
50 public:
51  HeightField() : m_blob(nullptr), m_altitudes(nullptr), m_tileSizeInv(1.f) {}
52  ~HeightField() { Clear(); }
53 
54  KyResult Initialize(const HeightFieldConfig& config);
55  KyResult InitFromBlob(HeightFieldBlob* blob);
56  KyResult InitFromBlobHandler(Ptr<BlobHandler<HeightFieldBlob> > handler);
57  void Clear();
58 
59  // RayCast on this heightfield. Returns RayHit if any triangles are intersected.
60  CollisionRayCastResult RayCast(const Vec3f& startPoint, const Vec3f& endPoint) const;
61 
62  KY_INLINE KyUInt32 GetXTileCount() const { return m_tileBox.CountX(); }
63  KY_INLINE KyUInt32 GetYTileCount() const { return m_tileBox.CountY(); }
64  KY_INLINE KyUInt32 GetTileCount() const { return GetXTileCount() * GetYTileCount(); }
65 
66  KY_INLINE KyUInt32 GetXAltitudeCount() const { return m_vertexBox.CountX(); }
67  KY_INLINE KyUInt32 GetYAltitudeCount() const { return m_vertexBox.CountY(); }
68  KY_INLINE KyUInt32 GetAltitudeCount() const { return GetXAltitudeCount() * GetYAltitudeCount(); }
69 
70  KY_INLINE KyFloat32 GetXExtents() const { return GetXTileCount() * m_blob->m_tileSize; }
71  KY_INLINE KyFloat32 GetYExtents() const { return GetYTileCount() * m_blob->m_tileSize; }
72 
73  KY_INLINE void SetAltitude(const HeightfieldVertexPos& pixelPos, KyFloat32 altitude)
74  {
75  m_altitudes[m_vertexBox.GetRowMajorIndex(pixelPos)] = altitude;
76  }
77 
78  KY_INLINE Vec3f GetVertex(const HeightfieldVertexPos& vertexPos) const
79  {
80  const KyFloat32 altitude = GetAltitude(vertexPos);
81  return m_blob->m_origin + Vec3f((KyFloat32)vertexPos.x * m_blob->m_tileSize, (KyFloat32)vertexPos.y * m_blob->m_tileSize, altitude);
82  }
83 
84  KY_INLINE KyResult GetTileAtPos(const Vec3f& pos, HeightFieldTile& tile) const
85  {
86  // Transform pos, snap it to grid.
87  const Vec3f localPos = pos - m_blob->m_origin;
88  const CellPos cellPos(SnapFloat(localPos.x), SnapFloat(localPos.y));
89  return GetTileAtPos(cellPos, tile);
90  }
91 
92  KY_INLINE KyResult GetTileAtPos(const HeightfieldTilePos& pixelPos, HeightFieldTile& tile) const
93  {
94  if (m_tileBox.DoesContain(pixelPos) == false)
95  return KY_ERROR;
96 
97  const KyFloat32 southEastX = ((KyFloat32)pixelPos.x * m_blob->m_tileSize) + m_blob->m_origin.x + m_blob->m_tileSize;
98  const KyFloat32 southEastY = ((KyFloat32)pixelPos.y * m_blob->m_tileSize) + m_blob->m_origin.y;
99 
100  tile.m_vertices[0].x = southEastX;
101  tile.m_vertices[0].y = southEastY;
102  tile.m_vertices[0].z = GetAltitude(pixelPos.NeighborEast());
103 
104  tile.m_vertices[1].x = southEastX;
105  tile.m_vertices[1].y = southEastY + m_blob->m_tileSize;
106  tile.m_vertices[1].z = GetAltitude(pixelPos.NeighborNorthEast());
107 
108  tile.m_vertices[2].x = southEastX - m_blob->m_tileSize;
109  tile.m_vertices[2].y = southEastY + m_blob->m_tileSize;
110  tile.m_vertices[2].z = GetAltitude(pixelPos.NeighborNorth());
111 
112  tile.m_vertices[3].x = southEastX - m_blob->m_tileSize;
113  tile.m_vertices[3].y = southEastY;
114  tile.m_vertices[3].z = GetAltitude(pixelPos);
115 
116  tile.m_cellPos = pixelPos;
117 
118  return KY_SUCCESS;
119  }
120 
121  Box2f GetAABB2D() const
122  {
123  return Box2f(m_blob->m_origin.Get2d(), m_blob->m_origin.Get2d() +
124  Vec2f(m_blob->m_xAltitudeCount * m_blob->m_tileSize, m_blob->m_yAltitudeCount * m_blob->m_tileSize));
125  }
126 
127  void VisualDebug(DisplayListManager* displayListManager);
128 
129  KyResult ConvertToIndexedMesh(IndexedMesh& mesh) const;
130 
131  KyResult WriteToObj(File* file) const;
132 
133  BlobHandler<HeightFieldBlob>* GetBlobHandler() { return m_blobHandler; }
134 
135 private:
136 
137  KY_INLINE KyFloat32 GetAltitude(const HeightfieldVertexPos& vertexPos) const
138  {
139  return m_altitudes[m_vertexBox.GetRowMajorIndex(vertexPos)];
140  }
141 
142  KyResult GetStartTile(const Vec3f& startPoint, const Vec3f& endPoint, HeightFieldTile& tile) const;
143  KyResult GetNextTile(const HeightFieldTile& tile, const Vec2f& rayA, const Vec2f& rayB, HeightFieldTile& outTile, const HeightFieldTile* destTile = nullptr) const;
144  CollisionRayCastResult RayVsTriangle(const Triangle3f& tri, const Vec3f& from, const Vec3f& to) const;
145 
146  KY_INLINE KyUInt32 SnapFloat(KyFloat32 inputValue) const
147  {
148  return KyUInt32(inputValue * m_tileSizeInv);
149  }
150 
151  KY_INLINE Vec3f Interpolate(const Vec3f& v0, const Vec3f& v1, KyFloat32 rt) const
152  {
153  const KyFloat32 s = 1.0f - rt;
154  return Vec3f(s * v0[0] + rt * v1[0],
155  s * v0[1] + rt * v1[1],
156  s * v0[2] + rt * v1[2]);
157  }
158 
159  void OnSetBlob();
160 
161  Ptr<BlobHandler<HeightFieldBlob> > m_blobHandler;
162  HeightFieldBlob* m_blob;
163  KyFloat32* m_altitudes; // Shortcut
164  KyFloat32 m_tileSizeInv;
165  HeightfieldTileBox m_tileBox;
166  HeightfieldVertexBox m_vertexBox;
167  Vec3f m_verts[4];
168 };
169 
170 }
171 
2d axis aligned box of 32bits floating points
Definition: box2f.h:15
Game side: Manages all DisplayListData, send them to the NavigationLab.
Definition: displaylist.h:375
2d axis aligned box of 32bits integers. Very Important: CountX() returns m_max.x - m_min...
Definition: box2i.h:17
std::uint32_t KyUInt32
uint32_t
Definition: types.h:29
Box2i HeightfieldTileBox
A type that represents a bounding box around the Tiles of the Heigtfield.
Definition: heightfield.h:26
3d triangle of 32bits floating points
Definition: triangle3f.h:15
Wraps a IndexedMeshBlob either as IndexedMeshBlob* or as Ptr< />> Also adds ...
Definition: indexedmesh.h:18
Box2i HeightfieldVertexBox
A type that represents a bounding box around the Vertices of the Heighfield.
Definition: heightfield.h:29
Vec2i HeightfieldVertexPos
A type that represents one of the vertices of a Tile within a 2D grid.
Definition: heightfield.h:28
#define KY_CLASS_WITHOUT_COPY(ClassName)
Define to forbid copy constructor and copy assignment.
Definition: types.h:196
Vec2i HeightfieldTilePos
A type that represents the position of a Tile within a 2D grid.
Definition: heightfield.h:23
KyInt32 GetRowMajorIndex(const Vec2i &pos) const
Compute index of position in box, where index is incremented in a outer-loop on Y and inner-loop on X...
Definition: box2i.h:101
2d vector using KyFloat32.
Definition: vec2f.h:18
Navigation return code class.
Definition: types.h:108
Heightfield with a uniform grid of sampled altitudes.
Definition: heightfield.h:47
2d vector using KyInt32
Definition: vec2i.h:18
CollisionRayCastResult
CollisionRayCastResult.
Definition: collisiontypes.h:15
The Autodesk Navigation namespace.
Definition: gamekitcrowddispersion.cpp:17
KyInt32 CountY() const
Return m_max.y - m_min.y + 1.
Definition: box2i.h:56
#define KY_ERROR
use result == KY_ERROR to test for error
Definition: types.h:132
KyInt32 CountX() const
Return m_max.x - m_min.x + 1.
Definition: box2i.h:55
float KyFloat32
float
Definition: types.h:32
3d vector using 32bits floating points.
Definition: vec3f.h:16