Commit 7edeccca360a5e6b4c6ea5005e0ed449b3fdfc47

Authored by David Steele
Committed by Gerrit Code Review
2 parents 7bf6ad1e 3d0d2231

Merge "Fixed physics demo on target and made it more interesting" into devel/master

examples/chipmunk-physics/frame-callback.cpp
... ... @@ -15,13 +15,18 @@
15 15 */
16 16  
17 17 #include "frame-callback.h"
18   -#include "physics-impl.h"
19   -#include <dali/public-api/math/vector3.h>
20   -#include <dali/devel-api/update/update-proxy.h>
21 18 #include <dali/devel-api/threading/mutex.h>
  19 +#include <dali/devel-api/update/update-proxy.h>
  20 +#include <dali/integration-api/debug.h>
  21 +#include <dali/public-api/math/vector3.h>
  22 +#include "physics-impl.h"
22 23  
23   -using Dali::Vector3;
24 24 using Dali::Quaternion;
  25 +using Dali::Vector3;
  26 +
  27 +#if defined(DEBUG_ENABLED)
  28 +extern Debug::Filter* gPhysicsDemo;
  29 +#endif
25 30  
26 31 FrameCallback::FrameCallback(PhysicsImpl& physicsImpl)
27 32 : mPhysicsImpl(physicsImpl)
... ... @@ -30,14 +35,22 @@ FrameCallback::FrameCallback(PhysicsImpl&amp; physicsImpl)
30 35  
31 36 bool FrameCallback::Update(Dali::UpdateProxy& updateProxy, float elapsedSeconds)
32 37 {
  38 + static int numCalls = 0;
  39 +
  40 + numCalls++;
  41 + if(numCalls % 30 == 0)
  42 + {
  43 + DALI_LOG_INFO(gPhysicsDemo, Debug::Concise, "Physics frame update\n");
  44 + }
  45 +
33 46 Dali::Mutex::ScopedLock lock(mPhysicsImpl.mMutex);
34   - static float frameTime=0;
35   - frameTime+=elapsedSeconds;
  47 + static float frameTime = 0;
  48 + frameTime += elapsedSeconds;
36 49 do
37 50 {
38 51 mPhysicsImpl.Integrate(mPhysicsTimeStep);
39   - frameTime-=mPhysicsTimeStep;
40   - } while (frameTime>0);
  52 + frameTime -= mPhysicsTimeStep;
  53 + } while(frameTime > 0);
