summaryrefslogtreecommitdiff
path: root/slideshow
diff options
context:
space:
mode:
authorSarper Akdemir <q.sarperakdemir@gmail.com>2020-08-14 01:18:14 +0300
committerThorsten Behrens <Thorsten.Behrens@CIB.de>2020-08-22 11:24:16 +0200
commit394f74e6f168f034f7ed73e3027e4ff07f6b94b9 (patch)
treeb4da98e1d95e6bd3bf0e0a1cf30a9a5769907dc3 /slideshow
parent8a360d04e43410e729c0ee270be5447ce6c1cd03 (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')
-rw-r--r--slideshow/source/engine/animationfactory.cxx17
-rw-r--r--slideshow/source/engine/animationnodes/animationphysicsnode.cxx47
-rw-r--r--slideshow/source/engine/animationnodes/animationphysicsnode.hxx3
-rw-r--r--slideshow/source/engine/box2dtools.cxx47
-rw-r--r--slideshow/source/inc/animationfactory.hxx3
-rw-r--r--slideshow/source/inc/box2dtools.hxx10
6 files changed, 115 insertions, 12 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));
diff --git a/slideshow/source/inc/animationfactory.hxx b/slideshow/source/inc/animationfactory.hxx
index af3b9b9a4e49..3004c71308a9 100644
--- a/slideshow/source/inc/animationfactory.hxx
+++ b/slideshow/source/inc/animationfactory.hxx
@@ -137,6 +137,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 );
}
diff --git a/slideshow/source/inc/box2dtools.hxx b/slideshow/source/inc/box2dtools.hxx
index 08b0f4b557cf..0debf1da4ef0 100644
--- a/slideshow/source/inc/box2dtools.hxx
+++ b/slideshow/source/inc/box2dtools.hxx
@@ -221,7 +221,9 @@ public:
@param pShape
Pointer to the shape to alter the corresponding Box2D body of
*/
- Box2DBodySharedPtr makeShapeDynamic(const slideshow::internal::ShapeSharedPtr& pShape);
+ Box2DBodySharedPtr makeShapeDynamic(const css::uno::Reference<css::drawing::XShape>& xShape,
+ const basegfx::B2DVector& rStartVelocity,
+ const double fDensity, const double fBounciness);
/** Make the Box2D body corresponding to the given shape a static one
@@ -267,6 +269,8 @@ public:
void queueShapeAnimationEndUpdate(const css::uno::Reference<css::drawing::XShape>& xShape,
const slideshow::internal::AttributeType eAttrType);
+
+ void alertAnimationEndForShape(const slideshow::internal::ShapeSharedPtr& pShape);
};
/// Class that manages a single box2D Body
@@ -327,6 +331,10 @@ public:
void setAngle(const double fAngle);
+ void setDensityAndRestitution(const double fDensity, const double fRestitution);
+
+ void setRestitution(const double fRestitution);
+
/// Set type of the body
void setType(box2DBodyType eType);