[Libreoffice-commits] core.git: Branch 'private/quwex/gsoc-box2d-experimental' - slideshow/source
Sarper Akdemir (via logerrit)
logerrit at kemper.freedesktop.org
Tue Jul 28 13:09:59 UTC 2020
Rebased ref, commits from common ancestor:
commit 6214bafdbf5909c6eb5958510309c5378b1a481a
Author: Sarper Akdemir <q.sarperakdemir at gmail.com>
AuthorDate: Mon Jul 27 23:02:48 2020 +0300
Commit: Sarper Akdemir <q.sarperakdemir at gmail.com>
CommitDate: Tue Jul 28 16:08:40 2020 +0300
work-in-progress complex shapes
Change-Id: I807bbde92c143b8c96792b3d8bf9603a31216486
diff --git a/slideshow/source/engine/box2dtools.cxx b/slideshow/source/engine/box2dtools.cxx
index 8729300184f6..dcca891c4dac 100644
--- a/slideshow/source/engine/box2dtools.cxx
+++ b/slideshow/source/engine/box2dtools.cxx
@@ -11,6 +11,12 @@
#include <Box2D/Box2D.h>
#include <shapemanager.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b2dpolygontriangulator.hxx>
+#include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
+
+#include <o3tl/any.hxx>
#define BOX2D_SLIDE_SIZE_IN_METERS 100.00f
@@ -62,6 +68,55 @@ b2Vec2 convertB2DPointToBox2DVec2(const basegfx::B2DPoint& aPoint, const double
return { static_cast<float>(aPoint.getX() * fScaleFactor),
static_cast<float>(aPoint.getY() * -fScaleFactor) };
}
+
+void addTriangleVectorToBody(const basegfx::triangulator::B2DTriangleVector& rTriangleVector,
+ b2Body* aBody, const basegfx::B2DRange& rShapeBounds,
+ const float fDensity, const float fFriction, const float fRestitution,
+ const double fScaleFactor)
+{
+ // aAdjustCenter is used to make coordinates relative to center of the shape instead of top left
+ basegfx::B2DPoint aAdjustCenter(rShapeBounds.getWidth() / 2, rShapeBounds.getHeight() / 2);
+ for (const basegfx::triangulator::B2DTriangle& aTriangle : rTriangleVector)
+ {
+ b2FixtureDef aFixture;
+ b2PolygonShape aPolygonShape;
+ b2Vec2 aTriangleVertices[3];
+ basegfx::B2DPoint aTriangleVertice = aTriangle.getA() - aAdjustCenter;
+ // putting the operation in place of aTriangleVertice creates weird behavior and i dont know why
+ aTriangleVertices[0] = convertB2DPointToBox2DVec2(aTriangleVertice, fScaleFactor);
+ aTriangleVertice = aTriangle.getB() - aAdjustCenter;
+ aTriangleVertices[1] = convertB2DPointToBox2DVec2(aTriangleVertice, fScaleFactor);
+ aTriangleVertice = aTriangle.getC() - aAdjustCenter;
+ aTriangleVertices[2] = convertB2DPointToBox2DVec2(aTriangleVertice, fScaleFactor);
+
+ // FIXME: weird bug when using a bezier curve with >10 vertices
+ // turns out bug was happening when there are triangles that have really close points
+ // box2d marks those as degenerate ones, and stops working, so we will just ignore
+ // really tiny triangles
+ bool bValidSizedTriangle = true;
+ for (int a = 0; a < 3; a++)
+ {
+ for (int b = 0; b < 3; b++)
+ {
+ if (a == b)
+ continue;
+ if (b2DistanceSquared(aTriangleVertices[a], aTriangleVertices[b]) < 0.003f)
+ {
+ bValidSizedTriangle = false;
+ }
+ }
+ }
+ if (bValidSizedTriangle)
+ {
+ aPolygonShape.Set(aTriangleVertices, 3);
+ aFixture.shape = &aPolygonShape;
+ aFixture.density = fDensity;
+ aFixture.friction = fFriction;
+ aFixture.restitution = fRestitution;
+ aBody->CreateFixture(&aFixture);
+ }
+ }
+}
}
box2DWorld::box2DWorld(const ::basegfx::B2DVector& rSlideSize)
@@ -224,7 +279,17 @@ void box2DWorld::initateAllShapesAsStaticBodies(
slideshow::internal::ShapeSharedPtr pShape = aIt->second;
if (pShape->isForeground())
{
- Box2DBodySharedPtr pBox2DBody = createStaticBodyFromBoundingBox(pShape);
+ Box2DBodySharedPtr pBox2DBody;
+
+ auto aShapeType = pShape->getXShape()->getShapeType();
+
+ if (aShapeType == "com.sun.star.drawing.PolyPolygonShape")
+ pBox2DBody = createStaticBodyFromPolygonShape(pShape);
+ else if (aShapeType == "com.sun.star.drawing.ClosedBezierShape")
+ pBox2DBody = createStaticBodyFromBezierShape(pShape);
+ else
+ pBox2DBody = createStaticBodyFromBoundingBox(pShape);
+
mpXShapeToBodyMap.insert(std::make_pair(pShape->getXShape(), pBox2DBody));
if (!pShape->isVisible())
{
@@ -382,6 +447,74 @@ box2DWorld::createStaticBodyFromBoundingBox(const slideshow::internal::ShapeShar
return std::make_shared<box2DBody>(pBody, mfScaleFactor);
}
+Box2DBodySharedPtr
+box2DWorld::createStaticBodyFromPolygonShape(const slideshow::internal::ShapeSharedPtr& rShape,
+ const float fDensity, const float fFriction)
+{
+ assert(mpBox2DWorld);
+
+ ::basegfx::B2DRectangle aShapeBounds = rShape->getBounds();
+
+ b2BodyDef aBodyDef;
+ aBodyDef.type = b2_staticBody;
+ aBodyDef.position = convertB2DPointToBox2DVec2(aShapeBounds.getCenter(), mfScaleFactor);
+
+ std::shared_ptr<b2Body> pBody(mpBox2DWorld->CreateBody(&aBodyDef), [](b2Body* pB2Body) {
+ pB2Body->GetWorld()->DestroyBody(pB2Body);
+ });
+
+ // triangulate and add the geometry to box2d body
+ css::uno::Reference<css::drawing::XShape> xShape = rShape->getXShape();
+ const css::uno::Reference<css::beans::XPropertySet> xPropSet(xShape, css::uno::UNO_QUERY);
+ assert(xPropSet.is());
+
+ css::uno::Any aAny(xPropSet->getPropertyValue("Geometry"));
+ const basegfx::B2DPolyPolygon aPolyPolygon(
+ ::basegfx::utils::UnoPointSequenceSequenceToB2DPolyPolygon(
+ *o3tl::doAccess<css::drawing::PointSequenceSequence>(aAny)));
+
+ // FIXME: Right now skewed/rotated shapes are not handled properly, should get and apply transformation etc to the polygon
+ basegfx::triangulator::B2DTriangleVector aTriangleVector
+ = basegfx::triangulator::triangulate(aPolyPolygon);
+ addTriangleVectorToBody(aTriangleVector, pBody.get(), aPolyPolygon.getB2DRange(), fDensity,
+ fFriction, 0.1f, mfScaleFactor);
+ return std::make_shared<box2DBody>(pBody, mfScaleFactor);
+}
+
+Box2DBodySharedPtr
+box2DWorld::createStaticBodyFromBezierShape(const slideshow::internal::ShapeSharedPtr& rShape,
+ const float fDensity, const float fFriction)
+{
+ assert(mpBox2DWorld);
+
+ ::basegfx::B2DRectangle aShapeBounds = rShape->getBounds();
+
+ b2BodyDef aBodyDef;
+ aBodyDef.type = b2_staticBody;
+ aBodyDef.position = convertB2DPointToBox2DVec2(aShapeBounds.getCenter(), mfScaleFactor);
+
+ std::shared_ptr<b2Body> pBody(mpBox2DWorld->CreateBody(&aBodyDef), [](b2Body* pB2Body) {
+ pB2Body->GetWorld()->DestroyBody(pB2Body);
+ });
+
+ // triangulate and add the geometry to box2d body
+ css::uno::Reference<css::drawing::XShape> xShape = rShape->getXShape();
+ const css::uno::Reference<css::beans::XPropertySet> xPropSet(xShape, css::uno::UNO_QUERY);
+ assert(xPropSet.is());
+
+ css::uno::Any aAny(xPropSet->getPropertyValue("Geometry"));
+ const basegfx::B2DPolyPolygon aPolyPolygon(
+ ::basegfx::utils::UnoPolyPolygonBezierCoordsToB2DPolyPolygon(
+ *o3tl::doAccess<css::drawing::PolyPolygonBezierCoords>(aAny)));
+
+ // FIXME: Right now skewed/rotated shapes are not handled properly, should get and apply transformation etc to the polygon
+ basegfx::triangulator::B2DTriangleVector aTriangleVector
+ = basegfx::triangulator::triangulate(aPolyPolygon);
+ addTriangleVectorToBody(aTriangleVector, pBody.get(), aPolyPolygon.getB2DRange(), fDensity,
+ fFriction, 0.1f, mfScaleFactor);
+ return std::make_shared<box2DBody>(pBody, mfScaleFactor);
+}
+
box2DBody::box2DBody(std::shared_ptr<b2Body> pBox2DBody, double fScaleFactor)
: mpBox2DBody(pBox2DBody)
, mfScaleFactor(fScaleFactor)
diff --git a/slideshow/source/inc/box2dtools.hxx b/slideshow/source/inc/box2dtools.hxx
index 0824a3c260c5..557645a4b70d 100644
--- a/slideshow/source/inc/box2dtools.hxx
+++ b/slideshow/source/inc/box2dtools.hxx
@@ -218,6 +218,14 @@ public:
createStaticBodyFromBoundingBox(const slideshow::internal::ShapeSharedPtr& rShape,
const float fDensity = 1.0f, const float fFriction = 0.3f);
+ Box2DBodySharedPtr
+ createStaticBodyFromPolygonShape(const slideshow::internal::ShapeSharedPtr& rShape,
+ const float fDensity = 1.0f, const float fFriction = 0.3f);
+
+ Box2DBodySharedPtr
+ createStaticBodyFromBezierShape(const slideshow::internal::ShapeSharedPtr& rShape,
+ const float fDensity = 1.0f, const float fFriction = 0.3f);
+
/// Initiate all the shapes in the current slide in the box2DWorld as static ones
void
initateAllShapesAsStaticBodies(const slideshow::internal::ShapeManagerSharedPtr pShapeManager);
More information about the Libreoffice-commits
mailing list