41 54  
42 55 for(auto&& actor : mPhysicsImpl.mPhysicsActors)
43 56 {
... ...
examples/chipmunk-physics/physics-demo-controller.cpp
... ... @@ -21,6 +21,7 @@
21 21 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
22 22 #include <dali/devel-api/adaptor-framework/key-devel.h>
23 23 #include <dali/devel-api/events/hit-test-algorithm.h>
  24 +#include <dali/integration-api/debug.h>
24 25  
25 26 #include <iostream>
26 27 #include <string>
... ... @@ -32,6 +33,10 @@
32 33  
33 34 using namespace Dali;
34 35  
  36 +#if defined(DEBUG_ENABLED)
  37 +Debug::Filter* gPhysicsDemo = Debug::Filter::New(Debug::Concise, false, "LOG_PHYSICS_EXAMPLE");
  38 +#endif
  39 +
35 40 namespace KeyModifier
36 41 {
37 42 enum Key
... ... @@ -84,8 +89,14 @@ public:
84 89  
85 90 mWindow.Add(mPhysicsRoot);
86 91  
87   - CreateBall();
88   - CreateBrickPyramid(windowSize);
  92 + // Ball area = 2*PI*26^2 ~= 6.28*26*26 ~= 5400
  93 + // Fill quarter of the screen...
  94 + int numBalls = 10 + windowSize.GetWidth() * windowSize.GetHeight() / 20000;
  95 +
  96 + for(int i = 0; i < numBalls; ++i)
  97 + {
  98 + CreateBall();
  99 + }
89 100  
90 101 // For funky mouse drag
91 102 mMouseBody = mPhysicsImpl.AddMouseBody();
... ... @@ -98,53 +109,17 @@ public:
98 109 const float BALL_ELASTICITY = 0.5f;
99 110 const float BALL_FRICTION = 0.5f;
100 111  
101   - Property::Value v{std::string{SHADER_RENDERING_TEXTURED_SHAPE_VERT}};
102   - Property::Value f{std::string{SHADER_RENDERING_TEXTURED_SHAPE_FRAG}};
103   -
104   - auto image = Property::Map{{Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE},
105   - {Toolkit::ImageVisual::Property::URL, BALL_IMAGE},
106   - {Toolkit::Visual::Property::SHADER, {{Toolkit::Visual::Shader::Property::FRAGMENT_SHADER, f}}}};
  112 + auto ball = Toolkit::ImageView::New(BALL_IMAGE);
107 113  
108   - auto ball = Toolkit::ImageView::New();
109   - ball[Toolkit::ImageView::Property::IMAGE] = image;
110   - mPhysicsImpl.AddBall(ball, BALL_MASS, BALL_RADIUS, BALL_ELASTICITY, BALL_FRICTION);
  114 + auto& physicsBall = mPhysicsImpl.AddBall(ball, BALL_MASS, BALL_RADIUS, BALL_ELASTICITY, BALL_FRICTION);
  115 + Window::WindowSize windowSize = mWindow.GetSize();
  116 + const float s = BALL_RADIUS;
  117 + const float fw = windowSize.GetWidth() - BALL_RADIUS;
  118 + const float fh = windowSize.GetHeight() - BALL_RADIUS;
  119 + physicsBall.SetPhysicsPosition(Vector3(Random::Range(s, fw), Random::Range(s, fh), 0.0f));
  120 + physicsBall.SetPhysicsVelocity(Vector3(Random::Range(-100.0, 100.0), Random::Range(-100.0, 100.0), 0.0f));
111 121 }
112 122  
113   - void CreateBrickPyramid(Dali::Window::WindowSize windowSize)
114   - {
115   - const float BRICK_MASS = 30.0f;
116   - const float BRICK_ELASTICITY = 0.0f;
117   - const float BRICK_FRICTION = 0.9f;
118   - const int BRICK_WIDTH = 128;
119   - const int BRICK_HEIGHT = 64;
120   - const int BRICK_GAP = 8;
121   -
122   - Property::Value v{std::string{SHADER_RENDERING_TEXTURED_SHAPE_VERT}};
123   - Property::Value f{std::string{SHADER_RENDERING_TEXTURED_SHAPE_FRAG}};
124   -
125   - int uriIndex = 0;
126   - int numberOfRows = windowSize.GetWidth() / (BRICK_WIDTH + BRICK_GAP) - 2;
127   - int oY = windowSize.GetHeight() - (1 + numberOfRows) * BRICK_HEIGHT;
128   - for(int i = 0; i < numberOfRows; ++i)
129   - {
130   - // Row start: i+1 is brick number. i is gap#
131   - int w = (i + 1) * BRICK_WIDTH + i * BRICK_GAP;
132   - int oX = (windowSize.GetWidth() - w) / 2;
133   - for(int j = 0; j < i + 1; ++j)
134   - {
135   - auto image = Property::Map{{Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE},
136   - {Toolkit::ImageVisual::Property::URL, BRICK_URIS[uriIndex]},
137   - {Toolkit::Visual::Property::SHADER, {{Toolkit::Visual::Shader::Property::FRAGMENT_SHADER, f}}}};
138   -
139   - auto brick = Toolkit::ImageView::New();
140   - brick[Toolkit::ImageView::Property::IMAGE] = image;
141   - auto& physicsActor = mPhysicsImpl.AddBrick(brick, BRICK_MASS, BRICK_ELASTICITY, BRICK_FRICTION, Vector3(BRICK_WIDTH, BRICK_HEIGHT, BRICK_HEIGHT));
142   - physicsActor.SetPhysicsPosition(Vector3(oX + j * (BRICK_WIDTH + BRICK_GAP), oY + i * BRICK_HEIGHT, 0.0f));
143   - uriIndex += 1;
144   - uriIndex %= 4;
145   - }
146   - }
147   - }
148 123 void OnTerminate(Application& application)
149 124 {
150 125 UnparentAndReset(mPhysicsRoot);
... ...
examples/chipmunk-physics/physics-impl.cpp
... ... @@ -19,26 +19,26 @@
19 19 #include "physics-actor.h"
20 20  
21 21 #include <devel-api/common/stage.h>
  22 +#include <iostream>
22 23 #include <map>
23 24 #include <utility>
24   -#include <iostream>
25 25  
26   -using Dali::Layer;
27 26 using Dali::Actor;
28   -using Dali::Window;
  27 +using Dali::Layer;
  28 +using Dali::Stage;
29 29 using Dali::Vector2;
30 30 using Dali::Vector3;
31   -using Dali::Stage;
  31 +using Dali::Window;
32 32 using namespace Dali::DevelStage;
33 33  
34   -#define GRABBABLE_MASK_BIT (1u<<31)
35   -cpShapeFilter GRAB_FILTER = {CP_NO_GROUP, GRABBABLE_MASK_BIT, GRABBABLE_MASK_BIT};
  34 +#define GRABBABLE_MASK_BIT (1u << 31)
  35 +cpShapeFilter GRAB_FILTER = {CP_NO_GROUP, GRABBABLE_MASK_BIT, GRABBABLE_MASK_BIT};
36 36 cpShapeFilter NOT_GRABBABLE_FILTER = {CP_NO_GROUP, ~GRABBABLE_MASK_BIT, ~GRABBABLE_MASK_BIT};
37 37  
38 38 Actor PhysicsImpl::Initialize(Window window)
39 39 {
40 40 mWindow = window;
41   - mSpace = cpSpaceNew();
  41 + mSpace = cpSpaceNew();
42 42 cpSpaceSetIterations(mSpace, 30);
43 43 cpSpaceSetSleepTimeThreshold(mSpace, 0.5f);
44 44 cpSpaceSetGravity(mSpace, cpv(0, -200));
... ... @@ -47,16 +47,15 @@ Actor PhysicsImpl::Initialize(Window window)
47 47 CreateWorldBounds(windowSize);
48 48  
49 49 // Create an actor that can handle mouse events.
50   - mPhysicsRoot = Layer::New();
51   - mPhysicsRoot[Actor::Property::SIZE] = Vector2(windowSize.GetWidth(), windowSize.GetHeight());
52   - mPhysicsRoot[Actor::Property::ANCHOR_POINT] = Dali::AnchorPoint::CENTER;
  50 + mPhysicsRoot = Layer::New();
  51 + mPhysicsRoot[Actor::Property::SIZE] = Vector2(windowSize.GetWidth(), windowSize.GetHeight());
  52 + mPhysicsRoot[Actor::Property::ANCHOR_POINT] = Dali::AnchorPoint::CENTER;
53 53 mPhysicsRoot[Actor::Property::PARENT_ORIGIN] = Dali::ParentOrigin::CENTER;
54 54  
55 55 mFrameCallback = new FrameCallback(*this);
56 56 AddFrameCallback(Stage::GetCurrent(), *mFrameCallback, window.GetRootLayer());
57 57 Stage::GetCurrent().KeepRendering(30);
58 58  
59   -
60 59 return mPhysicsRoot;
61 60 }
62 61  
... ... @@ -73,10 +72,10 @@ void PhysicsImpl::CreateWorldBounds(Window::WindowSize size)
73 72 // But, can't use actors in update, so cache transform.
74 73 SetTransform(Vector2(size.GetWidth(), size.GetHeight()));
75 74  
76   - int xBound=size.GetWidth()/2;
77   - int yBound=size.GetHeight()/2;
  75 + int xBound = size.GetWidth() / 2;
  76 + int yBound = size.GetHeight() / 2;
78 77  
79   - cpBody *staticBody = cpSpaceGetStaticBody(mSpace);
  78 + cpBody* staticBody = cpSpaceGetStaticBody(mSpace);
80 79  
81 80 if(mLeftBound)
82 81 {
... ... @@ -89,10 +88,10 @@ void PhysicsImpl::CreateWorldBounds(Window::WindowSize size)
89 88 cpShapeFree(mTopBound);
90 89 cpShapeFree(mBottomBound);
91 90 }
92   - mLeftBound = AddBound(staticBody, cpv(-xBound, -yBound), cpv(-xBound, yBound));
93   - mRightBound = AddBound(staticBody, cpv( xBound, -yBound), cpv( xBound, yBound));
94   - mTopBound = AddBound(staticBody, cpv(-xBound, -yBound), cpv( xBound, -yBound));
95   - mBottomBound = AddBound(staticBody, cpv(-xBound, yBound), cpv( xBound, yBound));
  91 + mLeftBound = AddBound(staticBody, cpv(-xBound, -yBound), cpv(-xBound, yBound));
  92 + mRightBound = AddBound(staticBody, cpv(xBound, -yBound), cpv(xBound, yBound));
  93 + mTopBound = AddBound(staticBody, cpv(-xBound, -yBound), cpv(xBound, -yBound));
  94 + mBottomBound = AddBound(staticBody, cpv(-xBound, yBound), cpv(xBound, yBound));
96 95 }
97 96  
98 97 void PhysicsImpl::SetTransform(Vector2 worldSize)
... ... @@ -104,7 +103,7 @@ void PhysicsImpl::SetTransform(Vector2 worldSize)
104 103  
105 104 cpShape* PhysicsImpl::AddBound(cpBody* staticBody, cpVect start, cpVect end)
106 105 {
107   - cpShape* shape = cpSpaceAddShape(mSpace, cpSegmentShapeNew(staticBody,start, end,0.0f));
  106 + cpShape* shape = cpSpaceAddShape(mSpace, cpSegmentShapeNew(staticBody, start, end, 0.0f));
108 107 cpShapeSetElasticity(shape, 1.0f);
109 108 cpShapeSetFriction(shape, 1.0f);
110 109 cpShapeSetFilter(shape, NOT_GRABBABLE_FILTER);
... ... @@ -114,7 +113,7 @@ cpShape* PhysicsImpl::AddBound(cpBody* staticBody, cpVect start, cpVect end)
114 113 PhysicsActor& PhysicsImpl::AddBall(::Actor actor, float mass, float radius, float elasticity, float friction)
115 114 {
116 115 Dali::Mutex::ScopedLock lock(mMutex);
117   - cpBody* body = cpSpaceAddBody(mSpace, cpBodyNew(mass, cpMomentForCircle(mass, 0.0f, radius, cpvzero)));
  116 + cpBody* body = cpSpaceAddBody(mSpace, cpBodyNew(mass, cpMomentForCircle(mass, 0.0f, radius, cpvzero)));
118 117 cpBodySetPosition(body, cpv(0, 0));
119 118 cpBodySetVelocity(body, cpv(0, 0));
120 119  
... ... @@ -122,11 +121,11 @@ PhysicsActor&amp; PhysicsImpl::AddBall(::Actor actor, float mass, float radius, floa
122 121 cpShapeSetElasticity(shape, elasticity);
123 122 cpShapeSetFriction(shape, friction);
124 123  
125   - int id = actor[Actor::Property::ID];
  124 + int id = actor[Actor::Property::ID];
126 125 Dali::Property::Index index = actor.RegisterProperty("uBrightness", 0.0f);
127 126 mPhysicsActors.insert(std::make_pair(id, PhysicsActor{actor, body, this, index}));
128 127 actor[Actor::Property::PARENT_ORIGIN] = Dali::ParentOrigin::TOP_LEFT;
129   - actor[Actor::Property::ANCHOR_POINT] = Dali::AnchorPoint::CENTER;
  128 + actor[Actor::Property::ANCHOR_POINT] = Dali::AnchorPoint::CENTER;
130 129 mPhysicsRoot.Add(actor);
131 130 return mPhysicsActors.at(id);
132 131 }
... ... @@ -134,7 +133,7 @@ PhysicsActor&amp; PhysicsImpl::AddBall(::Actor actor, float mass, float radius, floa
134 133 PhysicsActor& PhysicsImpl::AddBrick(Dali::Actor actor, float mass, float elasticity, float friction, Vector3 size)
135 134 {
136 135 Dali::Mutex::ScopedLock lock(mMutex);
137   - cpBody* body = cpSpaceAddBody(mSpace, cpBodyNew(mass, cpMomentForBox(mass, size.width, size.height)));
  136 + cpBody* body = cpSpaceAddBody(mSpace, cpBodyNew(mass, cpMomentForBox(mass, size.width, size.height)));
138 137 cpBodySetPosition(body, cpv(0, 0));
139 138 cpBodySetVelocity(body, cpv(0, 0));
140 139  
... ... @@ -142,11 +141,11 @@ PhysicsActor&amp; PhysicsImpl::AddBrick(Dali::Actor actor, float mass, float elastic
142 141 cpShapeSetFriction(shape, friction);
143 142 cpShapeSetElasticity(shape, elasticity);
144 143  
145   - int id = actor[Actor::Property::ID];
  144 + int id = actor[Actor::Property::ID];
146 145 Dali::Property::Index index = actor.RegisterProperty("uBrightness", 0.0f);
147 146 mPhysicsActors.insert(std::make_pair(id, PhysicsActor{actor, body, this, index}));
148 147 actor[Actor::Property::PARENT_ORIGIN] = Dali::ParentOrigin::TOP_LEFT;
149   - actor[Actor::Property::ANCHOR_POINT] = Dali::AnchorPoint::CENTER;
  148 + actor[Actor::Property::ANCHOR_POINT] = Dali::AnchorPoint::CENTER;
150 149 mPhysicsRoot.Add(actor);
151 150 return mPhysicsActors.at(id);
152 151 }
... ... @@ -154,7 +153,7 @@ PhysicsActor&amp; PhysicsImpl::AddBrick(Dali::Actor actor, float mass, float elastic
154 153 cpBody* PhysicsImpl::AddMouseBody()
155 154 {
156 155 Dali::Mutex::ScopedLock lock(mMutex);
157   - auto kinematicBody = cpBodyNewKinematic(); // Mouse actor is a kinematic body that is not integrated
  156 + auto kinematicBody = cpBodyNewKinematic(); // Mouse actor is a kinematic body that is not integrated
158 157 return kinematicBody;
159 158 }
160 159  
... ... @@ -171,7 +170,7 @@ void PhysicsImpl::HighlightBody(cpBody* body, bool highlight)
171 170 Actor actor = mPhysicsRoot.FindChildById(physicsActor->GetId());
172 171 if(actor)
173 172 {
174   - actor[physicsActor->GetBrightnessIndex()] = highlight?1.0f:0.0f;
  173 + actor[physicsActor->GetBrightnessIndex()] = highlight ? 1.0f : 0.0f;
175 174 }
176 175 }
177 176 }
... ... @@ -181,13 +180,13 @@ Vector3 PhysicsImpl::TranslateToPhysicsSpace(Vector3 vector)
181 180 {
182 181 // root actor origin is top left, DALi Y is inverted.
183 182 // Physics origin is center. Y: 0->1 => 0.5=>-0.5
184   - return Vector3(vector.x-mWorldOffset.x, mWorldOffset.y-vector.y, vector.z);
  183 + return Vector3(vector.x - mWorldOffset.x, mWorldOffset.y - vector.y, vector.z);
185 184 }
186 185  
187 186 // Convert from physics space to root actor local space
188 187 Vector3 PhysicsImpl::TranslateFromPhysicsSpace(Vector3 vector)
189 188 {
190   - return Vector3(vector.x+mWorldOffset.x, mWorldOffset.y-vector.y, vector.z);
  189 + return Vector3(vector.x + mWorldOffset.x, mWorldOffset.y - vector.y, vector.z);
191 190 }
192 191  
193 192 // Convert a vector from dali space to physics space
... ... @@ -210,39 +209,38 @@ void PhysicsImpl::Integrate(float timestep)
210 209 {
211 210 cpSpaceStep(mSpace, timestep);
212 211 }
213   -// if(mDynamicsWorld->getDebugDrawer() && mPhysicsDebugState)
214   -// {
215   -// mDynamicsWorld->debugDrawWorld();
216   -// }
  212 + // if(mDynamicsWorld->getDebugDrawer() && mPhysicsDebugState)
  213 + // {
  214 + // mDynamicsWorld->debugDrawWorld();
  215 + // }
217 216 }
218 217  
219 218 cpBody* PhysicsImpl::HitTest(Vector2 screenCoords, Vector3 origin, Vector3 direction, Vector3& localPivot, float& distanceFromCamera)
220 219 {
221   - Vector3 spacePosition = TranslateToPhysicsSpace(Vector3{screenCoords});
222   - cpVect mousePosition = cpv(spacePosition.x, spacePosition.y);
223   - cpFloat radius = 5.0f;
224   - cpPointQueryInfo info = {0};
225   - cpShape *shape = cpSpacePointQueryNearest(mSpace, mousePosition, radius, GRAB_FILTER, &info);
  220 + Vector3 spacePosition = TranslateToPhysicsSpace(Vector3{screenCoords});
  221 + cpVect mousePosition = cpv(spacePosition.x, spacePosition.y);
  222 + cpFloat radius = 5.0f;
  223 + cpPointQueryInfo info = {0};
  224 + cpShape* shape = cpSpacePointQueryNearest(mSpace, mousePosition, radius, GRAB_FILTER, &info);
226 225  
227   - cpBody *body{nullptr};
  226 + cpBody* body{nullptr};
228 227  
229 228 if(shape && cpBodyGetMass(cpShapeGetBody(shape)) < INFINITY)
230 229 {
231 230 // Use the closest point on the surface if the click is outside the shape.
232 231 cpVect nearest = (info.distance > 0.0f ? info.point : mousePosition);
233   - body = cpShapeGetBody(shape);
234   - cpVect local = cpBodyWorldToLocal(body, nearest);
235   - localPivot.x = local.x;
236   - localPivot.y = local.y;
237   - localPivot.z = 0.0;
  232 + body = cpShapeGetBody(shape);
  233 + cpVect local = cpBodyWorldToLocal(body, nearest);
  234 + localPivot.x = local.x;
  235 + localPivot.y = local.y;
  236 + localPivot.z = 0.0;
238 237 }
239 238 return body;
240 239 }
241 240  
242   -
243 241 cpConstraint* PhysicsImpl::AddPivotJoint(cpBody* body1, cpBody* body2, Vector3 localPivot)
244 242 {
245   - cpVect pivot{localPivot.x, localPivot.y};
  243 + cpVect pivot{localPivot.x, localPivot.y};
246 244 cpConstraint* joint = cpPivotJointNew2(body2, body1, cpvzero, pivot);
247 245 cpConstraintSetMaxForce(joint, 50000.0f); // Magic numbers for mouse feedback.
248 246 cpConstraintSetErrorBias(joint, cpfpow(1.0f - 0.15f, 60.0f));
... ... @@ -253,7 +251,7 @@ cpConstraint* PhysicsImpl::AddPivotJoint(cpBody* body1, cpBody* body2, Vector3 l
253 251 void PhysicsImpl::MoveMouseBody(cpBody* mouseBody, Vector3 position)
254 252 {
255 253 cpVect cpPosition = cpv(position.x, position.y);
256   - cpVect newPoint = cpvlerp(cpBodyGetPosition(mouseBody), cpPosition, 0.25f);
  254 + cpVect newPoint = cpvlerp(cpBodyGetPosition(mouseBody), cpPosition, 0.25f);
257 255 cpBodySetVelocity(mouseBody, cpvmult(cpvsub(newPoint, cpBodyGetPosition(mouseBody)), 60.0f));
258 256 // Normally, kinematic body's position would be calculated by engine.
259 257 // For mouse, though, we want to set it.
... ...