diff options
author | Sarper Akdemir <q.sarperakdemir@gmail.com> | 2020-08-14 01:18:14 +0300 |
---|---|---|
committer | Thorsten Behrens <Thorsten.Behrens@CIB.de> | 2020-08-22 11:24:16 +0200 |
commit | 394f74e6f168f034f7ed73e3027e4ff07f6b94b9 (patch) | |
tree | b4da98e1d95e6bd3bf0e0a1cf30a9a5769907dc3 /slideshow/source/engine | |
parent | 8a360d04e43410e729c0ee270be5447ce6c1cd03 (diff) |
add bounciness velocity and density options to physics animations
Adding new xml options to specify the starting velocity, bounciness,
and density of the rigid body that physics animation control.
Change-Id: Ifaba785e82c8ee17be00711a3e7a75257e7704ae
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/101141
Tested-by: Jenkins
Reviewed-by: Thorsten Behrens <Thorsten.Behrens@CIB.de>
Diffstat (limited to 'slideshow/source/engine')
4 files changed, 103 insertions, 11 deletions
diff --git a/slideshow/source/engine/animationfactory.cxx b/slideshow/source/engine/animationfactory.cxx index 8f6534a30539..327a048afeb1 100644 --- a/slideshow/source/engine/animationfactory.cxx +++ b/slideshow/source/engine/animationfactory.cxx @@ -362,6 +362,9 @@ namespace slideshow::internal const double fDuration, const ShapeManagerSharedPtr& rShapeManager, const ::basegfx::B2DVector& rSlideSize, + const ::basegfx::B2DVector& rStartVelocity, + const double fDensity, + const double fBounciness, int nFlags ) : mpShape(), mpAttrLayer(), @@ -372,6 +375,9 @@ namespace slideshow::internal mpBox2DBody(), mpBox2DWorld( pBox2DWorld ), mfDuration(fDuration), + maStartVelocity(rStartVelocity), + mfDensity(fDensity), + mfBounciness(fBounciness), mfPreviousElapsedTime(0.00f), mbIsBox2dWorldStepper(false) { @@ -411,7 +417,7 @@ namespace slideshow::internal ENSURE_OR_THROW( rAttrLayer, "PhysicsAnimation::start(): Invalid attribute layer" ); - mpBox2DBody = mpBox2DWorld->makeShapeDynamic( rShape ); + mpBox2DBody = mpBox2DWorld->makeShapeDynamic( rShape->getXShape(), maStartVelocity, mfDensity, mfBounciness ); if( !mbAnimationStarted ) { @@ -495,6 +501,9 @@ namespace slideshow::internal box2d::utils::Box2DBodySharedPtr mpBox2DBody; box2d::utils::Box2DWorldSharedPtr mpBox2DWorld; double mfDuration; + const ::basegfx::B2DVector maStartVelocity; + const double mfDensity; + const double mfBounciness; double mfPreviousElapsedTime; bool mbIsBox2dWorldStepper; }; @@ -1468,11 +1477,17 @@ namespace slideshow::internal const double fDuration, const ShapeManagerSharedPtr& rShapeManager, const ::basegfx::B2DVector& rSlideSize, + const ::basegfx::B2DVector& rStartVelocity, + const double fDensity, + const double fBounciness, int nFlags ) { return std::make_shared<PhysicsAnimation>( pBox2DWorld, fDuration, rShapeManager, rSlideSize, + rStartVelocity, + fDensity, + fBounciness, nFlags ); } diff --git a/slideshow/source/engine/animationnodes/animationphysicsnode.cxx b/slideshow/source/engine/animationnodes/animationphysicsnode.cxx index 8f531ea24ed7..3c7c227f2d0c 100644 --- a/slideshow/source/engine/animationnodes/animationphysicsnode.cxx +++ b/slideshow/source/engine/animationnodes/animationphysicsnode.cxx @@ -19,6 +19,12 @@ #include "animationphysicsnode.hxx" #include <animationfactory.hxx> +#include <o3tl/any.hxx> + +constexpr double fDefaultStartVelocityX(0.0); +constexpr double fDefaultStartVelocityY(0.0); +constexpr double fDefaultDensity(1.0); +constexpr double fDefaultBounciness(0.1); namespace slideshow::internal { @@ -34,12 +40,47 @@ AnimationActivitySharedPtr AnimationPhysicsNode::createActivity() const ENSURE_OR_THROW((mxPhysicsMotionNode->getDuration() >>= fDuration), "Couldn't get the animation duration."); + ::css::uno::Any aTemp; + double fStartVelocityX; + aTemp = mxPhysicsMotionNode->getStartVelocityX(); + if (aTemp.hasValue()) + aTemp >>= fStartVelocityX; + else + fStartVelocityX = fDefaultStartVelocityX; + + double fStartVelocityY; + aTemp = mxPhysicsMotionNode->getStartVelocityY(); + if (aTemp.hasValue()) + aTemp >>= fStartVelocityY; + else + fStartVelocityY = fDefaultStartVelocityY; + + double fDensity; + aTemp = mxPhysicsMotionNode->getDensity(); + if (aTemp.hasValue()) + { + aTemp >>= fDensity; + fDensity = (fDensity < 0.0) ? 0.0 : fDensity; + } + else + fDensity = fDefaultDensity; + + double fBounciness; + aTemp = mxPhysicsMotionNode->getBounciness(); + if (aTemp.hasValue()) + { + aTemp >>= fBounciness; + fBounciness = std::clamp(fBounciness, 0.0, 1.0); + } + else + fBounciness = fDefaultBounciness; + ActivitiesFactory::CommonParameters const aParms(fillCommonParameters()); return ActivitiesFactory::createSimpleActivity( aParms, - AnimationFactory::createPhysicsAnimation(getContext().mpBox2DWorld, fDuration, - getContext().mpSubsettableShapeManager, - getSlideSize(), 0), + AnimationFactory::createPhysicsAnimation( + getContext().mpBox2DWorld, fDuration, getContext().mpSubsettableShapeManager, + getSlideSize(), { fStartVelocityX, fStartVelocityY }, fDensity, fBounciness, 0), true); } diff --git a/slideshow/source/engine/animationnodes/animationphysicsnode.hxx b/slideshow/source/engine/animationnodes/animationphysicsnode.hxx index 8517dbbb803b..d9af6802a037 100644 --- a/slideshow/source/engine/animationnodes/animationphysicsnode.hxx +++ b/slideshow/source/engine/animationnodes/animationphysicsnode.hxx @@ -20,6 +20,7 @@ #include "animationbasenode.hxx" #include <com/sun/star/animations/XAnimateMotion.hpp> +#include <com/sun/star/animations/XAnimatePhysics.hpp> namespace slideshow { @@ -46,7 +47,7 @@ private: virtual AnimationActivitySharedPtr createActivity() const override; virtual bool enqueueActivity() const override; - css::uno::Reference<css::animations::XAnimateMotion> mxPhysicsMotionNode; + css::uno::Reference<css::animations::XAnimatePhysics> mxPhysicsMotionNode; }; } // namespace internal diff --git a/slideshow/source/engine/box2dtools.cxx b/slideshow/source/engine/box2dtools.cxx index bdeabc12e985..845363501ca4 100644 --- a/slideshow/source/engine/box2dtools.cxx +++ b/slideshow/source/engine/box2dtools.cxx @@ -20,6 +20,7 @@ #include <svx/svdoashp.hxx> #define BOX2D_SLIDE_SIZE_IN_METERS 100.00f +constexpr double fDefaultStaticBodyBounciness(0.1); namespace box2d::utils { @@ -551,6 +552,13 @@ void box2DWorld::queueShapeAnimationEndUpdate( } } +void box2DWorld::alertAnimationEndForShape(const slideshow::internal::ShapeSharedPtr& pShape) +{ + Box2DBodySharedPtr pBox2DBody = mpXShapeToBodyMap.find(pShape->getXShape())->second; + makeBodyStatic(pBox2DBody); + pBox2DBody->setRestitution(fDefaultStaticBodyBounciness); +} + void box2DWorld::step(const float fTimeStep, const int nVelocityIterations, const int nPositionIterations) { @@ -586,10 +594,15 @@ bool box2DWorld::isInitialized() return false; } -Box2DBodySharedPtr box2DWorld::makeShapeDynamic(const slideshow::internal::ShapeSharedPtr& pShape) +Box2DBodySharedPtr +box2DWorld::makeShapeDynamic(const css::uno::Reference<css::drawing::XShape>& xShape, + const basegfx::B2DVector& rStartVelocity, const double fDensity, + const double fBounciness) { assert(mpBox2DWorld); - Box2DBodySharedPtr pBox2DBody = mpXShapeToBodyMap.find(pShape->getXShape())->second; + Box2DBodySharedPtr pBox2DBody = mpXShapeToBodyMap.find(xShape)->second; + pBox2DBody->setDensityAndRestitution(fDensity, fBounciness); + queueLinearVelocityUpdate(xShape, rStartVelocity, 1); return makeBodyDynamic(pBox2DBody); } @@ -679,15 +692,17 @@ Box2DBodySharedPtr box2DWorld::createStaticBody(const slideshow::internal::Shape } else { - addEdgeShapeToBody(rPolygon, pBody.get(), fDensity, fFriction, 0.1f, mfScaleFactor); + addEdgeShapeToBody(rPolygon, pBody.get(), fDensity, fFriction, + static_cast<float>(fDefaultStaticBodyBounciness), mfScaleFactor); } } - addTriangleVectorToBody(aTriangleVector, pBody.get(), fDensity, fFriction, 0.1f, - mfScaleFactor); + addTriangleVectorToBody(aTriangleVector, pBody.get(), fDensity, fFriction, + static_cast<float>(fDefaultStaticBodyBounciness), mfScaleFactor); } else { - addEdgeShapeToBody(aPolyPolygon, pBody.get(), fDensity, fFriction, 0.1f, mfScaleFactor); + addEdgeShapeToBody(aPolyPolygon, pBody.get(), fDensity, fFriction, + static_cast<float>(fDefaultStaticBodyBounciness), mfScaleFactor); } return std::make_shared<box2DBody>(pBody, mfScaleFactor); @@ -776,6 +791,26 @@ void box2DBody::setAngle(const double fAngle) mpBox2DBody->SetTransform(mpBox2DBody->GetPosition(), ::basegfx::deg2rad(-fAngle)); } +void box2DBody::setDensityAndRestitution(const double fDensity, const double fRestitution) +{ + for (b2Fixture* pFixture = mpBox2DBody->GetFixtureList(); pFixture; + pFixture = pFixture->GetNext()) + { + pFixture->SetDensity(static_cast<float>(fDensity)); + pFixture->SetRestitution(static_cast<float>(fRestitution)); + } + mpBox2DBody->ResetMassData(); +} + +void box2DBody::setRestitution(const double fRestitution) +{ + for (b2Fixture* pFixture = mpBox2DBody->GetFixtureList(); pFixture; + pFixture = pFixture->GetNext()) + { + pFixture->SetRestitution(static_cast<float>(fRestitution)); + } +} + void box2DBody::setType(box2DBodyType eType) { mpBox2DBody->SetType(getBox2DInternalBodyType(eType)); |