[Libreoffice-commits] core.git: Branch 'private/quwex/gsoc-box2d-experimental' - slideshow/source
Rebased ref, commits from common ancestor: commit e4a31bcabad9b717307cdf6c3cea295f5b32f55b Author: Sarper Akdemir AuthorDate: Sun Aug 16 00:03:43 2020 +0300 Commit: Sarper Akdemir CommitDate: Mon Aug 17 10:18:49 2020 +0300 fix group shape crash for physics animations Change-Id: Icc4f69246b9fab69d2a1d96743a7b85a95d65dc7 diff --git a/slideshow/source/engine/box2dtools.cxx b/slideshow/source/engine/box2dtools.cxx index d1ef96f154ca..2c6c144a1ec9 100644 --- a/slideshow/source/engine/box2dtools.cxx +++ b/slideshow/source/engine/box2dtools.cxx @@ -18,6 +18,9 @@ #include #include +#include + +#include #define BOX2D_SLIDE_SIZE_IN_METERS 100.00f #define DEFAULT_BOUNCINESS 0.1 @@ -401,11 +404,35 @@ void box2DWorld::initateAllShapesAsStaticBodies( mbShapesInitialized = true; auto aXShapeToShapeMap = pShapeManager->getXShapeToShapeMap(); -// iterate over shapes in the current slide +std::unordered_map, bool> aXShapeBelongsToAGroup; + +// iterate over the shapes in the current slide and flag them if they belong to a group for (auto aIt = aXShapeToShapeMap.begin(); aIt != aXShapeToShapeMap.end(); aIt++) { slideshow::internal::ShapeSharedPtr pShape = aIt->second; if (pShape->isForeground()) +{ +SdrObject* pTemp = SdrObject::getSdrObjectFromXShape(pShape->getXShape()); +if (pTemp && pTemp->IsGroupObject()) +{ +SdrObjList* aObjList = pTemp->GetSubList(); +const size_t nObjCount(aObjList->GetObjCount()); + +for (size_t nObjIndex = 0; nObjIndex < nObjCount; ++nObjIndex) +{ +SdrObject* pGroupMember(aObjList->GetObj(nObjIndex)); +aXShapeBelongsToAGroup.insert( +std::make_pair(GetXShapeForSdrObject(pGroupMember), true)); +} +} +} +} + +// iterate over shapes in the current slide +for (auto aIt = aXShapeToShapeMap.begin(); aIt != aXShapeToShapeMap.end(); aIt++) +{ +slideshow::internal::ShapeSharedPtr pShape = aIt->second; +if (pShape->isForeground() && !aXShapeBelongsToAGroup[pShape->getXShape()]) { Box2DBodySharedPtr pBox2DBody = createStaticBody(pShape); diff --git a/slideshow/source/engine/shapes/shapeimporter.cxx b/slideshow/source/engine/shapes/shapeimporter.cxx index 8f2abded678d..b1b1b3417269 100644 --- a/slideshow/source/engine/shapes/shapeimporter.cxx +++ b/slideshow/source/engine/shapes/shapeimporter.cxx @@ -495,7 +495,6 @@ ShapeSharedPtr ShapeImporter::importShape() // throw (ShapeLoadFailedException) } if( bIsGroupShape && pRet ) { -pRet->setIsForeground(false); // push new group on the stack: group traversal maShapesStack.push( XShapesEntry( pRet ) ); } diff --git a/slideshow/source/inc/shape.hxx b/slideshow/source/inc/shape.hxx index 1638e87c08a7..0e6533fca6fe 100644 --- a/slideshow/source/inc/shape.hxx +++ b/slideshow/source/inc/shape.hxx @@ -269,8 +269,7 @@ namespace slideshow private: /** Flag to check whether the shape belongs to the foreground. -For instance, it is false if the shape belongs to the master slide or -a group shape. +For instance, it is false if the shape belongs to the master slide. */ bool mbIsForeground; }; ___ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
[Libreoffice-commits] core.git: Branch 'private/quwex/gsoc-box2d-experimental' - slideshow/source
slideshow/source/engine/box2dtools.cxx | 26 ++- slideshow/source/engine/shapes/shapeimporter.cxx |1 slideshow/source/inc/shape.hxx |3 -- 3 files changed, 26 insertions(+), 4 deletions(-) New commits: commit fd14e44cae952e4e03152a8d13ee2190e1423c99 Author: Sarper Akdemir AuthorDate: Sun Aug 16 00:03:43 2020 +0300 Commit: Sarper Akdemir CommitDate: Sun Aug 16 00:03:43 2020 +0300 fix group shape crash for physics animations Change-Id: Icc4f69246b9fab69d2a1d96743a7b85a95d65dc7 diff --git a/slideshow/source/engine/box2dtools.cxx b/slideshow/source/engine/box2dtools.cxx index d1ef96f154ca..860b0f37e791 100644 --- a/slideshow/source/engine/box2dtools.cxx +++ b/slideshow/source/engine/box2dtools.cxx @@ -18,6 +18,9 @@ #include #include +#include + +#include #define BOX2D_SLIDE_SIZE_IN_METERS 100.00f #define DEFAULT_BOUNCINESS 0.1 @@ -401,11 +404,32 @@ void box2DWorld::initateAllShapesAsStaticBodies( mbShapesInitialized = true; auto aXShapeToShapeMap = pShapeManager->getXShapeToShapeMap(); +std::unordered_map, bool> aXShapeBelongsToAGroup; + +// iterate over the shapes in the current slide and flag them if they belong to a group +for (auto aIt = aXShapeToShapeMap.begin(); aIt != aXShapeToShapeMap.end(); aIt++) +{ +slideshow::internal::ShapeSharedPtr pShape = aIt->second; +SdrObject* pTemp = SdrObject::getSdrObjectFromXShape(pShape->getXShape()); +if (pShape->isForeground() && pTemp && pTemp->IsGroupObject()) +{ +SdrObjList* aObjList = pTemp->GetSubList(); +const size_t nObjCount(aObjList->GetObjCount()); + +for (size_t nObjIndex = 0; nObjIndex < nObjCount; ++nObjIndex) +{ +SdrObject* pGroupMember(aObjList->GetObj(nObjIndex)); +aXShapeBelongsToAGroup.insert( +std::make_pair(GetXShapeForSdrObject(pGroupMember), true)); +} +} +} + // iterate over shapes in the current slide for (auto aIt = aXShapeToShapeMap.begin(); aIt != aXShapeToShapeMap.end(); aIt++) { slideshow::internal::ShapeSharedPtr pShape = aIt->second; -if (pShape->isForeground()) +if (pShape->isForeground() && !aXShapeBelongsToAGroup[pShape->getXShape()]) { Box2DBodySharedPtr pBox2DBody = createStaticBody(pShape); diff --git a/slideshow/source/engine/shapes/shapeimporter.cxx b/slideshow/source/engine/shapes/shapeimporter.cxx index 8f2abded678d..b1b1b3417269 100644 --- a/slideshow/source/engine/shapes/shapeimporter.cxx +++ b/slideshow/source/engine/shapes/shapeimporter.cxx @@ -495,7 +495,6 @@ ShapeSharedPtr ShapeImporter::importShape() // throw (ShapeLoadFailedException) } if( bIsGroupShape && pRet ) { -pRet->setIsForeground(false); // push new group on the stack: group traversal maShapesStack.push( XShapesEntry( pRet ) ); } diff --git a/slideshow/source/inc/shape.hxx b/slideshow/source/inc/shape.hxx index 1638e87c08a7..0e6533fca6fe 100644 --- a/slideshow/source/inc/shape.hxx +++ b/slideshow/source/inc/shape.hxx @@ -269,8 +269,7 @@ namespace slideshow private: /** Flag to check whether the shape belongs to the foreground. -For instance, it is false if the shape belongs to the master slide or -a group shape. +For instance, it is false if the shape belongs to the master slide. */ bool mbIsForeground; }; ___ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
[Libreoffice-commits] core.git: Branch 'private/quwex/gsoc-box2d-experimental' - slideshow/source
Rebased ref, commits from common ancestor: commit 31f1b66be2f0bfedf17fa4e1b83268c42c808430 Author: Sarper Akdemir AuthorDate: Thu Aug 13 03:40:25 2020 +0300 Commit: Sarper Akdemir CommitDate: Thu Aug 13 06:17:12 2020 +0300 make physics animations handle sequential animations correctly Change-Id: Ie8bb8b32588f4c7bf16317b5229adc5b0334d192 diff --git a/slideshow/source/engine/animationfactory.cxx b/slideshow/source/engine/animationfactory.cxx index bc1848f68435..d6198439b327 100644 --- a/slideshow/source/engine/animationfactory.cxx +++ b/slideshow/source/engine/animationfactory.cxx @@ -323,7 +323,9 @@ namespace slideshow::internal { mpShapeManager->notifyShapeUpdate( mpShape ); if ( mpBox2DWorld->isInitialized() ) -mpBox2DWorld->queuePositionUpdate( mpShape->getXShape(), rOutPos ); +{ +mpBox2DWorld->queueShapePathAnimationUpdate( mpShape->getXShape(), mpAttrLayer ); +} } return true; diff --git a/slideshow/source/engine/box2dtools.cxx b/slideshow/source/engine/box2dtools.cxx index 68ab37fb6868..0dbc7be63f2a 100644 --- a/slideshow/source/engine/box2dtools.cxx +++ b/slideshow/source/engine/box2dtools.cxx @@ -203,7 +203,8 @@ box2DWorld::box2DWorld(const ::basegfx::B2DVector& rSlideSize) , mbShapesInitialized(false) , mbHasWorldStepper(false) , mpXShapeToBodyMap() -, maShapeUpdateQueue() +, maShapeParallelUpdateQueue() +, maShapeSequentialUpdate() { } @@ -253,6 +254,13 @@ void box2DWorld::createStaticFrameAroundSlide(const ::basegfx::B2DVector& rSlide pStaticBody->CreateFixture(); } +void box2DWorld::setShapePosition(const css::uno::Reference xShape, + const basegfx::B2DPoint& rOutPos) +{ +Box2DBodySharedPtr pBox2DBody = mpXShapeToBodyMap.find(xShape)->second; +pBox2DBody->setPosition(rOutPos); +} + void box2DWorld::setShapePositionByLinearVelocity( const css::uno::Reference xShape, const basegfx::B2DPoint& rOutPos, const double fPassedTime) @@ -274,6 +282,13 @@ void box2DWorld::setShapeLinearVelocity( pBox2DBody->setLinearVelocity(rVelocity); } +void box2DWorld::setShapeAngle(const css::uno::Reference xShape, + const double fAngle) +{ +Box2DBodySharedPtr pBox2DBody = mpXShapeToBodyMap.find(xShape)->second; +pBox2DBody->setAngle(fAngle); +} + void box2DWorld::setShapeAngleByAngularVelocity( const css::uno::Reference xShape, const double fAngle, const double fPassedTime) @@ -305,41 +320,75 @@ void box2DWorld::setShapeCollision( void box2DWorld::processUpdateQueue(const double fPassedTime) { -while (!maShapeUpdateQueue.empty()) +if (maShapeSequentialUpdate.empty()) { -Box2DShapeUpdateInformation& aQueueElement = maShapeUpdateQueue.front(); - -if (aQueueElement.mnDelayForSteps > 0) +while (!maShapeParallelUpdateQueue.empty()) { -// it was queued as a delayed action, skip it, don't pop -aQueueElement.mnDelayForSteps--; +Box2DDynamicUpdateInformation& aQueueElement = maShapeParallelUpdateQueue.front(); + +if (aQueueElement.mnDelayForSteps > 0) +{ +// it was queued as a delayed action, skip it, don't pop +aQueueElement.mnDelayForSteps--; +} +else +{ +switch (aQueueElement.meUpdateType) +{ +default: +case BOX2D_UPDATE_POSITION: +setShapePositionByLinearVelocity(aQueueElement.mxShape, + aQueueElement.maPosition, fPassedTime); +break; +case BOX2D_UPDATE_ANGLE: +setShapeAngleByAngularVelocity(aQueueElement.mxShape, aQueueElement.mfAngle, + fPassedTime); +break; +case BOX2D_UPDATE_SIZE: +break; +case BOX2D_UPDATE_VISIBILITY: +setShapeCollision(aQueueElement.mxShape, aQueueElement.mbVisibility); +break; +case BOX2D_UPDATE_LINEAR_VELOCITY: +setShapeLinearVelocity(aQueueElement.mxShape, aQueueElement.maVelocity); +break; +case BOX2D_UPDATE_ANGULAR_VELOCITY: +setShapeAngularVelocity(aQueueElement.mxShape, + aQueueElement.mfAngularVelocity); +} +maShapeParallelUpdateQueue.pop(); +} } -else +} +else +{ +// clear the
[Libreoffice-commits] core.git: Branch 'private/quwex/gsoc-box2d-experimental' - slideshow/source
slideshow/source/engine/animationfactory.cxx |4 slideshow/source/engine/box2dtools.cxx | 189 ++- slideshow/source/inc/box2dtools.hxx | 44 +- 3 files changed, 168 insertions(+), 69 deletions(-) New commits: commit 1fb53ef7b889b8cc3e6941c64df7c129575c1c5c Author: Sarper Akdemir AuthorDate: Thu Aug 13 03:40:25 2020 +0300 Commit: Sarper Akdemir CommitDate: Thu Aug 13 03:40:25 2020 +0300 make physics animations handle sequential animations correctly Change-Id: Ie8bb8b32588f4c7bf16317b5229adc5b0334d192 diff --git a/slideshow/source/engine/animationfactory.cxx b/slideshow/source/engine/animationfactory.cxx index bc1848f68435..d6198439b327 100644 --- a/slideshow/source/engine/animationfactory.cxx +++ b/slideshow/source/engine/animationfactory.cxx @@ -323,7 +323,9 @@ namespace slideshow::internal { mpShapeManager->notifyShapeUpdate( mpShape ); if ( mpBox2DWorld->isInitialized() ) -mpBox2DWorld->queuePositionUpdate( mpShape->getXShape(), rOutPos ); +{ +mpBox2DWorld->queueShapePathAnimationUpdate( mpShape->getXShape(), mpAttrLayer ); +} } return true; diff --git a/slideshow/source/engine/box2dtools.cxx b/slideshow/source/engine/box2dtools.cxx index 68ab37fb6868..383836b7dca2 100644 --- a/slideshow/source/engine/box2dtools.cxx +++ b/slideshow/source/engine/box2dtools.cxx @@ -203,7 +203,7 @@ box2DWorld::box2DWorld(const ::basegfx::B2DVector& rSlideSize) , mbShapesInitialized(false) , mbHasWorldStepper(false) , mpXShapeToBodyMap() -, maShapeUpdateQueue() +, maShapeParallelUpdateQueue() { } @@ -253,6 +253,13 @@ void box2DWorld::createStaticFrameAroundSlide(const ::basegfx::B2DVector& rSlide pStaticBody->CreateFixture(); } +void box2DWorld::setShapePosition(const css::uno::Reference xShape, + const basegfx::B2DPoint& rOutPos) +{ +Box2DBodySharedPtr pBox2DBody = mpXShapeToBodyMap.find(xShape)->second; +pBox2DBody->setPosition(rOutPos); +} + void box2DWorld::setShapePositionByLinearVelocity( const css::uno::Reference xShape, const basegfx::B2DPoint& rOutPos, const double fPassedTime) @@ -274,6 +281,13 @@ void box2DWorld::setShapeLinearVelocity( pBox2DBody->setLinearVelocity(rVelocity); } +void box2DWorld::setShapeAngle(const css::uno::Reference xShape, + const double fAngle) +{ +Box2DBodySharedPtr pBox2DBody = mpXShapeToBodyMap.find(xShape)->second; +pBox2DBody->setAngle(fAngle); +} + void box2DWorld::setShapeAngleByAngularVelocity( const css::uno::Reference xShape, const double fAngle, const double fPassedTime) @@ -305,42 +319,65 @@ void box2DWorld::setShapeCollision( void box2DWorld::processUpdateQueue(const double fPassedTime) { -while (!maShapeUpdateQueue.empty()) +if (maShapeSequentialUpdate.empty()) { -Box2DShapeUpdateInformation& aQueueElement = maShapeUpdateQueue.front(); - -if (aQueueElement.mnDelayForSteps > 0) -{ -// it was queued as a delayed action, skip it, don't pop -aQueueElement.mnDelayForSteps--; -} -else +while (!maShapeParallelUpdateQueue.empty()) { -switch (aQueueElement.meUpdateType) +Box2DDynamicUpdateInformation& aQueueElement = maShapeParallelUpdateQueue.front(); + +if (aQueueElement.mnDelayForSteps > 0) +{ +// it was queued as a delayed action, skip it, don't pop +aQueueElement.mnDelayForSteps--; +} +else { -default: -case BOX2D_UPDATE_POSITION: -setShapePositionByLinearVelocity(aQueueElement.mxShape, - aQueueElement.maPosition, fPassedTime); -break; -case BOX2D_UPDATE_ANGLE: -setShapeAngleByAngularVelocity(aQueueElement.mxShape, aQueueElement.mfAngle, - fPassedTime); -break; -case BOX2D_UPDATE_SIZE: -break; -case BOX2D_UPDATE_VISIBILITY: -setShapeCollision(aQueueElement.mxShape, aQueueElement.mbVisibility); -break; -case BOX2D_UPDATE_LINEAR_VELOCITY: -setShapeLinearVelocity(aQueueElement.mxShape, aQueueElement.maVelocity); -break; -case BOX2D_UPDATE_ANGULAR_VELOCITY: -setShapeAngularVelocity(aQueueElement.mxShape, aQueueElement.mfAngularVelocity); +switch (aQueueElement.meUpdateType) +{ +
[Libreoffice-commits] core.git: Branch 'private/quwex/gsoc-box2d-experimental' - slideshow/source
Rebased ref, commits from common ancestor: commit 803c9170806f3f54a6169887b65ebc05f84b4c82 Author: Sarper Akdemir AuthorDate: Mon Jul 27 23:02:48 2020 +0300 Commit: Sarper Akdemir CommitDate: Tue Aug 4 19:12:44 2020 +0300 work-in-progress complex shapes Change-Id: I807bbde92c143b8c96792b3d8bf9603a31216486 diff --git a/slideshow/source/engine/box2dtools.cxx b/slideshow/source/engine/box2dtools.cxx index 8729300184f6..90f1d1853dba 100644 --- a/slideshow/source/engine/box2dtools.cxx +++ b/slideshow/source/engine/box2dtools.cxx @@ -11,6 +11,13 @@ #include #include +#include +#include +#include +#include + +#include +#include #define BOX2D_SLIDE_SIZE_IN_METERS 100.00f @@ -62,6 +69,124 @@ b2Vec2 convertB2DPointToBox2DVec2(const basegfx::B2DPoint& aPoint, const double return { static_cast(aPoint.getX() * fScaleFactor), static_cast(aPoint.getY() * -fScaleFactor) }; } + +// expects rPolygon to have coordinates relative to it's center +void addTriangleVectorToBody(const basegfx::triangulator::B2DTriangleVector& rTriangleVector, + b2Body* aBody, const float fDensity, const float fFriction, + const float fRestitution, const double fScaleFactor) +{ +for (const basegfx::triangulator::B2DTriangle& aTriangle : rTriangleVector) +{ +b2FixtureDef aFixture; +b2PolygonShape aPolygonShape; +b2Vec2 aTriangleVertices[3] += { convertB2DPointToBox2DVec2(aTriangle.getA(), fScaleFactor), +convertB2DPointToBox2DVec2(aTriangle.getB(), fScaleFactor), +convertB2DPointToBox2DVec2(aTriangle.getC(), fScaleFactor) }; + +bool bValidPointDistance = true; +for (int a = 0; a < 3; a++) +{ +for (int b = 0; b < 3; b++) +{ +if (a == b) +continue; +if (b2DistanceSquared(aTriangleVertices[a], aTriangleVertices[b]) < 0.003f) +{ +bValidPointDistance = false; +} +} +} +if (bValidPointDistance) +{ +aPolygonShape.Set(aTriangleVertices, 3); +aFixture.shape = +aFixture.density = fDensity; +aFixture.friction = fFriction; +aFixture.restitution = fRestitution; +aBody->CreateFixture(); +} +} +} + +// expects rPolygon to have coordinates relative to it's center +void addEdgeShapeToBody(const basegfx::B2DPolygon& rPolygon, b2Body* aBody, const float fDensity, +const float fFriction, const float fRestitution, const double fScaleFactor) +{ +basegfx::B2DPolygon aPolygon = basegfx::utils::removeNeutralPoints(rPolygon); +const float fHalfWidth = 0.1; +bool bHaveEdgeA = false; +b2Vec2 aEdgeBoxVertices[4]; + +for (sal_uInt32 nIndex = 0; nIndex < aPolygon.count(); nIndex++) +{ +b2FixtureDef aFixture; +b2PolygonShape aPolygonShape; + +basegfx::B2DPoint aPointA; +basegfx::B2DPoint aPointB; +if (nIndex != 0) +{ +aPointA = aPolygon.getB2DPoint(nIndex - 1); +aPointB = aPolygon.getB2DPoint(nIndex); +} +else if (/* nIndex == 0 && */ aPolygon.isClosed()) +{ +// start by connecting the last point to the first one +aPointA = aPolygon.getB2DPoint(aPolygon.count() - 1); +aPointB = aPolygon.getB2DPoint(nIndex); +} +else // the polygon isn't closed, won't connect last and first points +{ +continue; +} + +b2Vec2 aEdgeUnitVec = (convertB2DPointToBox2DVec2(aPointB, fScaleFactor) + - convertB2DPointToBox2DVec2(aPointA, fScaleFactor)); +aEdgeUnitVec.Normalize(); + +b2Vec2 aEdgeNormal(-aEdgeUnitVec.y, aEdgeUnitVec.x); + +if (!bHaveEdgeA) +{ +aEdgeBoxVertices[0] += convertB2DPointToBox2DVec2(aPointA, fScaleFactor) + fHalfWidth * aEdgeNormal; +aEdgeBoxVertices[1] += convertB2DPointToBox2DVec2(aPointA, fScaleFactor) + -fHalfWidth * aEdgeNormal; +bHaveEdgeA = true; +} +aEdgeBoxVertices[2] += convertB2DPointToBox2DVec2(aPointB, fScaleFactor) + fHalfWidth * aEdgeNormal; +aEdgeBoxVertices[3] += convertB2DPointToBox2DVec2(aPointB, fScaleFactor) + -fHalfWidth * aEdgeNormal; + +bool bValidPointDistance += (b2DistanceSquared(aEdgeBoxVertices[0], aEdgeBoxVertices[2]) > 0.003f); + +if (bValidPointDistance) +{ +aPolygonShape.Set(aEdgeBoxVertices, 4); +aFixture.shape = +aFixture.density = fDensity; +aFixture.friction = fFriction; +aFixture.restitution = fRestitution; +aBody->CreateFixture(); + +
[Libreoffice-commits] core.git: Branch 'private/quwex/gsoc-box2d-experimental' - slideshow/source
Rebased ref, commits from common ancestor: commit 3c5585e482953080fa9cd518393c7babe4808910 Author: Sarper Akdemir AuthorDate: Mon Jul 27 23:02:48 2020 +0300 Commit: Sarper Akdemir CommitDate: Tue Aug 4 02:50:16 2020 +0300 work-in-progress complex shapes Change-Id: I807bbde92c143b8c96792b3d8bf9603a31216486 diff --git a/slideshow/source/engine/box2dtools.cxx b/slideshow/source/engine/box2dtools.cxx index 8729300184f6..34794065df14 100644 --- a/slideshow/source/engine/box2dtools.cxx +++ b/slideshow/source/engine/box2dtools.cxx @@ -11,6 +11,13 @@ #include #include +#include +#include +#include +#include + +#include +#include #define BOX2D_SLIDE_SIZE_IN_METERS 100.00f @@ -62,6 +69,124 @@ b2Vec2 convertB2DPointToBox2DVec2(const basegfx::B2DPoint& aPoint, const double return { static_cast(aPoint.getX() * fScaleFactor), static_cast(aPoint.getY() * -fScaleFactor) }; } + +// expects rPolygon to have coordinates relative to it's center +void addTriangleVectorToBody(const basegfx::triangulator::B2DTriangleVector& rTriangleVector, + b2Body* aBody, const float fDensity, const float fFriction, + const float fRestitution, const double fScaleFactor) +{ +for (const basegfx::triangulator::B2DTriangle& aTriangle : rTriangleVector) +{ +b2FixtureDef aFixture; +b2PolygonShape aPolygonShape; +b2Vec2 aTriangleVertices[3] += { convertB2DPointToBox2DVec2(aTriangle.getA(), fScaleFactor), +convertB2DPointToBox2DVec2(aTriangle.getB(), fScaleFactor), +convertB2DPointToBox2DVec2(aTriangle.getC(), fScaleFactor) }; + +bool bValidPointDistance = true; +for (int a = 0; a < 3; a++) +{ +for (int b = 0; b < 3; b++) +{ +if (a == b) +continue; +if (b2DistanceSquared(aTriangleVertices[a], aTriangleVertices[b]) < 0.003f) +{ +bValidPointDistance = false; +} +} +} +if (bValidPointDistance) +{ +aPolygonShape.Set(aTriangleVertices, 3); +aFixture.shape = +aFixture.density = fDensity; +aFixture.friction = fFriction; +aFixture.restitution = fRestitution; +aBody->CreateFixture(); +} +} +} + +// expects rPolygon to have coordinates relative to it's center +void addEdgeShapeToBody(const basegfx::B2DPolygon& rPolygon, b2Body* aBody, const float fDensity, +const float fFriction, const float fRestitution, const double fScaleFactor) +{ +basegfx::B2DPolygon aPolygon = basegfx::utils::removeNeutralPoints(rPolygon); +const float fHalfWidth = 0.1; +bool bHaveEdgeA = false; +b2Vec2 aEdgeBoxVertices[4]; + +for (sal_uInt32 nIndex = 0; nIndex < aPolygon.count(); nIndex++) +{ +b2FixtureDef aFixture; +b2PolygonShape aPolygonShape; + +basegfx::B2DPoint aPointA; +basegfx::B2DPoint aPointB; +if (nIndex != 0) +{ +aPointA = aPolygon.getB2DPoint(nIndex - 1); +aPointB = aPolygon.getB2DPoint(nIndex); +} +else if (/* nIndex == 0 && */ aPolygon.isClosed()) +{ +// start by connecting the last point to the first one +aPointA = aPolygon.getB2DPoint(aPolygon.count() - 1); +aPointB = aPolygon.getB2DPoint(nIndex); +} +else // the polygon isn't closed, won't connect last and first points +{ +continue; +} + +b2Vec2 aEdgeUnitVec = (convertB2DPointToBox2DVec2(aPointB, fScaleFactor) + - convertB2DPointToBox2DVec2(aPointA, fScaleFactor)); +aEdgeUnitVec.Normalize(); + +b2Vec2 aEdgeNormal(-aEdgeUnitVec.y, aEdgeUnitVec.x); + +if (!bHaveEdgeA) +{ +aEdgeBoxVertices[0] += convertB2DPointToBox2DVec2(aPointA, fScaleFactor) + fHalfWidth * aEdgeNormal; +aEdgeBoxVertices[1] += convertB2DPointToBox2DVec2(aPointA, fScaleFactor) + -fHalfWidth * aEdgeNormal; +bHaveEdgeA = true; +} +aEdgeBoxVertices[2] += convertB2DPointToBox2DVec2(aPointB, fScaleFactor) + fHalfWidth * aEdgeNormal; +aEdgeBoxVertices[3] += convertB2DPointToBox2DVec2(aPointB, fScaleFactor) + -fHalfWidth * aEdgeNormal; + +bool bValidPointDistance += (b2DistanceSquared(aEdgeBoxVertices[0], aEdgeBoxVertices[2]) > 0.003f); + +if (bValidPointDistance) +{ +aPolygonShape.Set(aEdgeBoxVertices, 4); +aFixture.shape = +aFixture.density = fDensity; +aFixture.friction = fFriction; +aFixture.restitution = fRestitution; +aBody->CreateFixture(); + +
[Libreoffice-commits] core.git: Branch 'private/quwex/gsoc-box2d-experimental' - slideshow/source
Rebased ref, commits from common ancestor: commit 61bff7181ce0a02852530b8d3370ac4b5a026c65 Author: Sarper Akdemir AuthorDate: Mon Jul 27 23:02:48 2020 +0300 Commit: Sarper Akdemir CommitDate: Wed Jul 29 02:59:54 2020 +0300 work-in-progress complex shapes Change-Id: I807bbde92c143b8c96792b3d8bf9603a31216486 diff --git a/slideshow/source/engine/box2dtools.cxx b/slideshow/source/engine/box2dtools.cxx index 8729300184f6..0e774230800e 100644 --- a/slideshow/source/engine/box2dtools.cxx +++ b/slideshow/source/engine/box2dtools.cxx @@ -11,6 +11,14 @@ #include #include +#include +#include +#include +#include + +#include +#include +#include #define BOX2D_SLIDE_SIZE_IN_METERS 100.00f @@ -62,6 +70,55 @@ b2Vec2 convertB2DPointToBox2DVec2(const basegfx::B2DPoint& aPoint, const double return { static_cast(aPoint.getX() * fScaleFactor), static_cast(aPoint.getY() * -fScaleFactor) }; } + +void addTriangleVectorToBody(const basegfx::triangulator::B2DTriangleVector& rTriangleVector, + b2Body* aBody, const basegfx::B2DRange& rShapeBounds, + const float fDensity, const float fFriction, const float fRestitution, + const double fScaleFactor) +{ +// aAdjustCenter is used to make coordinates relative to center of the shape instead of top left +basegfx::B2DPoint aAdjustCenter(rShapeBounds.getWidth() / 2, rShapeBounds.getHeight() / 2); +for (const basegfx::triangulator::B2DTriangle& aTriangle : rTriangleVector) +{ +b2FixtureDef aFixture; +b2PolygonShape aPolygonShape; +b2Vec2 aTriangleVertices[3]; +basegfx::B2DPoint aTriangleVertice = aTriangle.getA() - aAdjustCenter; +// putting the operation in place of aTriangleVertice creates weird behavior and i dont know why +aTriangleVertices[0] = convertB2DPointToBox2DVec2(aTriangleVertice, fScaleFactor); +aTriangleVertice = aTriangle.getB() - aAdjustCenter; +aTriangleVertices[1] = convertB2DPointToBox2DVec2(aTriangleVertice, fScaleFactor); +aTriangleVertice = aTriangle.getC() - aAdjustCenter; +aTriangleVertices[2] = convertB2DPointToBox2DVec2(aTriangleVertice, fScaleFactor); + +// FIXME: weird bug when using a bezier curve with >10 vertices +// turns out bug was happening when there are triangles that have really close points +// box2d marks those as degenerate ones, and stops working, so we will just ignore +// really tiny triangles +bool bValidSizedTriangle = true; +for (int a = 0; a < 3; a++) +{ +for (int b = 0; b < 3; b++) +{ +if (a == b) +continue; +if (b2DistanceSquared(aTriangleVertices[a], aTriangleVertices[b]) < 0.003f) +{ +bValidSizedTriangle = false; +} +} +} +if (bValidSizedTriangle) +{ +aPolygonShape.Set(aTriangleVertices, 3); +aFixture.shape = +aFixture.density = fDensity; +aFixture.friction = fFriction; +aFixture.restitution = fRestitution; +aBody->CreateFixture(); +} +} +} } box2DWorld::box2DWorld(const ::basegfx::B2DVector& rSlideSize) @@ -224,7 +281,19 @@ void box2DWorld::initateAllShapesAsStaticBodies( slideshow::internal::ShapeSharedPtr pShape = aIt->second; if (pShape->isForeground()) { -Box2DBodySharedPtr pBox2DBody = createStaticBodyFromBoundingBox(pShape); +Box2DBodySharedPtr pBox2DBody; + +auto aShapeType = pShape->getXShape()->getShapeType(); + +if (aShapeType == "com.sun.star.drawing.PolyPolygonShape") +pBox2DBody = createStaticBodyFromPolygonShape(pShape); +else if (aShapeType == "com.sun.star.drawing.ClosedBezierShape") +pBox2DBody = createStaticBodyFromBezierShape(pShape); +else if (aShapeType == "com.sun.star.drawing.CustomShape") +pBox2DBody = createStaticBodyFromCustomShape(pShape); +else +pBox2DBody = createStaticBodyFromBoundingBox(pShape); + mpXShapeToBodyMap.insert(std::make_pair(pShape->getXShape(), pBox2DBody)); if (!pShape->isVisible()) { @@ -357,6 +426,7 @@ box2DWorld::createStaticBodyFromBoundingBox(const slideshow::internal::ShapeShar const float fDensity, const float fFriction) { assert(mpBox2DWorld); + ::basegfx::B2DRectangle aShapeBounds = rShape->getBounds(); double fShapeWidth = aShapeBounds.getWidth() * mfScaleFactor; double fShapeHeight = aShapeBounds.getHeight() * mfScaleFactor; @@ -382,6 +452,119 @@ box2DWorld::createStaticBodyFromBoundingBox(const slideshow::internal::ShapeShar return
[Libreoffice-commits] core.git: Branch 'private/quwex/gsoc-box2d-experimental' - slideshow/source
Rebased ref, commits from common ancestor: commit 6214bafdbf5909c6eb5958510309c5378b1a481a Author: Sarper Akdemir AuthorDate: Mon Jul 27 23:02:48 2020 +0300 Commit: Sarper Akdemir CommitDate: Tue Jul 28 16:08:40 2020 +0300 work-in-progress complex shapes Change-Id: I807bbde92c143b8c96792b3d8bf9603a31216486 diff --git a/slideshow/source/engine/box2dtools.cxx b/slideshow/source/engine/box2dtools.cxx index 8729300184f6..dcca891c4dac 100644 --- a/slideshow/source/engine/box2dtools.cxx +++ b/slideshow/source/engine/box2dtools.cxx @@ -11,6 +11,12 @@ #include #include +#include +#include +#include +#include + +#include #define BOX2D_SLIDE_SIZE_IN_METERS 100.00f @@ -62,6 +68,55 @@ b2Vec2 convertB2DPointToBox2DVec2(const basegfx::B2DPoint& aPoint, const double return { static_cast(aPoint.getX() * fScaleFactor), static_cast(aPoint.getY() * -fScaleFactor) }; } + +void addTriangleVectorToBody(const basegfx::triangulator::B2DTriangleVector& rTriangleVector, + b2Body* aBody, const basegfx::B2DRange& rShapeBounds, + const float fDensity, const float fFriction, const float fRestitution, + const double fScaleFactor) +{ +// aAdjustCenter is used to make coordinates relative to center of the shape instead of top left +basegfx::B2DPoint aAdjustCenter(rShapeBounds.getWidth() / 2, rShapeBounds.getHeight() / 2); +for (const basegfx::triangulator::B2DTriangle& aTriangle : rTriangleVector) +{ +b2FixtureDef aFixture; +b2PolygonShape aPolygonShape; +b2Vec2 aTriangleVertices[3]; +basegfx::B2DPoint aTriangleVertice = aTriangle.getA() - aAdjustCenter; +// putting the operation in place of aTriangleVertice creates weird behavior and i dont know why +aTriangleVertices[0] = convertB2DPointToBox2DVec2(aTriangleVertice, fScaleFactor); +aTriangleVertice = aTriangle.getB() - aAdjustCenter; +aTriangleVertices[1] = convertB2DPointToBox2DVec2(aTriangleVertice, fScaleFactor); +aTriangleVertice = aTriangle.getC() - aAdjustCenter; +aTriangleVertices[2] = convertB2DPointToBox2DVec2(aTriangleVertice, fScaleFactor); + +// FIXME: weird bug when using a bezier curve with >10 vertices +// turns out bug was happening when there are triangles that have really close points +// box2d marks those as degenerate ones, and stops working, so we will just ignore +// really tiny triangles +bool bValidSizedTriangle = true; +for (int a = 0; a < 3; a++) +{ +for (int b = 0; b < 3; b++) +{ +if (a == b) +continue; +if (b2DistanceSquared(aTriangleVertices[a], aTriangleVertices[b]) < 0.003f) +{ +bValidSizedTriangle = false; +} +} +} +if (bValidSizedTriangle) +{ +aPolygonShape.Set(aTriangleVertices, 3); +aFixture.shape = +aFixture.density = fDensity; +aFixture.friction = fFriction; +aFixture.restitution = fRestitution; +aBody->CreateFixture(); +} +} +} } box2DWorld::box2DWorld(const ::basegfx::B2DVector& rSlideSize) @@ -224,7 +279,17 @@ void box2DWorld::initateAllShapesAsStaticBodies( slideshow::internal::ShapeSharedPtr pShape = aIt->second; if (pShape->isForeground()) { -Box2DBodySharedPtr pBox2DBody = createStaticBodyFromBoundingBox(pShape); +Box2DBodySharedPtr pBox2DBody; + +auto aShapeType = pShape->getXShape()->getShapeType(); + +if (aShapeType == "com.sun.star.drawing.PolyPolygonShape") +pBox2DBody = createStaticBodyFromPolygonShape(pShape); +else if (aShapeType == "com.sun.star.drawing.ClosedBezierShape") +pBox2DBody = createStaticBodyFromBezierShape(pShape); +else +pBox2DBody = createStaticBodyFromBoundingBox(pShape); + mpXShapeToBodyMap.insert(std::make_pair(pShape->getXShape(), pBox2DBody)); if (!pShape->isVisible()) { @@ -382,6 +447,74 @@ box2DWorld::createStaticBodyFromBoundingBox(const slideshow::internal::ShapeShar return std::make_shared(pBody, mfScaleFactor); } +Box2DBodySharedPtr +box2DWorld::createStaticBodyFromPolygonShape(const slideshow::internal::ShapeSharedPtr& rShape, + const float fDensity, const float fFriction) +{ +assert(mpBox2DWorld); + +::basegfx::B2DRectangle aShapeBounds = rShape->getBounds(); + +b2BodyDef aBodyDef; +aBodyDef.type = b2_staticBody; +aBodyDef.position = convertB2DPointToBox2DVec2(aShapeBounds.getCenter(), mfScaleFactor); + +std::shared_ptr pBody(mpBox2DWorld->CreateBody(), [](b2Body* pB2Body) { +