From: sunghyun kim Date: Mon, 11 Sep 2023 00:55:26 +0000 (+0000) Subject: Merge "Apply fittingMode lazy when resource is not ready" into devel/master X-Git-Tag: dali_2.2.44~8 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=95078fdc62e85ae3454e77eb6eaa0e6b1817ff07;hp=08c00745e3c0f9930a48a5a07e6bf5441edafaab;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git Merge "Apply fittingMode lazy when resource is not ready" into devel/master --- diff --git a/automated-tests/src/dali-physics2d/utc-Dali-PhysicsActor.cpp b/automated-tests/src/dali-physics2d/utc-Dali-PhysicsActor.cpp index 855d686..91700fd 100644 --- a/automated-tests/src/dali-physics2d/utc-Dali-PhysicsActor.cpp +++ b/automated-tests/src/dali-physics2d/utc-Dali-PhysicsActor.cpp @@ -372,7 +372,7 @@ int UtcDaliPhysics2DActorSetRotation1(void) // Warning - physics properties are never reflected in the event size cache. // Have to use GetCurrentProperty to see the updated values. Quaternion q = actor.GetCurrentProperty(Actor::Property::ORIENTATION); - Quaternion expected(Degree(30), Vector3::ZAXIS); + Quaternion expected(Degree(-30), Vector3::ZAXIS); DALI_TEST_EQUALS(q, expected, 0.0001f, TEST_LOCATION); } @@ -385,7 +385,7 @@ int UtcDaliPhysics2DActorSetRotation2(void) ToolkitTestApplication application; Matrix transform(false); - transform.SetIdentityAndScale(Vector3(2.0f, -2.0f, 1.0f)); + transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 1.0f)); Uint16Pair size(640, 480); PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size); Actor rootActor = adaptor.GetRootActor(); diff --git a/automated-tests/src/dali-physics2d/utc-Dali-PhysicsAdaptor.cpp b/automated-tests/src/dali-physics2d/utc-Dali-PhysicsAdaptor.cpp index b6ca868..cf846bb 100644 --- a/automated-tests/src/dali-physics2d/utc-Dali-PhysicsAdaptor.cpp +++ b/automated-tests/src/dali-physics2d/utc-Dali-PhysicsAdaptor.cpp @@ -60,6 +60,49 @@ cpBody* CreateBody(cpSpace* space) return body; } +// Defines a PolyShape +cpBody* CreateHexBody(cpSpace* space) +{ + const float MASS = 10.0f; + const float RADIUS = 26.0f; + const float ELASTICITY = 0.5f; + const float FRICTION = 0.5f; + + cpVect hexagon[6]; + for(int i = 0; i < 6; i++) + { + cpFloat angle = -CP_PI * 2.0f * i / 6.0f; + hexagon[i] = cpvmult(cpv(cos(angle), sin(angle)), RADIUS - 1.0f); + } + + cpBody* body = cpSpaceAddBody(space, cpBodyNew(MASS, cpMomentForPoly(MASS, 6, hexagon, cpvzero, 0.0f))); + cpShape* shape = cpSpaceAddShape(space, cpPolyShapeNew(body, 6, hexagon, cpTransformIdentity, 1.0f)); + + cpShapeSetElasticity(shape, ELASTICITY); + cpShapeSetFriction(shape, FRICTION); + + return body; +} + +// Defines a SegmentShape +cpBody* CreateSegBody(cpSpace* space) +{ + const float MASS = 10.0f; + const float RADIUS = 26.0f; + const float ELASTICITY = 0.5f; + const float FRICTION = 0.5f; + + cpVect a = cpv(0, 100); + cpVect b = cpv(100, 0); + cpBody* body = cpSpaceAddBody(space, cpBodyNew(MASS, cpMomentForSegment(MASS, a, b, 0.0f))); + cpShape* shape = cpSpaceAddShape(space, cpSegmentShapeNew(body, a, b, RADIUS)); + + cpShapeSetElasticity(shape, ELASTICITY); + cpShapeSetFriction(shape, FRICTION); + + return body; +} + int UtcDaliPhysics2DCreateAdaptorP1(void) { ToolkitTestApplication application; @@ -290,7 +333,46 @@ int UtcDaliPhysics2DAdaptorCreateDebugLayer(void) Window window = DevelWindow::Get(rootActor); Layer layer = adaptor.CreateDebugLayer(window); - DALI_TEST_CHECK(!layer); + DALI_TEST_CHECK(layer); + + adaptor.SetDebugState(PhysicsAdaptor::DebugState::ON); + + cpBody* body{nullptr}; + cpBody* body2{nullptr}; + cpBody* body3{nullptr}; + { + auto accessor = adaptor.GetPhysicsAccessor(); + auto space = accessor->GetNative().Get(); + + body = CreateBody(space); + Dali::Actor ballActor = Toolkit::ImageView::New("gallery-small-1.jpg"); + auto physicsActor = adaptor.AddActorBody(ballActor, body); + cpBodySetPosition(body, cpv(0, 0)); + + // Constraint should create a dot in debug + cpBody* staticBody = cpSpaceGetStaticBody(space); + cpSpaceAddConstraint(space, cpPivotJointNew(staticBody, body, cpv(10, 10))); + + body2 = CreateHexBody(space); + Dali::Actor ballActor2 = Toolkit::ImageView::New("gallery-small-1.jpg"); + auto physicsActor2 = adaptor.AddActorBody(ballActor2, body2); + cpBodySleep(body2); + + body3 = CreateSegBody(space); + Dali::Actor ballActor3 = Toolkit::ImageView::New("gallery-small-1.jpg"); + auto physicsActor3 = adaptor.AddActorBody(ballActor3, body3); + } + Test::WaitForEventThreadTrigger(1); + + // Render - if it doesn't crash, great! + application.SendNotification(); + application.Render(); + + Uint16Pair size2(480, 640); + adaptor.SetTransformAndSize(transform, size2); + + application.SendNotification(); + application.Render(); END_TEST; } @@ -321,7 +403,8 @@ int UtcDaliPhysics2DAdaptorTranslateToPhysicsSpace2(void) // Rotation shouldn't change under this scale Quaternion q(Degree(30.0f), Vector3::XAXIS); - DALI_TEST_EQUALS(adaptor.TranslateToPhysicsSpace(q), q, 0.0001f, TEST_LOCATION); + Quaternion expected(Degree(30.0f), Vector3::XAXIS); + DALI_TEST_EQUALS(adaptor.TranslateToPhysicsSpace(q), expected, 0.0001f, TEST_LOCATION); END_TEST; } @@ -330,52 +413,16 @@ int UtcDaliPhysics2DAdaptorTranslateToPhysicsSpace3(void) { ToolkitTestApplication application; Matrix transform(false); - tet_infoline("Test that using an inverted Y scale does nothing to rotation"); + tet_infoline("Test that using an inverted Y scale inverts rotation"); transform.SetIdentityAndScale(Vector3(1.0f, -1.0f, 1.0f)); Uint16Pair size(640, 480); PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size); Quaternion q(Degree(30.0f), Vector3::ZAXIS); - Quaternion qp(Degree(30.0f), Vector3::ZAXIS); - - DALI_TEST_EQUALS(adaptor.TranslateToPhysicsSpace(q), qp, 0.0001f, TEST_LOCATION); - - END_TEST; -} - -int UtcDaliPhysics2DAdaptorTranslateToPhysicsSpace4(void) -{ - ToolkitTestApplication application; - Matrix transform(false); - tet_infoline("Test that using an inverted Y scale does nothing to rotation"); - - transform.SetIdentityAndScale(Vector3(1.0f, -1.0f, 1.0f)); - Uint16Pair size(640, 480); - PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size); + Quaternion expected(Degree(-30.0f), Vector3::ZAXIS); - Quaternion q(Degree(30.0f), Vector3::XAXIS); - Quaternion qp(Degree(30.0f), Vector3::XAXIS); - - DALI_TEST_EQUALS(adaptor.TranslateToPhysicsSpace(q), qp, 0.0001f, TEST_LOCATION); - - END_TEST; -} - -int UtcDaliPhysics2DAdaptorTranslateToPhysicsSpace5(void) -{ - ToolkitTestApplication application; - Matrix transform(false); - tet_infoline("Test that using an inverted Y scale does nothing to rotation"); - - transform.SetIdentityAndScale(Vector3(1.0f, -1.0f, 1.0f)); - Uint16Pair size(640, 480); - PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size); - - Quaternion q(Degree(30.0f), Vector3::YAXIS); - Quaternion qp(Degree(30.0f), Vector3::YAXIS); - - DALI_TEST_EQUALS(adaptor.TranslateToPhysicsSpace(q), qp, 0.0001f, TEST_LOCATION); + DALI_TEST_EQUALS(adaptor.TranslateToPhysicsSpace(q), expected, 0.0001f, TEST_LOCATION); END_TEST; } @@ -926,7 +973,11 @@ int UtcDaliPhysics2DAdaptorHitTestP(void) auto accessor = adaptor.GetPhysicsAccessor(); Vector3 localPivot; float distanceFromCamera; - auto body = accessor->HitTest(from, from, localPivot, distanceFromCamera); + + cpShapeFilter GRAB_FILTER = {CP_NO_GROUP, 1u << 31, 1u << 31}; + Dali::Any nativeFilter{GRAB_FILTER}; + + auto body = accessor->HitTest(from, from, nativeFilter, localPivot, distanceFromCamera); DALI_TEST_CHECK(!body.Empty()); } diff --git a/automated-tests/src/dali-physics3d/utc-Dali-PhysicsAdaptor.cpp b/automated-tests/src/dali-physics3d/utc-Dali-PhysicsAdaptor.cpp index b09c8fc..1315a55 100644 --- a/automated-tests/src/dali-physics3d/utc-Dali-PhysicsAdaptor.cpp +++ b/automated-tests/src/dali-physics3d/utc-Dali-PhysicsAdaptor.cpp @@ -947,10 +947,11 @@ int UtcDaliPhysics3DAdaptorHitTestP(void) adaptor.BuildPickingRay(origin, direction, from, to); // Hit test centre of screen { - auto accessor = adaptor.GetPhysicsAccessor(); - Vector3 localPivot; - float distanceFromCamera; - auto body = accessor->HitTest(from, to, localPivot, distanceFromCamera); + auto accessor = adaptor.GetPhysicsAccessor(); + Vector3 localPivot; + float distanceFromCamera; + Dali::Any nullFilter; + auto body = accessor->HitTest(from, to, nullFilter, localPivot, distanceFromCamera); DALI_TEST_CHECK(!body.Empty()); } diff --git a/build/tizen/dali-physics/CMakeLists.txt b/build/tizen/dali-physics/CMakeLists.txt index 00c482b..9c52173 100644 --- a/build/tizen/dali-physics/CMakeLists.txt +++ b/build/tizen/dali-physics/CMakeLists.txt @@ -75,9 +75,12 @@ include(${physics_dir}/public-api/file.list) include(${physics_dir}/internal/file.list) set(prefix_include_dir "${prefix}/include") -include_directories(${repo_root_dir} + +include_directories(BEFORE + ${repo_root_dir} "${prefix_include_dir}" "${repo_root_dir}/dali-physics/third-party/bullet3/src" + "${repo_root_dir}/dali-physics/third-party/chipmunk2d/include" ) MESSAGE(STATUS "2D sources: ${physics2d_src_files}") diff --git a/dali-physics/internal/bullet-impl/bullet-physics-world-impl.cpp b/dali-physics/internal/bullet-impl/bullet-physics-world-impl.cpp index 79d97de..920d015 100644 --- a/dali-physics/internal/bullet-impl/bullet-physics-world-impl.cpp +++ b/dali-physics/internal/bullet-impl/bullet-physics-world-impl.cpp @@ -114,7 +114,7 @@ inline btVector3 ConvertVector(Dali::Vector3 vector) return btVector3(vector.x, vector.y, vector.z); } -Dali::Any BulletPhysicsWorld::HitTest(Dali::Vector3 rayFromWorld, Dali::Vector3 rayToWorld, Dali::Vector3& localPivot, float& distanceFromCamera) +Dali::Any BulletPhysicsWorld::HitTest(Dali::Vector3 rayFromWorld, Dali::Vector3 rayToWorld, Dali::Any nativeFilter, Dali::Vector3& localPivot, float& distanceFromCamera) { btRigidBody* hitBody{nullptr}; diff --git a/dali-physics/internal/bullet-impl/bullet-physics-world-impl.h b/dali-physics/internal/bullet-impl/bullet-physics-world-impl.h index 2a5ff55..5f9f193 100644 --- a/dali-physics/internal/bullet-impl/bullet-physics-world-impl.h +++ b/dali-physics/internal/bullet-impl/bullet-physics-world-impl.h @@ -48,11 +48,12 @@ public: * * @param[in] rayFromWorld The origin in physics world space * @param[in] rayToWorld A point along the direction on the far side of the physics world + * @param[in] nativeFilter A native shape/body filter * @param[out] localPivot The hit point local to the body * @param[out] distanceFromCamera The distance of the pick point from the camera * @return Empty value if no dynamic body found, otherwise a valid ptr to the hit body. */ - Dali::Any HitTest(Dali::Vector3 rayFromWorld, Dali::Vector3 rayToWorld, Dali::Vector3& localPivot, float& distanceFromCamera) override; + Dali::Any HitTest(Dali::Vector3 rayFromWorld, Dali::Vector3 rayToWorld, Dali::Any nativeFilter, Dali::Vector3& localPivot, float& distanceFromCamera) override; void Integrate(float timestep) override; diff --git a/dali-physics/internal/chipmunk-impl/chipmunk-physics-adaptor-impl.cpp b/dali-physics/internal/chipmunk-impl/chipmunk-physics-adaptor-impl.cpp index 1a4ffb9..923927a 100644 --- a/dali-physics/internal/chipmunk-impl/chipmunk-physics-adaptor-impl.cpp +++ b/dali-physics/internal/chipmunk-impl/chipmunk-physics-adaptor-impl.cpp @@ -71,7 +71,42 @@ void ChipmunkPhysicsAdaptor::OnInitialize(const Dali::Matrix& transform, Uint16P Layer ChipmunkPhysicsAdaptor::CreateDebugLayer(Dali::Window window) { - return Layer(); + Layer debugLayer; + + auto renderTaskList = window.GetRenderTaskList(); + auto renderTask = renderTaskList.GetTask(0); + auto windowSize = window.GetSize(); + + debugLayer = Layer::New(); + debugLayer[Actor::Property::NAME] = "PhysicsDebugLayer"; + debugLayer[Actor::Property::ANCHOR_POINT] = Dali::AnchorPoint::CENTER; + debugLayer[Actor::Property::PARENT_ORIGIN] = Dali::ParentOrigin::CENTER; + + Constraint positionConstraint = Constraint::New(debugLayer, Actor::Property::POSITION, EqualToConstraint()); + positionConstraint.AddSource(Source(mRootActor, Actor::Property::POSITION)); + positionConstraint.Apply(); + Constraint sizeConstraint = Constraint::New(debugLayer, Actor::Property::SIZE, EqualToConstraint()); + sizeConstraint.AddSource(Source(mRootActor, Actor::Property::SIZE)); + sizeConstraint.Apply(); + + auto world = static_cast(mPhysicsWorld.get()); + + std::unique_ptr debugRenderer = PhysicsDebugRenderer::New(windowSize.GetWidth(), windowSize.GetHeight(), renderTask.GetCameraActor(), this); + + mDebugActor = DrawableActor::New(*(debugRenderer->GetCallback().get())); + world->SetDebugRenderer(debugRenderer.release()); + + mDebugActor[Actor::Property::ANCHOR_POINT] = Dali::AnchorPoint::CENTER; + mDebugActor[Actor::Property::PARENT_ORIGIN] = Dali::ParentOrigin::CENTER; + + Constraint sizeConstraint2 = Constraint::New(mDebugActor, Actor::Property::SIZE, EqualToConstraint()); + sizeConstraint2.AddSource(ParentSource(Actor::Property::SIZE)); + sizeConstraint2.Apply(); + + debugLayer.Add(mDebugActor); + + window.Add(debugLayer); + return debugLayer; } void ChipmunkPhysicsAdaptor::SetTransformAndSize(const Dali::Matrix& transform, Uint16Pair worldSize) @@ -82,6 +117,14 @@ void ChipmunkPhysicsAdaptor::SetTransformAndSize(const Dali::Matrix& transform, mSize = worldSize; GetRootActor()[Actor::Property::SIZE] = Vector3(worldSize.GetWidth(), worldSize.GetHeight(), 0); + + auto world = static_cast(mPhysicsWorld.get()); + if(world->HasDebugRenderer()) + { + Actor layer = mDebugActor.GetParent(); + layer[Actor::Property::SIZE] = Vector3(worldSize); + world->GetDebugRenderer().UpdateWindowSize(worldSize); + } } PhysicsActorPtr ChipmunkPhysicsAdaptor::AddActorBody(Dali::Actor actor, Dali::Any body) @@ -144,8 +187,22 @@ Vector3 ChipmunkPhysicsAdaptor::TranslateFromPhysicsSpace(Vector3 vector) const Quaternion ChipmunkPhysicsAdaptor::TranslateToPhysicsSpace(Quaternion orientation) const { - // It's complicated. - return orientation; + // Actors face outwards (+ve Z) + // In DALi world, +ve angle about +ve Z is clockwise. + // But, if physics is mirrored in Y axis, so +ve angle is anti-clockwise. + + // Compute angle about Z axis + Vector3 axis; + Radian angle; + orientation.ToAxisAngle(axis, angle); + + // Check if Transform matrix is mirrored in X xor Y + if(std::signbit(mTransform.AsFloat()[0]) ^ std::signbit(mTransform.AsFloat()[5])) + { + return Quaternion(-angle, axis); + } + + return Quaternion(angle, axis); } Quaternion ChipmunkPhysicsAdaptor::TranslateFromPhysicsSpace(Quaternion orientation) const diff --git a/dali-physics/internal/chipmunk-impl/chipmunk-physics-adaptor-impl.h b/dali-physics/internal/chipmunk-impl/chipmunk-physics-adaptor-impl.h index 48715e3..55f515d 100644 --- a/dali-physics/internal/chipmunk-impl/chipmunk-physics-adaptor-impl.h +++ b/dali-physics/internal/chipmunk-impl/chipmunk-physics-adaptor-impl.h @@ -106,6 +106,10 @@ public: * @copydoc Dali::Toolkit::Physics::PhysicsAdaptor::ProjectPoint */ Dali::Vector3 ProjectPoint(Dali::Vector3 origin, Dali::Vector3 direction, float distance) override; + +private: + Actor mDebugActor; + // Physics world owns debug renderer }; } // namespace Dali::Toolkit::Physics::Internal diff --git a/dali-physics/internal/chipmunk-impl/chipmunk-physics-debug-renderer.cpp b/dali-physics/internal/chipmunk-impl/chipmunk-physics-debug-renderer.cpp new file mode 100644 index 0000000..2e60d97 --- /dev/null +++ b/dali-physics/internal/chipmunk-impl/chipmunk-physics-debug-renderer.cpp @@ -0,0 +1,472 @@ +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd. + * + * Licensed 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 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +namespace +{ +GLuint LoadShader(GLenum shaderType, const char* shaderSource) +{ + GLuint shader = glCreateShader(shaderType); + if(shader != 0) + { + glShaderSource(shader, 1, &shaderSource, NULL); + glCompileShader(shader); + GLint compiled = 0; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); + if(compiled != GL_TRUE) + { + GLint infoLen = 0; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); + + if(infoLen > 0) + { + std::vector logBuffer; + logBuffer.resize(infoLen + 1); + glGetShaderInfoLog(shader, infoLen, NULL, &logBuffer[0]); + fprintf(stderr, "%s\n", &logBuffer[0]); + fflush(stderr); + + glDeleteShader(shader); + shader = 0; + } + } + } + return shader; +} + +GLuint CreateProgram(const char* vertexSource, const char* fragmentSource) +{ + GLuint vertexShader = LoadShader(GL_VERTEX_SHADER, vertexSource); + if(!vertexShader) + { + return 0; + } + GLuint fragmentShader = LoadShader(GL_FRAGMENT_SHADER, fragmentSource); + if(!fragmentShader) + { + return 0; + } + GLuint program = glCreateProgram(); + if(program) + { + glAttachShader(program, vertexShader); + glAttachShader(program, fragmentShader); + glLinkProgram(program); + GLint linkStatus = GL_FALSE; + glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); + if(linkStatus != GL_TRUE) + { + GLint bufLength = 0; + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); + if(bufLength) + { + std::vector logBuffer; + logBuffer.resize(bufLength + 1); + glGetProgramInfoLog(program, bufLength, NULL, &logBuffer[0]); + fprintf(stderr, "%s\n", &logBuffer[0]); + fflush(stderr); + } + glDeleteProgram(program); + program = 0; + } + } + return program; +} +} // namespace + +namespace Dali::Toolkit::Physics::Internal +{ +static void DebugDrawCircleImpl(cpVect pos, cpFloat angle, cpFloat radius, cpSpaceDebugColor outlineColor, cpSpaceDebugColor fillColor, cpDataPointer data) +{ + auto debugRenderer = static_cast(data); + debugRenderer->DrawCircle(pos, angle, radius, outlineColor, fillColor); +} + +static void DebugDrawSegmentImpl(cpVect a, cpVect b, cpSpaceDebugColor color, cpDataPointer data) +{ + auto debugRenderer = static_cast(data); + debugRenderer->DrawSegment(a, b, color); +} + +void DebugDrawFatSegmentImpl(cpVect a, cpVect b, cpFloat radius, cpSpaceDebugColor outlineColor, cpSpaceDebugColor fillColor, cpDataPointer data) +{ + auto debugRenderer = static_cast(data); + debugRenderer->DrawFatSegment(a, b, radius, outlineColor, fillColor); +} + +void DebugDrawPolygonImpl(int count, const cpVect* verts, cpFloat radius, cpSpaceDebugColor outlineColor, cpSpaceDebugColor fillColor, cpDataPointer data) +{ + auto debugRenderer = static_cast(data); + debugRenderer->DrawPolygon(count, verts, radius, outlineColor, fillColor); +} + +void DebugDrawDotImpl(cpFloat size, cpVect pos, cpSpaceDebugColor color, cpDataPointer data) +{ + auto debugRenderer = static_cast(data); + debugRenderer->DrawDot(size, pos, color); +} + +cpSpaceDebugColor DebugDrawColorForShapeImpl(cpShape* shape, cpDataPointer data) +{ + auto debugRenderer = static_cast(data); + return debugRenderer->DrawColorForShape(shape); +} + +std::unique_ptr PhysicsDebugRenderer::New(uint32_t width, uint32_t height, Dali::CameraActor camera, PhysicsAdaptor* adaptor) +{ + auto renderer = std::make_unique(width, height, camera, adaptor); + + renderer->mRenderCallback = Dali::RenderCallback::New(renderer.get(), &PhysicsDebugRenderer::OnRender); + return renderer; +} + +PhysicsDebugRenderer::PhysicsDebugRenderer(uint32_t width, uint32_t height, Dali::CameraActor camera, PhysicsAdaptor* adaptor) +: mCamera(camera), + mWidth(width), + mHeight(height), + mAdaptor(*adaptor), + mPositionLocation(-1), + mUvsLocation(-1), + mRadiusLocation(-1), + mFillColourLocation(-1), + mOutlineColourLocation(-1), + mProjectionLocation(-1), + mModelViewLocation(-1), + mIndexBufferId(0u), + mVertexBufferId(0u), + mProgramId(0u) +{ + mDebugDrawOptions.drawCircle = DebugDrawCircleImpl; + mDebugDrawOptions.drawSegment = DebugDrawSegmentImpl; + mDebugDrawOptions.drawFatSegment = DebugDrawFatSegmentImpl; + mDebugDrawOptions.drawPolygon = DebugDrawPolygonImpl; + mDebugDrawOptions.drawDot = DebugDrawDotImpl; + + mDebugDrawOptions.flags = static_cast(CP_SPACE_DEBUG_DRAW_SHAPES | + CP_SPACE_DEBUG_DRAW_COLLISION_POINTS | + CP_SPACE_DEBUG_DRAW_CONSTRAINTS); + mDebugDrawOptions.colorForShape = DebugDrawColorForShapeImpl; + mDebugDrawOptions.shapeOutlineColor = cpSpaceDebugColor{0.0f, 1.0f, 1.0f, 0.9f}; + mDebugDrawOptions.collisionPointColor = cpSpaceDebugColor{1.0f, 0.0f, 0.0f, 1.0f}; + mDebugDrawOptions.data = this; +} + +bool PhysicsDebugRenderer::OnRender(const Dali::RenderCallbackInput& input) +{ + if(mState == State::INIT) + { + Setup(); + mState = State::RENDER; + } + glViewport(0, 0, mWidth, mHeight); + + RenderLines(input); + + return false; +} + +// Run on first invocation of callback +void PhysicsDebugRenderer::Setup() +{ + PrepareShader(); + mPositionLocation = glGetAttribLocation(mProgramId, "position"); + mUvsLocation = glGetAttribLocation(mProgramId, "uvs"); + mRadiusLocation = glGetAttribLocation(mProgramId, "radius"); + mFillColourLocation = glGetAttribLocation(mProgramId, "fillColor"); + mOutlineColourLocation = glGetAttribLocation(mProgramId, "outlineColor"); + + mProjectionLocation = glGetUniformLocation(mProgramId, "projection"); + mModelViewLocation = glGetUniformLocation(mProgramId, "modelView"); + + glEnable(GL_DEPTH_TEST); + glViewport(0, 0, mWidth, mHeight); + + glGenBuffers(1, &mIndexBufferId); + glGenBuffers(1, &mVertexBufferId); +} + +void PhysicsDebugRenderer::UpdateWindowSize(Dali::Vector2 size) +{ + mWidth = size.width; + mHeight = size.height; +} + +void PhysicsDebugRenderer::PrepareShader() +{ + static const char glVertexShader[] = + "#version 300 es\n" + "in vec2 position;\n" + "in vec2 uvs;\n" + "in float radius;\n" + "in vec4 fillColor;\n" + "in vec4 outlineColor;\n" + "out vec2 v_uvs;\n" + "out vec4 v_fill;\n" + "out vec4 v_outline;\n" + "uniform mat4 projection;\n" + "uniform mat4 modelView;\n" + "void main()\n" + "{\n" + " gl_Position = projection * modelView * vec4(position.xy+radius*uvs, 0.0, 1.0);\n" + " v_uvs=uvs;\n" + " v_fill = fillColor;\n" + " v_fill.rgb *= v_fill.a;\n" + " v_outline = outlineColor;\n" + " v_outline.a *= v_outline.a;\n" + "}\n"; + + static const char glFragmentShader[] = + "#version 300 es\n" + "precision mediump float;\n" + "in vec2 v_uvs;\n" + "in vec4 v_fill;\n" + "in vec4 v_outline;\n" + "out vec4 fragColor;\n" + "void main()\n" + "{\n" + " float len=length(v_uvs);\n" + " float fw = length(vec2(dFdx(len), dFdy(len)));\n" + " float mask=smoothstep(-1.0, fw-1.0, -len);\n" + " float outline=1.0-fw;\n" + " float outline_mask=smoothstep(outline-fw, outline, len);\n" + " vec4 color = v_fill + (v_outline - v_fill*v_outline.a)*outline_mask;\n" + " fragColor = color*mask;\n" + "}\n"; + + mProgramId = CreateProgram(glVertexShader, glFragmentShader); +} + +void PhysicsDebugRenderer::RenderLines(const Dali::RenderCallbackInput& input) +{ + mModelViewMatrix.SetIdentity(); + mProjectionMatrix = input.projection; + + Matrix::Multiply(mModelViewMatrix, mModelViewMatrix, input.view); + glUseProgram(mProgramId); + + // In theory, input.clippingBox should tell us the actor position in clip-space. + // But, it appears to be bugged. + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBufferId); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, mIndices.size() * sizeof(uint16_t), &mIndices[0], GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, mVertexBufferId); + glBufferData(GL_ARRAY_BUFFER, mVertices.size() * sizeof(Vertex), &mVertices[0], GL_STATIC_DRAW); + + GLint stride = 52; // 4*(2 + 2 + 1 + 4 + 4) = 4*13=52 + glVertexAttribPointer(mPositionLocation, 2, GL_FLOAT, GL_FALSE, stride, 0); + glEnableVertexAttribArray(mPositionLocation); + + glVertexAttribPointer(mUvsLocation, 2, GL_FLOAT, GL_FALSE, stride, (const void*)8); + glEnableVertexAttribArray(mUvsLocation); + + glVertexAttribPointer(mRadiusLocation, 1, GL_FLOAT, GL_FALSE, stride, (const void*)16); + glEnableVertexAttribArray(mRadiusLocation); + + glVertexAttribPointer(mFillColourLocation, 4, GL_FLOAT, GL_FALSE, stride, reinterpret_cast(20)); + glEnableVertexAttribArray(mFillColourLocation); + glVertexAttribPointer(mOutlineColourLocation, 4, GL_FLOAT, GL_FALSE, stride, reinterpret_cast(36)); + glEnableVertexAttribArray(mOutlineColourLocation); + + glUniformMatrix4fv(mProjectionLocation, 1, GL_FALSE, mProjectionMatrix.AsFloat()); + glUniformMatrix4fv(mModelViewLocation, 1, GL_FALSE, mModelViewMatrix.AsFloat()); + + glDrawElements(GL_TRIANGLES, mIndices.size(), GL_UNSIGNED_SHORT, 0); + mIndices.clear(); + mVertices.clear(); +} + +PhysicsDebugRenderer::Vertex* PhysicsDebugRenderer::PushVertices(uint32_t vertexCount, uint32_t indexCount, const uint16_t* indices) +{ + auto base = mVertices.size(); + mVertices.resize(mVertices.size() + vertexCount); + mIndices.reserve(mIndices.size() + indexCount); + for(uint32_t i = 0; i < indexCount; ++i) + { + mIndices.push_back(base + indices[i]); + } + + return &mVertices[base]; +} + +PhysicsDebugRenderer::Vertex PhysicsDebugRenderer::MakeVertex(cpVect pos, float u, float v, float r, Vector4 fill, Vector4 outline) +{ + auto daliPos = mAdaptor.TranslateFromPhysicsSpace(Vector3((float)pos.x, (float)pos.y, 0.0f)); + return Vertex{Vector2(daliPos.x, daliPos.y), Vector2(u, v), r, fill, outline}; +} + +void PhysicsDebugRenderer::DrawCircle(cpVect pos, cpFloat angle, cpFloat radius, cpSpaceDebugColor outlineColor, cpSpaceDebugColor fillColor) +{ + float r = (float)radius + mPointLineScale; + Vector4 fill(fillColor.r, fillColor.g, fillColor.b, fillColor.a); + Vector4 outline(outlineColor.r, outlineColor.g, outlineColor.b, outlineColor.a); + static const uint16_t indices[] = {0, 1, 2, 0, 2, 3}; + + Vertex* vertices = PushVertices(4, 6, indices); + + vertices[0] = MakeVertex(pos, -1, -1, r, fill, outline); + vertices[1] = MakeVertex(pos, -1, 1, r, fill, outline); + vertices[2] = MakeVertex(pos, 1, 1, r, fill, outline); + vertices[3] = MakeVertex(pos, 1, -1, r, fill, outline); + + DrawSegment(pos, cpvadd(pos, cpvmult(cpvforangle(angle), 0.75f * radius)), outlineColor); +} + +void PhysicsDebugRenderer::DrawSegment(cpVect a, cpVect b, cpSpaceDebugColor color) +{ + DrawFatSegment(a, b, 0.0f, color, color); +} + +void PhysicsDebugRenderer::DrawFatSegment(cpVect a, cpVect b, cpFloat radius, cpSpaceDebugColor outlineColor, cpSpaceDebugColor fillColor) +{ + static const uint16_t indices[] = {0, 1, 2, 1, 2, 3, 2, 3, 4, 3, 4, 5, 4, 5, 6, 5, 6, 7}; + Vertex* vertices = PushVertices(8, 18, indices); + + cpVect t = cpvnormalize(cpvsub(b, a)); + + float r = (float)radius * mPointLineScale; + Vector4 fill(fillColor.r, fillColor.g, fillColor.b, fillColor.a); + Vector4 outline(outlineColor.r, outlineColor.g, outlineColor.b, outlineColor.a); + + vertices[0] = MakeVertex(a, (-t.x + t.y), (-t.x - t.y), r, fill, outline); + vertices[1] = MakeVertex(a, (-t.x - t.y), (+t.x - t.y), r, fill, outline); + vertices[2] = MakeVertex(a, (-0.0 + t.y), (-t.x + 0.0), r, fill, outline); + vertices[3] = MakeVertex(a, (-0.0 - t.y), (+t.x + 0.0), r, fill, outline); + vertices[4] = MakeVertex(a, (+0.0 + t.y), (-t.x - 0.0), r, fill, outline); + vertices[5] = MakeVertex(a, (+0.0 - t.y), (+t.x - 0.0), r, fill, outline); + vertices[6] = MakeVertex(a, (+t.x + t.y), (-t.x + t.y), r, fill, outline); + vertices[7] = MakeVertex(a, (+t.x - t.y), (+t.x + t.y), r, fill, outline); +} + +void PhysicsDebugRenderer::DrawPolygon(int count, const cpVect* verts, cpFloat radius, cpSpaceDebugColor outlineColor, cpSpaceDebugColor fillColor) +{ + Vector4 fill(fillColor.r, fillColor.g, fillColor.b, fillColor.a); + Vector4 outline(outlineColor.r, outlineColor.g, outlineColor.b, outlineColor.a); + + std::vector indices; + for(int i = 0; i < count - 2; i++) + { + indices.push_back(0); + indices.push_back(4 * (i + 1)); + indices.push_back(4 * (i + 2)); + } + + // Polygon outline triangles. + for(int i0 = 0; i0 < count; i0++) + { + int i1 = (i0 + 1) % count; + indices.push_back(4 * i0 + 0); + indices.push_back(4 * i0 + 1); + indices.push_back(4 * i0 + 2); + indices.push_back(4 * i0 + 0); + indices.push_back(4 * i0 + 2); + indices.push_back(4 * i0 + 3); + indices.push_back(4 * i0 + 0); + indices.push_back(4 * i0 + 3); + indices.push_back(4 * i1 + 0); + indices.push_back(4 * i0 + 3); + indices.push_back(4 * i1 + 0); + indices.push_back(4 * i1 + 1); + } + + float inset = (float)-cpfmax(0, 2 * mPointLineScale - radius); + float outset = (float)radius + mPointLineScale; + float r = outset - inset; + + Vertex* vertices = PushVertices(4 * count, 3 * (5 * count - 2), &indices[0]); + for(int i = 0; i < count; i++) + { + cpVect v0 = verts[i]; + cpVect v_prev = verts[(i + (count - 1)) % count]; + cpVect v_next = verts[(i + (count + 1)) % count]; + + cpVect n1 = cpvnormalize(cpvrperp(cpvsub(v0, v_prev))); + cpVect n2 = cpvnormalize(cpvrperp(cpvsub(v_next, v0))); + cpVect of = cpvmult(cpvadd(n1, n2), 1.0 / (cpvdot(n1, n2) + 1.0f)); + cpVect v = cpvadd(v0, cpvmult(of, inset)); + + vertices[4 * i + 0] = MakeVertex(v, 0.0f, 0.0f, 0.0f, fill, outline); + vertices[4 * i + 1] = MakeVertex(v, (float)n1.x, (float)n1.y, r, fill, outline); + vertices[4 * i + 2] = MakeVertex(v, (float)of.x, (float)of.y, r, fill, outline); + vertices[4 * i + 3] = MakeVertex(v, (float)n2.x, (float)n2.y, r, fill, outline); + } +} + +void PhysicsDebugRenderer::DrawDot(cpFloat size, cpVect pos, cpSpaceDebugColor color) +{ + float r = (float)(size * 0.5f * mPointLineScale); + Vector4 fill(color.r, color.g, color.b, color.a); + static const uint16_t indices[] = {0, 1, 2, 0, 2, 3}; + Vertex* vertex = PushVertices(4, 6, indices); + vertex[0] = MakeVertex(pos, -1, -1, r, fill, fill); + vertex[1] = MakeVertex(pos, -1, 1, r, fill, fill); + vertex[2] = MakeVertex(pos, 1, 1, r, fill, fill); + vertex[3] = MakeVertex(pos, 1, -1, r, fill, fill); +} + +cpSpaceDebugColor PhysicsDebugRenderer::DrawColorForShape(cpShape* shape) +{ + static cpSpaceDebugColor Colors[] = { + {0xb5 / 255.0f, 0x89 / 255.0f, 0x00 / 255.0f, 1.0f}, + {0xcb / 255.0f, 0x4b / 255.0f, 0x16 / 255.0f, 1.0f}, + {0xdc / 255.0f, 0x32 / 255.0f, 0x2f / 255.0f, 1.0f}, + {0xd3 / 255.0f, 0x36 / 255.0f, 0x82 / 255.0f, 1.0f}, + {0x6c / 255.0f, 0x71 / 255.0f, 0xc4 / 255.0f, 1.0f}, + {0x26 / 255.0f, 0x8b / 255.0f, 0xd2 / 255.0f, 1.0f}, + {0x2a / 255.0f, 0xa1 / 255.0f, 0x98 / 255.0f, 1.0f}, + {0x85 / 255.0f, 0x99 / 255.0f, 0x00 / 255.0f, 1.0f}, + }; + + if(cpShapeGetSensor(shape)) + { + return cpSpaceDebugColor{1.0f, 1.0f, 1.0f, 0.1f}; + } + else + { + cpBody* body = cpShapeGetBody(shape); + + if(cpBodyIsSleeping(body)) + { + return cpSpaceDebugColor{0x58 / 255.0f, 0x6e / 255.0f, 0x75 / 255.0f, 1.0f}; + } + else if(cpBodyIsSleepThresholdExceeded(body, shape)) + { + return cpSpaceDebugColor{0x93 / 255.0f, 0xa1 / 255.0f, 0xa1 / 255.0f, 1.0f}; + } + else + { + uint32_t val = (uint32_t)cpShapeGetHashId(shape); + + // scramble the bits up using Robert Jenkins' 32 bit integer hash function + val = (val + 0x7ed55d16) + (val << 12); + val = (val ^ 0xc761c23c) ^ (val >> 19); + val = (val + 0x165667b1) + (val << 5); + val = (val + 0xd3a2646c) ^ (val << 9); + val = (val + 0xfd7046c5) + (val << 3); + val = (val ^ 0xb55a4f09) ^ (val >> 16); + + return Colors[val & 0x7]; + } + } + + return cpSpaceDebugColor{1.0f, 1.0f, 1.0f, 1.0f}; +} + +} // namespace Dali::Toolkit::Physics::Internal diff --git a/dali-physics/internal/chipmunk-impl/chipmunk-physics-debug-renderer.h b/dali-physics/internal/chipmunk-impl/chipmunk-physics-debug-renderer.h new file mode 100644 index 0000000..2a4335b --- /dev/null +++ b/dali-physics/internal/chipmunk-impl/chipmunk-physics-debug-renderer.h @@ -0,0 +1,126 @@ +#pragma once + +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd. + * + * Licensed 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 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +using Dali::Actor; +using Dali::CameraActor; +using Dali::Geometry; +using Dali::Renderer; +using Dali::Shader; +using Dali::TextureSet; + +namespace Dali::Toolkit::Physics::Internal +{ +class PhysicsAdaptor; + +class PhysicsDebugRenderer +{ +public: + // Creates and initializes a new renderer + static std::unique_ptr New(uint32_t width, uint32_t height, Dali::CameraActor camera, PhysicsAdaptor* adaptor); + /** + * Get the callback (for actor creation) + */ + + std::unique_ptr& GetCallback() + { + return mRenderCallback; + } + + void UpdateWindowSize(Dali::Vector2 size); + + /** + * Constructor. + * @param[in] width Width of the renderer - viewport + * @param[in] height Height of the renderer - viewport + */ + PhysicsDebugRenderer(uint32_t width, uint32_t height, Dali::CameraActor camera, PhysicsAdaptor* adaptor); + + /** + * Get the drawing options struct ( construct only ) + */ + const cpSpaceDebugDrawOptions& GetDebugDrawOptions() + { + return mDebugDrawOptions; + } + + struct Vertex + { + Dali::Vector2 position; + Dali::Vector2 uvs; + float radius; + Dali::Vector4 fillColor; + Dali::Vector4 outlineColor; + }; + +public: // Debug functions (Creates indices & verts) + void DrawCircle(cpVect pos, cpFloat angle, cpFloat radius, cpSpaceDebugColor outlineColor, cpSpaceDebugColor fillColor); + void DrawSegment(cpVect a, cpVect b, cpSpaceDebugColor color); + void DrawFatSegment(cpVect a, cpVect b, cpFloat radius, cpSpaceDebugColor outlineColor, cpSpaceDebugColor fillColor); + void DrawPolygon(int count, const cpVect* verts, cpFloat radius, cpSpaceDebugColor outlineColor, cpSpaceDebugColor fillColor); + void DrawDot(cpFloat size, cpVect pos, cpSpaceDebugColor color); + cpSpaceDebugColor DrawColorForShape(cpShape* shape); + +private: + bool OnRender(const Dali::RenderCallbackInput& input); + void Setup(); + void PrepareShader(); + void RenderLines(const Dali::RenderCallbackInput& input); + + Vertex* PushVertices(uint32_t vertexCount, uint32_t indexCount, const uint16_t* indices); + Vertex MakeVertex(cpVect pos, float u, float v, float r, Vector4 fill, Vector4 outline); + +private: + CameraActor mCamera; + cpSpaceDebugDrawOptions mDebugDrawOptions; + Renderer mDebugRenderer; + std::unique_ptr mRenderCallback; + + enum class State + { + INIT, + RENDER + } mState{State::INIT}; + + std::vector mVertices; + std::vector mIndices; + + Dali::Matrix mModelViewMatrix; + Dali::Matrix mViewMatrix; + Dali::Matrix mProjectionMatrix; + int mWidth; + int mHeight; + PhysicsAdaptor& mAdaptor; + + float mPointLineScale{2.0f}; + GLint mPositionLocation; + GLint mUvsLocation; + GLint mRadiusLocation; + GLint mFillColourLocation; + GLint mOutlineColourLocation; + GLint mProjectionLocation; + GLint mModelViewLocation; + GLuint mIndexBufferId; + GLuint mVertexBufferId; + GLuint mProgramId; +}; + +} // namespace Dali::Toolkit::Physics::Internal diff --git a/dali-physics/internal/chipmunk-impl/chipmunk-physics-world-impl.cpp b/dali-physics/internal/chipmunk-impl/chipmunk-physics-world-impl.cpp index 6157780..7423edd 100644 --- a/dali-physics/internal/chipmunk-impl/chipmunk-physics-world-impl.cpp +++ b/dali-physics/internal/chipmunk-impl/chipmunk-physics-world-impl.cpp @@ -26,9 +26,6 @@ namespace { -#define GRABBABLE_MASK_BIT (1u << 31) -cpShapeFilter GRAB_FILTER = {CP_NO_GROUP, GRABBABLE_MASK_BIT, GRABBABLE_MASK_BIT}; - inline cpVect ConvertVector(Dali::Vector3 vector) { return cpv(vector.x, vector.y); @@ -115,14 +112,23 @@ void ChipmunkPhysicsWorld::Integrate(float timestep) { cpSpaceStep(mSpace, timestep); } + + if(mPhysicsDebugState == Physics::PhysicsAdaptor::DebugState::ON) + { + if(mDebugRenderer) + { + cpSpaceDebugDraw(mSpace, const_cast(&mDebugRenderer->GetDebugDrawOptions())); + } + } } -Dali::Any ChipmunkPhysicsWorld::HitTest(Dali::Vector3 rayFromWorld, Dali::Vector3 rayToWorld, Dali::Vector3& localPivot, float& distanceFromCamera) +Dali::Any ChipmunkPhysicsWorld::HitTest(Dali::Vector3 rayFromWorld, Dali::Vector3 rayToWorld, Dali::Any nativeFilter, Dali::Vector3& localPivot, float& distanceFromCamera) { cpVect spacePosition = cpv(rayFromWorld.x, rayFromWorld.y); cpFloat radius = 5.0f; cpPointQueryInfo info = {0}; - cpShape* shape = cpSpacePointQueryNearest(mSpace, spacePosition, radius, GRAB_FILTER, &info); + cpShapeFilter filter = nativeFilter.Get(); + cpShape* shape = cpSpacePointQueryNearest(mSpace, spacePosition, radius, filter, &info); cpBody* hitBody{nullptr}; if(shape && cpBodyGetMass(cpShapeGetBody(shape)) < INFINITY) diff --git a/dali-physics/internal/chipmunk-impl/chipmunk-physics-world-impl.h b/dali-physics/internal/chipmunk-impl/chipmunk-physics-world-impl.h index fbb2e03..10ba5e8 100644 --- a/dali-physics/internal/chipmunk-impl/chipmunk-physics-world-impl.h +++ b/dali-physics/internal/chipmunk-impl/chipmunk-physics-world-impl.h @@ -19,6 +19,7 @@ #include #include +#include #include namespace Dali::Toolkit::Physics::Internal @@ -37,10 +38,29 @@ public: void Integrate(float timestep) override; - Dali::Any HitTest(Dali::Vector3 rayFromWorld, Dali::Vector3 rayToWorld, Dali::Vector3& localPivot, float& distanceFromCamera) override; + Dali::Any HitTest(Dali::Vector3 rayFromWorld, Dali::Vector3 rayToWorld, Dali::Any nativeFilter, Dali::Vector3& localPivot, float& distanceFromCamera) override; + + /** + * Set the debug renderer. PhysicsWorld will take ownership + */ + void SetDebugRenderer(PhysicsDebugRenderer* renderer) + { + mDebugRenderer.reset(renderer); + } + + PhysicsDebugRenderer& GetDebugRenderer() + { + return *mDebugRenderer.get(); + } + + bool HasDebugRenderer() + { + return mDebugRenderer.get() != nullptr; + } private: - cpSpace* mSpace{nullptr}; + cpSpace* mSpace{nullptr}; + std::unique_ptr mDebugRenderer; }; } //namespace Dali::Toolkit::Physics::Internal diff --git a/dali-physics/internal/file.list b/dali-physics/internal/file.list index 87c7cb2..19137dd 100644 --- a/dali-physics/internal/file.list +++ b/dali-physics/internal/file.list @@ -5,6 +5,7 @@ set(physics3d_internal_dir ${physics_internal_dir}/bullet-impl) set(physics2d_src_files ${physics_src_files} ${physics2d_internal_dir}/chipmunk-physics-actor-impl.cpp ${physics2d_internal_dir}/chipmunk-physics-adaptor-impl.cpp + ${physics2d_internal_dir}/chipmunk-physics-debug-renderer.cpp ${physics2d_internal_dir}/chipmunk-physics-world-impl.cpp ${physics_internal_dir}/physics-adaptor-impl.cpp ${physics_internal_dir}/physics-world-impl.cpp diff --git a/dali-physics/internal/physics-world-impl.cpp b/dali-physics/internal/physics-world-impl.cpp index cd43633..b0ca04d 100644 --- a/dali-physics/internal/physics-world-impl.cpp +++ b/dali-physics/internal/physics-world-impl.cpp @@ -96,11 +96,11 @@ bool PhysicsWorld::OnUpdate(Dali::UpdateProxy& updateProxy, float elapsedSeconds if(mNotifySyncPoint != Dali::UpdateProxy::INVALID_SYNC && mNotifySyncPoint == updateProxy.PopSyncPoint()) { - do + while(!commandQueue.empty()) { commandQueue.front()(); // Execute the queued methods commandQueue.pop(); - } while(!commandQueue.empty()); + } mNotifySyncPoint = Dali::UpdateProxy::INVALID_SYNC; } diff --git a/dali-physics/internal/physics-world-impl.h b/dali-physics/internal/physics-world-impl.h index d6e1097..b1c9460 100644 --- a/dali-physics/internal/physics-world-impl.h +++ b/dali-physics/internal/physics-world-impl.h @@ -111,11 +111,12 @@ public: * * @param[in] rayFromWorld The origin in physics world space * @param[in] rayToWorld A point along the direction on the far side of the physics world + * @param[in] nativeFilter a native body / shape filter * @param[out] localPivot The hit point local to the body * @param[out] distanceFromCamera The distance of the pick point from the camera * @return Empty value if no dynamic body found, otherwise a valid ptr to the hit body. */ - virtual Dali::Any HitTest(Dali::Vector3 rayFromWorld, Dali::Vector3 rayToWorld, Dali::Vector3& localPivot, float& distanceFromCamera) = 0; + virtual Dali::Any HitTest(Dali::Vector3 rayFromWorld, Dali::Vector3 rayToWorld, Dali::Any nativeFilter, Dali::Vector3& localPivot, float& distanceFromCamera) = 0; /** * @copydoc Dali::Toolkit::Physics::PhysicsAdaptor::SetIntegrationState diff --git a/dali-physics/public-api/physics-adaptor.h b/dali-physics/public-api/physics-adaptor.h index 41c7da7..0bdd0c0 100644 --- a/dali-physics/public-api/physics-adaptor.h +++ b/dali-physics/public-api/physics-adaptor.h @@ -98,11 +98,12 @@ public: * @SINCE_2_2.43 * @param[in] rayFromWorld The origin in physics world space * @param[in] rayToWorld A point along the direction on the far side of the physics world + * @param[in] nativeFilter a native body / shape filter * @param[out] localPivot The hit point local to the body * @param[out] distanceFromCamera The distance of the pick point from the camera * @return Empty value if no dynamic body found, otherwise a valid ptr to the hit body. */ - Dali::Any HitTest(Dali::Vector3 rayFromWorld, Dali::Vector3 rayToWorld, Dali::Vector3& localPivot, float& distanceFromCamera); + Dali::Any HitTest(Dali::Vector3 rayFromWorld, Dali::Vector3 rayToWorld, Dali::Any nativeFilter, Dali::Vector3& localPivot, float& distanceFromCamera); // Not copyable ScopedPhysicsAccessor(ScopedPhysicsAccessor&) = delete; @@ -418,7 +419,8 @@ public: * btVector3 rayFromWorld, rayToWorld; * physicsAdaptor.BuildPickingRay(origin, direction, rayFromWorld, rayToWorld); * auto scopedAccessor = physicsAdaptor.GetPhysicsAccessor(); - * body = scopedAccessor->Get().HitTest(rayFromWorld, rayToWorld, ..); + * Dali::Any nativeFilter; + * body = scopedAccessor->Get().HitTest(rayFromWorld, rayToWorld, nativeFilter, ..); * } */ void BuildPickingRay(Dali::Vector3 origin, Dali::Vector3 direction, Dali::Vector3& rayFromWorld, Dali::Vector3& rayToWorld); diff --git a/dali-physics/public-api/scoped-physics-accessor.cpp b/dali-physics/public-api/scoped-physics-accessor.cpp index 1f4b6e8..1fad04c 100644 --- a/dali-physics/public-api/scoped-physics-accessor.cpp +++ b/dali-physics/public-api/scoped-physics-accessor.cpp @@ -52,9 +52,9 @@ Dali::Any PhysicsAdaptor::ScopedPhysicsAccessor::GetNative() } Dali::Any PhysicsAdaptor::ScopedPhysicsAccessor::HitTest( - Dali::Vector3 rayFromWorld, Dali::Vector3 rayToWorld, Dali::Vector3& localPivot, float& distanceFromCamera) + Dali::Vector3 rayFromWorld, Dali::Vector3 rayToWorld, Dali::Any nativeFilter, Dali::Vector3& localPivot, float& distanceFromCamera) { - return mImpl->mPhysicsWorld.HitTest(rayFromWorld, rayToWorld, localPivot, distanceFromCamera); + return mImpl->mPhysicsWorld.HitTest(rayFromWorld, rayToWorld, nativeFilter, localPivot, distanceFromCamera); } } // namespace Dali::Toolkit::Physics diff --git a/dali-physics/third-party/chipmunk2d/include/chipmunk/cpBody.h b/dali-physics/third-party/chipmunk2d/include/chipmunk/cpBody.h index 7e6943d..8e46cc3 100644 --- a/dali-physics/third-party/chipmunk2d/include/chipmunk/cpBody.h +++ b/dali-physics/third-party/chipmunk2d/include/chipmunk/cpBody.h @@ -76,6 +76,9 @@ CP_EXPORT void cpBodySleepWithGroup(cpBody *body, cpBody *group); /// Returns true if the body is sleeping. CP_EXPORT cpBool cpBodyIsSleeping(const cpBody *body); +// Returns true if the body is exceeding the sleep threshold +CP_EXPORT cpBool cpBodyIsSleepThresholdExceeded(const cpBody *body, const cpShape *shape); + /// Get the type of the body. CP_EXPORT cpBodyType cpBodyGetType(cpBody *body); /// Set the type of the body. diff --git a/dali-physics/third-party/chipmunk2d/include/chipmunk/cpShape.h b/dali-physics/third-party/chipmunk2d/include/chipmunk/cpShape.h index c78ed05..2b04062 100644 --- a/dali-physics/third-party/chipmunk2d/include/chipmunk/cpShape.h +++ b/dali-physics/third-party/chipmunk2d/include/chipmunk/cpShape.h @@ -79,6 +79,9 @@ CP_EXPORT void cpShapeDestroy(cpShape *shape); /// Destroy and Free a shape. CP_EXPORT void cpShapeFree(cpShape *shape); +/// Get the hash ID of the shape +CP_EXPORT cpHashValue cpShapeGetHashId(cpShape* shape); + /// Update, cache and return the bounding box of a shape based on the body it's attached to. CP_EXPORT cpBB cpShapeCacheBB(cpShape *shape); /// Update, cache and return the bounding box of a shape with an explicit transformation. diff --git a/dali-physics/third-party/chipmunk2d/src/CMakeLists.txt b/dali-physics/third-party/chipmunk2d/src/CMakeLists.txt index 34b30eb..55f7954 100644 --- a/dali-physics/third-party/chipmunk2d/src/CMakeLists.txt +++ b/dali-physics/third-party/chipmunk2d/src/CMakeLists.txt @@ -39,6 +39,12 @@ if(ANDROID) FIND_LIBRARY(LOGLIB log) endif(ANDROID) +# If you want to reduce the size of the library slightly, uncomment this section +# +#if(NOT ENABLE_DEBUG) +# add_definitions( "-DCP_SPACE_DISABLE_DEBUG_API") +#endif() + if(BUILD_SHARED) add_library(chipmunk SHARED ${chipmunk_source_files} @@ -117,4 +123,3 @@ if (ENABLE_PKG_CONFIGURE) DESTINATION ${LIB_DIR}/pkgconfig ) endif() - diff --git a/dali-physics/third-party/chipmunk2d/src/cpBody.c b/dali-physics/third-party/chipmunk2d/src/cpBody.c index 8ad2bc9..e5caaf9 100644 --- a/dali-physics/third-party/chipmunk2d/src/cpBody.c +++ b/dali-physics/third-party/chipmunk2d/src/cpBody.c @@ -133,6 +133,12 @@ cpBodyIsSleeping(const cpBody *body) return (body->sleeping.root != ((cpBody*)0)); } +cpBool +cpBodyIsSleepThresholdExceeded(const cpBody *body, const cpShape *shape) +{ + return body->sleeping.idleTime > shape->space->sleepTimeThreshold; +} + cpBodyType cpBodyGetType(cpBody *body) { diff --git a/dali-physics/third-party/chipmunk2d/src/cpShape.c b/dali-physics/third-party/chipmunk2d/src/cpShape.c index 513b535..942bfff 100644 --- a/dali-physics/third-party/chipmunk2d/src/cpShape.c +++ b/dali-physics/third-party/chipmunk2d/src/cpShape.c @@ -109,6 +109,12 @@ cpFloat cpShapeGetMoment(cpShape *shape){ return shape->massInfo.m*shape->massIn cpFloat cpShapeGetArea(cpShape *shape){ return shape->massInfo.area; } cpVect cpShapeGetCenterOfGravity(cpShape *shape) { return shape->massInfo.cog; } +cpHashValue +cpShapeGetHashId(cpShape* shape) +{ + return shape->hashid; +} + cpBB cpShapeGetBB(const cpShape *shape) { diff --git a/dali-toolkit/public-api/dali-toolkit-version.cpp b/dali-toolkit/public-api/dali-toolkit-version.cpp index 7e46322..faa354c 100644 --- a/dali-toolkit/public-api/dali-toolkit-version.cpp +++ b/dali-toolkit/public-api/dali-toolkit-version.cpp @@ -29,7 +29,7 @@ namespace Toolkit { const unsigned int TOOLKIT_MAJOR_VERSION = 2; const unsigned int TOOLKIT_MINOR_VERSION = 2; -const unsigned int TOOLKIT_MICRO_VERSION = 42; +const unsigned int TOOLKIT_MICRO_VERSION = 43; const char* const TOOLKIT_BUILD_DATE = __DATE__ " " __TIME__; #ifdef DEBUG_ENABLED diff --git a/packaging/dali-toolkit.spec b/packaging/dali-toolkit.spec index 48fab3d..da90ed7 100644 --- a/packaging/dali-toolkit.spec +++ b/packaging/dali-toolkit.spec @@ -1,6 +1,6 @@ Name: dali2-toolkit Summary: Dali 3D engine Toolkit -Version: 2.2.42 +Version: 2.2.43 Release: 1 Group: System/Libraries License: Apache-2.0 and BSD-3-Clause and MIT