[Libreoffice-commits] core.git: Branch 'private/quwex/gsoc-box2d-experimental' - 3 commits - animations/source include/xmloff offapi/com offapi/UnoApi_offapi.mk officecfg/registry sd/inc sd/source sd/uiconfig sd/xml slideshow/Library_slideshow.mk slideshow/source xmloff/source

Sarper Akdemir (via logerrit) logerrit at kemper.freedesktop.org
Mon Jul 20 11:00:23 UTC 2020


Rebased ref, commits from common ancestor:
commit d5284d05c77becd02567dadc380b928e52269f0e
Author:     Sarper Akdemir <q.sarperakdemir at gmail.com>
AuthorDate: Thu Jun 25 20:33:05 2020 +0300
Commit:     Sarper Akdemir <q.sarperakdemir at gmail.com>
CommitDate: Mon Jul 20 12:57:02 2020 +0300

    work-in-progress import export simulatedanimations
    
    Change-Id: I38b0511f973668655cff78becebe3f1e628d9083

diff --git a/animations/source/animcore/animcore.component b/animations/source/animcore/animcore.component
index 2f490aa0ae06..bcc7f58aaac3 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::AnimateSimulation"
+      constructor="com_sun_star_animations_AnimateSimulation_get_implementation">
+    <service name="com.sun.star.animations.AnimateSimulation"/>
   </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..e529ccfe6ba9 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_ANIMATESIMULATION()
+{
+    return { "com.sun.star.animations.AnimateSimulation" };
+}
+
+static OUString getImplementationName_ANIMATESIMULATION()
+{
+    return "animcore::AnimateSimulation";
+}
+
 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::ANIMATESIMULATED:
+            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, // ANIMATESIMULATED
     };
 
     // 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::ANIMATESIMULATED:
+        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::ANIMATESIMULATED:
+        return getImplementationName_ANIMATESIMULATION();
     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::ANIMATESIMULATED:
+        return getSupportedServiceNames_ANIMATESIMULATION();
     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_AnimateSimulation_get_implementation(css::uno::XComponentContext*,
+                                                             css::uno::Sequence<css::uno::Any> const &)
+{
+    return cppu::acquire(new animcore::AnimationNode(ANIMATESIMULATED));
+}
+
 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..4e3a23dacffd 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_ANIMATESIMULATION,
         XML_ANIMATETRANSFORM,
         XML_ANIMATECOLOR,
         XML_TRANSITIONFILTER,
@@ -2986,6 +2987,7 @@ namespace xmloff::token {
         XML_EXIT,
         XML_EMPHASIS,
         XML_MOTION_PATH,
+        XML_MOTION_SIMULATED,
         XML_OLE_ACTION,
         XML_MEDIA_CALL,
         XML_ON_CLICK,
diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk
index 68a493cfa6ac..cef77ecc02f8 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 \
+	AnimateSimulation \
 	AnimateSet \
 	Audio \
 	Command \
diff --git a/offapi/com/sun/star/animations/AnimateSimulation.idl b/offapi/com/sun/star/animations/AnimateSimulation.idl
new file mode 100644
index 000000000000..e8ce028db7a4
--- /dev/null
+++ b/offapi/com/sun/star/animations/AnimateSimulation.idl
@@ -0,0 +1,35 @@
+/* -*- 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 .
+ */
+#ifndef __com_sun_star_animations_AnimateSimulation_idl__
+#define __com_sun_star_animations_AnimateSimulation_idl__
+
+#include <com/sun/star/animations/XAnimationNode.idl>
+
+
+module com {  module sun {  module star {  module animations {
+
+
+service AnimateSimulation : com::sun::star::animations::XAnimationNode;
+
+
+}; }; }; };
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/offapi/com/sun/star/presentation/EffectPresetClass.idl b/offapi/com/sun/star/presentation/EffectPresetClass.idl
index 9ff0e1201a63..50b08d0913fd 100644
--- a/offapi/com/sun/star/presentation/EffectPresetClass.idl
+++ b/offapi/com/sun/star/presentation/EffectPresetClass.idl
@@ -40,6 +40,7 @@ constants EffectPresetClass
     const short EXIT = 2;
     const short EMPHASIS = 3;
     const short MOTIONPATH = 4;
+    const short MOTIONSIMULATION = 7;
     const short OLEACTION = 5;
     const short MEDIACALL = 6;
 };
diff --git a/officecfg/registry/data/org/openoffice/Office/UI/Effects.xcu b/officecfg/registry/data/org/openoffice/Office/UI/Effects.xcu
index 1f9267d958e1..fd0315913f1d 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="ooo-motionsimulated-basic" oor:op="replace">
+        <prop oor:name="Label" oor:type="xs:string">
+          <value xml:lang="en-US">Simulated 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>
@@ -2574,5 +2579,15 @@
         </prop>
       </node>
     </node>
+    <node oor:name="MotionSimulated">
+      <node oor:name="basic" oor:op="replace">
+        <prop oor:name="Label" oor:type="xs:string">
+          <value xml:lang="en-US">Basic</value>
+        </prop>
+        <prop oor:name="Effects" oor:type="oor:string-list">
+          <value oor:separator=";">ooo-motionsimulated-basic</value>
+        </prop>
+      </node>
+    </node>
   </node>
 </oor:component-data>
