1 // Copyright © 2008-2021 Pioneer Developers. See AUTHORS.txt for details 2 // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt 3 4 #ifndef _GEOPATCH_H 5 #define _GEOPATCH_H 6 7 #include <SDL_stdinc.h> 8 9 #include "Color.h" 10 #include "GeoPatchID.h" 11 #include "JobQueue.h" 12 #include "RefCounted.h" 13 #include "matrix4x4.h" 14 #include "vector3.h" 15 #include <deque> 16 #include <memory> 17 18 //#define DEBUG_BOUNDING_SPHERES 19 20 #ifdef DEBUG_BOUNDING_SPHERES 21 #include "graphics/Drawables.h" 22 namespace Graphics { 23 class RenderState; 24 } 25 #endif 26 27 namespace Graphics { 28 class Renderer; 29 class Frustum; 30 class VertexBuffer; 31 } 32 33 class GeoPatchContext; 34 class GeoSphere; 35 class BasePatchJob; 36 class SQuadSplitResult; 37 class SSingleSplitResult; 38 39 class GeoPatch { 40 public: 41 GeoPatch(const RefCountedPtr<GeoPatchContext> &_ctx, GeoSphere *gs, 42 const vector3d &v0_, const vector3d &v1_, const vector3d &v2_, const vector3d &v3_, 43 const int depth, const GeoPatchID &ID_); 44 45 ~GeoPatch(); 46 NeedToUpdateVBOs()47 inline void NeedToUpdateVBOs() 48 { 49 m_needUpdateVBOs = (nullptr != m_heights); 50 } 51 52 void UpdateVBOs(Graphics::Renderer *renderer); 53 GetChildIdx(const GeoPatch * child)54 int GetChildIdx(const GeoPatch *child) const 55 { 56 for (int i = 0; i < NUM_KIDS; i++) { 57 if (m_kids[i].get() == child) return i; 58 } 59 abort(); 60 return -1; 61 } 62 63 // in patch surface coords, [0,1] GetSpherePoint(const double x,const double y)64 inline vector3d GetSpherePoint(const double x, const double y) const 65 { 66 return (m_v0 + x * (1.0 - y) * (m_v1 - m_v0) + x * y * (m_v2 - m_v0) + (1.0 - x) * y * (m_v3 - m_v0)).Normalized(); 67 } 68 69 void Render(Graphics::Renderer *r, const vector3d &campos, const matrix4x4d &modelView, const Graphics::Frustum &frustum); 70 canBeMerged()71 inline bool canBeMerged() const 72 { 73 bool merge = true; 74 if (m_kids[0]) { 75 for (int i = 0; i < NUM_KIDS; i++) { 76 merge &= m_kids[i]->canBeMerged(); 77 } 78 } 79 merge &= !(m_HasJobRequest); 80 return merge; 81 } 82 83 void LODUpdate(const vector3d &campos, const Graphics::Frustum &frustum); 84 85 void RequestSinglePatch(); 86 void ReceiveHeightmaps(SQuadSplitResult *psr); 87 void ReceiveHeightmap(const SSingleSplitResult *psr); 88 void ReceiveJobHandle(Job::Handle job); 89 HasHeightData()90 inline bool HasHeightData() const { return (m_heights.get() != nullptr); } 91 private: 92 static const int NUM_KIDS = 4; 93 94 RefCountedPtr<GeoPatchContext> m_ctx; 95 const vector3d m_v0, m_v1, m_v2, m_v3; 96 std::unique_ptr<double[]> m_heights; 97 std::unique_ptr<vector3f[]> m_normals; 98 std::unique_ptr<Color3ub[]> m_colors; 99 std::unique_ptr<Graphics::VertexBuffer> m_vertexBuffer; 100 std::unique_ptr<GeoPatch> m_kids[NUM_KIDS]; 101 GeoPatch *m_parent; 102 GeoSphere *m_geosphere; 103 double m_roughLength; 104 vector3d m_clipCentroid, m_centroid; 105 double m_clipRadius; 106 Sint32 m_depth; 107 bool m_needUpdateVBOs; 108 109 const GeoPatchID m_PatchID; 110 Job::Handle m_job; 111 bool m_HasJobRequest; 112 #ifdef DEBUG_BOUNDING_SPHERES 113 std::unique_ptr<Graphics::Drawables::Sphere3D> m_boundsphere; 114 #endif 115 }; 116 117 #endif /* _GEOPATCH_H */ 118