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 _GEOSPHERE_H 5 #define _GEOSPHERE_H 6 7 #include <SDL_stdinc.h> 8 9 #include "BaseSphere.h" 10 #include "Camera.h" 11 #include "vector3.h" 12 13 #include <deque> 14 15 namespace Graphics { 16 class Renderer; 17 class Texture; 18 } 19 20 class SystemBody; 21 class GeoPatch; 22 class GeoPatchContext; 23 class SQuadSplitRequest; 24 class SQuadSplitResult; 25 class SSingleSplitResult; 26 27 #define NUM_PATCHES 6 28 29 class GeoSphere : public BaseSphere { 30 public: 31 GeoSphere(const SystemBody *body); 32 virtual ~GeoSphere(); 33 34 virtual void Update() override; 35 virtual void Render(Graphics::Renderer *renderer, const matrix4x4d &modelView, vector3d campos, const float radius, const std::vector<Camera::Shadow> &shadows) override; 36 GetHeight(const vector3d & p)37 virtual double GetHeight(const vector3d &p) const override final 38 { 39 const double h = m_terrain->GetHeight(p); 40 #ifdef DEBUG 41 // XXX don't remove this. Fix your fractals instead 42 // Fractals absolutely MUST return heights >= 0.0 (one planet radius) 43 // otherwise atmosphere and other things break. 44 if (h < 0.0) { 45 Output("GetHeight({ %f, %f, %f }) returned %f\n", p.x, p.y, p.z, h); 46 m_terrain->DebugDump(); 47 assert(h >= 0.0); 48 } 49 #endif /* DEBUG */ 50 return h; 51 } 52 53 static void Init(); 54 static void Uninit(); 55 static void UpdateAllGeoSpheres(); 56 static void OnChangeDetailLevel(); 57 static bool OnAddQuadSplitResult(const SystemPath &path, SQuadSplitResult *res); 58 static bool OnAddSingleSplitResult(const SystemPath &path, SSingleSplitResult *res); 59 // in sbody radii GetMaxFeatureHeight()60 virtual double GetMaxFeatureHeight() const override final { return m_terrain->GetMaxHeight(); } 61 62 bool AddQuadSplitResult(SQuadSplitResult *res); 63 bool AddSingleSplitResult(SSingleSplitResult *res); 64 void ProcessSplitResults(); 65 66 virtual void Reset() override; 67 GetMaxDepth()68 inline Sint32 GetMaxDepth() const { return m_maxDepth; } 69 70 void AddQuadSplitRequest(double, SQuadSplitRequest *, GeoPatch *); 71 72 private: 73 void BuildFirstPatches(); 74 void CalculateMaxPatchDepth(); GetColor(const vector3d & p,double height,const vector3d & norm)75 inline vector3d GetColor(const vector3d &p, double height, const vector3d &norm) const 76 { 77 return m_terrain->GetColor(p, height, norm); 78 } 79 void ProcessQuadSplitRequests(); 80 81 std::unique_ptr<GeoPatch> m_patches[6]; 82 struct TDistanceRequest { TDistanceRequestTDistanceRequest83 TDistanceRequest(double dist, SQuadSplitRequest *pRequest, GeoPatch *pRequester) : 84 mDistance(dist), 85 mpRequest(pRequest), 86 mpRequester(pRequester) {} 87 double mDistance; 88 SQuadSplitRequest *mpRequest; 89 GeoPatch *mpRequester; 90 }; 91 std::deque<TDistanceRequest> mQuadSplitRequests; 92 93 static const uint32_t MAX_SPLIT_OPERATIONS = 128; 94 std::deque<SQuadSplitResult *> mQuadSplitResults; 95 std::deque<SSingleSplitResult *> mSingleSplitResults; 96 97 bool m_hasTempCampos; 98 vector3d m_tempCampos; 99 Graphics::Frustum m_tempFrustum; 100 101 static RefCountedPtr<GeoPatchContext> s_patchContext; 102 103 virtual void SetUpMaterials() override; 104 105 RefCountedPtr<Graphics::Texture> m_texHi; 106 RefCountedPtr<Graphics::Texture> m_texLo; 107 108 enum EGSInitialisationStage { 109 eBuildFirstPatches = 0, 110 eRequestedFirstPatches, 111 eReceivedFirstPatches, 112 eDefaultUpdateState 113 }; 114 EGSInitialisationStage m_initStage; 115 116 Sint32 m_maxDepth; 117 }; 118 119 #endif /* _GEOSPHERE_H */ 120