diff --git a/officecfg/registry/schema/org/openoffice/Office/UI/Effects.xcs b/officecfg/registry/schema/org/openoffice/Office/UI/Effects.xcs
index d57104e3d121..873f2facfcb8 100644
--- a/officecfg/registry/schema/org/openoffice/Office/UI/Effects.xcs
+++ b/officecfg/registry/schema/org/openoffice/Office/UI/Effects.xcs
@@ -143,6 +143,11 @@
           <desc>Contains all the categories that don't fit anywhere else."</desc>
         </info>
       </set>
+      <set oor:name="MotionSimulated" oor:node-type="PresetCategory">
+        <info>
+          <desc>Contains the categories for simulated animation effects."</desc>
+        </info>
+      </set>
     </group>
   </component>
 </oor:component-schema>
diff --git a/sd/inc/CustomAnimationPreset.hxx b/sd/inc/CustomAnimationPreset.hxx
index b05f1675c6a7..3d25010a0b4e 100644
--- a/sd/inc/CustomAnimationPreset.hxx
+++ b/sd/inc/CustomAnimationPreset.hxx
@@ -105,6 +105,7 @@ public:
     SAL_DLLPRIVATE const PresetCategoryList& getExitPresets() const { return maExitPresets; }
     SAL_DLLPRIVATE const PresetCategoryList& getMotionPathsPresets() const { return maMotionPathsPresets; }
     SAL_DLLPRIVATE const PresetCategoryList& getMiscPresets() const { return maMiscPresets; }
+    SAL_DLLPRIVATE const PresetCategoryList& getMotionSimulatedPresets() const { return maMotionSimulatedPresets; }
 
     SAL_DLLPRIVATE void changePresetSubType( const CustomAnimationEffectPtr& pEffect, const OUString& rPresetSubType ) const;
 
@@ -127,6 +128,7 @@ private:
     PresetCategoryList maExitPresets;
     PresetCategoryList maMotionPathsPresets;
     PresetCategoryList maMiscPresets;
+    PresetCategoryList maMotionSimulatedPresets;
 
     //! Maps per-language the animation presets.
     SAL_DLLPRIVATE static std::map<OUString, CustomAnimationPresets>  mPresetsMap;
diff --git a/sd/inc/strings.hrc b/sd/inc/strings.hrc
index 0e093d1da84b..b339def6569d 100644
--- a/sd/inc/strings.hrc
+++ b/sd/inc/strings.hrc
@@ -434,6 +434,7 @@
 #define STR_CUSTOMANIMATION_EMPHASIS                    NC_("STR_CUSTOMANIMATION_EMPHASIS", "Emphasis: %1")
 #define STR_CUSTOMANIMATION_EXIT                        NC_("STR_CUSTOMANIMATION_EXIT", "Exit: %1")
 #define STR_CUSTOMANIMATION_MOTION_PATHS                NC_("STR_CUSTOMANIMATION_MOTION_PATHS", "Motion Paths: %1")
+#define STR_CUSTOMANIMATION_MOTION_SIMULATION           NC_("STR_CUSTOMANIMATION_MOTION_SIMULATION", "Simulated Motion: %1")
 #define STR_CUSTOMANIMATION_MISC                        NC_("STR_CUSTOMANIMATION_MISC", "Misc: %1")
 #define STR_SLIDETRANSITION_NONE                        NC_("STR_SLIDETRANSITION_NONE", "None")
 
diff --git a/sd/source/core/CustomAnimationPreset.cxx b/sd/source/core/CustomAnimationPreset.cxx
index 3be4e76941f8..bec05fa14259 100644
--- a/sd/source/core/CustomAnimationPreset.cxx
+++ b/sd/source/core/CustomAnimationPreset.cxx
@@ -349,6 +349,8 @@ void CustomAnimationPresets::importResources()
         importPresets( xConfigProvider, "/org.openoffice.Office.UI.Effects/Presets/MotionPaths", maMotionPathsPresets );
 
         importPresets( xConfigProvider, "/org.openoffice.Office.UI.Effects/Presets/Misc", maMiscPresets );
