Fixed physics demo on target and made it more interesting 32/296732/1
authorDavid Steele <david.steele@samsung.com>
Thu, 3 Aug 2023 16:57:22 +0000 (17:57 +0100)
committerDavid Steele <david.steele@samsung.com>
Thu, 3 Aug 2023 16:57:22 +0000 (17:57 +0100)
Change-Id: I3a03ccc0e410e279061e08ec82a82a071bb87b78

examples/chipmunk-physics/frame-callback.cpp
examples/chipmunk-physics/physics-demo-controller.cpp
examples/chipmunk-physics/physics-impl.cpp

index c6ef8a3..129b6d7 100644 (file)
  */
 
 #include "frame-callback.h"
-#include "physics-impl.h"
-#include <dali/public-api/math/vector3.h>
-#include <dali/devel-api/update/update-proxy.h>
 #include <dali/devel-api/threading/mutex.h>
+#include <dali/devel-api/update/update-proxy.h>
+#include <dali/integration-api/debug.h>
+#include <dali/public-api/math/vector3.h>
+#include "physics-impl.h"
 
-using Dali::Vector3;
 using Dali::Quaternion;
+using Dali::Vector3;
+
+#if defined(DEBUG_ENABLED)
+extern Debug::Filter* gPhysicsDemo;
+#endif
 
 FrameCallback::FrameCallback(PhysicsImpl& physicsImpl)
 : mPhysicsImpl(physicsImpl)
