[Libreoffice-commits] core.git: slideshow/README slideshow/source

Sarper Akdemir (via logerrit) logerrit at kemper.freedesktop.org
Mon Aug 31 10:26:39 UTC 2020


 slideshow/README                             |   33 ++++
 slideshow/source/engine/animationfactory.cxx |    7 
 slideshow/source/engine/box2dtools.cxx       |   56 ++++++-
 slideshow/source/inc/box2dtools.hxx          |  204 +++++++++++++++++++++------
 4 files changed, 251 insertions(+), 49 deletions(-)

New commits:
commit 8e36582d9289c3774f2733b021fafc93370cffae
Author:     Sarper Akdemir <q.sarperakdemir at gmail.com>
AuthorDate: Thu Aug 27 17:08:38 2020 +0300
Commit:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Mon Aug 31 12:25:59 2020 +0200

    document physics animations and related code
    
    Change-Id: I1369588dd757d5fedcd7e91eabe0020e5cf60c56
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/101492
    Tested-by: Jenkins
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>

diff --git a/slideshow/README b/slideshow/README
index e523458531ae..e67379f43c89 100644
--- a/slideshow/README
+++ b/slideshow/README
@@ -8,3 +8,36 @@ written by GSOC student Shane.M.Mathews. Radek has later polished the
 code a bit, added few new 3D transitions, added infrastructure for
 vertex and fragment shaders. Wrote few transitions with fragment shader
 too.
+
+== Physics Animation Effects ==
+
+Physics animation effects are simulated by external 2d physics engine
+library Box2D. They don't directly call Box2D functions but instead
+use the wrapper in:
+* slideshow/source/inc/box2dtools.hxx
+* slideshow/source/engine/box2dtools.cxx
+
+The wrapper has two corresponding classes to manage the Box2D world
+and Box2D bodies.
+
+When a physics animation starts, a Box2DWorld is initiated and
+populated with every shape that is part of the foreground (which are
+shapes that do not belong to the master slide and not a background
+shape).
+
+After creation until the end of the slide (not the whole slideshow)
+the Box2D World isn't destroyed and reused. But the bodies that
+represent the shapes in the slide get destroyed when there's a point
+in time that there's no physics animation in progress. And recreated
+when another physics animation starts.
+
+If there are multiple physics animations in parallel only one of them
+takes the role of stepping through the simulation.
+
+If there are other animation effects that go in parallel which change
+the shape position, rotation, or visibility - they also report the
+change to Box2D World. These updates are collected in a queue in
+Box2DWorld and processed before stepping through the simulation.
+To achieve convincing results these updates are performed by setting
+the box2d body's linear velocity or angular velocity instead of
+setting directly it's position or rotation.
diff --git a/slideshow/source/engine/animationfactory.cxx b/slideshow/source/engine/animationfactory.cxx
index db141c906a50..e874b0924cd8 100644
--- a/slideshow/source/engine/animationfactory.cxx
+++ b/slideshow/source/engine/animationfactory.cxx
@@ -288,7 +288,8 @@ namespace slideshow::internal
                         if( mpShape->isContentChanged() )
                             mpShapeManager->notifyShapeUpdate( mpShape );
 
-                        // since animation ended zero out the linear velocity
+                        // if there is a physics animation going on report the animation ending
+                        // and zero out the velocity of the shape
                         if( mpBox2DWorld->isInitialized() )
                             mpBox2DWorld->queueLinearVelocityUpdate( mpShape->getXShape(), {0,0});
                     }
