Add Geometry && add GeometrySink && rename ActionPath to ActionWalk
This commit is contained in:
		
							parent
							
								
									5327159e99
								
							
						
					
					
						commit
						671719fb34
					
				|  | @ -2,9 +2,11 @@ | ||||||
| <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <ClInclude Include="..\src\kiwano\2d\action\Action.h" /> |     <ClInclude Include="..\src\kiwano\2d\action\Action.h" /> | ||||||
|  |     <ClInclude Include="..\src\kiwano\2d\action\ActionDelay.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\2d\action\ActionGroup.h" /> |     <ClInclude Include="..\src\kiwano\2d\action\ActionGroup.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\2d\action\ActionHelper.h" /> |     <ClInclude Include="..\src\kiwano\2d\action\ActionHelper.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\2d\action\ActionManager.h" /> |     <ClInclude Include="..\src\kiwano\2d\action\ActionManager.h" /> | ||||||
|  |     <ClInclude Include="..\src\kiwano\2d\action\ActionWalk.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\2d\action\ActionTween.h" /> |     <ClInclude Include="..\src\kiwano\2d\action\ActionTween.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\2d\action\Animation.h" /> |     <ClInclude Include="..\src\kiwano\2d\action\Animation.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\2d\Frame.h" /> |     <ClInclude Include="..\src\kiwano\2d\Frame.h" /> | ||||||
|  | @ -69,6 +71,7 @@ | ||||||
|     <ClInclude Include="..\src\kiwano\renderer\D3D10DeviceResources.h" /> |     <ClInclude Include="..\src\kiwano\renderer\D3D10DeviceResources.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\renderer\D3D11DeviceResources.h" /> |     <ClInclude Include="..\src\kiwano\renderer\D3D11DeviceResources.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\renderer\D3DDeviceResourcesBase.h" /> |     <ClInclude Include="..\src\kiwano\renderer\D3DDeviceResourcesBase.h" /> | ||||||
|  |     <ClInclude Include="..\src\kiwano\renderer\Geometry.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\renderer\GifImage.h" /> |     <ClInclude Include="..\src\kiwano\renderer\GifImage.h" /> | ||||||
|     <ClInclude Include="..\src\kiwano\renderer\helper.hpp" /> |     <ClInclude Include="..\src\kiwano\renderer\helper.hpp" /> | ||||||
|     <ClInclude Include="..\src\kiwano\renderer\Image.h" /> |     <ClInclude Include="..\src\kiwano\renderer\Image.h" /> | ||||||
|  | @ -86,8 +89,10 @@ | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <ClCompile Include="..\src\kiwano\2d\action\Action.cpp" /> |     <ClCompile Include="..\src\kiwano\2d\action\Action.cpp" /> | ||||||
|  |     <ClCompile Include="..\src\kiwano\2d\action\ActionDelay.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\2d\action\ActionGroup.cpp" /> |     <ClCompile Include="..\src\kiwano\2d\action\ActionGroup.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\2d\action\ActionManager.cpp" /> |     <ClCompile Include="..\src\kiwano\2d\action\ActionManager.cpp" /> | ||||||
|  |     <ClCompile Include="..\src\kiwano\2d\action\ActionWalk.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\2d\action\ActionTween.cpp" /> |     <ClCompile Include="..\src\kiwano\2d\action\ActionTween.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\2d\action\Animation.cpp" /> |     <ClCompile Include="..\src\kiwano\2d\action\Animation.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\2d\Canvas.cpp" /> |     <ClCompile Include="..\src\kiwano\2d\Canvas.cpp" /> | ||||||
|  | @ -120,6 +125,7 @@ | ||||||
|     <ClCompile Include="..\src\kiwano\renderer\D2DDeviceResources.cpp" /> |     <ClCompile Include="..\src\kiwano\renderer\D2DDeviceResources.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\renderer\D3D10DeviceResources.cpp" /> |     <ClCompile Include="..\src\kiwano\renderer\D3D10DeviceResources.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\renderer\D3D11DeviceResources.cpp" /> |     <ClCompile Include="..\src\kiwano\renderer\D3D11DeviceResources.cpp" /> | ||||||
|  |     <ClCompile Include="..\src\kiwano\renderer\Geometry.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\renderer\GifImage.cpp" /> |     <ClCompile Include="..\src\kiwano\renderer\GifImage.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\renderer\Image.cpp" /> |     <ClCompile Include="..\src\kiwano\renderer\Image.cpp" /> | ||||||
|     <ClCompile Include="..\src\kiwano\renderer\ImageCache.cpp" /> |     <ClCompile Include="..\src\kiwano\renderer\ImageCache.cpp" /> | ||||||
|  |  | ||||||
|  | @ -279,6 +279,15 @@ | ||||||
|     <ClInclude Include="..\src\kiwano\2d\ShapeActor.h"> |     <ClInclude Include="..\src\kiwano\2d\ShapeActor.h"> | ||||||
|       <Filter>2d</Filter> |       <Filter>2d</Filter> | ||||||
|     </ClInclude> |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\kiwano\renderer\Geometry.h"> | ||||||
|  |       <Filter>renderer</Filter> | ||||||
|  |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\kiwano\2d\action\ActionDelay.h"> | ||||||
|  |       <Filter>2d\action</Filter> | ||||||
|  |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\src\kiwano\2d\action\ActionWalk.h"> | ||||||
|  |       <Filter>2d\action</Filter> | ||||||
|  |     </ClInclude> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <ClCompile Include="..\src\kiwano\ui\Button.cpp"> |     <ClCompile Include="..\src\kiwano\ui\Button.cpp"> | ||||||
|  | @ -425,5 +434,14 @@ | ||||||
|     <ClCompile Include="..\src\kiwano\2d\ShapeActor.cpp"> |     <ClCompile Include="..\src\kiwano\2d\ShapeActor.cpp"> | ||||||
|       <Filter>2d</Filter> |       <Filter>2d</Filter> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|  |     <ClCompile Include="..\src\kiwano\renderer\Geometry.cpp"> | ||||||
|  |       <Filter>renderer</Filter> | ||||||
|  |     </ClCompile> | ||||||
|  |     <ClCompile Include="..\src\kiwano\2d\action\ActionDelay.cpp"> | ||||||
|  |       <Filter>2d\action</Filter> | ||||||
|  |     </ClCompile> | ||||||
|  |     <ClCompile Include="..\src\kiwano\2d\action\ActionWalk.cpp"> | ||||||
|  |       <Filter>2d\action</Filter> | ||||||
|  |     </ClCompile> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
| </Project> | </Project> | ||||||
|  | @ -20,6 +20,7 @@ | ||||||
| 
 | 
 | ||||||
| #include "ShapeActor.h" | #include "ShapeActor.h" | ||||||
| #include "../base/logs.h" | #include "../base/logs.h" | ||||||
|  | #include "../renderer/render.h" | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
|  | @ -31,7 +32,7 @@ namespace kiwano | ||||||
| 	{ | 	{ | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	ShapeActor::ShapeActor(ComPtr<ID2D1Geometry> geometry) | 	ShapeActor::ShapeActor(Geometry geometry) | ||||||
| 		: ShapeActor() | 		: ShapeActor() | ||||||
| 	{ | 	{ | ||||||
| 		SetGeometry(geometry); | 		SetGeometry(geometry); | ||||||
|  | @ -46,10 +47,7 @@ namespace kiwano | ||||||
| 		if (!geo_) | 		if (!geo_) | ||||||
| 			return Rect{}; | 			return Rect{}; | ||||||
| 
 | 
 | ||||||
| 		D2D1_RECT_F rect; | 		return geo_.GetBoundingBox(Matrix()); | ||||||
| 		// no matter it failed or not
 |  | ||||||
| 		geo_->GetBounds(D2D1::Matrix3x2F::Identity(), &rect); |  | ||||||
| 		return Rect{ rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top }; |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	Rect ShapeActor::GetBoundingBox() const | 	Rect ShapeActor::GetBoundingBox() const | ||||||
|  | @ -57,63 +55,7 @@ namespace kiwano | ||||||
| 		if (!geo_) | 		if (!geo_) | ||||||
| 			return Rect{}; | 			return Rect{}; | ||||||
| 
 | 
 | ||||||
| 		D2D1_RECT_F rect; | 		return geo_.GetBoundingBox(GetTransformMatrix()); | ||||||
| 		// no matter it failed or not
 |  | ||||||
| 		geo_->GetBounds(DX::ConvertToMatrix3x2F(transform_matrix_), &rect); |  | ||||||
| 		return Rect{ rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top }; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	float ShapeActor::GetLength() |  | ||||||
| 	{ |  | ||||||
| 		float length = 0.f; |  | ||||||
| 		if (geo_) |  | ||||||
| 		{ |  | ||||||
| 			// no matter it failed or not
 |  | ||||||
| 			geo_->ComputeLength(D2D1::Matrix3x2F::Identity(), &length); |  | ||||||
| 		} |  | ||||||
| 		return length; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	bool ShapeActor::ComputePointAtLength(float length, Point& point, Vec2& tangent) |  | ||||||
| 	{ |  | ||||||
| 		if (geo_) |  | ||||||
| 		{ |  | ||||||
| 			if (SUCCEEDED(geo_->ComputePointAtLength( |  | ||||||
| 				length, |  | ||||||
| 				D2D1::Matrix3x2F::Identity(), |  | ||||||
| 				DX::ConvertToPoint2F(&point), |  | ||||||
| 				DX::ConvertToPoint2F(&tangent)))) |  | ||||||
| 			{ |  | ||||||
| 				return true; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		return false; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	float ShapeActor::ComputeArea() |  | ||||||
| 	{ |  | ||||||
| 		if (!geo_) |  | ||||||
| 			return 0.f; |  | ||||||
| 
 |  | ||||||
| 		float area = 0.f; |  | ||||||
| 		// no matter it failed or not
 |  | ||||||
| 		geo_->ComputeArea(D2D1::Matrix3x2F::Identity(), &area); |  | ||||||
| 		return area; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	bool ShapeActor::ContainsPoint(Point const& point) |  | ||||||
| 	{ |  | ||||||
| 		if (!geo_) |  | ||||||
| 			return false; |  | ||||||
| 
 |  | ||||||
| 		BOOL ret = 0; |  | ||||||
| 		// no matter it failed or not
 |  | ||||||
| 		geo_->FillContainsPoint( |  | ||||||
| 			DX::ConvertToPoint2F(point), |  | ||||||
| 			D2D1::Matrix3x2F::Identity(), |  | ||||||
| 			&ret |  | ||||||
| 		); |  | ||||||
| 		return !!ret; |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void ShapeActor::SetFillColor(const Color & color) | 	void ShapeActor::SetFillColor(const Color & color) | ||||||
|  | @ -164,49 +106,23 @@ namespace kiwano | ||||||
| 	{ | 	{ | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	LineActor::LineActor(Point const& begin, Point const& end) | 	LineActor::LineActor(Point const& end) | ||||||
| 	{ | 	{ | ||||||
| 		SetLine(begin, end); | 		SetEndPoint(end); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	LineActor::~LineActor() | 	LineActor::~LineActor() | ||||||
| 	{ | 	{ | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void LineActor::SetLine(Point const& begin, Point const& end) | 	void LineActor::SetEndPoint(Point const& end) | ||||||
| 	{ | 	{ | ||||||
| 		ComPtr<ID2D1PathGeometry> path_geo; | 		Renderer::GetInstance()->CreateLineGeometry(geo_, Point{}, end); | ||||||
| 		ComPtr<ID2D1GeometrySink> path_sink; |  | ||||||
| 
 | 
 | ||||||
| 		HRESULT hr = Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory()->CreatePathGeometry(&path_geo); | 		if (geo_) | ||||||
| 
 |  | ||||||
| 		if (SUCCEEDED(hr)) |  | ||||||
| 		{ | 		{ | ||||||
| 			hr = path_geo->Open(&path_sink); | 			SetSize(end); | ||||||
| 		} | 		} | ||||||
| 
 |  | ||||||
| 		if (SUCCEEDED(hr)) |  | ||||||
| 		{ |  | ||||||
| 			path_sink->BeginFigure(DX::ConvertToPoint2F(begin), D2D1_FIGURE_BEGIN_FILLED); |  | ||||||
| 			path_sink->AddLine(DX::ConvertToPoint2F(end)); |  | ||||||
| 			path_sink->EndFigure(D2D1_FIGURE_END_OPEN); |  | ||||||
| 			hr = path_sink->Close(); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (SUCCEEDED(hr)) |  | ||||||
| 		{ |  | ||||||
| 			geo_ = path_geo; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void LineActor::SetBegin(Point const& begin) |  | ||||||
| 	{ |  | ||||||
| 		SetLine(begin, end_); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void LineActor::SetEnd(Point const& end) |  | ||||||
| 	{ |  | ||||||
| 		SetLine(begin_, end); |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -218,29 +134,22 @@ namespace kiwano | ||||||
| 	{ | 	{ | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	RectActor::RectActor(Rect const& rect) | 	RectActor::RectActor(Size const& size) | ||||||
| 	{ | 	{ | ||||||
| 		SetRect(rect); | 		SetRectSize(size); | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	RectActor::RectActor(Point const& left_top, Size const& size) |  | ||||||
| 	{ |  | ||||||
| 		SetRect(Rect{ left_top, size }); |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	RectActor::~RectActor() | 	RectActor::~RectActor() | ||||||
| 	{ | 	{ | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void RectActor::SetRect(Rect const& rect) | 	void RectActor::SetRectSize(Size const& size) | ||||||
| 	{ | 	{ | ||||||
| 		ComPtr<ID2D1RectangleGeometry> geo; | 		Renderer::GetInstance()->CreateRectGeometry(geo_, Rect{ Point{}, size }); | ||||||
| 		auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory(); |  | ||||||
| 
 | 
 | ||||||
| 		if (SUCCEEDED(factory->CreateRectangleGeometry(DX::ConvertToRectF(rect), &geo))) | 		if (geo_) | ||||||
| 		{ | 		{ | ||||||
| 			geo_ = geo; | 			SetSize(size); | ||||||
| 			rect_ = rect; |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -250,47 +159,35 @@ namespace kiwano | ||||||
| 	//-------------------------------------------------------
 | 	//-------------------------------------------------------
 | ||||||
| 
 | 
 | ||||||
| 	RoundRectActor::RoundRectActor() | 	RoundRectActor::RoundRectActor() | ||||||
| 		: radius_x_(0.f) |  | ||||||
| 		, radius_y_(0.f) |  | ||||||
| 	{ | 	{ | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	RoundRectActor::RoundRectActor(Rect const& rect, float radius_x, float radius_y) | 	RoundRectActor::RoundRectActor(Size const& size, Vec2 const& radius) | ||||||
| 	{ | 	{ | ||||||
| 		SetRoundedRect(rect, radius_x, radius_y); | 		SetRoundedRect(size, radius); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	RoundRectActor::~RoundRectActor() | 	RoundRectActor::~RoundRectActor() | ||||||
| 	{ | 	{ | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void RoundRectActor::SetRadius(float radius_x, float radius_y) | 	void RoundRectActor::SetRadius(Vec2 const& radius) | ||||||
| 	{ | 	{ | ||||||
| 		SetRoundedRect(rect_, radius_x, radius_y); | 		SetRoundedRect(size_, radius); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void RoundRectActor::SetRect(Rect const& rect) | 	void RoundRectActor::SetRectSize(Size const& size) | ||||||
| 	{ | 	{ | ||||||
| 		SetRoundedRect(rect, radius_x_, radius_y_); | 		SetRoundedRect(size, radius_); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void RoundRectActor::SetRoundedRect(Rect const& rect, float radius_x, float radius_y) | 	void RoundRectActor::SetRoundedRect(Size const& size, Vec2 const& radius) | ||||||
| 	{ | 	{ | ||||||
| 		ComPtr<ID2D1RoundedRectangleGeometry> geo; | 		Renderer::GetInstance()->CreateRoundedRectGeometry(geo_, Rect{ Point{}, size }, radius); | ||||||
| 		auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory(); |  | ||||||
| 
 | 
 | ||||||
| 		if (SUCCEEDED(factory->CreateRoundedRectangleGeometry( | 		if (geo_) | ||||||
| 			D2D1::RoundedRect( |  | ||||||
| 				DX::ConvertToRectF(rect), |  | ||||||
| 				radius_x, |  | ||||||
| 				radius_y |  | ||||||
| 			), |  | ||||||
| 			&geo))) |  | ||||||
| 		{ | 		{ | ||||||
| 			geo_ = geo; | 			SetSize(size); | ||||||
| 			rect_ = rect; |  | ||||||
| 			radius_x_ = radius_x; |  | ||||||
| 			radius_y_ = radius_y; |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -304,9 +201,9 @@ namespace kiwano | ||||||
| 	{ | 	{ | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	CircleActor::CircleActor(Point const& center, float radius) | 	CircleActor::CircleActor(float radius) | ||||||
| 	{ | 	{ | ||||||
| 		SetCircle(center, radius); | 		SetRadius(radius); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	CircleActor::~CircleActor() | 	CircleActor::~CircleActor() | ||||||
|  | @ -315,29 +212,11 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 	void CircleActor::SetRadius(float radius) | 	void CircleActor::SetRadius(float radius) | ||||||
| 	{ | 	{ | ||||||
| 		SetCircle(center_, radius); | 		Renderer::GetInstance()->CreateEllipseGeometry(geo_, Point{}, Vec2{ radius, radius }); | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	void CircleActor::SetCenter(Point const& center) | 		if (geo_) | ||||||
| 		{ | 		{ | ||||||
| 		SetCircle(center, radius_); | 			SetSize(radius * 2, radius * 2); | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void CircleActor::SetCircle(Point const& center, float radius) |  | ||||||
| 	{ |  | ||||||
| 		ComPtr<ID2D1EllipseGeometry> geo; |  | ||||||
| 		auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory(); |  | ||||||
| 
 |  | ||||||
| 		if (SUCCEEDED(factory->CreateEllipseGeometry( |  | ||||||
| 			D2D1::Ellipse( |  | ||||||
| 				DX::ConvertToPoint2F(center), |  | ||||||
| 				radius, |  | ||||||
| 				radius), |  | ||||||
| 			&geo))) |  | ||||||
| 		{ |  | ||||||
| 			geo_ = geo; |  | ||||||
| 			center_ = center; |  | ||||||
| 			radius_ = radius; |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -347,45 +226,25 @@ namespace kiwano | ||||||
| 	//-------------------------------------------------------
 | 	//-------------------------------------------------------
 | ||||||
| 
 | 
 | ||||||
| 	EllipseActor::EllipseActor() | 	EllipseActor::EllipseActor() | ||||||
| 		: radius_x_(0.f) |  | ||||||
| 		, radius_y_(0.f) |  | ||||||
| 	{ | 	{ | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	EllipseActor::EllipseActor(Point const& center, float radius_x, float radius_y) | 	EllipseActor::EllipseActor(Vec2 const& radius) | ||||||
| 	{ | 	{ | ||||||
| 		SetEllipse(center, radius_x, radius_y); | 		SetRadius(radius); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	EllipseActor::~EllipseActor() | 	EllipseActor::~EllipseActor() | ||||||
| 	{ | 	{ | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void EllipseActor::SetRadius(float radius_x, float radius_y) | 	void EllipseActor::SetRadius(Vec2 const& radius) | ||||||
| 	{ | 	{ | ||||||
| 		SetEllipse(center_, radius_x, radius_y); | 		Renderer::GetInstance()->CreateEllipseGeometry(geo_, Point{}, radius); | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	void EllipseActor::SetCenter(Point const& center) | 		if (geo_) | ||||||
| 		{ | 		{ | ||||||
| 		SetEllipse(center, radius_x_, radius_y_); | 			SetSize(radius * 2); | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void EllipseActor::SetEllipse(Point const& center, float radius_x, float radius_y) |  | ||||||
| 	{ |  | ||||||
| 		ComPtr<ID2D1EllipseGeometry> geo; |  | ||||||
| 		auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory(); |  | ||||||
| 
 |  | ||||||
| 		if (SUCCEEDED(factory->CreateEllipseGeometry( |  | ||||||
| 			D2D1::Ellipse( |  | ||||||
| 				DX::ConvertToPoint2F(center), |  | ||||||
| 				radius_x, |  | ||||||
| 				radius_y), |  | ||||||
| 			&geo))) |  | ||||||
| 		{ |  | ||||||
| 			geo_ = geo; |  | ||||||
| 			radius_x_ = radius_x; |  | ||||||
| 			radius_y_ = radius_y; |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -404,89 +263,38 @@ namespace kiwano | ||||||
| 
 | 
 | ||||||
| 	void PathActor::BeginPath(Point const& begin_pos) | 	void PathActor::BeginPath(Point const& begin_pos) | ||||||
| 	{ | 	{ | ||||||
| 		current_geometry_ = nullptr; | 		sink_.BeginPath(begin_pos); | ||||||
| 
 |  | ||||||
| 		auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory(); |  | ||||||
| 
 |  | ||||||
| 		ThrowIfFailed( |  | ||||||
| 			factory->CreatePathGeometry(¤t_geometry_) |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		ThrowIfFailed( |  | ||||||
| 			current_geometry_->Open(¤t_sink_) |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		current_sink_->BeginFigure(DX::ConvertToPoint2F(begin_pos), D2D1_FIGURE_BEGIN_FILLED); |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void PathActor::EndPath(bool closed) | 	void PathActor::EndPath(bool closed) | ||||||
| 	{ | 	{ | ||||||
| 		if (current_sink_) | 		sink_.EndPath(closed); | ||||||
| 		{ | 		geo_ = sink_.GetGeometry(); | ||||||
| 			current_sink_->EndFigure(closed ? D2D1_FIGURE_END_CLOSED : D2D1_FIGURE_END_OPEN); |  | ||||||
| 			ThrowIfFailed( |  | ||||||
| 				current_sink_->Close() |  | ||||||
| 			); |  | ||||||
| 
 |  | ||||||
| 			geo_ = current_geometry_; |  | ||||||
| 
 |  | ||||||
| 			current_sink_ = nullptr; |  | ||||||
| 			current_geometry_ = nullptr; |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void PathActor::AddLine(Point const& point) | 	void PathActor::AddLine(Point const& point) | ||||||
| 	{ | 	{ | ||||||
| 		if (current_sink_) | 		sink_.AddLine(point); | ||||||
| 			current_sink_->AddLine(DX::ConvertToPoint2F(point)); |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void PathActor::AddLines(Vector<Point> const& points) | 	void PathActor::AddLines(Vector<Point> const& points) | ||||||
| 	{ | 	{ | ||||||
| 		if (current_sink_ && !points.empty()) | 		sink_.AddLines(points); | ||||||
| 		{ |  | ||||||
| 			current_sink_->AddLines( |  | ||||||
| 				reinterpret_cast<const D2D_POINT_2F*>(&points[0]), |  | ||||||
| 				static_cast<UINT32>(points.size()) |  | ||||||
| 			); |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void PathActor::AddBezier(Point const& point1, Point const& point2, Point const& point3) | 	void PathActor::AddBezier(Point const& point1, Point const& point2, Point const& point3) | ||||||
| 	{ | 	{ | ||||||
| 		if (current_sink_) | 		sink_.AddBezier(point1, point2, point3); | ||||||
| 		{ |  | ||||||
| 			current_sink_->AddBezier( |  | ||||||
| 				D2D1::BezierSegment( |  | ||||||
| 					DX::ConvertToPoint2F(point1), |  | ||||||
| 					DX::ConvertToPoint2F(point2), |  | ||||||
| 					DX::ConvertToPoint2F(point3) |  | ||||||
| 				) |  | ||||||
| 			); |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void PathActor::AddArc(Point const& point, Size const& radius, float rotation, bool clockwise, bool is_small) | 	void PathActor::AddArc(Point const& point, Size const& radius, float rotation, bool clockwise, bool is_small) | ||||||
| 	{ | 	{ | ||||||
| 		if (current_sink_) | 		sink_.AddArc(point, radius, rotation, clockwise, is_small); | ||||||
| 		{ |  | ||||||
| 			current_sink_->AddArc( |  | ||||||
| 				D2D1::ArcSegment( |  | ||||||
| 					DX::ConvertToPoint2F(point), |  | ||||||
| 					DX::ConvertToSizeF(radius), |  | ||||||
| 					rotation, |  | ||||||
| 					clockwise ? D2D1_SWEEP_DIRECTION_CLOCKWISE : D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE, |  | ||||||
| 					is_small ? D2D1_ARC_SIZE_SMALL : D2D1_ARC_SIZE_LARGE |  | ||||||
| 				) |  | ||||||
| 			); |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void PathActor::ClearPath() | 	void PathActor::ClearPath() | ||||||
| 	{ | 	{ | ||||||
| 		geo_ = nullptr; | 		geo_.SetGeometry(nullptr); | ||||||
| 		current_sink_ = nullptr; |  | ||||||
| 		current_geometry_ = nullptr; |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -20,7 +20,7 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include "Actor.h" | #include "Actor.h" | ||||||
| #include "../renderer/render.h"  // ID2D1Geometry | #include "../renderer/Geometry.h" | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
|  | @ -32,7 +32,7 @@ namespace kiwano | ||||||
| 		ShapeActor(); | 		ShapeActor(); | ||||||
| 
 | 
 | ||||||
| 		ShapeActor( | 		ShapeActor( | ||||||
| 			ComPtr<ID2D1Geometry> geometry | 			Geometry geometry | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		virtual ~ShapeActor(); | 		virtual ~ShapeActor(); | ||||||
|  | @ -55,24 +55,6 @@ namespace kiwano | ||||||
| 		// 삿혤棍학관鍋분
 | 		// 삿혤棍학관鍋분
 | ||||||
| 		Rect GetBoundingBox() const override; | 		Rect GetBoundingBox() const override; | ||||||
| 
 | 
 | ||||||
| 		// 判断图形是否包含点
 |  | ||||||
| 		bool ContainsPoint( |  | ||||||
| 			Point const& point |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		// 获取图形展开成一条直线的长度
 |  | ||||||
| 		float GetLength(); |  | ||||||
| 
 |  | ||||||
| 		// 计算面积
 |  | ||||||
| 		float ComputeArea(); |  | ||||||
| 
 |  | ||||||
| 		// 计算图形路径上点的位置和切线向量
 |  | ||||||
| 		bool ComputePointAtLength( |  | ||||||
| 			float length, |  | ||||||
| 			Point& point, |  | ||||||
| 			Vec2& tangent |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		// <20>零輕념奈<EB8590>
 | 		// <20>零輕념奈<EB8590>
 | ||||||
| 		void SetFillColor( | 		void SetFillColor( | ||||||
| 			const Color& color | 			const Color& color | ||||||
|  | @ -94,10 +76,10 @@ namespace kiwano | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		// <20>零近榴
 | 		// <20>零近榴
 | ||||||
| 		inline void SetGeometry(ComPtr<ID2D1Geometry> geometry)	{ geo_ = geometry; } | 		inline void SetGeometry(Geometry geometry)	{ geo_ = geometry; } | ||||||
| 
 | 
 | ||||||
| 		// 삿혤近榴
 | 		// 삿혤近榴
 | ||||||
| 		inline ComPtr<ID2D1Geometry> GetGeometry() const		{ return geo_; } | 		inline Geometry GetGeometry() const			{ return geo_; } | ||||||
| 
 | 
 | ||||||
| 		void OnRender(Renderer* renderer) override; | 		void OnRender(Renderer* renderer) override; | ||||||
| 
 | 
 | ||||||
|  | @ -106,7 +88,7 @@ namespace kiwano | ||||||
| 		Color		stroke_color_; | 		Color		stroke_color_; | ||||||
| 		float		stroke_width_; | 		float		stroke_width_; | ||||||
| 		StrokeStyle	outline_join_; | 		StrokeStyle	outline_join_; | ||||||
| 		ComPtr<ID2D1Geometry>	geo_; | 		Geometry	geo_; | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -118,31 +100,18 @@ namespace kiwano | ||||||
| 		LineActor(); | 		LineActor(); | ||||||
| 
 | 
 | ||||||
| 		LineActor( | 		LineActor( | ||||||
| 			Point const& begin, | 			Point const& end_pos | ||||||
| 			Point const& end |  | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		virtual ~LineActor(); | 		virtual ~LineActor(); | ||||||
| 
 | 
 | ||||||
| 		Point const& GetBegin() const { return begin_; } | 		Point const& GetEndPoint() const { return end_; } | ||||||
| 
 | 
 | ||||||
| 		Point const& GetEnd() const { return end_; } | 		void SetEndPoint( | ||||||
| 
 |  | ||||||
| 		void SetLine( |  | ||||||
| 			Point const& begin, |  | ||||||
| 			Point const& end |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		void SetBegin( |  | ||||||
| 			Point const& begin |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		void SetEnd( |  | ||||||
| 			Point const& end | 			Point const& end | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 	protected: | 	protected: | ||||||
| 		Point begin_; |  | ||||||
| 		Point end_; | 		Point end_; | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
|  | @ -155,22 +124,17 @@ namespace kiwano | ||||||
| 		RectActor(); | 		RectActor(); | ||||||
| 
 | 
 | ||||||
| 		RectActor( | 		RectActor( | ||||||
| 			Rect const& rect |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		RectActor( |  | ||||||
| 			Point const& left_top, |  | ||||||
| 			Size const& size | 			Size const& size | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		virtual ~RectActor(); | 		virtual ~RectActor(); | ||||||
| 
 | 
 | ||||||
| 		Rect const& GetRect() const { return rect_; } | 		void SetRectSize(Size const& size); | ||||||
| 
 | 
 | ||||||
| 		void SetRect(Rect const& rect); | 		inline Size const& GetRectSize() const { return size_; } | ||||||
| 
 | 
 | ||||||
| 	protected: | 	protected: | ||||||
| 		Rect rect_; | 		Size size_; | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -182,38 +146,32 @@ namespace kiwano | ||||||
| 		RoundRectActor(); | 		RoundRectActor(); | ||||||
| 
 | 
 | ||||||
| 		RoundRectActor( | 		RoundRectActor( | ||||||
| 			Rect const& rect, | 			Size const& size, | ||||||
| 			float radius_x, | 			Vec2 const& radius | ||||||
| 			float radius_y |  | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		virtual ~RoundRectActor(); | 		virtual ~RoundRectActor(); | ||||||
| 
 | 
 | ||||||
| 		float GetRadiusX() const { return radius_x_; } |  | ||||||
| 
 |  | ||||||
| 		float GetRadiusY() const { return radius_y_; } |  | ||||||
| 
 |  | ||||||
| 		void SetRadius( | 		void SetRadius( | ||||||
| 			float radius_x, | 			Vec2 const& radius | ||||||
| 			float radius_y |  | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		Rect const& GetRect() const { return rect_; } | 		void SetRectSize( | ||||||
| 
 | 			Size const& size | ||||||
| 		void SetRect( |  | ||||||
| 			Rect const& rect |  | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		void SetRoundedRect( | 		void SetRoundedRect( | ||||||
| 			Rect const& rect, | 			Size const& size, | ||||||
| 			float radius_x, | 			Vec2 const& radius | ||||||
| 			float radius_y |  | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
|  | 		inline Vec2 GetRadius() const	{ return radius_; } | ||||||
|  | 
 | ||||||
|  | 		inline Size GetRectSize() const	{ return size_; } | ||||||
|  | 
 | ||||||
| 	protected: | 	protected: | ||||||
| 		Rect	rect_; | 		Size size_; | ||||||
| 		float	radius_x_; | 		Vec2 radius_; | ||||||
| 		float	radius_y_; |  | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -225,31 +183,16 @@ namespace kiwano | ||||||
| 		CircleActor(); | 		CircleActor(); | ||||||
| 
 | 
 | ||||||
| 		CircleActor( | 		CircleActor( | ||||||
| 			Point const& center, |  | ||||||
| 			float radius | 			float radius | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		virtual ~CircleActor(); | 		virtual ~CircleActor(); | ||||||
| 
 | 
 | ||||||
| 		float GetRadius() const { return radius_; } | 		inline float GetRadius() const { return radius_; } | ||||||
| 
 | 
 | ||||||
| 		void SetRadius( | 		void SetRadius(float radius); | ||||||
| 			float radius |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		Point const& GetCenter() const { return center_; } |  | ||||||
| 
 |  | ||||||
| 		void SetCenter( |  | ||||||
| 			Point const& center |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		void SetCircle( |  | ||||||
| 			Point const& center, |  | ||||||
| 			float radius |  | ||||||
| 		); |  | ||||||
| 
 | 
 | ||||||
| 	protected: | 	protected: | ||||||
| 		Point center_; |  | ||||||
| 		float radius_; | 		float radius_; | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
|  | @ -262,38 +205,19 @@ namespace kiwano | ||||||
| 		EllipseActor(); | 		EllipseActor(); | ||||||
| 
 | 
 | ||||||
| 		EllipseActor( | 		EllipseActor( | ||||||
| 			Point const& center, | 			Vec2 const& radius | ||||||
| 			float radius_x, |  | ||||||
| 			float radius_y |  | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		virtual ~EllipseActor(); | 		virtual ~EllipseActor(); | ||||||
| 
 | 
 | ||||||
| 		float GetRadiusX() const { return radius_x_; } | 		Vec2 GetRadius() const { return radius_; } | ||||||
| 
 |  | ||||||
| 		float GetRadiusY() const { return radius_y_; } |  | ||||||
| 
 | 
 | ||||||
| 		void SetRadius( | 		void SetRadius( | ||||||
| 			float radius_x, | 			Vec2 const& radius | ||||||
| 			float radius_y |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		Point const& GetCenter() const { return center_; } |  | ||||||
| 
 |  | ||||||
| 		void SetCenter( |  | ||||||
| 			Point const& center |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		void SetEllipse( |  | ||||||
| 			Point const& center, |  | ||||||
| 			float radius_x, |  | ||||||
| 			float radius_y |  | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 	protected: | 	protected: | ||||||
| 		Point center_; | 		Vec2 radius_; | ||||||
| 		float radius_x_; |  | ||||||
| 		float radius_y_; |  | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -346,8 +270,7 @@ namespace kiwano | ||||||
| 		void ClearPath(); | 		void ClearPath(); | ||||||
| 
 | 
 | ||||||
| 	protected: | 	protected: | ||||||
| 		ComPtr<ID2D1PathGeometry>	current_geometry_; | 		GeometrySink sink_; | ||||||
| 		ComPtr<ID2D1GeometrySink>	current_sink_; |  | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -88,6 +88,7 @@ namespace kiwano | ||||||
| 		if (frame_ && renderer->CheckVisibility(size_, transform_matrix_)) | 		if (frame_ && renderer->CheckVisibility(size_, transform_matrix_)) | ||||||
| 		{ | 		{ | ||||||
| 			PrepareRender(renderer); | 			PrepareRender(renderer); | ||||||
|  | 
 | ||||||
| 			renderer->DrawBitmap(frame_->GetImage()->GetBitmap(), frame_->GetCropRect(), GetBounds()); | 			renderer->DrawBitmap(frame_->GetImage()->GetBitmap(), frame_->GetCropRect(), GetBounds()); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -0,0 +1,40 @@ | ||||||
|  | // Copyright (c) 2016-2018 Kiwano - 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 "ActionDelay.h" | ||||||
|  | 
 | ||||||
|  | namespace kiwano | ||||||
|  | { | ||||||
|  | 	ActionDelay::ActionDelay(Duration delay) | ||||||
|  | 	{ | ||||||
|  | 		SetDelay(delay); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ActionPtr ActionDelay::Clone() const | ||||||
|  | 	{ | ||||||
|  | 		return new ActionDelay(delay_); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ActionPtr ActionDelay::Reverse() const | ||||||
|  | 	{ | ||||||
|  | 		return new ActionDelay(delay_); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -0,0 +1,41 @@ | ||||||
|  | // Copyright (c) 2016-2018 Kiwano - 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.
 | ||||||
|  | 
 | ||||||
|  | #pragma once | ||||||
|  | #include "Action.h" | ||||||
|  | 
 | ||||||
|  | namespace kiwano | ||||||
|  | { | ||||||
|  | 	// 延时动作
 | ||||||
|  | 	class KGE_API ActionDelay | ||||||
|  | 		: public Action | ||||||
|  | 	{ | ||||||
|  | 	public: | ||||||
|  | 		ActionDelay( | ||||||
|  | 			Duration delay		/* 持续时长 */ | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		// 获取该动作的拷贝对象
 | ||||||
|  | 		ActionPtr Clone() const override; | ||||||
|  | 
 | ||||||
|  | 		// 获取该动作的倒转
 | ||||||
|  | 		ActionPtr Reverse() const override; | ||||||
|  | 	}; | ||||||
|  | } | ||||||
|  | @ -19,8 +19,10 @@ | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include "ActionGroup.h" |  | ||||||
| #include "ActionTween.h" | #include "ActionTween.h" | ||||||
|  | #include "ActionWalk.h" | ||||||
|  | #include "ActionDelay.h" | ||||||
|  | #include "ActionGroup.h" | ||||||
| #include "Animation.h" | #include "Animation.h" | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
|  | @ -185,6 +187,32 @@ namespace kiwano | ||||||
| 			return TweenHelper(new kiwano::ActionRotateTo(dur, rotation)); | 			return TweenHelper(new kiwano::ActionRotateTo(dur, rotation)); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		static inline TweenHelper | ||||||
|  | 		Walk( | ||||||
|  | 			Duration duration,		/* 持续时长 */ | ||||||
|  | 			Geometry const& geo,	/* 路线 */ | ||||||
|  | 			bool rotating = false,	/* 沿路线切线方向旋转 */ | ||||||
|  | 			float start = 0.f,		/* 起点 */ | ||||||
|  | 			float end = 1.f,		/* 终点 */ | ||||||
|  | 			EaseFunc func = nullptr	/* 速度变化 */ | ||||||
|  | 		) | ||||||
|  | 		{ | ||||||
|  | 			return TweenHelper(new kiwano::ActionWalk(duration, geo, rotating, start, end, func)); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		static inline TweenHelper | ||||||
|  | 		Walk( | ||||||
|  | 			Duration duration,			/* 持续时长 */ | ||||||
|  | 			GeometrySink& sink,			/* 路线生成器 */ | ||||||
|  | 			bool rotating = false,		/* 沿路线切线方向旋转 */ | ||||||
|  | 			float start = 0.f,			/* 起点 */ | ||||||
|  | 			float end = 1.f,			/* 终点 */ | ||||||
|  | 			EaseFunc func = nullptr		/* 速度变化 */ | ||||||
|  | 		) | ||||||
|  | 		{ | ||||||
|  | 			return TweenHelper(new kiwano::ActionWalk(duration, sink.GetGeometry(), rotating, start, end, func)); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		static inline TweenHelper | 		static inline TweenHelper | ||||||
| 		Animation(Duration dur, FrameSequencePtr frames) | 		Animation(Duration dur, FrameSequencePtr frames) | ||||||
| 		{ | 		{ | ||||||
|  |  | ||||||
|  | @ -419,218 +419,6 @@ namespace kiwano | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	//-------------------------------------------------------
 |  | ||||||
| 	// ActionPath
 |  | ||||||
| 	//-------------------------------------------------------
 |  | ||||||
| 
 |  | ||||||
| 	ActionPath::ActionPath(Duration duration, bool rotating, float start, float end, EaseFunc func) |  | ||||||
| 		: ActionTween(duration, func) |  | ||||||
| 		, start_(start) |  | ||||||
| 		, end_(end) |  | ||||||
| 		, rotating_(rotating) |  | ||||||
| 		, path_beginning_(false) |  | ||||||
| 		, geo_(nullptr) |  | ||||||
| 		, geo_sink_(nullptr) |  | ||||||
| 	{ |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	ActionPtr ActionPath::Clone() const |  | ||||||
| 	{ |  | ||||||
| 		ActionPathPtr clone = new ActionPath(dur_, rotating_, start_, end_, ease_func_); |  | ||||||
| 		if (clone) |  | ||||||
| 		{ |  | ||||||
| 			clone->SetGeometry(geo_); |  | ||||||
| 		} |  | ||||||
| 		return clone; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	ActionPtr ActionPath::Reverse() const |  | ||||||
| 	{ |  | ||||||
| 		ActionPathPtr reverse = new ActionPath(dur_, rotating_, end_, start_, ease_func_); |  | ||||||
| 		if (reverse) |  | ||||||
| 		{ |  | ||||||
| 			reverse->SetGeometry(geo_); |  | ||||||
| 		} |  | ||||||
| 		return reverse; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	float ActionPath::GetPathLength() const |  | ||||||
| 	{ |  | ||||||
| 		float length = 0.f; |  | ||||||
| 		if (geo_) |  | ||||||
| 		{ |  | ||||||
| 			// no matter it failed or not
 |  | ||||||
| 			geo_->ComputeLength(D2D1::Matrix3x2F::Identity(), &length); |  | ||||||
| 		} |  | ||||||
| 		return length; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	bool ActionPath::ComputePointAtLength(float length, Point* point, Vec2* tangent) const |  | ||||||
| 	{ |  | ||||||
| 		if (geo_) |  | ||||||
| 		{ |  | ||||||
| 			HRESULT hr = geo_->ComputePointAtLength( |  | ||||||
| 				length, |  | ||||||
| 				D2D1::Matrix3x2F::Identity(), |  | ||||||
| 				DX::ConvertToPoint2F(point), |  | ||||||
| 				DX::ConvertToPoint2F(tangent) |  | ||||||
| 			); |  | ||||||
| 			return SUCCEEDED(hr); |  | ||||||
| 		} |  | ||||||
| 		return false; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void ActionPath::Init(ActorPtr target) |  | ||||||
| 	{ |  | ||||||
| 		start_pos_ = target->GetPosition(); |  | ||||||
| 
 |  | ||||||
| 		if (path_beginning_) |  | ||||||
| 		{ |  | ||||||
| 			EndPath(); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (!geo_) |  | ||||||
| 		{ |  | ||||||
| 			Complete(target); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void ActionPath::UpdateTween(ActorPtr target, float percent) |  | ||||||
| 	{ |  | ||||||
| 		float length = GetPathLength() * std::min(std::max((end_ - start_) * percent + start_, 0.f), 1.f); |  | ||||||
| 
 |  | ||||||
| 		Point point, tangent; |  | ||||||
| 		if (ComputePointAtLength(length, &point, &tangent)) |  | ||||||
| 		{ |  | ||||||
| 			target->SetPosition(start_pos_ + point); |  | ||||||
| 
 |  | ||||||
| 			if (rotating_) |  | ||||||
| 			{ |  | ||||||
| 				float ac = math::Acos(tangent.x); |  | ||||||
| 				float rotation = (tangent.y < 0.f) ? 360.f - ac : ac; |  | ||||||
| 				target->SetRotation(rotation); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void ActionPath::BeginPath() |  | ||||||
| 	{ |  | ||||||
| 		if (path_beginning_) return; |  | ||||||
| 		path_beginning_ = true; |  | ||||||
| 
 |  | ||||||
| 		geo_ = nullptr; |  | ||||||
| 		geo_sink_ = nullptr; |  | ||||||
| 
 |  | ||||||
| 		auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory(); |  | ||||||
| 
 |  | ||||||
| 		ThrowIfFailed( |  | ||||||
| 			factory->CreatePathGeometry(&geo_) |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		ThrowIfFailed( |  | ||||||
| 			geo_->Open(&geo_sink_) |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		geo_sink_->BeginFigure(DX::ConvertToPoint2F(Point{ 0, 0 }), D2D1_FIGURE_BEGIN_FILLED); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void ActionPath::EndPath(bool closed) |  | ||||||
| 	{ |  | ||||||
| 		if (!path_beginning_) return; |  | ||||||
| 		path_beginning_ = false; |  | ||||||
| 
 |  | ||||||
| 		if (geo_sink_) |  | ||||||
| 		{ |  | ||||||
| 			geo_sink_->EndFigure(closed ? D2D1_FIGURE_END_CLOSED : D2D1_FIGURE_END_OPEN); |  | ||||||
| 			ThrowIfFailed( |  | ||||||
| 				geo_sink_->Close() |  | ||||||
| 			); |  | ||||||
| 
 |  | ||||||
| 			// Clear geometry sink
 |  | ||||||
| 			geo_sink_ = nullptr; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void ActionPath::AddLine(Point const& point) |  | ||||||
| 	{ |  | ||||||
| 		if (!path_beginning_) |  | ||||||
| 		{ |  | ||||||
| 			BeginPath(); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (geo_sink_) |  | ||||||
| 		{ |  | ||||||
| 			geo_sink_->AddLine(DX::ConvertToPoint2F(point)); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void ActionPath::AddLines(Vector<Point> const& points) |  | ||||||
| 	{ |  | ||||||
| 		if (!path_beginning_) |  | ||||||
| 		{ |  | ||||||
| 			BeginPath(); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (geo_sink_ && !points.empty()) |  | ||||||
| 		{ |  | ||||||
| 			geo_sink_->AddLines( |  | ||||||
| 				reinterpret_cast<const D2D_POINT_2F*>(&points[0]), |  | ||||||
| 				static_cast<UINT32>(points.size()) |  | ||||||
| 			); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void ActionPath::AddBezier(Point const& point1, Point const& point2, Point const& point3) |  | ||||||
| 	{ |  | ||||||
| 		if (!path_beginning_) |  | ||||||
| 		{ |  | ||||||
| 			BeginPath(); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (geo_sink_) |  | ||||||
| 		{ |  | ||||||
| 			geo_sink_->AddBezier( |  | ||||||
| 				D2D1::BezierSegment( |  | ||||||
| 					DX::ConvertToPoint2F(point1), |  | ||||||
| 					DX::ConvertToPoint2F(point2), |  | ||||||
| 					DX::ConvertToPoint2F(point3) |  | ||||||
| 				) |  | ||||||
| 			); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void ActionPath::AddArc(Point const& point, Size const& radius, float rotation, bool clockwise, bool is_small) |  | ||||||
| 	{ |  | ||||||
| 		if (!path_beginning_) |  | ||||||
| 		{ |  | ||||||
| 			BeginPath(); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (geo_sink_) |  | ||||||
| 		{ |  | ||||||
| 			geo_sink_->AddArc( |  | ||||||
| 				D2D1::ArcSegment( |  | ||||||
| 					DX::ConvertToPoint2F(point), |  | ||||||
| 					DX::ConvertToSizeF(radius), |  | ||||||
| 					rotation, |  | ||||||
| 					clockwise ? D2D1_SWEEP_DIRECTION_CLOCKWISE : D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE, |  | ||||||
| 					is_small ? D2D1_ARC_SIZE_SMALL : D2D1_ARC_SIZE_LARGE |  | ||||||
| 				) |  | ||||||
| 			); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	void ActionPath::ClearPath() |  | ||||||
| 	{ |  | ||||||
| 		if (path_beginning_) |  | ||||||
| 		{ |  | ||||||
| 			EndPath(); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		geo_sink_ = nullptr; |  | ||||||
| 		geo_ = nullptr; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	//-------------------------------------------------------
 | 	//-------------------------------------------------------
 | ||||||
| 	// ActionCustom
 | 	// ActionCustom
 | ||||||
| 	//-------------------------------------------------------
 | 	//-------------------------------------------------------
 | ||||||
|  | @ -658,24 +446,4 @@ namespace kiwano | ||||||
| 			tween_func_(target, percent); | 			tween_func_(target, percent); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 	//-------------------------------------------------------
 |  | ||||||
| 	// ActionDelay
 |  | ||||||
| 	//-------------------------------------------------------
 |  | ||||||
| 
 |  | ||||||
| 	ActionDelay::ActionDelay(Duration delay) |  | ||||||
| 	{ |  | ||||||
| 		SetDelay(delay); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	ActionPtr ActionDelay::Clone() const |  | ||||||
| 	{ |  | ||||||
| 		return new ActionDelay(delay_); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	ActionPtr ActionDelay::Reverse() const |  | ||||||
| 	{ |  | ||||||
| 		return new ActionDelay(delay_); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -21,7 +21,6 @@ | ||||||
| #pragma once | #pragma once | ||||||
| #include "Action.h" | #include "Action.h" | ||||||
| #include "../../base/logs.h" | #include "../../base/logs.h" | ||||||
| #include "../../renderer/render.h"  // ID2D1PathGeometry, ID2D1GeometrySink |  | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
|  | @ -412,91 +411,6 @@ namespace kiwano | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	// 路径动作
 |  | ||||||
| 	class KGE_API ActionPath |  | ||||||
| 		: public ActionTween |  | ||||||
| 	{ |  | ||||||
| 	public: |  | ||||||
| 		ActionPath( |  | ||||||
| 			Duration duration,		/* 持续时长 */ |  | ||||||
| 			bool rotating = false,	/* 沿路径切线方向旋转 */ |  | ||||||
| 			float start = 0.f,		/* 起点 */ |  | ||||||
| 			float end = 1.f,		/* 终点 */ |  | ||||||
| 			EaseFunc func = nullptr	/* 速度变化 */ |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		// 获取该动作的拷贝对象
 |  | ||||||
| 		ActionPtr Clone() const override; |  | ||||||
| 
 |  | ||||||
| 		// 获取该动作的倒转
 |  | ||||||
| 		ActionPtr Reverse() const override; |  | ||||||
| 
 |  | ||||||
| 		// 开始添加路径
 |  | ||||||
| 		void BeginPath(); |  | ||||||
| 
 |  | ||||||
| 		// 结束路径
 |  | ||||||
| 		void EndPath( |  | ||||||
| 			bool closed = false		/* 路径是否闭合 */ |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		// 添加一条线段
 |  | ||||||
| 		void AddLine( |  | ||||||
| 			Point const& point		/* 端点 */ |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		// 添加多条线段
 |  | ||||||
| 		void AddLines( |  | ||||||
| 			Vector<Point> const& points |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		// 添加一条三次方贝塞尔曲线
 |  | ||||||
| 		void AddBezier( |  | ||||||
| 			Point const& point1,	/* 贝塞尔曲线的第一个控制点 */ |  | ||||||
| 			Point const& point2,	/* 贝塞尔曲线的第二个控制点 */ |  | ||||||
| 			Point const& point3		/* 贝塞尔曲线的终点 */ |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		// 添加弧线
 |  | ||||||
| 		void AddArc( |  | ||||||
| 			Point const& point,		/* 终点 */ |  | ||||||
| 			Size const& radius,		/* 椭圆半径 */ |  | ||||||
| 			float rotation,			/* 椭圆旋转角度 */ |  | ||||||
| 			bool clockwise = true,	/* 顺时针 or 逆时针 */ |  | ||||||
| 			bool is_small = true	/* 是否取小于 180° 的弧 */ |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		// 清除路径
 |  | ||||||
| 		void ClearPath(); |  | ||||||
| 
 |  | ||||||
| 		// 获取路径长度
 |  | ||||||
| 		float GetPathLength() const; |  | ||||||
| 
 |  | ||||||
| 		// 计算当前路径上指定点坐标和切线
 |  | ||||||
| 		bool ComputePointAtLength(float length, Point* point, Vec2* tangent) const; |  | ||||||
| 
 |  | ||||||
| 		// 获取几何路径
 |  | ||||||
| 		inline ComPtr<ID2D1PathGeometry> GetGeometry() const	{ return geo_; } |  | ||||||
| 
 |  | ||||||
| 		// 设置几何路径
 |  | ||||||
| 		inline void SetGeometry(ComPtr<ID2D1PathGeometry> geo)	{ geo_ = geo; } |  | ||||||
| 
 |  | ||||||
| 	protected: |  | ||||||
| 		void Init(ActorPtr target) override; |  | ||||||
| 
 |  | ||||||
| 		void UpdateTween(ActorPtr target, float percent) override; |  | ||||||
| 
 |  | ||||||
| 	protected: |  | ||||||
| 		bool	path_beginning_; |  | ||||||
| 		bool	rotating_; |  | ||||||
| 		float	start_; |  | ||||||
| 		float	end_; |  | ||||||
| 		Point	start_pos_; |  | ||||||
| 
 |  | ||||||
| 		ComPtr<ID2D1PathGeometry> geo_; |  | ||||||
| 		ComPtr<ID2D1GeometrySink> geo_sink_; |  | ||||||
| 	}; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 	// 自定义动作
 | 	// 自定义动作
 | ||||||
| 	class KGE_API ActionCustom | 	class KGE_API ActionCustom | ||||||
| 		: public ActionTween | 		: public ActionTween | ||||||
|  | @ -529,20 +443,4 @@ namespace kiwano | ||||||
| 		TweenFunc tween_func_; | 		TweenFunc tween_func_; | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 	// 延时动作
 |  | ||||||
| 	class KGE_API ActionDelay |  | ||||||
| 		: public Action |  | ||||||
| 	{ |  | ||||||
| 	public: |  | ||||||
| 		ActionDelay( |  | ||||||
| 			Duration delay		/* 持续时长 */ |  | ||||||
| 		); |  | ||||||
| 
 |  | ||||||
| 		// 获取该动作的拷贝对象
 |  | ||||||
| 		ActionPtr Clone() const override; |  | ||||||
| 
 |  | ||||||
| 		// 获取该动作的倒转
 |  | ||||||
| 		ActionPtr Reverse() const override; |  | ||||||
| 	}; |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,128 @@ | ||||||
|  | // Copyright (c) 2016-2018 Kiwano - 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 "ActionWalk.h" | ||||||
|  | #include "../Actor.h" | ||||||
|  | 
 | ||||||
|  | namespace kiwano | ||||||
|  | { | ||||||
|  | 	ActionWalk::ActionWalk(Duration duration, bool rotating, float start, float end, EaseFunc func) | ||||||
|  | 		: ActionTween(duration, func) | ||||||
|  | 		, start_(start) | ||||||
|  | 		, end_(end) | ||||||
|  | 		, rotating_(rotating) | ||||||
|  | 		, length_(0.f) | ||||||
|  | 	{ | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ActionWalk::ActionWalk(Duration duration, Geometry const& path, bool rotating, float start, float end, EaseFunc func) | ||||||
|  | 		: ActionWalk(duration, rotating, start, end, func) | ||||||
|  | 	{ | ||||||
|  | 		path_ = path; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ActionPtr ActionWalk::Clone() const | ||||||
|  | 	{ | ||||||
|  | 		ActionWalkPtr clone = new ActionWalk(dur_, rotating_, start_, end_, ease_func_); | ||||||
|  | 		if (clone) | ||||||
|  | 		{ | ||||||
|  | 			clone->SetPath(path_); | ||||||
|  | 		} | ||||||
|  | 		return clone; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ActionPtr ActionWalk::Reverse() const | ||||||
|  | 	{ | ||||||
|  | 		ActionWalkPtr reverse = new ActionWalk(dur_, rotating_, end_, start_, ease_func_); | ||||||
|  | 		if (reverse) | ||||||
|  | 		{ | ||||||
|  | 			reverse->SetPath(path_); | ||||||
|  | 		} | ||||||
|  | 		return reverse; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void ActionWalk::Init(ActorPtr target) | ||||||
|  | 	{ | ||||||
|  | 		if (!path_) | ||||||
|  | 		{ | ||||||
|  | 			Complete(target); | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		start_pos_ = target->GetPosition(); | ||||||
|  | 		length_ = path_.GetLength(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void ActionWalk::UpdateTween(ActorPtr target, float percent) | ||||||
|  | 	{ | ||||||
|  | 		float distance = length_ * std::min(std::max((end_ - start_) * percent + start_, 0.f), 1.f); | ||||||
|  | 
 | ||||||
|  | 		Point point, tangent; | ||||||
|  | 		if (path_.ComputePointAtLength(distance, point, tangent)) | ||||||
|  | 		{ | ||||||
|  | 			target->SetPosition(start_pos_ + point); | ||||||
|  | 
 | ||||||
|  | 			if (rotating_) | ||||||
|  | 			{ | ||||||
|  | 				float ac = math::Acos(tangent.x); | ||||||
|  | 				float rotation = (tangent.y < 0.f) ? 360.f - ac : ac; | ||||||
|  | 				target->SetRotation(rotation); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		KGE_LOG(L"%.2f, %.2f", target->GetPositionX(), target->GetPositionY()); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void ActionWalk::BeginPath() | ||||||
|  | 	{ | ||||||
|  | 		sink_.BeginPath(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void ActionWalk::EndPath(bool closed) | ||||||
|  | 	{ | ||||||
|  | 		sink_.EndPath(closed); | ||||||
|  | 		path_ = sink_.GetGeometry(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void ActionWalk::AddLine(Point const& point) | ||||||
|  | 	{ | ||||||
|  | 		sink_.AddLine(point); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void ActionWalk::AddLines(Vector<Point> const& points) | ||||||
|  | 	{ | ||||||
|  | 		sink_.AddLines(points); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void ActionWalk::AddBezier(Point const& point1, Point const& point2, Point const& point3) | ||||||
|  | 	{ | ||||||
|  | 		sink_.AddBezier(point1, point2, point3); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void ActionWalk::AddArc(Point const& point, Size const& radius, float rotation, bool clockwise, bool is_small) | ||||||
|  | 	{ | ||||||
|  | 		sink_.AddArc(point, radius, rotation, clockwise, is_small); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void ActionWalk::ClearPath() | ||||||
|  | 	{ | ||||||
|  | 		path_.SetGeometry(nullptr); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -0,0 +1,112 @@ | ||||||
|  | // Copyright (c) 2016-2018 Kiwano - 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.
 | ||||||
|  | 
 | ||||||
|  | #pragma once | ||||||
|  | #include "ActionTween.h" | ||||||
|  | #include "../../renderer/Geometry.h"  // Geometry, GeometrySink | ||||||
|  | 
 | ||||||
|  | namespace kiwano | ||||||
|  | { | ||||||
|  | 	// 路线行走动作
 | ||||||
|  | 	class KGE_API ActionWalk | ||||||
|  | 		: public ActionTween | ||||||
|  | 	{ | ||||||
|  | 	public: | ||||||
|  | 		ActionWalk( | ||||||
|  | 			Duration duration,		/* 持续时长 */ | ||||||
|  | 			bool rotating = false,	/* 沿路线切线方向旋转 */ | ||||||
|  | 			float start = 0.f,		/* 起点 */ | ||||||
|  | 			float end = 1.f,		/* 终点 */ | ||||||
|  | 			EaseFunc func = nullptr	/* 速度变化 */ | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		ActionWalk( | ||||||
|  | 			Duration duration,		/* 持续时长 */ | ||||||
|  | 			Geometry const& path,	/* 路线 */ | ||||||
|  | 			bool rotating = false,	/* 沿路线切线方向旋转 */ | ||||||
|  | 			float start = 0.f,		/* 起点 */ | ||||||
|  | 			float end = 1.f,		/* 终点 */ | ||||||
|  | 			EaseFunc func = nullptr	/* 速度变化 */ | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		// 获取该动作的拷贝对象
 | ||||||
|  | 		ActionPtr Clone() const override; | ||||||
|  | 
 | ||||||
|  | 		// 获取该动作的倒转
 | ||||||
|  | 		ActionPtr Reverse() const override; | ||||||
|  | 
 | ||||||
|  | 		// 开始添加路线
 | ||||||
|  | 		void BeginPath(); | ||||||
|  | 
 | ||||||
|  | 		// 结束路线
 | ||||||
|  | 		void EndPath( | ||||||
|  | 			bool closed = false		/* 路线是否闭合 */ | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		// 添加一条线段
 | ||||||
|  | 		void AddLine( | ||||||
|  | 			Point const& point		/* 端点 */ | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		// 添加多条线段
 | ||||||
|  | 		void AddLines( | ||||||
|  | 			Vector<Point> const& points | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		// 添加一条三次方贝塞尔曲线
 | ||||||
|  | 		void AddBezier( | ||||||
|  | 			Point const& point1,	/* 贝塞尔曲线的第一个控制点 */ | ||||||
|  | 			Point const& point2,	/* 贝塞尔曲线的第二个控制点 */ | ||||||
|  | 			Point const& point3		/* 贝塞尔曲线的终点 */ | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		// 添加弧线
 | ||||||
|  | 		void AddArc( | ||||||
|  | 			Point const& point,		/* 终点 */ | ||||||
|  | 			Size const& radius,		/* 椭圆半径 */ | ||||||
|  | 			float rotation,			/* 椭圆旋转角度 */ | ||||||
|  | 			bool clockwise = true,	/* 顺时针 or 逆时针 */ | ||||||
|  | 			bool is_small = true	/* 是否取小于 180° 的弧 */ | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		// 清除路径
 | ||||||
|  | 		void ClearPath(); | ||||||
|  | 
 | ||||||
|  | 		// 获取路线
 | ||||||
|  | 		inline Geometry GetPath() const		{ return path_; } | ||||||
|  | 
 | ||||||
|  | 		// 设置路径
 | ||||||
|  | 		inline void SetPath(Geometry path)	{ path_ = path; } | ||||||
|  | 
 | ||||||
|  | 	protected: | ||||||
|  | 		void Init(ActorPtr target) override; | ||||||
|  | 
 | ||||||
|  | 		void UpdateTween(ActorPtr target, float percent) override; | ||||||
|  | 
 | ||||||
|  | 	protected: | ||||||
|  | 		bool			rotating_; | ||||||
|  | 		float			start_; | ||||||
|  | 		float			end_; | ||||||
|  | 		float			length_; | ||||||
|  | 		Point			start_pos_; | ||||||
|  | 		Geometry		path_; | ||||||
|  | 		GeometrySink	sink_; | ||||||
|  | 	}; | ||||||
|  | } | ||||||
|  | @ -62,7 +62,7 @@ namespace kiwano | ||||||
| 	KGE_DECLARE_SMART_PTR(ActionFadeOut); | 	KGE_DECLARE_SMART_PTR(ActionFadeOut); | ||||||
| 	KGE_DECLARE_SMART_PTR(ActionRotateBy); | 	KGE_DECLARE_SMART_PTR(ActionRotateBy); | ||||||
| 	KGE_DECLARE_SMART_PTR(ActionRotateTo); | 	KGE_DECLARE_SMART_PTR(ActionRotateTo); | ||||||
| 	KGE_DECLARE_SMART_PTR(ActionPath); | 	KGE_DECLARE_SMART_PTR(ActionWalk); | ||||||
| 	KGE_DECLARE_SMART_PTR(Animation); | 	KGE_DECLARE_SMART_PTR(Animation); | ||||||
| 	KGE_DECLARE_SMART_PTR(ActionGroup); | 	KGE_DECLARE_SMART_PTR(ActionGroup); | ||||||
| 	KGE_DECLARE_SMART_PTR(ActionSpawn); | 	KGE_DECLARE_SMART_PTR(ActionSpawn); | ||||||
|  |  | ||||||
|  | @ -92,6 +92,8 @@ | ||||||
| #include "2d/action/Action.h" | #include "2d/action/Action.h" | ||||||
| #include "2d/action/ActionGroup.h" | #include "2d/action/ActionGroup.h" | ||||||
| #include "2d/action/ActionTween.h" | #include "2d/action/ActionTween.h" | ||||||
|  | #include "2d/action/ActionWalk.h" | ||||||
|  | #include "2d/action/ActionDelay.h" | ||||||
| #include "2d/action/Animation.h" | #include "2d/action/Animation.h" | ||||||
| #include "2d/action/ActionHelper.h" | #include "2d/action/ActionHelper.h" | ||||||
| #include "2d/action/ActionManager.h" | #include "2d/action/ActionManager.h" | ||||||
|  |  | ||||||
|  | @ -0,0 +1,203 @@ | ||||||
|  | // Copyright (c) 2016-2018 Kiwano - 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 "Geometry.h" | ||||||
|  | #include "render.h" | ||||||
|  | #include "../base/logs.h" | ||||||
|  | 
 | ||||||
|  | namespace kiwano | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | 	//
 | ||||||
|  | 	// Geometry
 | ||||||
|  | 	//
 | ||||||
|  | 
 | ||||||
|  | 	Geometry::Geometry() | ||||||
|  | 	{ | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	Geometry::Geometry(ComPtr<ID2D1Geometry> geo) | ||||||
|  | 		: geo_(geo) | ||||||
|  | 	{ | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	Rect Geometry::GetBoundingBox(Matrix const& transform) const | ||||||
|  | 	{ | ||||||
|  | 		if (!geo_) | ||||||
|  | 			return Rect{}; | ||||||
|  | 
 | ||||||
|  | 		D2D1_RECT_F rect; | ||||||
|  | 		// no matter it failed or not
 | ||||||
|  | 		geo_->GetBounds(DX::ConvertToMatrix3x2F(transform), &rect); | ||||||
|  | 		return Rect{ rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top }; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	float Geometry::GetLength() | ||||||
|  | 	{ | ||||||
|  | 		float length = 0.f; | ||||||
|  | 		if (geo_) | ||||||
|  | 		{ | ||||||
|  | 			// no matter it failed or not
 | ||||||
|  | 			geo_->ComputeLength(D2D1::Matrix3x2F::Identity(), &length); | ||||||
|  | 		} | ||||||
|  | 		return length; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	bool Geometry::ComputePointAtLength(float length, Point& point, Vec2& tangent) | ||||||
|  | 	{ | ||||||
|  | 		if (geo_) | ||||||
|  | 		{ | ||||||
|  | 			HRESULT hr = geo_->ComputePointAtLength( | ||||||
|  | 				length, | ||||||
|  | 				D2D1::Matrix3x2F::Identity(), | ||||||
|  | 				DX::ConvertToPoint2F(&point), | ||||||
|  | 				DX::ConvertToPoint2F(&tangent) | ||||||
|  | 			); | ||||||
|  | 
 | ||||||
|  | 			return SUCCEEDED(hr); | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	float Geometry::ComputeArea() | ||||||
|  | 	{ | ||||||
|  | 		if (!geo_) | ||||||
|  | 			return 0.f; | ||||||
|  | 
 | ||||||
|  | 		float area = 0.f; | ||||||
|  | 		// no matter it failed or not
 | ||||||
|  | 		geo_->ComputeArea(D2D1::Matrix3x2F::Identity(), &area); | ||||||
|  | 		return area; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	bool Geometry::ContainsPoint(Point const& point) | ||||||
|  | 	{ | ||||||
|  | 		if (!geo_) | ||||||
|  | 			return false; | ||||||
|  | 
 | ||||||
|  | 		BOOL ret = 0; | ||||||
|  | 		// no matter it failed or not
 | ||||||
|  | 		geo_->FillContainsPoint( | ||||||
|  | 			DX::ConvertToPoint2F(point), | ||||||
|  | 			D2D1::Matrix3x2F::Identity(), | ||||||
|  | 			&ret | ||||||
|  | 		); | ||||||
|  | 		return !!ret; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	//
 | ||||||
|  | 	// GeometrySink
 | ||||||
|  | 	//
 | ||||||
|  | 
 | ||||||
|  | 	GeometrySink::GeometrySink() | ||||||
|  | 	{ | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	GeometrySink& GeometrySink::BeginPath(Point const& begin_pos) | ||||||
|  | 	{ | ||||||
|  | 		if (!path_geo_) | ||||||
|  | 		{ | ||||||
|  | 			Renderer::GetInstance()->CreatePathGeometrySink(*this); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (!sink_) | ||||||
|  | 		{ | ||||||
|  | 			ThrowIfFailed(path_geo_->Open(&sink_)); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (sink_) | ||||||
|  | 		{ | ||||||
|  | 			sink_->BeginFigure(DX::ConvertToPoint2F(begin_pos), D2D1_FIGURE_BEGIN_FILLED); | ||||||
|  | 		} | ||||||
|  | 		return (*this); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	GeometrySink& GeometrySink::EndPath(bool closed) | ||||||
|  | 	{ | ||||||
|  | 		if (sink_) | ||||||
|  | 		{ | ||||||
|  | 			sink_->EndFigure(closed ? D2D1_FIGURE_END_CLOSED : D2D1_FIGURE_END_OPEN); | ||||||
|  | 			 | ||||||
|  | 			ThrowIfFailed(sink_->Close()); | ||||||
|  | 
 | ||||||
|  | 			sink_ = nullptr; | ||||||
|  | 		} | ||||||
|  | 		return (*this); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	GeometrySink& GeometrySink::AddLine(Point const& point) | ||||||
|  | 	{ | ||||||
|  | 		if (!sink_) BeginPath(); | ||||||
|  | 
 | ||||||
|  | 		sink_->AddLine(DX::ConvertToPoint2F(point)); | ||||||
|  | 		return (*this); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	GeometrySink& GeometrySink::AddLines(Vector<Point> const& points) | ||||||
|  | 	{ | ||||||
|  | 		if (!sink_) BeginPath(); | ||||||
|  | 		 | ||||||
|  | 		sink_->AddLines( | ||||||
|  | 			reinterpret_cast<const D2D_POINT_2F*>(&points[0]), | ||||||
|  | 			static_cast<UINT32>(points.size()) | ||||||
|  | 		); | ||||||
|  | 		return (*this); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	GeometrySink& GeometrySink::AddBezier(Point const& point1, Point const& point2, Point const& point3) | ||||||
|  | 	{ | ||||||
|  | 		if (!sink_) BeginPath(); | ||||||
|  | 		 | ||||||
|  | 		sink_->AddBezier( | ||||||
|  | 			D2D1::BezierSegment( | ||||||
|  | 				DX::ConvertToPoint2F(point1), | ||||||
|  | 				DX::ConvertToPoint2F(point2), | ||||||
|  | 				DX::ConvertToPoint2F(point3) | ||||||
|  | 			) | ||||||
|  | 		); | ||||||
|  | 		return (*this); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	GeometrySink& GeometrySink::AddArc(Point const& point, Size const& radius, float rotation, bool clockwise, bool is_small) | ||||||
|  | 	{ | ||||||
|  | 		if (!sink_) BeginPath(); | ||||||
|  | 
 | ||||||
|  | 		sink_->AddArc( | ||||||
|  | 			D2D1::ArcSegment( | ||||||
|  | 				DX::ConvertToPoint2F(point), | ||||||
|  | 				DX::ConvertToSizeF(radius), | ||||||
|  | 				rotation, | ||||||
|  | 				clockwise ? D2D1_SWEEP_DIRECTION_CLOCKWISE : D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE, | ||||||
|  | 				is_small ? D2D1_ARC_SIZE_SMALL : D2D1_ARC_SIZE_LARGE | ||||||
|  | 			) | ||||||
|  | 		); | ||||||
|  | 		return (*this); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	Geometry GeometrySink::GetGeometry() | ||||||
|  | 	{ | ||||||
|  | 		if (sink_) | ||||||
|  | 		{ | ||||||
|  | 			EndPath(); | ||||||
|  | 		} | ||||||
|  | 		return Geometry(path_geo_); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -0,0 +1,126 @@ | ||||||
|  | // Copyright (c) 2016-2018 Kiwano - 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.
 | ||||||
|  | 
 | ||||||
|  | #pragma once | ||||||
|  | #include "../base/SmartPtr.hpp" | ||||||
|  | #include "D2DDeviceResources.h" | ||||||
|  | 
 | ||||||
|  | namespace kiwano | ||||||
|  | { | ||||||
|  | 	// 几何体
 | ||||||
|  | 	class KGE_API Geometry | ||||||
|  | 	{ | ||||||
|  | 	public: | ||||||
|  | 		// 获取外切包围盒
 | ||||||
|  | 		Rect GetBoundingBox( | ||||||
|  | 			Matrix const& transform = Matrix() | ||||||
|  | 		) const; | ||||||
|  | 
 | ||||||
|  | 		// 判断图形是否包含点
 | ||||||
|  | 		bool ContainsPoint( | ||||||
|  | 			Point const& point | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		// 获取图形展开成一条直线的长度
 | ||||||
|  | 		float GetLength(); | ||||||
|  | 
 | ||||||
|  | 		// 计算面积
 | ||||||
|  | 		float ComputeArea(); | ||||||
|  | 
 | ||||||
|  | 		// 计算图形路径上点的位置和切线向量
 | ||||||
|  | 		bool ComputePointAtLength( | ||||||
|  | 			float length, | ||||||
|  | 			Point& point, | ||||||
|  | 			Vec2& tangent | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 	public: | ||||||
|  | 		Geometry(); | ||||||
|  | 
 | ||||||
|  | 		Geometry(ComPtr<ID2D1Geometry> geo); | ||||||
|  | 
 | ||||||
|  | 	public: | ||||||
|  | 		inline ComPtr<ID2D1Geometry> GetGeometry() const		{ return geo_; } | ||||||
|  | 
 | ||||||
|  | 		inline void SetGeometry(ComPtr<ID2D1Geometry> geometry)	{ geo_ = geometry; } | ||||||
|  | 
 | ||||||
|  | 		inline operator bool() const							{ return static_cast<bool>(geo_); } | ||||||
|  | 
 | ||||||
|  | 	protected: | ||||||
|  | 		ComPtr<ID2D1Geometry> geo_; | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 	// 几何体生成器
 | ||||||
|  | 	class KGE_API GeometrySink | ||||||
|  | 		: protected noncopyable | ||||||
|  | 	{ | ||||||
|  | 	public: | ||||||
|  | 		GeometrySink(); | ||||||
|  | 
 | ||||||
|  | 		// 开始添加路径
 | ||||||
|  | 		GeometrySink& BeginPath( | ||||||
|  | 			Point const& begin_pos = Point{}	/* 起始点 */ | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		// 结束路径
 | ||||||
|  | 		GeometrySink& EndPath( | ||||||
|  | 			bool closed = false		/* 路径是否闭合 */ | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		// 添加一条线段
 | ||||||
|  | 		GeometrySink& AddLine( | ||||||
|  | 			Point const& point		/* 端点 */ | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		// 添加多条线段
 | ||||||
|  | 		GeometrySink& AddLines( | ||||||
|  | 			Vector<Point> const& points | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		// 添加一条三次方贝塞尔曲线
 | ||||||
|  | 		GeometrySink& AddBezier( | ||||||
|  | 			Point const& point1,	/* 贝塞尔曲线的第一个控制点 */ | ||||||
|  | 			Point const& point2,	/* 贝塞尔曲线的第二个控制点 */ | ||||||
|  | 			Point const& point3		/* 贝塞尔曲线的终点 */ | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		// 添加弧线
 | ||||||
|  | 		GeometrySink& AddArc( | ||||||
|  | 			Point const& point,		/* 终点 */ | ||||||
|  | 			Size const& radius,		/* 椭圆半径 */ | ||||||
|  | 			float rotation,			/* 椭圆旋转角度 */ | ||||||
|  | 			bool clockwise = true,	/* 顺时针 or 逆时针 */ | ||||||
|  | 			bool is_small = true	/* 是否取小于 180° 的弧 */ | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		// 获取生成路径几何体
 | ||||||
|  | 		Geometry GetGeometry(); | ||||||
|  | 
 | ||||||
|  | 	public: | ||||||
|  | 		inline ComPtr<ID2D1PathGeometry> GetPathGeometry() const	{ return path_geo_; } | ||||||
|  | 
 | ||||||
|  | 		inline void SetPathGeometry(ComPtr<ID2D1PathGeometry> path)	{ path_geo_ = path; } | ||||||
|  | 
 | ||||||
|  | 	protected: | ||||||
|  | 		ComPtr<ID2D1PathGeometry> path_geo_; | ||||||
|  | 		ComPtr<ID2D1GeometrySink> sink_; | ||||||
|  | 	}; | ||||||
|  | } | ||||||
|  | @ -20,7 +20,7 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include "../base/Resource.h" | #include "../base/Resource.h" | ||||||
| #include "render.h"  // ID2D1Bitmap | #include "D2DDeviceResources.h"  // ID2D1Bitmap | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -132,13 +132,16 @@ namespace kiwano | ||||||
| 	{ | 	{ | ||||||
| 		HRESULT hr = S_OK; | 		HRESULT hr = S_OK; | ||||||
| 
 | 
 | ||||||
|  | 		solid_color_brush_.reset(); | ||||||
| 		hr = device_context_->CreateSolidColorBrush( | 		hr = device_context_->CreateSolidColorBrush( | ||||||
| 			D2D1::ColorF(D2D1::ColorF::White), | 			D2D1::ColorF(D2D1::ColorF::White), | ||||||
|  | 			D2D1::BrushProperties(), | ||||||
| 			&solid_color_brush_ | 			&solid_color_brush_ | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		if (SUCCEEDED(hr)) | 		if (SUCCEEDED(hr)) | ||||||
| 		{ | 		{ | ||||||
|  | 			text_renderer_.reset(); | ||||||
| 			hr = ITextRenderer::Create( | 			hr = ITextRenderer::Create( | ||||||
| 				&text_renderer_, | 				&text_renderer_, | ||||||
| 				device_context_.get() | 				device_context_.get() | ||||||
|  | @ -242,8 +245,144 @@ namespace kiwano | ||||||
| 		ThrowIfFailed(hr); | 		ThrowIfFailed(hr); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	void Renderer::CreateLineGeometry(Geometry& geo, Point const& begin_pos, Point const& end_pos) | ||||||
|  | 	{ | ||||||
|  | 		HRESULT hr = S_OK; | ||||||
|  | 		if (!device_context_ || !d2d_res_) | ||||||
|  | 		{ | ||||||
|  | 			hr = E_UNEXPECTED; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		ComPtr<ID2D1PathGeometry> path_geo; | ||||||
|  | 		ComPtr<ID2D1GeometrySink> path_sink; | ||||||
|  | 		if (SUCCEEDED(hr)) | ||||||
|  | 		{ | ||||||
|  | 			hr = d2d_res_->GetFactory()->CreatePathGeometry(&path_geo); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (SUCCEEDED(hr)) | ||||||
|  | 		{ | ||||||
|  | 			hr = path_geo->Open(&path_sink); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (SUCCEEDED(hr)) | ||||||
|  | 		{ | ||||||
|  | 			path_sink->BeginFigure(DX::ConvertToPoint2F(begin_pos), D2D1_FIGURE_BEGIN_FILLED); | ||||||
|  | 			path_sink->AddLine(DX::ConvertToPoint2F(end_pos)); | ||||||
|  | 			path_sink->EndFigure(D2D1_FIGURE_END_OPEN); | ||||||
|  | 			hr = path_sink->Close(); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (SUCCEEDED(hr)) | ||||||
|  | 		{ | ||||||
|  | 			geo.SetGeometry(path_geo); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		ThrowIfFailed(hr); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void Renderer::CreateRectGeometry(Geometry& geo, Rect const& rect) | ||||||
|  | 	{ | ||||||
|  | 		HRESULT hr = S_OK; | ||||||
|  | 		if (!device_context_ || !d2d_res_) | ||||||
|  | 		{ | ||||||
|  | 			hr = E_UNEXPECTED; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		ComPtr<ID2D1RectangleGeometry> output; | ||||||
|  | 		if (SUCCEEDED(hr)) | ||||||
|  | 		{ | ||||||
|  | 			hr = d2d_res_->GetFactory()->CreateRectangleGeometry(DX::ConvertToRectF(rect), &output); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (SUCCEEDED(hr)) | ||||||
|  | 		{ | ||||||
|  | 			geo.SetGeometry(output); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		ThrowIfFailed(hr); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void Renderer::CreateRoundedRectGeometry(Geometry& geo, Rect const& rect, Vec2 const& radius) | ||||||
|  | 	{ | ||||||
|  | 		HRESULT hr = S_OK; | ||||||
|  | 		if (!device_context_ || !d2d_res_) | ||||||
|  | 		{ | ||||||
|  | 			hr = E_UNEXPECTED; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		ComPtr<ID2D1RoundedRectangleGeometry> output; | ||||||
|  | 		if (SUCCEEDED(hr)) | ||||||
|  | 		{ | ||||||
|  | 			hr = d2d_res_->GetFactory()->CreateRoundedRectangleGeometry( | ||||||
|  | 				D2D1::RoundedRect( | ||||||
|  | 					DX::ConvertToRectF(rect), | ||||||
|  | 					radius.x, | ||||||
|  | 					radius.y | ||||||
|  | 				), | ||||||
|  | 				&output); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (SUCCEEDED(hr)) | ||||||
|  | 		{ | ||||||
|  | 			geo.SetGeometry(output); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		ThrowIfFailed(hr); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void Renderer::CreateEllipseGeometry(Geometry& geo, Point const& center, Vec2 const& radius) | ||||||
|  | 	{ | ||||||
|  | 		HRESULT hr = S_OK; | ||||||
|  | 		if (!device_context_ || !d2d_res_) | ||||||
|  | 		{ | ||||||
|  | 			hr = E_UNEXPECTED; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		ComPtr<ID2D1EllipseGeometry> output; | ||||||
|  | 		if (SUCCEEDED(hr)) | ||||||
|  | 		{ | ||||||
|  | 			hr = d2d_res_->GetFactory()->CreateEllipseGeometry( | ||||||
|  | 				D2D1::Ellipse( | ||||||
|  | 					DX::ConvertToPoint2F(center), | ||||||
|  | 					radius.x, | ||||||
|  | 					radius.y | ||||||
|  | 				), | ||||||
|  | 				&output); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (SUCCEEDED(hr)) | ||||||
|  | 		{ | ||||||
|  | 			geo.SetGeometry(output); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		ThrowIfFailed(hr); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void Renderer::CreatePathGeometrySink(GeometrySink& sink) | ||||||
|  | 	{ | ||||||
|  | 		HRESULT hr = S_OK; | ||||||
|  | 		if (!device_context_ || !d2d_res_) | ||||||
|  | 		{ | ||||||
|  | 			hr = E_UNEXPECTED; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		ComPtr<ID2D1PathGeometry> output; | ||||||
|  | 		if (SUCCEEDED(hr)) | ||||||
|  | 		{ | ||||||
|  | 			hr = d2d_res_->GetFactory()->CreatePathGeometry(&output); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (SUCCEEDED(hr)) | ||||||
|  | 		{ | ||||||
|  | 			sink.SetPathGeometry(output); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		ThrowIfFailed(hr); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	void Renderer::DrawGeometry( | 	void Renderer::DrawGeometry( | ||||||
| 		ComPtr<ID2D1Geometry> const& geometry, | 		Geometry const& geometry, | ||||||
| 		Color const& stroke_color, | 		Color const& stroke_color, | ||||||
| 		float stroke_width, | 		float stroke_width, | ||||||
| 		StrokeStyle stroke | 		StrokeStyle stroke | ||||||
|  | @ -255,12 +394,12 @@ namespace kiwano | ||||||
| 			hr = E_UNEXPECTED; | 			hr = E_UNEXPECTED; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (SUCCEEDED(hr)) | 		if (SUCCEEDED(hr) && geometry.GetGeometry()) | ||||||
| 		{ | 		{ | ||||||
| 			solid_color_brush_->SetColor(DX::ConvertToColorF(stroke_color)); | 			solid_color_brush_->SetColor(DX::ConvertToColorF(stroke_color)); | ||||||
| 
 | 
 | ||||||
| 			device_context_->DrawGeometry( | 			device_context_->DrawGeometry( | ||||||
| 				geometry.get(), | 				geometry.GetGeometry().get(), | ||||||
| 				solid_color_brush_.get(), | 				solid_color_brush_.get(), | ||||||
| 				stroke_width, | 				stroke_width, | ||||||
| 				d2d_res_->GetStrokeStyle(stroke) | 				d2d_res_->GetStrokeStyle(stroke) | ||||||
|  | @ -272,7 +411,7 @@ namespace kiwano | ||||||
| 		ThrowIfFailed(hr); | 		ThrowIfFailed(hr); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void Renderer::FillGeometry(ComPtr<ID2D1Geometry> const & geometry, Color const& fill_color) | 	void Renderer::FillGeometry(Geometry const & geometry, Color const& fill_color) | ||||||
| 	{ | 	{ | ||||||
| 		HRESULT hr = S_OK; | 		HRESULT hr = S_OK; | ||||||
| 		if (!solid_color_brush_ || !device_context_) | 		if (!solid_color_brush_ || !device_context_) | ||||||
|  | @ -280,11 +419,11 @@ namespace kiwano | ||||||
| 			hr = E_UNEXPECTED; | 			hr = E_UNEXPECTED; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (SUCCEEDED(hr)) | 		if (SUCCEEDED(hr) && geometry.GetGeometry()) | ||||||
| 		{ | 		{ | ||||||
| 			solid_color_brush_->SetColor(DX::ConvertToColorF(fill_color)); | 			solid_color_brush_->SetColor(DX::ConvertToColorF(fill_color)); | ||||||
| 			device_context_->FillGeometry( | 			device_context_->FillGeometry( | ||||||
| 				geometry.get(), | 				geometry.GetGeometry().get(), | ||||||
| 				solid_color_brush_.get() | 				solid_color_brush_.get() | ||||||
| 			); | 			); | ||||||
| 		} | 		} | ||||||
|  | @ -292,7 +431,7 @@ namespace kiwano | ||||||
| 		ThrowIfFailed(hr); | 		ThrowIfFailed(hr); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void Renderer::DrawRectangle(Rect const& rect, const Color& stroke_color, float stroke_width, StrokeStyle stroke) | 	void Renderer::DrawRectangle(Rect const& rect, Color const& stroke_color, float stroke_width, StrokeStyle stroke) | ||||||
| 	{ | 	{ | ||||||
| 		HRESULT hr = S_OK; | 		HRESULT hr = S_OK; | ||||||
| 		if (!solid_color_brush_ || !device_context_) | 		if (!solid_color_brush_ || !device_context_) | ||||||
|  | @ -437,7 +576,7 @@ namespace kiwano | ||||||
| 					D2D1_ANTIALIAS_MODE_PER_PRIMITIVE, | 					D2D1_ANTIALIAS_MODE_PER_PRIMITIVE, | ||||||
| 					D2D1::Matrix3x2F::Identity(), | 					D2D1::Matrix3x2F::Identity(), | ||||||
| 					properties.opacity, | 					properties.opacity, | ||||||
| 					solid_color_brush_.get(), | 					nullptr, | ||||||
| 					D2D1_LAYER_OPTIONS_NONE | 					D2D1_LAYER_OPTIONS_NONE | ||||||
| 				), | 				), | ||||||
| 				layer.get() | 				layer.get() | ||||||
|  |  | ||||||
|  | @ -27,8 +27,8 @@ | ||||||
| #include "../2d/TextStyle.hpp" | #include "../2d/TextStyle.hpp" | ||||||
| #include "helper.hpp" | #include "helper.hpp" | ||||||
| #include "Image.h" | #include "Image.h" | ||||||
|  | #include "Geometry.h" | ||||||
| #include "TextRenderer.h" | #include "TextRenderer.h" | ||||||
| #include "D2DDeviceResources.h" |  | ||||||
| 
 | 
 | ||||||
| #if defined(KGE_USE_DIRECTX10) | #if defined(KGE_USE_DIRECTX10) | ||||||
| #	include "D3D10DeviceResources.h" | #	include "D3D10DeviceResources.h" | ||||||
|  | @ -56,21 +56,48 @@ namespace kiwano | ||||||
| 			ComPtr<ID2D1Layer>& layer | 			ComPtr<ID2D1Layer>& layer | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
|  | 		void CreateLineGeometry( | ||||||
|  | 			Geometry& geo, | ||||||
|  | 			Point const& begin_pos, | ||||||
|  | 			Point const& end_pos | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		void CreateRectGeometry( | ||||||
|  | 			Geometry& geo, | ||||||
|  | 			Rect const& rect | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		void CreateRoundedRectGeometry( | ||||||
|  | 			Geometry& geo, | ||||||
|  | 			Rect const& rect, | ||||||
|  | 			Vec2 const& radius | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		void CreateEllipseGeometry( | ||||||
|  | 			Geometry& geo, | ||||||
|  | 			Point const& center, | ||||||
|  | 			Vec2 const& radius | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		void CreatePathGeometrySink( | ||||||
|  | 			GeometrySink& sink | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
| 		void DrawGeometry( | 		void DrawGeometry( | ||||||
| 			ComPtr<ID2D1Geometry> const& geometry, | 			Geometry const& geometry, | ||||||
| 			const Color& stroke_color, | 			const Color& stroke_color, | ||||||
| 			float stroke_width, | 			float stroke_width, | ||||||
| 			StrokeStyle stroke = StrokeStyle::Miter | 			StrokeStyle stroke = StrokeStyle::Miter | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		void FillGeometry( | 		void FillGeometry( | ||||||
| 			ComPtr<ID2D1Geometry> const& geometry, | 			Geometry const& geometry, | ||||||
| 			Color const& fill_color | 			Color const& fill_color | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		void DrawRectangle( | 		void DrawRectangle( | ||||||
| 			Rect const& rect, | 			Rect const& rect, | ||||||
| 			const Color& stroke_color, | 			Color const& stroke_color, | ||||||
| 			float stroke_width, | 			float stroke_width, | ||||||
| 			StrokeStyle stroke = StrokeStyle::Miter | 			StrokeStyle stroke = StrokeStyle::Miter | ||||||
| 		); | 		); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue