1 // This file belongs to the "MiniCore" game engine.
2 // Copyright (C) 2015 Jussi Lind <jussi.lind@iki.fi>
3 //
4 // This program is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License
6 // as published by the Free Software Foundation; either version 2
7 // of the License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 // MA  02110-1301, USA.
18 //
19 
20 #ifndef MCCAMERA_HH
21 #define MCCAMERA_HH
22 
23 #include "mcbbox.hh"
24 #include "mcmacros.hh"
25 
26 /*! \class MCCamera.
27  *  \brief Scene camera window.
28  *
29  * The Camera represents a visible window to the game scene.
30  * The Camera window is moved along a human player and it can
31  * translate global scene coordinates of objects into relative
32  * "camera coordinates". Those camera coordinates are used when
33  * rendering objects onto the screen to get the effect of a scrolling
34  * background.
35  */
36 class MCCamera
37 {
38 public:
39     //! Default constructor.
40     MCCamera();
41 
42     /*! \brief Constructor.
43      *  \param w Width of the window.
44      *  \param h Height of the window.
45      *  \param x Center x of the window.
46      *  \param y Center y of the window.
47      *  \param maxX Maximum allowed x for the window.
48      *  \param maxY Maximum allowed y for the window.
49      */
50     MCCamera(float w, float h, float x, float y, float maxX, float maxY);
51 
52     /*! \brief Re-init.
53      *  \param w Width of the window.
54      *  \param h Height of the window.
55      *  \param x Center x of the window.
56      *  \param y Center y of the window.
57      *  \param maxX Maximum allowed x for the window.
58      *  \param maxY Maximum allowed y for the window.
59      */
60     void init(float w, float h, float x, float y, float maxX, float maxY);
61 
62     /*! \brief Set Camera location in the scene.
63      *  \param x Center x of the window.
64      *  \param y Center y of the window.
65      */
66     void setPos(float x, float y);
67 
68     /*! \brief Set Camera location in the scene.
69      *  \param pos Center location of the window.
70      */
71     void setPos(const MCVector2dF & pos);
72 
73     const MCVector2dF & pos() const;
74 
75     float x() const;
76 
77     float y() const;
78 
79     //! Get bounding box
80     MCBBox<float> bbox() const;
81 
82     //! Get width
83     float width() const;
84 
85     //! Get height
86     float height() const;
87 
88     //! Translate given scene x-coordinate into Camera coordinate
mapXToCamera(float x) const89     float mapXToCamera(float x) const
90     {
91         return x - m_pos.i() + m_halfW;
92     }
93 
94     //! Translate given scene y-coordinate into Camera coordinate
mapYToCamera(float y) const95     float mapYToCamera(float y) const
96     {
97         return y - m_pos.j() + m_halfH;
98     }
99 
100     //! Translate given scene coordinates in-place into Camera coordinates
mapToCamera(float & x,float & y)101     void mapToCamera(float & x, float & y)
102     {
103         x = x - m_pos.i() + m_halfW;
104         y = y - m_pos.j() + m_halfH;
105     }
106 
107     //! Translate given Camera x-coordinate into scene coordinate
mapXToScene(float x) const108     float mapXToScene(float x) const
109     {
110         return x + m_pos.i() - m_halfW;
111     }
112 
113     //! Translate given Camera y-coordinate into scene coordinate
mapYToScene(float y) const114     float mapYToScene(float y) const
115     {
116         return y + m_pos.j() - m_halfH;
117     }
118 
119     //! Translate given Camera coordinates in-place into scene coordinates
mapToScene(float & x,float & y)120     void mapToScene(float & x, float & y)
121     {
122         x = x + m_pos.i() - m_halfW;
123         y = y + m_pos.j() - m_halfH;
124     }
125 
126     //! Test if given BBox is visible through the current
127     //! camera window
isVisible(const MCBBox<float> & r) const128     bool isVisible(const MCBBox<float> & r) const
129     {
130         const float w2 = r.width() / 2;
131         const float h2 = r.height() / 2;
132 
133         // Give some space to possible shadows, that's why we're adding w2 and h2.
134         return MCBBox<float>(
135                  m_pos.i() - m_halfW - w2,
136                  m_pos.j() - m_halfH - h2,
137                  m_pos.i() + m_halfW + w2,
138                  m_pos.j() + m_halfH + h2)
139           .intersects(r);
140     }
141 
142 private:
143     //! Disable copy constructor
144     DISABLE_COPY(MCCamera);
145 
146     //! Disable assignment
147     DISABLE_ASSI(MCCamera);
148 
149     //! Width and height of the camera window
150     float m_w, m_h;
151 
152     //! Width and height of the camera window divided by 2
153     float m_halfW, m_halfH;
154 
155     //! Coordinates of the center of the camera window
156     MCVector2dF m_pos;
157 
158     //! Maximum camera coordinates
159     float m_maxX, m_maxY;
160 };
161 
162 #endif // MCCAMERA_HH
163