@@ -323,6 +324,8 @@ namespace slideshow::internal
                     if( mpShape->isContentChanged() )
                     {
                         mpShapeManager->notifyShapeUpdate( mpShape );
+
+                        // if there's a physics animation going on report the change to it
                         if ( mpBox2DWorld->isInitialized() )
                         {
                             mpBox2DWorld->queueShapePathAnimationUpdate( mpShape->getXShape(),
@@ -654,6 +657,7 @@ namespace slideshow::internal
 
                     if( mpBox2DWorld && mpBox2DWorld->isInitialized() )
                     {
+                        // if there's a physics animation going on report the animation ending to it
                         mpBox2DWorld->queueShapeAnimationEndUpdate( mpShape->getXShape(), meAttrType );
                     }
 
@@ -717,6 +721,7 @@ namespace slideshow::internal
 
                     if( mpBox2DWorld && mpBox2DWorld->isInitialized() )
                     {
+                        // if there's a physics animation going on report the change to it
                         mpBox2DWorld->queueShapeAnimationUpdate( mpShape->getXShape(), mpAttrLayer, meAttrType, mbAnimationFirstUpdate );
                     }
 
diff --git a/slideshow/source/engine/box2dtools.cxx b/slideshow/source/engine/box2dtools.cxx
index 5cefff743b2e..3c7c3deb657c 100644
--- a/slideshow/source/engine/box2dtools.cxx
+++ b/slideshow/source/engine/box2dtools.cxx
@@ -35,6 +35,8 @@ double calculateScaleFactor(const ::basegfx::B2DVector& rSlideSize)
     double fWidth = rSlideSize.getX();
     double fHeight = rSlideSize.getY();
 
+    // Scale factor is based on whatever is the larger
+    // value between slide width and height
     if (fWidth > fHeight)
         return BOX2D_SLIDE_SIZE_IN_METERS / fWidth;
     else
@@ -90,6 +92,8 @@ void addTriangleVectorToBody(const basegfx::triangulator::B2DTriangleVector& rTr
                 convertB2DPointToBox2DVec2(aTriangle.getC(), fScaleFactor) };
 
         bool bValidPointDistance = true;
+
+        // check whether the triangle has degenerately close points
         for (int nPointIndexA = 0; nPointIndexA < 3; nPointIndexA++)
         {
             for (int nPointIndexB = 0; nPointIndexB < 3; nPointIndexB++)
@@ -97,7 +101,6 @@ void addTriangleVectorToBody(const basegfx::triangulator::B2DTriangleVector& rTr
                 if (nPointIndexA == nPointIndexB)
                     continue;
 
-                // check whether the triangle would be a degenerately small one
                 if (b2DistanceSquared(aTriangleVertices[nPointIndexA],
                                       aTriangleVertices[nPointIndexB])
                     < 0.003f)
@@ -106,8 +109,10 @@ void addTriangleVectorToBody(const basegfx::triangulator::B2DTriangleVector& rTr
                 }
             }
         }
+
         if (bValidPointDistance)
         {
+            // create a fixture that represents the triangle
             aPolygonShape.Set(aTriangleVertices, 3);
             aFixture.shape = &aPolygonShape;
             aFixture.density = fDensity;
@@ -141,6 +146,7 @@ void addEdgeShapeToBody(const basegfx::B2DPolygon& rPolygon, b2Body* aBody, cons
         basegfx::B2DPoint aPointB;
         if (nIndex != 0)
         {
+            // get two adjacent points to create an edge out of
             aPointA = aPolygon.getB2DPoint(nIndex - 1);
             aPointB = aPolygon.getB2DPoint(nIndex);
         }
@@ -155,14 +161,22 @@ void addEdgeShapeToBody(const basegfx::B2DPolygon& rPolygon, b2Body* aBody, cons
             continue;
         }
 
+        // create a vector that represents the direction of the edge
+        // and make it a unit vector
         b2Vec2 aEdgeUnitVec(convertB2DPointToBox2DVec2(aPointB, fScaleFactor)
                             - convertB2DPointToBox2DVec2(aPointA, fScaleFactor));
         aEdgeUnitVec.Normalize();
 
+        // create a unit vector that represents Normal of the edge
         b2Vec2 aEdgeNormal(-aEdgeUnitVec.y, aEdgeUnitVec.x);
 
+        // if there was an edge previously created it should just connect
+        // using it's ending points so that there are no empty spots
+        // between edge segments, if not use wherever aPointA is at
         if (!bHasPreviousQuadrilateralEdge)
         {
+            // the point is translated along the edge normal both directions by
+            // fHalfWidth to create a quadrilateral edge
             aQuadrilateralVertices[0]
                 = convertB2DPointToBox2DVec2(aPointA, fScaleFactor) + fHalfWidth * aEdgeNormal;
             aQuadrilateralVertices[1]
@@ -174,11 +188,13 @@ void addEdgeShapeToBody(const basegfx::B2DPolygon& rPolygon, b2Body* aBody, cons
         aQuadrilateralVertices[3]
             = convertB2DPointToBox2DVec2(aPointB, fScaleFactor) + -fHalfWidth * aEdgeNormal;
 
+        // check whether the edge would have degenerately close points
         bool bValidPointDistance
             = b2DistanceSquared(aQuadrilateralVertices[0], aQuadrilateralVertices[2]) > 0.003f;
 
         if (bValidPointDistance)
         {
+            // create a quadrilateral shaped fixture to represent the edge
             aPolygonShape.Set(aQuadrilateralVertices, 4);
             aFixture.shape = &aPolygonShape;
             aFixture.density = fDensity;
@@ -243,7 +259,8 @@ void box2DWorld::createStaticFrameAroundSlide(const ::basegfx::B2DVector& rSlide
     aBodyDef.type = b2_staticBody;
     aBodyDef.position.Set(0, 0);
 
-    // not going to be stored anywhere, Box2DWorld will handle this body
+    // not going to be stored anywhere, will live
+    // as long as the Box2DWorld does
     b2Body* pStaticBody = mpBox2DWorld->CreateBody(&aBodyDef);
 
     // create an edge loop that represents slide frame
@@ -256,6 +273,7 @@ void box2DWorld::createStaticFrameAroundSlide(const ::basegfx::B2DVector& rSlide
     b2ChainShape aEdgesChainShape;
     aEdgesChainShape.CreateLoop(aEdgePoints, 4);
 
+    // create the fixture for the shape
     b2FixtureDef aFixtureDef;
     aFixtureDef.shape = &aEdgesChainShape;
     pStaticBody->CreateFixture(&aFixtureDef);
@@ -379,6 +397,8 @@ void box2DWorld::initateAllShapesAsStaticBodies(
     std::unordered_map<css::uno::Reference<css::drawing::XShape>, bool> aXShapeBelongsToAGroup;
 
     // iterate over the shapes in the current slide and flag them if they belong to a group
+    // will flag the only ones that are belong to a group since std::unordered_map operator[]
+    // defaults the value to false if the key doesn't have a corresponding value
     for (auto aIt = aXShapeToShapeMap.begin(); aIt != aXShapeToShapeMap.end(); aIt++)
     {
         slideshow::internal::ShapeSharedPtr pShape = aIt->second;
@@ -387,6 +407,7 @@ void box2DWorld::initateAllShapesAsStaticBodies(
             SdrObject* pTemp = SdrObject::getSdrObjectFromXShape(pShape->getXShape());
             if (pTemp && pTemp->IsGroupObject())
             {
+                // if it is a group object iterate over it's childs and flag them
                 SdrObjList* aObjList = pTemp->GetSubList();
                 const size_t nObjCount(aObjList->GetObjCount());
 
@@ -404,6 +425,9 @@ void box2DWorld::initateAllShapesAsStaticBodies(
     for (auto aIt = aXShapeToShapeMap.begin(); aIt != aXShapeToShapeMap.end(); aIt++)
     {
         slideshow::internal::ShapeSharedPtr pShape = aIt->second;
+        // only create static bodies for the shapes that do not belong to a group
+        // groups themselves will have one body that represents the whole shape
+        // collection
         if (pShape->isForeground() && !aXShapeBelongsToAGroup[pShape->getXShape()])
         {
             Box2DBodySharedPtr pBox2DBody = createStaticBody(pShape);
@@ -411,7 +435,7 @@ void box2DWorld::initateAllShapesAsStaticBodies(
             mpXShapeToBodyMap.insert(std::make_pair(pShape->getXShape(), pBox2DBody));
             if (!pShape->isVisible())
             {
-                // if the shape isn't visible, mark it
+                // if the shape isn't visible, queue an update for it
                 queueShapeVisibilityUpdate(pShape->getXShape(), false);
             }
         }
@@ -504,7 +528,7 @@ void box2DWorld::queueShapeAnimationUpdate(
             return;
         case slideshow::internal::AttributeType::PosX:
         case slideshow::internal::AttributeType::PosY:
-            if (bIsFirstUpdate)
+            if (bIsFirstUpdate) // if it is the first update shape should _teleport_ to the position
                 queueShapePositionUpdate(xShape, { pAttrLayer->getPosX(), pAttrLayer->getPosY() });
             else
                 queueDynamicPositionUpdate(xShape,
@@ -521,6 +545,8 @@ void box2DWorld::queueShapeAnimationEndUpdate(
 {
     switch (eAttrType)
     {
+        // end updates that change the velocity are delayed for a step
+        // since we do not want them to override the last position/angle
         case slideshow::internal::AttributeType::Rotate:
             queueAngularVelocityUpdate(xShape, 0.0, 1);
             return;
@@ -536,12 +562,16 @@ void box2DWorld::queueShapeAnimationEndUpdate(
 void box2DWorld::alertPhysicsAnimationEnd(const slideshow::internal::ShapeSharedPtr& pShape)
 {
     Box2DBodySharedPtr pBox2DBody = mpXShapeToBodyMap.find(pShape->getXShape())->second;
+    // since the animation ended make the body static
     makeBodyStatic(pBox2DBody);
     pBox2DBody->setRestitution(fDefaultStaticBodyBounciness);
     if (--mnPhysicsAnimationCounter == 0)
     {
+        // if there are no more physics animation effects going on clean up
         maShapeParallelUpdateQueue = {};
         mbShapesInitialized = false;
+        // clearing the map will make the box2d bodies get
+        // destroyed if there's nothing else that owns them
         mpXShapeToBodyMap.clear();
     }
 }
@@ -572,8 +602,11 @@ double box2DWorld::stepAmount(const double fPassedTime, const float fTimeStep,
     assert(mpBox2DWorld);
 
     unsigned int nStepAmount = static_cast<unsigned int>(std::round(fPassedTime / fTimeStep));
+    // find the actual time that will be stepped through so
+    // that the updates can be processed using that value
     double fTimeSteppedThrough = fTimeStep * nStepAmount;
 
+    // do the updates required to simulate other animaton effects going in parallel
     processUpdateQueue(fTimeSteppedThrough);
 
     for (unsigned int nStepCounter = 0; nStepCounter < nStepAmount; nStepCounter++)
@@ -647,9 +680,11 @@ Box2DBodySharedPtr box2DWorld::createStaticBody(const slideshow::internal::Shape
               ->getTopmostAttributeLayer();
     if (pShapeAttributeLayer && pShapeAttributeLayer->isRotationAngleValid())
     {
+        // if the shape's rotation value was altered by another animation effect set it.
         aBodyDef.angle = ::basegfx::deg2rad(-pShapeAttributeLayer->getRotationAngle());
     }
 
+    // create a shared pointer with a destructor so that the body will be properly destroyed
     std::shared_ptr<b2Body> pBody(mpBox2DWorld->CreateBody(&aBodyDef), [](b2Body* pB2Body) {
         pB2Body->GetWorld()->DestroyBody(pB2Body);
     });
@@ -679,6 +714,7 @@ Box2DBodySharedPtr box2DWorld::createStaticBody(const slideshow::internal::Shape
     aPolyPolygon.removeDoublePoints();
 
     // make polygon coordinates relative to the center of the shape instead of top left of the slide
+    // since box2d shapes are expressed this way
     aPolyPolygon
         = basegfx::utils::distort(aPolyPolygon, aPolyPolygon.getB2DRange(),
                                   { -aShapeBounds.getWidth() / 2, -aShapeBounds.getHeight() / 2 },
@@ -689,8 +725,10 @@ Box2DBodySharedPtr box2DWorld::createStaticBody(const slideshow::internal::Shape
     if (pSdrObject->IsClosedObj() && !pSdrObject->IsEdgeObj() && pSdrObject->HasFillStyle())
     {
         basegfx::triangulator::B2DTriangleVector aTriangleVector;
+        // iterate over the polygons of the shape and create representations for them
         for (auto& rPolygon : aPolyPolygon)
         {
+            // if the polygon is closed it will be represented by triangles
             if (rPolygon.isClosed())
             {
                 basegfx::triangulator::B2DTriangleVector aTempTriangleVector(
@@ -698,7 +736,7 @@ Box2DBodySharedPtr box2DWorld::createStaticBody(const slideshow::internal::Shape
                 aTriangleVector.insert(aTriangleVector.end(), aTempTriangleVector.begin(),
                                        aTempTriangleVector.end());
             }
-            else
+            else // otherwise it will be an edge representation (example: smile line of the smiley shape)
             {
                 addEdgeShapeToBody(rPolygon, pBody.get(), fDensity, fFriction,
                                    static_cast<float>(fDefaultStaticBodyBounciness), mfScaleFactor);
@@ -739,10 +777,12 @@ void box2DBody::setPosition(const basegfx::B2DPoint& rPos)
 void box2DBody::setPositionByLinearVelocity(const basegfx::B2DPoint& rDesiredPos,
                                             const double fPassedTime)
 {
+    // kinematic bodies are not affected by other bodies, but unlike static ones can still have velocity
     if (mpBox2DBody->GetType() != b2_kinematicBody)
         mpBox2DBody->SetType(b2_kinematicBody);
 
     ::basegfx::B2DPoint aCurrentPos = getPosition();
+    // calculate the velocity needed to reach the rDesiredPos in the given time frame
     ::basegfx::B2DVector aVelocity = (rDesiredPos - aCurrentPos) / fPassedTime;
 
     setLinearVelocity(aVelocity);
@@ -750,6 +790,7 @@ void box2DBody::setPositionByLinearVelocity(const basegfx::B2DPoint& rDesiredPos
 
 void box2DBody::setAngleByAngularVelocity(const double fDesiredAngle, const double fPassedTime)
 {
+    // kinematic bodies are not affected by other bodies, but unlike static ones can still have velocity
     if (mpBox2DBody->GetType() != b2_kinematicBody)
         mpBox2DBody->SetType(b2_kinematicBody);
 
@@ -779,10 +820,13 @@ void box2DBody::setAngularVelocity(const double fAngularVelocity)
 
 void box2DBody::setCollision(const bool bCanCollide)
 {
+    // collision have to be set for each fixture of the body individually
     for (b2Fixture* pFixture = mpBox2DBody->GetFixtureList(); pFixture;
          pFixture = pFixture->GetNext())
     {
         b2Filter aFilter = pFixture->GetFilterData();
+        // 0xFFFF means collides with everything
+        // 0x0000 means collides with nothing
         aFilter.maskBits = bCanCollide ? 0xFFFF : 0x0000;
         pFixture->SetFilterData(aFilter);
     }
@@ -801,12 +845,14 @@ void box2DBody::setAngle(const double fAngle)
 
 void box2DBody::setDensityAndRestitution(const double fDensity, const double fRestitution)
 {
+    // density and restitution have to be set for each fixture of the body individually
     for (b2Fixture* pFixture = mpBox2DBody->GetFixtureList(); pFixture;
          pFixture = pFixture->GetNext())
     {
         pFixture->SetDensity(static_cast<float>(fDensity));
         pFixture->SetRestitution(static_cast<float>(fRestitution));
     }
+    // without resetting the massdata of the body, density change won't take effect
     mpBox2DBody->ResetMassData();
 }
 
diff --git a/slideshow/source/inc/box2dtools.hxx b/slideshow/source/inc/box2dtools.hxx
index ae9daa5fee35..a71af1d34bef 100644
--- a/slideshow/source/inc/box2dtools.hxx
+++ b/slideshow/source/inc/box2dtools.hxx
@@ -54,6 +54,7 @@ enum box2DNonsimulatedShapeUpdateType
 /// body of a shape that was altered by an animation effect
 struct Box2DDynamicUpdateInformation
 {
+    /// reference to the shape that the update belongs to
     css::uno::Reference<css::drawing::XShape> mxShape;
     union {
         ::basegfx::B2DPoint maPosition;
@@ -63,42 +64,60 @@ struct Box2DDynamicUpdateInformation
         bool mbVisibility;
     };
     box2DNonsimulatedShapeUpdateType meUpdateType;
+    /// amount of steps to delay the update for
     int mnDelayForSteps = 0;
 };
 
 /** Class that manages the Box2D World
 
-    This class is used when there's a simulated animation going on,
-    it handles the stepping through the simulated world, updating the
-    shapes in the simulated world if they were changed by ongoing animations.
+    This class is used when there's a physics animation going on,
+    it handles the stepping through the box2d world, updating the
+    shapes in the box2d world if they were changed by ongoing animations.
  */
 class box2DWorld
 {
 private:
-    /// Pointer to the real Box2D World that this class manages for simulations
+    /// Pointer to the real Box2D World that this class manages
     std::unique_ptr<b2World> mpBox2DWorld;
     /// Scale factor for conversions between LO user space coordinates to Box2D World coordinates
     double mfScaleFactor;
     bool mbShapesInitialized;
-    /// Holds whether or not there is a Physics Animation node that
-    /// is stepping the Box2D World
+    /// Holds whether or not there is a PhysicsAnimation that
+    /// is stepping the Box2D World. Used to create a lock mechanism
     bool mbHasWorldStepper;
+    /// Number of Physics Animations going on
     int mnPhysicsAnimationCounter;
     std::unordered_map<css::uno::Reference<css::drawing::XShape>, Box2DBodySharedPtr>
         mpXShapeToBodyMap;
-    /// Holds any information needed to keep LO animations and Box2D world in sync
-    /// if they are going in parallel
+
+    /** Queue that holds any required information to keep LO animation effects
+        and Box2DWorld in sync
+
+        Is processed before every step of the box2d world by processUpdateQueue.
+        Holds position, rotation, visibility etc. changes and associated values.
+     */
     std::queue<Box2DDynamicUpdateInformation> maShapeParallelUpdateQueue;
 
     /// Creates a static frame in Box2D world that corresponds to the slide borders
     void createStaticFrameAroundSlide(const ::basegfx::B2DVector& rSlideSize);
 
+    /** Sets shape's corresponding Box2D body to the specified position
+
+        Body is teleported to the specified position, not moved
+
+        @param xShape
+        Shape reference
+
+        @param rOutPos
+        Position in LO user space coordinates
+     */
     void setShapePosition(const css::uno::Reference<css::drawing::XShape> xShape,
                           const ::basegfx::B2DPoint& rOutPos);
-    /** Sets shape's corresponding Box2D body to specified position
 
-        Sets shape's corresponding Box2D body to specified position as if
-        the body had velocity to reach that point in given time frame
+    /** Moves shape's corresponding Box2D body to specified position
+
+        Moves shape's corresponding Box2D body to specified position as if
+        the body had velocity to reach that point in given time frame.
 
         @param xShape
         Shape reference
@@ -112,35 +131,63 @@ private:
     void setShapePositionByLinearVelocity(const css::uno::Reference<css::drawing::XShape> xShape,
                                           const ::basegfx::B2DPoint& rOutPos,
                                           const double fPassedTime);
-    /// Sets linear velocity of the shape's corresponding body in the Box2D world
+
+    /** Sets linear velocity of the shape's corresponding Box2D body
+
+        Moves shape's corresponding Box2D body to specified position as if
+        the body had velocity to reach that point in given time frame.
+
+        @param xShape
+        Shape reference
+
+        @param rVelocity
+        Velocity vector in LO user space coordinates.
+     */
     void setShapeLinearVelocity(const css::uno::Reference<com::sun::star::drawing::XShape> xShape,
                                 const basegfx::B2DVector& rVelocity);
 
+    /** Sets rotation angle of the shape's corresponding Box2D body
+
+        @param xShape
+        Shape reference
+
+        @param fAngle
+        Angle of rotation in degrees.
+     */
     void setShapeAngle(const css::uno::Reference<com::sun::star::drawing::XShape> xShape,
                        const double fAngle);
-    /** Sets shape's corresponding Box2D body to specified angle
 
-        Sets shape's corresponding Box2D body to specified angle as if
-        the body had angular velocity to reach that point in given time frame
+    /** Rotates shape's corresponding Box2D body to specified angle
+
+        Rotates the Box2D body to specified angle as if the body
+        had exact angular velocity to reach that point in given
+        time frame
 
         @param xShape
         Shape reference
 
         @param fAngle
-        Position in LO user space coordinates
+        Angle of rotation in degrees.
 
         @param fPassedTime
-        Time frame which the Box2D body should move to the specified position.
+        Time frame which the Box2D body should rotate to the specified angle.
      */
     void setShapeAngleByAngularVelocity(
         const css::uno::Reference<com::sun::star::drawing::XShape> xShape, const double fAngle,
         const double fPassedTime);
 
-    /// Sets angular velocity of the shape's corresponding body in the Box2D world
+    /** Sets angular velocity of the shape's corresponding Box2D body.
+
+        @param xShape
+        Shape reference
+
+        @param fAngularVelocity
+        Angular velocity in degrees per second.
+     */
     void setShapeAngularVelocity(const css::uno::Reference<com::sun::star::drawing::XShape> xShape,
                                  const double fAngularVelocity);
 
-    /** Set whether a shape can have collision in the Box2D World
+    /** Sets whether a shape's corresponding Box2D body has collision in the Box2D World or not
 
         Used for animations that change the visibility of the shape.
 
@@ -153,7 +200,8 @@ private:
     */
     void setShapeCollision(const css::uno::Reference<com::sun::star::drawing::XShape> xShape,
                            const bool bCanCollide);
-    /** Process the updates queued in the maShapeUpdateQueue
+
+    /** Process the updates queued in the maShapeParallelUpdateQueue
 
         Called on each step of the box2DWorld.
 
@@ -162,23 +210,26 @@ private:
      */
     void processUpdateQueue(const double fPassedTime);
 
-    /// Simulate and step through time in the Box2D World
+    /** Simulate and step through time in the Box2D World
+
+        Used in stepAmount
+
+        @attention fTimeStep should not vary.
+     */
     void step(const float fTimeStep = 1.0f / 100.0f, const int nVelocityIterations = 6,
               const int nPositionIterations = 2);
 
-    /// Queue a rotation update on the next step of the box2DWorld for the corresponding body
+    /// Queue a rotation update that is simulated as if shape's corresponding box2D body rotated to given angle when processed
     void
     queueDynamicRotationUpdate(const css::uno::Reference<com::sun::star::drawing::XShape>& xShape,
                                const double fAngle);
 
-    /// Queue an angular velocity update for the corresponding body
-    /// to take place after the next step of the box2DWorld
+    /// Queue an angular velocity update that sets the shape's corresponding box2D body angular velocity to the given value when processed
     void
     queueAngularVelocityUpdate(const css::uno::Reference<com::sun::star::drawing::XShape>& xShape,
                                const double fAngularVelocity, const int nDelayForSteps = 0);
 
-    /// Queue an update that changes collision of the corresponding body
-    /// on the next step of the box2DWorld, used for animations that change visibility
+    /// Queue an collision update that sets the collision of shape's corresponding box2D body when processed
     void queueShapeVisibilityUpdate(const css::uno::Reference<css::drawing::XShape>& xShape,
                                     const bool bVisibility);
 
@@ -198,21 +249,35 @@ public:
 
         @return Amount of time actually stepped through, since it is possible
         to only step through a multiple of fTimeStep
+
+        @attention fTimeStep should not vary.
     */
     double stepAmount(const double fPassedTime, const float fTimeStep = 1.0f / 100.0f,
                       const int nVelocityIterations = 6, const int nPositionIterations = 2);
 
     /// @return whether shapes in the slide are initialized as Box2D bodies or not
     bool shapesInitialized();
-    /// @return whether the Box2D shape is initialized or not
+    /// @return whether the Box2D World is initialized or not
     bool isInitialized();
 
-    /** Make the Box2D body corresponding to the given shape a dynamic one
+    /** Make the shape's corresponding box2D body a dynamic one.
 
         A dynamic body will be affected by other bodies and the gravity.
 
-        @param pShape
-        Pointer to the shape to alter the corresponding Box2D body of
+        @param xShape
+        Shape reference
+
+        @param rStartVelocity
+        Velocity of the shape after making it dynamic
+
+        @param fDensity
+        Density of the body that is in kg/m^2
+
+        @param fBounciness
+        Bounciness of the body that is usually in between [0,1].
+        Even though it could take values that are >1, it is way too chaotic.
+
+        @return box2d body pointer
      */
     Box2DBodySharedPtr makeShapeDynamic(const css::uno::Reference<css::drawing::XShape>& xShape,
                                         const basegfx::B2DVector& rStartVelocity,
@@ -220,14 +285,21 @@ public:
 
     /** Make the Box2D body corresponding to the given shape a static one
 
-        A static body will not be affected by other bodies and the gravity.
+        A static body will not be affected by other bodies and the gravity. But will
+        affect other bodies that are dynamic (will still collide with them but won't
+        move etc.)
 
         @param pShape
         Pointer to the shape to alter the corresponding Box2D body of
+
+        @return box2d body pointer
      */
     Box2DBodySharedPtr makeShapeStatic(const slideshow::internal::ShapeSharedPtr& pShape);
 
-    /// Create a static body from the given shape's geometry
+    /** Create a static body that represeted by the shape's geometry
+
+        @return pointer to the box2d body
+     */
     Box2DBodySharedPtr createStaticBody(const slideshow::internal::ShapeSharedPtr& rShape,
                                         const float fDensity = 1.0f, const float fFriction = 0.3f);
 
@@ -241,32 +313,47 @@ public:
     /// Set the flag for whether the box2DWorld has a stepper or not
     void setHasWorldStepper(const bool bHasWorldStepper);
 
-    /// Queue a position update the next step of the box2DWorld for the corresponding body
+    /// Queue a position update that is simulated as if shape's corresponding box2D body moved to given position when processed
     void queueDynamicPositionUpdate(const css::uno::Reference<css::drawing::XShape>& xShape,
                                     const ::basegfx::B2DPoint& rOutPos);
 
-    /// Queue a linear velocity update for the corresponding body
-    /// to take place after the next step of the box2DWorld
+    /// Queue a update that sets the corresponding box2D body's linear velocity to the given value when processed
     void queueLinearVelocityUpdate(const css::uno::Reference<css::drawing::XShape>& xShape,
                                    const ::basegfx::B2DVector& rVelocity,
                                    const int nDelayForSteps = 0);
 
+    /// Queue an appropraite update for the animation effect that is in parallel with a physics animation
     void
     queueShapeAnimationUpdate(const css::uno::Reference<css::drawing::XShape>& xShape,
                               const slideshow::internal::ShapeAttributeLayerSharedPtr& pAttrLayer,
                               const slideshow::internal::AttributeType eAttrType,
                               const bool bIsFirstUpdate);
 
+    /// Queue an appropraite update for a path animation that is in parallel with a physics animation
     void queueShapePathAnimationUpdate(
         const css::uno::Reference<com::sun::star::drawing::XShape>& xShape,
         const slideshow::internal::ShapeAttributeLayerSharedPtr& pAttrLayer,
         const bool bIsFirstUpdate);
 
+    /// Queue an appropraite update for the animation effect that just ended
     void queueShapeAnimationEndUpdate(const css::uno::Reference<css::drawing::XShape>& xShape,
                                       const slideshow::internal::AttributeType eAttrType);
 
+    /** Alert that a physics animation effect has ended
+
+        Makes the given shape static, if this was the last physics animation effect
+        that was in parallel, box2d bodies that are owned by the mpXShapeToBodyMap
+        are dumped and potentially destroyed.
+
+        @attention the box2d body owned by the PhysicsAnimation won't be destroyed.
+     */
     void alertPhysicsAnimationEnd(const slideshow::internal::ShapeSharedPtr& pShape);
 
+    /** Alert that a physics animation effect has started
+
+        Initiates the box2D world if it is not initiated yet, and likewise constructs
+        box2d bodies for the shapes in the current slide if they are not constructed.
+     */
     void
     alertPhysicsAnimationStart(const ::basegfx::B2DVector& rSlideSize,
                                const slideshow::internal::ShapeManagerSharedPtr& pShapeManager);
@@ -287,12 +374,17 @@ public:
     /// @return current position in LO user space coordinates
     ::basegfx::B2DPoint getPosition();
 
+    /** Set the position of box2d body
+
+        @param rPos
+        Position in LO user space coordinates
+     */
     void setPosition(const ::basegfx::B2DPoint& rPos);
 
-    /** Sets body to specified position
+    /** Moves body to the specified position
 
-        Sets body to specified position as if the body had
-        velocity to reach that point in given time frame
+        Moves body to the specified position by setting velocity of
+        the body so that it reaches to rDesiredPos in given time fram
 
         @param rDesiredPos
         Position to arrive in the time frame
@@ -303,23 +395,31 @@ public:
     void setPositionByLinearVelocity(const ::basegfx::B2DPoint& rDesiredPos,
                                      const double fPassedTime);
 
-    /// Sets linear velocity of the body
+    /** Sets linear velocity of the body
+
+        @param rVelocity
+        Velocity vector in LO user space coordinates
+     */
     void setLinearVelocity(const ::basegfx::B2DVector& rVelocity);
 
-    /** Sets body to specified angle of rotation
+    /** Rotate body to specified angle of rotation
 
-        Sets body to specified rotation as if the body had
+        Rotates body to specified rotation as if the body had
         angular velocity to reach that state in given time frame
 
         @param fDesiredAngle
-        Rotation angle to arrive in the time frame
+        Rotation angle in degrees to arrive in the time frame
 
         @param fPassedTime
         Amount of time for the movement to take place
      */
     void setAngleByAngularVelocity(const double fDesiredAngle, const double fPassedTime);
 
-    /// Sets angular velocity of the body
+    /** Sets angular velocity of the body
+
+        @param fAngularVelocity
+        Angular velocity in degrees per second
+     */
     void setAngularVelocity(const double fAngularVelocity);
 
     /// Sets whether the body have collisions or not
@@ -328,10 +428,28 @@ public:
     /// @return current angle of rotation of the body
     double getAngle();
 
+    /** Set angle of the box2d body
+
+        @param fAngle
+        Angle in degrees
+     */
     void setAngle(const double fAngle);
 
+    /** Set density and restitution of the box2d body
+
+        @param fDensity
+        Density in kg/m^2
+
+        @param fRestitution
+        Restitution (elasticity) coefficient, usually in the range [0,1]
+     */
     void setDensityAndRestitution(const double fDensity, const double fRestitution);
 
+    /** Set restitution of the box2d body
+
+        @param fRestitution
+        Restitution (elasticity) coefficient, usually in the range [0,1]
+     */
     void setRestitution(const double fRestitution);
 
     /// Set type of the body


More information about the Libreoffice-commits mailing list