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 _target;
103  bool _isLerping = false;
104  float _lerpSpeed = 0.0f;
105  uint32 _lastUpdateTime = 0;
106 };
107 
108 // V2 is so similar that most can be reused from V1
109 class CameraV2 final : public CameraV1 {
110 public:
111  void update() override;
112  void setRoomBounds(Graphic &background) override;
113  void setFollow(WalkingCharacter *target) override;
114 };
115 
116 class CameraV3 final : public Camera {
117 public:
118  Math::Angle rotation() const override;
119  float scale() const override;
120 
121  void preUpdate() override;
122  void update() override;
123  void setRoomBounds(Graphic &background) override;
124  void setFollow(WalkingCharacter *target) override;
125  void setFollow(WalkingCharacter *target, bool catchup);
126  void onChangedRoom(bool resetCamera) override;
127  void onTriggeredDoor(WalkingCharacter *target) override;
128  void onTriggeredDoor(Common::Point fixedPosition) override;
129  void onScriptChangedCharacter(MainCharacterKind kind) override;
130  void onUserChangedCharacter() override;
131  void onOpenMenu() override;
132  void onCloseMenu() override;
133  void syncGame(Common::Serializer &s) override;
134 
135  Task *lerpPos(Process &process,
136  Math::Vector2d targetPos,
137  int32 duration, EasingType easingType);
138  Task *lerpPos(Process &process,
139  Math::Vector3d targetPos,
140  int32 duration, EasingType easingType);
141  Task *lerpPosZ(Process &process,
142  float targetPosZ,
143  int32 duration, EasingType easingType);
144  Task *lerpScale(Process &process,
145  float targetScale,
146  int32 duration, EasingType easingType);
147  Task *lerpRotation(Process &process,
148  float targetRotation,
149  int32 duration, EasingType easingType);
150  Task *lerpPosScale(Process &process,
151  Math::Vector3d targetPos, float targetScale,
152  int32 duration, EasingType moveEasingType, EasingType scaleEasingType);
153  Task *waitToStop(Process &process);
154  Task *shake(Process &process, Math::Vector2d amplitude, Math::Vector2d frequency, int32 duration);
155 
156 private:
157  friend struct CamLerpTask;
158  friend struct CamLerpPosTask;
159  friend struct CamLerpScaleTask;
160  friend struct CamLerpPosScaleTask;
161  friend struct CamLerpRotationTask;
162  friend struct CamShakeTask;
163  friend struct CamWaitToStopTask;
164  friend struct CamSetInactiveAttributeTask;
165 
166  void resetRotationAndScale();
167  void setPosition(Math::Vector2d v);
168  void setPosition(Math::Vector3d v);
169  void backup(uint slot);
170  void restore(uint slot);
171  void updateFollowing(float deltaTime);
172 
173  struct State {
174  Math::Vector3d _usedCenter = Math::Vector3d(512, 384, 0);
175  float
176  _scale = 1.0f,
177  _speed = 0.0f,
178  _maxSpeedFactor = 230.0f;
179  Math::Angle _rotation;
180  bool _isBraking = false;
181  bool _isFollowingTarget = false;
182 
183  void syncGame(Common::Serializer &s);
184  };
185 
186  static constexpr uint kStateBackupCount = 2;
187  State _cur, _backups[kStateBackupCount];
188  WalkingCharacter *_followTarget = nullptr;
189  uint32 _lastUpdateTime = 0;
190  bool _isChanging = false,
191  _catchUp = false;
192  Math::Vector2d _shake;
193 };
194 
195 }
196 
197 #endif // ALCACHOFA_CAMERA_H
Definition: objects.h:505
Definition: alcachofa.h:45
Definition: scheduler.h:84
Definition: scheduler.h:164
Definition: graphics.h:297
Definition: serializer.h:79
Definition: camera.h:109
Definition: camera.h:116
Definition: rect.h:144
Definition: camera.h:76
Definition: camera.h:38