Commit 606bbd44cf947c8f347e70cddb169d22531638a6
1 parent
08a1f2fb
Add physics demo using chipmunk
Change-Id: I40d9fb813bbb7f6360bf1bbadcff4b976e9c47bb
Showing
17 changed files
with
1245 additions
and
0 deletions
build/tizen/CMakeLists.txt
| ... | ... | @@ -243,6 +243,21 @@ IF( ENABLE_PKG_CONFIGURE ) |
| 243 | 243 | SET( ENABLE_SCENE3D "ON" ) |
| 244 | 244 | ENDIF() |
| 245 | 245 | |
| 246 | + pkg_check_modules(DALI_PHYSICS_2D dali2-physics-2d) | |
| 247 | + IF( DALI_PHYSICS_2D_FOUND ) | |
| 248 | + FOREACH(flag ${DALI_PHYSICS_2D_CFLAGS}) | |
| 249 | + SET(REQUIRED_CFLAGS "${REQUIRED_CFLAGS} ${flag}") | |
| 250 | + ENDFOREACH(flag) | |
| 251 | + | |
| 252 | + SET( REQUIRED_CFLAGS "${REQUIRED_CFLAGS} -DDALI_PHYSICS_2D_AVAILABLE" ) | |
| 253 | + | |
| 254 | + FOREACH(flag ${DALI_PHYSICS_2D_LDFLAGS}) | |
| 255 | + SET(REQUIRED_PKGS_LDFLAGS "${REQUIRED_PKGS_LDFLAGS} ${flag}") | |
| 256 | + ENDFOREACH(flag) | |
| 257 | + | |
| 258 | + SET( ENABLE_PHYSICS_2D "ON" ) | |
| 259 | + ENDIF() | |
| 260 | + | |
| 246 | 261 | # if build as tizen platform, use capi-appfw-app-control |
| 247 | 262 | IF( TIZEN ) |
| 248 | 263 | pkg_check_modules(CAPI_APPFW_APP_CONTROL capi-appfw-app-control) |
| ... | ... | @@ -292,6 +307,8 @@ IF( WIN32 OR APPLE ) # WIN32 includes x64 as well according to the cmake doc. |
| 292 | 307 | |
| 293 | 308 | FIND_PACKAGE( dali2-scene3d ) |
| 294 | 309 | |
| 310 | + FIND_PACKAGE( chipmunk ) | |
| 311 | + | |
| 295 | 312 | # Set up the include dir |
| 296 | 313 | SET( INCLUDE_DIR $ENV{includedir} ) |
| 297 | 314 | IF( NOT INCLUDE_DIR ) |
| ... | ... | @@ -346,6 +363,15 @@ IF( WIN32 OR APPLE ) # WIN32 includes x64 as well according to the cmake doc. |
| 346 | 363 | ) |
| 347 | 364 | SET( ENABLE_SCENE3D "ON" ) |
| 348 | 365 | ENDIF() |
| 366 | + | |
| 367 | + IF (chipmunk_FOUND) | |
| 368 | + SET(REQUIRED_LIBS | |
| 369 | + ${REQUIRED_LIBS} | |
| 370 | + -lchipmunk | |
| 371 | + ) | |
| 372 | + SET( ENABLE_PHYSICS_2D "ON" ) | |
| 373 | + ENDIF() | |
| 374 | + | |
| 349 | 375 | ELSEIF( UNIX ) |
| 350 | 376 | SET( REQUIRED_LIBS |
| 351 | 377 | ${REQUIRED_PKGS_LDFLAGS} |
| ... | ... | @@ -374,6 +400,10 @@ IF( ENABLE_SCENE3D ) |
| 374 | 400 | SET(DALI_DEMO_CFLAGS "${DALI_DEMO_CFLAGS} -DDALI_SCENE3D_AVAILABLE") |
| 375 | 401 | ENDIF() |
| 376 | 402 | |
| 403 | +IF( ENABLE_PHYSICS_2D ) | |
| 404 | + SET(DALI_DEMO_CFLAGS "${DALI_DEMO_CFLAGS} -DDALI_PHYSICS_2D_AVAILABLE") | |
| 405 | +ENDIF() | |
| 406 | + | |
| 377 | 407 | IF( UNIX ) |
| 378 | 408 | IF( NOT ${ENABLE_EXPORTALL} ) |
| 379 | 409 | ADD_DEFINITIONS( "-DHIDE_DALI_INTERNALS" ) |
| ... | ... | @@ -491,3 +521,4 @@ MESSAGE( " Folder DEMO_LANG : [" ${DEMO_LANG} "]" ) |
| 491 | 521 | MESSAGE( " Current Build Platform : [" ${CURRENT_BUILD_PLATFORM} "]" ) |
| 492 | 522 | MESSAGE( " Build example name : [" ${CURRENT_BUILD_EXAMPLE_NAME} "]" ) |
| 493 | 523 | MESSAGE( " Scene3D Enabled : [" ${ENABLE_SCENE3D} "]" ) |
| 524 | +MESSAGE( " Physics 2D Enabled : [" ${ENABLE_PHYSICS_2D} "]" ) | ... | ... |
build/tizen/examples/CMakeLists.txt
| ... | ... | @@ -20,6 +20,13 @@ IF (NOT "${ENABLE_SCENE3D}" ) |
| 20 | 20 | ENDIF() |
| 21 | 21 | ENDIF() |
| 22 | 22 | |
| 23 | +SET(PHYSICS_2D_DIR "chipmunk") | |
| 24 | +IF (NOT "${ENABLE_PHYSICS_2D}" ) | |
| 25 | + IF ( ${PHYSICS_2D_DIR} IN_LIST SUBDIRS ) | |
| 26 | + LIST( REMOVE_ITEM SUBDIRS ${PHYSICS_2D_DIR} ) | |
| 27 | + ENDIF() | |
| 28 | +ENDIF() | |
| 29 | + | |
| 23 | 30 | FIND_PROGRAM( SHADER_GENERATOR "dali-shader-generator" ) |
| 24 | 31 | IF( NOT SHADER_GENERATOR ) |
| 25 | 32 | MESSAGE( FATAL_ERROR "dali-shader-generator not found!" ) | ... | ... |
com.samsung.dali-demo.xml
| ... | ... | @@ -67,6 +67,9 @@ |
| 67 | 67 | <ui-application appid="canvas-view.example" exec="/usr/apps/com.samsung.dali-demo/bin/canvas-view.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true"> |
| 68 | 68 | <label>Canvas View</label> |
| 69 | 69 | </ui-application> |
| 70 | + <ui-application appid="chipmunk-physics.example" exec="/usr/apps/com.samsung.dali-demo/bin/chipmunk-physics.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true"> | |
| 71 | + <label>Chipmunk Physics</label> | |
| 72 | + </ui-application> | |
| 70 | 73 | <ui-application appid="clipping-draw-order.example" exec="/usr/apps/com.samsung.dali-demo/bin/clipping-draw-order.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true"> |
| 71 | 74 | <label>Clipping Draw Order</label> |
| 72 | 75 | </ui-application> | ... | ... |
examples-reel/dali-examples-reel.cpp
| ... | ... | @@ -47,6 +47,7 @@ int DALI_EXPORT_API main(int argc, char** argv) |
| 47 | 47 | demo.AddExample(Example("builder.example", DALI_DEMO_STR_TITLE_SCRIPT_BASED_UI)); |
| 48 | 48 | demo.AddExample(Example("buttons.example", DALI_DEMO_STR_TITLE_BUTTONS)); |
| 49 | 49 | demo.AddExample(Example("canvas-view.example", DALI_DEMO_STR_TITLE_CANVAS_VIEW)); |
| 50 | + demo.AddExample(Example("chipmunk-physics.example", DALI_DEMO_STR_TITLE_CHIPMUNK_PHYSICS)); | |
| 50 | 51 | demo.AddExample(Example("clipping.example", DALI_DEMO_STR_TITLE_CLIPPING)); |
| 51 | 52 | demo.AddExample(Example("clipping-draw-order.example", DALI_DEMO_STR_TITLE_CLIPPING_DRAW_ORDER)); |
| 52 | 53 | demo.AddExample(Example("color-transition.example", DALI_DEMO_STR_TITLE_COLOR_TRANSITION)); | ... | ... |
examples/chipmunk-physics/frame-callback.cpp
0 → 100644
| 1 | +/* | |
| 2 | + * Copyright (c) 2023 Samsung Electronics Co., Ltd. | |
| 3 | + * | |
| 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 | |
| 7 | + * | |
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
| 9 | + * | |
| 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. | |
| 15 | + */ | |
| 16 | + | |
| 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 | +#include <dali/devel-api/threading/mutex.h> | |
| 22 | + | |
| 23 | +using Dali::Vector3; | |
| 24 | +using Dali::Quaternion; | |
| 25 | + | |
| 26 | +FrameCallback::FrameCallback(PhysicsImpl& physicsImpl) | |
| 27 | +: mPhysicsImpl(physicsImpl) | |
| 28 | +{ | |
| 29 | +} | |
| 30 | + | |
| 31 | +bool FrameCallback::Update(Dali::UpdateProxy& updateProxy, float elapsedSeconds) | |
| 32 | +{ | |
| 33 | + Dali::Mutex::ScopedLock lock(mPhysicsImpl.mMutex); | |
| 34 | + static float frameTime=0; | |
| 35 | + frameTime+=elapsedSeconds; | |
| 36 | + do | |
| 37 | + { | |
| 38 | + mPhysicsImpl.Integrate(mPhysicsTimeStep); | |
| 39 | + frameTime-=mPhysicsTimeStep; | |
| 40 | + } while (frameTime>0); | |
| 41 | + | |
| 42 | + for(auto&& actor : mPhysicsImpl.mPhysicsActors) | |
| 43 | + { | |
| 44 | + // Get position, orientation from physics world. | |
| 45 | + Vector3 position = actor.second.GetActorPosition(); | |
| 46 | + updateProxy.BakePosition(actor.first, position); | |
| 47 | + Quaternion rotation = actor.second.GetActorRotation(); | |
| 48 | + updateProxy.BakeOrientation(actor.first, rotation); | |
| 49 | + } | |
| 50 | + | |
| 51 | + return true; | |
| 52 | +} | ... | ... |
examples/chipmunk-physics/frame-callback.h
0 → 100644
| 1 | +#ifndef PHYSICS_DEMO_FRAME_CALLBACK_H | |
| 2 | +#define PHYSICS_DEMO_FRAME_CALLBACK_H | |
| 3 | + | |
| 4 | +/* | |
| 5 | + * Copyright (c) 2023 Samsung Electronics Co., Ltd. | |
| 6 | + * | |
| 7 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
| 8 | + * you may not use this file except in compliance with the License. | |
| 9 | + * You may obtain a copy of the License at | |
| 10 | + * | |
| 11 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
| 12 | + * | |
| 13 | + * Unless required by applicable law or agreed to in writing, software | |
| 14 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
| 15 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 16 | + * See the License for the specific language governing permissions and | |
| 17 | + * limitations under the License. | |
| 18 | + */ | |
| 19 | + | |
| 20 | +#include <dali/public-api/adaptor-framework/window.h> | |
| 21 | +#include <dali/devel-api/update/frame-callback-interface.h> | |
| 22 | +#include <map> | |
| 23 | +#include <chrono> | |
| 24 | + | |
| 25 | +class PhysicsImpl; | |
| 26 | + | |
| 27 | +class FrameCallback : public Dali::FrameCallbackInterface | |
| 28 | +{ | |
| 29 | +public: | |
| 30 | + /** | |
| 31 | + * Constructor | |
| 32 | + */ | |
| 33 | + explicit FrameCallback(PhysicsImpl& physicsImpl); | |
| 34 | + | |
| 35 | + /** | |
| 36 | + * Set the physics time step | |
| 37 | + * @param timeStep (in seconds) | |
| 38 | + */ | |
| 39 | + void SetPhysicsTimeStep(float timeStep) | |
| 40 | + { | |
| 41 | + mPhysicsTimeStep = timeStep; | |
| 42 | + } | |
| 43 | + | |
| 44 | +private: | |
| 45 | + /** | |
| 46 | + * Called each frame. | |
| 47 | + * @param[in] updateProxy Used to set world matrix and size | |
| 48 | + * @param[in] elapsedSeconds Time since last frame | |
| 49 | + * @return Whether we should keep rendering. | |
| 50 | + */ | |
| 51 | + bool Update(Dali::UpdateProxy& updateProxy, float elapsedSeconds) override; | |
| 52 | + | |
| 53 | +private: // Member variables | |
| 54 | + PhysicsImpl& mPhysicsImpl; | |
| 55 | + float mPhysicsTimeStep{1.0/180.0}; | |
| 56 | +}; | |
| 57 | + | |
| 58 | +#endif //PHYSICS_DEMO_FRAME_CALLBACK_H | ... | ... |
examples/chipmunk-physics/physics-actor.cpp
0 → 100644
| 1 | +/* | |
| 2 | + * Copyright (c) 2023 Samsung Electronics Co., Ltd. | |
| 3 | + * | |
| 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 | |
| 7 | + * | |
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
| 9 | + * | |
| 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. | |
| 15 | + * | |
| 16 | + */ | |
| 17 | + | |
| 18 | +#include "physics-actor.h" | |
| 19 | +#include "physics-impl.h" | |
| 20 | +#include <dali/public-api/common/constants.h> | |
| 21 | +#include <dali/public-api/math/vector3.h> | |
| 22 | +#include <dali/public-api/math/quaternion.h> | |
| 23 | + | |
| 24 | +using Dali::Vector3; | |
| 25 | +using Dali::Quaternion; | |
| 26 | +using Dali::Radian; | |
| 27 | + | |
| 28 | +void PhysicsActor::ClearForces() | |
| 29 | +{ | |
| 30 | + printf("Not Implemented\n"); | |
| 31 | + //mBody->clearForces(); | |
| 32 | + // No similar API | |
| 33 | +} | |
| 34 | + | |
| 35 | +Dali::Vector3 PhysicsActor::GetPhysicsPosition() | |
| 36 | +{ | |
| 37 | + cpVect cpPosition = cpBodyGetPosition(mBody); | |
| 38 | + return Vector3(cpPosition.x, cpPosition.y, 0.0f); | |
| 39 | +} | |
| 40 | + | |
| 41 | +void PhysicsActor::SetPhysicsPosition(Dali::Vector3 actorPosition) | |
| 42 | +{ | |
| 43 | + Dali::Mutex::ScopedLock lock(mImpl->mMutex); | |
| 44 | + Vector3 physicsPosition = mImpl->TranslateToPhysicsSpace(actorPosition); | |
| 45 | + cpBodySetPosition(mBody, cpv(physicsPosition.x, physicsPosition.y)); | |
| 46 | +} | |
| 47 | + | |
| 48 | +void PhysicsActor::SetPhysicsVelocity(Dali::Vector3 actorVelocity) | |
| 49 | +{ | |
| 50 | + Dali::Mutex::ScopedLock lock(mImpl->mMutex); | |
| 51 | + Vector3 physicsVelocity = mImpl->ConvertVectorToPhysicsSpace(actorVelocity); | |
| 52 | + cpBodySetVelocity(mBody, cpv(physicsVelocity.x, physicsVelocity.y)); | |
| 53 | +} | |
| 54 | + | |
| 55 | +void PhysicsActor::SetPhysicsAngularVelocity(Dali::Vector3 velocity) | |
| 56 | +{ | |
| 57 | + Dali::Mutex::ScopedLock lock(mImpl->mMutex); | |
| 58 | + printf("Not Implemented\n"); | |
| 59 | + //mBody->setAngularVelocity(btVector3(velocity.x, velocity.y, velocity.z)); | |
| 60 | +} | |
| 61 | + | |
| 62 | +Quaternion PhysicsActor::GetPhysicsRotation() | |
| 63 | +{ | |
| 64 | + return Quaternion{}; | |
| 65 | +} | |
| 66 | + | |
| 67 | +void PhysicsActor::SetPhysicsRotation(Dali::Quaternion rotation) | |
| 68 | +{ | |
| 69 | + Dali::Mutex::ScopedLock lock(mImpl->mMutex); | |
| 70 | + | |
| 71 | + Vector3 axis; | |
| 72 | + Radian angle; | |
| 73 | + rotation.ToAxisAngle(axis, angle); | |
| 74 | + | |
| 75 | + //btQuaternion orn = btQuaternion(btVector3(axis.x, -axis.y, axis.z), btScalar(float(-angle))); | |
| 76 | + //btTransform& transform = mBody->getWorldTransform(); | |
| 77 | + //transform.setRotation(orn); | |
| 78 | + printf("Not Implemented\n"); | |
| 79 | +} | |
| 80 | + | |
| 81 | + | |
| 82 | +Vector3 PhysicsActor::GetActorPosition() | |
| 83 | +{ | |
| 84 | + cpVect cpPosition = cpBodyGetPosition(mBody); | |
| 85 | + return mImpl->TranslateFromPhysicsSpace(Vector3(cpPosition.x, cpPosition.y, 0.0f)); | |
| 86 | +} | |
| 87 | + | |
| 88 | +Vector3 PhysicsActor::GetActorVelocity() | |
| 89 | +{ | |
| 90 | + cpVect cpVelocity = cpBodyGetVelocity(mBody); | |
| 91 | + return mImpl->ConvertVectorFromPhysicsSpace(Vector3(cpVelocity.x, cpVelocity.y, 0.0f)); | |
| 92 | +} | |
| 93 | + | |
| 94 | +Quaternion PhysicsActor::GetActorRotation() | |
| 95 | +{ | |
| 96 | + cpFloat angle = cpBodyGetAngle(mBody); | |
| 97 | + return Quaternion(Radian(angle), -Vector3::ZAXIS); | |
| 98 | +} | ... | ... |
examples/chipmunk-physics/physics-actor.h
0 → 100644
| 1 | +#ifndef DALI_PHYSICS_DEMO_PHYSICS_ACTOR_H | |
| 2 | +#define DALI_PHYSICS_DEMO_PHYSICS_ACTOR_H | |
| 3 | +/* | |
| 4 | + * Copyright (c) 2023 Samsung Electronics Co., Ltd. | |
| 5 | + * | |
| 6 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
| 7 | + * you may not use this file except in compliance with the License. | |
| 8 | + * You may obtain a copy of the License at | |
| 9 | + * | |
| 10 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
| 11 | + * | |
| 12 | + * Unless required by applicable law or agreed to in writing, software | |
| 13 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
| 14 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 15 | + * See the License for the specific language governing permissions and | |
| 16 | + * limitations under the License. | |
| 17 | + * | |
| 18 | + */ | |
| 19 | + | |
| 20 | +#include <chipmunk/chipmunk.h> | |
| 21 | +#include <cstdint> | |
| 22 | +#include <dali/dali.h> | |
| 23 | +#include <iosfwd> | |
| 24 | + | |
| 25 | +// Forward declarations | |
| 26 | +class PhysicsImpl; | |
| 27 | + | |
| 28 | +/** | |
| 29 | + * Class that associates an actor with a physics body. (Initially, rigid body) | |
| 30 | + */ | |
| 31 | +class PhysicsActor | |
| 32 | +{ | |
| 33 | +public: | |
| 34 | + PhysicsActor() = default; | |
| 35 | + PhysicsActor(Dali::Actor& actor, cpBody* body, PhysicsImpl* impl, Dali::Property::Index brightnessId) | |
| 36 | + : mImpl(impl), | |
| 37 | + mActorId(actor.GetProperty<int>(Dali::Actor::Property::ID)), | |
| 38 | + mBody(body), | |
| 39 | + mBrightnessIndex(brightnessId) | |
| 40 | + { | |
| 41 | + cpBodySetUserData(mBody, this); | |
| 42 | + } | |
| 43 | + | |
| 44 | + PhysicsActor(const PhysicsActor& rhs)=delete; | |
| 45 | + PhysicsActor& operator=(const PhysicsActor& rhs)=delete; | |
| 46 | + | |
| 47 | + PhysicsActor(const PhysicsActor&& rhs) | |
| 48 | + { | |
| 49 | + if(this != &rhs) | |
| 50 | + { | |
| 51 | + mImpl = rhs.mImpl; | |
| 52 | + mActorId = rhs.mActorId; | |
| 53 | + mBody = rhs.mBody; | |
| 54 | + cpBodySetUserData(mBody, this); | |
| 55 | + mBrightnessIndex = rhs.mBrightnessIndex; | |
| 56 | + } | |
| 57 | + } | |
| 58 | + | |
| 59 | + PhysicsActor& operator=(const PhysicsActor&& rhs) | |
| 60 | + { | |
| 61 | + if(this != &rhs) | |
| 62 | + { | |
| 63 | + mActorId = rhs.mActorId; | |
| 64 | + mBody = rhs.mBody; | |
| 65 | + mImpl = rhs.mImpl; | |
| 66 | + mBrightnessIndex = rhs.mBrightnessIndex; | |
| 67 | + cpBodySetUserData(mBody, this); | |
| 68 | + } | |
| 69 | + return *this; | |
| 70 | + } | |
| 71 | + | |
| 72 | + uint32_t GetId() | |
| 73 | + { | |
| 74 | + return mActorId; | |
| 75 | + } | |
| 76 | + | |
| 77 | + cpBody* GetBody() | |
| 78 | + { | |
| 79 | + return mBody; | |
| 80 | + } | |
| 81 | + | |
| 82 | + Dali::Property::Index GetBrightnessIndex() | |
| 83 | + { | |
| 84 | + return mBrightnessIndex; | |
| 85 | + } | |
| 86 | + | |
| 87 | + Dali::Vector3 GetPhysicsPosition(); | |
| 88 | + Dali::Quaternion GetPhysicsRotation(); | |
| 89 | + | |
| 90 | + void SetPhysicsPosition(Dali::Vector3 actorPosition); | |
| 91 | + void SetPhysicsVelocity(Dali::Vector3 actorVelocity); | |
| 92 | + void SetPhysicsAngularVelocity(Dali::Vector3 actorVelocity); | |
| 93 | + void SetPhysicsRotation(Dali::Quaternion actorRotation); | |
| 94 | + Dali::Vector3 GetActorPosition(); | |
| 95 | + Dali::Vector3 GetActorVelocity(); | |
| 96 | + Dali::Quaternion GetActorRotation(); | |
| 97 | + void ClearForces(); | |
| 98 | + | |
| 99 | +private: | |
| 100 | + PhysicsImpl* mImpl{nullptr}; | |
| 101 | + uint32_t mActorId{0}; | |
| 102 | + cpBody* mBody{nullptr}; | |
| 103 | + Dali::Property::Index mBrightnessIndex{Dali::Property::INVALID_INDEX}; | |
| 104 | +}; | |
| 105 | + | |
| 106 | +#endif // DALI_PHYSICS_DEMO_PHYSICS_ACTOR_H | ... | ... |
examples/chipmunk-physics/physics-demo-controller.cpp
0 → 100644
| 1 | +/* | |
| 2 | + * Copyright (c) 2023 Samsung Electronics Co., Ltd. | |
| 3 | + * | |
| 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 | |
| 7 | + * | |
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
| 9 | + * | |
| 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. | |
| 15 | + */ | |
| 16 | + | |
| 17 | +#include <dali-toolkit/dali-toolkit.h> | |
| 18 | +#include <dali/dali.h> | |
| 19 | + | |
| 20 | +#include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h> | |
| 21 | +#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h> | |
| 22 | +#include <dali/devel-api/adaptor-framework/key-devel.h> | |
| 23 | +#include <dali/devel-api/events/hit-test-algorithm.h> | |
| 24 | + | |
| 25 | +#include <iostream> | |
| 26 | +#include <string> | |
| 27 | + | |
| 28 | +#include "generated/rendering-textured-shape-frag.h" | |
| 29 | +#include "generated/rendering-textured-shape-vert.h" | |
| 30 | +#include "physics-actor.h" | |
| 31 | +#include "physics-impl.h" | |
| 32 | + | |
| 33 | +using namespace Dali; | |
| 34 | + | |
| 35 | +namespace KeyModifier | |
| 36 | +{ | |
| 37 | +enum Key | |
| 38 | +{ | |
| 39 | + CONTROL_L = DevelKey::DALI_KEY_CONTROL_LEFT, | |
| 40 | + CONTROL_R = DevelKey::DALI_KEY_CONTROL_RIGHT, | |
| 41 | + SHIFT_L = 50, | |
| 42 | + SHIFT_R = 62, | |
| 43 | + ALT_L = 64, | |
| 44 | + ALT_R = 108, | |
| 45 | + SUPER_L = 133, | |
| 46 | + SUPER_R = 134, | |
| 47 | + MENU = 135, | |
| 48 | +}; | |
| 49 | +} | |
| 50 | + | |
| 51 | +const std::string BRICK_WALL = DEMO_IMAGE_DIR "/brick-wall.jpg"; | |
| 52 | +const std::string BALL_IMAGE = DEMO_IMAGE_DIR "/blocks-ball.png"; | |
| 53 | +const std::string BRICK_URIS[4] = { | |
| 54 | + DEMO_IMAGE_DIR "/blocks-brick-1.png", DEMO_IMAGE_DIR "/blocks-brick-2.png", DEMO_IMAGE_DIR "/blocks-brick-3.png", DEMO_IMAGE_DIR "/blocks-brick-4.png"}; | |
| 55 | + | |
| 56 | +/** | |
| 57 | + * @brief The physics demo using Chipmunk2D APIs. | |
| 58 | + */ | |
| 59 | +class PhysicsDemoController : public ConnectionTracker | |
| 60 | +{ | |
| 61 | +public: | |
| 62 | + PhysicsDemoController(Application& app) | |
| 63 | + : mApplication(app) | |
| 64 | + { | |
| 65 | + app.InitSignal().Connect(this, &PhysicsDemoController::OnInit); | |
| 66 | + app.TerminateSignal().Connect(this, &PhysicsDemoController::OnTerminate); | |
| 67 | + } | |
| 68 | + | |
| 69 | + ~PhysicsDemoController() override | |
| 70 | + { | |
| 71 | + } | |
| 72 | + | |
| 73 | + void OnInit(Application& application) | |
| 74 | + { | |
| 75 | + mWindow = application.GetWindow(); | |
| 76 | + mWindow.ResizeSignal().Connect(this, &PhysicsDemoController::OnWindowResize); | |
| 77 | + mWindow.KeyEventSignal().Connect(this, &PhysicsDemoController::OnKeyEv); | |
| 78 | + Stage::GetCurrent().KeepRendering(30); | |
| 79 | + mWindow.SetBackgroundColor(Color::DARK_SLATE_GRAY); | |
| 80 | + Window::WindowSize windowSize = mWindow.GetSize(); | |
| 81 | + | |
| 82 | + mPhysicsRoot = mPhysicsImpl.Initialize(mWindow); | |
| 83 | + mPhysicsRoot.TouchedSignal().Connect(this, &PhysicsDemoController::OnTouched); | |
| 84 | + | |
| 85 | + mWindow.Add(mPhysicsRoot); | |
| 86 | + | |
| 87 | + CreateBall(); | |
| 88 | + CreateBrickPyramid(windowSize); | |
| 89 | + | |
| 90 | + // For funky mouse drag | |
| 91 | + mMouseBody = mPhysicsImpl.AddMouseBody(); | |
| 92 | + } | |
| 93 | + | |
| 94 | + void CreateBall() | |
| 95 | + { | |
| 96 | + const float BALL_MASS = 10.0f; | |
| 97 | + const float BALL_RADIUS = 26.0f; | |
| 98 | + const float BALL_ELASTICITY = 0.5f; | |
| 99 | + const float BALL_FRICTION = 0.5f; | |
| 100 | + | |
| 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}}}}; | |
| 107 | + | |
| 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); | |
| 111 | + } | |
| 112 | + | |
| 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 | + void OnTerminate(Application& application) | |
| 149 | + { | |
| 150 | + UnparentAndReset(mPhysicsRoot); | |
| 151 | + } | |
| 152 | + | |
| 153 | + void OnWindowResize(Window window, Window::WindowSize newSize) | |
| 154 | + { | |
| 155 | + mPhysicsImpl.CreateWorldBounds(newSize); | |
| 156 | + } | |
| 157 | + | |
| 158 | + bool OnTouched(Dali::Actor actor, const Dali::TouchEvent& touch) | |
| 159 | + { | |
| 160 | + static enum { | |
| 161 | + None, | |
| 162 | + MoveCameraXZ, | |
| 163 | + MovePivot, | |
| 164 | + } state = None; | |
| 165 | + | |
| 166 | + auto renderTask = mWindow.GetRenderTaskList().GetTask(0); | |
| 167 | + auto screenCoords = touch.GetScreenPosition(0); | |
| 168 | + Vector3 origin, direction; | |
| 169 | + Dali::HitTestAlgorithm::BuildPickingRay(renderTask, screenCoords, origin, direction); | |
| 170 | + | |
| 171 | + switch(state) | |
| 172 | + { | |
| 173 | + case None: | |
| 174 | + { | |
| 175 | + if(touch.GetState(0) == Dali::PointState::STARTED) | |
| 176 | + { | |
| 177 | + if(mCtrlDown) | |
| 178 | + { | |
| 179 | + state = MoveCameraXZ; | |
| 180 | + // local to top left | |
| 181 | + //cameraY = touch.GetLocalPosition(0).y; | |
| 182 | + // Could move on fixed plane, e.g. y=0. | |
| 183 | + // position.Y corresponds to a z value depending on perspective | |
| 184 | + // position.X scales to an x value depending on perspective | |
| 185 | + } | |
| 186 | + else | |
| 187 | + { | |
| 188 | + state = MovePivot; | |
| 189 | + Dali::Mutex::ScopedLock lock(mPhysicsImpl.mMutex); | |
| 190 | + | |
| 191 | + Vector3 localPivot; | |
| 192 | + float pickingDistance; | |
| 193 | + auto body = mPhysicsImpl.HitTest(screenCoords, origin, direction, localPivot, pickingDistance); | |
| 194 | + if(body) | |
| 195 | + { | |
| 196 | + mPickedBody = body; | |
| 197 | + mPhysicsImpl.HighlightBody(mPickedBody, true); | |
| 198 | + mPickedSavedState = mPhysicsImpl.ActivateBody(mPickedBody); | |
| 199 | + mPickedConstraint = mPhysicsImpl.AddPivotJoint(mPickedBody, mMouseBody, localPivot); | |
| 200 | + } | |
| 201 | + } | |
| 202 | + } | |
| 203 | + break; | |
| 204 | + } | |
| 205 | + case MovePivot: | |
| 206 | + { | |
| 207 | + if(touch.GetState(0) == Dali::PointState::MOTION) | |
| 208 | + { | |
| 209 | + if(mPickedBody && mPickedConstraint) | |
| 210 | + { | |
| 211 | + if(!mShiftDown) | |
| 212 | + { | |
| 213 | + // Move point in XY plane, projected into scene | |
| 214 | + Dali::Mutex::ScopedLock lock(mPhysicsImpl.mMutex); | |
| 215 | + | |
| 216 | + Vector3 position = mPhysicsImpl.TranslateToPhysicsSpace(Vector3(screenCoords)); | |
| 217 | + mPhysicsImpl.MoveMouseBody(mMouseBody, position); | |
| 218 | + } | |
| 219 | + else | |
| 220 | + { | |
| 221 | + // Move point in XZ plane | |
| 222 | + // Above vanishing pt, it's on top plane of frustum; below vanishing pt it's on bottom plane. | |
| 223 | + // Kind of want to project onto the plane using initial touch xy, rather than top/bottom. | |
| 224 | + // Whole new projection code needed. | |
| 225 | + | |
| 226 | + // Cheat! | |
| 227 | + } | |
| 228 | + } | |
| 229 | + } | |
| 230 | + else if(touch.GetState(0) == Dali::PointState::FINISHED || | |
| 231 | + touch.GetState(0) == Dali::PointState::INTERRUPTED) | |
| 232 | + { | |
| 233 | + if(mPickedConstraint) | |
| 234 | + { | |
| 235 | + mPhysicsImpl.HighlightBody(mPickedBody, false); | |
| 236 | + | |
| 237 | + Dali::Mutex::ScopedLock lock(mPhysicsImpl.mMutex); | |
| 238 | + mPhysicsImpl.RestoreBodyState(mPickedBody, mPickedSavedState); | |
| 239 | + mPhysicsImpl.ReleaseConstraint(mPickedConstraint); | |
| 240 | + mPickedConstraint = nullptr; | |
| 241 | + mPickedBody = nullptr; | |
| 242 | + } | |
| 243 | + state = None; | |
| 244 | + } | |
| 245 | + break; | |
| 246 | + } | |
| 247 | + case MoveCameraXZ: | |
| 248 | + { | |
| 249 | + if(touch.GetState(0) == Dali::PointState::MOTION) | |
| 250 | + { | |
| 251 | + // Move camera in XZ plane | |
| 252 | + //float y = cameraY; // touch point in Y. Move camera in an XZ plane on this point. | |
| 253 | + } | |
| 254 | + else if(touch.GetState(0) == Dali::PointState::FINISHED || | |
| 255 | + touch.GetState(0) == Dali::PointState::INTERRUPTED) | |
| 256 | + { | |
| 257 | + state = None; | |
| 258 | + } | |
| 259 | + break; | |
| 260 | + } | |
| 261 | + } | |
| 262 | + | |
| 263 | + //std::cout<<"Touch State: "<<state<<std::endl; | |
| 264 | + Stage::GetCurrent().KeepRendering(30.0f); | |
| 265 | + | |
| 266 | + return true; | |
| 267 | + } | |
| 268 | + | |
| 269 | + void OnKeyEv(const Dali::KeyEvent& event) | |
| 270 | + { | |
| 271 | + if(event.GetState() == KeyEvent::DOWN) | |
| 272 | + { | |
| 273 | + switch(event.GetKeyCode()) | |
| 274 | + { | |
| 275 | + case KeyModifier::CONTROL_L: | |
| 276 | + case KeyModifier::CONTROL_R: | |
| 277 | + { | |
| 278 | + mCtrlDown = true; | |
| 279 | + break; | |
| 280 | + } | |
| 281 | + case KeyModifier::ALT_L: | |
| 282 | + case KeyModifier::ALT_R: | |
| 283 | + { | |
| 284 | + mAltDown = true; | |
| 285 | + break; | |
| 286 | + } | |
| 287 | + case KeyModifier::SHIFT_L: | |
| 288 | + case KeyModifier::SHIFT_R: | |
| 289 | + { | |
| 290 | + mShiftDown = true; | |
| 291 | + break; | |
| 292 | + } | |
| 293 | + default: | |
| 294 | + { | |
| 295 | + if(IsKey(event, Dali::DALI_KEY_ESCAPE) || IsKey(event, Dali::DALI_KEY_BACK)) | |
| 296 | + { | |
| 297 | + mApplication.Quit(); | |
| 298 | + } | |
| 299 | + else if(!event.GetKeyString().compare(" ")) | |
| 300 | + { | |
| 301 | + mPhysicsImpl.ToggleIntegrateState(); | |
| 302 | + } | |
| 303 | + else if(!event.GetKeyString().compare("m")) | |
| 304 | + { | |
| 305 | + mPhysicsImpl.ToggleDebugState(); | |
| 306 | + } | |
| 307 | + break; | |
| 308 | + } | |
| 309 | + } | |
| 310 | + } | |
| 311 | + else if(event.GetState() == KeyEvent::UP) | |
| 312 | + { | |
| 313 | + switch(event.GetKeyCode()) | |
| 314 | + { | |
| 315 | + case KeyModifier::CONTROL_L: | |
| 316 | + case KeyModifier::CONTROL_R: | |
| 317 | + { | |
| 318 | + mCtrlDown = false; | |
| 319 | + break; | |
| 320 | + } | |
| 321 | + case KeyModifier::ALT_L: | |
| 322 | + case KeyModifier::ALT_R: | |
| 323 | + { | |
| 324 | + mAltDown = false; | |
| 325 | + break; | |
| 326 | + } | |
| 327 | + case KeyModifier::SHIFT_L: | |
| 328 | + case KeyModifier::SHIFT_R: | |
| 329 | + { | |
| 330 | + mShiftDown = false; | |
| 331 | + break; | |
| 332 | + } | |
| 333 | + } | |
| 334 | + } | |
| 335 | + } | |
| 336 | + | |
| 337 | +private: | |
| 338 | + Application& mApplication; | |
| 339 | + Window mWindow; | |
| 340 | + | |
| 341 | + PhysicsImpl mPhysicsImpl; | |
| 342 | + Actor mPhysicsRoot; | |
| 343 | + cpBody* mMouseBody; | |
| 344 | + cpBody* mPickedBody; | |
| 345 | + int mPickedSavedState; | |
| 346 | + cpConstraint* mPickedConstraint; | |
| 347 | + | |
| 348 | + bool mCtrlDown{false}; | |
| 349 | + bool mAltDown{false}; | |
| 350 | + bool mShiftDown{false}; | |
| 351 | +}; | |
| 352 | + | |
| 353 | +int DALI_EXPORT_API main(int argc, char** argv) | |
| 354 | +{ | |
| 355 | + Application application = Application::New(&argc, &argv); | |
| 356 | + PhysicsDemoController controller(application); | |
| 357 | + application.MainLoop(); | |
| 358 | + return 0; | |
| 359 | +} | ... | ... |
examples/chipmunk-physics/physics-impl.cpp
0 → 100644
| 1 | +/* | |
| 2 | + * Copyright (c) 2023 Samsung Electronics Co., Ltd. | |
| 3 | + * | |
| 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 | |
| 7 | + * | |
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
| 9 | + * | |
| 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. | |
| 15 | + * | |
| 16 | + */ | |
| 17 | + | |
| 18 | +#include "physics-impl.h" | |
| 19 | +#include "physics-actor.h" | |
| 20 | + | |
| 21 | +#include <devel-api/common/stage.h> | |
| 22 | +#include <map> | |
| 23 | +#include <utility> | |
| 24 | +#include <iostream> | |
| 25 | + | |
| 26 | +using Dali::Layer; | |
| 27 | +using Dali::Actor; | |
| 28 | +using Dali::Window; | |
| 29 | +using Dali::Vector2; | |
| 30 | +using Dali::Vector3; | |
| 31 | +using Dali::Stage; | |
| 32 | +using namespace Dali::DevelStage; | |
| 33 | + | |
| 34 | +#define GRABBABLE_MASK_BIT (1u<<31) | |
| 35 | +cpShapeFilter GRAB_FILTER = {CP_NO_GROUP, GRABBABLE_MASK_BIT, GRABBABLE_MASK_BIT}; | |
| 36 | +cpShapeFilter NOT_GRABBABLE_FILTER = {CP_NO_GROUP, ~GRABBABLE_MASK_BIT, ~GRABBABLE_MASK_BIT}; | |
| 37 | + | |
| 38 | +Actor PhysicsImpl::Initialize(Window window) | |
| 39 | +{ | |
| 40 | + mWindow = window; | |
| 41 | + mSpace = cpSpaceNew(); | |
| 42 | + cpSpaceSetIterations(mSpace, 30); | |
| 43 | + cpSpaceSetSleepTimeThreshold(mSpace, 0.5f); | |
| 44 | + cpSpaceSetGravity(mSpace, cpv(0, -200)); | |
| 45 | + | |
| 46 | + auto windowSize = window.GetSize(); | |
| 47 | + CreateWorldBounds(windowSize); | |
| 48 | + | |
| 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; | |
| 53 | + mPhysicsRoot[Actor::Property::PARENT_ORIGIN] = Dali::ParentOrigin::CENTER; | |
| 54 | + | |
| 55 | + mFrameCallback = new FrameCallback(*this); | |
| 56 | + AddFrameCallback(Stage::GetCurrent(), *mFrameCallback, window.GetRootLayer()); | |
| 57 | + Stage::GetCurrent().KeepRendering(30); | |
| 58 | + | |
| 59 | + | |
| 60 | + return mPhysicsRoot; | |
| 61 | +} | |
| 62 | + | |
| 63 | +Layer PhysicsImpl::CreateDebug(Vector2 windowSize) | |
| 64 | +{ | |
| 65 | + return Layer(); | |
| 66 | +} | |
| 67 | + | |
| 68 | +void PhysicsImpl::CreateWorldBounds(Window::WindowSize size) | |
| 69 | +{ | |
| 70 | + // Physics origin is 0,0,0 in DALi coords. | |
| 71 | + // But, Y is inverted, so bottom is -ve, top is +ve. | |
| 72 | + // Perform this correction when applying position to actor. | |
| 73 | + // But, can't use actors in update, so cache transform. | |
| 74 | + SetTransform(Vector2(size.GetWidth(), size.GetHeight())); | |
| 75 | + | |
| 76 | + int xBound=size.GetWidth()/2; | |
| 77 | + int yBound=size.GetHeight()/2; | |
| 78 | + | |
| 79 | + cpBody *staticBody = cpSpaceGetStaticBody(mSpace); | |
| 80 | + | |
| 81 | + if(mLeftBound) | |
| 82 | + { | |
| 83 | + cpSpaceRemoveShape(mSpace, mLeftBound); | |
| 84 | + cpSpaceRemoveShape(mSpace, mRightBound); | |
| 85 | + cpSpaceRemoveShape(mSpace, mTopBound); | |
| 86 | + cpSpaceRemoveShape(mSpace, mBottomBound); | |
| 87 | + cpShapeFree(mLeftBound); | |
| 88 | + cpShapeFree(mRightBound); | |
| 89 | + cpShapeFree(mTopBound); | |
| 90 | + cpShapeFree(mBottomBound); | |
| 91 | + } | |
| 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)); | |
| 96 | +} | |
| 97 | + | |
| 98 | +void PhysicsImpl::SetTransform(Vector2 worldSize) | |
| 99 | +{ | |
| 100 | + mWorldOffset.x = worldSize.x * 0.5f; | |
| 101 | + mWorldOffset.y = worldSize.y * 0.5f; | |
| 102 | + // y is always inverted. | |
| 103 | +} | |
| 104 | + | |
| 105 | +cpShape* PhysicsImpl::AddBound(cpBody* staticBody, cpVect start, cpVect end) | |
| 106 | +{ | |
| 107 | + cpShape* shape = cpSpaceAddShape(mSpace, cpSegmentShapeNew(staticBody,start, end,0.0f)); | |
| 108 | + cpShapeSetElasticity(shape, 1.0f); | |
| 109 | + cpShapeSetFriction(shape, 1.0f); | |
| 110 | + cpShapeSetFilter(shape, NOT_GRABBABLE_FILTER); | |
| 111 | + return shape; | |
| 112 | +} | |
| 113 | + | |
| 114 | +PhysicsActor& PhysicsImpl::AddBall(::Actor actor, float mass, float radius, float elasticity, float friction) | |
| 115 | +{ | |
| 116 | + Dali::Mutex::ScopedLock lock(mMutex); | |
| 117 | + cpBody* body = cpSpaceAddBody(mSpace, cpBodyNew(mass, cpMomentForCircle(mass, 0.0f, radius, cpvzero))); | |
| 118 | + cpBodySetPosition(body, cpv(0, 0)); | |
| 119 | + cpBodySetVelocity(body, cpv(0, 0)); | |
| 120 | + | |
| 121 | + cpShape* shape = cpSpaceAddShape(mSpace, cpCircleShapeNew(body, radius, cpvzero)); | |
| 122 | + cpShapeSetElasticity(shape, elasticity); | |
| 123 | + cpShapeSetFriction(shape, friction); | |
| 124 | + | |
| 125 | + int id = actor[Actor::Property::ID]; | |
| 126 | + Dali::Property::Index index = actor.RegisterProperty("uBrightness", 0.0f); | |
| 127 | + mPhysicsActors.insert(std::make_pair(id, PhysicsActor{actor, body, this, index})); | |
| 128 | + actor[Actor::Property::PARENT_ORIGIN] = Dali::ParentOrigin::TOP_LEFT; | |
| 129 | + actor[Actor::Property::ANCHOR_POINT] = Dali::AnchorPoint::CENTER; | |
| 130 | + mPhysicsRoot.Add(actor); | |
| 131 | + return mPhysicsActors.at(id); | |
| 132 | +} | |
| 133 | + | |
| 134 | +PhysicsActor& PhysicsImpl::AddBrick(Dali::Actor actor, float mass, float elasticity, float friction, Vector3 size) | |
| 135 | +{ | |
| 136 | + Dali::Mutex::ScopedLock lock(mMutex); | |
| 137 | + cpBody* body = cpSpaceAddBody(mSpace, cpBodyNew(mass, cpMomentForBox(mass, size.width, size.height))); | |
| 138 | + cpBodySetPosition(body, cpv(0, 0)); | |
| 139 | + cpBodySetVelocity(body, cpv(0, 0)); | |
| 140 | + | |
| 141 | + cpShape* shape = cpSpaceAddShape(mSpace, cpBoxShapeNew(body, size.width, size.height, 0.0f)); | |
| 142 | + cpShapeSetFriction(shape, friction); | |
| 143 | + cpShapeSetElasticity(shape, elasticity); | |
| 144 | + | |
| 145 | + int id = actor[Actor::Property::ID]; | |
| 146 | + Dali::Property::Index index = actor.RegisterProperty("uBrightness", 0.0f); | |
| 147 | + mPhysicsActors.insert(std::make_pair(id, PhysicsActor{actor, body, this, index})); | |
| 148 | + actor[Actor::Property::PARENT_ORIGIN] = Dali::ParentOrigin::TOP_LEFT; | |
| 149 | + actor[Actor::Property::ANCHOR_POINT] = Dali::AnchorPoint::CENTER; | |
| 150 | + mPhysicsRoot.Add(actor); | |
| 151 | + return mPhysicsActors.at(id); | |
| 152 | +} | |
| 153 | + | |
| 154 | +cpBody* PhysicsImpl::AddMouseBody() | |
| 155 | +{ | |
| 156 | + Dali::Mutex::ScopedLock lock(mMutex); | |
| 157 | + auto kinematicBody = cpBodyNewKinematic(); // Mouse actor is a kinematic body that is not integrated | |
| 158 | + return kinematicBody; | |
| 159 | +} | |
| 160 | + | |
| 161 | +PhysicsActor* PhysicsImpl::GetPhysicsActor(cpBody* body) | |
| 162 | +{ | |
| 163 | + return reinterpret_cast<PhysicsActor*>(cpBodyGetUserData(body)); | |
| 164 | +} | |
| 165 | + | |
| 166 | +void PhysicsImpl::HighlightBody(cpBody* body, bool highlight) | |
| 167 | +{ | |
| 168 | + auto physicsActor = GetPhysicsActor(body); | |
| 169 | + if(physicsActor) | |
| 170 | + { | |
| 171 | + Actor actor = mPhysicsRoot.FindChildById(physicsActor->GetId()); | |
| 172 | + if(actor) | |
| 173 | + { | |
| 174 | + actor[physicsActor->GetBrightnessIndex()] = highlight?1.0f:0.0f; | |
| 175 | + } | |
| 176 | + } | |
| 177 | +} | |
| 178 | + | |
| 179 | +// Convert from root actor local space to physics space | |
| 180 | +Vector3 PhysicsImpl::TranslateToPhysicsSpace(Vector3 vector) | |
| 181 | +{ | |
| 182 | + // root actor origin is top left, DALi Y is inverted. | |
| 183 | + // Physics origin is center. Y: 0->1 => 0.5=>-0.5 | |
| 184 | + return Vector3(vector.x-mWorldOffset.x, mWorldOffset.y-vector.y, vector.z); | |
| 185 | +} | |
| 186 | + | |
| 187 | +// Convert from physics space to root actor local space | |
| 188 | +Vector3 PhysicsImpl::TranslateFromPhysicsSpace(Vector3 vector) | |
| 189 | +{ | |
| 190 | + return Vector3(vector.x+mWorldOffset.x, mWorldOffset.y-vector.y, vector.z); | |
| 191 | +} | |
| 192 | + | |
| 193 | +// Convert a vector from dali space to physics space | |
| 194 | +Vector3 PhysicsImpl::ConvertVectorToPhysicsSpace(Vector3 vector) | |
| 195 | +{ | |
| 196 | + // root actor origin is top left, DALi Y is inverted. | |
| 197 | + // @todo Add space config scale. | |
| 198 | + return Vector3(vector.x, -vector.y, vector.z); | |
| 199 | +} | |
| 200 | + | |
| 201 | +// Convert a vector physics space to root actor local space | |
| 202 | +Vector3 PhysicsImpl::ConvertVectorFromPhysicsSpace(Vector3 vector) | |
| 203 | +{ | |
| 204 | + return Vector3(vector.x, -vector.y, vector.z); | |
| 205 | +} | |
| 206 | + | |
| 207 | +void PhysicsImpl::Integrate(float timestep) | |
| 208 | +{ | |
| 209 | + if(mPhysicsIntegrateState) | |
| 210 | + { | |
| 211 | + cpSpaceStep(mSpace, timestep); | |
| 212 | + } | |
| 213 | +// if(mDynamicsWorld->getDebugDrawer() && mPhysicsDebugState) | |
| 214 | +// { | |
| 215 | +// mDynamicsWorld->debugDrawWorld(); | |
| 216 | +// } | |
| 217 | +} | |
| 218 | + | |
| 219 | +cpBody* PhysicsImpl::HitTest(Vector2 screenCoords, Vector3 origin, Vector3 direction, Vector3& localPivot, float& distanceFromCamera) | |
| 220 | +{ | |
| 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); | |
| 226 | + | |
| 227 | + cpBody *body{nullptr}; | |
| 228 | + | |
| 229 | + if(shape && cpBodyGetMass(cpShapeGetBody(shape)) < INFINITY) | |
| 230 | + { | |
| 231 | + // Use the closest point on the surface if the click is outside the shape. | |
| 232 | + 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; | |
| 238 | + } | |
| 239 | + return body; | |
| 240 | +} | |
| 241 | + | |
| 242 | + | |
| 243 | +cpConstraint* PhysicsImpl::AddPivotJoint(cpBody* body1, cpBody* body2, Vector3 localPivot) | |
| 244 | +{ | |
| 245 | + cpVect pivot{localPivot.x, localPivot.y}; | |
| 246 | + cpConstraint* joint = cpPivotJointNew2(body2, body1, cpvzero, pivot); | |
| 247 | + cpConstraintSetMaxForce(joint, 50000.0f); // Magic numbers for mouse feedback. | |
| 248 | + cpConstraintSetErrorBias(joint, cpfpow(1.0f - 0.15f, 60.0f)); | |
| 249 | + cpConstraint* constraint = cpSpaceAddConstraint(mSpace, joint); | |
| 250 | + return constraint; // Constraint & joint are the same... | |
| 251 | +} | |
| 252 | + | |
| 253 | +void PhysicsImpl::MoveMouseBody(cpBody* mouseBody, Vector3 position) | |
| 254 | +{ | |
| 255 | + cpVect cpPosition = cpv(position.x, position.y); | |
| 256 | + cpVect newPoint = cpvlerp(cpBodyGetPosition(mouseBody), cpPosition, 0.25f); | |
| 257 | + cpBodySetVelocity(mouseBody, cpvmult(cpvsub(newPoint, cpBodyGetPosition(mouseBody)), 60.0f)); | |
| 258 | + // Normally, kinematic body's position would be calculated by engine. | |
| 259 | + // For mouse, though, we want to set it. | |
| 260 | + cpBodySetPosition(mouseBody, newPoint); | |
| 261 | +} | |
| 262 | + | |
| 263 | +void PhysicsImpl::MoveConstraint(cpConstraint* constraint, Vector3 newPosition) | |
| 264 | +{ | |
| 265 | +} | |
| 266 | + | |
| 267 | +void PhysicsImpl::ReleaseConstraint(cpConstraint* constraint) | |
| 268 | +{ | |
| 269 | + cpSpaceRemoveConstraint(mSpace, constraint); | |
| 270 | + cpConstraintFree(constraint); | |
| 271 | +} | |
| 272 | + | |
| 273 | +int PhysicsImpl::ActivateBody(cpBody* body) | |
| 274 | +{ | |
| 275 | + int oldState = cpBodyIsSleeping(body); | |
| 276 | + cpBodyActivate(body); | |
| 277 | + | |
| 278 | + return oldState; | |
| 279 | +} | |
| 280 | + | |
| 281 | +void PhysicsImpl::RestoreBodyState(cpBody* body, int oldState) | |
| 282 | +{ | |
| 283 | + if(oldState) | |
| 284 | + { | |
| 285 | + cpBodyActivate(body); | |
| 286 | + } | |
| 287 | + else | |
| 288 | + { | |
| 289 | + cpBodySleep(body); | |
| 290 | + } | |
| 291 | +} | ... | ... |
examples/chipmunk-physics/physics-impl.h
0 → 100644
| 1 | +#ifndef DALI_PHYSICS_DEMO_PHYSICS_IMPL_H | |
| 2 | +#define DALI_PHYSICS_DEMO_PHYSICS_IMPL_H | |
| 3 | +/* | |
| 4 | + * Copyright (c) 2023 Samsung Electronics Co., Ltd. | |
| 5 | + * | |
| 6 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
| 7 | + * you may not use this file except in compliance with the License. | |
| 8 | + * You may obtain a copy of the License at | |
| 9 | + * | |
| 10 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
| 11 | + * | |
| 12 | + * Unless required by applicable law or agreed to in writing, software | |
| 13 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
| 14 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 15 | + * See the License for the specific language governing permissions and | |
| 16 | + * limitations under the License. | |
| 17 | + * | |
| 18 | + */ | |
| 19 | + | |
| 20 | +#include <dali/dali.h> | |
| 21 | +#include <dali/devel-api/threading/mutex.h> | |
| 22 | +#include <dali/devel-api/common/stage-devel.h> | |
| 23 | + | |
| 24 | +#include <map> | |
| 25 | +#include <chipmunk/chipmunk.h> | |
| 26 | + | |
| 27 | +#include "physics-actor.h" | |
| 28 | +#include "frame-callback.h" | |
| 29 | + | |
| 30 | + | |
| 31 | +class PhysicsImpl : public Dali::ConnectionTracker | |
| 32 | +{ | |
| 33 | +public: | |
| 34 | + Dali::Actor Initialize(Dali::Window window); | |
| 35 | + | |
| 36 | + /** | |
| 37 | + * Create a layer & debug renderer | |
| 38 | + */ | |
| 39 | + Dali::Layer CreateDebug(Dali::Vector2 windowSize); | |
| 40 | + | |
| 41 | + /** | |
| 42 | + * Converts a point in RootActor local coords (e.g. gesture) | |
| 43 | + * into physics space coords. | |
| 44 | + * @param vector The point to convert | |
| 45 | + * @return The converted point | |
| 46 | + */ | |
| 47 | + Dali::Vector3 TranslateToPhysicsSpace(Dali::Vector3 vector); | |
| 48 | + | |
| 49 | + /** | |
| 50 | + * Converts a point in physics space coords. | |
| 51 | + * into RootActor local coords | |
| 52 | + * @param vector The point to convert | |
| 53 | + * @return The converted point | |
| 54 | + */ | |
| 55 | + Dali::Vector3 TranslateFromPhysicsSpace(Dali::Vector3 vector); | |
| 56 | + | |
| 57 | + /** | |
| 58 | + * Converts a vector in DALi space into physics space. | |
| 59 | + * @param vector The vector to convert | |
| 60 | + * @return The converted vector | |
| 61 | + */ | |
| 62 | + Dali::Vector3 ConvertVectorToPhysicsSpace(Dali::Vector3 vector); | |
| 63 | + | |
| 64 | + /** | |
| 65 | + * Converts a vector in physics space to DALi space | |
| 66 | + * @param vector The vector to convert | |
| 67 | + * @return The converted vector | |
| 68 | + */ | |
| 69 | + Dali::Vector3 ConvertVectorFromPhysicsSpace(Dali::Vector3 vector); | |
| 70 | + | |
| 71 | + /** | |
| 72 | + * Set up the transform from world space to physics space | |
| 73 | + * @param[in] worldSize The 2d bounding box of the world in screen space | |
| 74 | + */ | |
| 75 | + void SetTransform(Dali::Vector2 worldSize); | |
| 76 | + | |
| 77 | + /** | |
| 78 | + * Run the physics integration over the given timestep. | |
| 79 | + * @param timeStep | |
| 80 | + */ | |
| 81 | + void Integrate(float timeStep); | |
| 82 | + | |
| 83 | + /** | |
| 84 | + * Toggle the integration state. If it's turned on, physics will run | |
| 85 | + * during the frame callback. | |
| 86 | + */ | |
| 87 | + void ToggleIntegrateState() | |
| 88 | + { | |
| 89 | + mPhysicsIntegrateState ^= true; | |
| 90 | + } | |
| 91 | + | |
| 92 | + /** | |
| 93 | + * Toggle the debug state. If debug is turned on, use the physics engine | |
| 94 | + * debug to show wireframes. | |
| 95 | + */ | |
| 96 | + void ToggleDebugState() | |
| 97 | + { | |
| 98 | + mPhysicsDebugState ^= true; | |
| 99 | + } | |
| 100 | + | |
| 101 | + void CreateWorldBounds(Dali::Window::WindowSize size); | |
| 102 | + cpShape* AddBound(cpBody* staticBody, cpVect start, cpVect end); | |
| 103 | + PhysicsActor& AddBall(Dali::Actor actor, float mass, float radius, float elasticity, float friction); | |
| 104 | + PhysicsActor& AddBrick(Dali::Actor actor,float mass, float elasticity, float friction, Dali::Vector3 size); | |
| 105 | + | |
| 106 | + cpBody* AddMouseBody(); | |
| 107 | + | |
| 108 | + /** | |
| 109 | + * @param[in] screenCoords The touch point in screen coordinates | |
| 110 | + * @param[in] origin The camera origin in DALi world space | |
| 111 | + * @param[in] direction The ray direction in DALi world space | |
| 112 | + * @param[out] localPivot The hit point local to the body | |
| 113 | + * @param[out] distanceFromCamera The distance of the pick point from the camera | |
| 114 | + * @return nullptr if no dynamic body found, otherwise a valid ptr to the hit body. | |
| 115 | + */ | |
| 116 | + cpBody* HitTest(Dali::Vector2 screenCoords, Dali::Vector3 origin, Dali::Vector3 direction, | |
| 117 | + Dali::Vector3& localPivot, float& distanceFromCamera); | |
| 118 | + | |
| 119 | + cpConstraint* AddPivotJoint(cpBody* body1, cpBody* body2, Dali::Vector3 localPivot); | |
| 120 | + | |
| 121 | + void MoveMouseBody(cpBody* mouseBody, Dali::Vector3 position); | |
| 122 | + | |
| 123 | + void MoveConstraint(cpConstraint* constraint, Dali::Vector3 newPosition); | |
| 124 | + | |
| 125 | + void ReleaseConstraint(cpConstraint* constraint); | |
| 126 | + | |
| 127 | + /** | |
| 128 | + * Ensure that the physics body does not go to sleep | |
| 129 | + * @param[in] body The physics body | |
| 130 | + * @return The old state | |
| 131 | + */ | |
| 132 | + int ActivateBody(cpBody* body); | |
| 133 | + | |
| 134 | + /** | |
| 135 | + * Restore the state of the physics body | |
| 136 | + * @param[in] body The physics body | |
| 137 | + * @param[in] oldState The previous state to restore | |
| 138 | + */ | |
| 139 | + void RestoreBodyState(cpBody* body, int oldState); | |
| 140 | + | |
| 141 | + /** | |
| 142 | + * Get the physics actor associated with the given body | |
| 143 | + * @param[in] body The physics body | |
| 144 | + * @return the associated physics actor | |
| 145 | + */ | |
| 146 | + PhysicsActor* GetPhysicsActor(cpBody* body); | |
| 147 | + | |
| 148 | + /** | |
| 149 | + * Set the highlight state of the actor associated with the physics body | |
| 150 | + * @param[in] body The physics body | |
| 151 | + * @param[in] highlight Whether to turn the highlight on or off. | |
| 152 | + */ | |
| 153 | + void HighlightBody(cpBody* body, bool highlight); | |
| 154 | + | |
| 155 | + | |
| 156 | +public: | |
| 157 | + std::map<uint32_t, PhysicsActor> mPhysicsActors; | |
| 158 | + bool mPhysicsIntegrateState{true}; | |
| 159 | + bool mPhysicsDebugState{true}; | |
| 160 | + | |
| 161 | + cpSpace* mSpace; | |
| 162 | + cpShape* mLeftBound{nullptr}; | |
| 163 | + cpShape* mRightBound{nullptr}; | |
| 164 | + cpShape* mTopBound{nullptr}; | |
| 165 | + cpShape* mBottomBound{nullptr}; | |
| 166 | + | |
| 167 | + Dali::Window mWindow; | |
| 168 | + Dali::Mutex mMutex; | |
| 169 | + | |
| 170 | + Dali::Actor mPhysicsRoot; | |
| 171 | + Dali::Vector2 mWorldOffset; | |
| 172 | + FrameCallback* mFrameCallback; | |
| 173 | +}; | |
| 174 | + | |
| 175 | +#endif // DALI_PHYSICS_DEMO_PHYSICS_IMPL_H | ... | ... |
examples/chipmunk-physics/shaders/rendering-textured-shape.frag
0 → 100644
| 1 | +uniform sampler2D uTexture; | |
| 2 | +uniform mediump float uBrightness; | |
| 3 | +varying mediump vec2 vTexCoord; | |
| 4 | +varying mediump vec3 vIllumination; | |
| 5 | + | |
| 6 | +mediump vec3 redistribute_rgb(mediump vec3 color) | |
| 7 | +{ | |
| 8 | + mediump float threshold = 0.9999999; | |
| 9 | + mediump float m = max(max(color.r, color.g), color.b); | |
| 10 | + if(m <= threshold) | |
| 11 | + { | |
| 12 | + return color; | |
| 13 | + } | |
| 14 | + mediump float total = color.r + color.g + color.b; | |
| 15 | + if( total >= 3.0 * threshold) | |
| 16 | + { | |
| 17 | + return vec3(threshold); | |
| 18 | + } | |
| 19 | + mediump float x = (3.0 * threshold - total) / (3.0 * m - total); | |
| 20 | + mediump float gray = threshold - x * m; | |
| 21 | + return vec3(gray) + vec3(x)*color; | |
| 22 | +} | |
| 23 | + | |
| 24 | +void main() | |
| 25 | +{ | |
| 26 | + mediump vec4 texColor = texture2D( uTexture, vTexCoord ); | |
| 27 | + mediump vec3 pcol=texColor.rgb*(1.0+uBrightness); | |
| 28 | + gl_FragColor = vec4( redistribute_rgb(pcol), texColor.a); | |
| 29 | +} | |
| 0 | 30 | \ No newline at end of file | ... | ... |
examples/chipmunk-physics/shaders/rendering-textured-shape.vert
0 → 100644
| 1 | +attribute mediump vec3 aPosition; // DALi shader builtin | |
| 2 | +//attribute mediump vec2 aTexCoord; // DALi shader builtin | |
| 3 | +uniform mediump mat4 uMvpMatrix; // DALi shader builtin | |
| 4 | +uniform mediump mat4 uViewMatrix; // DALi shader builtin | |
| 5 | +uniform mediump mat4 uModelView; // DALi shader builtin | |
| 6 | +uniform mediump vec3 uSize; // DALi shader builtin | |
| 7 | +varying mediump vec3 vIllumination; | |
| 8 | +varying mediump vec2 vTexCoord; | |
| 9 | + | |
| 10 | +void main() | |
| 11 | +{ | |
| 12 | + mediump vec4 vertexPosition = vec4(aPosition, 1.0); | |
| 13 | + mediump vec3 normal = normalize(vertexPosition.xyz); | |
| 14 | + | |
| 15 | + vertexPosition.xyz *= uSize; | |
| 16 | + vec4 pos = uModelView * vertexPosition; | |
| 17 | + | |
| 18 | + vec4 lightPosition = vec4(400.0, 0.0, 100.0, 1.0); | |
| 19 | + vec4 mvLightPos = uViewMatrix * lightPosition; | |
| 20 | + vec3 vectorToLight = normalize(mvLightPos.xyz - pos.xyz); | |
| 21 | + float lightDiffuse = max(dot(vectorToLight, normal), 0.0); | |
| 22 | + | |
| 23 | + vIllumination = vec3(lightDiffuse * 0.5 + 0.5); | |
| 24 | + vTexCoord = aPosition.xy*2.0; | |
| 25 | + gl_Position = uMvpMatrix * vertexPosition; | |
| 26 | +} | |
| 0 | 27 | \ No newline at end of file | ... | ... |
packaging/com.samsung.dali-demo.spec
| ... | ... | @@ -23,6 +23,7 @@ BuildRequires: pkgconfig(dali2-core) |
| 23 | 23 | BuildRequires: pkgconfig(dali2-adaptor) |
| 24 | 24 | BuildRequires: pkgconfig(dali2-toolkit) |
| 25 | 25 | BuildRequires: pkgconfig(dali2-scene3d) |
| 26 | +BuildRequires: pkgconfig(dali2-physics-2d) | |
| 26 | 27 | BuildRequires: pkgconfig(libtzplatform-config) |
| 27 | 28 | BuildRequires: pkgconfig(gles20) |
| 28 | 29 | BuildRequires: pkgconfig(glesv2) | ... | ... |
resources/po/en_GB.po
| ... | ... | @@ -43,6 +43,9 @@ msgstr "Card Active" |
| 43 | 43 | msgid "DALI_DEMO_STR_TITLE_COMPRESSED_TEXTURE_FORMATS" |
| 44 | 44 | msgstr "Compressed Texture Formats" |
| 45 | 45 | |
| 46 | +msgid "DALI_DEMO_STR_TITLE_CHIPMUNK_PHYSICS" | |
| 47 | +msgstr "Chipmunk Physics" | |
| 48 | + | |
| 46 | 49 | msgid "DALI_DEMO_STR_TITLE_CLIPPING" |
| 47 | 50 | msgstr "Clipping" |
| 48 | 51 | ... | ... |
resources/po/en_US.po
| ... | ... | @@ -46,6 +46,9 @@ msgstr "Card Active" |
| 46 | 46 | msgid "DALI_DEMO_STR_TITLE_COMPRESSED_TEXTURE_FORMATS" |
| 47 | 47 | msgstr "Compressed Texture Formats" |
| 48 | 48 | |
| 49 | +msgid "DALI_DEMO_STR_TITLE_CHIPMUNK_PHYSICS" | |
| 50 | +msgstr "Chipmunk Physics" | |
| 51 | + | |
| 49 | 52 | msgid "DALI_DEMO_STR_TITLE_CLIPPING" |
| 50 | 53 | msgstr "Clipping" |
| 51 | 54 | ... | ... |
shared/dali-demo-strings.h
| ... | ... | @@ -50,6 +50,7 @@ extern "C" |
| 50 | 50 | #define DALI_DEMO_STR_TITLE_CANVAS_VIEW dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_CANVAS_VIEW") |
| 51 | 51 | #define DALI_DEMO_STR_TITLE_CALL_ACTIVE dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_CALL_ACTIVE") |
| 52 | 52 | #define DALI_DEMO_STR_TITLE_CARD_ACTIVE dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_CARD_ACTIVE") |
| 53 | +#define DALI_DEMO_STR_TITLE_CHIPMUNK_PHYSICS dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_CHIPMUNK_PHYSICS") | |
| 53 | 54 | #define DALI_DEMO_STR_TITLE_CLIPPING dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_CLIPPING") |
| 54 | 55 | #define DALI_DEMO_STR_TITLE_CLIPPING_DRAW_ORDER dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_CLIPPING_DRAW_ORDER") |
| 55 | 56 | #define DALI_DEMO_STR_TITLE_COLOR_TRANSITION dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_COLOR_TRANSITION") |
| ... | ... | @@ -169,6 +170,7 @@ extern "C" |
| 169 | 170 | #define DALI_DEMO_STR_TITLE_CANVAS_VIEW "Canvas View" |
| 170 | 171 | #define DALI_DEMO_STR_TITLE_CALL_ACTIVE "Call Active" |
| 171 | 172 | #define DALI_DEMO_STR_TITLE_CARD_ACTIVE "Card Active" |
| 173 | +#define DALI_DEMO_STR_TITLE_CHIPMUNK_PHYSICS "Chipmunk Physics" | |
| 172 | 174 | #define DALI_DEMO_STR_TITLE_CLIPPING "Clipping" |
| 173 | 175 | #define DALI_DEMO_STR_TITLE_CLIPPING_DRAW_ORDER "Clipping Draw Order" |
| 174 | 176 | #define DALI_DEMO_STR_TITLE_COLOR_TRANSITION "Color Transition" | ... | ... |