+
+        importPresets( xConfigProvider, "/org.openoffice.Office.UI.Effects/Presets/MotionSimulated", maMotionSimulatedPresets );
     }
     catch (const lang::WrappedTargetException&)
     {
@@ -502,6 +504,7 @@ Reference< XAnimationNode > CustomAnimationPresets::getRandomPreset( sal_Int16 n
     case EffectPresetClass::EXIT:       pCategoryList = &maExitPresets; break;
     case EffectPresetClass::EMPHASIS:   pCategoryList = &maEmphasisPresets; break;
     case EffectPresetClass::MOTIONPATH: pCategoryList = &maMotionPathsPresets; break;
+    case EffectPresetClass::MOTIONSIMULATION: pCategoryList = &maMotionSimulatedPresets; break;
     default:
         pCategoryList = nullptr;
     }
diff --git a/sd/source/ui/animations/CustomAnimationList.cxx b/sd/source/ui/animations/CustomAnimationList.cxx
index 0e2762ce762e..63fe7b391a97 100644
--- a/sd/source/ui/animations/CustomAnimationList.cxx
+++ b/sd/source/ui/animations/CustomAnimationList.cxx
@@ -252,6 +252,8 @@ CustomAnimationListEntryItem::CustomAnimationListEntryItem(const OUString& aDesc
         msEffectName = SdResId(STR_CUSTOMANIMATION_EMPHASIS); break;
     case EffectPresetClass::MOTIONPATH:
         msEffectName = SdResId(STR_CUSTOMANIMATION_MOTION_PATHS); break;
+    case EffectPresetClass::MOTIONSIMULATION:
+        msEffectName = SdResId(STR_CUSTOMANIMATION_MOTION_SIMULATION); break;
     default:
         msEffectName = SdResId(STR_CUSTOMANIMATION_MISC); break;
     }
@@ -371,6 +373,7 @@ void CustomAnimationListEntryItem::PaintEffect(vcl::RenderContext& rRenderContex
     case EffectPresetClass::EMPHASIS:
         sImage = BMP_CUSTOMANIMATION_EMPHASIS_EFFECT; break;
     case EffectPresetClass::MOTIONPATH:
+    case EffectPresetClass::MOTIONSIMULATION:
         sImage = BMP_CUSTOMANIMATION_MOTION_PATH; break;
     case EffectPresetClass::OLEACTION:
         sImage = BMP_CUSTOMANIMATION_OLE; break;
diff --git a/sd/source/ui/animations/CustomAnimationPane.cxx b/sd/source/ui/animations/CustomAnimationPane.cxx
index 45e44c0d8628..cdcc1cb97cc3 100644
--- a/sd/source/ui/animations/CustomAnimationPane.cxx
+++ b/sd/source/ui/animations/CustomAnimationPane.cxx
@@ -585,6 +585,7 @@ void CustomAnimationPane::updateControls()
             case EffectPresetClass::EMPHASIS: nCategoryPos = 1; break;
             case EffectPresetClass::EXIT: nCategoryPos = 2; break;
             case EffectPresetClass::MOTIONPATH: nCategoryPos = 3; break;
+            case EffectPresetClass::MOTIONSIMULATION: nCategoryPos = 5; break;
             default:
                 break;
         }
@@ -2186,6 +2187,7 @@ sal_Int32 CustomAnimationPane::fillAnimationLB( bool bHasText )
         case 2:rCategoryList = rPresets.getExitPresets();break;
         case 3:rCategoryList = rPresets.getMotionPathsPresets();break;
         case 4:rCategoryList = rPresets.getMiscPresets();break;
+        case 5:rCategoryList = rPresets.getMotionSimulatedPresets();break;
     }
 
     sal_Int32 nFirstEffect = -1;
diff --git a/sd/uiconfig/simpress/ui/customanimationspanel.ui b/sd/uiconfig/simpress/ui/customanimationspanel.ui
index 94184323a775..333cf74793ba 100644
--- a/sd/uiconfig/simpress/ui/customanimationspanel.ui
+++ b/sd/uiconfig/simpress/ui/customanimationspanel.ui
@@ -290,6 +290,7 @@
                   <item translatable="yes" context="customanimationspanel|categorylb">Exit</item>
                   <item translatable="yes" context="customanimationspanel|categorylb">Motion Paths</item>
                   <item translatable="yes" context="customanimationspanel|categorylb">Misc Effects</item>
+                  <item translatable="yes" context="customanimationspanel|categorylb">Simulated Motion</item>
                 </items>
               </object>
               <packing>
diff --git a/sd/xml/effects.xml b/sd/xml/effects.xml
index 393ad5d50263..94584fa329b0 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="motion-simulated" pres:preset-id="ooo-motionsimulated-basic">
+                <anim:animateSimulation smil:dur="2" 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..d0528ca80e33 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( "animateSimulation",         XML_ANIMATESIMULATION ),
         TOKEN( "animateTransform",          XML_ANIMATETRANSFORM ),
         TOKEN( "animateColor",              XML_ANIMATECOLOR ),
         TOKEN( "transitionFilter",          XML_TRANSITIONFILTER ),
@@ -2987,6 +2988,7 @@ namespace xmloff::token {
         TOKEN( "exit",              XML_EXIT ),
         TOKEN( "emphasis",          XML_EMPHASIS ),
         TOKEN( "motion-path",           XML_MOTION_PATH ),
+        TOKEN( "motion-simulated",      XML_MOTION_SIMULATED ),
         TOKEN( "ole-action",            XML_OLE_ACTION ),
         TOKEN( "media-call",            XML_MEDIA_CALL ),
         TOKEN( "on-click",          XML_ON_CLICK ),
diff --git a/xmloff/source/draw/animationexport.cxx b/xmloff/source/draw/animationexport.cxx
index 7aa293e75716..25ff6357523f 100644
--- a/xmloff/source/draw/animationexport.cxx
+++ b/xmloff/source/draw/animationexport.cxx
@@ -357,6 +357,7 @@ const SvXMLEnumMapEntry<sal_Int16> aAnimations_EnumMap_EffectPresetClass[] =
     { XML_MOTION_PATH,  EffectPresetClass::MOTIONPATH },
     { XML_OLE_ACTION,   EffectPresetClass::OLEACTION },
     { XML_MEDIA_CALL,   EffectPresetClass::MEDIACALL },
+    { XML_MOTION_SIMULATED, EffectPresetClass::MOTIONSIMULATION },
     { XML_TOKEN_INVALID, 0 }
 };
 const SvXMLEnumMapEntry<sal_Int16> aAnimations_EnumMap_EffectNodeType[] =
