optimize: use expression template to calculate matrixs multiply
This commit is contained in:
parent
32ecc0cbe8
commit
4ce0a470de
|
|
@ -75,7 +75,7 @@ namespace easy2d
|
|||
this->Reset();
|
||||
}
|
||||
|
||||
virtual void Init(Node* target) {}
|
||||
virtual void Init(Node* target) { initialized_ = true; }
|
||||
|
||||
virtual void Update(Node* target, Duration const& dt)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -356,8 +356,8 @@ namespace easy2d
|
|||
|
||||
RotateBy::RotateBy(Duration const& duration, float rotation)
|
||||
: FiniteTimeAction(duration)
|
||||
, delta_val_(rotation)
|
||||
{
|
||||
delta_val_ = rotation;
|
||||
}
|
||||
|
||||
void RotateBy::Init(Node* target)
|
||||
|
|
|
|||
|
|
@ -68,12 +68,14 @@ namespace easy2d
|
|||
|
||||
bool Image::Load(Resource& res)
|
||||
{
|
||||
HRESULT hr = devices::Graphics::Instance().CreateBitmapFromResource(res, &bitmap_);
|
||||
ID2D1Bitmap* bitmap;
|
||||
HRESULT hr = devices::Graphics::Instance().CreateBitmapFromResource(res, &bitmap);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
logs::Trace(L"Load Image from resource failed!", hr);
|
||||
return false;
|
||||
}
|
||||
this->SetBitmap(bitmap);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -92,12 +94,14 @@ namespace easy2d
|
|||
// 默认搜索路径,所以需要通过 File::GetPath 获取完整路径
|
||||
String image_file_path = image_file.GetPath();
|
||||
|
||||
HRESULT hr = devices::Graphics::Instance().CreateBitmapFromFile(image_file_path, &bitmap_);
|
||||
ID2D1Bitmap* bitmap;
|
||||
HRESULT hr = devices::Graphics::Instance().CreateBitmapFromFile(image_file_path, &bitmap);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
logs::Trace(L"Load Image from file failed!", hr);
|
||||
return false;
|
||||
}
|
||||
this->SetBitmap(bitmap);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
// THE SOFTWARE.
|
||||
|
||||
#include "input.h"
|
||||
#include <cstring>
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
|
|
@ -28,6 +29,7 @@ namespace easy2d
|
|||
: initialized(false)
|
||||
{
|
||||
ZeroMemory(keys_, sizeof(keys_));
|
||||
ZeroMemory(keys_cache_, sizeof(keys_cache_));
|
||||
}
|
||||
|
||||
InputDevice::~InputDevice()
|
||||
|
|
@ -44,11 +46,12 @@ namespace easy2d
|
|||
|
||||
void InputDevice::Update(HWND hwnd, float scale_x, float scale_y)
|
||||
{
|
||||
::GetKeyboardState(keys_);
|
||||
memcpy(keys_cache_, keys_, sizeof(keys_cache_));
|
||||
GetKeyboardState(keys_);
|
||||
|
||||
POINT client_cursor_pos;
|
||||
::GetCursorPos(&client_cursor_pos);
|
||||
::ScreenToClient(hwnd, &client_cursor_pos);
|
||||
GetCursorPos(&client_cursor_pos);
|
||||
ScreenToClient(hwnd, &client_cursor_pos);
|
||||
|
||||
mouse_pos_ = Point(client_cursor_pos.x * scale_x, client_cursor_pos.y * scale_y);
|
||||
}
|
||||
|
|
@ -67,6 +70,22 @@ namespace easy2d
|
|||
return false;
|
||||
}
|
||||
|
||||
bool InputDevice::WasPressed(KeyCode code)
|
||||
{
|
||||
if (keys_cache_[static_cast<int>(code)] & 0x80 &&
|
||||
!(keys_[static_cast<int>(code)] & 0x80))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InputDevice::WasPressed(MouseCode code)
|
||||
{
|
||||
if (keys_cache_[static_cast<int>(code)] & 0x80 &&
|
||||
!(keys_[static_cast<int>(code)] & 0x80))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
float InputDevice::GetMouseX()
|
||||
{
|
||||
return mouse_pos_.x;
|
||||
|
|
|
|||
|
|
@ -45,6 +45,16 @@ namespace easy2d
|
|||
MouseCode code
|
||||
);
|
||||
|
||||
// 检测键盘某按键是否点击
|
||||
bool WasPressed(
|
||||
KeyCode code
|
||||
);
|
||||
|
||||
// 检测鼠标按键是否点击
|
||||
bool WasPressed(
|
||||
MouseCode code
|
||||
);
|
||||
|
||||
// 資誼報炎X已恫炎峙
|
||||
float GetMouseX();
|
||||
|
||||
|
|
@ -69,6 +79,7 @@ namespace easy2d
|
|||
protected:
|
||||
bool initialized;
|
||||
BYTE keys_[256];
|
||||
BYTE keys_cache_[256];
|
||||
Point mouse_pos_;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include <cassert>
|
||||
#include "macros.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
|
|
@ -51,7 +51,11 @@ namespace easy2d
|
|||
IntrusivePtrAddRef(ptr_);
|
||||
}
|
||||
|
||||
IntrusivePtr(IntrusivePtr&& other) : ptr_(::std::move(other.ptr_)) {}
|
||||
IntrusivePtr(IntrusivePtr&& other)
|
||||
{
|
||||
ptr_ = other.ptr_;
|
||||
other.ptr_ = nullptr;
|
||||
}
|
||||
|
||||
~IntrusivePtr()
|
||||
{
|
||||
|
|
@ -67,14 +71,14 @@ namespace easy2d
|
|||
|
||||
inline ElemType* operator ->() const
|
||||
{
|
||||
assert(ptr_ && ptr_->GetRefCount() > 0 &&
|
||||
E2D_WARNING_IF(!ptr_ || ptr_->GetRefCount() <= 0,
|
||||
"Invalid pointer!");
|
||||
return ptr_;
|
||||
}
|
||||
|
||||
inline ElemType& operator *() const
|
||||
{
|
||||
assert(ptr_ && ptr_->GetRefCount() > 0 &&
|
||||
E2D_WARNING_IF(!ptr_ || ptr_->GetRefCount() <= 0,
|
||||
"Invalid pointer!");
|
||||
return *ptr_;
|
||||
}
|
||||
|
|
@ -89,6 +93,14 @@ namespace easy2d
|
|||
return *this;
|
||||
}
|
||||
|
||||
inline IntrusivePtr& operator =(IntrusivePtr&& other)
|
||||
{
|
||||
IntrusivePtrRelease(ptr_);
|
||||
ptr_ = other.ptr_;
|
||||
other.ptr_ = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline IntrusivePtr& operator =(ElemType* p)
|
||||
{
|
||||
IntrusivePtr(p).Swap(*this);
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@
|
|||
#include "Task.h"
|
||||
#include "Action.hpp"
|
||||
#include "render.h"
|
||||
#include <iterator>
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
|
|
@ -56,14 +55,16 @@ namespace easy2d
|
|||
if (!visible_)
|
||||
return;
|
||||
|
||||
auto& graphics = devices::Graphics::Instance();
|
||||
|
||||
if (clip_enabled_)
|
||||
{
|
||||
devices::Graphics::Instance().PushClip(final_matrix_, transform_.size);
|
||||
graphics.PushClip(final_matrix_, transform_.size);
|
||||
}
|
||||
|
||||
if (children_.empty())
|
||||
{
|
||||
devices::Graphics::Instance().SetTransform(final_matrix_);
|
||||
graphics.SetTransform(final_matrix_);
|
||||
OnDraw();
|
||||
}
|
||||
else
|
||||
|
|
@ -72,8 +73,8 @@ namespace easy2d
|
|||
if (dirty_sort_)
|
||||
{
|
||||
std::sort(
|
||||
std::begin(children_),
|
||||
std::end(children_),
|
||||
children_.begin(),
|
||||
children_.end(),
|
||||
[](spNode const& n1, spNode const& n2) { return n1->GetOrder() < n2->GetOrder(); }
|
||||
);
|
||||
|
||||
|
|
@ -95,7 +96,7 @@ namespace easy2d
|
|||
}
|
||||
}
|
||||
|
||||
devices::Graphics::Instance().SetTransform(final_matrix_);
|
||||
graphics.SetTransform(final_matrix_);
|
||||
OnDraw();
|
||||
|
||||
// 访问剩余节点
|
||||
|
|
@ -105,7 +106,7 @@ namespace easy2d
|
|||
|
||||
if (clip_enabled_)
|
||||
{
|
||||
devices::Graphics::Instance().PopClip();
|
||||
graphics.PopClip();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -170,13 +171,9 @@ namespace easy2d
|
|||
dirty_transform_ = false;
|
||||
|
||||
final_matrix_ = transform_.ToMatrix();
|
||||
|
||||
// 根据自身支点计算 Initial 矩阵,子节点将根据这个矩阵进行变换
|
||||
auto pivot = Point(
|
||||
transform_.size.width * transform_.pivot.x,
|
||||
transform_.size.height * transform_.pivot.y
|
||||
initial_matrix_ = final_matrix_ * math::Matrix::Translation(
|
||||
Point{ transform_.size.width * transform_.pivot.x, transform_.size.height * transform_.pivot.y }
|
||||
);
|
||||
initial_matrix_ = final_matrix_ * math::Matrix::Translation(pivot);
|
||||
|
||||
if (parent_)
|
||||
{
|
||||
|
|
@ -186,13 +183,11 @@ namespace easy2d
|
|||
|
||||
// 重新构造轮廓
|
||||
SafeRelease(border_);
|
||||
|
||||
ThrowIfFailed(
|
||||
devices::Graphics::Instance().CreateRectGeometry(final_matrix_, transform_.size, &border_)
|
||||
);
|
||||
|
||||
// 通知子节点进行转换
|
||||
for (const auto& child : children_)
|
||||
for (auto& child : children_)
|
||||
{
|
||||
child->dirty_transform_ = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,8 +85,10 @@
|
|||
|
||||
#if VS_VER >= VS_2015
|
||||
# define E2D_NOEXCEPT noexcept
|
||||
# define E2D_CONSTEXPR constexpr
|
||||
#else
|
||||
# define E2D_NOEXCEPT throw()
|
||||
# define E2D_CONSTEXPR const
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -26,127 +26,105 @@ namespace easy2d
|
|||
{
|
||||
namespace math
|
||||
{
|
||||
class Matrix;
|
||||
|
||||
template <typename L, typename R>
|
||||
struct MatrixMultiply;
|
||||
|
||||
inline MatrixMultiply<Matrix, Matrix>
|
||||
operator *(Matrix const& lhs, Matrix const& rhs);
|
||||
|
||||
template <typename L, typename R>
|
||||
inline MatrixMultiply<MatrixMultiply<L, R>, Matrix>
|
||||
operator *(MatrixMultiply<L, R> const& lhs, Matrix const& rhs);
|
||||
|
||||
|
||||
class Matrix
|
||||
{
|
||||
float _11;
|
||||
float _12;
|
||||
float _21;
|
||||
float _22;
|
||||
float _31;
|
||||
float _32;
|
||||
float m[6]; // m[3][2]
|
||||
|
||||
public:
|
||||
Matrix()
|
||||
: _11(1.f)
|
||||
, _12(0.f)
|
||||
, _21(0.f)
|
||||
, _22(1.f)
|
||||
, _31(0.f)
|
||||
, _32(0.f)
|
||||
{
|
||||
m[0] = 1.f; m[1] = 0.f;
|
||||
m[2] = 0.f; m[3] = 1.f;
|
||||
m[4] = 0.f; m[5] = 0.f;
|
||||
}
|
||||
|
||||
Matrix(
|
||||
float _11,
|
||||
float _12,
|
||||
float _21,
|
||||
float _22,
|
||||
float _31,
|
||||
float _32)
|
||||
Matrix(float val[6])
|
||||
{
|
||||
this->_11 = _11;
|
||||
this->_12 = _12;
|
||||
this->_21 = _21;
|
||||
this->_22 = _22;
|
||||
this->_31 = _31;
|
||||
this->_32 = _32;
|
||||
m[0] = val[0]; m[1] = val[1];
|
||||
m[2] = val[2]; m[3] = val[3];
|
||||
m[4] = val[4]; m[5] = val[5];
|
||||
}
|
||||
|
||||
inline const Matrix operator*(const Matrix &matrix) const
|
||||
Matrix(float _11, float _12, float _21, float _22, float _31, float _32)
|
||||
{
|
||||
return Matrix(
|
||||
_11 * matrix._11 + _12 * matrix._21,
|
||||
_11 * matrix._12 + _12 * matrix._22,
|
||||
_21 * matrix._11 + _22 * matrix._21,
|
||||
_21 * matrix._12 + _22 * matrix._22,
|
||||
_31 * matrix._11 + _32 * matrix._21 + matrix._31,
|
||||
_31 * matrix._12 + _32 * matrix._22 + matrix._32
|
||||
);
|
||||
m[0] = _11; m[1] = _12;
|
||||
m[2] = _21; m[3] = _22;
|
||||
m[4] = _31; m[5] = _32;
|
||||
}
|
||||
|
||||
Matrix(Matrix const& other)
|
||||
{
|
||||
m[0] = other.m[0]; m[1] = other.m[1];
|
||||
m[2] = other.m[2]; m[3] = other.m[3];
|
||||
m[4] = other.m[4]; m[5] = other.m[5];
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Matrix(T const& other)
|
||||
{
|
||||
m[0] = other[0]; m[1] = other[1];
|
||||
m[2] = other[2]; m[3] = other[3];
|
||||
m[4] = other[4]; m[5] = other[5];
|
||||
}
|
||||
|
||||
inline float operator [](unsigned int index) const { return m[index]; }
|
||||
|
||||
template <typename T>
|
||||
inline Matrix& operator =(T const& other)
|
||||
{
|
||||
m[0] = other[0]; m[1] = other[1];
|
||||
m[2] = other[2]; m[3] = other[3];
|
||||
m[4] = other[4]; m[5] = other[5];
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline operator D2D1_MATRIX_3X2_F () const
|
||||
{
|
||||
return D2D1_MATRIX_3X2_F{
|
||||
_11, _12,
|
||||
_21, _22,
|
||||
_31, _32
|
||||
m[0], m[1],
|
||||
m[2], m[3],
|
||||
m[4], m[5]
|
||||
};
|
||||
}
|
||||
|
||||
inline Matrix& Identity()
|
||||
{
|
||||
_11 = 1.f;
|
||||
_12 = 0.f;
|
||||
_21 = 0.f;
|
||||
_22 = 1.f;
|
||||
_31 = 0.f;
|
||||
_32 = 0.f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Matrix& Translate(const Vector2& v)
|
||||
{
|
||||
*this = *this * Matrix::Translation(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Matrix& Translate(float x, float y)
|
||||
{
|
||||
*this = *this * Matrix::Translation(x, y);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Matrix& Scale(const Vector2& v, const Vector2& center)
|
||||
{
|
||||
*this = *this * Matrix::Scaling(v, center);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Matrix& Scale(float scale_x, float scale_y, const Vector2& center)
|
||||
{
|
||||
*this = *this * Matrix::Scaling(scale_x, scale_y, center);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Matrix& Rotate(float angle, const Vector2& center)
|
||||
{
|
||||
*this = *this * Matrix::Rotation(angle, center);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Matrix& Skew(float angle_x, float angle_y, const Vector2& center)
|
||||
{
|
||||
*this = *this * Matrix::Skewing(angle_x, angle_y, center);
|
||||
m[0] = 1.f; m[1] = 0.f;
|
||||
m[2] = 0.f; m[3] = 1.f;
|
||||
m[4] = 0.f; m[5] = 0.f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline float Determinant() const
|
||||
{
|
||||
return (_11 * _22) - (_12 * _21);
|
||||
return (m[0] * m[3]) - (m[1] * m[2]);
|
||||
}
|
||||
|
||||
inline bool IsIdentity() const
|
||||
{
|
||||
return _11 == 1.f && _12 == 0.f &&
|
||||
_21 == 0.f && _22 == 1.f &&
|
||||
_31 == 0.f && _32 == 0.f;
|
||||
return m[0] == 1.f && m[1] == 0.f &&
|
||||
m[2] == 0.f && m[3] == 1.f &&
|
||||
m[4] == 0.f && m[5] == 0.f;
|
||||
}
|
||||
|
||||
Vector2 Transform(const Vector2& v) const
|
||||
{
|
||||
return Vector2(
|
||||
v.x * _11 + v.y * _21 + _31,
|
||||
v.x * _12 + v.y * _22 + _32
|
||||
v.x * m[0] + v.y * m[2] + m[4],
|
||||
v.x * m[1] + v.y * m[3] + m[5]
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -214,5 +192,50 @@ namespace easy2d
|
|||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename L, typename R>
|
||||
struct MatrixMultiply
|
||||
{
|
||||
L const& lhs;
|
||||
R const& rhs;
|
||||
|
||||
MatrixMultiply(L const& lhs, R const& rhs)
|
||||
: lhs(lhs)
|
||||
, rhs(rhs)
|
||||
{}
|
||||
|
||||
inline float operator [](unsigned int index) const
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return lhs[0] * rhs[0] + lhs[1] * rhs[2];
|
||||
case 1:
|
||||
return lhs[0] * rhs[1] + lhs[1] * rhs[3];
|
||||
case 2:
|
||||
return lhs[2] * rhs[0] + lhs[3] * rhs[2];
|
||||
case 3:
|
||||
return lhs[2] * rhs[1] + lhs[3] * rhs[3];
|
||||
case 4:
|
||||
return lhs[4] * rhs[0] + lhs[5] * rhs[2] + rhs[4];
|
||||
case 5:
|
||||
return lhs[4] * rhs[1] + lhs[5] * rhs[3] + rhs[5];
|
||||
default:
|
||||
return 0.f;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
inline MatrixMultiply<Matrix, Matrix> operator *(Matrix const& lhs, Matrix const& rhs)
|
||||
{
|
||||
return MatrixMultiply<Matrix, Matrix>(lhs, rhs);
|
||||
}
|
||||
|
||||
template <typename L, typename R>
|
||||
inline MatrixMultiply<MatrixMultiply<L, R>, Matrix> operator *(MatrixMultiply<L, R> const& lhs, Matrix const& rhs)
|
||||
{
|
||||
return MatrixMultiply<MatrixMultiply<L, R>, Matrix>(lhs, rhs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,10 +49,10 @@ namespace easy2d
|
|||
inline Matrix ToMatrix() const
|
||||
{
|
||||
auto center = Vector2{ size.width * pivot.x, size.height * pivot.y };
|
||||
return Matrix{}.Scale(scale.x, scale.y, center)
|
||||
.Skew(skew.x, skew.y, center)
|
||||
.Rotate(rotation, center)
|
||||
.Translate(position - center);
|
||||
return Matrix{} * Matrix::Scaling(scale.x, scale.y, center)
|
||||
* Matrix::Skewing(skew.x, skew.y, center)
|
||||
* Matrix::Rotation(rotation, center)
|
||||
* Matrix::Translation(position - center);
|
||||
}
|
||||
|
||||
bool operator== (const Transform& other) const
|
||||
|
|
|
|||
|
|
@ -21,10 +21,23 @@
|
|||
#pragma once
|
||||
#include <cmath>
|
||||
|
||||
#if _MSC_VER >= 1900
|
||||
# define E2D_CONSTEXPR constexpr
|
||||
#else
|
||||
# define E2D_CONSTEXPR const
|
||||
#endif
|
||||
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
namespace math
|
||||
{
|
||||
namespace constants
|
||||
{
|
||||
E2D_CONSTEXPR auto PIf = 3.14159265358979f;
|
||||
E2D_CONSTEXPR auto PId = 3.14159265358979323846;
|
||||
}
|
||||
|
||||
inline int Abs(int val) { return ::abs(val); }
|
||||
|
||||
inline float Abs(float val) { return ::fabsf(val); }
|
||||
|
|
@ -41,17 +54,17 @@ namespace easy2d
|
|||
|
||||
inline double Sign(double val) { return val < 0 ? -1.0 : 1.0; }
|
||||
|
||||
inline float Sin(float val) { return ::sinf(val); }
|
||||
inline float Sin(float val) { return ::sinf(val * constants::PIf / 180.f); }
|
||||
|
||||
inline double Sin(double val) { return ::sin(val); }
|
||||
inline double Sin(double val) { return ::sin(val * constants::PId / 180.0); }
|
||||
|
||||
inline float Cos(float val) { return ::cosf(val); }
|
||||
inline float Cos(float val) { return ::cosf(val * constants::PIf / 180.f); }
|
||||
|
||||
inline double Cos(double val) { return ::cos(val); }
|
||||
inline double Cos(double val) { return ::cos(val * constants::PId / 180.0); }
|
||||
|
||||
inline float Tan(float val) { return ::tanf(val); }
|
||||
inline float Tan(float val) { return ::tanf(val * constants::PIf / 180.f); }
|
||||
|
||||
inline double Tan(double val) { return ::tan(val); }
|
||||
inline double Tan(double val) { return ::tan(val * constants::PId / 180.0); }
|
||||
|
||||
inline float Ceil(float val) { return ::ceil(val); }
|
||||
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ namespace easy2d
|
|||
auto iter = std::find(search_paths_.cbegin(), search_paths_.cend(), tmp);
|
||||
if (iter == search_paths_.cend())
|
||||
{
|
||||
search_paths_.push_front(path);
|
||||
search_paths_.push_front(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue