]> git.lizzy.rs Git - dragonfireclient.git/blob - src/client/clientmap.h
Properly keep noclip state in Game and ClientMap
[dragonfireclient.git] / src / client / clientmap.h
1 /*
2 Minetest
3 Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #pragma once
21
22 #include "irrlichttypes_extrabloated.h"
23 #include "map.h"
24 #include "camera.h"
25 #include <set>
26 #include <map>
27
28 struct MapDrawControl
29 {
30         // Wanted drawing range
31         float wanted_range = 0.0f;
32         // Overrides limits by drawing everything
33         bool range_all = false;
34         // Allow rendering out of bounds
35         bool allow_noclip = false;
36         // show a wire frame for debugging
37         bool show_wireframe = false;
38 };
39
40 struct MeshBufList
41 {
42         video::SMaterial m;
43         std::vector<std::pair<v3s16,scene::IMeshBuffer*>> bufs;
44 };
45
46 struct MeshBufListList
47 {
48         /*!
49          * Stores the mesh buffers of the world.
50          * The array index is the material's layer.
51          * The vector part groups vertices by material.
52          */
53         std::vector<MeshBufList> lists[MAX_TILE_LAYERS];
54
55         void clear();
56         void add(scene::IMeshBuffer *buf, v3s16 position, u8 layer);
57 };
58
59 class Client;
60 class ITextureSource;
61 class PartialMeshBuffer;
62
63 /*
64         ClientMap
65
66         This is the only map class that is able to render itself on screen.
67 */
68
69 class ClientMap : public Map, public scene::ISceneNode
70 {
71 public:
72         ClientMap(
73                         Client *client,
74                         RenderingEngine *rendering_engine,
75                         MapDrawControl &control,
76                         s32 id
77         );
78
79         virtual ~ClientMap() = default;
80
81         bool maySaveBlocks() override
82         {
83                 return false;
84         }
85
86         void drop() override
87         {
88                 ISceneNode::drop(); // calls destructor
89         }
90
91         void updateCamera(v3f pos, v3f dir, f32 fov, v3s16 offset);
92
93         /*
94                 Forcefully get a sector from somewhere
95         */
96         MapSector * emergeSector(v2s16 p) override;
97
98         /*
99                 ISceneNode methods
100         */
101
102         virtual void OnRegisterSceneNode() override;
103
104         virtual void render() override
105         {
106                 video::IVideoDriver* driver = SceneManager->getVideoDriver();
107                 driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
108                 renderMap(driver, SceneManager->getSceneNodeRenderPass());
109         }
110
111         virtual const aabb3f &getBoundingBox() const override
112         {
113                 return m_box;
114         }
115
116         void getBlocksInViewRange(v3s16 cam_pos_nodes,
117                 v3s16 *p_blocks_min, v3s16 *p_blocks_max, float range=-1.0f);
118         void updateDrawList();
119         void updateDrawListShadow(v3f shadow_light_pos, v3f shadow_light_dir, float radius, float length);
120         // Returns true if draw list needs updating before drawing the next frame.
121         bool needsUpdateDrawList() { return m_needs_update_drawlist; }
122         void renderMap(video::IVideoDriver* driver, s32 pass);
123
124         void renderMapShadows(video::IVideoDriver *driver,
125                         const video::SMaterial &material, s32 pass, int frame, int total_frames);
126
127         int getBackgroundBrightness(float max_d, u32 daylight_factor,
128                         int oldvalue, bool *sunlight_seen_result);
129
130         void renderPostFx(CameraMode cam_mode);
131
132         // For debug printing
133         void PrintInfo(std::ostream &out) override;
134
135         const MapDrawControl & getControl() const { return m_control; }
136         f32 getWantedRange() const { return m_control.wanted_range; }
137         f32 getCameraFov() const { return m_camera_fov; }
138
139 private:
140
141         // update the vertex order in transparent mesh buffers
142         void updateTransparentMeshBuffers();
143
144         // Orders blocks by distance to the camera
145         class MapBlockComparer
146         {
147         public:
148                 MapBlockComparer(const v3s16 &camera_block) : m_camera_block(camera_block) {}
149
150                 bool operator() (const v3s16 &left, const v3s16 &right) const
151                 {
152                         auto distance_left = left.getDistanceFromSQ(m_camera_block);
153                         auto distance_right = right.getDistanceFromSQ(m_camera_block);
154                         return distance_left > distance_right || (distance_left == distance_right && left > right);
155                 }
156
157         private:
158                 v3s16 m_camera_block;
159         };
160
161
162         // reference to a mesh buffer used when rendering the map.
163         struct DrawDescriptor {
164                 v3s16 m_pos;
165                 union {
166                         scene::IMeshBuffer *m_buffer;
167                         const PartialMeshBuffer *m_partial_buffer;
168                 };
169                 bool m_reuse_material:1;
170                 bool m_use_partial_buffer:1;
171
172                 DrawDescriptor(v3s16 pos, scene::IMeshBuffer *buffer, bool reuse_material) :
173                         m_pos(pos), m_buffer(buffer), m_reuse_material(reuse_material), m_use_partial_buffer(false)
174                 {}
175
176                 DrawDescriptor(v3s16 pos, const PartialMeshBuffer *buffer) :
177                         m_pos(pos), m_partial_buffer(buffer), m_reuse_material(false), m_use_partial_buffer(true)
178                 {}
179
180                 scene::IMeshBuffer* getBuffer();
181                 void draw(video::IVideoDriver* driver);
182         };
183
184         Client *m_client;
185         RenderingEngine *m_rendering_engine;
186
187         aabb3f m_box = aabb3f(-BS * 1000000, -BS * 1000000, -BS * 1000000,
188                 BS * 1000000, BS * 1000000, BS * 1000000);
189
190         MapDrawControl &m_control;
191
192         v3f m_camera_position = v3f(0,0,0);
193         v3f m_camera_direction = v3f(0,0,1);
194         f32 m_camera_fov = M_PI;
195         v3s16 m_camera_offset;
196         bool m_needs_update_transparent_meshes = true;
197
198         std::map<v3s16, MapBlock*, MapBlockComparer> m_drawlist;
199         std::map<v3s16, MapBlock*> m_drawlist_shadow;
200         bool m_needs_update_drawlist;
201
202         std::set<v2s16> m_last_drawn_sectors;
203
204         bool m_cache_trilinear_filter;
205         bool m_cache_bilinear_filter;
206         bool m_cache_anistropic_filter;
207         bool m_added_to_shadow_renderer{false};
208         u16 m_cache_transparency_sorting_distance;
209 };