@@ -697,6 +698,7 @@ void AnimationsExporterImpl::prepareNode( const Reference< XAnimationNode >& xNo
         case AnimationNodeType::ANIMATE:
         case AnimationNodeType::SET:
         case AnimationNodeType::ANIMATEMOTION:
+        case AnimationNodeType::ANIMATESIMULATED:
         case AnimationNodeType::ANIMATECOLOR:
         case AnimationNodeType::ANIMATETRANSFORM:
         case AnimationNodeType::TRANSITIONFILTER:
@@ -947,6 +949,7 @@ void AnimationsExporterImpl::exportNode( const Reference< XAnimationNode >& xNod
         case AnimationNodeType::ANIMATE:
         case AnimationNodeType::SET:
         case AnimationNodeType::ANIMATEMOTION:
+        case AnimationNodeType::ANIMATESIMULATED:
         case AnimationNodeType::ANIMATECOLOR:
         case AnimationNodeType::ANIMATETRANSFORM:
         case AnimationNodeType::TRANSITIONFILTER:
@@ -1089,6 +1092,10 @@ void AnimationsExporterImpl::exportAnimate( const Reference< XAnimate >& xAnimat
         {
             eAttributeName = XML_ANIMATEMOTION;
         }
+        else if( nNodeType == AnimationNodeType::ANIMATESIMULATED )
+        {
+            eAttributeName = XML_ANIMATESIMULATION;
+        }
         else
         {
             OUString sTemp( xAnimate->getAttributeName() );
@@ -1234,6 +1241,15 @@ void AnimationsExporterImpl::exportAnimate( const Reference< XAnimate >& xAnimat
         }
         break;
 
+        case AnimationNodeType::ANIMATESIMULATED:
+        {
+            eElementToken = XML_ANIMATESIMULATION;
+
+            Reference< XAnimateMotion > xAnimateMotion( xAnimate, UNO_QUERY_THROW );
+            aTemp = xAnimateMotion->getOrigin();
+        }
+        break;
+
         case AnimationNodeType::ANIMATECOLOR:
         {
             eElementToken = XML_ANIMATECOLOR;
@@ -1437,6 +1453,7 @@ void AnimationsExporterImpl::convertValue( XMLTokenEnum eAttributeName, OUString
         case XML_HEIGHT:
         case XML_ANIMATETRANSFORM:
         case XML_ANIMATEMOTION:
+        case XML_ANIMATESIMULATION:
         {
             if( auto aString = o3tl::tryAccess<OUString>(rValue) )
             {
diff --git a/xmloff/source/draw/animationimport.cxx b/xmloff/source/draw/animationimport.cxx
index ebccff3d1a22..0cddb5169f80 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_ANIMATESIMULATION:
+                pServiceName = "com.sun.star.animations.AnimateSimulation"; 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..18f75351e199 100644
--- a/xmloff/source/token/tokens.txt
+++ b/xmloff/source/token/tokens.txt
@@ -2620,6 +2620,7 @@ additive
 multiply
 animate
 animateMotion
+animateSimulation
 animateTransform
 animateColor
 transitionFilter
@@ -2802,6 +2803,7 @@ entrance
 exit
 emphasis
 motion-path
+motion-simulated
 ole-action
 media-call
 on-click
commit 37f2dc25a9bb3de361179c835980fbf4cd9783aa
Author:     Sarper Akdemir <q.sarperakdemir at gmail.com>
AuthorDate: Thu Jun 11 19:29:38 2020 +0300
Commit:     Sarper Akdemir <q.sarperakdemir at gmail.com>
CommitDate: Mon Jul 20 12:57:02 2020 +0300

    make simulated animations 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 AnimationSimulationNode
    for simulated animations and SimulatedAnimation class
    that inherits from NumberAnimation in the animation
    factory.
    
    Also, this commit makes it possible to have two box2d
    animation effects in parallel with -with previous-
    option
    
    Change-Id: I1f125df5324673e9937b8164c0fc267c9683afa0

diff --git a/offapi/com/sun/star/animations/AnimationNodeType.idl b/offapi/com/sun/star/animations/AnimationNodeType.idl
index 31bed11ff728..770f148356ae 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 simulated animation */
+    const short ANIMATESIMULATED = 12;
+
 };
 
 
diff --git a/slideshow/Library_slideshow.mk b/slideshow/Library_slideshow.mk
index 53324ea25dcc..398f82bd1f51 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/animationsimulatednode \
     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..0b370da7bc10 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 the linear velocity
+                        if( mpBox2DWorld->isInitialized() )
+                            mpBox2DWorld->queryLinearVelocityUpdate( mpShape->getXShape(), {0,0});
                     }
                 }
 
@@ -312,8 +319,11 @@ namespace slideshow::internal
 
                     mpAttrLayer->setPosition( rOutPos );
 
-                    if( mpShape->isContentChanged() )
+                    if( mpShape->isContentChanged() ) {
+                        if ( mpBox2DWorld->isInitialized() )
+                            mpBox2DWorld->queryPositionUpdate( mpShape->getXShape(), rOutPos );
                         mpShapeManager->notifyShapeUpdate( mpShape );
+                    }
 
                     return true;
                 }
@@ -339,8 +349,157 @@ namespace slideshow::internal
                 const int                          mnFlags;
                 bool                               mbAnimationStarted;
                 sal_Int16                          mnAdditive;
+                box2d::utils::Box2DWorldSharedPtr  mpBox2DWorld;
             };
 
+            class SimulatedAnimation : public NumberAnimation
+            {
+            public:
+                SimulatedAnimation( 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,
+                                     "SimulatedAnimation::SimulatedAnimation(): Invalid ShapeManager" );
+                }
+
+                virtual ~SimulatedAnimation() override
+                {
+                    end();
+                }
+
+                // Animation interface
+
+                virtual void prefetch() override
+                {}
+
+                virtual void start( const AnimatableShapeSharedPtr&     rShape,
+                                    const ShapeAttributeLayerSharedPtr& rAttrLayer ) override
+                {
+                    OSL_ENSURE( !mpShape,
+                                "SimulatedAnimation::start(): Shape already set" );
+                    OSL_ENSURE( !mpAttrLayer,
+                                "SimulatedAnimation::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,
+                                      "SimulatedAnimation::start(): Invalid shape" );
+                    ENSURE_OR_THROW( rAttrLayer,
+                                      "SimulatedAnimation::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
+                {
+                    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,
+                                       "SimulatedAnimation::operator(): Invalid ShapeAttributeLayer" );
+
+                    // if there are multiple simulated 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 );
+                    }
+
+                    ::basegfx::B2DPoint rOutPos = mpBox2DBody->getPosition();
+                    mpAttrLayer->setPosition( rOutPos );
+
+                    double fAngle = mpBox2DBody->getAngle();
+                    mpAttrLayer->setRotationAngle( fAngle );
+
+                    if( mpShape->isContentChanged() )
+                        mpShapeManager->notifyShapeUpdate( mpShape );
+
+                    return true;
+                }
+
+                virtual double getUnderlyingValue() const override
+                {
+                    ENSURE_OR_THROW( mpAttrLayer,
+                                      "SimulatedAnimation::getUnderlyingValue(): Invalid ShapeAttributeLayer" );
+
+                    return 0.0; // though this should be used in concert with
+                                // ActivitiesFactory::createSimpleActivity, better
+                                // explicitly name our start value.
+                                // Permissible range for operator() above is [0,1]
+                }
+
+            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 +564,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 +577,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 +636,19 @@ namespace slideshow::internal
 
                     mbAnimationStarted = false;
 
+                    if( mpBox2DWorld && mpBox2DWorld->isInitialized() ){
+                        switch( mapAttributeName( maAttrName ) ){
+                        case AttributeType::Rotate:
+                            mpBox2DWorld->queryAngularVelocityUpdate( mpShape->getXShape(), 0.0f );
+                            break;
+                        case AttributeType::PosX:
+                        case AttributeType::PosY:
+                            mpBox2DWorld->queryLinearVelocityUpdate( mpShape->getXShape(), { 0, 0 } );
+                        default:
+                            break;
+                        }
+                    }
+
                     if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) )
                         mpShapeManager->leaveAnimationMode( mpShape );
 
@@ -529,6 +705,24 @@ namespace slideshow::internal
 
                     ((*mpAttrLayer).*mpSetValueFunc)( maSetterModifier( x ) );
 
+                    if( mpBox2DWorld && mpBox2DWorld->isInitialized() ){
+                        switch( mapAttributeName( maAttrName ) ){
+                        case AttributeType::Visibility:
+                            mpBox2DWorld->queryShapeVisibilityUpdate( mpShape->getXShape(), (*mpAttrLayer).getVisibility() );
+                            break;
+                        case AttributeType::Rotate:
+                            mpBox2DWorld->queryRotationUpdate( mpShape->getXShape(), (*mpAttrLayer).getRotationAngle() );
+                            break;
+                        case AttributeType::PosX:
+                        case AttributeType::PosY:
+                            mpBox2DWorld->queryPositionUpdate( 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::createSimulatedAnimation(  const box2d::utils::Box2DWorldSharedPtr pBox2DWorld,
+                                                                              const double                      fDuration,
+                                                                              const ShapeManagerSharedPtr&      rShapeManager,
+                                                                              const ::basegfx::B2DVector&       rSlideSize,
+                                                                              int                               nFlags )
+        {
+            return std::make_shared<SimulatedAnimation>( 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..a88c3a8ab7e0 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 "animationsimulatednode.hxx"
 #include "animationcolornode.hxx"
 #include "animationtransformnode.hxx"
 #include "animationtransitionfilternode.hxx"
@@ -493,6 +494,11 @@ BaseNodeSharedPtr implCreateAnimationNode(
                                 xNode, rParent, rContext );
         break;
 
+    case animations::AnimationNodeType::ANIMATESIMULATED:
+        pCreatedNode = std::make_shared<AnimationSimulatedNode>(
+                                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/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/animationsimulatednode.cxx b/slideshow/source/engine/animationnodes/animationsimulatednode.cxx
new file mode 100644
index 000000000000..3ad3837a1d23
--- /dev/null
+++ b/slideshow/source/engine/animationnodes/animationsimulatednode.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 "animationsimulatednode.hxx"
+#include <animationfactory.hxx>
+
+namespace slideshow::internal
+{
+void AnimationSimulatedNode::dispose()
+{
+    mxSimulatedMotionNode.clear();
+    AnimationBaseNode::dispose();
+}
+
+AnimationActivitySharedPtr AnimationSimulatedNode::createActivity() const
+{
+    double fDuration;
+    ENSURE_OR_THROW((mxSimulatedMotionNode->getDuration() >>= fDuration),
+                    "Couldn't get the animation duration.");
+
+    ActivitiesFactory::CommonParameters const aParms(fillCommonParameters());
+    return ActivitiesFactory::createSimpleActivity(
+        aParms,
+        AnimationFactory::createSimulatedAnimation(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/animationsimulatednode.hxx b/slideshow/source/engine/animationnodes/animationsimulatednode.hxx
new file mode 100644
index 000000000000..82fa764c805d
--- /dev/null
+++ b/slideshow/source/engine/animationnodes/animationsimulatednode.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 AnimationSimulatedNode : public AnimationBaseNode
+{
+public:
+    AnimationSimulatedNode(const css::uno::Reference<css::animations::XAnimationNode>& xNode,
+                           const BaseContainerNodeSharedPtr& rParent, const NodeContext& rContext)
+        : AnimationBaseNode(xNode, rParent, rContext)
+        , mxSimulatedMotionNode(xNode, css::uno::UNO_QUERY_THROW)
+    {
+    }
+
+#if defined(DBG_UTIL)
+    virtual const char* getDescription() const override { return "AnimationSimulationNode"; }
+#endif
+
+protected:
+    virtual void dispose() override;
+
+private:
+    virtual AnimationActivitySharedPtr createActivity() const override;
+
+    css::uno::Reference<css::animations::XAnimateMotion> mxSimulatedMotionNode;
+};
+
+} // namespace internal
+} // namespace slideshow
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
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/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..3ea5ab50393b 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..273b7d57e151 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,
                                                                            const ShapeManagerSharedPtr&         rShapeManager,
                                                                            const ::basegfx::B2DVector&          rSlideSize,
+                                                                           const box2d::utils::Box2DWorldSharedPtr pBox2DWorld,
                                                                            int                                  nFlags );
 
             BoolAnimationSharedPtr   createBoolPropertyAnimation( const OUString&                 rAttrName,
                                                                          const AnimatableShapeSharedPtr&        rShape,
                                                                          const ShapeManagerSharedPtr&           rShapeManager,
                                                                          const ::basegfx::B2DVector&            rSlideSize,
+                                                                         const box2d::utils::Box2DWorldSharedPtr pBox2DWorld,
                                                                          int                                    nFlags );
 
             NumberAnimationSharedPtr createPathMotionAnimation( const OUString&                   rSVGDPath,
@@ -125,7 +132,14 @@ namespace slideshow
                                                                        const AnimatableShapeSharedPtr&          rShape,
                                                                        const ShapeManagerSharedPtr&             rShapeManager,
                                                                        const ::basegfx::B2DVector&              rSlideSize,
-                                                                       int                                      nFlags);
+                                                                       const box2d::utils::Box2DWorldSharedPtr pBox2DWorld,
+                                                                       int                                      nFlags );
+
+            NumberAnimationSharedPtr createSimulatedAnimation( const box2d::utils::Box2DWorldSharedPtr pBox2DWorld,
+                                                               const double                            fDuration,
+                                                               const ShapeManagerSharedPtr&            rShapeManager,
+                                                               const ::basegfx::B2DVector&             rSlideSize,
+                                                               int                                     nFlags );
         }
     }
 }
diff --git a/slideshow/source/inc/slideshowcontext.hxx b/slideshow/source/inc/slideshowcontext.hxx
index 6d14fb34b1b2..3d2918674112 100644
--- a/slideshow/source/inc/slideshowcontext.hxx
+++ b/slideshow/source/inc/slideshowcontext.hxx
@@ -24,6 +24,9 @@
 #include <memory>
 
 namespace com::sun::star::uno { class XComponentContext; }
+namespace box2d::utils { class box2DWorld;
+                         typedef ::std::shared_ptr< box2DWorld > Box2DWorldSharedPtr; }
+
 
 
 namespace slideshow
@@ -41,7 +44,6 @@ namespace slideshow
         class MediaFileManager;
         class SubsettableShapeManager;
         typedef ::std::shared_ptr< SubsettableShapeManager > SubsettableShapeManagerSharedPtr;
-
         /** Common arguments for slideshow objects.
 
             This struct combines a number of object references
@@ -92,7 +94,8 @@ namespace slideshow
                               CursorManager&                                    rCursorManager,
                               MediaFileManager&                                 rMediaFileManager,
                               const UnoViewContainer&                           rViewContainer,
-                              const css::uno::Reference< css::uno::XComponentContext>&    rComponentContext );
+                              const css::uno::Reference< css::uno::XComponentContext>&    rComponentContext,
+                              box2d::utils::Box2DWorldSharedPtr                 rBox2DWorldPtr );
             void dispose();
 
             std::shared_ptr<SubsettableShapeManager>&     mpSubsettableShapeManager;
@@ -105,6 +108,7 @@ namespace slideshow
             MediaFileManager&                               mrMediaFileManager;
             const UnoViewContainer&                         mrViewContainer;
             css::uno::Reference< css::uno::XComponentContext>   mxComponentContext;
+            box2d::utils::Box2DWorldSharedPtr               mpBox2DWorld;
         };
     }
 }
commit 73e9f8ba5e7ffd434f60de74477fb432cd26b86e
Author:     Sarper Akdemir <q.sarperakdemir at gmail.com>
AuthorDate: Fri Jun 5 20:23:21 2020 +0300
Commit:     Sarper Akdemir <q.sarperakdemir at gmail.com>
CommitDate: Mon Jul 20 12:57:02 2020 +0300

    box2d tools: initial work for physics based animation effects
    
    Two new classes for managing box2d bodies(b2Body) and box2d worlds(b2World)
    
    ::box2d::utils::Box2DBody :
    Since b2Body has a private constructor, it is forbidden to
    make a shared_ptr out of it.
    When there are multiple parallel physics based animation effects
    going on, it will be useful to share b2Body pointers around.
    This class will help with that and also has get methods that return
    LO types instead of box2d ones.
    
    ::box2d::utils::Box2DWorld :
    A class that manages b2World with convenient functions that
    will be needed during animation effects.
    
    Change-Id: Id02fefe937347029daddde043da2b8e8dba3acaf

diff --git a/slideshow/Library_slideshow.mk b/slideshow/Library_slideshow.mk
index 55c531a86f43..53324ea25dcc 100644
--- a/slideshow/Library_slideshow.mk
+++ b/slideshow/Library_slideshow.mk
@@ -24,6 +24,7 @@ $(eval $(call gb_Library_set_precompiled_header,slideshow,slideshow/inc/pch/prec
 
 $(eval $(call gb_Library_use_externals,slideshow,\
 	boost_headers \
+	box2d \
 ))
 ifeq ($(DISABLE_GUI),)
 $(eval $(call gb_Library_use_externals,slideshow,\
@@ -84,6 +85,7 @@ $(eval $(call gb_Library_add_exception_objects,slideshow,\
     slideshow/source/engine/animationnodes/propertyanimationnode \
     slideshow/source/engine/animationnodes/sequentialtimecontainer \
     slideshow/source/engine/attributemap \
+    slideshow/source/engine/box2dtools \
     slideshow/source/engine/color \
     slideshow/source/engine/delayevent \
     slideshow/source/engine/effectrewinder \
diff --git a/slideshow/source/engine/box2dtools.cxx b/slideshow/source/engine/box2dtools.cxx
new file mode 100644
index 000000000000..3953cc08bc29
--- /dev/null
+++ b/slideshow/source/engine/box2dtools.cxx
@@ -0,0 +1,530 @@
+/* -*- 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 <box2dtools.hxx>
+#include <Box2D/Box2D.h>
+#include <shapemanager.hxx>
+
+#define BOX2D_SLIDE_SIZE_IN_METERS 100.00f
+
+namespace box2d::utils
+{
+enum box2DNonsimulatedShapeUpdateType
+{
+    BOX2D_UPDATE_POSITION,
+    BOX2D_UPDATE_ANGLE,
+    BOX2D_UPDATE_SIZE,
+    BOX2D_UPDATE_VISIBILITY,
+    BOX2D_UPDATE_LINEAR_VELOCITY,
+    BOX2D_UPDATE_ANGULAR_VELOCITY
+};
+
+struct Box2DShapeUpdateInformation
+{
+    css::uno::Reference<css::drawing::XShape> mxShape;
+    union {
+        ::basegfx::B2DPoint maPosition;
+        ::basegfx::B2DVector maVelocity;
+        double mfAngle;
+        double mfAngularVelocity;
+        bool mbVisibility;
+    };
+    box2DNonsimulatedShapeUpdateType meUpdateType;
+    int mnDelayForSteps = 0;
+};
+
+double calculateScaleFactor(const ::basegfx::B2DVector& rSlideSize)
+{
+    double fWidth = rSlideSize.getX();
+    double fHeight = rSlideSize.getY();
+
+    if (fWidth > fHeight)
+        return BOX2D_SLIDE_SIZE_IN_METERS / fWidth;
+    else
+        return BOX2D_SLIDE_SIZE_IN_METERS / fHeight;
+}
+
+b2BodyType getBox2DInternalBodyType(box2DBodyType eType)
+{
+    switch (eType)
+    {
+        default:
+        case BOX2D_STATIC_BODY:
+            return b2_staticBody;
+        case BOX2D_KINEMATIC_BODY:
+            return b2_kinematicBody;
+        case BOX2D_DYNAMIC_BODY:
+            return b2_dynamicBody;
+    }
+}
+
+box2DBodyType getBox2DLOBodyType(b2BodyType eType)
+{
+    switch (eType)
+    {
+        default:
+        case b2_staticBody:
+            return BOX2D_STATIC_BODY;
+        case b2_kinematicBody:
+            return BOX2D_KINEMATIC_BODY;
+        case b2_dynamicBody:
+            return BOX2D_DYNAMIC_BODY;
+    }
+}
+
+box2DWorld::box2DWorld(const ::basegfx::B2DVector& rSlideSize)
+    : mpBox2DWorld()
+    , mfScaleFactor(calculateScaleFactor(rSlideSize))
+    , mbShapesInitialized(false)
+    , mbHasWorldStepper(false)
+    , mpXShapeToBodyMap()
+    , maShapeUpdateQueue()
+{
+}
+
+box2DWorld::~box2DWorld() = default;
+
+bool box2DWorld::initiateWorld(const ::basegfx::B2DVector& rSlideSize)
+{
+    if (!mpBox2DWorld)
+    {
+        mpBox2DWorld = std::make_unique<b2World>(b2Vec2(0.0f, -30.0f));
+        createStaticFrameAroundSlide(rSlideSize);
+        return false;
+    }
+    else
+    {
+        return true;
+    }
+}
+
+void box2DWorld::createStaticFrameAroundSlide(const ::basegfx::B2DVector& rSlideSize)
+{
+    assert(mpBox2DWorld);
+
+    float fWidth = static_cast<float>(rSlideSize.getX() * mfScaleFactor);
+    float fHeight = static_cast<float>(rSlideSize.getY() * mfScaleFactor);
+
+    // static body for creating the frame around the slide
+    b2BodyDef aBodyDef;
+    aBodyDef.type = b2_staticBody;
+    aBodyDef.position.Set(0, 0);
+    b2Body* pStaticBody = mpBox2DWorld->CreateBody(&aBodyDef);
+
+    b2Vec2 aEdgePoints[4];
+    aEdgePoints[0].Set(0, 0);
+    aEdgePoints[1].Set(0, -fHeight);
+    aEdgePoints[2].Set(fWidth, -fHeight);
+    aEdgePoints[3].Set(fWidth, 0);
+
+    b2ChainShape aEdgesChainShape;
+    aEdgesChainShape.CreateLoop(aEdgePoints, 4);
+
+    b2FixtureDef aFixtureDef;
+    aFixtureDef.shape = &aEdgesChainShape;
+    pStaticBody->CreateFixture(&aFixtureDef);
+}
+
+void box2DWorld::setShapePositionByLinearVelocity(
+    const css::uno::Reference<com::sun::star::drawing::XShape> xShape,
+    const basegfx::B2DPoint& rOutPos, const double fPassedTime)
+{
+    assert(mpBox2DWorld);
+    if (fPassedTime > 0) // this only makes sense if there was an advance in time
+    {
+        Box2DBodySharedPtr pBox2DBody = mpXShapeToBodyMap.find(xShape)->second;
+        pBox2DBody->setPositionByLinearVelocity(rOutPos, fPassedTime);
+    }
+}
+
+void box2DWorld::setShapeLinearVelocity(
+    const css::uno::Reference<com::sun::star::drawing::XShape> xShape,
+    const basegfx::B2DVector& rVelocity)
+{
+    assert(mpBox2DWorld);
+    Box2DBodySharedPtr pBox2DBody = mpXShapeToBodyMap.find(xShape)->second;
+    pBox2DBody->setLinearVelocity(rVelocity);
+}
+
+void box2DWorld::setShapeAngleByAngularVelocity(
+    const css::uno::Reference<com::sun::star::drawing::XShape> xShape, const double fAngle,
+    const double fPassedTime)
+{
+    assert(mpBox2DWorld);
+    if (fPassedTime > 0) // this only makes sense if there was an advance in time
+    {
+        Box2DBodySharedPtr pBox2DBody = mpXShapeToBodyMap.find(xShape)->second;
+        pBox2DBody->setAngleByAngularVelocity(fAngle, fPassedTime);
+    }
+}
+
+void box2DWorld::setShapeAngularVelocity(
+    const css::uno::Reference<com::sun::star::drawing::XShape> xShape,
+    const double fAngularVelocity)
+{
+    assert(mpBox2DWorld);
+    Box2DBodySharedPtr pBox2DBody = mpXShapeToBodyMap.find(xShape)->second;
+    pBox2DBody->setAngularVelocity(fAngularVelocity);
+}
+
+void box2DWorld::setShapeCollision(
+    const css::uno::Reference<com::sun::star::drawing::XShape> xShape, bool bCanCollide)
+{
+    assert(mpBox2DWorld);
+    Box2DBodySharedPtr pBox2DBody = mpXShapeToBodyMap.find(xShape)->second;
+    pBox2DBody->setCollision(bCanCollide);
+}
+
+void box2DWorld::processUpdateQueue(const double fPassedTime)
+{
+    while (!maShapeUpdateQueue.empty())
+    {
+        auto& aQueueElement = maShapeUpdateQueue.front();
+
+        if (aQueueElement.mnDelayForSteps > 0)
+        {

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list