diff options
author | Sarper Akdemir <q.sarperakdemir@gmail.com> | 2020-06-11 19:29:38 +0300 |
---|---|---|
committer | Thorsten Behrens <Thorsten.Behrens@CIB.de> | 2020-08-09 23:44:00 +0200 |
commit | 28022cee396715bc4b474ed1571074dc721bbe13 (patch) | |
tree | 98918b687f2ebddc979083771c4614f9e7f44f7f /slideshow/source/engine | |
parent | 6ce2eddfdc35100b8079a4584dd3945e923d66a9 (diff) |
make physics based animation effects part of the animation engine
Wiring up and creating required classes for physics based
animation effects 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
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/100151
Tested-by: Jenkins
Reviewed-by: Thorsten Behrens <Thorsten.Behrens@CIB.de>
Diffstat (limited to 'slideshow/source/engine')
14 files changed, 488 insertions, 62 deletions
diff --git a/slideshow/source/engine/animationfactory.cxx b/slideshow/source/engine/animationfactory.cxx index f81c37b77df3..bc1848f68435 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 AttributeType eAttrType, + 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 ), + meAttrType( eAttrType ), + mpBox2DWorld ( pBox2DWorld ) { ENSURE_OR_THROW( rShapeManager, "GenericAnimation::GenericAnimation(): Invalid ShapeManager" ); @@ -473,6 +632,11 @@ namespace slideshow::internal mbAnimationStarted = false; + if( mpBox2DWorld && mpBox2DWorld->isInitialized() ) + { + mpBox2DWorld->queueShapeAnimationEndUpdate( mpShape->getXShape(), meAttrType ); + } + if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) ) mpShapeManager->leaveAnimationMode( mpShape ); @@ -529,6 +693,11 @@ namespace slideshow::internal ((*mpAttrLayer).*mpSetValueFunc)( maSetterModifier( x ) ); + if( mpBox2DWorld && mpBox2DWorld->isInitialized() ) + { + mpBox2DWorld->queueShapeAnimationUpdate( mpShape->getXShape(), mpAttrLayer, meAttrType ); + } + if( mpShape->isContentChanged() ) mpShapeManager->notifyShapeUpdate( mpShape ); @@ -564,6 +733,9 @@ namespace slideshow::internal const ValueT maDefaultValue; bool mbAnimationStarted; + + const AttributeType meAttrType; + const box2d::utils::Box2DWorldSharedPtr mpBox2DWorld; }; //Current c++0x draft (apparently) has std::identity, but not operator() @@ -585,7 +757,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 AttributeType eAttrType, + const box2d::utils::Box2DWorldSharedPtr& pBox2DWorld ) { return std::make_shared<GenericAnimation< AnimationBase, SGI_identity< typename AnimationBase::ValueType > >>( @@ -597,7 +771,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 >(), + eAttrType, + pBox2DWorld ); } class Scaler @@ -625,7 +801,9 @@ namespace slideshow::internal double nDefaultValue, double (ShapeAttributeLayer::*pGetValue)() const, void (ShapeAttributeLayer::*pSetValue)( const double& ), - double nScaleValue ) + double nScaleValue, + const AttributeType eAttrType, + const box2d::utils::Box2DWorldSharedPtr& pBox2DWorld ) { return std::make_shared<GenericAnimation< NumberAnimation, Scaler >>( rShapeManager, nFlags, @@ -634,7 +812,9 @@ namespace slideshow::internal pGetValue, pSetValue, Scaler( 1.0/nScaleValue ), - Scaler( nScaleValue ) ); + Scaler( nScaleValue ), + eAttrType, + pBox2DWorld ); } @@ -760,11 +940,13 @@ 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 // be checked and possibly adapted in their switch statement - switch( mapAttributeName( rAttrName ) ) + AttributeType eAttrType = mapAttributeName(rAttrName); + switch( eAttrType ) { default: case AttributeType::Invalid: @@ -794,7 +976,9 @@ namespace slideshow::internal 1.0, // CharHeight is a relative attribute, thus // default is 1.0 &ShapeAttributeLayer::getCharScale, - &ShapeAttributeLayer::setCharScale ); + &ShapeAttributeLayer::setCharScale, + eAttrType, + pBox2DWorld ); case AttributeType::CharWeight: return makeGenericAnimation<NumberAnimation>( rShapeManager, @@ -802,7 +986,9 @@ namespace slideshow::internal &ShapeAttributeLayer::isCharWeightValid, getDefault<double>( rShape, rAttrName ), &ShapeAttributeLayer::getCharWeight, - &ShapeAttributeLayer::setCharWeight ); + &ShapeAttributeLayer::setCharWeight, + eAttrType, + pBox2DWorld ); case AttributeType::Height: return makeGenericAnimation( rShapeManager, @@ -816,7 +1002,9 @@ namespace slideshow::internal &ShapeAttributeLayer::getHeight, &ShapeAttributeLayer::setHeight, // convert expression parser value from relative page size - rSlideSize.getY() ); + rSlideSize.getY(), + eAttrType, + pBox2DWorld ); case AttributeType::Opacity: return makeGenericAnimation<NumberAnimation>( rShapeManager, @@ -825,7 +1013,9 @@ namespace slideshow::internal // TODO(F1): Provide shape default here (FillTransparency?) 1.0, &ShapeAttributeLayer::getAlpha, - &ShapeAttributeLayer::setAlpha ); + &ShapeAttributeLayer::setAlpha, + eAttrType, + pBox2DWorld ); case AttributeType::Rotate: return makeGenericAnimation<NumberAnimation>( rShapeManager, @@ -835,7 +1025,9 @@ namespace slideshow::internal // rotation angle is always 0.0, even for rotated shapes 0.0, &ShapeAttributeLayer::getRotationAngle, - &ShapeAttributeLayer::setRotationAngle ); + &ShapeAttributeLayer::setRotationAngle, + eAttrType, + pBox2DWorld ); case AttributeType::SkewX: return makeGenericAnimation<NumberAnimation>( rShapeManager, @@ -844,7 +1036,9 @@ namespace slideshow::internal // TODO(F1): Is there any shape property for skew? 0.0, &ShapeAttributeLayer::getShearXAngle, - &ShapeAttributeLayer::setShearXAngle ); + &ShapeAttributeLayer::setShearXAngle, + eAttrType, + pBox2DWorld ); case AttributeType::SkewY: return makeGenericAnimation<NumberAnimation>( rShapeManager, @@ -853,7 +1047,9 @@ namespace slideshow::internal // TODO(F1): Is there any shape property for skew? 0.0, &ShapeAttributeLayer::getShearYAngle, - &ShapeAttributeLayer::setShearYAngle ); + &ShapeAttributeLayer::setShearYAngle, + eAttrType, + pBox2DWorld ); case AttributeType::Width: return makeGenericAnimation( rShapeManager, @@ -867,7 +1063,9 @@ namespace slideshow::internal &ShapeAttributeLayer::getWidth, &ShapeAttributeLayer::setWidth, // convert expression parser value from relative page size - rSlideSize.getX() ); + rSlideSize.getX(), + eAttrType, + pBox2DWorld ); case AttributeType::PosX: return makeGenericAnimation( rShapeManager, @@ -881,7 +1079,9 @@ namespace slideshow::internal &ShapeAttributeLayer::getPosX, &ShapeAttributeLayer::setPosX, // convert expression parser value from relative page size - rSlideSize.getX() ); + rSlideSize.getX(), + eAttrType, + pBox2DWorld ); case AttributeType::PosY: return makeGenericAnimation( rShapeManager, @@ -895,7 +1095,9 @@ namespace slideshow::internal &ShapeAttributeLayer::getPosY, &ShapeAttributeLayer::setPosY, // convert expression parser value from relative page size - rSlideSize.getY() ); + rSlideSize.getY(), + eAttrType, + pBox2DWorld ); } return NumberAnimationSharedPtr(); @@ -905,11 +1107,13 @@ 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 // be checked and possibly adapted in their switch statement - switch( mapAttributeName( rAttrName ) ) + AttributeType eAttrType = mapAttributeName( rAttrName ); + switch( eAttrType ) { default: case AttributeType::Invalid: @@ -946,7 +1150,9 @@ namespace slideshow::internal sal::static_int_cast<sal_Int16>( getDefault<drawing::FillStyle>( rShape, rAttrName )), &ShapeAttributeLayer::getFillStyle, - &ShapeAttributeLayer::setFillStyle ); + &ShapeAttributeLayer::setFillStyle, + eAttrType, + pBox2DWorld ); case AttributeType::LineStyle: return makeGenericAnimation<EnumAnimation>( rShapeManager, @@ -955,7 +1161,9 @@ namespace slideshow::internal sal::static_int_cast<sal_Int16>( getDefault<drawing::LineStyle>( rShape, rAttrName )), &ShapeAttributeLayer::getLineStyle, - &ShapeAttributeLayer::setLineStyle ); + &ShapeAttributeLayer::setLineStyle, + eAttrType, + pBox2DWorld ); case AttributeType::CharPosture: return makeGenericAnimation<EnumAnimation>( rShapeManager, @@ -964,7 +1172,9 @@ namespace slideshow::internal sal::static_int_cast<sal_Int16>( getDefault<awt::FontSlant>( rShape, rAttrName )), &ShapeAttributeLayer::getCharPosture, - &ShapeAttributeLayer::setCharPosture ); + &ShapeAttributeLayer::setCharPosture, + eAttrType, + pBox2DWorld ); case AttributeType::CharUnderline: return makeGenericAnimation<EnumAnimation>( rShapeManager, @@ -972,7 +1182,9 @@ namespace slideshow::internal &ShapeAttributeLayer::isUnderlineModeValid, getDefault<sal_Int16>( rShape, rAttrName ), &ShapeAttributeLayer::getUnderlineMode, - &ShapeAttributeLayer::setUnderlineMode ); + &ShapeAttributeLayer::setUnderlineMode, + eAttrType, + pBox2DWorld ); } return EnumAnimationSharedPtr(); @@ -982,11 +1194,13 @@ 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 // be checked and possibly adapted in their switch statement - switch( mapAttributeName( rAttrName ) ) + AttributeType eAttrType = mapAttributeName(rAttrName); + switch( eAttrType ) { default: case AttributeType::Invalid: @@ -1020,7 +1234,9 @@ namespace slideshow::internal &ShapeAttributeLayer::isCharColorValid, getDefault<RGBColor>( rShape, rAttrName ), &ShapeAttributeLayer::getCharColor, - &ShapeAttributeLayer::setCharColor ); + &ShapeAttributeLayer::setCharColor, + eAttrType, + pBox2DWorld ); case AttributeType::Color: // TODO(F2): This is just mapped to fill color to make it work @@ -1029,7 +1245,9 @@ namespace slideshow::internal &ShapeAttributeLayer::isFillColorValid, getDefault<RGBColor>( rShape, rAttrName ), &ShapeAttributeLayer::getFillColor, - &ShapeAttributeLayer::setFillColor ); + &ShapeAttributeLayer::setFillColor, + eAttrType, + pBox2DWorld ); case AttributeType::DimColor: return makeGenericAnimation<ColorAnimation>( rShapeManager, @@ -1037,7 +1255,9 @@ namespace slideshow::internal &ShapeAttributeLayer::isDimColorValid, getDefault<RGBColor>( rShape, rAttrName ), &ShapeAttributeLayer::getDimColor, - &ShapeAttributeLayer::setDimColor ); + &ShapeAttributeLayer::setDimColor, + eAttrType, + pBox2DWorld ); case AttributeType::FillColor: return makeGenericAnimation<ColorAnimation>( rShapeManager, @@ -1045,7 +1265,9 @@ namespace slideshow::internal &ShapeAttributeLayer::isFillColorValid, getDefault<RGBColor>( rShape, rAttrName ), &ShapeAttributeLayer::getFillColor, - &ShapeAttributeLayer::setFillColor ); + &ShapeAttributeLayer::setFillColor, + eAttrType, + pBox2DWorld ); case AttributeType::LineColor: return makeGenericAnimation<ColorAnimation>( rShapeManager, @@ -1053,7 +1275,9 @@ namespace slideshow::internal &ShapeAttributeLayer::isLineColorValid, getDefault<RGBColor>( rShape, rAttrName ), &ShapeAttributeLayer::getLineColor, - &ShapeAttributeLayer::setLineColor ); + &ShapeAttributeLayer::setLineColor, + eAttrType, + pBox2DWorld ); } return ColorAnimationSharedPtr(); @@ -1114,11 +1338,13 @@ 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 // be checked and possibly adapted in their switch statement - switch( mapAttributeName( rAttrName ) ) + AttributeType eAttrType = mapAttributeName(rAttrName); + switch( eAttrType ) { default: case AttributeType::Invalid: @@ -1156,7 +1382,9 @@ namespace slideshow::internal &ShapeAttributeLayer::isFontFamilyValid, getDefault< OUString >( rShape, rAttrName ), &ShapeAttributeLayer::getFontFamily, - &ShapeAttributeLayer::setFontFamily ); + &ShapeAttributeLayer::setFontFamily, + eAttrType, + pBox2DWorld ); } return StringAnimationSharedPtr(); @@ -1166,11 +1394,13 @@ 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 // be checked and possibly adapted in their switch statement - switch( mapAttributeName( rAttrName ) ) + AttributeType eAttrType = mapAttributeName(rAttrName); + switch( eAttrType ) { default: case AttributeType::Invalid: @@ -1209,7 +1439,9 @@ namespace slideshow::internal // TODO(F1): Is there a corresponding shape property? true, &ShapeAttributeLayer::getVisibility, - &ShapeAttributeLayer::setVisibility ); + &ShapeAttributeLayer::setVisibility, + eAttrType, + pBox2DWorld ); } return BoolAnimationSharedPtr(); @@ -1220,11 +1452,25 @@ 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..c188234105d7 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,13 +278,53 @@ 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; maShapeUpdateQueue.push(aQueueElement); } +void box2DWorld::queueShapeAnimationUpdate( + const css::uno::Reference<com::sun::star::drawing::XShape>& xShape, + const slideshow::internal::ShapeAttributeLayerSharedPtr& pAttrLayer, + const slideshow::internal::AttributeType eAttrType) +{ + switch (eAttrType) + { + case slideshow::internal::AttributeType::Visibility: + queueShapeVisibilityUpdate(xShape, pAttrLayer->getVisibility()); + return; + case slideshow::internal::AttributeType::Rotate: + queueRotationUpdate(xShape, pAttrLayer->getRotationAngle()); + return; + case slideshow::internal::AttributeType::PosX: + case slideshow::internal::AttributeType::PosY: + queuePositionUpdate(xShape, { pAttrLayer->getPosX(), pAttrLayer->getPosY() }); + return; + default: + return; + } +} + +void box2DWorld::queueShapeAnimationEndUpdate( + const css::uno::Reference<com::sun::star::drawing::XShape>& xShape, + const slideshow::internal::AttributeType eAttrType) +{ + switch (eAttrType) + { + case slideshow::internal::AttributeType::Rotate: + queueAngularVelocityUpdate(xShape, 0.0f); + return; + case slideshow::internal::AttributeType::PosX: + case slideshow::internal::AttributeType::PosY: + queueLinearVelocityUpdate(xShape, { 0, 0 }); + return; + default: + return; + } +} + void box2DWorld::step(const float fTimeStep, const int nVelocityIterations, const int nPositionIterations) { @@ -318,14 +360,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 +377,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 b70f8b5abe4e..569b7fea09a9 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 cbc468d9f17b..a91d5857bc7d 100644 --- a/slideshow/source/engine/slideshowimpl.cxx +++ b/slideshow/source/engine/slideshowimpl.cxx @@ -85,6 +85,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 @@ -422,6 +425,7 @@ private: ActivitiesQueue maActivitiesQueue; UserEventQueue maUserEventQueue; SubsettableShapeManagerSharedPtr mpDummyPtr; + box2d::utils::Box2DWorldSharedPtr mpBox2DDummyPtr; std::shared_ptr<SeparateListenerImpl> mpListener; @@ -550,6 +554,7 @@ SlideShowImpl::SlideShowImpl( maEventQueue, *this ), mpDummyPtr(), + mpBox2DDummyPtr(), mpListener(), mpRehearseTimingsActivity(), mpWaitSymbol(), @@ -1694,7 +1699,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; |