From 5beafa1c198fae40735649b4d33f26c4b39362ea Mon Sep 17 00:00:00 2001 From: Youri Sdobnikov Date: Thu, 17 Oct 2013 17:59:52 +0300 Subject: [PATCH] VisualElement::GetChildListAt selection by region algorithm fixed and upgraded, IList* pointers used, BoundingVolume destructor segfault fixed Change-Id: I65859f7e573a58b2d46309cb5dc7c2c314a7ab58 Signed-off-by: Youri Sdobnikov --- inc/FUiAnimVisualElement.h | 4 +- src/ui/animations/FUiAnimBoundingVolume.cpp | 1 + src/ui/animations/FUiAnimVisualElement.cpp | 6 +- src/ui/animations/FUiAnim_Plane.cpp | 631 +++++++++++++++++++++--- src/ui/animations/FUiAnim_Plane.h | 69 ++- src/ui/animations/FUiAnim_VisualElementImpl.cpp | 268 +++++----- src/ui/inc/FUiAnim_VisualElementImpl.h | 7 +- 7 files changed, 737 insertions(+), 249 deletions(-) diff --git a/inc/FUiAnimVisualElement.h b/inc/FUiAnimVisualElement.h index 4ef3bf7..b258194 100644 --- a/inc/FUiAnimVisualElement.h +++ b/inc/FUiAnimVisualElement.h @@ -1550,7 +1550,7 @@ public: * @see GetChildAt() * @see OnHitTest() */ - result GetChildListAt(const Tizen::Graphics::FloatPoint& point, Tizen::Base::Collection::ArrayListT& list); + result GetChildListAt(const Tizen::Graphics::FloatPoint& point, Tizen::Base::Collection::IList* list); /** * Build list of selected VisualElements in the selection region * @@ -1562,7 +1562,7 @@ public: * @param[out] list Tizen::Base::Collection::ArrayListT list to add intersected VE's pointers * @see VisualElementSelectionMode */ - result GetChildListAt(const Tizen::Graphics::FloatRectangle& selection, SelectionMode mode, Tizen::Base::Collection::ArrayListT& list); + result GetChildListAt(const Tizen::Graphics::FloatRectangle& selection, SelectionMode mode, Tizen::Base::Collection::IList* list); diff --git a/src/ui/animations/FUiAnimBoundingVolume.cpp b/src/ui/animations/FUiAnimBoundingVolume.cpp index c7ce72a..77e43ec 100644 --- a/src/ui/animations/FUiAnimBoundingVolume.cpp +++ b/src/ui/animations/FUiAnimBoundingVolume.cpp @@ -55,6 +55,7 @@ BoundingVolume::~BoundingVolume(void) if(_pBoundingVolumeImpl != null) { delete _pBoundingVolumeImpl; + _pBoundingVolumeImpl = null; } } diff --git a/src/ui/animations/FUiAnimVisualElement.cpp b/src/ui/animations/FUiAnimVisualElement.cpp index c4b1d54..0345a9b 100644 --- a/src/ui/animations/FUiAnimVisualElement.cpp +++ b/src/ui/animations/FUiAnimVisualElement.cpp @@ -1075,7 +1075,7 @@ VisualElement::GetBoundingVolume() } result -VisualElement::GetChildListAt(const Tizen::Graphics::FloatPoint& point, Tizen::Base::Collection::ArrayListT& list) +VisualElement::GetChildListAt(const Tizen::Graphics::FloatPoint& point, Tizen::Base::Collection::IList* list) { CHECK_CONSTRUCTED; @@ -1083,10 +1083,12 @@ VisualElement::GetChildListAt(const Tizen::Graphics::FloatPoint& point, Tizen::B } result -VisualElement::GetChildListAt(const Tizen::Graphics::FloatRectangle& selection, SelectionMode mode, Tizen::Base::Collection::ArrayListT& list) +VisualElement::GetChildListAt(const Tizen::Graphics::FloatRectangle& selection, SelectionMode mode, Tizen::Base::Collection::IList* list) { CHECK_CONSTRUCTED; + list->RemoveAll(); + SysTryReturnResult(NID_UI_ANIM, selection.height > 0.0f && selection.width > 0.0f, E_INVALID_ARG, "Selection width and height must be greater than 0"); return _pVisualElementImpl->GetChildListAt(selection, mode, list); diff --git a/src/ui/animations/FUiAnim_Plane.cpp b/src/ui/animations/FUiAnim_Plane.cpp index ded2b54..610d72f 100644 --- a/src/ui/animations/FUiAnim_Plane.cpp +++ b/src/ui/animations/FUiAnim_Plane.cpp @@ -19,6 +19,7 @@ #include "FUiAnimMesh.h" #include "FUiAnim_MathAdapterFunctions.h" +#include "FUiAnim_MatrixUtil.h" using namespace Tizen::Graphics; using namespace Tizen::Ui::Animations::_Math; @@ -26,59 +27,104 @@ using namespace Tizen::Ui::Animations::_Math; namespace Tizen{ namespace Ui{ namespace Animations { +float DotProduct(Tizen::Graphics::FloatPoint3& v1, Tizen::Graphics::FloatPoint3& v2) +{ + return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; +} + _Plane::_Plane() : _a(0.0f) , _b(0.0f) , _c(0.0f) , _d(0.0f) + , _v1(0.0f,0.0f,0.0f) + , _v2(0.0f,0.0f,0.0f) + , _v3(0.0f,0.0f,0.0f) { } -_Plane::_Plane(float a,float b, float c, float d) - : _a(a) - , _b(b) - , _c(c) - , _d(d) -{ - -} +//_Plane::_Plane(float a,float b, float c, float d) +//{ +// _a = a; +// _b = b; +// _c = c; +// _d = d; +// +// //normalize +// FloatPoint3 n(_a,_b,_c); +// n = n / Sqrt(_a * _a + _b * _b + _c * _c); +// _a = n.x; +// _b = n.y; +// _c = n.z; +// _d = - ((_a * v2.x) + (_b * v2.y) + (_c * v2.z)); +// +//} -_Plane::_Plane(Tizen::Graphics::FloatPoint3& v1, Tizen::Graphics::FloatPoint3& v2, Tizen::Graphics::FloatPoint3& v3) +_Plane::_Plane(const Tizen::Graphics::FloatPoint3& v1, const Tizen::Graphics::FloatPoint3& v2, const Tizen::Graphics::FloatPoint3& v3) { + _v1 = v1; + _v2 = v2; + _v3 = v3; + FloatPoint3 a(v1 - v2), b(v3 - v2); _a = (a.y)*(b.z) - (a.z)*(b.y); _b = (a.z)*(b.x) - (a.x)*(b.z); _c = (a.x)*(b.y) - (a.y)*(b.x); + + //normalize + FloatPoint3 n(_a,_b,_c); + n = n / Sqrt(_a * _a + _b * _b + _c * _c); + _a = n.x; + _b = n.y; + _c = n.z; + _d = - ((_a * v2.x) + (_b * v2.y) + (_c * v2.z)); } -_Plane::_Plane(Tizen::Ui::Animations::_Plane& other) +_Plane::_Plane(const Tizen::Ui::Animations::_Plane& other) { _a = other._a; _b = other._b; _c = other._c; _d = other._d; + + _v1 = other._v1; + _v2 = other._v2; + _v3 = other._v3; } -_Plane& _Plane::operator = (_Plane& other) +_Plane& _Plane::operator = (const _Plane& other) { Set(other); return *this; } -result -_Plane::Set(float a,float b, float c, float d) -{ - _a = a; - _b = b; - _c = c; - _d = d; - return E_SUCCESS; -} +//result +//_Plane::Set(float a,float b, float c, float d) +//{ +// _a = a; +// _b = b; +// _c = c; +// _d = d; +// +// //normalize +// FloatPoint3 n(_a,_b,_c); +// n = n / Sqrt(_a * _a + _b * _b + _c * _c); +// _a = n.x; +// _b = n.y; +// _c = n.z; +// _d = - ((_a * v2.x) + (_b * v2.y) + (_c * v2.z)); +// +// return E_SUCCESS; +//} result -_Plane::Set(Tizen::Graphics::FloatPoint3& v1, Tizen::Graphics::FloatPoint3& v2, Tizen::Graphics::FloatPoint3& v3) +_Plane::Set(const Tizen::Graphics::FloatPoint3& v1, const Tizen::Graphics::FloatPoint3& v2, const Tizen::Graphics::FloatPoint3& v3) { + _v1 = v1; + _v2 = v2; + _v3 = v3; + FloatPoint3 a(v1 - v2), b(v3 - v2); _a = (a.y)*(b.z) - (a.z)*(b.y); _b = (a.z)*(b.x) - (a.x)*(b.z); @@ -95,12 +141,17 @@ _Plane::Set(Tizen::Graphics::FloatPoint3& v1, Tizen::Graphics::FloatPoint3& v2, } result -_Plane::Set(Tizen::Ui::Animations::_Plane& other) +_Plane::Set(const Tizen::Ui::Animations::_Plane& other) { _a = other._a; _b = other._b; _c = other._c; _d = other._d; + + _v1 = other._v1; + _v2 = other._v2; + _v3 = other._v3; + return E_SUCCESS; } @@ -111,16 +162,22 @@ _Plane::Get(float& a,float& b, float& c, float& d) const b = _b; c = _c; d = _d; + + return E_SUCCESS; +} + +result +_Plane::Get(Tizen::Graphics::FloatPoint3& v1, Tizen::Graphics::FloatPoint3& v2, Tizen::Graphics::FloatPoint3& v3) const +{ + v1 = _v1; + v2 = _v2; + v3 = _v3; + return E_SUCCESS; } -//result -//_Plane::Get(Tizen::Graphics::FloatPoint3& v1, Tizen::Graphics::FloatPoint3& v2, Tizen::Graphics::FloatPoint3& v3) const -//{ -// -//} PlaneIntersectionResult -_Plane::Intersect(Tizen::Ui::Animations::_Plane& other) +_Plane::Intersect(Tizen::Ui::Animations::_Plane& other) const { if (_a == other._a && _b == other._b && _c == other._c) { @@ -145,7 +202,7 @@ _Plane::Intersect(Tizen::Ui::Animations::_Plane& other) } PlaneIntersectionResult -_Plane::Intersect(Tizen::Graphics::FloatPoint3& v) +_Plane::Intersect(Tizen::Graphics::FloatPoint3& v) const { float d = (_a * v.x + _b * v.y + _c * v.z + _d); @@ -165,17 +222,8 @@ _Plane::Intersect(Tizen::Graphics::FloatPoint3& v) } PlaneIntersectionResult -_Plane::Intersect(Tizen::Ui::Animations::BoundingVolume& volume) +_Plane::Intersect(Tizen::Ui::Animations::BoundingVolume& volume) const { -// FloatPoint3 max,min,v; -// bool pos = false; -// bool neg = false; -// PlaneIntersectionResult res; -// //int i; -// unsigned int j; -// //FloatPoint3 min; -// float d,r; - switch(volume.GetType()) { case BOUNDING_VOLUME_TYPE_AABB: @@ -195,39 +243,8 @@ _Plane::Intersect(Tizen::Ui::Animations::BoundingVolume& volume) v.y = ((((i % 4)>>1) == 1)? (max.y): (min.y)); v.z = ((((i % 8)>>2) == 1)? (max.z): (min.z)); -// if ((i % 2) == 1) -// { -// v.x = max.x; -// } -// else -// { -// v.x = min.x; -// } -// if ( ((i % 4)>>1) == 1 ) -// { -// v.y = max.y; -// } -// else -// { -// v.y = min.y; -// } -// if ( ((i % 8)>>2) == 1 ) -// { -// v.z = max.z; -// } -// else -// { -// v.z = min.z; -// } - res = Intersect(v); - //AppLog("Plane Intersect BV i = %d, v = %.3f %.3f %.3f res = %d (0 -int, 1 -neg, 2 -pos)",i,v.x,v.y,v.z,res); - - if (res == PLANE_INTERSECTION_RESULT_INTERSECT || (pos && neg)) - { - return PLANE_INTERSECTION_RESULT_INTERSECT; - } if (res == PLANE_INTERSECTION_RESULT_POS) { pos = true; @@ -236,6 +253,11 @@ _Plane::Intersect(Tizen::Ui::Animations::BoundingVolume& volume) { neg = true; } + + if (res == PLANE_INTERSECTION_RESULT_INTERSECT || (pos && neg)) + { + return PLANE_INTERSECTION_RESULT_INTERSECT; + } } if(pos) @@ -256,7 +278,7 @@ _Plane::Intersect(Tizen::Ui::Animations::BoundingVolume& volume) volume.Get(min,r); - d = Abs(_a * min.x + _b * min.y + _c * min.z + _d) / Sqrt(_a * _a + _b * _b + _c * _c); + d = Abs(_a * min.x + _b * min.y + _c * min.z + _d);//normilized / Sqrt(_a * _a + _b * _b + _c * _c); if (d > r) { @@ -280,7 +302,7 @@ _Plane::Intersect(Tizen::Ui::Animations::BoundingVolume& volume) } PlaneIntersectionResult -_Plane::Intersect(Tizen::Ui::Animations::Mesh* pMesh) +_Plane::Intersect(Tizen::Ui::Animations::Mesh* pMesh) const { FloatPoint3 v; bool pos = false; @@ -294,10 +316,6 @@ _Plane::Intersect(Tizen::Ui::Animations::Mesh* pMesh) v = pMesh->GetVertex(i); r = Intersect(v); - if (r == PLANE_INTERSECTION_RESULT_INTERSECT || (pos && neg)) - { - return PLANE_INTERSECTION_RESULT_INTERSECT; - } if (r == PLANE_INTERSECTION_RESULT_POS) { pos = true; @@ -306,6 +324,11 @@ _Plane::Intersect(Tizen::Ui::Animations::Mesh* pMesh) { neg = true; } + + if (r == PLANE_INTERSECTION_RESULT_INTERSECT || (pos && neg)) + { + return PLANE_INTERSECTION_RESULT_INTERSECT; + } } if(pos) @@ -319,4 +342,460 @@ _Plane::Intersect(Tizen::Ui::Animations::Mesh* pMesh) } +float +_Plane::GetDistance(Tizen::Graphics::FloatPoint3& v) const +{ + return Abs(_a * v.x + _b * v.y + _c * v.z + _d);//normilized / Sqrt(_a * _a + _b * _b + _c * _c); +} + +Tizen::Graphics::FloatPoint3 +_Plane::GetNormal() const +{ + return FloatPoint3(_a,_b,_c); +} + +result +_Plane::Transform(const Tizen::Graphics::FloatMatrix4& transformMatrix) +{ + _MatrixUtilTransform(transformMatrix, &_v1.x, &_v1.y, &_v1.z); + _MatrixUtilTransform(transformMatrix, &_v2.x, &_v2.y, &_v2.z); + _MatrixUtilTransform(transformMatrix, &_v3.x, &_v3.y, &_v3.z); + + Set(_v1,_v2,_v3); + + return E_SUCCESS; +} + +//_Selection + +_Selection::_Selection() +{ + +} + +_Selection::_Selection(_Plane& plane1,_Plane& plane2,_Plane& plane3,_Plane& plane4) +{ + _plane[0] = plane1; + _plane[1] = plane2; + _plane[2] = plane3; + _plane[3] = plane4; +} + +_Selection::~_Selection() +{ + +} + +_Selection& +_Selection::operator = (const _Selection& rhs) +{ + _plane[0] = rhs._plane[0]; + _plane[1] = rhs._plane[1]; + _plane[2] = rhs._plane[2]; + _plane[3] = rhs._plane[3]; + + return *this; +} + +result +_Selection::Set(_Plane& plane1, _Plane& plane2, _Plane& plane3, _Plane& plane4) +{ + _plane[0] = plane1; + _plane[1] = plane2; + _plane[2] = plane3; + _plane[3] = plane4; + + return E_SUCCESS; +} + +result +_Selection::Set(int index, _Plane& plane) +{ + if (index >= 0 && index < 4) + { + _plane[index] = plane; + + return E_SUCCESS; + } + else + { + return E_INVALID_ARG; + } +} + +result +_Selection::Set(int index, Tizen::Graphics::FloatPoint3& v1, Tizen::Graphics::FloatPoint3& v2, Tizen::Graphics::FloatPoint3& v3) +{ + if (index >= 0 && index < 4) + { + _plane[index].Set(v1,v2,v3); + + return E_SUCCESS; + } + else + { + return E_INVALID_ARG; + } +} + +_Plane& +_Selection::Get(int index) +{ + if (index >= 0 && index < 4) + { + return _plane[index]; + } + else + { + return _plane[0]; + } +} + +bool +_Selection::FindIncludedPoints(Tizen::Graphics::FloatPoint3& v) const +{ + bool pos = false; + bool neg = false; + PlaneIntersectionResult res; + + for (int i = 0; i < 4; i++) + { + res = _plane[i].Intersect(v); + if (res == PLANE_INTERSECTION_RESULT_POS) + { + pos = true; + } + if (res == PLANE_INTERSECTION_RESULT_NEG) + { + neg = true; + } + if (pos && neg) + { + return false; + } + } + + return true; +} + +bool +_Selection::FindExcludedPoints(Tizen::Graphics::FloatPoint3& v) const +{ + bool pos = false; + bool neg = false; + PlaneIntersectionResult res; + + for (int i = 0; i < 4; i++) + { + res = _plane[i].Intersect(v); + if (res == PLANE_INTERSECTION_RESULT_POS) + { + pos = true; + } + if (res == PLANE_INTERSECTION_RESULT_NEG) + { + neg = true; + } + if (pos && neg) + { + return true; + } + } + + return false; +} + +bool +_Selection::FindIncludedPoints(Tizen::Ui::Animations::BoundingVolume& volume) const +{ + bool pos = false; + bool neg = false; + PlaneIntersectionResult res; + + for (int i = 0; i < 4; i++) + { + res = _plane[i].Intersect(volume); + if (res == PLANE_INTERSECTION_RESULT_POS) + { + pos = true; + } + if (res == PLANE_INTERSECTION_RESULT_NEG) + { + neg = true; + } + if (pos && neg) + { + return false; + } + } + + return true; +} + +bool +_Selection::FindExcludedPoints(Tizen::Ui::Animations::BoundingVolume& volume) const +{ + bool pos = false; + bool neg = false; + PlaneIntersectionResult res; + + for (int i = 0; i < 4; i++) + { + res = _plane[i].Intersect(volume); + if (res == PLANE_INTERSECTION_RESULT_POS) + { + pos = true; + } + if (res == PLANE_INTERSECTION_RESULT_NEG) + { + neg = true; + } + if (res == PLANE_INTERSECTION_RESULT_INTERSECT) + { + return true; + } + if (pos && neg) + { + return true; + } + } + + return false; +} + +bool +_Selection::FindIncludedPoints(Tizen::Ui::Animations::Mesh* pMesh) const +{ + if (pMesh != null) + { + FloatPoint3 v; + + int count = pMesh->GetVertexCount(); + + for (int i = 0; i < count; i++) + { + v = pMesh->GetVertex(i); + if (FindIncludedPoints(v)) + { + return true; + } + } + } + + return false; +} + +bool +_Selection::FindExcludedPoints(Tizen::Ui::Animations::Mesh* pMesh) const +{ + if (pMesh != null) + { + FloatPoint3 v; + + int count = pMesh->GetVertexCount(); + + for (int i = 0; i < count; i++) + { + v = pMesh->GetVertex(i); + if (FindExcludedPoints(v)) + { + return true; + } + } + } + + return false; +} + +result +_Selection::FindIncludedExcludedPoints(Tizen::Ui::Animations::Mesh* pMesh, bool& hasIncluded, bool& hasExcluded) const +{ + hasIncluded = false; + hasExcluded = false; + + if (pMesh != null) + { + FloatPoint3 v; + int count = pMesh->GetVertexCount(); + + for (int i = 0; i < count; i++) + { + v = pMesh->GetVertex(i); + + if (!hasIncluded) + { + if (FindIncludedPoints(v)) + { + hasIncluded = true; + } + } + if (!hasExcluded) + { + if (FindExcludedPoints(v)) + { + hasExcluded = true; + } + } + + if (hasIncluded && hasExcluded) + { + return E_SUCCESS; + } + } + + return E_SUCCESS; + } + else + { + return E_INVALID_ARG; + } +} + +bool +_Selection::FindIncludedEdgeIntersections(Tizen::Graphics::FloatPoint3& v1, Tizen::Graphics::FloatPoint3& v2) const +{ + FloatPoint3 v1v2(v2 - v1); + FloatPoint3 n, intersectPoint; + float K; + //search edge intersection for each plane + for (int e = 0; e < 4; e++) + { + //edge intersects plane? + n = _plane[e].GetNormal(); + K = _plane[e].GetDistance(v1) / DotProduct(v1v2, n); + if (K <= 1 && K >= 0) //edge v2 -v1 intersects plane + { + intersectPoint = v1v2 * K + v1; + //intersection point included in selection? + if (FindIncludedPoints(intersectPoint)) + { + return true; + } + } + } + + return false; +} + +bool +_Selection::FindIncludedMeshIntersections(Tizen::Ui::Animations::Mesh* pMesh) const +{ + if (pMesh != null) + { + FloatPoint3 v1, v2; + int count = pMesh->GetIndexCount(); + + + //switch geometry types + switch(pMesh->GetGeometryType()) + { + case Mesh::GEO_TYPE_LINES: + { + //for each line + for (int i = 0; i < count; i += 2) + { + v1 = pMesh->GetVertex(pMesh->GetIndex(i)); + v2 = pMesh->GetVertex(pMesh->GetIndex(i + 1)); + + //search edge intersection for each plane + if (FindIncludedEdgeIntersections(v1,v2)) + { + return true; + } + } + + }break; + + case Mesh::GEO_TYPE_LINE_STRIP: + { + //for each line + for (int i = 1; i < count; i += 1) + { + v1 = pMesh->GetVertex(pMesh->GetIndex(i)); + v2 = pMesh->GetVertex(pMesh->GetIndex(i - 1)); + + //search edge intersection for each plane + if (FindIncludedEdgeIntersections(v1,v2)) + { + return true; + } + } + }break; + + case Mesh::GEO_TYPE_TRIANGLES: + { + //for each triangle + for (int i = 0; i < count; i += 3) + { + //for each edge + for(int j = 0; j < 3; j++) + { + v1 = pMesh->GetVertex(pMesh->GetIndex(i + j)); + v2 = pMesh->GetVertex(pMesh->GetIndex(i + (j + 1) % 3)); + + //search edge intersection for each plane + if (FindIncludedEdgeIntersections(v1,v2)) + { + return true; + } + } + } + + }break; + + case Mesh::GEO_TYPE_TRIANGLE_STRIP: + { + + v1 = pMesh->GetVertex(pMesh->GetIndex(0)); + v2 = pMesh->GetVertex(pMesh->GetIndex(1)); + + //search edge intersection for each plane + if (FindIncludedEdgeIntersections(v1,v2)) + { + return true; + } + + //for each edge + for(int j = 2; j + 1 < count; j++) + { + v1 = pMesh->GetVertex(pMesh->GetIndex(j)); + v2 = pMesh->GetVertex(pMesh->GetIndex(j - 1)); + + //search edge intersection for each plane + if (FindIncludedEdgeIntersections(v1,v2)) + { + return true; + } + + v1 = pMesh->GetVertex(pMesh->GetIndex(j)); + v2 = pMesh->GetVertex(pMesh->GetIndex(j - 2)); + + //search edge intersection for each plane + if (FindIncludedEdgeIntersections(v1,v2)) + { + return true; + } + } + + }break; + + default: + break; + }//switch(pMesh->GetGeometryType()) + }//if (pMesh != null) + + return false; +} + +result +_Selection::Transform(const Tizen::Graphics::FloatMatrix4& transformMatrix) +{ + _plane[0].Transform(transformMatrix); + _plane[1].Transform(transformMatrix); + _plane[2].Transform(transformMatrix); + _plane[3].Transform(transformMatrix); + + return E_SUCCESS; +} + }}} //namespace Tizen{ namespace Ui{ namespace Animations diff --git a/src/ui/animations/FUiAnim_Plane.h b/src/ui/animations/FUiAnim_Plane.h index 712ee5d..8ea494a 100644 --- a/src/ui/animations/FUiAnim_Plane.h +++ b/src/ui/animations/FUiAnim_Plane.h @@ -10,7 +10,7 @@ //#include //#include -//#include +#include //#include //#include // @@ -24,7 +24,7 @@ namespace Tizen{ namespace Graphics class FloatMatrix4; class FloatRectangle; class FloatPoint; -class FloatPoint3; +//class FloatPoint3; class FloatDimension; }} @@ -58,25 +58,66 @@ class _Plane { public: _Plane(); - _Plane(float a,float b, float c, float d); - _Plane(Tizen::Graphics::FloatPoint3& v1, Tizen::Graphics::FloatPoint3& v2, Tizen::Graphics::FloatPoint3& v3); - _Plane(Tizen::Ui::Animations::_Plane& other); - _Plane& operator = (_Plane& rhs); + //_Plane(float a,float b, float c, float d); + _Plane(const Tizen::Graphics::FloatPoint3& v1, const Tizen::Graphics::FloatPoint3& v2, const Tizen::Graphics::FloatPoint3& v3); + _Plane(const Tizen::Ui::Animations::_Plane& other); + _Plane& operator = (const _Plane& rhs); - result Set(float a,float b, float c, float d); - result Set(Tizen::Graphics::FloatPoint3& v1, Tizen::Graphics::FloatPoint3& v2, Tizen::Graphics::FloatPoint3& v3); - result Set(Tizen::Ui::Animations::_Plane& other); + //result Set(float a,float b, float c, float d); + result Set(const Tizen::Graphics::FloatPoint3& v1, const Tizen::Graphics::FloatPoint3& v2, const Tizen::Graphics::FloatPoint3& v3); + result Set(const Tizen::Ui::Animations::_Plane& other); result Get(float& a,float& b, float& c, float& d) const; - //result Get(Tizen::Graphics::FloatPoint3& v1, Tizen::Graphics::FloatPoint3& v2, Tizen::Graphics::FloatPoint3& v3) const; + result Get(Tizen::Graphics::FloatPoint3& v1, Tizen::Graphics::FloatPoint3& v2, Tizen::Graphics::FloatPoint3& v3) const; - PlaneIntersectionResult Intersect(Tizen::Ui::Animations::_Plane& other); - PlaneIntersectionResult Intersect(Tizen::Graphics::FloatPoint3& v); - PlaneIntersectionResult Intersect(Tizen::Ui::Animations::BoundingVolume& volume); - PlaneIntersectionResult Intersect(Tizen::Ui::Animations::Mesh* pMesh); + PlaneIntersectionResult Intersect(Tizen::Ui::Animations::_Plane& other) const; + PlaneIntersectionResult Intersect(Tizen::Graphics::FloatPoint3& v) const; + PlaneIntersectionResult Intersect(Tizen::Ui::Animations::BoundingVolume& volume) const; + PlaneIntersectionResult Intersect(Tizen::Ui::Animations::Mesh* pMesh) const; + + float GetDistance(Tizen::Graphics::FloatPoint3& v) const; //distance to point + Tizen::Graphics::FloatPoint3 GetNormal() const; //distance to point + + result Transform(const Tizen::Graphics::FloatMatrix4& transformMatrix); protected: float _a,_b,_c,_d; + Tizen::Graphics::FloatPoint3 _v1, _v2, _v3; + +private: +}; + +class _Selection +{ +public: + _Selection(); + _Selection(_Plane& plane1,_Plane& plane2,_Plane& plane3,_Plane& plane4); + ~_Selection(); + _Selection& operator = (const _Selection& rhs); + + result Set(_Plane& plane1, _Plane& plane2, _Plane& plane3, _Plane& plane4); + result Set(int index, _Plane& plane); + result Set(int index, Tizen::Graphics::FloatPoint3& v1, Tizen::Graphics::FloatPoint3& v2, Tizen::Graphics::FloatPoint3& v3); + + _Plane& Get(int index); + + result Transform(const Tizen::Graphics::FloatMatrix4& transformMatrix); + + bool FindIncludedPoints(Tizen::Graphics::FloatPoint3& v) const; + bool FindExcludedPoints(Tizen::Graphics::FloatPoint3& v) const; + + bool FindIncludedPoints(Tizen::Ui::Animations::BoundingVolume& volume) const; + bool FindExcludedPoints(Tizen::Ui::Animations::BoundingVolume& volume) const; + + bool FindIncludedPoints(Tizen::Ui::Animations::Mesh* pMesh) const; + bool FindExcludedPoints(Tizen::Ui::Animations::Mesh* pMesh) const; + result FindIncludedExcludedPoints(Tizen::Ui::Animations::Mesh* pMesh, bool& hasIncluded, bool& hasExcluded) const; + + bool FindIncludedMeshIntersections(Tizen::Ui::Animations::Mesh* pMesh) const; + bool FindIncludedEdgeIntersections(Tizen::Graphics::FloatPoint3& v1, Tizen::Graphics::FloatPoint3& v2) const; + +protected: + _Plane _plane[4]; private: }; diff --git a/src/ui/animations/FUiAnim_VisualElementImpl.cpp b/src/ui/animations/FUiAnim_VisualElementImpl.cpp index 577619d..e2c0fad 100644 --- a/src/ui/animations/FUiAnim_VisualElementImpl.cpp +++ b/src/ui/animations/FUiAnim_VisualElementImpl.cpp @@ -24,9 +24,6 @@ #include #include -#include -#include - #include #include #include @@ -62,6 +59,8 @@ #include "FUiAnim_AnimationManager.h" //3D feature +#include +#include #include "FUiAnimMesh.h" #include "FUiAnim_MeshImpl.h" #include "FUiAnim_VisualElementSharedData.h" @@ -6691,7 +6690,7 @@ _VisualElementImpl::HitTestI(const FloatPoint& point) { //make gloabl ray __globalRay.MakeRayGlobal(this,point); - __hasGlobalRay = true; + //__hasGlobalRay = true; } //hit VE mesh box? @@ -8608,7 +8607,7 @@ public: bool operator == (const Tizen::Base::Collection::MapEntryT< float, VisualElement* >& obj1, const Tizen::Base::Collection::MapEntryT< float, VisualElement* >& obj2) { - if (obj1.GetValue() == obj2.GetValue()) + if (obj1.GetValue() == obj2.GetValue() && obj1.GetKey() == obj2.GetKey()) { return true; } @@ -8624,7 +8623,7 @@ bool operator != (const Tizen::Base::Collection::MapEntryT< float, VisualElement } result -_VisualElementImpl::GetChildListAt(const Tizen::Graphics::FloatPoint& point, Tizen::Base::Collection::ArrayListT& list) +_VisualElementImpl::GetChildListAt(const Tizen::Graphics::FloatPoint& point, Tizen::Base::Collection::IList* list) { Tizen::Base::Collection::ArrayListT < Tizen::Base::Collection::MapEntryT < float, VisualElement* > > pairList; @@ -8634,7 +8633,7 @@ _VisualElementImpl::GetChildListAt(const Tizen::Graphics::FloatPoint& point, Tiz GetChildListAtI(point, pairList); - list.RemoveAll(); + list->RemoveAll(); //sort by float Tizen::Base::Collection::IComparerT< Tizen::Base::Collection::MapEntryT< float, VisualElement* > >* pPairComparer = new IntersectedPairComparer(); @@ -8650,7 +8649,7 @@ _VisualElementImpl::GetChildListAt(const Tizen::Graphics::FloatPoint& point, Tiz for (int i = 0; i < count; i++) { pairList.GetAt(i,intersectedPair); - list.Add(intersectedPair.GetValue()); + list->Add(intersectedPair.GetValue()); } return E_SUCCESS; @@ -8688,197 +8687,162 @@ _VisualElementImpl::GetChildListAtI(const Tizen::Graphics::FloatPoint point, Tiz } result -_VisualElementImpl::GetChildListAt(const Tizen::Graphics::FloatRectangle& selection, VisualElement::SelectionMode mode, Tizen::Base::Collection::ArrayListT& list) +_VisualElementImpl::GetChildListAt(const Tizen::Graphics::FloatRectangle& selection, VisualElement::SelectionMode mode, Tizen::Base::Collection::IList* list) { - list.RemoveAll(); + list->RemoveAll(); + int j; - Tizen::Graphics::FloatPoint point[4]; + //make global selection - //build points as 1-2-3-4-1 - point[0].x = selection.x; - point[0].y = selection.y; + //build local points as 1-2-3-4-1 + Tizen::Graphics::FloatPoint points[4]; + points[0].x = selection.x; + points[0].y = selection.y; - point[1].x = selection.x + selection.width; - point[1].y = selection.y; + points[1].x = selection.x + selection.width; + points[1].y = selection.y; - point[2].x = selection.x + selection.width; - point[2].y = selection.y + selection.height; + points[2].x = selection.x + selection.width; + points[2].y = selection.y + selection.height; - point[3].x = selection.x; - point[3].y = selection.y + selection.height; + points[3].x = selection.x; + points[3].y = selection.y + selection.height; - GetSelectedChildListI(point, mode, list); + //make points global + _VisualElementImpl* pRootVe = GetRoot(); - return E_SUCCESS; -} - -result -_VisualElementImpl::GetSelectedChildListI(const Tizen::Graphics::FloatPoint points[4], VisualElement::SelectionMode mode, Tizen::Base::Collection::ArrayListT& list) -{ - _VisualElementImpl* pChild = null; - FloatPoint localPoint[4]; - _Plane planes[4]; - FloatPoint3 v[3]; - PlaneIntersectionResult r[4]; - int i,j; - - if (!this->IsVisible()) + for (j = 0; j < 4; j++) { - return E_SUCCESS; + pRootVe->ConvertCoordinates(points[j],this); } - //test if VE BV intersected with selection - if (GetBoundingVolume().GetState() == BOUNDING_VOLUME_STATE_VALID) - { - GetBoundingVolume().Get(v[0],v[1]); - - //AppLog("VE \"%ls\" BV min %.3f,%.3f,%.3f, max %.3f,%.3f,%.3f, ", GetName().GetPointer(), v[0].x,v[0].y,v[0].z,v[1].x,v[1].y,v[1].z); - - for (j = 0; j < 4; j++) - { - v[0].x = points[j].x; - v[0].y = points[j].y; - v[0].z = 0.0f; - - v[1].x = points[j].x; - v[1].y = points[j].y; - v[1].z = 1.0f; - v[2].x = points[(j + 1)%4].x; - v[2].y = points[(j + 1)%4].y; - v[2].z = 0.0f; + FloatPoint3 v[3]; + _Selection globalSelection, localSelection; - planes[j].Set(v[0], v[1], v[2]); + //build planes of global selection + for (j = 0; j < 4; j++) + { + v[0].x = points[j].x; + v[0].y = points[j].y; + v[0].z = 0.0f; - r[j] = planes[j].Intersect(GetBoundingVolume()); + v[1].x = points[j].x; + v[1].y = points[j].y; + v[1].z = 1.0f; - //AppLog("Point for planes %d:%.3f,%.3f ",j, points[j].x,points[j].y); - //AppLog("VE BV test %d = %d", j, r[j]); - } + v[2].x = points[(j + 1)%4].x; + v[2].y = points[(j + 1)%4].y; + v[2].z = 0.0f; - //if BV outside - //pos outside - neg inside - //weak rules for BV - for (j = 0; j < 4; j++) - { - if (r[j] == PLANE_INTERSECTION_RESULT_INTERSECT) - { - r[j] = PLANE_INTERSECTION_RESULT_NEG; - } - } + globalSelection.Set(j,v[0],v[1],v[2]); + } + //make local selection to test BV + localSelection = globalSelection; + localSelection.Transform(GetMatrixFromTop()); - if (r[0] == PLANE_INTERSECTION_RESULT_POS || - r[2] == PLANE_INTERSECTION_RESULT_POS || - r[1] == PLANE_INTERSECTION_RESULT_POS || - r[3] == PLANE_INTERSECTION_RESULT_POS) + //test VE::BV + //test this VE to be intersected or included by selection + if (GetBoundingVolume().GetState() == BOUNDING_VOLUME_STATE_VALID) + { + //test if VE BV is included with selection + if (!localSelection.FindIncludedPoints(GetBoundingVolume())) { return E_SUCCESS; } } - Mesh* pMesh; + //GetSelectedI for VE childs + // remark: we do not call directly to this (rootlike) VE::GetSelectedI to exclude this VE from selection list. due to function name Get_Child_List + _VisualElementImpl* pChild = null; int count = __children.GetCount(); - for (i = 0; i < count; i++) + //test all children to have intersected and included elements + for (int i = 0; i < count; i++) { __children.GetAt(i, pChild); + if (pChild != null) { - //convert selection rectangle points to local - for (j = 0; j < 4; j++) - { - localPoint[j] = points[j]; - pChild->ConvertCoordinates(localPoint[j], this); - } - - pMesh = pChild->GetSharedData().geometry.GetMesh(); - if (pMesh != null) - { - //stopped here - //TODO: complete with bools, pMesh only - //test if Child Mesh BV intersected with selection - for (j = 0; j < 4; j++) - { - v[0].x = localPoint[j].x; - v[0].y = localPoint[j].y; - v[0].z = 0.0f; + pChild->GetSelectedI(globalSelection, mode, list); + } + } - v[1].x = localPoint[j].x; - v[1].y = localPoint[j].y; - v[1].z = 1.0f; + return E_SUCCESS; +} - v[2].x = localPoint[(j + 1)%4].x; - v[2].y = localPoint[(j + 1)%4].y; - v[2].z = 0.0f; +result +_VisualElementImpl::GetSelectedI(const Tizen::Ui::Animations::_Selection& globalSelection, VisualElement::SelectionMode mode, Tizen::Base::Collection::IList* list) +{ + _Selection localSelection = globalSelection; + localSelection.Transform(GetMatrixFromTop()); - planes[j].Set(v[0], v[1], v[2]); + //test this VE to be intersected or included by selection + if (GetBoundingVolume().GetState() == BOUNDING_VOLUME_STATE_VALID) + { + //test if VE BV is included with selection + if (!localSelection.FindIncludedPoints(GetBoundingVolume())) + { + return E_SUCCESS; + } + } - r[j] = planes[j].Intersect(pMesh->GetBoundingVolume()); - } + Mesh* pMesh = GetSharedData().geometry.GetMesh(); - //if intersect or include BV - //weak rules for BV - for (j = 0; j < 4; j++) + //test this mesh to be included in selection + if (pMesh != null) + { + //test this mesh BV to be intersected or included by selection + if (pMesh->GetBoundingVolume().GetState() == BOUNDING_VOLUME_STATE_VALID) + { + if (localSelection.FindIncludedPoints(pMesh->GetBoundingVolume())) + { + //branch by selection mode + //SELECTION_MODE can be converted to true|false if needed + //strong rules for mesh if user wanna fully included mesh + if (mode == VisualElement::SELECTION_MODE_FULLY_SELECTED) { - if (r[j] == PLANE_INTERSECTION_RESULT_INTERSECT) + //test this mesh to be included by selection + if (!localSelection.FindExcludedPoints(pMesh)) { - r[j] = PLANE_INTERSECTION_RESULT_NEG; + list->Add(GetPublic()); } } - - - //if Mesh BV included (or intersected) - if ((r[0] != PLANE_INTERSECTION_RESULT_POS && /*or object lies inside of selection*/ - r[2] != PLANE_INTERSECTION_RESULT_POS && - r[1] != PLANE_INTERSECTION_RESULT_POS && - r[3] != PLANE_INTERSECTION_RESULT_POS)) + else + //if mode == VisualElement::SELECTION_MODE_INCLUDE_INTERSECTED or default + //weak rules for mesh if user wanna intersected mesh. and other cases { - //intersect mesh - for (j = 0; j < 4; j++) + + //test this mesh to have points included in selection + if (localSelection.FindIncludedPoints(pMesh)) { - r[j] = planes[j].Intersect(pMesh); + list->Add(GetPublic()); } - - switch(mode) + else { - //weak rules for mesh if user wanna intersected mesh. and other cases - default: - case VisualElement::SELECTION_MODE_INCLUDE_INTERSECTED: - for (j = 0; j < 4; j++) + //test this mesh to have edges intersected with selection + if (localSelection.FindIncludedMeshIntersections(pMesh)) { - if (r[j] == PLANE_INTERSECTION_RESULT_INTERSECT) - { - r[j] = PLANE_INTERSECTION_RESULT_NEG; - } - } - break; - //strong rules for mesh if user wanna fully included mesh - case VisualElement::SELECTION_MODE_FULLY_SELECTED: - for (j = 0; j < 4; j++) - { - if (r[j] == PLANE_INTERSECTION_RESULT_INTERSECT) - { - r[j] = PLANE_INTERSECTION_RESULT_POS; - } + list->Add(GetPublic()); } - break; - } - - //if mesh included - if (r[0] != PLANE_INTERSECTION_RESULT_POS && /*or object lies inside of selection*/ - r[2] != PLANE_INTERSECTION_RESULT_POS && - r[1] != PLANE_INTERSECTION_RESULT_POS && - r[3] != PLANE_INTERSECTION_RESULT_POS) - { - list.Add(pChild->GetPublic()); } } + } + } + } + _VisualElementImpl* pChild = null; + int count = __children.GetCount(); - }//if(pMesh != null) + //test all children to have intersected and included elements + for (int i = 0; i < count; i++) + { + __children.GetAt(i, pChild); - pChild->GetSelectedChildListI(localPoint, mode, list); - }//if (pChild != null) - }//for (int i = 0; i < count; i++) //children + if (pChild != null) + { + pChild->GetSelectedI(globalSelection, mode, list); + } + } return E_SUCCESS; } diff --git a/src/ui/inc/FUiAnim_VisualElementImpl.h b/src/ui/inc/FUiAnim_VisualElementImpl.h index c84abbd..88d14f4 100644 --- a/src/ui/inc/FUiAnim_VisualElementImpl.h +++ b/src/ui/inc/FUiAnim_VisualElementImpl.h @@ -85,6 +85,7 @@ class Matrix4; namespace Tizen { namespace Ui { namespace Animations { class _Ray; +class _Selection; class _IVisualElementObserver; class IVisualElementAnimationProvider; class IVisualElementContentProvider; @@ -1424,10 +1425,10 @@ private: BoundingVolume& GetBoundingVolume(); //Picking instruments - result GetChildListAt(const Tizen::Graphics::FloatPoint& point, Tizen::Base::Collection::ArrayListT& list); + result GetChildListAt(const Tizen::Graphics::FloatPoint& point, Tizen::Base::Collection::IList* list); result GetChildListAtI(const Tizen::Graphics::FloatPoint point, Tizen::Base::Collection::ArrayListT >& pairList); - result GetChildListAt(const Tizen::Graphics::FloatRectangle& selection, VisualElement::SelectionMode mode, Tizen::Base::Collection::ArrayListT& list); - result GetSelectedChildListI(const Tizen::Graphics::FloatPoint points[4], VisualElement::SelectionMode mode, Tizen::Base::Collection::ArrayListT& list); + result GetChildListAt(const Tizen::Graphics::FloatRectangle& selection, VisualElement::SelectionMode mode, Tizen::Base::Collection::IList* list); + result GetSelectedI(const Tizen::Ui::Animations::_Selection& selection, VisualElement::SelectionMode mode, Tizen::Base::Collection::IList* list); public: enum -- 2.7.4