Commit 0fb7eb9844f083c4edb33d1fe1ae3585cbb58659

Authored by David Steele
1 parent d9f0323e

Added bullet-physics-demo

Added mechanism to handle optional dependencies

Change-Id: Ib24df94c68bb1cca58ff8fbb2be3d32cc5668ed0
.gitignore
... ... @@ -60,6 +60,10 @@ simple-image-wall.js
60 60 /com.samsung.dali-demo-debugsource.manifest
61 61 /build/tizen/*.vcxproj
62 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 67 /build/tizen/builder/Debug/*
64 68 /build/tizen/builder/Release/*
65 69 /build/tizen/builder/*.dir
... ...
build/tizen/CMakeLists.txt
... ... @@ -243,21 +243,39 @@ 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)
  246 + pkg_check_modules(DALI_PHYSICS_2D dali2-physics-2d chipmunk2d)
247 247 IF( DALI_PHYSICS_2D_FOUND )
248 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 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 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 256 ENDFOREACH(flag)
  257 + STRING(STRIP ${OPTIONAL_PHYSICS_2D_LDFLAGS} OPTIONAL_PHYSICS_2D_LDFLAGS)
257 258  
258 259 SET( ENABLE_PHYSICS_2D "ON" )
259 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 279 # if build as tizen platform, use capi-appfw-app-control
262 280 IF( TIZEN )
263 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 326 FIND_PACKAGE( dali2-scene3d )
309 327  
310 328 FIND_PACKAGE( chipmunk )
  329 + FIND_PACKAGE( bullet3 )
  330 + FIND_PACKAGE( dali2-physics-3d )
311 331  
312 332 # Set up the include dir
313 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 385 ENDIF()
366 386  
367 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 399 ENDIF()
374 400  
375 401 ELSEIF( UNIX )
... ... @@ -404,6 +430,10 @@ IF( ENABLE_PHYSICS_2D )
404 430 SET(DALI_DEMO_CFLAGS "${DALI_DEMO_CFLAGS} -DDALI_PHYSICS_2D_AVAILABLE")
405 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 437 IF( UNIX )
408 438 IF( NOT ${ENABLE_EXPORTALL} )
409 439 ADD_DEFINITIONS( "-DHIDE_DALI_INTERNALS" )
... ... @@ -522,3 +552,4 @@ MESSAGE( " Current Build Platform : [" ${CURRENT_BUILD_PLATFORM} "]" )
522 552 MESSAGE( " Build example name : [" ${CURRENT_BUILD_EXAMPLE_NAME} "]" )
523 553 MESSAGE( " Scene3D Enabled : [" ${ENABLE_SCENE3D} "]" )
524 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 35 FUNCTION(INSTALL_EXAMPLES EXAMPLE)
36 36 SET(PARENT_CMAKE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../")
37 37 FILE(GLOB_RECURSE SRCS "${EXAMPLES_SRC_DIR}/${EXAMPLE}/*.cpp")
  38 +
38 39 SET(SRCS ${SRCS} "${ROOT_SRC_DIR}/shared/resources-location.cpp")
39 40 IF(SHARED)
40 41 ADD_LIBRARY(${EXAMPLE}.example SHARED ${SRCS})
... ... @@ -42,6 +43,10 @@ FUNCTION(INSTALL_EXAMPLES EXAMPLE)
42 43 ADD_EXECUTABLE(${EXAMPLE}.example ${SRCS})
43 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 50 # Generate source files for shaders
46 51 SET(SHADER_SOURCE_DIR "${EXAMPLES_SRC_DIR}/${EXAMPLE}/shaders/")
47 52 IF (EXISTS ${SHADER_SOURCE_DIR})
... ... @@ -64,4 +69,3 @@ IF( NOT BUILD_EXAMPLE_NAME )
64 69 ELSE()
65 70 INSTALL_EXAMPLES(${BUILD_EXAMPLE_NAME})
66 71 ENDIF()
67   -
... ...
com.samsung.dali-demo.xml
... ... @@ -58,6 +58,9 @@
58 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 59 <label>Script Based UI</label>
60 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 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 65 <label>Buttons</label>
63 66 </ui-application>
... ...
examples-reel/dali-examples-reel.cpp
... ... @@ -46,6 +46,7 @@ int DALI_EXPORT_API main(int argc, char** argv)
46 46 demo.AddExample(Example("bloom-view.example", DALI_DEMO_STR_TITLE_BLOOM_VIEW));
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 + demo.AddExample(Example("bullet-physics.example", DALI_DEMO_STR_TITLE_BULLET_PHYSICS));
49 50 demo.AddExample(Example("canvas-view.example", DALI_DEMO_STR_TITLE_CANVAS_VIEW));
50 51 demo.AddExample(Example("chipmunk-physics.example", DALI_DEMO_STR_TITLE_CHIPMUNK_PHYSICS));
51 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 4 * Licensed under the Apache License, Version 2.0 (the "License");
5 5 * you may not use this file except in compliance with the License.
... ... @@ -35,9 +35,8 @@ using namespace Dali;
35 35 class DrawableActorExampleController : public ConnectionTracker
36 36 {
37 37 public:
38   -
39 38 explicit DrawableActorExampleController(Application& application)
40   - : mApplication(application)
  39 + : mApplication(application)
41 40 {
42 41 // Connect to the Application's Init signal
43 42 mApplication.InitSignal().Connect(this, &DrawableActorExampleController::Create);
... ... @@ -56,16 +55,17 @@ public:
56 55 mRenderer = std::make_unique<NativeRenderer>(window.GetSize().GetWidth(), window.GetSize().GetHeight());
57 56  
58 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 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 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 70 // Add actor to the scene
71 71 window.Add(mGLActor);
... ... @@ -101,7 +101,7 @@ public:
101 101 }
102 102 }
103 103  
104   - TextLabel mTextLabel;
  104 + TextLabel mTextLabel;
105 105 DrawableActor mGLActor;
106 106  
107 107 std::unique_ptr<RenderCallback> mRenderCallback;
... ... @@ -113,7 +113,7 @@ private:
113 113  
114 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 117 DrawableActorExampleController test(application);
118 118 application.MainLoop();
119 119 return 0;
... ...
resources/po/en_GB.po
... ... @@ -28,6 +28,9 @@ msgstr &quot;Bloom&quot;
28 28 msgid "DALI_DEMO_STR_TITLE_BUBBLES"
29 29 msgstr "Bubbles"
30 30  
  31 +msgid "DALI_DEMO_STR_TITLE_BULLET_PHYSICS"
  32 +msgstr "Bullet Physics"
  33 +
31 34 msgid "DALI_DEMO_STR_TITLE_BUTTONS"
32 35 msgstr "Buttons"
33 36  
... ...
resources/po/en_US.po
... ... @@ -28,6 +28,9 @@ msgstr &quot;Bloom&quot;
28 28 msgid "DALI_DEMO_STR_TITLE_BUBBLES"
29 29 msgstr "Bubbles"
30 30  
  31 +msgid "DALI_DEMO_STR_TITLE_BULLET_PHYSICS"
  32 +msgstr "Bullet Physics"
  33 +
31 34 msgid "DALI_DEMO_STR_TITLE_BUTTONS"
32 35 msgstr "Buttons"
33 36  
... ...
shared/dali-demo-strings.h
... ... @@ -45,6 +45,7 @@ extern &quot;C&quot;
45 45 #define DALI_DEMO_STR_TITLE_BLOCKS dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_BLOCKS")
46 46 #define DALI_DEMO_STR_TITLE_BLOOM_VIEW dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_BLOOM_VIEW")
47 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 49 #define DALI_DEMO_STR_TITLE_BUTTONS dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_BUTTONS")
49 50 #define DALI_DEMO_STR_TITLE_CAMERA_TEST dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_CAMERA_TEST")
50 51 #define DALI_DEMO_STR_TITLE_CANVAS_VIEW dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_CANVAS_VIEW")
... ... @@ -165,6 +166,7 @@ extern &quot;C&quot;
165 166 #define DALI_DEMO_STR_TITLE_BLOCKS "Blocks"
166 167 #define DALI_DEMO_STR_TITLE_BLOOM_VIEW "Bloom"
167 168 #define DALI_DEMO_STR_TITLE_BUBBLES "Bubbles"
  169 +#define DALI_DEMO_STR_TITLE_BULLET_PHYSICS "Bullet Physics"
168 170 #define DALI_DEMO_STR_TITLE_BUTTONS "Buttons"
169 171 #define DALI_DEMO_STR_TITLE_CAMERA_TEST "Camera Test"
170 172 #define DALI_DEMO_STR_TITLE_CANVAS_VIEW "Canvas View"
... ...