@@ -30,14 +35,22 @@ FrameCallback::FrameCallback(PhysicsImpl& physicsImpl)
 
 bool FrameCallback::Update(Dali::UpdateProxy& updateProxy, float elapsedSeconds)
 {
+  static int numCalls = 0;
+
+  numCalls++;
+  if(numCalls % 30 == 0)
+  {
+    DALI_LOG_INFO(gPhysicsDemo, Debug::Concise, "Physics frame update\n");
+  }
+
   Dali::Mutex::ScopedLock lock(mPhysicsImpl.mMutex);
-  static float frameTime=0;
-  frameTime+=elapsedSeconds;
+  static float            frameTime = 0;
+  frameTime += elapsedSeconds;
   do
   {
     mPhysicsImpl.Integrate(mPhysicsTimeStep);
-    frameTime-=mPhysicsTimeStep;
-  } while (frameTime>0);
+    frameTime -= mPhysicsTimeStep;
+  } while(frameTime > 0);
 
   for(auto&& actor : mPhysicsImpl.mPhysicsActors)
   {
index 14a9b0f..377322a 100644 (file)
@@ -21,6 +21,7 @@
 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
 #include <dali/devel-api/adaptor-framework/key-devel.h>
 #include <dali/devel-api/events/hit-test-algorithm.h>
+#include <dali/integration-api/debug.h>
 
 #include <iostream>
 #include <string>
 
 using namespace Dali;
 
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gPhysicsDemo = Debug::Filter::New(Debug::Concise, false, "LOG_PHYSICS_EXAMPLE");
+#endif
+
 namespace KeyModifier
 {
 enum Key
@@ -84,8 +89,14 @@ public:
 
     mWindow.Add(mPhysicsRoot);
 
-    CreateBall();
-    CreateBrickPyramid(windowSize);
+    // Ball area = 2*PI*26^2 ~= 6.28*26*26 ~= 5400
+    // Fill quarter of the screen...
+    int numBalls = 10 + windowSize.GetWidth() * windowSize.GetHeight() / 20000;
+
+    for(int i = 0; i < numBalls; ++i)
+    {
+      CreateBall();
+    }
 
     // For funky mouse drag
     mMouseBody = mPhysicsImpl.AddMouseBody();
@@ -98,53 +109,17 @@ public:
     const float BALL_ELASTICITY = 0.5f;
     const float BALL_FRICTION   = 0.5f;
 
-    Property::Value v{std::string{SHADER_RENDERING_TEXTURED_SHAPE_VERT}};
-    Property::Value f{std::string{SHADER_RENDERING_TEXTURED_SHAPE_FRAG}};
-
-    auto image = Property::Map{{Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE},
-                               {Toolkit::ImageVisual::Property::URL, BALL_IMAGE},
-                               {Toolkit::Visual::Property::SHADER, {{Toolkit::Visual::Shader::Property::FRAGMENT_SHADER, f}}}};
+    auto ball = Toolkit::ImageView::New(BALL_IMAGE);
 
-    auto ball                                 = Toolkit::ImageView::New();
-    ball[Toolkit::ImageView::Property::IMAGE] = image;
-    mPhysicsImpl.AddBall(ball, BALL_MASS, BALL_RADIUS, BALL_ELASTICITY, BALL_FRICTION);
+    auto&              physicsBall = mPhysicsImpl.AddBall(ball, BALL_MASS, BALL_RADIUS, BALL_ELASTICITY, BALL_FRICTION);
+    Window::WindowSize windowSize  = mWindow.GetSize();
+    const float        s           = BALL_RADIUS;
+    const float        fw          = windowSize.GetWidth() - BALL_RADIUS;
+    const float        fh          = windowSize.GetHeight() - BALL_RADIUS;
+    physicsBall.SetPhysicsPosition(Vector3(Random::Range(s, fw), Random::Range(s, fh), 0.0f));
+    physicsBall.SetPhysicsVelocity(Vector3(Random::Range(-100.0, 100.0), Random::Range(-100.0, 100.0), 0.0f));
   }
 
-  void CreateBrickPyramid(Dali::Window::WindowSize windowSize)
-  {
-    const float BRICK_MASS       = 30.0f;
-    const float BRICK_ELASTICITY = 0.0f;
-    const float BRICK_FRICTION   = 0.9f;
-    const int   BRICK_WIDTH      = 128;
-    const int   BRICK_HEIGHT     = 64;
-    const int   BRICK_GAP        = 8;
-
-    Property::Value v{std::string{SHADER_RENDERING_TEXTURED_SHAPE_VERT}};
-    Property::Value f{std::string{SHADER_RENDERING_TEXTURED_SHAPE_FRAG}};
-
-    int uriIndex     = 0;
-    int numberOfRows = windowSize.GetWidth() / (BRICK_WIDTH + BRICK_GAP) - 2;
-    int oY           = windowSize.GetHeight() - (1 + numberOfRows) * BRICK_HEIGHT;
-    for(int i = 0; i < numberOfRows; ++i)
-    {
-      // Row start: i+1 is brick number. i is gap#
-      int w  = (i + 1) * BRICK_WIDTH + i * BRICK_GAP;
-      int oX = (windowSize.GetWidth() - w) / 2;
-      for(int j = 0; j < i + 1; ++j)
-      {
-        auto image = Property::Map{{Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE},
-                                   {Toolkit::ImageVisual::Property::URL, BRICK_URIS[uriIndex]},
-                                   {Toolkit::Visual::Property::SHADER, {{Toolkit::Visual::Shader::Property::FRAGMENT_SHADER, f}}}};
-
-        auto brick                                 = Toolkit::ImageView::New();
-        brick[Toolkit::ImageView::Property::IMAGE] = image;
-        auto& physicsActor                         = mPhysicsImpl.AddBrick(brick, BRICK_MASS, BRICK_ELASTICITY, BRICK_FRICTION, Vector3(BRICK_WIDTH, BRICK_HEIGHT, BRICK_HEIGHT));
-        physicsActor.SetPhysicsPosition(Vector3(oX + j * (BRICK_WIDTH + BRICK_GAP), oY + i * BRICK_HEIGHT, 0.0f));
-        uriIndex += 1;
-        uriIndex %= 4;
-      }
-    }
-  }
   void OnTerminate(Application& application)
   {
     UnparentAndReset(mPhysicsRoot);
index 12e94a8..1916ee0 100644 (file)
 #include "physics-actor.h"
 
 #include <devel-api/common/stage.h>
+#include <iostream>
 #include <map>
 #include <utility>
-#include <iostream>
 
-using Dali::Layer;
 using Dali::Actor;
-using Dali::Window;
+using Dali::Layer;
+using Dali::Stage;
 using Dali::Vector2;
 using Dali::Vector3;
-using Dali::Stage;
+using Dali::Window;
 using namespace Dali::DevelStage;
 
-#define GRABBABLE_MASK_BIT (1u<<31)
-cpShapeFilter GRAB_FILTER = {CP_NO_GROUP, GRABBABLE_MASK_BIT, GRABBABLE_MASK_BIT};
+#define GRABBABLE_MASK_BIT (1u << 31)
+cpShapeFilter GRAB_FILTER          = {CP_NO_GROUP, GRABBABLE_MASK_BIT, GRABBABLE_MASK_BIT};
 cpShapeFilter NOT_GRABBABLE_FILTER = {CP_NO_GROUP, ~GRABBABLE_MASK_BIT, ~GRABBABLE_MASK_BIT};
 
 Actor PhysicsImpl::Initialize(Window window)
 {
   mWindow = window;
-  mSpace = cpSpaceNew();
+  mSpace  = cpSpaceNew();
   cpSpaceSetIterations(mSpace, 30);
   cpSpaceSetSleepTimeThreshold(mSpace, 0.5f);
   cpSpaceSetGravity(mSpace, cpv(0, -200));
@@ -47,16 +47,15 @@ Actor PhysicsImpl::Initialize(Window window)
   CreateWorldBounds(windowSize);
 
   // Create an actor that can handle mouse events.
-  mPhysicsRoot = Layer::New();
-  mPhysicsRoot[Actor::Property::SIZE] = Vector2(windowSize.GetWidth(), windowSize.GetHeight());
-  mPhysicsRoot[Actor::Property::ANCHOR_POINT] = Dali::AnchorPoint::CENTER;
+  mPhysicsRoot                                 = Layer::New();
+  mPhysicsRoot[Actor::Property::SIZE]          = Vector2(windowSize.GetWidth(), windowSize.GetHeight());
+  mPhysicsRoot[Actor::Property::ANCHOR_POINT]  = Dali::AnchorPoint::CENTER;
   mPhysicsRoot[Actor::Property::PARENT_ORIGIN] = Dali::ParentOrigin::CENTER;
 
   mFrameCallback = new FrameCallback(*this);
   AddFrameCallback(Stage::GetCurrent(), *mFrameCallback, window.GetRootLayer());
   Stage::GetCurrent().KeepRendering(30);
 
-
   return mPhysicsRoot;
 }
 
@@ -73,10 +72,10 @@ void PhysicsImpl::CreateWorldBounds(Window::WindowSize size)
   // But, can't use actors in update, so cache transform.
   SetTransform(Vector2(size.GetWidth(), size.GetHeight()));
 
-  int xBound=size.GetWidth()/2;
-  int yBound=size.GetHeight()/2;
+  int xBound = size.GetWidth() / 2;
+  int yBound = size.GetHeight() / 2;
 
-  cpBody *staticBody = cpSpaceGetStaticBody(mSpace);
+  cpBodystaticBody = cpSpaceGetStaticBody(mSpace);
 
   if(mLeftBound)
   {
@@ -89,10 +88,10 @@ void PhysicsImpl::CreateWorldBounds(Window::WindowSize size)
     cpShapeFree(mTopBound);
     cpShapeFree(mBottomBound);
   }
-  mLeftBound   = AddBound(staticBody, cpv(-xBound, -yBound), cpv(-xBound,  yBound));
-  mRightBound  = AddBound(staticBody, cpv( xBound, -yBound), cpv( xBound,  yBound));
-  mTopBound    = AddBound(staticBody, cpv(-xBound, -yBound), cpv( xBound, -yBound));
-  mBottomBound = AddBound(staticBody, cpv(-xBound,  yBound), cpv( xBound,  yBound));
+  mLeftBound   = AddBound(staticBody, cpv(-xBound, -yBound), cpv(-xBound, yBound));
+  mRightBound  = AddBound(staticBody, cpv(xBound, -yBound), cpv(xBound, yBound));
+  mTopBound    = AddBound(staticBody, cpv(-xBound, -yBound), cpv(xBound, -yBound));
+  mBottomBound = AddBound(staticBody, cpv(-xBound, yBound), cpv(xBound, yBound));
 }
 
 void PhysicsImpl::SetTransform(Vector2 worldSize)
@@ -104,7 +103,7 @@ void PhysicsImpl::SetTransform(Vector2 worldSize)
 
 cpShape* PhysicsImpl::AddBound(cpBody* staticBody, cpVect start, cpVect end)
 {
-  cpShape* shape = cpSpaceAddShape(mSpace, cpSegmentShapeNew(staticBody,start, end,0.0f));
+  cpShape* shape = cpSpaceAddShape(mSpace, cpSegmentShapeNew(staticBody, start, end, 0.0f));
   cpShapeSetElasticity(shape, 1.0f);
   cpShapeSetFriction(shape, 1.0f);
   cpShapeSetFilter(shape, NOT_GRABBABLE_FILTER);
@@ -114,7 +113,7 @@ cpShape* PhysicsImpl::AddBound(cpBody* staticBody, cpVect start, cpVect end)
 PhysicsActor& PhysicsImpl::AddBall(::Actor actor, float mass, float radius, float elasticity, float friction)
 {
   Dali::Mutex::ScopedLock lock(mMutex);
-  cpBody* body = cpSpaceAddBody(mSpace, cpBodyNew(mass, cpMomentForCircle(mass, 0.0f, radius, cpvzero)));
+  cpBody*                 body = cpSpaceAddBody(mSpace, cpBodyNew(mass, cpMomentForCircle(mass, 0.0f, radius, cpvzero)));
   cpBodySetPosition(body, cpv(0, 0));
   cpBodySetVelocity(body, cpv(0, 0));
 
@@ -122,11 +121,11 @@ PhysicsActor& PhysicsImpl::AddBall(::Actor actor, float mass, float radius, floa
   cpShapeSetElasticity(shape, elasticity);
   cpShapeSetFriction(shape, friction);
 
-  int id = actor[Actor::Property::ID];
+  int                   id    = actor[Actor::Property::ID];
   Dali::Property::Index index = actor.RegisterProperty("uBrightness", 0.0f);
   mPhysicsActors.insert(std::make_pair(id, PhysicsActor{actor, body, this, index}));
   actor[Actor::Property::PARENT_ORIGIN] = Dali::ParentOrigin::TOP_LEFT;
-  actor[Actor::Property::ANCHOR_POINT] = Dali::AnchorPoint::CENTER;
+  actor[Actor::Property::ANCHOR_POINT]  = Dali::AnchorPoint::CENTER;
   mPhysicsRoot.Add(actor);
   return mPhysicsActors.at(id);
 }
@@ -134,7 +133,7 @@ PhysicsActor& PhysicsImpl::AddBall(::Actor actor, float mass, float radius, floa
 PhysicsActor& PhysicsImpl::AddBrick(Dali::Actor actor, float mass, float elasticity, float friction, Vector3 size)
 {
   Dali::Mutex::ScopedLock lock(mMutex);
-  cpBody* body = cpSpaceAddBody(mSpace, cpBodyNew(mass, cpMomentForBox(mass, size.width, size.height)));
+  cpBody*                 body = cpSpaceAddBody(mSpace, cpBodyNew(mass, cpMomentForBox(mass, size.width, size.height)));
   cpBodySetPosition(body, cpv(0, 0));
   cpBodySetVelocity(body, cpv(0, 0));
 
@@ -142,11 +141,11 @@ PhysicsActor& PhysicsImpl::AddBrick(Dali::Actor actor, float mass, float elastic
   cpShapeSetFriction(shape, friction);
   cpShapeSetElasticity(shape, elasticity);
 
-  int id = actor[Actor::Property::ID];
+  int                   id    = actor[Actor::Property::ID];
   Dali::Property::Index index = actor.RegisterProperty("uBrightness", 0.0f);
   mPhysicsActors.insert(std::make_pair(id, PhysicsActor{actor, body, this, index}));
   actor[Actor::Property::PARENT_ORIGIN] = Dali::ParentOrigin::TOP_LEFT;
-  actor[Actor::Property::ANCHOR_POINT] = Dali::AnchorPoint::CENTER;
+  actor[Actor::Property::ANCHOR_POINT]  = Dali::AnchorPoint::CENTER;
   mPhysicsRoot.Add(actor);
   return mPhysicsActors.at(id);
 }
@@ -154,7 +153,7 @@ PhysicsActor& PhysicsImpl::AddBrick(Dali::Actor actor, float mass, float elastic
 cpBody* PhysicsImpl::AddMouseBody()
 {
   Dali::Mutex::ScopedLock lock(mMutex);
-  auto kinematicBody = cpBodyNewKinematic(); // Mouse actor is a kinematic body that is not integrated
+  auto                    kinematicBody = cpBodyNewKinematic(); // Mouse actor is a kinematic body that is not integrated
   return kinematicBody;
 }
 
@@ -171,7 +170,7 @@ void PhysicsImpl::HighlightBody(cpBody* body, bool highlight)
     Actor actor = mPhysicsRoot.FindChildById(physicsActor->GetId());
     if(actor)
     {
-      actor[physicsActor->GetBrightnessIndex()] = highlight?1.0f:0.0f;
+      actor[physicsActor->GetBrightnessIndex()] = highlight ? 1.0f : 0.0f;
     }
   }
 }
@@ -181,13 +180,13 @@ Vector3 PhysicsImpl::TranslateToPhysicsSpace(Vector3 vector)
 {
   // root actor origin is top left, DALi Y is inverted.
   // Physics origin is center. Y: 0->1 => 0.5=>-0.5
-  return Vector3(vector.x-mWorldOffset.x, mWorldOffset.y-vector.y, vector.z);
+  return Vector3(vector.x - mWorldOffset.x, mWorldOffset.y - vector.y, vector.z);
 }
 
 // Convert from physics space to root actor local space
 Vector3 PhysicsImpl::TranslateFromPhysicsSpace(Vector3 vector)
 {
-  return Vector3(vector.x+mWorldOffset.x, mWorldOffset.y-vector.y, vector.z);
+  return Vector3(vector.x + mWorldOffset.x, mWorldOffset.y - vector.y, vector.z);
 }
 
 // Convert a vector from dali space to physics space
@@ -210,39 +209,38 @@ void PhysicsImpl::Integrate(float timestep)
   {
     cpSpaceStep(mSpace, timestep);
   }
-//  if(mDynamicsWorld->getDebugDrawer() && mPhysicsDebugState)
-//  {
-//    mDynamicsWorld->debugDrawWorld();
-//  }
+  //  if(mDynamicsWorld->getDebugDrawer() && mPhysicsDebugState)
+  //  {
+  //    mDynamicsWorld->debugDrawWorld();
+  //  }
 }
 
 cpBody* PhysicsImpl::HitTest(Vector2 screenCoords, Vector3 origin, Vector3 direction, Vector3& localPivot, float& distanceFromCamera)
 {
-  Vector3 spacePosition = TranslateToPhysicsSpace(Vector3{screenCoords});
-  cpVect mousePosition = cpv(spacePosition.x, spacePosition.y);
-  cpFloat radius = 5.0f;
-  cpPointQueryInfo info = {0};
-  cpShape *shape = cpSpacePointQueryNearest(mSpace, mousePosition, radius, GRAB_FILTER, &info);
+  Vector3          spacePosition = TranslateToPhysicsSpace(Vector3{screenCoords});
+  cpVect           mousePosition = cpv(spacePosition.x, spacePosition.y);
+  cpFloat          radius        = 5.0f;
+  cpPointQueryInfo info          = {0};
+  cpShape*         shape         = cpSpacePointQueryNearest(mSpace, mousePosition, radius, GRAB_FILTER, &info);
 
-  cpBody *body{nullptr};
+  cpBodybody{nullptr};
 
   if(shape && cpBodyGetMass(cpShapeGetBody(shape)) < INFINITY)
   {
     // Use the closest point on the surface if the click is outside the shape.
     cpVect nearest = (info.distance > 0.0f ? info.point : mousePosition);
-    body = cpShapeGetBody(shape);
-    cpVect local = cpBodyWorldToLocal(body, nearest);
-    localPivot.x = local.x;
-    localPivot.y = local.y;
-    localPivot.z = 0.0;
+    body           = cpShapeGetBody(shape);
+    cpVect local   = cpBodyWorldToLocal(body, nearest);
+    localPivot.x   = local.x;
+    localPivot.y   = local.y;
+    localPivot.z   = 0.0;
   }
   return body;
 }
 
-
 cpConstraint* PhysicsImpl::AddPivotJoint(cpBody* body1, cpBody* body2, Vector3 localPivot)
 {
-  cpVect pivot{localPivot.x, localPivot.y};
+  cpVect        pivot{localPivot.x, localPivot.y};
   cpConstraint* joint = cpPivotJointNew2(body2, body1, cpvzero, pivot);
   cpConstraintSetMaxForce(joint, 50000.0f); // Magic numbers for mouse feedback.
   cpConstraintSetErrorBias(joint, cpfpow(1.0f - 0.15f, 60.0f));
@@ -253,7 +251,7 @@ cpConstraint* PhysicsImpl::AddPivotJoint(cpBody* body1, cpBody* body2, Vector3 l
 void PhysicsImpl::MoveMouseBody(cpBody* mouseBody, Vector3 position)
 {
   cpVect cpPosition = cpv(position.x, position.y);
-  cpVect newPoint = cpvlerp(cpBodyGetPosition(mouseBody), cpPosition, 0.25f);
+  cpVect newPoint   = cpvlerp(cpBodyGetPosition(mouseBody), cpPosition, 0.25f);
   cpBodySetVelocity(mouseBody, cpvmult(cpvsub(newPoint, cpBodyGetPosition(mouseBody)), 60.0f));
   // Normally, kinematic body's position would be calculated by engine.
   // For mouse, though, we want to set it.