Rebased ref, commits from common ancestor: commit 215dd4b85dd6c5afa52af313481543a7a0ecad4d Author: Sarper Akdemir <q.sarperakde...@gmail.com> AuthorDate: Thu Aug 6 10:32:55 2020 +0300 Commit: Sarper Akdemir <q.sarperakde...@gmail.com> CommitDate: Sat Aug 8 03:40:53 2020 +0300
make physics based animation effects always processed last Change-Id: I92d436aced6ef3ee2c8b0bf0167c1f7e642ba3b5 diff --git a/slideshow/source/engine/activitiesqueue.cxx b/slideshow/source/engine/activitiesqueue.cxx index ba982385356e..38e79d1e5677 100644 --- a/slideshow/source/engine/activitiesqueue.cxx +++ b/slideshow/source/engine/activitiesqueue.cxx @@ -50,6 +50,8 @@ namespace slideshow::internal { for( const auto& pActivity : maCurrentActivitiesWaiting ) pActivity->dispose(); + for( const auto& pActivity : maCurrentActivitiesToBeProcessedLast ) + pActivity->dispose(); for( const auto& pActivity : maCurrentActivitiesReinsert ) pActivity->dispose(); } @@ -59,7 +61,7 @@ namespace slideshow::internal } } - bool ActivitiesQueue::addActivity( const ActivitySharedPtr& pActivity ) + bool ActivitiesQueue::addActivity( const ActivitySharedPtr& pActivity, const bool bProcessLast ) { OSL_ENSURE( pActivity, "ActivitiesQueue::addActivity: activity ptr NULL" ); @@ -67,7 +69,17 @@ namespace slideshow::internal return false; // add entry to waiting list - maCurrentActivitiesWaiting.push_back( pActivity ); + if( !bProcessLast ) + { + maCurrentActivitiesWaiting.push_back( pActivity ); + } + else + { + // Activities that should be processed last is kept in a different + // ActivityQueue, and later added to the end of the maCurrentActivitiesWaiting + // at the start of ActivitiesQueue::process() + maCurrentActivitiesToBeProcessedLast.push_back( pActivity ); + } return true; } @@ -76,6 +88,12 @@ namespace slideshow::internal { SAL_INFO("slideshow.verbose", "ActivitiesQueue: outer loop heartbeat" ); + // If there are activities to be processed last add them to the end of the ActivitiesQueue + maCurrentActivitiesWaiting.insert( maCurrentActivitiesWaiting.end(), + maCurrentActivitiesToBeProcessedLast.begin(), + maCurrentActivitiesToBeProcessedLast.end() ); + maCurrentActivitiesToBeProcessedLast.clear(); + // accumulate time lag for all activities, and lag time // base if necessary: double fLag = 0.0; diff --git a/slideshow/source/engine/animationnodes/animationbasenode.cxx b/slideshow/source/engine/animationnodes/animationbasenode.cxx index 4dcb640795aa..7999b5a7654a 100644 --- a/slideshow/source/engine/animationnodes/animationbasenode.cxx +++ b/slideshow/source/engine/animationnodes/animationbasenode.cxx @@ -23,6 +23,7 @@ #include <com/sun/star/animations/Timing.hpp> #include <com/sun/star/animations/AnimationAdditiveMode.hpp> #include <com/sun/star/presentation/ShapeAnimationSubType.hpp> +#include <com/sun/star/animations/AnimationNodeType.hpp> #include "nodetools.hxx" #include <doctreenode.hxx> @@ -294,7 +295,10 @@ void AnimationBaseNode::activate_st() mpActivity->setTargets( getShape(), maAttributeLayerHolder.get() ); // add to activities queue - getContext().mrActivitiesQueue.addActivity( mpActivity ); + if( mxAnimateNode->getType() == css::animations::AnimationNodeType::ANIMATEPHYSICS ) + getContext().mrActivitiesQueue.addActivity(mpActivity, true); + else + getContext().mrActivitiesQueue.addActivity( mpActivity ); } else { // Actually, DO generate the event for empty activity, diff --git a/slideshow/source/inc/activitiesqueue.hxx b/slideshow/source/inc/activitiesqueue.hxx index b4f88b1b39d1..76dc981f8f65 100644 --- a/slideshow/source/inc/activitiesqueue.hxx +++ b/slideshow/source/inc/activitiesqueue.hxx @@ -57,7 +57,7 @@ namespace slideshow /** Add the given activity to the queue. */ - bool addActivity( const ActivitySharedPtr& pActivity ); + bool addActivity( const ActivitySharedPtr& pActivity, const bool bProcessLast = false ); /** Process the activities queue. @@ -96,6 +96,11 @@ namespace slideshow // await processing for this // round + ActivityQueue maCurrentActivitiesToBeProcessedLast; // activities that will be + // added to the end of + // maCurrentActivitiesWaiting at + // the start of process() + ActivityQueue maCurrentActivitiesReinsert; // currently running // activities, that are // already processed for commit ec1c95dc4a4341a358d3dd1781f18c012e234a4f Author: Sarper Akdemir <q.sarperakde...@gmail.com> AuthorDate: Mon Jul 27 23:02:48 2020 +0300 Commit: Sarper Akdemir <q.sarperakde...@gmail.com> CommitDate: Sat Aug 8 03:40:52 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 737687713614..0711027597e9 100644 --- a/slideshow/source/engine/box2dtools.cxx +++ b/slideshow/source/engine/box2dtools.cxx @@ -11,6 +11,13 @@ #include <Box2D/Box2D.h> #include <shapemanager.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolygontriangulator.hxx> +#include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp> + +#include <svx/svdobj.hxx> +#include <svx/svdoashp.hxx> #define BOX2D_SLIDE_SIZE_IN_METERS 100.00f @@ -62,6 +69,124 @@ b2Vec2 convertB2DPointToBox2DVec2(const basegfx::B2DPoint& aPoint, const double return { static_cast<float>(aPoint.getX() * fScaleFactor), static_cast<float>(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 = &aPolygonShape; + aFixture.density = fDensity; + aFixture.friction = fFriction; + aFixture.restitution = fRestitution; + aBody->CreateFixture(&aFixture); + } + } +} + +// 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 = &aPolygonShape; + aFixture.density = fDensity; + aFixture.friction = fFriction; + aFixture.restitution = fRestitution; + aBody->CreateFixture(&aFixture); + + aEdgeBoxVertices[0] = aEdgeBoxVertices[2]; + aEdgeBoxVertices[1] = aEdgeBoxVertices[3]; + } + } +} + +void addEdgeShapeToBody(const basegfx::B2DPolyPolygon& rPolyPolygon, b2Body* aBody, + const float fDensity, const float fFriction, const float fRestitution, + const double fScaleFactor) +{ + for (const basegfx::B2DPolygon& rPolygon : rPolyPolygon) + { + addEdgeShapeToBody(rPolygon, aBody, fDensity, fFriction, fRestitution, fScaleFactor); + } +} } box2DWorld::box2DWorld(const ::basegfx::B2DVector& rSlideSize) @@ -224,7 +349,8 @@ void box2DWorld::initateAllShapesAsStaticBodies( slideshow::internal::ShapeSharedPtr pShape = aIt->second; if (pShape->isForeground()) { - Box2DBodySharedPtr pBox2DBody = createStaticBodyFromBoundingBox(pShape); + Box2DBodySharedPtr pBox2DBody = createStaticBody(pShape); + mpXShapeToBodyMap.insert(std::make_pair(pShape->getXShape(), pBox2DBody)); if (!pShape->isVisible()) { @@ -354,14 +480,12 @@ Box2DBodySharedPtr box2DWorld::makeBodyStatic(const Box2DBodySharedPtr& pBox2DBo return pBox2DBody; } -Box2DBodySharedPtr -box2DWorld::createStaticBodyFromBoundingBox(const slideshow::internal::ShapeSharedPtr& rShape, - const float fDensity, const float fFriction) +Box2DBodySharedPtr box2DWorld::createStaticBody(const slideshow::internal::ShapeSharedPtr& rShape, + const float fDensity, const float fFriction) { assert(mpBox2DWorld); + ::basegfx::B2DRectangle aShapeBounds = rShape->getBounds(); - double fShapeWidth = aShapeBounds.getWidth() * mfScaleFactor; - double fShapeHeight = aShapeBounds.getHeight() * mfScaleFactor; b2BodyDef aBodyDef; aBodyDef.type = b2_staticBody; @@ -371,16 +495,63 @@ box2DWorld::createStaticBodyFromBoundingBox(const slideshow::internal::ShapeShar pB2Body->GetWorld()->DestroyBody(pB2Body); }); - b2PolygonShape aDynamicBox; - aDynamicBox.SetAsBox(static_cast<float>(fShapeWidth / 2), static_cast<float>(fShapeHeight / 2)); + SdrObject* pSdrObject = SdrObject::getSdrObjectFromXShape(rShape->getXShape()); - b2FixtureDef aFixtureDef; - aFixtureDef.shape = &aDynamicBox; - aFixtureDef.density = fDensity; - aFixtureDef.friction = fFriction; - aFixtureDef.restitution = 0.1f; + auto aShapeType = rShape->getXShape()->getShapeType(); + + basegfx::B2DPolyPolygon aPolyPolygon; + // workaround: + // TakeXorPoly() doesn't return beziers for CustomShapes and we want the beziers + // so that we can decide the complexity of the polygons generated from them + if (aShapeType == "com.sun.star.drawing.CustomShape") + { + aPolyPolygon = static_cast<SdrObjCustomShape*>(pSdrObject)->GetLineGeometry(true); + } + else + { + aPolyPolygon = pSdrObject->TakeXorPoly(); + } + + // make beziers into polygons, using a high degree angle as fAngleBound in + // adaptiveSubdivideByAngle reduces complexity of the resulting polygon shapes + aPolyPolygon = aPolyPolygon.areControlPointsUsed() + ? basegfx::utils::adaptiveSubdivideByAngle(aPolyPolygon, 20) + : aPolyPolygon; + aPolyPolygon.removeDoublePoints(); + + // make polygon coordinates relative to the center of the shape instead of top left of the slide + aPolyPolygon + = basegfx::utils::distort(aPolyPolygon, aPolyPolygon.getB2DRange(), + { -aShapeBounds.getWidth() / 2, -aShapeBounds.getHeight() / 2 }, + { aShapeBounds.getWidth() / 2, -aShapeBounds.getHeight() / 2 }, + { -aShapeBounds.getWidth() / 2, aShapeBounds.getHeight() / 2 }, + { aShapeBounds.getWidth() / 2, aShapeBounds.getHeight() / 2 }); + + if (pSdrObject->IsClosedObj() && !pSdrObject->IsEdgeObj() && pSdrObject->HasFillStyle()) + { + basegfx::triangulator::B2DTriangleVector aTriangleVector; + for (auto& rPolygon : aPolyPolygon) + { + if (rPolygon.isClosed()) + { + basegfx::triangulator::B2DTriangleVector aTempTriangleVector( + basegfx::triangulator::triangulate(rPolygon)); + aTriangleVector.insert(aTriangleVector.end(), aTempTriangleVector.begin(), + aTempTriangleVector.end()); + } + else + { + addEdgeShapeToBody(rPolygon, pBody.get(), fDensity, fFriction, 0.1f, mfScaleFactor); + } + } + addTriangleVectorToBody(aTriangleVector, pBody.get(), fDensity, fFriction, 0.1f, + mfScaleFactor); + } + else + { + addEdgeShapeToBody(aPolyPolygon, pBody.get(), fDensity, fFriction, 0.1f, mfScaleFactor); + } - pBody->CreateFixture(&aFixtureDef); return std::make_shared<box2DBody>(pBody, mfScaleFactor); } @@ -417,7 +588,6 @@ void box2DBody::setAngleByAngularVelocity(const double fDesiredAngle, const doub double fDeltaAngle = fDesiredAngle - getAngle(); - // temporary hack for repeating animation effects while (fDeltaAngle > 180 || fDeltaAngle < -180) // if it is bigger than 180 opposite rotation is actually closer fDeltaAngle += fDeltaAngle > 0 ? -360 : +360; diff --git a/slideshow/source/inc/box2dtools.hxx b/slideshow/source/inc/box2dtools.hxx index aafdfbb64bde..f9fea6150ae6 100644 --- a/slideshow/source/inc/box2dtools.hxx +++ b/slideshow/source/inc/box2dtools.hxx @@ -213,10 +213,9 @@ public: */ Box2DBodySharedPtr makeBodyStatic(const Box2DBodySharedPtr& pBox2DBody); - /// Create a static body from the given shape's bounding box - Box2DBodySharedPtr - createStaticBodyFromBoundingBox(const slideshow::internal::ShapeSharedPtr& rShape, - const float fDensity = 1.0f, const float fFriction = 0.3f); + /// Create a static body from the given shape's geometry + Box2DBodySharedPtr createStaticBody(const slideshow::internal::ShapeSharedPtr& rShape, + const float fDensity = 1.0f, const float fFriction = 0.3f); /// Initiate all the shapes in the current slide in the box2DWorld as static ones void commit eceaef3735400beba6db58024a3a22463f0889ee Author: Sarper Akdemir <q.sarperakde...@gmail.com> AuthorDate: Thu Jun 25 20:33:05 2020 +0300 Commit: Sarper Akdemir <q.sarperakde...@gmail.com> CommitDate: Sat Aug 8 03:40:52 2020 +0300 make physics based animation effects importable-exportable Makes physics based animation effects importable and exportable on content.xml. Uses one new xml token animateSimulation. Also adds a new animation preset called Physics Basic that is available under Emphasis animation effect category. Change-Id: I38b0511f973668655cff78becebe3f1e628d9083 diff --git a/animations/source/animcore/animcore.component b/animations/source/animcore/animcore.component index 2f490aa0ae06..cd691f05e0ba 100644 --- a/animations/source/animcore/animcore.component +++ b/animations/source/animcore/animcore.component @@ -30,6 +30,10 @@ <implementation name="animcore::AnimateMotion" constructor="com_sun_star_animations_AnimateMotion_get_implementation"> <service name="com.sun.star.animations.AnimateMotion"/> + </implementation> + <implementation name="animcore::AnimatePhysics" + constructor="com_sun_star_animations_AnimatePhysics_get_implementation"> + <service name="com.sun.star.animations.AnimatePhysics"/> </implementation> <implementation name="animcore::AnimateSet" constructor="com_sun_star_animations_AnimateSet_get_implementation"> diff --git a/animations/source/animcore/animcore.cxx b/animations/source/animcore/animcore.cxx index f3ffe8c4190a..88e42772936a 100644 --- a/animations/source/animcore/animcore.cxx +++ b/animations/source/animcore/animcore.cxx @@ -291,7 +291,7 @@ private: const sal_Int16 mnNodeType; // for XTypeProvider - static std::array<Sequence< Type >*, 12> mpTypes; + static std::array<Sequence< Type >*, 13> mpTypes; // attributes for the XAnimationNode interface implementation Any maBegin, maDuration, maEnd, maEndSync, maRepeatCount, maRepeatDuration; @@ -394,7 +394,7 @@ Any SAL_CALL TimeContainerEnumeration::nextElement() } -std::array<Sequence< Type >*, 12> AnimationNode::mpTypes = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }; +std::array<Sequence< Type >*, 13> AnimationNode::mpTypes = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }; AnimationNode::AnimationNode( sal_Int16 nNodeType ) : maChangeListener(maMutex), @@ -565,6 +565,16 @@ static OUString getImplementationName_ANIMATEMOTION() return "animcore::AnimateMotion"; } +static Sequence<OUString> getSupportedServiceNames_ANIMATEPHYSICS() +{ + return { "com.sun.star.animations.AnimatePhysics" }; +} + +static OUString getImplementationName_ANIMATEPHYSICS() +{ + return "animcore::AnimatePhysics"; +} + static Sequence<OUString> getSupportedServiceNames_ANIMATETRANSFORM() { return { "com.sun.star.animations.AnimateTransform" }; @@ -658,6 +668,12 @@ Any SAL_CALL AnimationNode::queryInterface( const Type& aType ) static_cast< XAnimate * >( static_cast< XAnimateMotion * >(this) ), static_cast< XAnimateMotion * >( this ) ); break; + case AnimationNodeType::ANIMATEPHYSICS: + aRet = ::cppu::queryInterface( + aType, + static_cast< XAnimate * >( static_cast< XAnimateMotion * >(this) ), + static_cast< XAnimateMotion * >( this ) ); + break; case AnimationNodeType::ANIMATECOLOR: aRet = ::cppu::queryInterface( aType, @@ -717,6 +733,7 @@ void AnimationNode::initTypeProvider( sal_Int16 nNodeType ) throw() 8, // TRANSITIONFILTER 8, // AUDIO 8, // COMMAND + 8, // ANIMATEPHYSICS }; // collect types @@ -749,6 +766,9 @@ void AnimationNode::initTypeProvider( sal_Int16 nNodeType ) throw() case AnimationNodeType::ANIMATEMOTION: pTypeAr[nPos++] = cppu::UnoType<XAnimateMotion>::get(); break; + case AnimationNodeType::ANIMATEPHYSICS: + pTypeAr[nPos++] = cppu::UnoType<XAnimateMotion>::get(); + break; case AnimationNodeType::ANIMATECOLOR: pTypeAr[nPos++] = cppu::UnoType<XAnimateColor>::get(); break; @@ -817,6 +837,8 @@ OUString AnimationNode::getImplementationName() return getImplementationName_ANIMATECOLOR(); case AnimationNodeType::ANIMATEMOTION: return getImplementationName_ANIMATEMOTION(); + case AnimationNodeType::ANIMATEPHYSICS: + return getImplementationName_ANIMATEPHYSICS(); case AnimationNodeType::TRANSITIONFILTER: return getImplementationName_TRANSITIONFILTER(); case AnimationNodeType::ANIMATETRANSFORM: @@ -854,6 +876,8 @@ Sequence< OUString > AnimationNode::getSupportedServiceNames() return getSupportedServiceNames_ANIMATECOLOR(); case AnimationNodeType::ANIMATEMOTION: return getSupportedServiceNames_ANIMATEMOTION(); + case AnimationNodeType::ANIMATEPHYSICS: + return getSupportedServiceNames_ANIMATEPHYSICS(); case AnimationNodeType::TRANSITIONFILTER: return getSupportedServiceNames_TRANSITIONFILTER(); case AnimationNodeType::ANIMATETRANSFORM: @@ -2041,6 +2065,13 @@ com_sun_star_animations_AnimateMotion_get_implementation(css::uno::XComponentCon return cppu::acquire(new animcore::AnimationNode(ANIMATEMOTION)); } +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +com_sun_star_animations_AnimatePhysics_get_implementation(css::uno::XComponentContext*, + css::uno::Sequence<css::uno::Any> const &) +{ + return cppu::acquire(new animcore::AnimationNode(ANIMATEPHYSICS)); +} + extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* com_sun_star_animations_AnimateTransform_get_implementation(css::uno::XComponentContext*, css::uno::Sequence<css::uno::Any> const &) diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx index 49178ebdc996..ffa9206d4f44 100644 --- a/include/xmloff/xmltoken.hxx +++ b/include/xmloff/xmltoken.hxx @@ -2791,6 +2791,7 @@ namespace xmloff::token { XML_MULTIPLY, XML_ANIMATE, XML_ANIMATEMOTION, + XML_ANIMATEPHYSICS, XML_ANIMATETRANSFORM, XML_ANIMATECOLOR, XML_TRANSITIONFILTER, diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk index 68a493cfa6ac..8d78a3c2f696 100644 --- a/offapi/UnoApi_offapi.mk +++ b/offapi/UnoApi_offapi.mk @@ -29,6 +29,7 @@ $(eval $(call gb_UnoApi_use_api,offapi,\ $(eval $(call gb_UnoApi_add_idlfiles_nohdl,offapi,com/sun/star/animations,\ AnimateColor \ AnimateMotion \ + AnimatePhysics \ AnimateSet \ Audio \ Command \ diff --git a/offapi/com/sun/star/animations/AnimatePhysics.idl b/offapi/com/sun/star/animations/AnimatePhysics.idl new file mode 100644 index 000000000000..87fe960e611c --- /dev/null +++ b/offapi/com/sun/star/animations/AnimatePhysics.idl @@ -0,0 +1,25 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#ifndef __com_sun_star_animations_AnimatePhysics_idl__ +#define __com_sun_star_animations_AnimatePhysics_idl__ + +#include <com/sun/star/animations/XAnimationNode.idl> + + +module com { module sun { module star { module animations { + + +service AnimatePhysics : com::sun::star::animations::XAnimationNode; + + +}; }; }; }; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/officecfg/registry/data/org/openoffice/Office/UI/Effects.xcu b/officecfg/registry/data/org/openoffice/Office/UI/Effects.xcu index 1f9267d958e1..84156c1d3722 100644 --- a/officecfg/registry/data/org/openoffice/Office/UI/Effects.xcu +++ b/officecfg/registry/data/org/openoffice/Office/UI/Effects.xcu @@ -1035,6 +1035,11 @@ <value xml:lang="en-US">Vertical Figure 8</value> </prop> </node> + <node oor:name="libo-physics-basic" oor:op="replace"> + <prop oor:name="Label" oor:type="xs:string"> + <value xml:lang="en-US">Physics Basic</value> + </prop> + </node> <node oor:name="ooo-media-start" oor:op="replace"> <prop oor:name="Label" oor:type="xs:string"> <value xml:lang="en-US">Start media</value> @@ -2500,7 +2505,7 @@ <value xml:lang="en-US">Exciting</value> </prop> <prop oor:name="Effects" oor:type="oor:string-list"> - <value oor:separator=";">ooo-emphasis-blast;ooo-emphasis-bold-reveal;ooo-emphasis-style-emphasis;ooo-emphasis-wave;ooo-emphasis-blink</value> + <value oor:separator=";">ooo-emphasis-blast;ooo-emphasis-bold-reveal;ooo-emphasis-style-emphasis;ooo-emphasis-wave;ooo-emphasis-blink;libo-physics-basic</value> </prop> </node> </node> diff --git a/sd/xml/effects.xml b/sd/xml/effects.xml index 393ad5d50263..d3e03da56ee2 100644 --- a/sd/xml/effects.xml +++ b/sd/xml/effects.xml @@ -2639,6 +2639,13 @@ </anim:par> </anim:par> </anim:par> + <anim:par smil:begin="indefinite" smil:fill="hold"> + <anim:par smil:begin="0" smil:fill="hold"> + <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="libo-physics-basic"> + <anim:animatePhysics smil:dur="4" smil:fill="hold"/> + </anim:par> + </anim:par> + </anim:par> <anim:par smil:begin="indefinite" smil:fill="hold"> <anim:par smil:begin="0" smil:fill="hold"> <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="media-call" pres:preset-id="ooo-media-start"> diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx index 8d9a70f5e082..03e777185d0e 100644 --- a/xmloff/source/core/xmltoken.cxx +++ b/xmloff/source/core/xmltoken.cxx @@ -2792,6 +2792,7 @@ namespace xmloff::token { TOKEN( "multiply", XML_MULTIPLY ), TOKEN( "animate", XML_ANIMATE ), TOKEN( "animateMotion", XML_ANIMATEMOTION ), + TOKEN( "animatePhysics", XML_ANIMATEPHYSICS ), TOKEN( "animateTransform", XML_ANIMATETRANSFORM ), TOKEN( "animateColor", XML_ANIMATECOLOR ), TOKEN( "transitionFilter", XML_TRANSITIONFILTER ), diff --git a/xmloff/source/draw/animationexport.cxx b/xmloff/source/draw/animationexport.cxx index 7aa293e75716..f217e46a709d 100644 --- a/xmloff/source/draw/animationexport.cxx +++ b/xmloff/source/draw/animationexport.cxx @@ -697,6 +697,7 @@ void AnimationsExporterImpl::prepareNode( const Reference< XAnimationNode >& xNo case AnimationNodeType::ANIMATE: case AnimationNodeType::SET: case AnimationNodeType::ANIMATEMOTION: + case AnimationNodeType::ANIMATEPHYSICS: case AnimationNodeType::ANIMATECOLOR: case AnimationNodeType::ANIMATETRANSFORM: case AnimationNodeType::TRANSITIONFILTER: @@ -947,6 +948,7 @@ void AnimationsExporterImpl::exportNode( const Reference< XAnimationNode >& xNod case AnimationNodeType::ANIMATE: case AnimationNodeType::SET: case AnimationNodeType::ANIMATEMOTION: + case AnimationNodeType::ANIMATEPHYSICS: case AnimationNodeType::ANIMATECOLOR: case AnimationNodeType::ANIMATETRANSFORM: case AnimationNodeType::TRANSITIONFILTER: @@ -1089,6 +1091,10 @@ void AnimationsExporterImpl::exportAnimate( const Reference< XAnimate >& xAnimat { eAttributeName = XML_ANIMATEMOTION; } + else if( nNodeType == AnimationNodeType::ANIMATEPHYSICS ) + { + eAttributeName = XML_ANIMATEPHYSICS; + } else { OUString sTemp( xAnimate->getAttributeName() ); @@ -1234,6 +1240,15 @@ void AnimationsExporterImpl::exportAnimate( const Reference< XAnimate >& xAnimat } break; + case AnimationNodeType::ANIMATEPHYSICS: + { + eElementToken = XML_ANIMATEPHYSICS; + + Reference< XAnimateMotion > xAnimateMotion( xAnimate, UNO_QUERY_THROW ); + aTemp = xAnimateMotion->getOrigin(); + } + break; + case AnimationNodeType::ANIMATECOLOR: { eElementToken = XML_ANIMATECOLOR; @@ -1295,7 +1310,14 @@ void AnimationsExporterImpl::exportAnimate( const Reference< XAnimate >& xAnimat break; } - SvXMLElementExport aElement( *mxExport, XML_NAMESPACE_ANIMATION, eElementToken, true, true ); + if( eElementToken == XML_ANIMATEPHYSICS ) // not a standart should use the extension namespace + { + SvXMLElementExport aElement( *mxExport, XML_NAMESPACE_LO_EXT, eElementToken, true, true ); + } + else + { + SvXMLElementExport aElement( *mxExport, XML_NAMESPACE_ANIMATION, eElementToken, true, true ); + } } catch (const Exception&) @@ -1437,6 +1459,7 @@ void AnimationsExporterImpl::convertValue( XMLTokenEnum eAttributeName, OUString case XML_HEIGHT: case XML_ANIMATETRANSFORM: case XML_ANIMATEMOTION: + case XML_ANIMATEPHYSICS: { if( auto aString = o3tl::tryAccess<OUString>(rValue) ) { diff --git a/xmloff/source/draw/animationimport.cxx b/xmloff/source/draw/animationimport.cxx index ebccff3d1a22..52e020e8f939 100644 --- a/xmloff/source/draw/animationimport.cxx +++ b/xmloff/source/draw/animationimport.cxx @@ -460,6 +460,8 @@ AnimationNodeContext::AnimationNodeContext( pServiceName = "com.sun.star.animations.AnimateSet"; break; case XML_ANIMATEMOTION: pServiceName = "com.sun.star.animations.AnimateMotion"; break; + case XML_ANIMATEPHYSICS: + pServiceName = "com.sun.star.animations.AnimatePhysics"; break; case XML_ANIMATECOLOR: pServiceName = "com.sun.star.animations.AnimateColor"; break; case XML_ANIMATETRANSFORM: diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt index 34b9af91e03c..368cf7d67014 100644 --- a/xmloff/source/token/tokens.txt +++ b/xmloff/source/token/tokens.txt @@ -2620,6 +2620,7 @@ additive multiply animate animateMotion +animatePhysics animateTransform animateColor transitionFilter commit 512cf483b3c9cfd4a2b01524474290e3f40a9103 Author: Sarper Akdemir <q.sarperakde...@gmail.com> AuthorDate: Thu Jun 11 19:29:38 2020 +0300 Commit: Sarper Akdemir <q.sarperakde...@gmail.com> CommitDate: Sat Aug 8 03:40:44 2020 +0300 make physics based animation effects part of the animation engine Wiring up and creating required classes for simulated animations to be part of the animation engine. Creating a new animation node AnimationPhysicsNode for physics based animation effects and PhysicsAnimation class that inherits the NumberAnimation in the animation factory. Change-Id: I1f125df5324673e9937b8164c0fc267c9683afa0 diff --git a/offapi/com/sun/star/animations/AnimationNodeType.idl b/offapi/com/sun/star/animations/AnimationNodeType.idl index 31bed11ff728..d0cd6e268fd6 100644 --- a/offapi/com/sun/star/animations/AnimationNodeType.idl +++ b/offapi/com/sun/star/animations/AnimationNodeType.idl @@ -68,6 +68,9 @@ constants AnimationNodeType /** Defines a command effect. */ const short COMMAND = 11; + /** Defines a physics animation */ + const short ANIMATEPHYSICS = 12; + }; diff --git a/slideshow/Library_slideshow.mk b/slideshow/Library_slideshow.mk index 53324ea25dcc..3ff098c01639 100644 --- a/slideshow/Library_slideshow.mk +++ b/slideshow/Library_slideshow.mk @@ -75,6 +75,7 @@ $(eval $(call gb_Library_add_exception_objects,slideshow,\ slideshow/source/engine/animationnodes/animationnodefactory \ slideshow/source/engine/animationnodes/animationpathmotionnode \ slideshow/source/engine/animationnodes/animationsetnode \ + slideshow/source/engine/animationnodes/animationphysicsnode \ slideshow/source/engine/animationnodes/animationtransformnode \ slideshow/source/engine/animationnodes/animationtransitionfilternode \ slideshow/source/engine/animationnodes/basecontainernode \ diff --git a/slideshow/source/engine/animationfactory.cxx b/slideshow/source/engine/animationfactory.cxx index f81c37b77df3..d402f0a22044 100644 --- a/slideshow/source/engine/animationfactory.cxx +++ b/slideshow/source/engine/animationfactory.cxx @@ -35,6 +35,7 @@ #include <basegfx/polygon/b2dpolygontools.hxx> #include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <box2dtools.hxx> using namespace ::com::sun::star; @@ -203,7 +204,8 @@ namespace slideshow::internal sal_Int16 nAdditive, const ShapeManagerSharedPtr& rShapeManager, const ::basegfx::B2DVector& rSlideSize, - int nFlags ) : + int nFlags, + const box2d::utils::Box2DWorldSharedPtr& pBox2DWorld ) : maPathPoly(), mpShape(), mpAttrLayer(), @@ -212,7 +214,8 @@ namespace slideshow::internal maShapeOrig(), mnFlags( nFlags ), mbAnimationStarted( false ), - mnAdditive( nAdditive ) + mnAdditive( nAdditive ), + mpBox2DWorld( pBox2DWorld ) { ENSURE_OR_THROW( rShapeManager, "PathAnimation::PathAnimation(): Invalid ShapeManager" ); @@ -283,6 +286,10 @@ namespace slideshow::internal if( mpShape->isContentChanged() ) mpShapeManager->notifyShapeUpdate( mpShape ); + + // since animation ended zero out the linear velocity + if( mpBox2DWorld->isInitialized() ) + mpBox2DWorld->queueLinearVelocityUpdate( mpShape->getXShape(), {0,0}); } } @@ -313,7 +320,11 @@ namespace slideshow::internal mpAttrLayer->setPosition( rOutPos ); if( mpShape->isContentChanged() ) + { mpShapeManager->notifyShapeUpdate( mpShape ); + if ( mpBox2DWorld->isInitialized() ) + mpBox2DWorld->queuePositionUpdate( mpShape->getXShape(), rOutPos ); + } return true; } @@ -339,8 +350,152 @@ namespace slideshow::internal const int mnFlags; bool mbAnimationStarted; sal_Int16 mnAdditive; + box2d::utils::Box2DWorldSharedPtr mpBox2DWorld; }; + class PhysicsAnimation : public NumberAnimation + { + public: + PhysicsAnimation( const ::box2d::utils::Box2DWorldSharedPtr& pBox2DWorld, + const double fDuration, + const ShapeManagerSharedPtr& rShapeManager, + const ::basegfx::B2DVector& rSlideSize, + int nFlags ) : + mpShape(), + mpAttrLayer(), + mpShapeManager( rShapeManager ), + maPageSize( rSlideSize ), + mnFlags( nFlags ), + mbAnimationStarted( false ), + mpBox2DBody(), + mpBox2DWorld( pBox2DWorld ), + mfDuration(fDuration), + mfPreviousElapsedTime(0.00f), + mbIsBox2dWorldStepper(false) + { + ENSURE_OR_THROW( rShapeManager, + "PhysicsAnimation::PhysicsAnimation(): Invalid ShapeManager" ); + } + + virtual ~PhysicsAnimation() override + { + end_(); + } + + // Animation interface + + virtual void prefetch() override + {} + + virtual void start( const AnimatableShapeSharedPtr& rShape, + const ShapeAttributeLayerSharedPtr& rAttrLayer ) override + { + OSL_ENSURE( !mpShape, + "PhysicsAnimation::start(): Shape already set" ); + OSL_ENSURE( !mpAttrLayer, + "PhysicsAnimation::start(): Attribute layer already set" ); + + mpShape = rShape; + mpAttrLayer = rAttrLayer; + + if( !(mpBox2DWorld->isInitialized()) ) + mpBox2DWorld->initiateWorld(maPageSize); + + if( !(mpBox2DWorld->shapesInitialized()) ) + mpBox2DWorld->initateAllShapesAsStaticBodies( mpShapeManager ); + + ENSURE_OR_THROW( rShape, + "PhysicsAnimation::start(): Invalid shape" ); + ENSURE_OR_THROW( rAttrLayer, + "PhysicsAnimation::start(): Invalid attribute layer" ); + + mpBox2DBody = mpBox2DWorld->makeShapeDynamic( rShape ); + + if( !mbAnimationStarted ) + { + mbAnimationStarted = true; + + if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) ) + mpShapeManager->enterAnimationMode( mpShape ); + } + } + + virtual void end() override { end_(); } + void end_() + { + if( mbIsBox2dWorldStepper ) + { + mbIsBox2dWorldStepper = false; + mpBox2DWorld->setHasWorldStepper(false); + } + + if( mbAnimationStarted ) + { + mbAnimationStarted = false; + + // Animation have ended for this body, make it static + mpBox2DWorld->makeBodyStatic( mpBox2DBody ); + + if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) ) + mpShapeManager->leaveAnimationMode( mpShape ); + + if( mpShape->isContentChanged() ) + mpShapeManager->notifyShapeUpdate( mpShape ); + } + } + + // NumberAnimation interface + + + virtual bool operator()( double nValue ) override + { + ENSURE_OR_RETURN_FALSE( mpAttrLayer && mpShape, + "PhysicsAnimation::operator(): Invalid ShapeAttributeLayer" ); + + // if there are multiple physics animations going in parallel + // Only one of them should step the box2d world + if( !mpBox2DWorld->hasWorldStepper() ) + { + mbIsBox2dWorldStepper = true; + mpBox2DWorld->setHasWorldStepper(true); + } + + if( mbIsBox2dWorldStepper ) + { + double fPassedTime = (mfDuration * nValue) - mfPreviousElapsedTime; + mfPreviousElapsedTime += mpBox2DWorld->stepAmount( fPassedTime ); + } + + mpAttrLayer->setPosition( mpBox2DBody->getPosition() ); + mpAttrLayer->setRotationAngle( mpBox2DBody->getAngle() ); + + if( mpShape->isContentChanged() ) + mpShapeManager->notifyShapeUpdate( mpShape ); + + return true; + } + + virtual double getUnderlyingValue() const override + { + ENSURE_OR_THROW( mpAttrLayer, + "PhysicsAnimation::getUnderlyingValue(): Invalid ShapeAttributeLayer" ); + + return 0.0; + } + + private: + AnimatableShapeSharedPtr mpShape; + ShapeAttributeLayerSharedPtr mpAttrLayer; + ShapeManagerSharedPtr mpShapeManager; + const ::basegfx::B2DSize maPageSize; + const int mnFlags; + bool mbAnimationStarted; + box2d::utils::Box2DBodySharedPtr mpBox2DBody; + box2d::utils::Box2DWorldSharedPtr mpBox2DWorld; + double mfDuration; + double mfPreviousElapsedTime; + bool mbIsBox2dWorldStepper; + }; /** GenericAnimation template @@ -405,7 +560,9 @@ namespace slideshow::internal ValueT (ShapeAttributeLayer::*pGetValue)() const, void (ShapeAttributeLayer::*pSetValue)( const ValueT& ), const ModifierFunctor& rGetterModifier, - const ModifierFunctor& rSetterModifier ) : + const ModifierFunctor& rSetterModifier, + const OUString& rAttrName, + const box2d::utils::Box2DWorldSharedPtr& pBox2DWorld ) : mpShape(), mpAttrLayer(), mpShapeManager( rShapeManager ), @@ -416,7 +573,9 @@ namespace slideshow::internal maSetterModifier( rSetterModifier ), mnFlags( nFlags ), maDefaultValue(rDefaultValue), - mbAnimationStarted( false ) + mbAnimationStarted( false ), + maAttrName( rAttrName ), + mpBox2DWorld ( pBox2DWorld ) { ENSURE_OR_THROW( rShapeManager, "GenericAnimation::GenericAnimation(): Invalid ShapeManager" ); @@ -473,6 +632,22 @@ namespace slideshow::internal mbAnimationStarted = false; + if( mpBox2DWorld && mpBox2DWorld->isInitialized() ) + { + switch( mapAttributeName( maAttrName ) ) + { + case AttributeType::Rotate: + mpBox2DWorld->queueAngularVelocityUpdate( mpShape->getXShape(), 0.0f ); + break; + case AttributeType::PosX: + case AttributeType::PosY: + mpBox2DWorld->queueLinearVelocityUpdate( mpShape->getXShape(), {0,0} ); + break; + default: + break; + } + } + if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) ) mpShapeManager->leaveAnimationMode( mpShape ); @@ -529,6 +704,25 @@ namespace slideshow::internal ((*mpAttrLayer).*mpSetValueFunc)( maSetterModifier( x ) ); + if( mpBox2DWorld && mpBox2DWorld->isInitialized() ) + { + switch( mapAttributeName( maAttrName ) ){ + case AttributeType::Visibility: + mpBox2DWorld->queueShapeVisibilityUpdate( mpShape->getXShape(), (*mpAttrLayer).getVisibility() ); + break; + case AttributeType::Rotate: + mpBox2DWorld->queueRotationUpdate( mpShape->getXShape(), (*mpAttrLayer).getRotationAngle() ); + break; + case AttributeType::PosX: + case AttributeType::PosY: + mpBox2DWorld->queuePositionUpdate( mpShape->getXShape(), + { (*mpAttrLayer).getPosX(), (*mpAttrLayer).getPosY() } ); + break; + default: + break; + } + } + if( mpShape->isContentChanged() ) mpShapeManager->notifyShapeUpdate( mpShape ); @@ -564,6 +758,9 @@ namespace slideshow::internal const ValueT maDefaultValue; bool mbAnimationStarted; + + const OUString maAttrName; + const box2d::utils::Box2DWorldSharedPtr mpBox2DWorld; }; //Current c++0x draft (apparently) has std::identity, but not operator() @@ -585,7 +782,9 @@ namespace slideshow::internal bool (ShapeAttributeLayer::*pIsValid)() const, const typename AnimationBase::ValueType& rDefaultValue, typename AnimationBase::ValueType (ShapeAttributeLayer::*pGetValue)() const, - void (ShapeAttributeLayer::*pSetValue)( const typename AnimationBase::ValueType& ) ) + void (ShapeAttributeLayer::*pSetValue)( const typename AnimationBase::ValueType& ), + const OUString& rAttrName, + const box2d::utils::Box2DWorldSharedPtr& pBox2DWorld ) { return std::make_shared<GenericAnimation< AnimationBase, SGI_identity< typename AnimationBase::ValueType > >>( @@ -597,7 +796,9 @@ namespace slideshow::internal pSetValue, // no modification necessary, use identity functor here SGI_identity< typename AnimationBase::ValueType >(), - SGI_identity< typename AnimationBase::ValueType >() ); + SGI_identity< typename AnimationBase::ValueType >(), + rAttrName, + pBox2DWorld ); } class Scaler @@ -625,7 +826,9 @@ namespace slideshow::internal double nDefaultValue, double (ShapeAttributeLayer::*pGetValue)() const, void (ShapeAttributeLayer::*pSetValue)( const double& ), - double nScaleValue ) + double nScaleValue, + const OUString& rAttrName, + const box2d::utils::Box2DWorldSharedPtr& pBox2DWorld ) { return std::make_shared<GenericAnimation< NumberAnimation, Scaler >>( rShapeManager, nFlags, @@ -634,7 +837,9 @@ namespace slideshow::internal pGetValue, pSetValue, Scaler( 1.0/nScaleValue ), - Scaler( nScaleValue ) ); + Scaler( nScaleValue ), + rAttrName, + pBox2DWorld ); } @@ -760,6 +965,7 @@ namespace slideshow::internal const AnimatableShapeSharedPtr& rShape, const ShapeManagerSharedPtr& rShapeManager, const ::basegfx::B2DVector& rSlideSize, + const box2d::utils::Box2DWorldSharedPtr& pBox2DWorld, int nFlags ) { // ATTENTION: When changing this map, also the classifyAttributeName() method must @@ -794,7 +1000,9 @@ namespace slideshow::internal 1.0, // CharHeight is a relative attribute, thus // default is 1.0 &ShapeAttributeLayer::getCharScale, - &ShapeAttributeLayer::setCharScale ); + &ShapeAttributeLayer::setCharScale, + rAttrName, + pBox2DWorld ); case AttributeType::CharWeight: return makeGenericAnimation<NumberAnimation>( rShapeManager, @@ -802,7 +1010,9 @@ namespace slideshow::internal &ShapeAttributeLayer::isCharWeightValid, getDefault<double>( rShape, rAttrName ), &ShapeAttributeLayer::getCharWeight, - &ShapeAttributeLayer::setCharWeight ); + &ShapeAttributeLayer::setCharWeight, + rAttrName, + pBox2DWorld ); case AttributeType::Height: return makeGenericAnimation( rShapeManager, @@ -816,7 +1026,9 @@ namespace slideshow::internal &ShapeAttributeLayer::getHeight, &ShapeAttributeLayer::setHeight, // convert expression parser value from relative page size - rSlideSize.getY() ); + rSlideSize.getY(), + rAttrName, + pBox2DWorld ); case AttributeType::Opacity: return makeGenericAnimation<NumberAnimation>( rShapeManager, @@ -825,7 +1037,9 @@ namespace slideshow::internal // TODO(F1): Provide shape default here (FillTransparency?) 1.0, &ShapeAttributeLayer::getAlpha, - &ShapeAttributeLayer::setAlpha ); + &ShapeAttributeLayer::setAlpha, + rAttrName, + pBox2DWorld ); case AttributeType::Rotate: return makeGenericAnimation<NumberAnimation>( rShapeManager, @@ -835,7 +1049,9 @@ namespace slideshow::internal // rotation angle is always 0.0, even for rotated shapes 0.0, &ShapeAttributeLayer::getRotationAngle, - &ShapeAttributeLayer::setRotationAngle ); + &ShapeAttributeLayer::setRotationAngle, + rAttrName, + pBox2DWorld ); case AttributeType::SkewX: return makeGenericAnimation<NumberAnimation>( rShapeManager, @@ -844,7 +1060,9 @@ namespace slideshow::internal // TODO(F1): Is there any shape property for skew? 0.0, &ShapeAttributeLayer::getShearXAngle, - &ShapeAttributeLayer::setShearXAngle ); + &ShapeAttributeLayer::setShearXAngle, + rAttrName, + pBox2DWorld ); case AttributeType::SkewY: return makeGenericAnimation<NumberAnimation>( rShapeManager, @@ -853,7 +1071,9 @@ namespace slideshow::internal // TODO(F1): Is there any shape property for skew? 0.0, &ShapeAttributeLayer::getShearYAngle, - &ShapeAttributeLayer::setShearYAngle ); + &ShapeAttributeLayer::setShearYAngle, + rAttrName, + pBox2DWorld ); case AttributeType::Width: return makeGenericAnimation( rShapeManager, @@ -867,7 +1087,9 @@ namespace slideshow::internal &ShapeAttributeLayer::getWidth, &ShapeAttributeLayer::setWidth, // convert expression parser value from relative page size - rSlideSize.getX() ); + rSlideSize.getX(), + rAttrName, + pBox2DWorld ); case AttributeType::PosX: return makeGenericAnimation( rShapeManager, @@ -881,7 +1103,9 @@ namespace slideshow::internal &ShapeAttributeLayer::getPosX, &ShapeAttributeLayer::setPosX, // convert expression parser value from relative page size - rSlideSize.getX() ); + rSlideSize.getX(), + rAttrName, + pBox2DWorld ); case AttributeType::PosY: return makeGenericAnimation( rShapeManager, @@ -895,7 +1119,9 @@ namespace slideshow::internal &ShapeAttributeLayer::getPosY, &ShapeAttributeLayer::setPosY, // convert expression parser value from relative page size - rSlideSize.getY() ); + rSlideSize.getY(), + rAttrName, + pBox2DWorld ); } return NumberAnimationSharedPtr(); @@ -905,6 +1131,7 @@ namespace slideshow::internal const AnimatableShapeSharedPtr& rShape, const ShapeManagerSharedPtr& rShapeManager, const ::basegfx::B2DVector& /*rSlideSize*/, + const box2d::utils::Box2DWorldSharedPtr& pBox2DWorld, int nFlags ) { // ATTENTION: When changing this map, also the classifyAttributeName() method must @@ -946,7 +1173,9 @@ namespace slideshow::internal sal::static_int_cast<sal_Int16>( getDefault<drawing::FillStyle>( rShape, rAttrName )), &ShapeAttributeLayer::getFillStyle, - &ShapeAttributeLayer::setFillStyle ); + &ShapeAttributeLayer::setFillStyle, + rAttrName, + pBox2DWorld ); case AttributeType::LineStyle: return makeGenericAnimation<EnumAnimation>( rShapeManager, @@ -955,7 +1184,9 @@ namespace slideshow::internal sal::static_int_cast<sal_Int16>( getDefault<drawing::LineStyle>( rShape, rAttrName )), &ShapeAttributeLayer::getLineStyle, - &ShapeAttributeLayer::setLineStyle ); + &ShapeAttributeLayer::setLineStyle, + rAttrName, + pBox2DWorld ); case AttributeType::CharPosture: return makeGenericAnimation<EnumAnimation>( rShapeManager, @@ -964,7 +1195,9 @@ namespace slideshow::internal sal::static_int_cast<sal_Int16>( getDefault<awt::FontSlant>( rShape, rAttrName )), &ShapeAttributeLayer::getCharPosture, - &ShapeAttributeLayer::setCharPosture ); + &ShapeAttributeLayer::setCharPosture, + rAttrName, + pBox2DWorld ); case AttributeType::CharUnderline: return makeGenericAnimation<EnumAnimation>( rShapeManager, @@ -972,7 +1205,9 @@ namespace slideshow::internal &ShapeAttributeLayer::isUnderlineModeValid, getDefault<sal_Int16>( rShape, rAttrName ), &ShapeAttributeLayer::getUnderlineMode, - &ShapeAttributeLayer::setUnderlineMode ); + &ShapeAttributeLayer::setUnderlineMode, + rAttrName, + pBox2DWorld ); } return EnumAnimationSharedPtr(); @@ -982,6 +1217,7 @@ namespace slideshow::internal const AnimatableShapeSharedPtr& rShape, const ShapeManagerSharedPtr& rShapeManager, const ::basegfx::B2DVector& /*rSlideSize*/, + const box2d::utils::Box2DWorldSharedPtr& pBox2DWorld, int nFlags ) { // ATTENTION: When changing this map, also the classifyAttributeName() method must @@ -1020,7 +1256,9 @@ namespace slideshow::internal &ShapeAttributeLayer::isCharColorValid, getDefault<RGBColor>( rShape, rAttrName ), &ShapeAttributeLayer::getCharColor, - &ShapeAttributeLayer::setCharColor ); + &ShapeAttributeLayer::setCharColor, + rAttrName, + pBox2DWorld ); case AttributeType::Color: // TODO(F2): This is just mapped to fill color to make it work @@ -1029,7 +1267,9 @@ namespace slideshow::internal &ShapeAttributeLayer::isFillColorValid, getDefault<RGBColor>( rShape, rAttrName ), &ShapeAttributeLayer::getFillColor, - &ShapeAttributeLayer::setFillColor ); + &ShapeAttributeLayer::setFillColor, + rAttrName, + pBox2DWorld ); case AttributeType::DimColor: return makeGenericAnimation<ColorAnimation>( rShapeManager, @@ -1037,7 +1277,9 @@ namespace slideshow::internal &ShapeAttributeLayer::isDimColorValid, getDefault<RGBColor>( rShape, rAttrName ), &ShapeAttributeLayer::getDimColor, - &ShapeAttributeLayer::setDimColor ); + &ShapeAttributeLayer::setDimColor, + rAttrName, + pBox2DWorld ); case AttributeType::FillColor: return makeGenericAnimation<ColorAnimation>( rShapeManager, @@ -1045,7 +1287,9 @@ namespace slideshow::internal &ShapeAttributeLayer::isFillColorValid, getDefault<RGBColor>( rShape, rAttrName ), &ShapeAttributeLayer::getFillColor, - &ShapeAttributeLayer::setFillColor ); + &ShapeAttributeLayer::setFillColor, + rAttrName, + pBox2DWorld ); case AttributeType::LineColor: return makeGenericAnimation<ColorAnimation>( rShapeManager, @@ -1053,7 +1297,9 @@ namespace slideshow::internal &ShapeAttributeLayer::isLineColorValid, getDefault<RGBColor>( rShape, rAttrName ), &ShapeAttributeLayer::getLineColor, - &ShapeAttributeLayer::setLineColor ); + &ShapeAttributeLayer::setLineColor, + rAttrName, + pBox2DWorld ); } return ColorAnimationSharedPtr(); @@ -1114,6 +1360,7 @@ namespace slideshow::internal const AnimatableShapeSharedPtr& rShape, const ShapeManagerSharedPtr& rShapeManager, const ::basegfx::B2DVector& /*rSlideSize*/, + const box2d::utils::Box2DWorldSharedPtr& pBox2DWorld, int nFlags ) { // ATTENTION: When changing this map, also the classifyAttributeName() method must @@ -1156,7 +1403,9 @@ namespace slideshow::internal &ShapeAttributeLayer::isFontFamilyValid, getDefault< OUString >( rShape, rAttrName ), &ShapeAttributeLayer::getFontFamily, - &ShapeAttributeLayer::setFontFamily ); + &ShapeAttributeLayer::setFontFamily, + rAttrName, + pBox2DWorld ); } return StringAnimationSharedPtr(); @@ -1166,6 +1415,7 @@ namespace slideshow::internal const AnimatableShapeSharedPtr& /*rShape*/, const ShapeManagerSharedPtr& rShapeManager, const ::basegfx::B2DVector& /*rSlideSize*/, + const box2d::utils::Box2DWorldSharedPtr& pBox2DWorld, int nFlags ) { // ATTENTION: When changing this map, also the classifyAttributeName() method must @@ -1209,7 +1459,9 @@ namespace slideshow::internal // TODO(F1): Is there a corresponding shape property? true, &ShapeAttributeLayer::getVisibility, - &ShapeAttributeLayer::setVisibility ); + &ShapeAttributeLayer::setVisibility, + rAttrName, + pBox2DWorld ); } return BoolAnimationSharedPtr(); @@ -1220,9 +1472,23 @@ namespace slideshow::internal const AnimatableShapeSharedPtr& /*rShape*/, const ShapeManagerSharedPtr& rShapeManager, const ::basegfx::B2DVector& rSlideSize, + const box2d::utils::Box2DWorldSharedPtr& pBox2DWorld, int nFlags ) { return std::make_shared<PathAnimation>( rSVGDPath, nAdditive, + rShapeManager, + rSlideSize, + nFlags, + pBox2DWorld); + } + + NumberAnimationSharedPtr AnimationFactory::createPhysicsAnimation( const box2d::utils::Box2DWorldSharedPtr& pBox2DWorld, + const double fDuration, + const ShapeManagerSharedPtr& rShapeManager, + const ::basegfx::B2DVector& rSlideSize, + int nFlags ) + { + return std::make_shared<PhysicsAnimation>( pBox2DWorld, fDuration, rShapeManager, rSlideSize, nFlags ); diff --git a/slideshow/source/engine/animationnodes/animationcolornode.cxx b/slideshow/source/engine/animationnodes/animationcolornode.cxx index 39ca961c478f..14a32aae4af9 100644 --- a/slideshow/source/engine/animationnodes/animationcolornode.cxx +++ b/slideshow/source/engine/animationnodes/animationcolornode.cxx @@ -91,7 +91,8 @@ AnimationActivitySharedPtr AnimationColorNode::createActivity() const mxColorNode->getAttributeName(), getShape(), getContext().mpSubsettableShapeManager, - getSlideSize() ), + getSlideSize(), + getContext().mpBox2DWorld ), getXAnimateNode() ); case animations::AnimationColorSpace::HSL: @@ -105,7 +106,8 @@ AnimationActivitySharedPtr AnimationColorNode::createActivity() const mxColorNode->getAttributeName(), getShape(), getContext().mpSubsettableShapeManager, - getSlideSize() )), + getSlideSize(), + getContext().mpBox2DWorld )), mxColorNode ); default: diff --git a/slideshow/source/engine/animationnodes/animationnodefactory.cxx b/slideshow/source/engine/animationnodes/animationnodefactory.cxx index f9fa01b2f1fd..4df097cb08c0 100644 --- a/slideshow/source/engine/animationnodes/animationnodefactory.cxx +++ b/slideshow/source/engine/animationnodes/animationnodefactory.cxx @@ -33,6 +33,7 @@ #include "propertyanimationnode.hxx" #include "animationsetnode.hxx" #include "animationpathmotionnode.hxx" +#include "animationphysicsnode.hxx" #include "animationcolornode.hxx" #include "animationtransformnode.hxx" #include "animationtransitionfilternode.hxx" @@ -493,6 +494,11 @@ BaseNodeSharedPtr implCreateAnimationNode( xNode, rParent, rContext ); break; + case animations::AnimationNodeType::ANIMATEPHYSICS: + pCreatedNode = std::make_shared<AnimationPhysicsNode>( + xNode, rParent, rContext ); + break; + case animations::AnimationNodeType::TRANSITIONFILTER: pCreatedNode = std::make_shared<AnimationTransitionFilterNode>( xNode, rParent, rContext ); diff --git a/slideshow/source/engine/animationnodes/animationpathmotionnode.cxx b/slideshow/source/engine/animationnodes/animationpathmotionnode.cxx index 2490b6e2cbc8..cbef1f3eabba 100644 --- a/slideshow/source/engine/animationnodes/animationpathmotionnode.cxx +++ b/slideshow/source/engine/animationnodes/animationpathmotionnode.cxx @@ -43,7 +43,8 @@ AnimationActivitySharedPtr AnimationPathMotionNode::createActivity() const mxPathMotionNode->getAdditive(), getShape(), getContext().mpSubsettableShapeManager, - getSlideSize(), 0 ), + getSlideSize(), + getContext().mpBox2DWorld, 0 ), true ); } diff --git a/slideshow/source/engine/animationnodes/animationphysicsnode.cxx b/slideshow/source/engine/animationnodes/animationphysicsnode.cxx new file mode 100644 index 000000000000..28e247c30d6c --- /dev/null +++ b/slideshow/source/engine/animationnodes/animationphysicsnode.cxx @@ -0,0 +1,48 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "animationphysicsnode.hxx" +#include <animationfactory.hxx> + +namespace slideshow::internal +{ +void AnimationPhysicsNode::dispose() +{ + mxPhysicsMotionNode.clear(); + AnimationBaseNode::dispose(); +} + +AnimationActivitySharedPtr AnimationPhysicsNode::createActivity() const +{ + double fDuration; + ENSURE_OR_THROW((mxPhysicsMotionNode->getDuration() >>= fDuration), + "Couldn't get the animation duration."); + + ActivitiesFactory::CommonParameters const aParms(fillCommonParameters()); + return ActivitiesFactory::createSimpleActivity( + aParms, + AnimationFactory::createPhysicsAnimation(getContext().mpBox2DWorld, fDuration, + getContext().mpSubsettableShapeManager, + getSlideSize(), 0), + true); +} + +} // namespace slideshow::internal + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/animationnodes/animationphysicsnode.hxx b/slideshow/source/engine/animationnodes/animationphysicsnode.hxx new file mode 100644 index 000000000000..15ac8911e916 --- /dev/null +++ b/slideshow/source/engine/animationnodes/animationphysicsnode.hxx @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#pragma once + +#include "animationbasenode.hxx" +#include <com/sun/star/animations/XAnimateMotion.hpp> + +namespace slideshow +{ +namespace internal +{ +class AnimationPhysicsNode : public AnimationBaseNode +{ +public: + AnimationPhysicsNode(const css::uno::Reference<css::animations::XAnimationNode>& xNode, + const BaseContainerNodeSharedPtr& rParent, const NodeContext& rContext) + : AnimationBaseNode(xNode, rParent, rContext) + , mxPhysicsMotionNode(xNode, css::uno::UNO_QUERY_THROW) + { + } + +#if defined(DBG_UTIL) + virtual const char* getDescription() const override { return "AnimationPhysicsNode"; } +#endif + +protected: + virtual void dispose() override; + +private: + virtual AnimationActivitySharedPtr createActivity() const override; + + css::uno::Reference<css::animations::XAnimateMotion> mxPhysicsMotionNode; +}; + +} // namespace internal +} // namespace slideshow + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/animationnodes/animationsetnode.cxx b/slideshow/source/engine/animationnodes/animationsetnode.cxx index 350e80fbcfe7..89747901e73c 100644 --- a/slideshow/source/engine/animationnodes/animationsetnode.cxx +++ b/slideshow/source/engine/animationnodes/animationsetnode.cxx @@ -86,6 +86,7 @@ AnimationActivitySharedPtr AnimationSetNode::createActivity() const pShape, getContext().mpSubsettableShapeManager, getSlideSize(), + getContext().mpBox2DWorld, AnimationFactory::FLAG_NO_SPRITE ), aValue ); } @@ -109,6 +110,7 @@ AnimationActivitySharedPtr AnimationSetNode::createActivity() const pShape, getContext().mpSubsettableShapeManager, getSlideSize(), + getContext().mpBox2DWorld, AnimationFactory::FLAG_NO_SPRITE ), aValue ); } @@ -132,6 +134,7 @@ AnimationActivitySharedPtr AnimationSetNode::createActivity() const pShape, getContext().mpSubsettableShapeManager, getSlideSize(), + getContext().mpBox2DWorld, AnimationFactory::FLAG_NO_SPRITE ), aValue ); } @@ -155,6 +158,7 @@ AnimationActivitySharedPtr AnimationSetNode::createActivity() const pShape, getContext().mpSubsettableShapeManager, getSlideSize(), + getContext().mpBox2DWorld, AnimationFactory::FLAG_NO_SPRITE ), aValue ); } @@ -178,6 +182,7 @@ AnimationActivitySharedPtr AnimationSetNode::createActivity() const pShape, getContext().mpSubsettableShapeManager, getSlideSize(), + getContext().mpBox2DWorld, AnimationFactory::FLAG_NO_SPRITE ), aValue ); } diff --git a/slideshow/source/engine/animationnodes/animationtransformnode.cxx b/slideshow/source/engine/animationnodes/animationtransformnode.cxx index b8019d77e6a1..624bad401e8b 100644 --- a/slideshow/source/engine/animationnodes/animationtransformnode.cxx +++ b/slideshow/source/engine/animationnodes/animationtransformnode.cxx @@ -67,7 +67,8 @@ AnimationActivitySharedPtr AnimationTransformNode::createActivity() const "Rotate", rShape, getContext().mpSubsettableShapeManager, - getSlideSize() ), + getSlideSize(), + getContext().mpBox2DWorld ), getXAnimateNode() ); case animations::AnimationTransformType::SKEWX: @@ -77,7 +78,8 @@ AnimationActivitySharedPtr AnimationTransformNode::createActivity() const "SkewX", rShape, getContext().mpSubsettableShapeManager, - getSlideSize() ), + getSlideSize(), + getContext().mpBox2DWorld ), getXAnimateNode() ); case animations::AnimationTransformType::SKEWY: @@ -87,7 +89,8 @@ AnimationActivitySharedPtr AnimationTransformNode::createActivity() const "SkewY", rShape, getContext().mpSubsettableShapeManager, - getSlideSize() ), + getSlideSize(), + getContext().mpBox2DWorld ), getXAnimateNode() ); } } diff --git a/slideshow/source/engine/animationnodes/propertyanimationnode.cxx b/slideshow/source/engine/animationnodes/propertyanimationnode.cxx index 2643c44036d8..3e7d68b4beb7 100644 --- a/slideshow/source/engine/animationnodes/propertyanimationnode.cxx +++ b/slideshow/source/engine/animationnodes/propertyanimationnode.cxx @@ -48,7 +48,8 @@ AnimationActivitySharedPtr PropertyAnimationNode::createActivity() const attrName, pShape, getContext().mpSubsettableShapeManager, - getSlideSize() ), + getSlideSize(), + getContext().mpBox2DWorld ), xAnimateNode ); case AnimationFactory::CLASS_ENUM_PROPERTY: @@ -58,7 +59,8 @@ AnimationActivitySharedPtr PropertyAnimationNode::createActivity() const attrName, pShape, getContext().mpSubsettableShapeManager, - getSlideSize(), 0 ), + getSlideSize(), + getContext().mpBox2DWorld, 0 ), xAnimateNode ); case AnimationFactory::CLASS_COLOR_PROPERTY: @@ -68,7 +70,8 @@ AnimationActivitySharedPtr PropertyAnimationNode::createActivity() const attrName, pShape, getContext().mpSubsettableShapeManager, - getSlideSize() ), + getSlideSize(), + getContext().mpBox2DWorld ), xAnimateNode ); case AnimationFactory::CLASS_STRING_PROPERTY: @@ -78,7 +81,8 @@ AnimationActivitySharedPtr PropertyAnimationNode::createActivity() const attrName, pShape, getContext().mpSubsettableShapeManager, - getSlideSize(), 0 ), + getSlideSize(), + getContext().mpBox2DWorld, 0 ), xAnimateNode ); case AnimationFactory::CLASS_BOOL_PROPERTY: @@ -88,7 +92,8 @@ AnimationActivitySharedPtr PropertyAnimationNode::createActivity() const attrName, pShape, getContext().mpSubsettableShapeManager, - getSlideSize(), 0 ), + getSlideSize(), + getContext().mpBox2DWorld, 0 ), xAnimateNode ); } diff --git a/slideshow/source/engine/box2dtools.cxx b/slideshow/source/engine/box2dtools.cxx index 8729300184f6..737687713614 100644 --- a/slideshow/source/engine/box2dtools.cxx +++ b/slideshow/source/engine/box2dtools.cxx @@ -211,7 +211,7 @@ void box2DWorld::processUpdateQueue(const double fPassedTime) } void box2DWorld::initateAllShapesAsStaticBodies( - const slideshow::internal::ShapeManagerSharedPtr pShapeManager) + const slideshow::internal::ShapeManagerSharedPtr& pShapeManager) { assert(mpBox2DWorld); @@ -242,8 +242,9 @@ void box2DWorld::setHasWorldStepper(const bool bHasWorldStepper) mbHasWorldStepper = bHasWorldStepper; } -void box2DWorld::queuePositionUpdate(css::uno::Reference<com::sun::star::drawing::XShape> xShape, - const basegfx::B2DPoint& rOutPos) +void box2DWorld::queuePositionUpdate( + const css::uno::Reference<com::sun::star::drawing::XShape>& xShape, + const basegfx::B2DPoint& rOutPos) { Box2DShapeUpdateInformation aQueueElement = { xShape, {}, BOX2D_UPDATE_POSITION }; aQueueElement.maPosition = rOutPos; @@ -251,7 +252,7 @@ void box2DWorld::queuePositionUpdate(css::uno::Reference<com::sun::star::drawing } void box2DWorld::queueLinearVelocityUpdate( - css::uno::Reference<com::sun::star::drawing::XShape> xShape, + const css::uno::Reference<com::sun::star::drawing::XShape>& xShape, const basegfx::B2DVector& rVelocity) { Box2DShapeUpdateInformation aQueueElement = { xShape, {}, BOX2D_UPDATE_LINEAR_VELOCITY, 1 }; @@ -259,8 +260,8 @@ void box2DWorld::queueLinearVelocityUpdate( maShapeUpdateQueue.push(aQueueElement); } -void box2DWorld::queueRotationUpdate(css::uno::Reference<com::sun::star::drawing::XShape> xShape, - const double fAngle) +void box2DWorld::queueRotationUpdate( + const css::uno::Reference<com::sun::star::drawing::XShape>& xShape, const double fAngle) { Box2DShapeUpdateInformation aQueueElement = { xShape, {}, BOX2D_UPDATE_ANGLE }; aQueueElement.mfAngle = fAngle; @@ -268,7 +269,8 @@ void box2DWorld::queueRotationUpdate(css::uno::Reference<com::sun::star::drawing } void box2DWorld::queueAngularVelocityUpdate( - css::uno::Reference<com::sun::star::drawing::XShape> xShape, const double fAngularVelocity) + const css::uno::Reference<com::sun::star::drawing::XShape>& xShape, + const double fAngularVelocity) { Box2DShapeUpdateInformation aQueueElement = { xShape, {}, BOX2D_UPDATE_ANGULAR_VELOCITY, 1 }; aQueueElement.mfAngularVelocity = fAngularVelocity; @@ -276,7 +278,7 @@ void box2DWorld::queueAngularVelocityUpdate( } void box2DWorld::queueShapeVisibilityUpdate( - css::uno::Reference<com::sun::star::drawing::XShape> xShape, const bool bVisibility) + const css::uno::Reference<com::sun::star::drawing::XShape>& xShape, const bool bVisibility) { Box2DShapeUpdateInformation aQueueElement = { xShape, {}, BOX2D_UPDATE_VISIBILITY }; aQueueElement.mbVisibility = bVisibility; @@ -318,14 +320,14 @@ bool box2DWorld::isInitialized() return false; } -Box2DBodySharedPtr box2DWorld::makeShapeDynamic(const slideshow::internal::ShapeSharedPtr pShape) +Box2DBodySharedPtr box2DWorld::makeShapeDynamic(const slideshow::internal::ShapeSharedPtr& pShape) { assert(mpBox2DWorld); Box2DBodySharedPtr pBox2DBody = mpXShapeToBodyMap.find(pShape->getXShape())->second; return makeBodyDynamic(pBox2DBody); } -Box2DBodySharedPtr box2DWorld::makeBodyDynamic(const Box2DBodySharedPtr pBox2DBody) +Box2DBodySharedPtr box2DWorld::makeBodyDynamic(const Box2DBodySharedPtr& pBox2DBody) { assert(mpBox2DWorld); if (pBox2DBody->getType() != BOX2D_DYNAMIC_BODY) @@ -335,14 +337,14 @@ Box2DBodySharedPtr box2DWorld::makeBodyDynamic(const Box2DBodySharedPtr pBox2DBo return pBox2DBody; } -Box2DBodySharedPtr box2DWorld::makeShapeStatic(const slideshow::internal::ShapeSharedPtr pShape) +Box2DBodySharedPtr box2DWorld::makeShapeStatic(const slideshow::internal::ShapeSharedPtr& pShape) { assert(mpBox2DWorld); Box2DBodySharedPtr pBox2DBody = mpXShapeToBodyMap.find(pShape->getXShape())->second; return makeBodyStatic(pBox2DBody); } -Box2DBodySharedPtr box2DWorld::makeBodyStatic(const Box2DBodySharedPtr pBox2DBody) +Box2DBodySharedPtr box2DWorld::makeBodyStatic(const Box2DBodySharedPtr& pBox2DBody) { assert(mpBox2DWorld); if (pBox2DBody->getType() != BOX2D_STATIC_BODY) diff --git a/slideshow/source/engine/slide/slideimpl.cxx b/slideshow/source/engine/slide/slideimpl.cxx index a9120c6da829..a300c946e52a 100644 --- a/slideshow/source/engine/slide/slideimpl.cxx +++ b/slideshow/source/engine/slide/slideimpl.cxx @@ -47,6 +47,7 @@ #include "userpaintoverlay.hxx" #include "targetpropertiescreator.hxx" #include <tools.hxx> +#include <box2dtools.hxx> using namespace ::com::sun::star; @@ -193,6 +194,7 @@ private: LayerManagerSharedPtr mpLayerManager; std::shared_ptr<ShapeManagerImpl> mpShapeManager; std::shared_ptr<SubsettableShapeManager> mpSubsettableShapeManager; + box2d::utils::Box2DWorldSharedPtr mpBox2DWorld; /// Contains common objects needed throughout the slideshow SlideShowContext maContext; @@ -316,6 +318,8 @@ SlideImpl::SlideImpl( const uno::Reference< drawing::XDrawPage >& xDra rShapeCursorMap, xDrawPage)), mpSubsettableShapeManager( mpShapeManager ), + mpBox2DWorld( std::make_shared<box2d::utils::box2DWorld>( + basegfx::B2DSize( getSlideSizeImpl() ) ) ), maContext( mpSubsettableShapeManager, rEventQueue, rEventMultiplexer, @@ -325,7 +329,8 @@ SlideImpl::SlideImpl( const uno::Reference< drawing::XDrawPage >& xDra *this, rMediaFileManager, rViewContainer, - xComponentContext ), + xComponentContext, + mpBox2DWorld ), mrCursorManager( rCursorManager ), maAnimations( maContext, basegfx::B2DSize( getSlideSizeImpl() ) ), diff --git a/slideshow/source/engine/slideshowcontext.cxx b/slideshow/source/engine/slideshowcontext.cxx index 8c0811e9ecf7..f0433b9d846b 100644 --- a/slideshow/source/engine/slideshowcontext.cxx +++ b/slideshow/source/engine/slideshowcontext.cxx @@ -45,7 +45,8 @@ SlideShowContext::SlideShowContext( SubsettableShapeManagerSharedPtr& rSubsettab MediaFileManager& rMediaFileManager, const UnoViewContainer& rViewContainer, const uno::Reference< - uno::XComponentContext>& rComponentContext ) : + uno::XComponentContext>& rComponentContext, + box2d::utils::Box2DWorldSharedPtr& rBox2DWorldPtr ) : mpSubsettableShapeManager( rSubsettableShapeManager ), mrEventQueue( rEventQueue ), mrEventMultiplexer( rEventMultiplexer ), @@ -55,7 +56,8 @@ SlideShowContext::SlideShowContext( SubsettableShapeManagerSharedPtr& rSubsettab mrCursorManager( rCursorManager ), mrMediaFileManager( rMediaFileManager ), mrViewContainer( rViewContainer ), - mxComponentContext( rComponentContext ) + mxComponentContext( rComponentContext ), + mpBox2DWorld( rBox2DWorldPtr ) {} void SlideShowContext::dispose() diff --git a/slideshow/source/engine/slideshowimpl.cxx b/slideshow/source/engine/slideshowimpl.cxx index 9fd3d536dbce..afac7a392763 100644 --- a/slideshow/source/engine/slideshowimpl.cxx +++ b/slideshow/source/engine/slideshowimpl.cxx @@ -84,6 +84,9 @@ using namespace com::sun::star; using namespace ::slideshow::internal; +namespace box2d::utils { class box2DWorld; + typedef ::std::shared_ptr< box2DWorld > Box2DWorldSharedPtr; } + namespace { /** During animations the update() method tells its caller to call it as @@ -416,6 +419,7 @@ private: ActivitiesQueue maActivitiesQueue; UserEventQueue maUserEventQueue; SubsettableShapeManagerSharedPtr mpDummyPtr; + box2d::utils::Box2DWorldSharedPtr mpBox2DDummyPtr; std::shared_ptr<SeparateListenerImpl> mpListener; @@ -544,6 +548,7 @@ SlideShowImpl::SlideShowImpl( maEventQueue, *this ), mpDummyPtr(), + mpBox2DDummyPtr(), mpListener(), mpRehearseTimingsActivity(), mpWaitSymbol(), @@ -1673,7 +1678,8 @@ sal_Bool SlideShowImpl::setProperty( beans::PropertyValue const& rProperty ) *this, *this, maViewContainer, - mxComponentContext) ); + mxComponentContext, + mpBox2DDummyPtr ) ); } else if (mpRehearseTimingsActivity) { diff --git a/slideshow/source/engine/transitions/shapetransitionfactory.cxx b/slideshow/source/engine/transitions/shapetransitionfactory.cxx index d0ff5325e252..3586cff71d39 100644 --- a/slideshow/source/engine/transitions/shapetransitionfactory.cxx +++ b/slideshow/source/engine/transitions/shapetransitionfactory.cxx @@ -324,7 +324,8 @@ AnimationActivitySharedPtr createShapeTransitionByType( "Opacity", rShape, rShapeManager, - rSlideSize ), + rSlideSize, + nullptr ), xTransition->getMode() ); } break; diff --git a/slideshow/source/inc/animationfactory.hxx b/slideshow/source/inc/animationfactory.hxx index 7d2f205c63a5..0517a7a79ee4 100644 --- a/slideshow/source/inc/animationfactory.hxx +++ b/slideshow/source/inc/animationfactory.hxx @@ -30,6 +30,8 @@ #include "shapemanager.hxx" +namespace box2d::utils { typedef ::std::shared_ptr< class box2DWorld > Box2DWorldSharedPtr; } + /* Definition of AnimationFactory class */ namespace slideshow @@ -81,18 +83,21 @@ namespace slideshow const AnimatableShapeSharedPtr& rShape, const ShapeManagerSharedPtr& rShapeManager, const ::basegfx::B2DVector& rSlideSize, + const box2d::utils::Box2DWorldSharedPtr& pBox2DWorld, int nFlags=0 ); EnumAnimationSharedPtr createEnumPropertyAnimation( const OUString& rAttrName, const AnimatableShapeSharedPtr& rShape, const ShapeManagerSharedPtr& rShapeManager, const ::basegfx::B2DVector& rSlideSize, + const box2d::utils::Box2DWorldSharedPtr& pBox2DWorld, int nFlags ); ColorAnimationSharedPtr createColorPropertyAnimation( const OUString& rAttrName, const AnimatableShapeSharedPtr& rShape, const ShapeManagerSharedPtr& rShapeManager, const ::basegfx::B2DVector& rSlideSize, + const box2d::utils::Box2DWorldSharedPtr& pBox2DWorld, int nFlags=0 ); /** Create scale or move animation @@ -112,12 +117,14 @@ namespace slideshow const AnimatableShapeSharedPtr& rShape, ... etc. - the rest is truncated _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits