Commit 0fb7eb9844f083c4edb33d1fe1ae3585cbb58659
1 parent
d9f0323e
Added bullet-physics-demo
Added mechanism to handle optional dependencies Change-Id: Ib24df94c68bb1cca58ff8fbb2be3d32cc5668ed0
Showing
19 changed files
with
1297 additions
and
21 deletions
.gitignore
| @@ -60,6 +60,10 @@ simple-image-wall.js | @@ -60,6 +60,10 @@ simple-image-wall.js | ||
| 60 | /com.samsung.dali-demo-debugsource.manifest | 60 | /com.samsung.dali-demo-debugsource.manifest |
| 61 | /build/tizen/*.vcxproj | 61 | /build/tizen/*.vcxproj |
| 62 | /build/tizen/*.vcxproj.filters | 62 | /build/tizen/*.vcxproj.filters |
| 63 | +/build/tizen/.ninja_deps | ||
| 64 | +/build/tizen/.ninja_log | ||
| 65 | +/build/tizen/build.ninja | ||
| 66 | +/build/tizen/rules.ninja | ||
| 63 | /build/tizen/builder/Debug/* | 67 | /build/tizen/builder/Debug/* |
| 64 | /build/tizen/builder/Release/* | 68 | /build/tizen/builder/Release/* |
| 65 | /build/tizen/builder/*.dir | 69 | /build/tizen/builder/*.dir |
build/tizen/CMakeLists.txt
| @@ -243,21 +243,39 @@ IF( ENABLE_PKG_CONFIGURE ) | @@ -243,21 +243,39 @@ IF( ENABLE_PKG_CONFIGURE ) | ||
| 243 | SET( ENABLE_SCENE3D "ON" ) | 243 | SET( ENABLE_SCENE3D "ON" ) |
| 244 | ENDIF() | 244 | ENDIF() |
| 245 | 245 | ||
| 246 | - pkg_check_modules(DALI_PHYSICS_2D dali2-physics-2d) | 246 | + pkg_check_modules(DALI_PHYSICS_2D dali2-physics-2d chipmunk2d) |
| 247 | IF( DALI_PHYSICS_2D_FOUND ) | 247 | IF( DALI_PHYSICS_2D_FOUND ) |
| 248 | FOREACH(flag ${DALI_PHYSICS_2D_CFLAGS}) | 248 | FOREACH(flag ${DALI_PHYSICS_2D_CFLAGS}) |
| 249 | - SET(REQUIRED_CFLAGS "${REQUIRED_CFLAGS} ${flag}") | 249 | + SET(OPTIONAL_PHYSICS_2D_CFLAGS "${OPTIONAL_PHYSICS_2D_CFLAGS} ${flag}") |
| 250 | ENDFOREACH(flag) | 250 | ENDFOREACH(flag) |
| 251 | - | ||
| 252 | - SET( REQUIRED_CFLAGS "${REQUIRED_CFLAGS} -DDALI_PHYSICS_2D_AVAILABLE" ) | 251 | + SET(OPTIONAL_PHYSICS_2D_CFLAGS "${OPTIONAL_PHYSICS_2D_CFLAGS} -DDALI_PHYSICS_2D_AVAILABLE" ) |
| 252 | + STRING(STRIP ${OPTIONAL_PHYSICS_2D_CFLAGS} OPTIONAL_PHYSICS_2D_CFLAGS) | ||
| 253 | 253 | ||
| 254 | FOREACH(flag ${DALI_PHYSICS_2D_LDFLAGS}) | 254 | FOREACH(flag ${DALI_PHYSICS_2D_LDFLAGS}) |
| 255 | - SET(REQUIRED_PKGS_LDFLAGS "${REQUIRED_PKGS_LDFLAGS} ${flag}") | 255 | + SET(OPTIONAL_PHYSICS_2D_LDFLAGS "${OPTIONAL_PHYSICS_2D_LDFLAGS} ${flag}") |
| 256 | ENDFOREACH(flag) | 256 | ENDFOREACH(flag) |
| 257 | + STRING(STRIP ${OPTIONAL_PHYSICS_2D_LDFLAGS} OPTIONAL_PHYSICS_2D_LDFLAGS) | ||
| 257 | 258 | ||
| 258 | SET( ENABLE_PHYSICS_2D "ON" ) | 259 | SET( ENABLE_PHYSICS_2D "ON" ) |
| 259 | ENDIF() | 260 | ENDIF() |
| 260 | 261 | ||
| 262 | + pkg_check_modules(DALI_PHYSICS_3D dali2-physics-3d bullet3) | ||
| 263 | + IF( DALI_PHYSICS_3D_FOUND ) | ||
| 264 | + FOREACH(flag ${DALI_PHYSICS_3D_CFLAGS}) | ||
| 265 | + SET(OPTIONAL_PHYSICS_3D_CFLAGS "${OPTIONAL_PHYSICS_3D_CFLAGS} ${flag}") | ||
| 266 | + ENDFOREACH(flag) | ||
| 267 | + | ||
| 268 | + SET( OPTIONAL_PHYSICS_3D_CFLAGS "${OPTIONAL_PHYSICS_3D_CFLAGS} -DDALI_PHYSICS_3D_AVAILABLE" ) | ||
| 269 | + STRING(STRIP ${OPTIONAL_PHYSICS_3D_CFLAGS} OPTIONAL_PHYSICS_3D_CFLAGS) | ||
| 270 | + | ||
| 271 | + FOREACH(flag ${DALI_PHYSICS_3D_LDFLAGS}) | ||
| 272 | + SET(OPTIONAL_PHYSICS_3D_LDFLAGS "${OPTIONAL_PHYSICS_3D_LDFLAGS} ${flag}") | ||
| 273 | + ENDFOREACH(flag) | ||
| 274 | + STRING(STRIP ${OPTIONAL_PHYSICS_3D_LDFLAGS} OPTIONAL_PHYSICS_3D_LDFLAGS) | ||
| 275 | + | ||
| 276 | + SET( ENABLE_PHYSICS_3D "ON" ) | ||
| 277 | + ENDIF() | ||
| 278 | + | ||
| 261 | # if build as tizen platform, use capi-appfw-app-control | 279 | # if build as tizen platform, use capi-appfw-app-control |
| 262 | IF( TIZEN ) | 280 | IF( TIZEN ) |
| 263 | pkg_check_modules(CAPI_APPFW_APP_CONTROL capi-appfw-app-control) | 281 | pkg_check_modules(CAPI_APPFW_APP_CONTROL capi-appfw-app-control) |
| @@ -308,6 +326,8 @@ IF( WIN32 OR APPLE ) # WIN32 includes x64 as well according to the cmake doc. | @@ -308,6 +326,8 @@ IF( WIN32 OR APPLE ) # WIN32 includes x64 as well according to the cmake doc. | ||
| 308 | FIND_PACKAGE( dali2-scene3d ) | 326 | FIND_PACKAGE( dali2-scene3d ) |
| 309 | 327 | ||
| 310 | FIND_PACKAGE( chipmunk ) | 328 | FIND_PACKAGE( chipmunk ) |
| 329 | + FIND_PACKAGE( bullet3 ) | ||
| 330 | + FIND_PACKAGE( dali2-physics-3d ) | ||
| 311 | 331 | ||
| 312 | # Set up the include dir | 332 | # Set up the include dir |
| 313 | SET( INCLUDE_DIR $ENV{includedir} ) | 333 | SET( INCLUDE_DIR $ENV{includedir} ) |
| @@ -365,11 +385,17 @@ IF( WIN32 OR APPLE ) # WIN32 includes x64 as well according to the cmake doc. | @@ -365,11 +385,17 @@ IF( WIN32 OR APPLE ) # WIN32 includes x64 as well according to the cmake doc. | ||
| 365 | ENDIF() | 385 | ENDIF() |
| 366 | 386 | ||
| 367 | IF (chipmunk_FOUND) | 387 | IF (chipmunk_FOUND) |
| 368 | - SET(REQUIRED_LIBS | ||
| 369 | - ${REQUIRED_LIBS} | ||
| 370 | - -lchipmunk | ||
| 371 | - ) | ||
| 372 | - SET( ENABLE_PHYSICS_2D "ON" ) | 388 | + SET(DALI_PHYSICS_2D_LDFLAGS ${DALI_PHYSICS_2D_LDFLAGS} -lchipmunk) |
| 389 | + SET(ENABLE_PHYSICS_2D "ON" ) | ||
| 390 | + ENDIF() | ||
| 391 | + | ||
| 392 | + IF (bullet3_FOUND) | ||
| 393 | + SET(DALI_PHYSICS_3D_LDFLAGS ${OPTIONAL_PHYSICS_3D_LDFLAGS} -lbullet3) | ||
| 394 | + SET(ENABLE_PHYSICS_3D "ON" ) | ||
| 395 | + ENDIF() | ||
| 396 | + | ||
| 397 | + IF (dali2-physics-3d_FOUND) | ||
| 398 | + SET(DALI_PHYSICS_3D_LDFLAGS ${DALI_PHYSICS_3D_LDFLAGS} dali2-physics-3d::dali2-physics-3d) | ||
| 373 | ENDIF() | 399 | ENDIF() |
| 374 | 400 | ||
| 375 | ELSEIF( UNIX ) | 401 | ELSEIF( UNIX ) |
| @@ -404,6 +430,10 @@ IF( ENABLE_PHYSICS_2D ) | @@ -404,6 +430,10 @@ IF( ENABLE_PHYSICS_2D ) | ||
| 404 | SET(DALI_DEMO_CFLAGS "${DALI_DEMO_CFLAGS} -DDALI_PHYSICS_2D_AVAILABLE") | 430 | SET(DALI_DEMO_CFLAGS "${DALI_DEMO_CFLAGS} -DDALI_PHYSICS_2D_AVAILABLE") |
| 405 | ENDIF() | 431 | ENDIF() |
| 406 | 432 | ||
| 433 | +IF( ENABLE_PHYSICS_3D ) | ||
| 434 | + SET(DALI_DEMO_CFLAGS "${DALI_DEMO_CFLAGS} -DDALI_PHYSICS_3D_AVAILABLE") | ||
| 435 | +ENDIF() | ||
| 436 | + | ||
| 407 | IF( UNIX ) | 437 | IF( UNIX ) |
| 408 | IF( NOT ${ENABLE_EXPORTALL} ) | 438 | IF( NOT ${ENABLE_EXPORTALL} ) |
| 409 | ADD_DEFINITIONS( "-DHIDE_DALI_INTERNALS" ) | 439 | ADD_DEFINITIONS( "-DHIDE_DALI_INTERNALS" ) |
| @@ -522,3 +552,4 @@ MESSAGE( " Current Build Platform : [" ${CURRENT_BUILD_PLATFORM} "]" ) | @@ -522,3 +552,4 @@ MESSAGE( " Current Build Platform : [" ${CURRENT_BUILD_PLATFORM} "]" ) | ||
| 522 | MESSAGE( " Build example name : [" ${CURRENT_BUILD_EXAMPLE_NAME} "]" ) | 552 | MESSAGE( " Build example name : [" ${CURRENT_BUILD_EXAMPLE_NAME} "]" ) |
| 523 | MESSAGE( " Scene3D Enabled : [" ${ENABLE_SCENE3D} "]" ) | 553 | MESSAGE( " Scene3D Enabled : [" ${ENABLE_SCENE3D} "]" ) |
| 524 | MESSAGE( " Physics 2D Enabled : [" ${ENABLE_PHYSICS_2D} "]" ) | 554 | MESSAGE( " Physics 2D Enabled : [" ${ENABLE_PHYSICS_2D} "]" ) |
| 555 | +MESSAGE( " Physics 3D Enabled : [" ${ENABLE_PHYSICS_3D} "]" ) |
build/tizen/examples/CMakeLists.txt
| @@ -35,6 +35,7 @@ ENDIF() | @@ -35,6 +35,7 @@ ENDIF() | ||
| 35 | FUNCTION(INSTALL_EXAMPLES EXAMPLE) | 35 | FUNCTION(INSTALL_EXAMPLES EXAMPLE) |
| 36 | SET(PARENT_CMAKE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../") | 36 | SET(PARENT_CMAKE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../") |
| 37 | FILE(GLOB_RECURSE SRCS "${EXAMPLES_SRC_DIR}/${EXAMPLE}/*.cpp") | 37 | FILE(GLOB_RECURSE SRCS "${EXAMPLES_SRC_DIR}/${EXAMPLE}/*.cpp") |
| 38 | + | ||
| 38 | SET(SRCS ${SRCS} "${ROOT_SRC_DIR}/shared/resources-location.cpp") | 39 | SET(SRCS ${SRCS} "${ROOT_SRC_DIR}/shared/resources-location.cpp") |
| 39 | IF(SHARED) | 40 | IF(SHARED) |
| 40 | ADD_LIBRARY(${EXAMPLE}.example SHARED ${SRCS}) | 41 | ADD_LIBRARY(${EXAMPLE}.example SHARED ${SRCS}) |
| @@ -42,6 +43,10 @@ FUNCTION(INSTALL_EXAMPLES EXAMPLE) | @@ -42,6 +43,10 @@ FUNCTION(INSTALL_EXAMPLES EXAMPLE) | ||
| 42 | ADD_EXECUTABLE(${EXAMPLE}.example ${SRCS}) | 43 | ADD_EXECUTABLE(${EXAMPLE}.example ${SRCS}) |
| 43 | ENDIF() | 44 | ENDIF() |
| 44 | 45 | ||
| 46 | + IF(EXISTS ${EXAMPLES_SRC_DIR}/${EXAMPLE}/dependencies.cmake) | ||
| 47 | + INCLUDE( ${EXAMPLES_SRC_DIR}/${EXAMPLE}/dependencies.cmake OPTIONAL) | ||
| 48 | + endif() | ||
| 49 | + | ||
| 45 | # Generate source files for shaders | 50 | # Generate source files for shaders |
| 46 | SET(SHADER_SOURCE_DIR "${EXAMPLES_SRC_DIR}/${EXAMPLE}/shaders/") | 51 | SET(SHADER_SOURCE_DIR "${EXAMPLES_SRC_DIR}/${EXAMPLE}/shaders/") |
| 47 | IF (EXISTS ${SHADER_SOURCE_DIR}) | 52 | IF (EXISTS ${SHADER_SOURCE_DIR}) |
| @@ -64,4 +69,3 @@ IF( NOT BUILD_EXAMPLE_NAME ) | @@ -64,4 +69,3 @@ IF( NOT BUILD_EXAMPLE_NAME ) | ||
| 64 | ELSE() | 69 | ELSE() |
| 65 | INSTALL_EXAMPLES(${BUILD_EXAMPLE_NAME}) | 70 | INSTALL_EXAMPLES(${BUILD_EXAMPLE_NAME}) |
| 66 | ENDIF() | 71 | ENDIF() |
| 67 | - |
com.samsung.dali-demo.xml
| @@ -58,6 +58,9 @@ | @@ -58,6 +58,9 @@ | ||
| 58 | <ui-application appid="builder.example" exec="/usr/apps/com.samsung.dali-demo/bin/builder.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true"> | 58 | <ui-application appid="builder.example" exec="/usr/apps/com.samsung.dali-demo/bin/builder.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true"> |
| 59 | <label>Script Based UI</label> | 59 | <label>Script Based UI</label> |
| 60 | </ui-application> | 60 | </ui-application> |
| 61 | + <ui-application appid="bullet-physics.example" exec="/usr/apps/com.samsung.dali-demo/bin/bullet-physics.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true"> | ||
| 62 | + <label>Bullet Physics</label> | ||
| 63 | + </ui-application> | ||
| 61 | <ui-application appid="buttons.example" exec="/usr/apps/com.samsung.dali-demo/bin/buttons.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true"> | 64 | <ui-application appid="buttons.example" exec="/usr/apps/com.samsung.dali-demo/bin/buttons.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true"> |
| 62 | <label>Buttons</label> | 65 | <label>Buttons</label> |
| 63 | </ui-application> | 66 | </ui-application> |
examples-reel/dali-examples-reel.cpp
| @@ -46,6 +46,7 @@ int DALI_EXPORT_API main(int argc, char** argv) | @@ -46,6 +46,7 @@ int DALI_EXPORT_API main(int argc, char** argv) | ||
| 46 | demo.AddExample(Example("bloom-view.example", DALI_DEMO_STR_TITLE_BLOOM_VIEW)); | 46 | demo.AddExample(Example("bloom-view.example", DALI_DEMO_STR_TITLE_BLOOM_VIEW)); |
| 47 | demo.AddExample(Example("builder.example", DALI_DEMO_STR_TITLE_SCRIPT_BASED_UI)); | 47 | demo.AddExample(Example("builder.example", DALI_DEMO_STR_TITLE_SCRIPT_BASED_UI)); |
| 48 | demo.AddExample(Example("buttons.example", DALI_DEMO_STR_TITLE_BUTTONS)); | 48 | demo.AddExample(Example("buttons.example", DALI_DEMO_STR_TITLE_BUTTONS)); |
| 49 | + demo.AddExample(Example("bullet-physics.example", DALI_DEMO_STR_TITLE_BULLET_PHYSICS)); | ||
| 49 | demo.AddExample(Example("canvas-view.example", DALI_DEMO_STR_TITLE_CANVAS_VIEW)); | 50 | 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)); | 51 | demo.AddExample(Example("chipmunk-physics.example", DALI_DEMO_STR_TITLE_CHIPMUNK_PHYSICS)); |
| 51 | demo.AddExample(Example("clipping.example", DALI_DEMO_STR_TITLE_CLIPPING)); | 52 | demo.AddExample(Example("clipping.example", DALI_DEMO_STR_TITLE_CLIPPING)); |
examples/bullet-physics/README.md
0 โ 100644
| 1 | +# Bullet physics example | ||
| 2 | + | ||
| 3 | +This is an example showing how to use the Bullet physics library to create and control | ||
| 4 | +physics objects in DALi. | ||
| 5 | + | ||
| 6 | +It creates a pyramid of bricks and a ball falling onto a large block. | ||
| 7 | + | ||
| 8 | +The user can select and drag any of the actors with the mouse. | ||
| 9 | +The user can zoom in and out using the mouse wheel. | ||
| 10 | + | ||
| 11 | +"wasd" keys move the last touched actor up/down/left/right. | ||
| 12 | +"qe" keys rotate the last touched actor in Z axis | ||
| 13 | +"zx" keys rotate the last touched actor in Y axis | ||
| 14 | +"cv" keys rotate the last touched actor in X axis | ||
| 15 | +"p" key resets the position/forces on the last touched actor to the origin | ||
| 16 | + | ||
| 17 | +"m" key toggles the debug rendering | ||
| 18 | +Space key toggles the integration state. | ||
| 19 | + | ||
| 20 | + |
examples/bullet-physics/ball-renderer.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 "ball-renderer.h" | ||
| 18 | +#include <dali-toolkit/dali-toolkit.h> | ||
| 19 | +#include "cube-renderer.h" | ||
| 20 | +#include "generated/rendering-textured-shape-frag.h" | ||
| 21 | +#include "generated/rendering-textured-shape-vert.h" | ||
| 22 | + | ||
| 23 | +using namespace Dali; | ||
| 24 | + | ||
| 25 | +namespace | ||
| 26 | +{ | ||
| 27 | +const char* TEXTURE_URL = DEMO_IMAGE_DIR "/background-3.jpg"; | ||
| 28 | +} // namespace | ||
| 29 | + | ||
| 30 | +Dali::Geometry BallRenderer::gBallGeometry; | ||
| 31 | +Dali::TextureSet BallRenderer::gBallTextureSet; | ||
| 32 | + | ||
| 33 | +struct Vertex | ||
| 34 | +{ | ||
| 35 | + Vector3 aPosition; | ||
| 36 | + Vector2 aTexCoord; | ||
| 37 | +}; | ||
| 38 | + | ||
| 39 | +void SubDivide(std::vector<Vertex>& vertices, std::vector<uint16_t>& indices) | ||
| 40 | +{ | ||
| 41 | + uint16_t triangleCount = indices.size() / 3; | ||
| 42 | + for(uint16_t i = 0; i < triangleCount; ++i) | ||
| 43 | + { | ||
| 44 | + auto v1 = vertices[indices[i * 3]].aPosition; | ||
| 45 | + auto v2 = vertices[indices[i * 3 + 1]].aPosition; | ||
| 46 | + auto v3 = vertices[indices[i * 3 + 2]].aPosition; | ||
| 47 | + // Triangle subdivision adds pts halfway along each edge. | ||
| 48 | + auto v4 = v1 + (v2 - v1) * 0.5f; | ||
| 49 | + auto v5 = v2 + (v3 - v2) * 0.5f; | ||
| 50 | + auto v6 = v3 + (v1 - v3) * 0.5f; | ||
| 51 | + uint16_t j = vertices.size(); | ||
| 52 | + vertices.emplace_back(Vertex{ | ||
| 53 | + {v4}, | ||
| 54 | + }); | ||
| 55 | + vertices.emplace_back(Vertex{ | ||
| 56 | + {v5}, | ||
| 57 | + }); | ||
| 58 | + vertices.emplace_back(Vertex{ | ||
| 59 | + {v6}, | ||
| 60 | + }); | ||
| 61 | + // Now, original tri breaks into 4, so replace this tri, and add 3 more | ||
| 62 | + uint16_t i1 = indices[i * 3 + 1]; | ||
| 63 | + uint16_t i2 = indices[i * 3 + 2]; | ||
| 64 | + indices[i * 3 + 1] = j; | ||
| 65 | + indices[i * 3 + 2] = j + 2; | ||
| 66 | + | ||
| 67 | + std::vector<uint16_t> newTris = {j, i1, uint16_t(j + 1), j, uint16_t(j + 1), uint16_t(j + 2), uint16_t(j + 1), i2, uint16_t(j + 2)}; | ||
| 68 | + indices.insert(indices.end(), newTris.begin(), newTris.end()); | ||
| 69 | + } | ||
| 70 | + for(auto& vertex : vertices) | ||
| 71 | + { | ||
| 72 | + vertex.aPosition.Normalize(); | ||
| 73 | + } | ||
| 74 | +} | ||
| 75 | + | ||
| 76 | +void MapUVsToSphere(std::vector<Vertex>& vertices) | ||
| 77 | +{ | ||
| 78 | + // Convert world coords to long-lat | ||
| 79 | + // Assume radius=1; | ||
| 80 | + // V=(cos(long)cos(lat), sin(long)cos(lat), sin(lat)) | ||
| 81 | + // => lat=arcsin(z), range (-PI/2, PI/2); => 0.5+(asin(z)/PI) range(0,1) | ||
| 82 | + // => y/x = sin(long)/cos(long) => long = atan2(y/x), range(-pi, pi) | ||
| 83 | + // But, rotate 90 deg for portrait texture! | ||
| 84 | + for(auto& vertex : vertices) | ||
| 85 | + { | ||
| 86 | + vertex.aTexCoord.y = 1.0f + (atan2f(vertex.aPosition.y, vertex.aPosition.x) / (2.0f * Math::PI)); | ||
| 87 | + vertex.aTexCoord.x = 1.0f - (0.5f + (asinf(vertex.aPosition.z) / Math::PI)); | ||
| 88 | + } | ||
| 89 | +} | ||
| 90 | + | ||
| 91 | +/** | ||
| 92 | + * @brief CreateBallGeometry | ||
| 93 | + * This function creates a ball geometry including texture coordinates. | ||
| 94 | + */ | ||
| 95 | +Geometry BallRenderer::CreateBallGeometry() | ||
| 96 | +{ | ||
| 97 | + if(!gBallGeometry) | ||
| 98 | + { | ||
| 99 | + float phi = (1.0f + sqrt(5.0f)) * 0.5f; // golden ratio | ||
| 100 | + float a = 1.0f; | ||
| 101 | + float b = 1.0f / phi; | ||
| 102 | + | ||
| 103 | + // add vertices | ||
| 104 | + std::vector<Vertex> vertices; | ||
| 105 | + vertices.emplace_back(Vertex{Vector3{0, b, -a}}); | ||
| 106 | + vertices.emplace_back(Vertex{Vector3{b, a, 0}}); | ||
| 107 | + vertices.emplace_back(Vertex{Vector3{-b, a, -a}}); | ||
| 108 | + | ||
| 109 | + vertices.emplace_back(Vertex{Vector3{0, b, a}}); | ||
| 110 | + vertices.emplace_back(Vertex{Vector3{0, -b, a}}); | ||
| 111 | + vertices.emplace_back(Vertex{Vector3{-a, 0, b}}); | ||
| 112 | + | ||
| 113 | + vertices.emplace_back(Vertex{Vector3{0, -b, -a}}); | ||
| 114 | + vertices.emplace_back(Vertex{Vector3{a, 0, -b}}); | ||
| 115 | + vertices.emplace_back(Vertex{Vector3{a, 0, b}}); | ||
| 116 | + | ||
| 117 | + vertices.emplace_back(Vertex{Vector3{-a, 0, -b}}); | ||
| 118 | + vertices.emplace_back(Vertex{Vector3{b, -a, 0}}); | ||
| 119 | + vertices.emplace_back(Vertex{Vector3{-b, -a, 0}}); | ||
| 120 | + | ||
| 121 | + for(auto vertex : vertices) | ||
| 122 | + { | ||
| 123 | + vertex.aPosition.Normalize(); | ||
| 124 | + } | ||
| 125 | + | ||
| 126 | + // this dodgy code is not zero indexed but starts at 1. | ||
| 127 | + std::vector<uint16_t> indices = { | ||
| 128 | + 3, 2, 1, 2, 3, 4, 6, 5, 4, 5, 9, 4, 8, 7, 1, 7, 10, 1, 12, 11, 5, 11, 12, 7, 10, 6, 3, 6, 10, 12, 9, 8, 2, 8, 9, 11, 3, 6, 4, 9, 2, 4, 10, 3, 1, 2, 8, 1, 12, 10, 7, 8, 11, 7, 6, 12, 5, 11, 9, 5}; | ||
| 129 | + // fix offset indices | ||
| 130 | + for(auto& index : indices) | ||
| 131 | + { | ||
| 132 | + --index; | ||
| 133 | + } | ||
| 134 | + | ||
| 135 | + // 2 subdivisions gives a reasonably nice sphere | ||
| 136 | + SubDivide(vertices, indices); | ||
| 137 | + SubDivide(vertices, indices); | ||
| 138 | + | ||
| 139 | + MapUVsToSphere(vertices); | ||
| 140 | + | ||
| 141 | + VertexBuffer vertexBuffer = VertexBuffer::New(Property::Map() | ||
| 142 | + .Add("aPosition", Property::VECTOR3) | ||
| 143 | + .Add("aTexCoord", Property::VECTOR2)); | ||
| 144 | + vertexBuffer.SetData(&vertices[0], vertices.size()); | ||
| 145 | + | ||
| 146 | + gBallGeometry = Geometry::New(); | ||
| 147 | + gBallGeometry.AddVertexBuffer(vertexBuffer); | ||
| 148 | + gBallGeometry.SetIndexBuffer(&indices[0], indices.size()); | ||
| 149 | + gBallGeometry.SetType(Geometry::TRIANGLES); | ||
| 150 | + } | ||
| 151 | + return gBallGeometry; | ||
| 152 | +} | ||
| 153 | + | ||
| 154 | +TextureSet BallRenderer::CreateTexture(std::string url) | ||
| 155 | +{ | ||
| 156 | + // Load image from file | ||
| 157 | + PixelData pixels = Dali::Toolkit::SyncImageLoader::Load(url); | ||
| 158 | + | ||
| 159 | + Texture texture = Texture::New(TextureType::TEXTURE_2D, pixels.GetPixelFormat(), pixels.GetWidth(), pixels.GetHeight()); | ||
| 160 | + texture.Upload(pixels, 0, 0, 0, 0, pixels.GetWidth(), pixels.GetHeight()); | ||
| 161 | + | ||
| 162 | + // create TextureSet | ||
| 163 | + auto textureSet = TextureSet::New(); | ||
| 164 | + textureSet.SetTexture(0, texture); | ||
| 165 | + | ||
| 166 | + return textureSet; | ||
| 167 | +} | ||
| 168 | + | ||
| 169 | +/** | ||
| 170 | + * Function creates renderer. It turns on depth test and depth write. | ||
| 171 | + */ | ||
| 172 | +Dali::Renderer BallRenderer::CreateRenderer(TextureSet textures) | ||
| 173 | +{ | ||
| 174 | + CreateBallGeometry(); | ||
| 175 | + Dali::Shader shader = CreateShader(); | ||
| 176 | + Renderer renderer = Renderer::New(gBallGeometry, shader); | ||
| 177 | + renderer.SetTextures(textures); | ||
| 178 | + | ||
| 179 | + // Face culling is enabled to hide the backwards facing sides of the ball | ||
| 180 | + // This is sufficient to render a single object; for more complex scenes depth-testing might be required | ||
| 181 | + renderer.SetProperty(Renderer::Property::FACE_CULLING_MODE, FaceCullingMode::BACK); | ||
| 182 | + return renderer; | ||
| 183 | +} | ||
| 184 | + | ||
| 185 | +/** | ||
| 186 | + * Creates new actor and renderer. | ||
| 187 | + */ | ||
| 188 | +Actor BallRenderer::CreateActor(Vector3 size, Vector4 color) | ||
| 189 | +{ | ||
| 190 | + Actor actor = Actor::New(); | ||
| 191 | + actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER); | ||
| 192 | + actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); | ||
| 193 | + actor.SetProperty(Actor::Property::POSITION, Vector3(0.0f, 0.0f, 0.0f)); | ||
| 194 | + actor.SetProperty(Actor::Property::SIZE, Vector3(size.x, size.y, size.z) * 0.5f); | ||
| 195 | + actor.SetProperty(Actor::Property::COLOR, color); | ||
| 196 | + if(!gBallTextureSet) | ||
| 197 | + { | ||
| 198 | + gBallTextureSet = CreateTexture(TEXTURE_URL); | ||
| 199 | + } | ||
| 200 | + Renderer renderer = CreateRenderer(gBallTextureSet); | ||
| 201 | + actor.AddRenderer(renderer); | ||
| 202 | + return actor; | ||
| 203 | +} | ||
| 204 | + | ||
| 205 | +Actor BallRenderer::CreateActor(Vector3 size, std::string url) | ||
| 206 | +{ | ||
| 207 | + Actor actor = Actor::New(); | ||
| 208 | + actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER); | ||
| 209 | + actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); | ||
| 210 | + actor.SetProperty(Actor::Property::POSITION, Vector3(0.0f, 0.0f, 0.0f)); | ||
| 211 | + // Sphere is radius 1; so has natural diameter 2, so halve the size | ||
| 212 | + actor.SetProperty(Actor::Property::SIZE, Vector3(size.x, size.y, size.z) * 0.5f); | ||
| 213 | + | ||
| 214 | + TextureSet textures = CreateTexture(url); | ||
| 215 | + Renderer renderer = CreateRenderer(textures); | ||
| 216 | + actor.AddRenderer(renderer); | ||
| 217 | + return actor; | ||
| 218 | +} |
examples/bullet-physics/ball-renderer.h
0 โ 100644
| 1 | +#pragma once | ||
| 2 | + | ||
| 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 | +#include <dali/dali.h> | ||
| 20 | +using Dali::Actor; | ||
| 21 | +using Dali::Geometry; | ||
| 22 | +using Dali::Renderer; | ||
| 23 | +using Dali::Shader; | ||
| 24 | +using Dali::TextureSet; | ||
| 25 | + | ||
| 26 | +class BallRenderer | ||
| 27 | +{ | ||
| 28 | +public: | ||
| 29 | + static Dali::Geometry CreateBallGeometry(); | ||
| 30 | + static Dali::Renderer CreateRenderer(TextureSet textures); | ||
| 31 | + static Dali::TextureSet CreateTexture(std::string url); | ||
| 32 | + | ||
| 33 | + /** | ||
| 34 | + * The size can control whether this is a ball or a cuboid. Note, textures | ||
| 35 | + * will be stretched on non-square sides. | ||
| 36 | + */ | ||
| 37 | + static Dali::Actor CreateActor(Dali::Vector3 size, Dali::Vector4 color); | ||
| 38 | + static Dali::Actor CreateActor(Dali::Vector3 size, std::string url); | ||
| 39 | + | ||
| 40 | + static Geometry gBallGeometry; | ||
| 41 | + static Shader gBallShader; | ||
| 42 | + static TextureSet gBallTextureSet; | ||
| 43 | +}; |
examples/bullet-physics/cube-renderer.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 "cube-renderer.h" | ||
| 18 | +#include <dali-toolkit/dali-toolkit.h> | ||
| 19 | +#include "generated/rendering-textured-shape-frag.h" | ||
| 20 | +#include "generated/rendering-textured-shape-vert.h" | ||
| 21 | + | ||
| 22 | +using namespace Dali; | ||
| 23 | + | ||
| 24 | +namespace | ||
| 25 | +{ | ||
| 26 | +const char* TEXTURE_URL = DEMO_IMAGE_DIR "/wood.png"; | ||
| 27 | +} // namespace | ||
| 28 | + | ||
| 29 | +Dali::Geometry CubeRenderer::gCubeGeometry; | ||
| 30 | +Dali::TextureSet CubeRenderer::gCubeTextureSet; | ||
| 31 | + | ||
| 32 | +Dali::Shader CreateShader() | ||
| 33 | +{ | ||
| 34 | + static Dali::Shader gShapeShader; | ||
| 35 | + | ||
| 36 | + if(!gShapeShader) | ||
| 37 | + { | ||
| 38 | + gShapeShader = Shader::New(SHADER_RENDERING_TEXTURED_SHAPE_VERT, SHADER_RENDERING_TEXTURED_SHAPE_FRAG); | ||
| 39 | + } | ||
| 40 | + return gShapeShader; | ||
| 41 | +} | ||
| 42 | + | ||
| 43 | +/** | ||
| 44 | + * @brief CreateCubeGeometry | ||
| 45 | + * This function creates a cube geometry including texture coordinates. | ||
| 46 | + */ | ||
| 47 | +Geometry CubeRenderer::CreateCubeGeometry() | ||
| 48 | +{ | ||
| 49 | + if(!gCubeGeometry) | ||
| 50 | + { | ||
| 51 | + struct Vertex | ||
| 52 | + { | ||
| 53 | + Vector3 aPosition; | ||
| 54 | + Vector2 aTexCoord; | ||
| 55 | + }; | ||
| 56 | + | ||
| 57 | + Vertex vertices[] = { | ||
| 58 | + {Vector3(1.0f, -1.0f, -1.0f), Vector2(1.0, 1.0)}, | ||
| 59 | + {Vector3(-1.0f, 1.0f, -1.0f), Vector2(0.0, 0.0)}, | ||
| 60 | + {Vector3(1.0f, 1.0f, -1.0f), Vector2(0.0, 1.0)}, | ||
| 61 | + {Vector3(-1.0f, 1.0f, 1.0f), Vector2(1.0, 1.0)}, | ||
| 62 | + {Vector3(1.0f, -1.0f, 1.0f), Vector2(0.0, 0.0)}, | ||
| 63 | + {Vector3(1.0f, 1.0f, 1.0f), Vector2(0.0, 1.0)}, | ||
| 64 | + {Vector3(1.0f, 1.0f, 1.0f), Vector2(1.0, 1.0)}, | ||
| 65 | + {Vector3(1.0f, -1.0f, -1.0f), Vector2(0.0, 0.0)}, | ||
| 66 | + {Vector3(1.0f, 1.0f, -1.0f), Vector2(0.0, 1.0)}, | ||
| 67 | + {Vector3(1.0f, -1.0f, 1.0f), Vector2(1.0, 1.0)}, | ||
| 68 | + {Vector3(-1.0f, -1.0f, -1.0f), Vector2(0.0, 0.0)}, | ||
| 69 | + {Vector3(1.0f, -1.0f, -1.0f), Vector2(0.0, 1.0)}, | ||
| 70 | + {Vector3(-1.0f, -1.0f, -1.0f), Vector2(1.0, 1.0)}, | ||
| 71 | + {Vector3(-1.0f, 1.0f, 1.0f), Vector2(0.0, 0.0)}, | ||
| 72 | + {Vector3(-1.0f, 1.0f, -1.0f), Vector2(0.0, 1.0)}, | ||
| 73 | + {Vector3(1.0f, 1.0f, -1.0f), Vector2(1.0, 1.0)}, | ||
| 74 | + {Vector3(-1.0f, 1.0f, 1.0f), Vector2(0.0, 0.0)}, | ||
| 75 | + {Vector3(1.0f, 1.0f, 1.0f), Vector2(0.0, 1.0)}, | ||
| 76 | + {Vector3(1.0f, -1.0f, -1.0f), Vector2(1.0, 1.0)}, | ||
| 77 | + {Vector3(-1.0f, -1.0f, -1.0f), Vector2(1.0, 0.0)}, | ||
| 78 | + {Vector3(-1.0f, 1.0f, -1.0f), Vector2(0.0, 0.0)}, | ||
| 79 | + {Vector3(-1.0f, 1.0f, 1.0f), Vector2(1.0, 1.0)}, | ||
| 80 | + {Vector3(-1.0f, -1.0f, 1.0f), Vector2(1.0, 0.0)}, | ||
| 81 | + {Vector3(1.0f, -1.0f, 1.0f), Vector2(0.0, 0.0)}, | ||
| 82 | + {Vector3(1.0f, 1.0f, 1.0f), Vector2(1.0, 1.0)}, | ||
| 83 | + {Vector3(1.0f, -1.0f, 1.0f), Vector2(1.0, 0.0)}, | ||
| 84 | + {Vector3(1.0f, -1.0f, -1.0f), Vector2(0.0, 0.0)}, | ||
| 85 | + {Vector3(1.0f, -1.0f, 1.0f), Vector2(1.0, 1.0)}, | ||
| 86 | + {Vector3(-1.0f, -1.0f, 1.0f), Vector2(1.0, 0.0)}, | ||
| 87 | + {Vector3(-1.0f, -1.0f, -1.0f), Vector2(0.0, 0.0)}, | ||
| 88 | + {Vector3(-1.0f, -1.0f, -1.0f), Vector2(1.0, 1.0)}, | ||
| 89 | + {Vector3(-1.0f, -1.0f, 1.0f), Vector2(1.0, 0.0)}, | ||
| 90 | + {Vector3(-1.0f, 1.0f, 1.0f), Vector2(0.0, 0.0)}, | ||
| 91 | + {Vector3(1.0f, 1.0f, -1.0f), Vector2(1.0, 1.0)}, | ||
| 92 | + {Vector3(-1.0f, 1.0f, -1.0f), Vector2(1.0, 0.0)}, | ||
| 93 | + {Vector3(-1.0f, 1.0f, 1.0f), Vector2(0.0, 0.0)}, | ||
| 94 | + }; | ||
| 95 | + | ||
| 96 | + VertexBuffer vertexBuffer = VertexBuffer::New(Property::Map() | ||
| 97 | + .Add("aPosition", Property::VECTOR3) | ||
| 98 | + .Add("aTexCoord", Property::VECTOR2)); | ||
| 99 | + vertexBuffer.SetData(vertices, sizeof(vertices) / sizeof(Vertex)); | ||
| 100 | + | ||
| 101 | + // create indices | ||
| 102 | + const unsigned short INDEX_CUBE[] = { | ||
| 103 | + 2, 1, 0, 5, 4, 3, 8, 7, 6, 11, 10, 9, 14, 13, 12, 17, 16, 15, 20, 19, 18, 23, 22, 21, 26, 25, 24, 29, 28, 27, 32, 31, 30, 35, 34, 33}; | ||
| 104 | + | ||
| 105 | + gCubeGeometry = Geometry::New(); | ||
| 106 | + gCubeGeometry.AddVertexBuffer(vertexBuffer); | ||
| 107 | + gCubeGeometry.SetIndexBuffer(INDEX_CUBE, | ||
| 108 | + sizeof(INDEX_CUBE) / sizeof(INDEX_CUBE[0])); | ||
| 109 | + gCubeGeometry.SetType(Geometry::TRIANGLES); | ||
| 110 | + } | ||
| 111 | + return gCubeGeometry; | ||
| 112 | +} | ||
| 113 | + | ||
| 114 | +/** | ||
| 115 | + * This function loads a pixel data from a file. In order to load it we use SyncImageLoader utility. | ||
| 116 | + * If loading succeeds returned PixelData object can be used to create a texture. | ||
| 117 | + * Texture must be uploaded. In the end the texture must be set on the TextureSet object. | ||
| 118 | + */ | ||
| 119 | +TextureSet CubeRenderer::CreateTexture(std::string url) | ||
| 120 | +{ | ||
| 121 | + // Load image from file | ||
| 122 | + PixelData pixels = Dali::Toolkit::SyncImageLoader::Load(url); | ||
| 123 | + | ||
| 124 | + Texture texture = Texture::New(TextureType::TEXTURE_2D, pixels.GetPixelFormat(), pixels.GetWidth(), pixels.GetHeight()); | ||
| 125 | + texture.Upload(pixels, 0, 0, 0, 0, pixels.GetWidth(), pixels.GetHeight()); | ||
| 126 | + | ||
| 127 | + // create TextureSet | ||
| 128 | + auto textureSet = TextureSet::New(); | ||
| 129 | + textureSet.SetTexture(0, texture); | ||
| 130 | + | ||
| 131 | + return textureSet; | ||
| 132 | +} | ||
| 133 | + | ||
| 134 | +/** | ||
| 135 | + * Function creates renderer. It turns on depth test and depth write. | ||
| 136 | + */ | ||
| 137 | +Dali::Renderer CubeRenderer::CreateRenderer(TextureSet textures) | ||
| 138 | +{ | ||
| 139 | + CreateCubeGeometry(); | ||
| 140 | + Dali::Shader shader = CreateShader(); | ||
| 141 | + Renderer renderer = Renderer::New(gCubeGeometry, shader); | ||
| 142 | + renderer.SetTextures(textures); | ||
| 143 | + | ||
| 144 | + // Face culling is enabled to hide the backwards facing sides of the cube | ||
| 145 | + // This is sufficient to render a single object; for more complex scenes depth-testing might be required | ||
| 146 | + renderer.SetProperty(Renderer::Property::FACE_CULLING_MODE, FaceCullingMode::BACK); | ||
| 147 | + return renderer; | ||
| 148 | +} | ||
| 149 | + | ||
| 150 | +/** | ||
| 151 | + * Creates new actor and renderer. | ||
| 152 | + */ | ||
| 153 | +Actor CubeRenderer::CreateActor(Vector3 size, Vector4 color) | ||
| 154 | +{ | ||
| 155 | + Actor actor = Actor::New(); | ||
| 156 | + actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER); | ||
| 157 | + actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); | ||
| 158 | + actor.SetProperty(Actor::Property::POSITION, Vector3(0.0f, 0.0f, 0.0f)); | ||
| 159 | + // Mesh is 2x2x2, so halve the size | ||
| 160 | + actor.SetProperty(Actor::Property::SIZE, Vector3(size.x, size.y, size.z) * 0.5f); | ||
| 161 | + actor.SetProperty(Actor::Property::COLOR, color); | ||
| 162 | + if(!gCubeTextureSet) | ||
| 163 | + { | ||
| 164 | + gCubeTextureSet = CreateTexture(TEXTURE_URL); | ||
| 165 | + } | ||
| 166 | + Renderer renderer = CreateRenderer(gCubeTextureSet); | ||
| 167 | + actor.AddRenderer(renderer); | ||
| 168 | + return actor; | ||
| 169 | +} | ||
| 170 | + | ||
| 171 | +Actor CubeRenderer::CreateActor(Vector3 size, std::string url) | ||
| 172 | +{ | ||
| 173 | + Actor actor = Actor::New(); | ||
| 174 | + actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER); | ||
| 175 | + actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); | ||
| 176 | + actor.SetProperty(Actor::Property::POSITION, Vector3(0.0f, 0.0f, 0.0f)); | ||
| 177 | + actor.SetProperty(Actor::Property::SIZE, Vector3(size.x, size.y, size.z) * 0.5f); | ||
| 178 | + | ||
| 179 | + TextureSet textures = CreateTexture(url); | ||
| 180 | + Renderer renderer = CreateRenderer(textures); | ||
| 181 | + actor.AddRenderer(renderer); | ||
| 182 | + return actor; | ||
| 183 | +} |
examples/bullet-physics/cube-renderer.h
0 โ 100644
| 1 | +#pragma once | ||
| 2 | + | ||
| 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 | +#include <dali/dali.h> | ||
| 20 | +using Dali::Actor; | ||
| 21 | +using Dali::Geometry; | ||
| 22 | +using Dali::Renderer; | ||
| 23 | +using Dali::Shader; | ||
| 24 | +using Dali::TextureSet; | ||
| 25 | + | ||
| 26 | +Dali::Shader CreateShader(); | ||
| 27 | + | ||
| 28 | +class CubeRenderer | ||
| 29 | +{ | ||
| 30 | +public: | ||
| 31 | + static Dali::Geometry CreateCubeGeometry(); | ||
| 32 | + static Dali::Renderer CreateRenderer(TextureSet textures); | ||
| 33 | + static Dali::TextureSet CreateTexture(std::string url); | ||
| 34 | + | ||
| 35 | + /** | ||
| 36 | + * The size can control whether this is a cube or a cuboid. Note, textures | ||
| 37 | + * will be stretched on non-square sides. | ||
| 38 | + */ | ||
| 39 | + static Dali::Actor CreateActor(Dali::Vector3 size, Dali::Vector4 color); | ||
| 40 | + static Dali::Actor CreateActor(Dali::Vector3 size, std::string url); | ||
| 41 | + | ||
| 42 | + static Geometry gCubeGeometry; | ||
| 43 | + static TextureSet gCubeTextureSet; | ||
| 44 | +}; |
examples/bullet-physics/dependencies.cmake
0 โ 100644
| 1 | +TARGET_COMPILE_OPTIONS(${EXAMPLE}.example PUBLIC ${DALI_PHYSICS_3D_CFLAGS}) | ||
| 2 | +TARGET_LINK_LIBRARIES(${EXAMPLE}.example ${DALI_PHYSICS_3D_LDFLAGS}) | ||
| 3 | +MESSAGE(STATUS "Included dependencies for ${EXAMPLE}") | ||
| 4 | +MESSAGE(STATUS " Compile options: ${DALI_PHYSICS_3D_CFLAGS}") | ||
| 5 | +MESSAGE(STATUS " Link options: ${DALI_PHYSICS_3D_LDFLAGS}") |
examples/bullet-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 | +#include "dali-physics/public-api/physics-actor.h" | ||
| 20 | +#include "dali-physics/public-api/physics-adaptor.h" | ||
| 21 | + | ||
| 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 <btBulletDynamicsCommon.h> | ||
| 29 | + | ||
| 30 | +#include "ball-renderer.h" | ||
| 31 | +#include "cube-renderer.h" | ||
| 32 | + | ||
| 33 | +using namespace Dali; | ||
| 34 | +using namespace Dali::Toolkit::Physics; | ||
| 35 | + | ||
| 36 | +namespace KeyModifier | ||
| 37 | +{ | ||
| 38 | +enum Key | ||
| 39 | +{ | ||
| 40 | + CONTROL_L = DevelKey::DALI_KEY_CONTROL_LEFT, | ||
| 41 | + CONTROL_R = DevelKey::DALI_KEY_CONTROL_RIGHT, | ||
| 42 | + SHIFT_L = 50, | ||
| 43 | + SHIFT_R = 62, | ||
| 44 | + ALT_L = 64, | ||
| 45 | + ALT_R = 108, | ||
| 46 | + SUPER_L = 133, | ||
| 47 | + SUPER_R = 134, | ||
| 48 | + MENU = 135, | ||
| 49 | +}; | ||
| 50 | +} | ||
| 51 | + | ||
| 52 | +const std::string BRICK_WALL = DEMO_IMAGE_DIR "/brick-wall.jpg"; | ||
| 53 | +const std::string BALL_IMAGE = DEMO_IMAGE_DIR "/blocks-ball.png"; | ||
| 54 | +const std::string BRICK_URIS[4] = { | ||
| 55 | + 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"}; | ||
| 56 | + | ||
| 57 | +class PhysicsDemoController : public ConnectionTracker | ||
| 58 | +{ | ||
| 59 | +public: | ||
| 60 | + PhysicsDemoController(Application& app) | ||
| 61 | + : mApplication(app) | ||
| 62 | + { | ||
| 63 | + app.InitSignal().Connect(this, &PhysicsDemoController::OnInit); | ||
| 64 | + app.TerminateSignal().Connect(this, &PhysicsDemoController::OnTerminate); | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + ~PhysicsDemoController() override | ||
| 68 | + { | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + void OnInit(Application& application) | ||
| 72 | + { | ||
| 73 | + mWindow = application.GetWindow(); | ||
| 74 | + mWindow.ResizeSignal().Connect(this, &PhysicsDemoController::OnWindowResize); | ||
| 75 | + mWindow.KeyEventSignal().Connect(this, &PhysicsDemoController::OnKeyEv); | ||
| 76 | + Stage::GetCurrent().KeepRendering(30); | ||
| 77 | + mWindow.SetBackgroundColor(Color::DARK_SLATE_GRAY); | ||
| 78 | + Window::WindowSize windowSize = mWindow.GetSize(); | ||
| 79 | + | ||
| 80 | + auto cameraActor = mWindow.GetRenderTaskList().GetTask(0).GetCameraActor(); | ||
| 81 | + cameraActor[CameraActor::Property::FIELD_OF_VIEW] = Math::PI/2.5f; // 72 degrees | ||
| 82 | + cameraActor[Actor::Property::POSITION_X] = 500; | ||
| 83 | + float z = cameraActor[Actor::Property::POSITION_Z]; | ||
| 84 | + cameraActor[Actor::Property::POSITION_Z] = z-100; | ||
| 85 | + cameraActor[CameraActor::Property::TARGET_POSITION] = Vector3(); | ||
| 86 | + cameraActor[CameraActor::Property::TYPE] = Camera::LOOK_AT_TARGET; | ||
| 87 | + mPhysicsTransform.SetIdentityAndScale(Vector3(1.0f, -1.0f, 1.0f)); | ||
| 88 | + mPhysicsTransform.SetTranslation(Vector3(windowSize.GetWidth() * 0.5f, | ||
| 89 | + windowSize.GetHeight() * 0.5f, | ||
| 90 | + -100.0f)); | ||
| 91 | + | ||
| 92 | + mPhysicsAdaptor = PhysicsAdaptor::New(mPhysicsTransform, windowSize); | ||
| 93 | + mPhysicsRoot = mPhysicsAdaptor.GetRootActor(); | ||
| 94 | + | ||
| 95 | + mPhysicsRoot.TouchedSignal().Connect(this, &PhysicsDemoController::OnTouched); | ||
| 96 | + mPhysicsRoot.WheelEventSignal().Connect(this, &PhysicsDemoController::OnWheel); | ||
| 97 | + | ||
| 98 | + mWindow.Add(mPhysicsRoot); | ||
| 99 | + | ||
| 100 | + auto scopedAccessor = mPhysicsAdaptor.GetPhysicsAccessor(); | ||
| 101 | + auto bulletWorld = scopedAccessor->GetNative().Get<btDiscreteDynamicsWorld*>(); | ||
| 102 | + bulletWorld->setGravity(btVector3(0, -200, 0)); | ||
| 103 | + | ||
| 104 | + CreateGround(scopedAccessor, windowSize); | ||
| 105 | + mBrick = CreateLargeBrick(scopedAccessor); | ||
| 106 | + mSelectedActor = mBrick; | ||
| 107 | + | ||
| 108 | + CreateBall(scopedAccessor); | ||
| 109 | + CreateBrickPyramid(scopedAccessor, windowSize); | ||
| 110 | + | ||
| 111 | + mPhysicsAdaptor.CreateSyncPoint(); | ||
| 112 | + } | ||
| 113 | + | ||
| 114 | + btRigidBody* CreateRigidBody(btDiscreteDynamicsWorld* bulletWorld, float mass, const btTransform& bulletTransform, btCollisionShape* shape) | ||
| 115 | + { | ||
| 116 | + bool isDynamic = (mass != 0.0); | ||
| 117 | + btVector3 localInertia(0.0f, 0.0f, 0.0f); | ||
| 118 | + if(isDynamic) | ||
| 119 | + { | ||
| 120 | + shape->calculateLocalInertia(mass, localInertia); | ||
| 121 | + } | ||
| 122 | + | ||
| 123 | + auto* motionState = new btDefaultMotionState(bulletTransform); | ||
| 124 | + btRigidBody::btRigidBodyConstructionInfo rigidBodyConstructionInfo(mass, motionState, shape, localInertia); | ||
| 125 | + auto* body = new btRigidBody(rigidBodyConstructionInfo); | ||
| 126 | + | ||
| 127 | + bulletWorld->addRigidBody(body); | ||
| 128 | + return body; | ||
| 129 | + } | ||
| 130 | + | ||
| 131 | + void CreateGround(PhysicsAdaptor::ScopedPhysicsAccessorPtr& scopedAccessor, Dali::Window::WindowSize windowSize) | ||
| 132 | + { | ||
| 133 | + Dali::Vector3 size(2 * windowSize.GetWidth(), 10.f, 2 * windowSize.GetWidth()); | ||
| 134 | + Actor groundActor = CubeRenderer::CreateActor(size, BRICK_WALL); | ||
| 135 | + | ||
| 136 | + auto physicsActor = CreateBrick(scopedAccessor, groundActor, 0.0f, 0.1f, 0.9f, size); | ||
| 137 | + physicsActor.AsyncSetPhysicsPosition(Vector3(0.0f, 0.5f * windowSize.GetHeight(), 0.0f)); | ||
| 138 | + } | ||
| 139 | + | ||
| 140 | + void CreateBall(PhysicsAdaptor::ScopedPhysicsAccessorPtr& scopedAccessor) | ||
| 141 | + { | ||
| 142 | + const float BALL_MASS = 1.0f; | ||
| 143 | + const float BALL_RADIUS = 50.0f; | ||
| 144 | + const float BALL_ELASTICITY = 0.5f; | ||
| 145 | + const float BALL_FRICTION = 0.5f; | ||
| 146 | + auto actor = BallRenderer::CreateActor(Vector3(BALL_RADIUS * 2, BALL_RADIUS * 2, BALL_RADIUS * 2), Dali::Color::WHITE); | ||
| 147 | + | ||
| 148 | + btSphereShape* ball = new btSphereShape(BALL_RADIUS); // @todo Fix leak | ||
| 149 | + btTransform transform; | ||
| 150 | + transform.setIdentity(); | ||
| 151 | + | ||
| 152 | + auto bulletWorld = scopedAccessor->GetNative().Get<btDiscreteDynamicsWorld*>(); | ||
| 153 | + btRigidBody* body = CreateRigidBody(bulletWorld, BALL_MASS, transform, ball); | ||
| 154 | + | ||
| 155 | + body->setFriction(BALL_FRICTION); | ||
| 156 | + body->setRestitution(BALL_ELASTICITY); | ||
| 157 | + | ||
| 158 | + auto physicsActor = mPhysicsAdaptor.AddActorBody(actor, body); | ||
| 159 | + actor.RegisterProperty("uBrightness", 0.0f); | ||
| 160 | + | ||
| 161 | + physicsActor.AsyncSetPhysicsPosition(Vector3(0.0f, -400.0f, -150.0f)); | ||
| 162 | + } | ||
| 163 | + | ||
| 164 | + PhysicsActor CreateBrick(PhysicsAdaptor::ScopedPhysicsAccessorPtr& scopedAccessor, | ||
| 165 | + Dali::Actor actor, | ||
| 166 | + float mass, | ||
| 167 | + float elasticity, | ||
| 168 | + float friction, | ||
| 169 | + Vector3 size) | ||
| 170 | + { | ||
| 171 | + btVector3 halfExtents(size.width * 0.5f, size.height * 0.5f, size.depth * 0.5f); | ||
| 172 | + btBoxShape* shape = new btBoxShape(halfExtents); // @todo Fix leak | ||
| 173 | + btVector3 inertia; | ||
| 174 | + inertia.setZero(); | ||
| 175 | + shape->calculateLocalInertia(mass, inertia); | ||
| 176 | + | ||
| 177 | + btTransform startTransform; | ||
| 178 | + startTransform.setIdentity(); | ||
| 179 | + auto bulletWorld = scopedAccessor->GetNative().Get<btDiscreteDynamicsWorld*>(); | ||
| 180 | + btRigidBody* body = CreateRigidBody(bulletWorld, mass, startTransform, shape); | ||
| 181 | + | ||
| 182 | + body->setFriction(friction); | ||
| 183 | + body->setRestitution(elasticity); | ||
| 184 | + | ||
| 185 | + actor.RegisterProperty("uBrightness", 0.0f); | ||
| 186 | + | ||
| 187 | + auto physicsActor = mPhysicsAdaptor.AddActorBody(actor, body); | ||
| 188 | + return physicsActor; | ||
| 189 | + } | ||
| 190 | + | ||
| 191 | + PhysicsActor CreateLargeBrick(PhysicsAdaptor::ScopedPhysicsAccessorPtr& scopedAccessor) | ||
| 192 | + { | ||
| 193 | + const float BRICK_MASS = 1.0f; | ||
| 194 | + const float BRICK_ELASTICITY = 0.1f; | ||
| 195 | + const float BRICK_FRICTION = 0.6f; | ||
| 196 | + const int BRICK_WIDTH = 400; | ||
| 197 | + const int BRICK_HEIGHT = 150; | ||
| 198 | + const int BRICK_DEPTH = 200; | ||
| 199 | + | ||
| 200 | + auto brick = CubeRenderer::CreateActor(Vector3(BRICK_WIDTH, BRICK_HEIGHT, BRICK_DEPTH), Dali::Color::WHITE); | ||
| 201 | + auto physicsActor = CreateBrick(scopedAccessor, brick, BRICK_MASS, BRICK_ELASTICITY, BRICK_FRICTION, Vector3(BRICK_WIDTH, BRICK_HEIGHT, BRICK_DEPTH)); | ||
| 202 | + | ||
| 203 | + physicsActor.AsyncSetPhysicsPosition(Vector3(0, 0, -300)); | ||
| 204 | + return physicsActor; | ||
| 205 | + } | ||
| 206 | + | ||
| 207 | + void CreateBrickPyramid(PhysicsAdaptor::ScopedPhysicsAccessorPtr& scopedAccessor, Dali::Window::WindowSize windowSize) | ||
| 208 | + { | ||
| 209 | + const float BRICK_MASS = 1.0f; | ||
| 210 | + const float BRICK_ELASTICITY = 0.1f; | ||
| 211 | + const float BRICK_FRICTION = 0.6f; | ||
| 212 | + const int BRICK_WIDTH = 60; | ||
| 213 | + const int BRICK_HEIGHT = 30; | ||
| 214 | + const int BRICK_DEPTH = 30; | ||
| 215 | + const int BRICK_GAP = 12; | ||
| 216 | + | ||
| 217 | + Dali::Vector4 colors[5] = {Dali::Color::AQUA_MARINE, Dali::Color::DARK_SEA_GREEN, Dali::Color::BLUE_VIOLET, Dali::Color::MISTY_ROSE, Dali::Color::ORCHID}; | ||
| 218 | + | ||
| 219 | + int numberOfRows = 10; | ||
| 220 | + int oY = -(1 + numberOfRows) * (BRICK_HEIGHT + BRICK_GAP); | ||
| 221 | + for(int i = 0; i < numberOfRows; ++i) | ||
| 222 | + { | ||
| 223 | + int w = (i + 1) * BRICK_WIDTH + i * BRICK_GAP; | ||
| 224 | + float oX = w * -0.5f; | ||
| 225 | + for(int j = 0; j < i + 1; ++j) | ||
| 226 | + { | ||
| 227 | + auto brick = CubeRenderer::CreateActor(Vector3(BRICK_WIDTH, BRICK_HEIGHT, BRICK_DEPTH), colors[(i + j) % 5]); | ||
| 228 | + auto physicsActor = CreateBrick(scopedAccessor, brick, BRICK_MASS, BRICK_ELASTICITY, BRICK_FRICTION, Vector3(BRICK_WIDTH, BRICK_HEIGHT, BRICK_DEPTH)); | ||
| 229 | + | ||
| 230 | + physicsActor.AsyncSetPhysicsPosition(Vector3(oX + j * (BRICK_WIDTH + BRICK_GAP), oY + i * (BRICK_HEIGHT + BRICK_GAP), -300.0f)); | ||
| 231 | + // Create slight rotation offset to trigger automatic collapse | ||
| 232 | + auto axis = Vector3(Random::Range(-0.2f, 0.2f), // Roughly the z axis | ||
| 233 | + Random::Range(-0.2f, 0.2f), | ||
| 234 | + Random::Range(0.8f, 1.2f)); | ||
| 235 | + axis.Normalize(); | ||
| 236 | + physicsActor.AsyncSetPhysicsRotation(Quaternion(Radian(Random::Range(-0.3f, 0.3f)), axis)); | ||
| 237 | + } | ||
| 238 | + } | ||
| 239 | + } | ||
| 240 | + | ||
| 241 | + void HighlightBody(btRigidBody* body, bool highlight) | ||
| 242 | + { | ||
| 243 | + auto physicsActor = mPhysicsAdaptor.GetPhysicsActor(body); | ||
| 244 | + if(physicsActor) | ||
| 245 | + { | ||
| 246 | + Actor actor = mPhysicsAdaptor.GetRootActor().FindChildById(physicsActor.GetId()); | ||
| 247 | + if(actor) | ||
| 248 | + { | ||
| 249 | + actor["uBrightness"] = highlight ? 1.0f : 0.0f; | ||
| 250 | + } | ||
| 251 | + } | ||
| 252 | + } | ||
| 253 | + | ||
| 254 | + void OnTerminate(Application& application) | ||
| 255 | + { | ||
| 256 | + UnparentAndReset(mPhysicsRoot); | ||
| 257 | + } | ||
| 258 | + | ||
| 259 | + void OnWindowResize(Window window, Window::WindowSize newSize) | ||
| 260 | + { | ||
| 261 | + Vector2 size(newSize.GetWidth(), newSize.GetHeight()); | ||
| 262 | + window.GetRenderTaskList().GetTask(0).GetCameraActor().SetPerspectiveProjection(size); | ||
| 263 | + mPhysicsAdaptor.SetTransformAndSize(mPhysicsTransform, newSize); | ||
| 264 | + } | ||
| 265 | + | ||
| 266 | + bool OnTouched(Dali::Actor actor, const Dali::TouchEvent& touch) | ||
| 267 | + { | ||
| 268 | + static enum { | ||
| 269 | + None, | ||
| 270 | + MoveCameraXZ, | ||
| 271 | + MovePivot, | ||
| 272 | + } state = None; | ||
| 273 | + | ||
| 274 | + const float MOUSE_CLAMPING(30.0f); | ||
| 275 | + const float TAU(0.001f); | ||
| 276 | + //static float cameraY{0.0f}; | ||
| 277 | + auto renderTask = mWindow.GetRenderTaskList().GetTask(0); | ||
| 278 | + auto screenCoords = touch.GetScreenPosition(0); | ||
| 279 | + Vector3 origin, direction; | ||
| 280 | + Dali::HitTestAlgorithm::BuildPickingRay(renderTask, screenCoords, origin, direction); | ||
| 281 | + | ||
| 282 | + switch(state) | ||
| 283 | + { | ||
| 284 | + case None: | ||
| 285 | + { | ||
| 286 | + if(touch.GetState(0) == Dali::PointState::STARTED) | ||
| 287 | + { | ||
| 288 | + if(mCtrlDown) | ||
| 289 | + { | ||
| 290 | + state = MoveCameraXZ; | ||
| 291 | + // local to top left | ||
| 292 | + //cameraY = touch.GetLocalPosition(0).y; | ||
| 293 | + // Could move on fixed plane, e.g. y=0. | ||
| 294 | + // position.Y corresponds to a z value depending on perspective | ||
| 295 | + // position.X scales to an x value depending on perspective | ||
| 296 | + } | ||
| 297 | + else | ||
| 298 | + { | ||
| 299 | + state = MovePivot; | ||
| 300 | + auto scopedAccessor = mPhysicsAdaptor.GetPhysicsAccessor(); | ||
| 301 | + auto bulletWorld = scopedAccessor->GetNative().Get<btDiscreteDynamicsWorld*>(); | ||
| 302 | + | ||
| 303 | + Vector3 localPivot; | ||
| 304 | + Vector3 rayPhysicsOrigin; | ||
| 305 | + Vector3 rayPhysicsEnd; | ||
| 306 | + mPhysicsAdaptor.BuildPickingRay(origin, direction, rayPhysicsOrigin, rayPhysicsEnd); | ||
| 307 | + auto body = scopedAccessor->HitTest(rayPhysicsOrigin, rayPhysicsEnd, localPivot, mOldPickingDistance); | ||
| 308 | + if(!body.Empty()) | ||
| 309 | + { | ||
| 310 | + mPickedBody = body.Get<btRigidBody*>(); | ||
| 311 | + HighlightBody(mPickedBody, true); | ||
| 312 | + mSelectedActor = mPhysicsAdaptor.GetPhysicsActor(mPickedBody); | ||
| 313 | + | ||
| 314 | + mPickedSavedState = mPickedBody->getActivationState(); | ||
| 315 | + mPickedBody->setActivationState(DISABLE_DEACTIVATION); | ||
| 316 | + | ||
| 317 | + btVector3 pivot(localPivot.x, localPivot.y, localPivot.z); | ||
| 318 | + auto p2p = new btPoint2PointConstraint(*mPickedBody, pivot); | ||
| 319 | + bulletWorld->addConstraint(p2p, true); | ||
| 320 | + p2p->m_setting.m_impulseClamp = MOUSE_CLAMPING; | ||
| 321 | + p2p->m_setting.m_tau = TAU; | ||
| 322 | + | ||
| 323 | + mPickedConstraint = p2p; | ||
| 324 | + } | ||
| 325 | + } | ||
| 326 | + } | ||
| 327 | + break; | ||
| 328 | + } | ||
| 329 | + case MovePivot: | ||
| 330 | + { | ||
| 331 | + if(touch.GetState(0) == Dali::PointState::MOTION) | ||
| 332 | + { | ||
| 333 | + if(mPickedBody && mPickedConstraint) | ||
| 334 | + { | ||
| 335 | + if(!mShiftDown) | ||
| 336 | + { | ||
| 337 | + // Move point in XY plane, projected into scene | ||
| 338 | + auto scopedAccessor = mPhysicsAdaptor.GetPhysicsAccessor(); // Ensure we get a lock | ||
| 339 | + | ||
| 340 | + Vector3 newPosition = mPhysicsAdaptor.ProjectPoint(origin, direction, mOldPickingDistance); | ||
| 341 | + btPoint2PointConstraint* p2p = static_cast<btPoint2PointConstraint*>(mPickedConstraint); | ||
| 342 | + if(p2p) | ||
| 343 | + { | ||
| 344 | + // @todo Add inline memory cast... (only viable if physics uses floats not doubles) | ||
| 345 | + p2p->setPivotB(btVector3(newPosition.x, newPosition.y, newPosition.z)); | ||
| 346 | + } | ||
| 347 | + } | ||
| 348 | + // @todo Add code to move objects in XZ plane | ||
| 349 | + } | ||
| 350 | + } | ||
| 351 | + else if(touch.GetState(0) == Dali::PointState::FINISHED || | ||
| 352 | + touch.GetState(0) == Dali::PointState::INTERRUPTED) | ||
| 353 | + { | ||
| 354 | + if(mPickedConstraint) | ||
| 355 | + { | ||
| 356 | + auto scopedAccessor = mPhysicsAdaptor.GetPhysicsAccessor(); // Ensure we get a lock | ||
| 357 | + auto bulletWorld = scopedAccessor->GetNative().Get<btDiscreteDynamicsWorld*>(); | ||
| 358 | + HighlightBody(mPickedBody, false); | ||
| 359 | + mPickedBody->forceActivationState(mPickedSavedState); | ||
| 360 | + mPickedBody->activate(); | ||
| 361 | + bulletWorld->removeConstraint(mPickedConstraint); | ||
| 362 | + | ||
| 363 | + mPickedConstraint = nullptr; | ||
| 364 | + mPickedBody = nullptr; | ||
| 365 | + } | ||
| 366 | + state = None; | ||
| 367 | + } | ||
| 368 | + break; | ||
| 369 | + } | ||
| 370 | + case MoveCameraXZ: | ||
| 371 | + { | ||
| 372 | + if(touch.GetState(0) == Dali::PointState::MOTION) | ||
| 373 | + { | ||
| 374 | + // Move camera in XZ plane | ||
| 375 | + //float y = cameraY; // touch point in Y. Move camera in an XZ plane on this point. | ||
| 376 | + } | ||
| 377 | + else if(touch.GetState(0) == Dali::PointState::FINISHED || | ||
| 378 | + touch.GetState(0) == Dali::PointState::INTERRUPTED) | ||
| 379 | + { | ||
| 380 | + state = None; | ||
| 381 | + } | ||
| 382 | + break; | ||
| 383 | + } | ||
| 384 | + } | ||
| 385 | + | ||
| 386 | + static int reduceSpam = 0; | ||
| 387 | + ++reduceSpam; | ||
| 388 | + if(reduceSpam == 30) | ||
| 389 | + { | ||
| 390 | + reduceSpam = 0; | ||
| 391 | + std::cout << "Dali scrnpos:" << screenCoords << "\nDali pos: " << mBrick.GetActorPosition() << "\nDali rot: " << mBrick.GetActorRotation() << "\nPhys pos: " << mBrick.GetPhysicsPosition() << "\nPhys rot: " << mBrick.GetPhysicsRotation() << "\n"; | ||
| 392 | + } | ||
| 393 | + | ||
| 394 | + Stage::GetCurrent().KeepRendering(30.0f); | ||
| 395 | + | ||
| 396 | + return true; | ||
| 397 | + } | ||
| 398 | + | ||
| 399 | + bool OnWheel(Actor actor, const WheelEvent& event) | ||
| 400 | + { | ||
| 401 | + // Move camera along it's fwd axis | ||
| 402 | + auto renderTask = mWindow.GetRenderTaskList().GetTask(0); | ||
| 403 | + auto camera = renderTask.GetCameraActor(); | ||
| 404 | + static uint32_t lastTime = 0; | ||
| 405 | + | ||
| 406 | + int32_t delta = event.GetDelta(); | ||
| 407 | + if(lastTime > 0) | ||
| 408 | + { | ||
| 409 | + uint32_t timeDiff = event.GetTime() - lastTime; | ||
| 410 | + ++timeDiff; // Can be zero. | ||
| 411 | + if(timeDiff < 50) // When it's less than some threshold | ||
| 412 | + { | ||
| 413 | + // Scale delta by speed (range: 0-6) | ||
| 414 | + float scale = (50.0f - timeDiff) * 6.0f / 50.0f; // smaller times = bigger factor | ||
| 415 | + scale *= (scale * scale); // Cube it. (Max - 360) | ||
| 416 | + scale = std::max(1.0f, scale); | ||
| 417 | + delta *= scale; | ||
| 418 | + } | ||
| 419 | + } | ||
| 420 | + lastTime = event.GetTime(); | ||
| 421 | + | ||
| 422 | + float z = camera[Actor::Property::POSITION_Z]; | ||
| 423 | + z += delta; | ||
| 424 | + camera[Actor::Property::POSITION_Z] = z; | ||
| 425 | + return true; | ||
| 426 | + } | ||
| 427 | + | ||
| 428 | + void OnKeyEv(const Dali::KeyEvent& event) | ||
| 429 | + { | ||
| 430 | + if(event.GetState() == KeyEvent::DOWN) | ||
| 431 | + { | ||
| 432 | + switch(event.GetKeyCode()) | ||
| 433 | + { | ||
| 434 | + case KeyModifier::CONTROL_L: | ||
| 435 | + case KeyModifier::CONTROL_R: | ||
| 436 | + { | ||
| 437 | + mCtrlDown = true; | ||
| 438 | + break; | ||
| 439 | + } | ||
| 440 | + case KeyModifier::ALT_L: | ||
| 441 | + case KeyModifier::ALT_R: | ||
| 442 | + { | ||
| 443 | + mAltDown = true; | ||
| 444 | + break; | ||
| 445 | + } | ||
| 446 | + case KeyModifier::SHIFT_L: | ||
| 447 | + case KeyModifier::SHIFT_R: | ||
| 448 | + { | ||
| 449 | + mShiftDown = true; | ||
| 450 | + break; | ||
| 451 | + } | ||
| 452 | + default: | ||
| 453 | + { | ||
| 454 | + if(IsKey(event, Dali::DALI_KEY_ESCAPE) || IsKey(event, Dali::DALI_KEY_BACK)) | ||
| 455 | + { | ||
| 456 | + mApplication.Quit(); | ||
| 457 | + } | ||
| 458 | + else if(!event.GetKeyString().compare(" ")) | ||
| 459 | + { | ||
| 460 | + if(mIntegrationState == PhysicsAdaptor::IntegrationState::ON) | ||
| 461 | + { | ||
| 462 | + mIntegrationState = PhysicsAdaptor::IntegrationState::OFF; | ||
| 463 | + } | ||
| 464 | + else | ||
| 465 | + { | ||
| 466 | + mIntegrationState = PhysicsAdaptor::IntegrationState::ON; | ||
| 467 | + } | ||
| 468 | + mPhysicsAdaptor.SetIntegrationState(mIntegrationState); | ||
| 469 | + } | ||
| 470 | + else if(!event.GetKeyString().compare("m")) | ||
| 471 | + { | ||
| 472 | + if(mDebugState == PhysicsAdaptor::DebugState::ON) | ||
| 473 | + { | ||
| 474 | + mDebugState = PhysicsAdaptor::DebugState::OFF; | ||
| 475 | + } | ||
| 476 | + else | ||
| 477 | + { | ||
| 478 | + mDebugState = PhysicsAdaptor::DebugState::ON; | ||
| 479 | + if(!mPhysicsDebugLayer) | ||
| 480 | + { | ||
| 481 | + mPhysicsDebugLayer = mPhysicsAdaptor.CreateDebugLayer(mWindow); | ||
| 482 | + } | ||
| 483 | + } | ||
| 484 | + mPhysicsAdaptor.SetDebugState(mDebugState); | ||
| 485 | + } | ||
| 486 | + else if(!event.GetKeyString().compare("w")) | ||
| 487 | + { | ||
| 488 | + Vector3 pos = mSelectedActor.GetActorPosition(); | ||
| 489 | + mSelectedActor.AsyncSetPhysicsPosition(pos + Vector3(0, 10, 0)); | ||
| 490 | + btRigidBody* body = mSelectedActor.GetBody().Get<btRigidBody*>(); | ||
| 491 | + mPhysicsAdaptor.Queue([body]() { body->activate(true); }); | ||
| 492 | + mPhysicsAdaptor.CreateSyncPoint(); | ||
| 493 | + } | ||
| 494 | + else if(!event.GetKeyString().compare("s")) | ||
| 495 | + { | ||
| 496 | + Vector3 pos = mSelectedActor.GetActorPosition(); | ||
| 497 | + mSelectedActor.AsyncSetPhysicsPosition(pos + Vector3(0, -10, 0)); | ||
| 498 | + btRigidBody* body = mSelectedActor.GetBody().Get<btRigidBody*>(); | ||
| 499 | + mPhysicsAdaptor.Queue([body]() { body->activate(true); }); | ||
| 500 | + mPhysicsAdaptor.CreateSyncPoint(); | ||
| 501 | + } | ||
| 502 | + else if(!event.GetKeyString().compare("a")) | ||
| 503 | + { | ||
| 504 | + Vector3 pos = mSelectedActor.GetActorPosition(); | ||
| 505 | + mSelectedActor.AsyncSetPhysicsPosition(pos + Vector3(-10, 0, 0)); | ||
| 506 | + btRigidBody* body = mSelectedActor.GetBody().Get<btRigidBody*>(); | ||
| 507 | + mPhysicsAdaptor.Queue([body]() { body->activate(true); }); | ||
| 508 | + mPhysicsAdaptor.CreateSyncPoint(); | ||
| 509 | + } | ||
| 510 | + else if(!event.GetKeyString().compare("d")) | ||
| 511 | + { | ||
| 512 | + Vector3 pos = mSelectedActor.GetActorPosition(); | ||
| 513 | + mSelectedActor.AsyncSetPhysicsPosition(pos + Vector3(10, 0, 0)); | ||
| 514 | + btRigidBody* body = mSelectedActor.GetBody().Get<btRigidBody*>(); | ||
| 515 | + mPhysicsAdaptor.Queue([body]() { body->activate(true); }); | ||
| 516 | + mPhysicsAdaptor.CreateSyncPoint(); | ||
| 517 | + } | ||
| 518 | + else if(!event.GetKeyString().compare("q")) | ||
| 519 | + { | ||
| 520 | + Quaternion quat = mSelectedActor.GetActorRotation(); | ||
| 521 | + quat *= Quaternion(Radian(-0.1f), Vector3::ZAXIS); | ||
| 522 | + mSelectedActor.AsyncSetPhysicsRotation(quat); | ||
| 523 | + btRigidBody* body = mSelectedActor.GetBody().Get<btRigidBody*>(); | ||
| 524 | + mPhysicsAdaptor.Queue([body]() { body->activate(true); }); | ||
| 525 | + mPhysicsAdaptor.CreateSyncPoint(); | ||
| 526 | + } | ||
| 527 | + else if(!event.GetKeyString().compare("e")) | ||
| 528 | + { | ||
| 529 | + Quaternion quat = mSelectedActor.GetActorRotation(); | ||
| 530 | + quat *= Quaternion(Radian(0.1f), Vector3::ZAXIS); | ||
| 531 | + mSelectedActor.AsyncSetPhysicsRotation(quat); | ||
| 532 | + btRigidBody* body = mSelectedActor.GetBody().Get<btRigidBody*>(); | ||
| 533 | + mPhysicsAdaptor.Queue([body]() { body->activate(true); }); | ||
| 534 | + mPhysicsAdaptor.CreateSyncPoint(); | ||
| 535 | + } | ||
| 536 | + else if(!event.GetKeyString().compare("z")) | ||
| 537 | + { | ||
| 538 | + Quaternion quat = mSelectedActor.GetActorRotation(); | ||
| 539 | + quat *= Quaternion(Radian(-0.1f), Vector3::YAXIS); | ||
| 540 | + mSelectedActor.AsyncSetPhysicsRotation(quat); | ||
| 541 | + btRigidBody* body = mSelectedActor.GetBody().Get<btRigidBody*>(); | ||
| 542 | + mPhysicsAdaptor.Queue([body]() { body->activate(true); }); | ||
| 543 | + mPhysicsAdaptor.CreateSyncPoint(); | ||
| 544 | + } | ||
| 545 | + else if(!event.GetKeyString().compare("x")) | ||
| 546 | + { | ||
| 547 | + Quaternion quat = mSelectedActor.GetActorRotation(); | ||
| 548 | + quat *= Quaternion(Radian(0.1f), Vector3::YAXIS); | ||
| 549 | + mSelectedActor.AsyncSetPhysicsRotation(quat); | ||
| 550 | + btRigidBody* body = mSelectedActor.GetBody().Get<btRigidBody*>(); | ||
| 551 | + mPhysicsAdaptor.Queue([body]() { body->activate(true); }); | ||
| 552 | + mPhysicsAdaptor.CreateSyncPoint(); | ||
| 553 | + } | ||
| 554 | + else if(!event.GetKeyString().compare("c")) | ||
| 555 | + { | ||
| 556 | + Quaternion quat = mSelectedActor.GetActorRotation(); | ||
| 557 | + quat *= Quaternion(Radian(-0.1f), Vector3::XAXIS); | ||
| 558 | + mSelectedActor.AsyncSetPhysicsRotation(quat); | ||
| 559 | + btRigidBody* body = mSelectedActor.GetBody().Get<btRigidBody*>(); | ||
| 560 | + mPhysicsAdaptor.Queue([body]() { body->activate(true); }); | ||
| 561 | + mPhysicsAdaptor.CreateSyncPoint(); | ||
| 562 | + } | ||
| 563 | + else if(!event.GetKeyString().compare("v")) | ||
| 564 | + { | ||
| 565 | + Quaternion quat = mSelectedActor.GetActorRotation(); | ||
| 566 | + quat *= Quaternion(Radian(0.1f), Vector3::XAXIS); | ||
| 567 | + mSelectedActor.AsyncSetPhysicsRotation(quat); | ||
| 568 | + btRigidBody* body = mSelectedActor.GetBody().Get<btRigidBody*>(); | ||
| 569 | + mPhysicsAdaptor.Queue([body]() { body->activate(true); }); | ||
| 570 | + mPhysicsAdaptor.CreateSyncPoint(); | ||
| 571 | + } | ||
| 572 | + else if(!event.GetKeyString().compare("p")) | ||
| 573 | + { | ||
| 574 | + mSelectedActor.AsyncSetPhysicsPosition(Vector3::ZERO); | ||
| 575 | + mSelectedActor.AsyncSetPhysicsRotation(Quaternion(Radian(0.001f), Vector3::XAXIS)); | ||
| 576 | + | ||
| 577 | + // Example of calling specific function asyncronously: | ||
| 578 | + btRigidBody* body = mSelectedActor.GetBody().Get<btRigidBody*>(); | ||
| 579 | + mPhysicsAdaptor.Queue([body]() { body->clearForces(); }); | ||
| 580 | + mPhysicsAdaptor.CreateSyncPoint(); | ||
| 581 | + } | ||
| 582 | + break; | ||
| 583 | + } | ||
| 584 | + } | ||
| 585 | + } | ||
| 586 | + else if(event.GetState() == KeyEvent::UP) | ||
| 587 | + { | ||
| 588 | + switch(event.GetKeyCode()) | ||
| 589 | + { | ||
| 590 | + case KeyModifier::CONTROL_L: | ||
| 591 | + case KeyModifier::CONTROL_R: | ||
| 592 | + { | ||
| 593 | + mCtrlDown = false; | ||
| 594 | + break; | ||
| 595 | + } | ||
| 596 | + case KeyModifier::ALT_L: | ||
| 597 | + case KeyModifier::ALT_R: | ||
| 598 | + { | ||
| 599 | + mAltDown = false; | ||
| 600 | + break; | ||
| 601 | + } | ||
| 602 | + case KeyModifier::SHIFT_L: | ||
| 603 | + case KeyModifier::SHIFT_R: | ||
| 604 | + { | ||
| 605 | + mShiftDown = false; | ||
| 606 | + break; | ||
| 607 | + } | ||
| 608 | + } | ||
| 609 | + } | ||
| 610 | + | ||
| 611 | + static int reduceSpam = 0; | ||
| 612 | + ++reduceSpam; | ||
| 613 | + if(reduceSpam == 2) | ||
| 614 | + { | ||
| 615 | + reduceSpam = 0; | ||
| 616 | + std::cout << "Dali pos: " << mBrick.GetActorPosition() << "\nDali rot: " << mBrick.GetActorRotation() << "\nPhys pos: " << mBrick.GetPhysicsPosition() << "\nPhys rot: " << mBrick.GetPhysicsRotation() << "\n"; | ||
| 617 | + } | ||
| 618 | + } | ||
| 619 | + | ||
| 620 | +private: | ||
| 621 | + Application& mApplication; | ||
| 622 | + Window mWindow; | ||
| 623 | + | ||
| 624 | + Matrix mPhysicsTransform; | ||
| 625 | + PhysicsAdaptor mPhysicsAdaptor; | ||
| 626 | + Actor mPhysicsRoot; | ||
| 627 | + Layer mPhysicsDebugLayer; | ||
| 628 | + PhysicsActor mBrick; | ||
| 629 | + PhysicsActor mSelectedActor; | ||
| 630 | + | ||
| 631 | + btRigidBody* mPickedBody; | ||
| 632 | + float mOldPickingDistance{0.0f}; | ||
| 633 | + int mPickedSavedState{0}; | ||
| 634 | + btTypedConstraint* mPickedConstraint{nullptr}; | ||
| 635 | + PhysicsAdaptor::IntegrationState mIntegrationState{PhysicsAdaptor::IntegrationState::ON}; | ||
| 636 | + PhysicsAdaptor::DebugState mDebugState{PhysicsAdaptor::DebugState::OFF}; | ||
| 637 | + | ||
| 638 | + bool mCtrlDown{false}; | ||
| 639 | + bool mAltDown{false}; | ||
| 640 | + bool mShiftDown{false}; | ||
| 641 | +}; | ||
| 642 | + | ||
| 643 | +int main(int argc, char** argv) | ||
| 644 | +{ | ||
| 645 | + Application application = Application::New(&argc, &argv); | ||
| 646 | + PhysicsDemoController controller(application); | ||
| 647 | + application.MainLoop(); | ||
| 648 | + return 0; | ||
| 649 | +} |
examples/bullet-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 vec4 texColor = vec4(0.5,0.5,0.5,1.0); | ||
| 28 | + //gl_FragColor = vec4(texColor.rgb, 1.0); | ||
| 29 | + | ||
| 30 | + mediump vec3 pcol=vec3(vIllumination.rgb * texColor.rgb)*(1.0+uBrightness); | ||
| 31 | + gl_FragColor = vec4( redistribute_rgb(pcol), 1.0); | ||
| 32 | +} |
examples/bullet-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 = aTexCoord; | ||
| 25 | + gl_Position = uMvpMatrix * vertexPosition; | ||
| 26 | +} |
examples/chipmunk-physics/dependencies.cmake
0 โ 100644
| 1 | +TARGET_COMPILE_OPTIONS(${EXAMPLE}.example PUBLIC ${DALI_PHYSICS_2D_CFLAGS}) | ||
| 2 | +TARGET_LINK_LIBRARIES(${EXAMPLE}.example ${DALI_PHYSICS_2D_LDFLAGS}) | ||
| 3 | +MESSAGE(STATUS "Included dependencies for ${EXAMPLE}") | ||
| 4 | +MESSAGE(STATUS " Compile options: ${DALI_PHYSICS_2D_CFLAGS}") | ||
| 5 | +MESSAGE(STATUS " Link options: ${DALI_PHYSICS_2D_LDFLAGS}") |
examples/drawable-actor/drawable-actor-example.cpp
| 1 | /* | 1 | /* |
| 2 | - * Copyright (c) 2020 Samsung Electronics Co., Ltd. | 2 | + * Copyright (c) 2023 Samsung Electronics Co., Ltd. |
| 3 | * | 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. | 5 | * you may not use this file except in compliance with the License. |
| @@ -35,9 +35,8 @@ using namespace Dali; | @@ -35,9 +35,8 @@ using namespace Dali; | ||
| 35 | class DrawableActorExampleController : public ConnectionTracker | 35 | class DrawableActorExampleController : public ConnectionTracker |
| 36 | { | 36 | { |
| 37 | public: | 37 | public: |
| 38 | - | ||
| 39 | explicit DrawableActorExampleController(Application& application) | 38 | explicit DrawableActorExampleController(Application& application) |
| 40 | - : mApplication(application) | 39 | + : mApplication(application) |
| 41 | { | 40 | { |
| 42 | // Connect to the Application's Init signal | 41 | // Connect to the Application's Init signal |
| 43 | mApplication.InitSignal().Connect(this, &DrawableActorExampleController::Create); | 42 | mApplication.InitSignal().Connect(this, &DrawableActorExampleController::Create); |
| @@ -56,16 +55,17 @@ public: | @@ -56,16 +55,17 @@ public: | ||
| 56 | mRenderer = std::make_unique<NativeRenderer>(window.GetSize().GetWidth(), window.GetSize().GetHeight()); | 55 | mRenderer = std::make_unique<NativeRenderer>(window.GetSize().GetWidth(), window.GetSize().GetHeight()); |
| 57 | 56 | ||
| 58 | // Create render callback | 57 | // Create render callback |
| 59 | - mRenderCallback = RenderCallback::New<NativeRenderer>( mRenderer.get(), &NativeRenderer::OnRender ); | 58 | + mRenderCallback = RenderCallback::New<NativeRenderer>(mRenderer.get(), &NativeRenderer::OnRender); |
| 60 | 59 | ||
| 61 | // Create drawable actor | 60 | // Create drawable actor |
| 62 | - mGLActor = DrawableActor::New( *mRenderCallback ); | 61 | + mGLActor = DrawableActor::New(*mRenderCallback); |
| 63 | 62 | ||
| 64 | - mGLActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER); | ||
| 65 | - mGLActor.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER ); | 63 | + mGLActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); |
| 64 | + mGLActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT); | ||
| 66 | 65 | ||
| 67 | // Set size on the actor (half the window size to show that glClear() and scissor test work together) | 66 | // Set size on the actor (half the window size to show that glClear() and scissor test work together) |
| 68 | - mGLActor.SetProperty( Actor::Property::SIZE, Size( window.GetSize() ) * 0.5f); | 67 | + mGLActor.SetProperty(Actor::Property::SIZE, Size(window.GetSize()) * 0.75f); |
| 68 | + mGLActor[Actor::Property::POSITION] = Vector3(50.0f, 50.0f, 0.0f); | ||
| 69 | 69 | ||
| 70 | // Add actor to the scene | 70 | // Add actor to the scene |
| 71 | window.Add(mGLActor); | 71 | window.Add(mGLActor); |
| @@ -101,7 +101,7 @@ public: | @@ -101,7 +101,7 @@ public: | ||
| 101 | } | 101 | } |
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | - TextLabel mTextLabel; | 104 | + TextLabel mTextLabel; |
| 105 | DrawableActor mGLActor; | 105 | DrawableActor mGLActor; |
| 106 | 106 | ||
| 107 | std::unique_ptr<RenderCallback> mRenderCallback; | 107 | std::unique_ptr<RenderCallback> mRenderCallback; |
| @@ -113,7 +113,7 @@ private: | @@ -113,7 +113,7 @@ private: | ||
| 113 | 113 | ||
| 114 | int DALI_EXPORT_API main(int argc, char** argv) | 114 | int DALI_EXPORT_API main(int argc, char** argv) |
| 115 | { | 115 | { |
| 116 | - Application application = Application::New(&argc, &argv); | 116 | + Application application = Application::New(&argc, &argv); |
| 117 | DrawableActorExampleController test(application); | 117 | DrawableActorExampleController test(application); |
| 118 | application.MainLoop(); | 118 | application.MainLoop(); |
| 119 | return 0; | 119 | return 0; |
resources/po/en_GB.po
| @@ -28,6 +28,9 @@ msgstr "Bloom" | @@ -28,6 +28,9 @@ msgstr "Bloom" | ||
| 28 | msgid "DALI_DEMO_STR_TITLE_BUBBLES" | 28 | msgid "DALI_DEMO_STR_TITLE_BUBBLES" |
| 29 | msgstr "Bubbles" | 29 | msgstr "Bubbles" |
| 30 | 30 | ||
| 31 | +msgid "DALI_DEMO_STR_TITLE_BULLET_PHYSICS" | ||
| 32 | +msgstr "Bullet Physics" | ||
| 33 | + | ||
| 31 | msgid "DALI_DEMO_STR_TITLE_BUTTONS" | 34 | msgid "DALI_DEMO_STR_TITLE_BUTTONS" |
| 32 | msgstr "Buttons" | 35 | msgstr "Buttons" |
| 33 | 36 |
resources/po/en_US.po
| @@ -28,6 +28,9 @@ msgstr "Bloom" | @@ -28,6 +28,9 @@ msgstr "Bloom" | ||
| 28 | msgid "DALI_DEMO_STR_TITLE_BUBBLES" | 28 | msgid "DALI_DEMO_STR_TITLE_BUBBLES" |
| 29 | msgstr "Bubbles" | 29 | msgstr "Bubbles" |
| 30 | 30 | ||
| 31 | +msgid "DALI_DEMO_STR_TITLE_BULLET_PHYSICS" | ||
| 32 | +msgstr "Bullet Physics" | ||
| 33 | + | ||
| 31 | msgid "DALI_DEMO_STR_TITLE_BUTTONS" | 34 | msgid "DALI_DEMO_STR_TITLE_BUTTONS" |
| 32 | msgstr "Buttons" | 35 | msgstr "Buttons" |
| 33 | 36 |
shared/dali-demo-strings.h
| @@ -45,6 +45,7 @@ extern "C" | @@ -45,6 +45,7 @@ extern "C" | ||
| 45 | #define DALI_DEMO_STR_TITLE_BLOCKS dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_BLOCKS") | 45 | #define DALI_DEMO_STR_TITLE_BLOCKS dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_BLOCKS") |
| 46 | #define DALI_DEMO_STR_TITLE_BLOOM_VIEW dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_BLOOM_VIEW") | 46 | #define DALI_DEMO_STR_TITLE_BLOOM_VIEW dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_BLOOM_VIEW") |
| 47 | #define DALI_DEMO_STR_TITLE_BUBBLES dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_BUBBLES") | 47 | #define DALI_DEMO_STR_TITLE_BUBBLES dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_BUBBLES") |
| 48 | +#define DALI_DEMO_STR_TITLE_BULLET_PHYSICS dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_BULLET_PHYSICS") | ||
| 48 | #define DALI_DEMO_STR_TITLE_BUTTONS dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_BUTTONS") | 49 | #define DALI_DEMO_STR_TITLE_BUTTONS dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_BUTTONS") |
| 49 | #define DALI_DEMO_STR_TITLE_CAMERA_TEST dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_CAMERA_TEST") | 50 | #define DALI_DEMO_STR_TITLE_CAMERA_TEST dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_CAMERA_TEST") |
| 50 | #define DALI_DEMO_STR_TITLE_CANVAS_VIEW dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_CANVAS_VIEW") | 51 | #define DALI_DEMO_STR_TITLE_CANVAS_VIEW dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_CANVAS_VIEW") |
| @@ -165,6 +166,7 @@ extern "C" | @@ -165,6 +166,7 @@ extern "C" | ||
| 165 | #define DALI_DEMO_STR_TITLE_BLOCKS "Blocks" | 166 | #define DALI_DEMO_STR_TITLE_BLOCKS "Blocks" |
| 166 | #define DALI_DEMO_STR_TITLE_BLOOM_VIEW "Bloom" | 167 | #define DALI_DEMO_STR_TITLE_BLOOM_VIEW "Bloom" |
| 167 | #define DALI_DEMO_STR_TITLE_BUBBLES "Bubbles" | 168 | #define DALI_DEMO_STR_TITLE_BUBBLES "Bubbles" |
| 169 | +#define DALI_DEMO_STR_TITLE_BULLET_PHYSICS "Bullet Physics" | ||
| 168 | #define DALI_DEMO_STR_TITLE_BUTTONS "Buttons" | 170 | #define DALI_DEMO_STR_TITLE_BUTTONS "Buttons" |
| 169 | #define DALI_DEMO_STR_TITLE_CAMERA_TEST "Camera Test" | 171 | #define DALI_DEMO_STR_TITLE_CAMERA_TEST "Camera Test" |
| 170 | #define DALI_DEMO_STR_TITLE_CANVAS_VIEW "Canvas View" | 172 | #define DALI_DEMO_STR_TITLE_CANVAS_VIEW "Canvas View" |