Skip to content

Commit b150565

Browse files
committed
Engine: fix Camera rotation matrixes
1 parent 5c5b9cd commit b150565

8 files changed

Lines changed: 77 additions & 26 deletions

File tree

Common/util/geometry.h

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -138,31 +138,55 @@ struct PointT
138138
return Pt(X - p.X, Y - p.Y);
139139
}
140140

141-
inline Pt operator *(T mul) const
141+
inline Pt operator *(const Pt &p) const
142+
{
143+
return Pt(X * p.X, Y * p.Y);
144+
}
145+
146+
inline Pt operator /(const Pt &p) const
147+
{
148+
return Pt(X / p.X, Y / p.Y);
149+
}
150+
151+
inline Pt &operator *=(const Pt p)
152+
{
153+
X *= p.X;
154+
Y *= p.Y;
155+
return *this;
156+
}
157+
158+
inline Pt &operator /=(const Pt p)
159+
{
160+
X /= p.X;
161+
Y /= p.Y;
162+
return *this;
163+
}
164+
165+
inline Pt operator *(const T &mul) const
142166
{
143167
return Pt(X * mul, Y * mul);
144168
}
145169

146-
inline Pt operator /(T div) const
170+
inline Pt operator /(const T &div) const
147171
{
148172
return Pt(X / div, Y / div);
149173
}
150174

151-
inline Pt &operator *=(T mul)
175+
inline Pt &operator *=(const T &mul)
152176
{
153177
X *= mul;
154178
Y *= mul;
155179
return *this;
156180
}
157181

158-
inline Pt &operator /=(T div)
182+
inline Pt &operator /=(const T &div)
159183
{
160184
X /= div;
161185
Y /= div;
162186
return *this;
163187
}
164188

165-
inline bool Equals(const T x, const T y) const
189+
inline bool Equals(const T &x, const T &y) const
166190
{
167191
return X == x && Y == y;
168192
}

Engine/ac/draw.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2967,7 +2967,7 @@ static void construct_roomview_hw(const Viewport *viewport)
29672967
camera->GetRotation(), camera->GetEffectivePivot());
29682968

29692969
gfxDriver->BeginSpriteBatch(view_rc, view_trans, RENDER_BATCH_ROOM_LAYER);
2970-
gfxDriver->BeginSpriteBatch(Rect(), cam_trans);
2970+
gfxDriver->BeginSpriteBatch(Rect(), cam_trans, cam_rc.GetSize());
29712971
gfxDriver->SetStageScreen(cam_rc.GetSize(), cam_rc.Left, cam_rc.Top);
29722972
put_sprite_list_on_screen(true);
29732973
gfxDriver->EndSpriteBatch();

Engine/game/viewport.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,14 +259,19 @@ void Viewport::AdjustTransformation()
259259
float scale_x = (float)_position.GetWidth() / (float)cam_rc.GetWidth();
260260
float scale_y = (float)_position.GetHeight() / (float)cam_rc.GetHeight();
261261
float rotate = locked_cam->GetRotation();
262+
Pointf pivot = locked_cam->GetEffectivePivot();
262263

263264
glm::mat4 mat_v2c = glmex::make_transform2d(cam_rc.Left, cam_rc.Top,
264-
1.f / scale_x, 1.f / scale_y, -Math::DegreesToRadians(rotate), -0.5 * cam_rc.GetWidth(), -0.5 * cam_rc.GetHeight());
265+
1.f / scale_x, 1.f / scale_y, Math::DegreesToRadians(rotate),
266+
-cam_rc.GetWidth() * pivot.X, -cam_rc.GetHeight() * pivot.Y
267+
);
265268
_v2cTransform = glmex::translate(mat_v2c, -_position.Left, -_position.Top);
266269

267270
glm::mat4 mat_c2v = glmex::translate(_position.Left, _position.Top);
268271
_c2vTransform = glmex::inv_transform2d(mat_c2v, -cam_rc.Left, -cam_rc.Top,
269-
scale_x, scale_y, Math::DegreesToRadians(rotate), 0.5 * cam_rc.GetWidth(), 0.5 * cam_rc.GetHeight());;
272+
scale_x, scale_y, -Math::DegreesToRadians(rotate),
273+
cam_rc.GetWidth() * pivot.X, cam_rc.GetHeight() * pivot.Y
274+
);
270275
}
271276
}
272277

Engine/gfx/ali3dogl.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1939,13 +1939,13 @@ void OGLGraphicsDriver::InitSpriteBatch(size_t index, const SpriteBatchDesc &des
19391939
// Translate scaled node into Top-Left screen coordinates
19401940
float scaled_offx = _srcRect.GetWidth() * ((1.f - desc.Transform.ScaleX) * 0.5f);
19411941
float scaled_offy = _srcRect.GetHeight() * ((1.f - desc.Transform.ScaleY) * 0.5f);
1942-
float pivotx = _srcRect.GetWidth() / 2.f - (_srcRect.GetWidth() * desc.Transform.Pivot.X);
1943-
float pivoty = _srcRect.GetHeight() / 2.f - (_srcRect.GetHeight() * desc.Transform.Pivot.Y);
1942+
float pivotx = -_srcRect.GetWidth() * 0.5f + desc.SizeRef.Width * desc.Transform.ScaleX * desc.Transform.Pivot.X;
1943+
float pivoty = -_srcRect.GetHeight() * 0.5f + desc.SizeRef.Height * desc.Transform.ScaleY * desc.Transform.Pivot.Y;
19441944
model = glmex::translate(model, -scaled_offx, -(-scaled_offy));
1945-
// Classic Scale-Rotate-Translate, but inverse, because it's GLM
1946-
glm::mat4 msrt = glmex::make_transform2d((float)desc.Transform.X, (float)-desc.Transform.Y,
1945+
// Inverse transformation, because it should affect the textures drawn within this batch
1946+
glm::mat4 msrt = glmex::make_inv_transform2d((float)desc.Transform.X, (float)-desc.Transform.Y,
19471947
desc.Transform.ScaleX, desc.Transform.ScaleY,
1948-
-Math::DegreesToRadians(desc.Transform.Rotate), pivotx, -pivoty);
1948+
Math::DegreesToRadians(desc.Transform.Rotate), pivotx, -pivoty);
19491949
model = model * msrt;
19501950

19511951
// Also create separate viewport transformation matrix:
@@ -1954,7 +1954,7 @@ void OGLGraphicsDriver::InitSpriteBatch(size_t index, const SpriteBatchDesc &des
19541954
glm::mat4 mat_viewport = glmex::make_transform2d(
19551955
(float)desc.Transform.X, (float)desc.Transform.Y,
19561956
desc.Transform.ScaleX, desc.Transform.ScaleY, // CHECKME: rotation args here
1957-
-Math::DegreesToRadians(desc.Transform.Rotate), pivotx, -pivoty);
1957+
Math::DegreesToRadians(desc.Transform.Rotate), pivotx, -pivoty);
19581958
glm::mat4 vp_flip_off = glmex::translate(
19591959
_srcRect.GetWidth() * ((1.f - flip_sx) * 0.5f),
19601960
_srcRect.GetHeight() * ((1.f - flip_sy) * 0.5f));

Engine/gfx/gfxdriverbase.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,24 @@ bool GraphicsDriverBase::GetVsync() const
9191

9292
void GraphicsDriverBase::BeginSpriteBatch(const Rect &viewport, const SpriteTransform &transform, uint32_t filter_flags)
9393
{
94-
BeginSpriteBatch(SpriteBatchDesc(_actSpriteBatch, viewport, transform, kFlip_None, nullptr, filter_flags));
94+
BeginSpriteBatch(SpriteBatchDesc(_actSpriteBatch, viewport, transform, Size(), kFlip_None, nullptr, filter_flags));
95+
}
96+
97+
void GraphicsDriverBase::BeginSpriteBatch(const Rect &viewport, const SpriteTransform &transform, const Size &size_ref, uint32_t filter_flags)
98+
{
99+
BeginSpriteBatch(SpriteBatchDesc(_actSpriteBatch, viewport, transform, size_ref, kFlip_None, nullptr, filter_flags));
95100
}
96101

97102
void GraphicsDriverBase::BeginSpriteBatch(const Rect &viewport, const SpriteTransform &transform,
98103
GraphicFlip flip, PBitmap surface, uint32_t filter_flags)
99104
{
100-
BeginSpriteBatch(SpriteBatchDesc(_actSpriteBatch, viewport, transform, flip, surface, filter_flags));
105+
BeginSpriteBatch(SpriteBatchDesc(_actSpriteBatch, viewport, transform, Size(), flip, surface, filter_flags));
106+
}
107+
108+
void GraphicsDriverBase::BeginSpriteBatch(const Rect &viewport, const SpriteTransform &transform, const Size &size_ref,
109+
GraphicFlip flip, PBitmap surface, uint32_t filter_flags)
110+
{
111+
BeginSpriteBatch(SpriteBatchDesc(_actSpriteBatch, viewport, transform, size_ref, flip, surface, filter_flags));
101112
}
102113

103114
void GraphicsDriverBase::BeginSpriteBatch(IDriverDependantBitmap *render_target,

Engine/gfx/gfxdriverbase.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ struct SpriteBatchDesc
4747
SpriteTransform Transform;
4848
// Optional flip, applied to the whole batch as the last transform
4949
Common::GraphicFlip Flip = Common::kFlip_None;
50+
// Reference size, used mainly for deducing absolute rotation pivot
51+
Size SizeRef;
5052
// Optional bitmap to draw sprites upon. Used exclusively by the software rendering mode.
5153
// TODO: merge with the RenderTexture?
5254
PBitmap Surface;
@@ -58,11 +60,12 @@ struct SpriteBatchDesc
5860

5961
SpriteBatchDesc() = default;
6062
SpriteBatchDesc(uint32_t parent, const Rect viewport, const SpriteTransform &transform,
61-
Common::GraphicFlip flip = Common::kFlip_None, PBitmap surface = nullptr,
63+
Size size_ref = Size(), Common::GraphicFlip flip = Common::kFlip_None, PBitmap surface = nullptr,
6264
uint32_t filter_flags = 0)
6365
: Parent(parent)
6466
, Viewport(viewport)
6567
, Transform(transform)
68+
, SizeRef(size_ref)
6669
, Flip(flip)
6770
, Surface(surface)
6871
, FilterFlags(filter_flags)
@@ -75,6 +78,7 @@ struct SpriteBatchDesc
7578
: Parent(parent)
7679
, Viewport(viewport)
7780
, Transform(transform)
81+
, SizeRef(render_target ? Size(render_target->GetWidth(), render_target->GetHeight()) : Size())
7882
, Flip(flip)
7983
, RenderTarget(render_target)
8084
, FilterFlags(filter_flags)
@@ -145,15 +149,18 @@ class GraphicsDriverBase : public IGraphicsDriver
145149
//
146150
// Prepares next sprite batch, a list of sprites with defined viewport and optional
147151
// global model transformation.
148-
void BeginSpriteBatch(const Rect &viewport, const SpriteTransform &transform, uint32_t filter_flags = 0) override;
152+
void BeginSpriteBatch(const Rect &viewport, const SpriteTransform &transform, uint32_t filter_flags) override;
153+
void BeginSpriteBatch(const Rect &viewport, const SpriteTransform &transform, const Size &size_ref, uint32_t filter_flags) override;
149154
// Begins a sprite batch with defined viewport and a global model transformation
150155
// and a global flip setting. Optionally provides a surface which should be rendered
151156
// underneath the rest of the sprites.
152157
void BeginSpriteBatch(const Rect &viewport, const SpriteTransform &transform,
153-
Common::GraphicFlip flip, PBitmap surface = nullptr, uint32_t filter_flags = 0) override;
158+
Common::GraphicFlip flip, PBitmap surface, uint32_t filter_flags) override;
159+
void BeginSpriteBatch(const Rect &viewport, const SpriteTransform &transform, const Size &size_ref,
160+
Common::GraphicFlip flip, PBitmap surface, uint32_t filter_flags) override;
154161
// Begins a sprite batch which will be rendered on a target texture.
155162
void BeginSpriteBatch(IDriverDependantBitmap *render_target, const Rect &viewport, const SpriteTransform &transform,
156-
Common::GraphicFlip flip = Common::kFlip_None, uint32_t filter_flags = 0) override;
163+
Common::GraphicFlip flip, uint32_t filter_flags) override;
157164
// Ends current sprite batch
158165
void EndSpriteBatch() override;
159166
// Clears all sprite batches, resets batch counter

Engine/gfx/graphicsdriver.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,13 +329,16 @@ class IGraphicsDriver
329329
// Optionally you can assign "filter flags" to this batch; this lets to filter certain
330330
// batches out during some operations, such as fading effects or making screenshots.
331331
virtual void BeginSpriteBatch(const Rect &viewport, const SpriteTransform &transform, uint32_t filter_flags = 0) = 0;
332+
virtual void BeginSpriteBatch(const Rect &viewport, const SpriteTransform &transform, const Size &size_ref, uint32_t filter_flags = 0) = 0;
332333
// Begins a sprite batch with defined viewport and a global model transformation
333334
// and a global flip setting. Optionally provides a surface which should be rendered
334335
// underneath the rest of the sprites.
335336
// TODO: merge GraphicFlip with SpriteTransform.
336337
// TODO: can we merge PBitmap surface and render_target from overriden method?
337338
virtual void BeginSpriteBatch(const Rect &viewport, const SpriteTransform &transform,
338339
Common::GraphicFlip flip, PBitmap surface = nullptr, uint32_t filter_flags = 0) = 0;
340+
virtual void BeginSpriteBatch(const Rect &viewport, const SpriteTransform &transform, const Size &size_ref,
341+
Common::GraphicFlip flip, PBitmap surface = nullptr, uint32_t filter_flags = 0) = 0;
339342
// Begins a sprite batch which will be rendered on a target texture.
340343
// This batch will ignore any parent transforms, regardless whether it's nested
341344
// or not. Its common child batches will also be rendered on the same texture.

