ScummVM API documentation
camera.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef ALCACHOFA_CAMERA_H
23 #define ALCACHOFA_CAMERA_H
24 
25 #include "alcachofa/common.h"
26 #include "math/matrix4.h"
27 
28 namespace Alcachofa {
29 
30 class Graphic;
31 class WalkingCharacter;
32 class Process;
33 struct Task;
34 
35 static constexpr const int16_t kBaseScale = 300;
36 static constexpr const float kInvBaseScale = 1.0f / kBaseScale;
37 
38 class Camera {
39 public:
40  static Camera *create();
41  virtual ~Camera();
42  virtual Math::Angle rotation() const = 0;
43  virtual float scale() const = 0;
44 
45  virtual void preUpdate() = 0;
46  virtual void update() = 0;
47  virtual void setRoomBounds(Graphic &background) = 0;
48  virtual void setFollow(WalkingCharacter *target) = 0;
49  virtual void onChangedRoom(bool resetCamera) = 0;
50  virtual void onTriggeredDoor(WalkingCharacter *target) = 0;
51  virtual void onTriggeredDoor(Common::Point fixedPosition) = 0;
52  virtual void onScriptChangedCharacter(MainCharacterKind kind) = 0;
53  virtual void onUserChangedCharacter() = 0;
54  virtual void onOpenMenu() = 0;
55  virtual void onCloseMenu() = 0;
56  virtual void syncGame(Common::Serializer &s) = 0;
57 
58  Math::Vector3d transform2Dto3D(Math::Vector3d v) const;
59  Math::Vector3d transform3Dto2D(Math::Vector3d v) const;
60  Common::Point transform3Dto2D(Common::Point p) const;
61 
62 protected:
63  Math::Vector3d setAppliedCenter(Math::Vector3d center);
64  void setupMatricesAround(Math::Vector3d center);
65 
66  float _roomScale = 1.0f;
67  Math::Vector2d
68  _roomMin = Math::Vector2d(-10000, -10000),
69  _roomMax = Math::Vector2d(10000, 10000);
70  Math::Vector3d _appliedCenter;
71  Math::Matrix4
72  _mat3Dto2D,
73  _mat2Dto3D;
74 };
75 
76 class CameraV1 : public Camera {
77 public:
78  Math::Angle rotation() const override;
79  float scale() const override;
80 
81  void preUpdate() override;
82  void update() override;
83  void setRoomBounds(Graphic &background) override;
84  void setFollow(WalkingCharacter *target) override;
85  void onChangedRoom(bool resetCamera) override;
86  void onTriggeredDoor(WalkingCharacter *target) override;
87  void onTriggeredDoor(Common::Point fixedPosition) override;
88  void onScriptChangedCharacter(MainCharacterKind kind) override;
89  void onUserChangedCharacter() override;
90  void onOpenMenu() override;
91  void onCloseMenu() override;
92  void syncGame(Common::Serializer &s) override;
93  void lerpOrSet(Common::Point target, int32 mode);
94 
95  Task *disguise(Process &process, int32 duration);
96 
97 protected:
98  friend struct CamV1DisguiseTask;
99  void updateLerping(Math::Vector3d &newCenter, float deltaTime, float speed);
100 
101  WalkingCharacter *_followTarget = nullptr;
102  Math::Vector3d
103  _usedCenter, // in V2 the used center is not clipped (that would _appliedCenter)
104  // in menus this variable stays in room space and is clipped to the one valid menu pos
105  // as such it acts like the state backup in CameraV3
106  _target;
107  bool _isLerping = false;
108  float _lerpSpeed = 0.0f;
109  uint32 _lastUpdateTime = 0;
110 };
111 
112 // V2 is so similar that most can be reused from V1
113 class CameraV2 final : public CameraV1 {
114 public:
115  void update() override;
116  void setRoomBounds(Graphic &background) override;
117  void setFollow(WalkingCharacter *target) override;
118 };
119 
120 class CameraV3 final : public Camera {
121 public:
122  Math::Angle rotation() const override;
123  float scale() const override;
124 
125  void preUpdate() override;
126  void update() override;
127  void setRoomBounds(Graphic &background) override;
128  void setFollow(WalkingCharacter *target) override;
129  void setFollow(WalkingCharacter *target, bool catchup);
130  void onChangedRoom(bool resetCamera) override;
131  void onTriggeredDoor(WalkingCharacter *target) override;
132  void onTriggeredDoor(Common::Point fixedPosition) override;
133  void onScriptChangedCharacter(MainCharacterKind kind) override;
134  void onUserChangedCharacter() override;
135  void onOpenMenu() override;
136  void onCloseMenu() override;
137  void syncGame(Common::Serializer &s) override;
138 
139  Task *lerpPos(Process &process,
140  Math::Vector2d targetPos,
141  int32 duration, EasingType easingType);
142  Task *lerpPos(Process &process,
143  Math::Vector3d targetPos,
144  int32 duration, EasingType easingType);
145  Task *lerpPosZ(Process &process,
146  float targetPosZ,
147  int32 duration, EasingType easingType);
148  Task *lerpScale(Process &process,
149  float targetScale,
150  int32 duration, EasingType easingType);
151  Task *lerpRotation(Process &process,
152  float targetRotation,
153  int32 duration, EasingType easingType);
154  Task *lerpPosScale(Process &process,
155  Math::Vector3d targetPos, float targetScale,
156  int32 duration, EasingType moveEasingType, EasingType scaleEasingType);
157  Task *waitToStop(Process &process);
158  Task *shake(Process &process, Math::Vector2d amplitude, Math::Vector2d frequency, int32 duration);
159 
160 private:
161  friend struct CamLerpTask;
162  friend struct CamLerpPosTask;
163  friend struct CamLerpScaleTask;
164  friend struct CamLerpPosScaleTask;
165  friend struct CamLerpRotationTask;
166  friend struct CamShakeTask;
167  friend struct CamWaitToStopTask;
168  friend struct CamSetInactiveAttributeTask;
169 
170  void resetRotationAndScale();
171  void setPosition(Math::Vector2d v);
172  void setPosition(Math::Vector3d v);
173  void backup(uint slot);
174  void restore(uint slot);
175  void updateFollowing(float deltaTime);
176 
177  struct State {
178  Math::Vector3d _usedCenter = Math::Vector3d(512, 384, 0);
179  float
180  _scale = 1.0f,
181  _speed = 0.0f,
182  _maxSpeedFactor = 230.0f;
183  Math::Angle _rotation;
184  bool _isBraking = false;
185  bool _isFollowingTarget = false;
186 
187  void syncGame(Common::Serializer &s);
188  };
189 
190  static constexpr uint kStateBackupCount = 2;
191  State _cur, _backups[kStateBackupCount];
192  WalkingCharacter *_followTarget = nullptr;
193  uint32 _lastUpdateTime = 0;
194  bool _isChanging = false,
195  _catchUp = false;
196  Math::Vector2d _shake;
197 };
198 
199 }
200 
201 #endif // ALCACHOFA_CAMERA_H
Definition: objects.h:534
Definition: alcachofa.h:45
Definition: scheduler.h:84
Definition: scheduler.h:164
Definition: graphics.h:297
Definition: serializer.h:80
Definition: camera.h:113
Definition: camera.h:120
Definition: rect.h:144
Definition: camera.h:76
Definition: camera.h:38