2 * Copyright (c) 2023 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <dali-physics/internal/chipmunk-impl/chipmunk-physics-world-impl.h>
23 #include <dali/dali.h>
24 #include <dali/devel-api/common/stage-devel.h>
25 #include <dali/devel-api/update/frame-callback-interface.h>
29 inline cpVect ConvertVector(Dali::Vector3 vector)
31 return cpv(vector.x, vector.y);
34 static void ShapeFreeWrap(cpSpace* space, cpShape* shape, void* unused)
36 cpSpaceRemoveShape(space, shape);
40 static void PostShapeFree(cpShape* shape, cpSpace* space)
42 cpSpaceAddPostStepCallback(space, (cpPostStepFunc)ShapeFreeWrap, shape, NULL);
45 static void ConstraintFreeWrap(cpSpace* space, cpConstraint* constraint, void* unused)
47 cpSpaceRemoveConstraint(space, constraint);
48 cpConstraintFree(constraint);
51 static void PostConstraintFree(cpConstraint* constraint, cpSpace* space)
53 cpSpaceAddPostStepCallback(space, (cpPostStepFunc)ConstraintFreeWrap, constraint, NULL);
56 static void BodyFreeWrap(cpSpace* space, cpBody* body, void* unused)
58 cpSpaceRemoveBody(space, body);
62 static void PostBodyFree(cpBody* body, cpSpace* space)
64 cpSpaceAddPostStepCallback(space, (cpPostStepFunc)BodyFreeWrap, body, NULL);
68 namespace Dali::Toolkit::Physics::Internal
70 std::unique_ptr<PhysicsWorld> ChipmunkPhysicsWorld::New(Dali::Actor rootActor, Dali::CallbackBase* updateCallback)
72 std::unique_ptr<ChipmunkPhysicsWorld> world = std::make_unique<ChipmunkPhysicsWorld>(rootActor, updateCallback);
77 ChipmunkPhysicsWorld::ChipmunkPhysicsWorld(Dali::Actor rootActor, Dali::CallbackBase* updateCallback)
78 : PhysicsWorld(rootActor, updateCallback)
82 void ChipmunkPhysicsWorld::OnInitialize(/*void* dynamicsWorld*/)
84 // @todo Should enable developer to optionally supply their own created cpSpace.
85 mSpace = cpSpaceNew();
86 cpSpaceSetIterations(mSpace, 30);
87 cpSpaceSetSleepTimeThreshold(mSpace, 0.5f);
88 cpSpaceSetGravity(mSpace, cpv(0, -200));
91 ChipmunkPhysicsWorld::~ChipmunkPhysicsWorld()
93 Dali::Mutex::ScopedLock lock(mMutex);
96 cpSpaceEachShape(mSpace, (cpSpaceShapeIteratorFunc)PostShapeFree, mSpace);
97 cpSpaceEachConstraint(mSpace, (cpSpaceConstraintIteratorFunc)PostConstraintFree, mSpace);
98 cpSpaceEachBody(mSpace, (cpSpaceBodyIteratorFunc)PostBodyFree, mSpace);
104 Dali::Any ChipmunkPhysicsWorld::GetNative()
109 void ChipmunkPhysicsWorld::Integrate(float timestep)
111 if(mPhysicsIntegrateState == Physics::PhysicsAdaptor::IntegrationState::ON)
113 cpSpaceStep(mSpace, timestep);
116 if(mPhysicsDebugState == Physics::PhysicsAdaptor::DebugState::ON)
120 cpSpaceDebugDraw(mSpace, const_cast<cpSpaceDebugDrawOptions*>(&mDebugRenderer->GetDebugDrawOptions()));
125 Dali::Any ChipmunkPhysicsWorld::HitTest(Dali::Vector3 rayFromWorld, Dali::Vector3 rayToWorld, Dali::Any nativeFilter, Dali::Vector3& localPivot, float& distanceFromCamera)
127 cpVect spacePosition = cpv(rayFromWorld.x, rayFromWorld.y);
128 cpFloat radius = 5.0f;
129 cpPointQueryInfo info = {0};
130 cpShapeFilter filter = nativeFilter.Get<cpShapeFilter>();
131 cpShape* shape = cpSpacePointQueryNearest(mSpace, spacePosition, radius, filter, &info);
132 cpBody* hitBody{nullptr};
134 if(shape && cpBodyGetMass(cpShapeGetBody(shape)) < INFINITY)
136 // Use the closest point on the surface if the click is outside the shape.
137 cpVect nearest = (info.distance > 0.0f ? info.point : spacePosition);
138 hitBody = cpShapeGetBody(shape);
139 cpVect local = cpBodyWorldToLocal(hitBody, nearest);
140 localPivot.x = local.x;
141 localPivot.y = local.y;
146 // Only set non-null ptr into bodyPtr, leave empty if null.
154 } // namespace Dali::Toolkit::Physics::Internal