Engine/platform/windows/gfx/ali3dd3d.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1942,13 +1942,14 @@ size_t D3DGraphicsDriver::RenderSpriteBatch(const D3DSpriteBatch &batch, size_t
19421942
void D3DGraphicsDriver::InitSpriteBatch(size_t index, const SpriteBatchDesc &desc)
19431943
{
19441944
// Create transformation matrix for this batch
1945-
// Classic Scale-Rotate-Translate, but inverse, because it's GLM
1946-
float pivotx = _srcRect.GetWidth() / 2.f - _srcRect.GetWidth() * desc.Transform.Pivot.X;
1947-
float pivoty = _srcRect.GetHeight() / 2.f - _srcRect.GetHeight() * desc.Transform.Pivot.Y;
1948-
glm::mat4 msrt = glmex::make_transform2d(
1945+
float pivotx = -_srcRect.GetWidth() * 0.5f + desc.SizeRef.Width * desc.Transform.ScaleX * desc.Transform.Pivot.X;
1946+
float pivoty = -_srcRect.GetHeight() * 0.5f + desc.SizeRef.Height * desc.Transform.ScaleY * desc.Transform.Pivot.Y;
1947+
1948+
// Inverse transformation, because it should affect the textures drawn within this batch
1949+
glm::mat4 msrt = glmex::make_inv_transform2d(
19491950
(float)desc.Transform.X, (float)-desc.Transform.Y,
19501951
desc.Transform.ScaleX, desc.Transform.ScaleY,
1951-
-Math::DegreesToRadians(desc.Transform.Rotate), pivotx, -pivoty);
1952+
Math::DegreesToRadians(desc.Transform.Rotate), pivotx, -pivoty);
19521953
// Translate scaled node into Top-Left screen coordinates
19531954
float scaled_offx = _srcRect.GetWidth() * ((1.f - desc.Transform.ScaleX) * 0.5f);
19541955
float scaled_offy = _srcRect.GetHeight() * ((1.f - desc.Transform.ScaleY) * 0.5f);
@@ -1974,7 +1975,7 @@ void D3DGraphicsDriver::InitSpriteBatch(size_t index, const SpriteBatchDesc &des
19741975
glm::mat4 mat_viewport = glmex::make_transform2d(
19751976
(float)desc.Transform.X, (float)desc.Transform.Y,
19761977
desc.Transform.ScaleX, desc.Transform.ScaleY,
1977-
-Math::DegreesToRadians(desc.Transform.Rotate), pivotx, -pivoty);
1978+
Math::DegreesToRadians(desc.Transform.Rotate), pivotx, -pivoty);
19781979
glm::mat4 vp_flip_off = glmex::translate(
19791980
_srcRect.GetWidth() * ((1.f - flip_sx) * 0.5f),
19801981
_srcRect.GetHeight() * ((1.f - flip_sy) * 0.5f));

0 commit comments

Comments
 (0)