utility.h: Change Buffer's interface to be more compatible with SharedBuffer's interf...
[oweals/minetest.git] / src / camera.h
1 /*
2 Minetest-c55
3 Copyright (C) 2010-2011 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 General Public License as published by
7 the Free Software Foundation; either version 2 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 General Public License for more details.
14
15 You should have received a copy of the GNU 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 #ifndef CAMERA_HEADER
21 #define CAMERA_HEADER
22
23 #include "common_irrlicht.h"
24 #include "inventory.h"
25 #include "tile.h"
26 #include "utility.h"
27 #include <ICameraSceneNode.h>
28 #include <IMeshCache.h>
29 #include <IAnimatedMesh.h>
30
31 class LocalPlayer;
32 class MapDrawControl;
33 class ExtrudedSpriteSceneNode;
34
35 /*
36         Client camera class, manages the player and camera scene nodes, the viewing distance
37         and performs view bobbing etc. It also displays the wielded tool in front of the
38         first-person camera.
39 */
40 class Camera
41 {
42 public:
43         Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control);
44         ~Camera();
45
46         // Get player scene node.
47         // This node is positioned at the player's torso (without any view bobbing),
48         // as given by Player::m_position. Yaw is applied but not pitch.
49         inline scene::ISceneNode* getPlayerNode() const
50         {
51                 return m_playernode;
52         }
53
54         // Get head scene node.
55         // It has the eye transformation and pitch applied,
56         // but no view bobbing.
57         inline scene::ISceneNode* getHeadNode() const
58         {
59                 return m_headnode;
60         }
61
62         // Get camera scene node.
63         // It has the eye transformation, pitch and view bobbing applied.
64         inline scene::ICameraSceneNode* getCameraNode() const
65         {
66                 return m_cameranode;
67         }
68
69         // Get the camera position (in absolute scene coordinates).
70         // This has view bobbing applied.
71         inline v3f getPosition() const
72         {
73                 return m_camera_position;
74         }
75
76         // Get the camera direction (in absolute camera coordinates).
77         // This has view bobbing applied.
78         inline v3f getDirection() const
79         {
80                 return m_camera_direction;
81         }
82
83         // Horizontal field of view
84         inline f32 getFovX() const
85         {
86                 return m_fov_x;
87         }
88
89         // Vertical field of view
90         inline f32 getFovY() const
91         {
92                 return m_fov_y;
93         }
94
95         // Get maximum of getFovX() and getFovY()
96         inline f32 getFovMax() const
97         {
98                 return MYMAX(m_fov_x, m_fov_y);
99         }
100
101         // Checks if the constructor was able to create the scene nodes
102         bool successfullyCreated(std::wstring& error_message);
103
104         // Step the camera: updates the viewing range and view bobbing.
105         void step(f32 dtime);
106
107         // Update the camera from the local player's position.
108         // frametime is used to adjust the viewing range.
109         void update(LocalPlayer* player, f32 frametime, v2u32 screensize);
110
111         // Render distance feedback loop
112         void updateViewingRange(f32 frametime_in);
113
114         // Update settings from g_settings
115         void updateSettings();
116
117         // Replace the wielded item mesh
118         void wield(const InventoryItem* item);
119
120         // Start digging animation
121         // Pass 0 for left click, 1 for right click
122         void setDigging(s32 button);
123
124         // Draw the wielded tool.
125         // This has to happen *after* the main scene is drawn.
126         // Warning: This clears the Z buffer.
127         void drawWieldedTool();
128
129 private:
130         // Scene manager and nodes
131         scene::ISceneManager* m_smgr;
132         scene::ISceneNode* m_playernode;
133         scene::ISceneNode* m_headnode;
134         scene::ICameraSceneNode* m_cameranode;
135
136         scene::ISceneManager* m_wieldmgr;
137         ExtrudedSpriteSceneNode* m_wieldnode;
138
139         // draw control
140         MapDrawControl& m_draw_control;
141
142         // viewing_range_min_nodes setting
143         f32 m_viewing_range_min;
144         // viewing_range_max_nodes setting
145         f32 m_viewing_range_max;
146
147         // Absolute camera position
148         v3f m_camera_position;
149         // Absolute camera direction
150         v3f m_camera_direction;
151
152         // Field of view and aspect ratio stuff
153         f32 m_aspect;
154         f32 m_fov_x;
155         f32 m_fov_y;
156
157         // Stuff for viewing range calculations
158         f32 m_wanted_frametime;
159         f32 m_added_frametime;
160         s16 m_added_frames;
161         f32 m_range_old;
162         f32 m_frametime_old;
163         f32 m_frametime_counter;
164         f32 m_time_per_range;
165
166         // View bobbing animation frame (0 <= m_view_bobbing_anim < 1)
167         f32 m_view_bobbing_anim;
168         // If 0, view bobbing is off (e.g. player is standing).
169         // If 1, view bobbing is on (player is walking).
170         // If 2, view bobbing is getting switched off.
171         s32 m_view_bobbing_state;
172         // Speed of view bobbing animation
173         f32 m_view_bobbing_speed;
174
175         // Digging animation frame (0 <= m_digging_anim < 1)
176         f32 m_digging_anim;
177         // If -1, no digging animation
178         // If 0, left-click digging animation
179         // If 1, right-click digging animation
180         s32 m_digging_button;
181 };
182
183
184 /*
185         A scene node that displays a 2D mesh extruded into the third dimension,
186         to add an illusion of depth.
187
188         Since this class was created to display the wielded tool of the local
189         player, and only tools and items are rendered like this (but not solid
190         content like stone and mud, which are shown as cubes), the option to
191         draw a textured cube instead is provided.
192  */
193 class ExtrudedSpriteSceneNode: public scene::ISceneNode
194 {
195 public:
196         ExtrudedSpriteSceneNode(
197                 scene::ISceneNode* parent,
198                 scene::ISceneManager* mgr,
199                 s32 id = -1,
200                 const v3f& position = v3f(0,0,0),
201                 const v3f& rotation = v3f(0,0,0),
202                 const v3f& scale = v3f(1,1,1));
203         ~ExtrudedSpriteSceneNode();
204
205         void setSprite(video::ITexture* texture);
206         void setCube(const TileSpec tiles[6]);
207
208         f32 getSpriteThickness() const { return m_thickness; }
209         void setSpriteThickness(f32 thickness);
210
211         void updateLight(u8 light);
212
213         void removeSpriteFromCache(video::ITexture* texture);
214
215         virtual const core::aabbox3d<f32>& getBoundingBox() const;
216         virtual void OnRegisterSceneNode();
217         virtual void render();
218
219 private:
220         scene::IMeshSceneNode* m_meshnode;
221         f32 m_thickness;
222         scene::IMesh* m_cubemesh;
223         bool m_is_cube;
224         u8 m_light;
225
226         // internal extrusion helper methods
227         io::path getExtrudedName(video::ITexture* texture);
228         scene::IAnimatedMesh* extrudeARGB(u32 width, u32 height, u8* data);
229         scene::IAnimatedMesh* extrude(video::ITexture* texture);
230         scene::IMesh* createCubeMesh();
231 };
232
233 #endif