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()
96 cpSpaceEachShape(mSpace, (cpSpaceShapeIteratorFunc)PostShapeFree, mSpace);
97 cpSpaceEachConstraint(mSpace, (cpSpaceConstraintIteratorFunc)PostConstraintFree, mSpace);
98 cpSpaceEachBody(mSpace, (cpSpaceBodyIteratorFunc)PostBodyFree, mSpace);
105 Dali::Any ChipmunkPhysicsWorld::GetNative()
110 void ChipmunkPhysicsWorld::Integrate(float timestep)
112 if(mPhysicsIntegrateState == Physics::PhysicsAdaptor::IntegrationState::ON)
114 cpSpaceStep(mSpace, timestep);
117 if(mPhysicsDebugState == Physics::PhysicsAdaptor::DebugState::ON)
121 cpSpaceDebugDraw(mSpace, const_cast<cpSpaceDebugDrawOptions*>(&mDebugRenderer->GetDebugDrawOptions()));
126 Dali::Any ChipmunkPhysicsWorld::HitTest(Dali::Vector3 rayFromWorld, Dali::Vector3 rayToWorld, Dali::Any nativeFilter, Dali::Vector3& localPivot, float& distanceFromCamera)
128 cpVect spacePosition = cpv(rayFromWorld.x, rayFromWorld.y);
129 cpFloat radius = 5.0f;
130 cpPointQueryInfo info = {0};
131 cpShapeFilter filter = nativeFilter.Get<cpShapeFilter>();
132 cpShape* shape = cpSpacePointQueryNearest(mSpace, spacePosition, radius, filter, &info);
133 cpBody* hitBody{nullptr};
135 if(shape && cpBodyGetMass(cpShapeGetBody(shape)) < INFINITY)
137 // Use the closest point on the surface if the click is outside the shape.
138 cpVect nearest = (info.distance > 0.0f ? info.point : spacePosition);
139 hitBody = cpShapeGetBody(shape);
140 cpVect local = cpBodyWorldToLocal(hitBody, nearest);
141 localPivot.x = local.x;
142 localPivot.y = local.y;
147 // Only set non-null ptr into bodyPtr, leave empty if null.
155 } // namespace Dali::Toolkit::Physics::Internal