parent
9ba885222f
commit
a72d296c14
@ -1,313 +1,313 @@ |
|||||||
/*
|
/*
|
||||||
olcPGEX_Graphics2D.h |
olcPGEX_Graphics2D.h |
||||||
|
|
||||||
+-------------------------------------------------------------+ |
+-------------------------------------------------------------+ |
||||||
| OneLoneCoder Pixel Game Engine Extension | |
| OneLoneCoder Pixel Game Engine Extension | |
||||||
| Advanced 2D Rendering - v0.4 | |
| Advanced 2D Rendering - v0.5 | |
||||||
+-------------------------------------------------------------+ |
+-------------------------------------------------------------+ |
||||||
|
|
||||||
What is this? |
What is this? |
||||||
~~~~~~~~~~~~~ |
~~~~~~~~~~~~~ |
||||||
This is an extension to the olcPixelGameEngine, which provides |
This is an extension to the olcPixelGameEngine, which provides |
||||||
advanced olc::Sprite manipulation and drawing routines. To use |
advanced olc::Sprite manipulation and drawing routines. To use |
||||||
it, simply include this header file. |
it, simply include this header file. |
||||||
|
|
||||||
License (OLC-3) |
License (OLC-3) |
||||||
~~~~~~~~~~~~~~~ |
~~~~~~~~~~~~~~~ |
||||||
|
|
||||||
Copyright 2018 - 2019 OneLoneCoder.com |
Copyright 2018 - 2019 OneLoneCoder.com |
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without |
Redistribution and use in source and binary forms, with or without |
||||||
modification, are permitted provided that the following conditions |
modification, are permitted provided that the following conditions |
||||||
are met: |
are met: |
||||||
|
|
||||||
1. Redistributions or derivations of source code must retain the above |
1. Redistributions or derivations of source code must retain the above |
||||||
copyright notice, this list of conditions and the following disclaimer. |
copyright notice, this list of conditions and the following disclaimer. |
||||||
|
|
||||||
2. Redistributions or derivative works in binary form must reproduce |
2. Redistributions or derivative works in binary form must reproduce |
||||||
the above copyright notice. This list of conditions and the following |
the above copyright notice. This list of conditions and the following |
||||||
disclaimer must be reproduced in the documentation and/or other |
disclaimer must be reproduced in the documentation and/or other |
||||||
materials provided with the distribution. |
materials provided with the distribution. |
||||||
|
|
||||||
3. Neither the name of the copyright holder nor the names of its |
3. Neither the name of the copyright holder nor the names of its |
||||||
contributors may be used to endorse or promote products derived |
contributors may be used to endorse or promote products derived |
||||||
from this software without specific prior written permission. |
from this software without specific prior written permission. |
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
|
||||||
Links |
Links |
||||||
~~~~~ |
~~~~~ |
||||||
YouTube: https://www.youtube.com/javidx9
|
YouTube: https://www.youtube.com/javidx9
|
||||||
Discord: https://discord.gg/WhwHUMV
|
Discord: https://discord.gg/WhwHUMV
|
||||||
Twitter: https://www.twitter.com/javidx9
|
Twitter: https://www.twitter.com/javidx9
|
||||||
Twitch: https://www.twitch.tv/javidx9
|
Twitch: https://www.twitch.tv/javidx9
|
||||||
GitHub: https://www.github.com/onelonecoder
|
GitHub: https://www.github.com/onelonecoder
|
||||||
Homepage: https://www.onelonecoder.com
|
Homepage: https://www.onelonecoder.com
|
||||||
|
|
||||||
Author |
Author |
||||||
~~~~~~ |
~~~~~~ |
||||||
David Barr, aka javidx9, ©OneLoneCoder 2019 |
David Barr, aka javidx9, ©OneLoneCoder 2019 |
||||||
*/ |
*/ |
||||||
|
|
||||||
/*
|
/*
|
||||||
Matrices stored as [Column][Row] (i.e. x, y) |
Matrices stored as [Column][Row] (i.e. x, y) |
||||||
|
|
||||||
|C0R0 C1R0 C2R0| | x | | x'| |
|C0R0 C1R0 C2R0| | x | | x'| |
||||||
|C0R1 C1R1 C2R1| * | y | = | y'| |
|C0R1 C1R1 C2R1| * | y | = | y'| |
||||||
|C0R2 C1R2 C2R2| |1.0| | - | |
|C0R2 C1R2 C2R2| |1.0| | - | |
||||||
*/ |
*/ |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef OLC_PGEX_GFX2D |
#ifndef OLC_PGEX_GFX2D |
||||||
#define OLC_PGEX_GFX2D |
#define OLC_PGEX_GFX2D |
||||||
|
|
||||||
#include <algorithm> |
#include <algorithm> |
||||||
#undef min |
#undef min |
||||||
#undef max |
#undef max |
||||||
|
|
||||||
namespace olc |
namespace olc |
||||||
{ |
{ |
||||||
// Container class for Advanced 2D Drawing functions
|
// Container class for Advanced 2D Drawing functions
|
||||||
class GFX2D : public olc::PGEX |
class GFX2D : public olc::PGEX |
||||||
{ |
{ |
||||||
// A representation of an affine transform, used to rotate, scale, offset & shear space
|
// A representation of an affine transform, used to rotate, scale, offset & shear space
|
||||||
public: |
public: |
||||||
class Transform2D |
class Transform2D |
||||||
{ |
{ |
||||||
public: |
public: |
||||||
inline Transform2D(); |
Transform2D(); |
||||||
|
|
||||||
public: |
public: |
||||||
// Set this transformation to unity
|
// Set this transformation to unity
|
||||||
inline void Reset(); |
void Reset(); |
||||||
// Append a rotation of fTheta radians to this transform
|
// Append a rotation of fTheta radians to this transform
|
||||||
inline void Rotate(float fTheta); |
void Rotate(float fTheta); |
||||||
// Append a translation (ox, oy) to this transform
|
// Append a translation (ox, oy) to this transform
|
||||||
inline void Translate(float ox, float oy); |
void Translate(float ox, float oy); |
||||||
// Append a scaling operation (sx, sy) to this transform
|
// Append a scaling operation (sx, sy) to this transform
|
||||||
inline void Scale(float sx, float sy); |
void Scale(float sx, float sy); |
||||||
// Append a shear operation (sx, sy) to this transform
|
// Append a shear operation (sx, sy) to this transform
|
||||||
inline void Shear(float sx, float sy); |
void Shear(float sx, float sy); |
||||||
|
|
||||||
inline void Perspective(float ox, float oy); |
void Perspective(float ox, float oy); |
||||||
// Calculate the Forward Transformation of the coordinate (in_x, in_y) -> (out_x, out_y)
|
// Calculate the Forward Transformation of the coordinate (in_x, in_y) -> (out_x, out_y)
|
||||||
inline void Forward(float in_x, float in_y, float &out_x, float &out_y); |
void Forward(float in_x, float in_y, float &out_x, float &out_y); |
||||||
// Calculate the Inverse Transformation of the coordinate (in_x, in_y) -> (out_x, out_y)
|
// Calculate the Inverse Transformation of the coordinate (in_x, in_y) -> (out_x, out_y)
|
||||||
inline void Backward(float in_x, float in_y, float &out_x, float &out_y); |
void Backward(float in_x, float in_y, float &out_x, float &out_y); |
||||||
// Regenerate the Inverse Transformation
|
// Regenerate the Inverse Transformation
|
||||||
inline void Invert(); |
void Invert(); |
||||||
|
|
||||||
private: |
private: |
||||||
inline void Multiply(); |
void Multiply(); |
||||||
float matrix[4][3][3]; |
float matrix[4][3][3]; |
||||||
int nTargetMatrix; |
int nTargetMatrix; |
||||||
int nSourceMatrix; |
int nSourceMatrix; |
||||||
bool bDirty; |
bool bDirty; |
||||||
}; |
}; |
||||||
|
|
||||||
public: |
public: |
||||||
// Draws a sprite with the transform applied
|
// Draws a sprite with the transform applied
|
||||||
inline static void DrawSprite(olc::Sprite *sprite, olc::GFX2D::Transform2D &transform); |
static void DrawSprite(olc::Sprite *sprite, olc::GFX2D::Transform2D &transform); |
||||||
}; |
}; |
||||||
} |
} |
||||||
|
|
||||||
|
|
||||||
#ifdef OLC_PGE_GRAPHICS2D |
#ifdef OLC_PGEX_GRAPHICS2D |
||||||
#undef OLC_PGE_GRAPHICS2D |
#undef OLC_PGEX_GRAPHICS2D |
||||||
|
|
||||||
namespace olc |
namespace olc |
||||||
{ |
{ |
||||||
void GFX2D::DrawSprite(olc::Sprite *sprite, olc::GFX2D::Transform2D &transform) |
void GFX2D::DrawSprite(olc::Sprite *sprite, olc::GFX2D::Transform2D &transform) |
||||||
{ |
{ |
||||||
if (sprite == nullptr) |
if (sprite == nullptr) |
||||||
return; |
return; |
||||||
|
|
||||||
// Work out bounding rectangle of sprite
|
// Work out bounding rectangle of sprite
|
||||||
float ex, ey; |
float ex, ey; |
||||||
float sx, sy;
|
float sx, sy;
|
||||||
float px, py; |
float px, py; |
||||||
|
|
||||||
transform.Forward(0.0f, 0.0f, sx, sy); |
transform.Forward(0.0f, 0.0f, sx, sy); |
||||||
px = sx; py = sy; |
px = sx; py = sy; |
||||||
sx = std::min(sx, px); sy = std::min(sy, py); |
sx = std::min(sx, px); sy = std::min(sy, py); |
||||||
ex = std::max(ex, px); ey = std::max(ey, py); |
ex = std::max(ex, px); ey = std::max(ey, py); |
||||||
|
|
||||||
transform.Forward((float)sprite->width, (float)sprite->height, px, py); |
transform.Forward((float)sprite->width, (float)sprite->height, px, py); |
||||||
sx = std::min(sx, px); sy = std::min(sy, py); |
sx = std::min(sx, px); sy = std::min(sy, py); |
||||||
ex = std::max(ex, px); ey = std::max(ey, py); |
ex = std::max(ex, px); ey = std::max(ey, py); |
||||||
|
|
||||||
transform.Forward(0.0f, (float)sprite->height, px, py); |
transform.Forward(0.0f, (float)sprite->height, px, py); |
||||||
sx = std::min(sx, px); sy = std::min(sy, py); |
sx = std::min(sx, px); sy = std::min(sy, py); |
||||||
ex = std::max(ex, px); ey = std::max(ey, py); |
ex = std::max(ex, px); ey = std::max(ey, py); |
||||||
|
|
||||||
transform.Forward((float)sprite->width, 0.0f, px, py); |
transform.Forward((float)sprite->width, 0.0f, px, py); |
||||||
sx = std::min(sx, px); sy = std::min(sy, py); |
sx = std::min(sx, px); sy = std::min(sy, py); |
||||||
ex = std::max(ex, px); ey = std::max(ey, py); |
ex = std::max(ex, px); ey = std::max(ey, py); |
||||||
|
|
||||||
// Perform inversion of transform if required
|
// Perform inversion of transform if required
|
||||||
transform.Invert(); |
transform.Invert(); |
||||||
|
|
||||||
if (ex < sx)
|
if (ex < sx)
|
||||||
std::swap(ex, sx); |
std::swap(ex, sx); |
||||||
if (ey < sy)
|
if (ey < sy)
|
||||||
std::swap(ey, sy); |
std::swap(ey, sy); |
||||||
|
|
||||||
// Iterate through render space, and sample Sprite from suitable texel location
|
// Iterate through render space, and sample Sprite from suitable texel location
|
||||||
for (float i = sx; i < ex; i++) |
for (float i = sx; i < ex; i++) |
||||||
{ |
{ |
||||||
for (float j = sy; j < ey; j++) |
for (float j = sy; j < ey; j++) |
||||||
{ |
{ |
||||||
float ox, oy; |
float ox, oy; |
||||||
transform.Backward(i, j, ox, oy); |
transform.Backward(i, j, ox, oy); |
||||||
pge->Draw((int32_t)i, (int32_t)j, sprite->GetPixel((int32_t)(ox+0.5f), (int32_t)(oy+0.5f))); |
pge->Draw((int32_t)i, (int32_t)j, sprite->GetPixel((int32_t)(ox+0.5f), (int32_t)(oy+0.5f))); |
||||||
} |
} |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
olc::GFX2D::Transform2D::Transform2D() |
olc::GFX2D::Transform2D::Transform2D() |
||||||
{ |
{ |
||||||
Reset(); |
Reset(); |
||||||
} |
} |
||||||
|
|
||||||
void olc::GFX2D::Transform2D::Reset() |
void olc::GFX2D::Transform2D::Reset() |
||||||
{ |
{ |
||||||
nTargetMatrix = 0; |
nTargetMatrix = 0; |
||||||
nSourceMatrix = 1; |
nSourceMatrix = 1; |
||||||
bDirty = true; |
bDirty = true; |
||||||
|
|
||||||
// Columns Then Rows
|
// Columns Then Rows
|
||||||
|
|
||||||
// Matrices 0 & 1 are used as swaps in Transform accumulation
|
// Matrices 0 & 1 are used as swaps in Transform accumulation
|
||||||
matrix[0][0][0] = 1.0f; matrix[0][1][0] = 0.0f; matrix[0][2][0] = 0.0f; |
matrix[0][0][0] = 1.0f; matrix[0][1][0] = 0.0f; matrix[0][2][0] = 0.0f; |
||||||
matrix[0][0][1] = 0.0f; matrix[0][1][1] = 1.0f; matrix[0][2][1] = 0.0f; |
matrix[0][0][1] = 0.0f; matrix[0][1][1] = 1.0f; matrix[0][2][1] = 0.0f; |
||||||
matrix[0][0][2] = 0.0f; matrix[0][1][2] = 0.0f; matrix[0][2][2] = 1.0f; |
matrix[0][0][2] = 0.0f; matrix[0][1][2] = 0.0f; matrix[0][2][2] = 1.0f; |
||||||
|
|
||||||
matrix[1][0][0] = 1.0f; matrix[1][1][0] = 0.0f; matrix[1][2][0] = 0.0f; |
matrix[1][0][0] = 1.0f; matrix[1][1][0] = 0.0f; matrix[1][2][0] = 0.0f; |
||||||
matrix[1][0][1] = 0.0f; matrix[1][1][1] = 1.0f; matrix[1][2][1] = 0.0f; |
matrix[1][0][1] = 0.0f; matrix[1][1][1] = 1.0f; matrix[1][2][1] = 0.0f; |
||||||
matrix[1][0][2] = 0.0f; matrix[1][1][2] = 0.0f; matrix[1][2][2] = 1.0f; |
matrix[1][0][2] = 0.0f; matrix[1][1][2] = 0.0f; matrix[1][2][2] = 1.0f; |
||||||
|
|
||||||
// Matrix 2 is a cache matrix to hold the immediate transform operation
|
// Matrix 2 is a cache matrix to hold the immediate transform operation
|
||||||
// Matrix 3 is a cache matrix to hold the inverted transform
|
// Matrix 3 is a cache matrix to hold the inverted transform
|
||||||
} |
} |
||||||
|
|
||||||
void olc::GFX2D::Transform2D::Multiply() |
void olc::GFX2D::Transform2D::Multiply() |
||||||
{ |
{ |
||||||
for (int c = 0; c < 3; c++) |
for (int c = 0; c < 3; c++) |
||||||
{ |
{ |
||||||
for (int r = 0; r < 3; r++) |
for (int r = 0; r < 3; r++) |
||||||
{ |
{ |
||||||
matrix[nTargetMatrix][c][r] = matrix[2][0][r] * matrix[nSourceMatrix][c][0] + |
matrix[nTargetMatrix][c][r] = matrix[2][0][r] * matrix[nSourceMatrix][c][0] + |
||||||
matrix[2][1][r] * matrix[nSourceMatrix][c][1] + |
matrix[2][1][r] * matrix[nSourceMatrix][c][1] + |
||||||
matrix[2][2][r] * matrix[nSourceMatrix][c][2]; |
matrix[2][2][r] * matrix[nSourceMatrix][c][2]; |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
std::swap(nTargetMatrix, nSourceMatrix); |
std::swap(nTargetMatrix, nSourceMatrix); |
||||||
bDirty = true; // Any transform multiply dirties the inversion
|
bDirty = true; // Any transform multiply dirties the inversion
|
||||||
} |
} |
||||||
|
|
||||||
void olc::GFX2D::Transform2D::Rotate(float fTheta) |
void olc::GFX2D::Transform2D::Rotate(float fTheta) |
||||||
{
|
{
|
||||||
// Construct Rotation Matrix
|
// Construct Rotation Matrix
|
||||||
matrix[2][0][0] = cosf(fTheta); matrix[2][1][0] = sinf(fTheta); matrix[2][2][0] = 0.0f; |
matrix[2][0][0] = cosf(fTheta); matrix[2][1][0] = sinf(fTheta); matrix[2][2][0] = 0.0f; |
||||||
matrix[2][0][1] = -sinf(fTheta); matrix[2][1][1] = cosf(fTheta); matrix[2][2][1] = 0.0f; |
matrix[2][0][1] = -sinf(fTheta); matrix[2][1][1] = cosf(fTheta); matrix[2][2][1] = 0.0f; |
||||||
matrix[2][0][2] = 0.0f; matrix[2][1][2] = 0.0f; matrix[2][2][2] = 1.0f; |
matrix[2][0][2] = 0.0f; matrix[2][1][2] = 0.0f; matrix[2][2][2] = 1.0f; |
||||||
Multiply();
|
Multiply();
|
||||||
} |
} |
||||||
|
|
||||||
void olc::GFX2D::Transform2D::Scale(float sx, float sy) |
void olc::GFX2D::Transform2D::Scale(float sx, float sy) |
||||||
{ |
{ |
||||||
// Construct Scale Matrix
|
// Construct Scale Matrix
|
||||||
matrix[2][0][0] = sx; matrix[2][1][0] = 0.0f; matrix[2][2][0] = 0.0f; |
matrix[2][0][0] = sx; matrix[2][1][0] = 0.0f; matrix[2][2][0] = 0.0f; |
||||||
matrix[2][0][1] = 0.0f; matrix[2][1][1] = sy; matrix[2][2][1] = 0.0f; |
matrix[2][0][1] = 0.0f; matrix[2][1][1] = sy; matrix[2][2][1] = 0.0f; |
||||||
matrix[2][0][2] = 0.0f; matrix[2][1][2] = 0.0f; matrix[2][2][2] = 1.0f; |
matrix[2][0][2] = 0.0f; matrix[2][1][2] = 0.0f; matrix[2][2][2] = 1.0f; |
||||||
Multiply(); |
Multiply(); |
||||||
} |
} |
||||||
|
|
||||||
void olc::GFX2D::Transform2D::Shear(float sx, float sy) |
void olc::GFX2D::Transform2D::Shear(float sx, float sy) |
||||||
{ |
{ |
||||||
// Construct Shear Matrix
|
// Construct Shear Matrix
|
||||||
matrix[2][0][0] = 1.0f; matrix[2][1][0] = sx; matrix[2][2][0] = 0.0f; |
matrix[2][0][0] = 1.0f; matrix[2][1][0] = sx; matrix[2][2][0] = 0.0f; |
||||||
matrix[2][0][1] = sy; matrix[2][1][1] = 1.0f; matrix[2][2][1] = 0.0f; |
matrix[2][0][1] = sy; matrix[2][1][1] = 1.0f; matrix[2][2][1] = 0.0f; |
||||||
matrix[2][0][2] = 0.0f; matrix[2][1][2] = 0.0f; matrix[2][2][2] = 1.0f; |
matrix[2][0][2] = 0.0f; matrix[2][1][2] = 0.0f; matrix[2][2][2] = 1.0f; |
||||||
Multiply(); |
Multiply(); |
||||||
} |
} |
||||||
|
|
||||||
void olc::GFX2D::Transform2D::Translate(float ox, float oy) |
void olc::GFX2D::Transform2D::Translate(float ox, float oy) |
||||||
{ |
{ |
||||||
// Construct Translate Matrix
|
// Construct Translate Matrix
|
||||||
matrix[2][0][0] = 1.0f; matrix[2][1][0] = 0.0f; matrix[2][2][0] = ox; |
matrix[2][0][0] = 1.0f; matrix[2][1][0] = 0.0f; matrix[2][2][0] = ox; |
||||||
matrix[2][0][1] = 0.0f; matrix[2][1][1] = 1.0f; matrix[2][2][1] = oy; |
matrix[2][0][1] = 0.0f; matrix[2][1][1] = 1.0f; matrix[2][2][1] = oy; |
||||||
matrix[2][0][2] = 0.0f; matrix[2][1][2] = 0.0f; matrix[2][2][2] = 1.0f; |
matrix[2][0][2] = 0.0f; matrix[2][1][2] = 0.0f; matrix[2][2][2] = 1.0f; |
||||||
Multiply(); |
Multiply(); |
||||||
} |
} |
||||||
|
|
||||||
void olc::GFX2D::Transform2D::Perspective(float ox, float oy) |
void olc::GFX2D::Transform2D::Perspective(float ox, float oy) |
||||||
{ |
{ |
||||||
// Construct Translate Matrix
|
// Construct Translate Matrix
|
||||||
matrix[2][0][0] = 1.0f; matrix[2][1][0] = 0.0f; matrix[2][2][0] = 0.0f; |
matrix[2][0][0] = 1.0f; matrix[2][1][0] = 0.0f; matrix[2][2][0] = 0.0f; |
||||||
matrix[2][0][1] = 0.0f; matrix[2][1][1] = 1.0f; matrix[2][2][1] = 0.0f; |
matrix[2][0][1] = 0.0f; matrix[2][1][1] = 1.0f; matrix[2][2][1] = 0.0f; |
||||||
matrix[2][0][2] = ox; matrix[2][1][2] = oy; matrix[2][2][2] = 1.0f; |
matrix[2][0][2] = ox; matrix[2][1][2] = oy; matrix[2][2][2] = 1.0f; |
||||||
Multiply(); |
Multiply(); |
||||||
} |
} |
||||||
|
|
||||||
void olc::GFX2D::Transform2D::Forward(float in_x, float in_y, float &out_x, float &out_y) |
void olc::GFX2D::Transform2D::Forward(float in_x, float in_y, float &out_x, float &out_y) |
||||||
{ |
{ |
||||||
out_x = in_x * matrix[nSourceMatrix][0][0] + in_y * matrix[nSourceMatrix][1][0] + matrix[nSourceMatrix][2][0]; |
out_x = in_x * matrix[nSourceMatrix][0][0] + in_y * matrix[nSourceMatrix][1][0] + matrix[nSourceMatrix][2][0]; |
||||||
out_y = in_x * matrix[nSourceMatrix][0][1] + in_y * matrix[nSourceMatrix][1][1] + matrix[nSourceMatrix][2][1]; |
out_y = in_x * matrix[nSourceMatrix][0][1] + in_y * matrix[nSourceMatrix][1][1] + matrix[nSourceMatrix][2][1]; |
||||||
float out_z = in_x * matrix[nSourceMatrix][0][2] + in_y * matrix[nSourceMatrix][1][2] + matrix[nSourceMatrix][2][2]; |
float out_z = in_x * matrix[nSourceMatrix][0][2] + in_y * matrix[nSourceMatrix][1][2] + matrix[nSourceMatrix][2][2]; |
||||||
if (out_z != 0) |
if (out_z != 0) |
||||||
{ |
{ |
||||||
out_x /= out_z; |
out_x /= out_z; |
||||||
out_y /= out_z; |
out_y /= out_z; |
||||||
} |
} |
||||||
}
|
}
|
||||||
|
|
||||||
void olc::GFX2D::Transform2D::Backward(float in_x, float in_y, float &out_x, float &out_y) |
void olc::GFX2D::Transform2D::Backward(float in_x, float in_y, float &out_x, float &out_y) |
||||||
{ |
{ |
||||||
out_x = in_x * matrix[3][0][0] + in_y * matrix[3][1][0] + matrix[3][2][0]; |
out_x = in_x * matrix[3][0][0] + in_y * matrix[3][1][0] + matrix[3][2][0]; |
||||||
out_y = in_x * matrix[3][0][1] + in_y * matrix[3][1][1] + matrix[3][2][1]; |
out_y = in_x * matrix[3][0][1] + in_y * matrix[3][1][1] + matrix[3][2][1]; |
||||||
float out_z = in_x * matrix[3][0][2] + in_y * matrix[3][1][2] + matrix[3][2][2]; |
float out_z = in_x * matrix[3][0][2] + in_y * matrix[3][1][2] + matrix[3][2][2]; |
||||||
if (out_z != 0) |
if (out_z != 0) |
||||||
{ |
{ |
||||||
out_x /= out_z; |
out_x /= out_z; |
||||||
out_y /= out_z; |
out_y /= out_z; |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
void olc::GFX2D::Transform2D::Invert() |
void olc::GFX2D::Transform2D::Invert() |
||||||
{ |
{ |
||||||
if (bDirty) // Obviously costly so only do if needed
|
if (bDirty) // Obviously costly so only do if needed
|
||||||
{
|
{
|
||||||
float det = matrix[nSourceMatrix][0][0] * (matrix[nSourceMatrix][1][1] * matrix[nSourceMatrix][2][2] - matrix[nSourceMatrix][1][2] * matrix[nSourceMatrix][2][1]) - |
float det = matrix[nSourceMatrix][0][0] * (matrix[nSourceMatrix][1][1] * matrix[nSourceMatrix][2][2] - matrix[nSourceMatrix][1][2] * matrix[nSourceMatrix][2][1]) - |
||||||
matrix[nSourceMatrix][1][0] * (matrix[nSourceMatrix][0][1] * matrix[nSourceMatrix][2][2] - matrix[nSourceMatrix][2][1] * matrix[nSourceMatrix][0][2]) + |
matrix[nSourceMatrix][1][0] * (matrix[nSourceMatrix][0][1] * matrix[nSourceMatrix][2][2] - matrix[nSourceMatrix][2][1] * matrix[nSourceMatrix][0][2]) + |
||||||
matrix[nSourceMatrix][2][0] * (matrix[nSourceMatrix][0][1] * matrix[nSourceMatrix][1][2] - matrix[nSourceMatrix][1][1] * matrix[nSourceMatrix][0][2]); |
matrix[nSourceMatrix][2][0] * (matrix[nSourceMatrix][0][1] * matrix[nSourceMatrix][1][2] - matrix[nSourceMatrix][1][1] * matrix[nSourceMatrix][0][2]); |
||||||
|
|
||||||
float idet = 1.0f / det; |
float idet = 1.0f / det; |
||||||
matrix[3][0][0] = (matrix[nSourceMatrix][1][1] * matrix[nSourceMatrix][2][2] - matrix[nSourceMatrix][1][2] * matrix[nSourceMatrix][2][1]) * idet; |
matrix[3][0][0] = (matrix[nSourceMatrix][1][1] * matrix[nSourceMatrix][2][2] - matrix[nSourceMatrix][1][2] * matrix[nSourceMatrix][2][1]) * idet; |
||||||
matrix[3][1][0] = (matrix[nSourceMatrix][2][0] * matrix[nSourceMatrix][1][2] - matrix[nSourceMatrix][1][0] * matrix[nSourceMatrix][2][2]) * idet; |
matrix[3][1][0] = (matrix[nSourceMatrix][2][0] * matrix[nSourceMatrix][1][2] - matrix[nSourceMatrix][1][0] * matrix[nSourceMatrix][2][2]) * idet; |
||||||
matrix[3][2][0] = (matrix[nSourceMatrix][1][0] * matrix[nSourceMatrix][2][1] - matrix[nSourceMatrix][2][0] * matrix[nSourceMatrix][1][1]) * idet; |
matrix[3][2][0] = (matrix[nSourceMatrix][1][0] * matrix[nSourceMatrix][2][1] - matrix[nSourceMatrix][2][0] * matrix[nSourceMatrix][1][1]) * idet; |
||||||
matrix[3][0][1] = (matrix[nSourceMatrix][2][1] * matrix[nSourceMatrix][0][2] - matrix[nSourceMatrix][0][1] * matrix[nSourceMatrix][2][2]) * idet; |
matrix[3][0][1] = (matrix[nSourceMatrix][2][1] * matrix[nSourceMatrix][0][2] - matrix[nSourceMatrix][0][1] * matrix[nSourceMatrix][2][2]) * idet; |
||||||
matrix[3][1][1] = (matrix[nSourceMatrix][0][0] * matrix[nSourceMatrix][2][2] - matrix[nSourceMatrix][2][0] * matrix[nSourceMatrix][0][2]) * idet; |
matrix[3][1][1] = (matrix[nSourceMatrix][0][0] * matrix[nSourceMatrix][2][2] - matrix[nSourceMatrix][2][0] * matrix[nSourceMatrix][0][2]) * idet; |
||||||
matrix[3][2][1] = (matrix[nSourceMatrix][0][1] * matrix[nSourceMatrix][2][0] - matrix[nSourceMatrix][0][0] * matrix[nSourceMatrix][2][1]) * idet; |
matrix[3][2][1] = (matrix[nSourceMatrix][0][1] * matrix[nSourceMatrix][2][0] - matrix[nSourceMatrix][0][0] * matrix[nSourceMatrix][2][1]) * idet; |
||||||
matrix[3][0][2] = (matrix[nSourceMatrix][0][1] * matrix[nSourceMatrix][1][2] - matrix[nSourceMatrix][0][2] * matrix[nSourceMatrix][1][1]) * idet; |
matrix[3][0][2] = (matrix[nSourceMatrix][0][1] * matrix[nSourceMatrix][1][2] - matrix[nSourceMatrix][0][2] * matrix[nSourceMatrix][1][1]) * idet; |
||||||
matrix[3][1][2] = (matrix[nSourceMatrix][0][2] * matrix[nSourceMatrix][1][0] - matrix[nSourceMatrix][0][0] * matrix[nSourceMatrix][1][2]) * idet; |
matrix[3][1][2] = (matrix[nSourceMatrix][0][2] * matrix[nSourceMatrix][1][0] - matrix[nSourceMatrix][0][0] * matrix[nSourceMatrix][1][2]) * idet; |
||||||
matrix[3][2][2] = (matrix[nSourceMatrix][0][0] * matrix[nSourceMatrix][1][1] - matrix[nSourceMatrix][0][1] * matrix[nSourceMatrix][1][0]) * idet; |
matrix[3][2][2] = (matrix[nSourceMatrix][0][0] * matrix[nSourceMatrix][1][1] - matrix[nSourceMatrix][0][1] * matrix[nSourceMatrix][1][0]) * idet; |
||||||
bDirty = false; |
bDirty = false; |
||||||
}
|
}
|
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
#endif |
#endif |
||||||
#endif |
#endif |
Loading…
Reference in new issue