diff --git a/project/vs2013/Easy2D.vcxproj b/project/vs2013/Easy2D.vcxproj index 3b5933ed..ebc74304 100644 --- a/project/vs2013/Easy2D.vcxproj +++ b/project/vs2013/Easy2D.vcxproj @@ -73,7 +73,7 @@ - + @@ -123,6 +123,7 @@ + diff --git a/project/vs2013/Easy2D.vcxproj.filters b/project/vs2013/Easy2D.vcxproj.filters index 2a5164c8..c7d0b63c 100644 --- a/project/vs2013/Easy2D.vcxproj.filters +++ b/project/vs2013/Easy2D.vcxproj.filters @@ -62,9 +62,6 @@ core - - math - math @@ -203,6 +200,9 @@ core + + math + @@ -351,5 +351,8 @@ core + + math + \ No newline at end of file diff --git a/project/vs2015/Easy2D.vcxproj b/project/vs2015/Easy2D.vcxproj index 707919bb..545da6a1 100644 --- a/project/vs2015/Easy2D.vcxproj +++ b/project/vs2015/Easy2D.vcxproj @@ -73,7 +73,7 @@ - + @@ -123,6 +123,7 @@ + diff --git a/project/vs2015/Easy2D.vcxproj.filters b/project/vs2015/Easy2D.vcxproj.filters index 2a5164c8..c7d0b63c 100644 --- a/project/vs2015/Easy2D.vcxproj.filters +++ b/project/vs2015/Easy2D.vcxproj.filters @@ -62,9 +62,6 @@ core - - math - math @@ -203,6 +200,9 @@ core + + math + @@ -351,5 +351,8 @@ core + + math + \ No newline at end of file diff --git a/project/vs2017/Easy2D.vcxproj b/project/vs2017/Easy2D.vcxproj index 78bd6f34..0c41e53f 100644 --- a/project/vs2017/Easy2D.vcxproj +++ b/project/vs2017/Easy2D.vcxproj @@ -73,7 +73,7 @@ - + @@ -123,6 +123,7 @@ + diff --git a/project/vs2017/Easy2D.vcxproj.filters b/project/vs2017/Easy2D.vcxproj.filters index 2a5164c8..c7d0b63c 100644 --- a/project/vs2017/Easy2D.vcxproj.filters +++ b/project/vs2017/Easy2D.vcxproj.filters @@ -62,9 +62,6 @@ core - - math - math @@ -203,6 +200,9 @@ core + + math + @@ -351,5 +351,8 @@ core + + math + \ No newline at end of file diff --git a/src/core/Node.cpp b/src/core/Node.cpp index d8f8273f..2a984ca7 100644 --- a/src/core/Node.cpp +++ b/src/core/Node.cpp @@ -500,6 +500,11 @@ namespace easy2d return Rect(Point{}, size_); } + Rect Node::GetBoundingBox() const + { + return GetTransformMatrix().Transform(GetBounds()); + } + Array Node::GetChildren(String const& name) const { Array children; diff --git a/src/core/Node.h b/src/core/Node.h index 2f0668b9..547320e4 100644 --- a/src/core/Node.h +++ b/src/core/Node.h @@ -127,6 +127,9 @@ namespace easy2d // 获取包围盒 Rect GetBounds() const; + // 获取外切包围盒 + Rect GetBoundingBox() const; + // 获取二维变换矩阵 Matrix const& GetTransformMatrix() const; diff --git a/src/core/Sprite.cpp b/src/core/Sprite.cpp index 898b838f..529289be 100644 --- a/src/core/Sprite.cpp +++ b/src/core/Sprite.cpp @@ -99,7 +99,7 @@ namespace easy2d { if (image_) { - RenderSystem::Instance()->DrawImage(image_); + RenderSystem::Instance()->DrawImage(image_, GetBounds()); } } } \ No newline at end of file diff --git a/src/core/helper.hpp b/src/core/helper.hpp index a8078b6e..6fc580aa 100644 --- a/src/core/helper.hpp +++ b/src/core/helper.hpp @@ -24,7 +24,7 @@ #include "closure.hpp" #include "../math/vector.hpp" #include "../math/Rect.hpp" -#include "../math/Matrix.hpp" +#include "../math/Matrix.h" #include #include #include diff --git a/src/core/render.cpp b/src/core/render.cpp index 09f3eaf7..07f902e8 100644 --- a/src/core/render.cpp +++ b/src/core/render.cpp @@ -187,7 +187,7 @@ namespace easy2d return S_OK; } - HRESULT RenderSystem::DrawImage(ImagePtr const & image) + HRESULT RenderSystem::DrawImage(ImagePtr const & image, Rect const& dest_rect) { if (!render_target_) return E_UNEXPECTED; @@ -200,7 +200,7 @@ namespace easy2d render_target_->DrawBitmap( image->GetBitmap().Get(), - D2D1::RectF(0.f, 0.f, image->GetWidth(), image->GetHeight()), + dest_rect, opacity_, D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, image->GetCropRect() diff --git a/src/core/render.h b/src/core/render.h index 3a7283ed..97e4c391 100644 --- a/src/core/render.h +++ b/src/core/render.h @@ -26,7 +26,7 @@ #include "TextRenderer.h" #include "TextStyle.hpp" #include "Singleton.hpp" -#include "../math/Matrix.hpp" +#include "../math/Matrix.h" #include namespace easy2d @@ -128,7 +128,8 @@ namespace easy2d ); HRESULT DrawImage( - ImagePtr const& image + ImagePtr const& image, + Rect const& dest_rect ); HRESULT DrawBitmap( diff --git a/src/easy2d.h b/src/easy2d.h index 4ebe0aaa..d1bdb858 100644 --- a/src/easy2d.h +++ b/src/easy2d.h @@ -91,7 +91,7 @@ #include "math/ease.hpp" #include "math/vector.hpp" #include "math/rand.h" -#include "math/Matrix.hpp" +#include "math/Matrix.h" // diff --git a/src/math/Matrix.cpp b/src/math/Matrix.cpp new file mode 100644 index 00000000..d74cbf96 --- /dev/null +++ b/src/math/Matrix.cpp @@ -0,0 +1,152 @@ +// Copyright (c) 2016-2018 Easy2D - Nomango +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include "Matrix.h" + +namespace easy2d +{ + namespace math + { + Matrix::Matrix() + : _11(1.f), _12(0.f) + , _21(0.f), _22(1.f) + , _31(0.f), _32(0.f) + { + } + + Matrix::Matrix(float _11, float _12, float _21, float _22, float _31, float _32) + : _11(_11), _12(_12), _21(_21), _22(_22), _31(_31), _32(_32) + { + } + + Matrix::Matrix(const float* p) + { + for (int i = 0; i < 6; i++) + m[i] = p[i]; + } + + Matrix::Matrix(Matrix const& other) + : _11(other._11), _12(other._12) + , _21(other._21), _22(other._22) + , _31(other._31), _32(other._32) + { + } + + void Matrix::Identity() + { + _11 = 1.f; _12 = 0.f; + _21 = 0.f; _12 = 1.f; + _31 = 0.f; _32 = 0.f; + } + + Rect Matrix::Transform(const Rect & rect) const + { + Vector2 top_left = Transform(rect.GetLeftTop()); + Vector2 top_right = Transform(rect.GetRightTop()); + Vector2 bottom_left = Transform(rect.GetLeftBottom()); + Vector2 bottom_right = Transform(rect.GetRightBottom()); + + float left = min(min(top_left.x, top_right.x), min(bottom_left.x, bottom_right.x)); + float right = max(max(top_left.x, top_right.x), max(bottom_left.x, bottom_right.x)); + float top = min(min(top_left.y, top_right.y), min(bottom_left.y, bottom_right.y)); + float bottom = max(max(top_left.y, top_right.y), max(bottom_left.y, bottom_right.y)); + + return Rect{ left, top, (right - left), (bottom - top) }; + } + + Matrix Matrix::Translation(const Vector2& v) + { + return Matrix( + 1.f, 0.f, + 0.f, 1.f, + v.x, v.y + ); + } + + Matrix Matrix::Translation( + float x, + float y) + { + return Translation(Vector2(x, y)); + } + + Matrix Matrix::Scaling( + const Vector2& v, + const Vector2& center) + { + return Matrix( + v.x, 0.f, + 0.f, v.y, + center.x - v.x * center.x, + center.y - v.y * center.y + ); + } + + Matrix Matrix::Scaling( + float x, + float y, + const Vector2& center) + { + return Scaling(Vector2(x, y), center); + } + + Matrix Matrix::Rotation( + float angle, + const Vector2& center) + { + float s = math::Sin(angle); + float c = math::Cos(angle); + return Matrix( + c, s, + -s, c, + center.x * (1 - c) + center.y * s, + center.y * (1 - c) - center.x * s + ); + } + + Matrix Matrix::Skewing( + float angle_x, + float angle_y, + const Vector2& center) + { + float tx = math::Tan(angle_x); + float ty = math::Tan(angle_y); + return Matrix( + 1.f, -ty, + -tx, 1.f, + center.y * tx, center.x * ty + ); + } + + Matrix Matrix::Invert(Matrix const& matrix) + { + float det = 1.f / matrix.Determinant(); + + return Matrix( + det * matrix._22, + -det * matrix._12, + -det * matrix._21, + det * matrix._11, + det * (matrix._21 * matrix._32 - matrix._22 * matrix._31), + det * (matrix._12 * matrix._31 - matrix._11 * matrix._32) + ); + } + } +} diff --git a/src/math/Matrix.hpp b/src/math/Matrix.h similarity index 63% rename from src/math/Matrix.hpp rename to src/math/Matrix.h index 29ce64a0..4e52cf15 100644 --- a/src/math/Matrix.hpp +++ b/src/math/Matrix.h @@ -20,25 +20,13 @@ #pragma once #include "vector.hpp" +#include "Rect.hpp" #include namespace easy2d { namespace math { - struct Matrix; - - template - struct MatrixMultiply; - - inline MatrixMultiply - operator *(Matrix const& lhs, Matrix const& rhs); - - template - inline MatrixMultiply, Matrix> - operator *(MatrixMultiply const& lhs, Matrix const& rhs); - - struct Matrix { union @@ -57,31 +45,13 @@ namespace easy2d }; }; - public: - Matrix() - : _11(1.f), _12(0.f) - , _21(0.f), _22(1.f) - , _31(0.f), _32(0.f) - { - } + Matrix(); - Matrix(float _11, float _12, float _21, float _22, float _31, float _32) - : _11(_11), _12(_12), _21(_21), _22(_22), _31(_31), _32(_32) - { - } + Matrix(float _11, float _12, float _21, float _22, float _31, float _32); - Matrix(const float* p) - { - for (int i = 0; i < 6; i++) - m[i] = p[i]; - } + Matrix(const float* p); - Matrix(Matrix const& other) - : _11(other._11), _12(other._12) - , _21(other._21), _22(other._22) - , _31(other._31), _32(other._32) - { - } + Matrix(Matrix const& other); template Matrix(T const& other) @@ -90,6 +60,24 @@ namespace easy2d m[i] = other[i]; } + void Identity(); + + inline Vector2 Transform(const Vector2& v) const + { + return Vector2( + v.x * _11 + v.y * _21 + _31, + v.x * _12 + v.y * _22 + _32 + ); + } + + Rect Transform(const Rect& rect) const; + + inline void Translate(const Vector2& v) + { + _31 += _11 * v.x + _21 * v.y; + _32 += _12 * v.x + _22 * v.y; + } + inline float operator [](unsigned int index) const { return m[index]; @@ -103,14 +91,6 @@ namespace easy2d return *this; } - inline Matrix& Identity() - { - _11 = 1.f; _12 = 0.f; - _21 = 0.f; _12 = 1.f; - _31 = 0.f; _32 = 0.f; - return *this; - } - inline float Determinant() const { return (_11 * _22) - (_12 * _21); @@ -128,20 +108,6 @@ namespace easy2d return 0 != Determinant(); } - Vector2 Transform(const Vector2& v) const - { - return Vector2( - v.x * _11 + v.y * _21 + _31, - v.x * _12 + v.y * _22 + _32 - ); - } - - void Translate(const Vector2& v) - { - _31 += _11 * v.x + _21 * v.y; - _32 += _12 * v.x + _22 * v.y; - } - inline operator D2D1_MATRIX_3X2_F const& () const { return reinterpret_cast(*this); @@ -152,86 +118,40 @@ namespace easy2d return reinterpret_cast(*this); } - static Matrix Translation(const Vector2& v) - { - return Matrix( - 1.f, 0.f, - 0.f, 1.f, - v.x, v.y - ); - } + static Matrix Translation(const Vector2& v); static Matrix Translation( float x, - float y) - { - return Translation(Vector2(x, y)); - } + float y + ); static Matrix Scaling( const Vector2& v, - const Vector2& center = Vector2()) - { - return Matrix( - v.x, 0.f, - 0.f, v.y, - center.x - v.x * center.x, - center.y - v.y * center.y - ); - } + const Vector2& center = Vector2() + ); static Matrix Scaling( float x, float y, - const Vector2& center = Vector2()) - { - return Scaling(Vector2(x, y), center); - } + const Vector2& center = Vector2() + ); static Matrix Rotation( float angle, - const Vector2& center = Vector2()) - { - float s = math::Sin(angle); - float c = math::Cos(angle); - return Matrix( - c, s, - -s, c, - center.x * (1 - c) + center.y * s, - center.y * (1 - c) - center.x * s - ); - } + const Vector2& center = Vector2() + ); static Matrix Skewing( float angle_x, float angle_y, - const Vector2& center = Vector2()) - { - float tx = math::Tan(angle_x); - float ty = math::Tan(angle_y); - return Matrix( - 1.f, -ty, - -tx, 1.f, - center.y * tx, center.x * ty - ); - } + const Vector2& center = Vector2() + ); - static Matrix Invert(Matrix const& matrix) - { - float det = 1.f / matrix.Determinant(); - - return Matrix( - det * matrix._22, - -det * matrix._12, - -det * matrix._21, - det * matrix._11, - det * (matrix._21 * matrix._32 - matrix._22 * matrix._31), - det * (matrix._12 * matrix._31 - matrix._11 * matrix._32) - ); - } + static Matrix Invert(Matrix const& matrix); }; + // Use template expression to optimize matrix multiply template struct MatrixMultiply {