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-adaptor-impl.h>
24 #include <dali-physics/internal/chipmunk-impl/chipmunk-physics-world-impl.h>
25 #include <dali/dali.h>
26 #include <dali/integration-api/debug.h>
30 #if defined(DEBUG_ENABLED)
31 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, false, "LOG_PHYSICS");
34 inline cpVect ConvertVector(Dali::Vector3 vector)
36 return cpv(vector.x, vector.y);
41 namespace Dali::Toolkit::Physics::Internal
43 PhysicsAdaptorPtr CreateNewPhysicsAdaptor(const Dali::Matrix& transform, Uint16Pair worldSize)
45 PhysicsAdaptorPtr adaptor(new ChipmunkPhysicsAdaptor());
46 adaptor->Initialize(transform, worldSize);
50 ChipmunkPhysicsAdaptor::ChipmunkPhysicsAdaptor()
55 ChipmunkPhysicsAdaptor::~ChipmunkPhysicsAdaptor()
57 // @todo Ensure physics bodies don't leak
60 void ChipmunkPhysicsAdaptor::OnInitialize(const Dali::Matrix& transform, Uint16Pair worldSize)
62 mTransform = transform;
63 mInverseTransform = transform;
64 mInverseTransform.Invert();
67 mPhysicsWorld = ChipmunkPhysicsWorld::New(mRootActor,
68 Dali::MakeCallback(mSlotDelegate.GetSlot(),
69 &PhysicsAdaptor::OnUpdateActors));
72 Layer ChipmunkPhysicsAdaptor::CreateDebugLayer(Dali::Window window)
77 void ChipmunkPhysicsAdaptor::SetTransformAndSize(const Dali::Matrix& transform, Uint16Pair worldSize)
79 mTransform = transform;
80 mInverseTransform = transform;
81 mInverseTransform.Invert();
84 GetRootActor()[Actor::Property::SIZE] = Vector3(worldSize.GetWidth(), worldSize.GetHeight(), 0);
87 PhysicsActorPtr ChipmunkPhysicsAdaptor::AddActorBody(Dali::Actor actor, Dali::Any body)
89 uint32_t id = static_cast<uint32_t>(actor.GetProperty<int>(Actor::Property::ID));
90 cpBody* cBody = body.Get<cpBody*>();
91 cpBodySetUserData(cBody, this);
93 mPhysicsActors.insert(std::make_pair(id, PhysicsActor::New(actor, body, *this)));
94 actor[Actor::Property::PARENT_ORIGIN] = Dali::ParentOrigin::CENTER;
95 actor[Actor::Property::ANCHOR_POINT] = Dali::AnchorPoint::CENTER;
96 mRootActor.Add(actor);
97 return mPhysicsActors.at(id);
100 void ChipmunkPhysicsAdaptor::RemoveActorBody(PhysicsActor& physicsActor)
102 auto iter = mPhysicsActors.find(physicsActor.GetId());
103 if(iter != mPhysicsActors.end())
105 mPhysicsActors.erase(iter);
107 Dali::Actor actor = mRootActor.FindChildById(physicsActor.GetId());
112 auto body = physicsActor.GetBody();
113 cpBody* cBody = body.Get<cpBody*>();
116 cpBodySetUserData(cBody, nullptr);
120 PhysicsActorPtr ChipmunkPhysicsAdaptor::GetPhysicsActor(Dali::Any body) const
122 cpBody* cBody = body.Get<cpBody*>();
125 return reinterpret_cast<PhysicsActor*>(cpBodyGetUserData(cBody));
127 DALI_LOG_ERROR("Body not found in physics actors");
131 // Convert a position from root actor local space to physics space
132 Vector3 ChipmunkPhysicsAdaptor::TranslateToPhysicsSpace(Vector3 vector) const
134 Vector4 position = mTransform * Vector4(vector.x, vector.y, vector.z, 1.0f);
135 return Vector3(position);
138 // Convert a position from physics space to root actor local space
139 Vector3 ChipmunkPhysicsAdaptor::TranslateFromPhysicsSpace(Vector3 vector) const
141 Vector4 position = mInverseTransform * Vector4(vector.x, vector.y, vector.z, 1.0f);
142 return Vector3(position);
145 Quaternion ChipmunkPhysicsAdaptor::TranslateToPhysicsSpace(Quaternion orientation) const
151 Quaternion ChipmunkPhysicsAdaptor::TranslateFromPhysicsSpace(Quaternion orientation) const
153 // Mirroring conversion is identical in both transforms
154 return TranslateToPhysicsSpace(orientation);
157 // Convert a vector from dali space to physics space
158 Vector3 ChipmunkPhysicsAdaptor::ConvertVectorToPhysicsSpace(Vector3 vector) const
160 Vector4 otherVector(mTransform * Vector4(vector.x, vector.y, vector.z, 0.0f));
161 return Vector3(otherVector);
164 // Convert a vector from physics space to root actor local space
165 Vector3 ChipmunkPhysicsAdaptor::ConvertVectorFromPhysicsSpace(Vector3 vector) const
167 Vector4 otherVector(mInverseTransform * Vector4(vector.x, vector.y, vector.z, 0.0f));
168 return Vector3(otherVector);
171 void ChipmunkPhysicsAdaptor::BuildPickingRay(Vector3 origin, Vector3 direction, Dali::Vector3& rayFromWorld, Dali::Vector3& rayToWorld)
173 rayFromWorld = TranslateToPhysicsSpace(origin);
174 rayToWorld = TranslateToPhysicsSpace(origin); // rayToWorld is identical - there's no depth
177 Vector3 ChipmunkPhysicsAdaptor::ProjectPoint(Vector3 origin, Vector3 direction, float distance)
179 // Ignore direction & distance.
180 return TranslateToPhysicsSpace(origin);
183 } // namespace Dali::Toolkit::Physics::Internal