Commit 94b12f95897032fe73182ed01e1061f7f7f36aad
[dali_1.9.5] Merge branch 'devel/master'
Change-Id: Idab8962dccdaf89a6972b5a8e9f4ad77342566b1
Showing
20 changed files
with
3980 additions
and
9 deletions
build/tizen/CMakeLists.txt
| @@ -11,8 +11,8 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") | @@ -11,8 +11,8 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") | ||
| 11 | endif() | 11 | endif() |
| 12 | endif() | 12 | endif() |
| 13 | 13 | ||
| 14 | -SET(ROOT_SRC_DIR ${CMAKE_SOURCE_DIR}/../..) | ||
| 15 | -SET(DEMO_SHARED ${CMAKE_SOURCE_DIR}/../../shared) | 14 | +SET(ROOT_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../..) |
| 15 | +SET(DEMO_SHARED ${CMAKE_CURRENT_SOURCE_DIR}/../../shared) | ||
| 16 | 16 | ||
| 17 | SET(PREFIX ${CMAKE_INSTALL_PREFIX}) | 17 | SET(PREFIX ${CMAKE_INSTALL_PREFIX}) |
| 18 | 18 | ||
| @@ -177,7 +177,7 @@ SET(PO_DIR ${RESOURCE_DIR}/po) | @@ -177,7 +177,7 @@ SET(PO_DIR ${RESOURCE_DIR}/po) | ||
| 177 | FILE(GLOB PO_FILES RELATIVE "${PO_DIR}" "${PO_DIR}/*.po") | 177 | FILE(GLOB PO_FILES RELATIVE "${PO_DIR}" "${PO_DIR}/*.po") |
| 178 | 178 | ||
| 179 | SET(MSGFMT "/usr/bin/msgfmt") | 179 | SET(MSGFMT "/usr/bin/msgfmt") |
| 180 | -SET(MO_FILES_DIR ${CMAKE_BINARY_DIR}/mo) | 180 | +SET(MO_FILES_DIR ${CMAKE_CURRENT_BINARY_DIR}/mo) |
| 181 | FILE(MAKE_DIRECTORY ${MO_FILES_DIR}) | 181 | FILE(MAKE_DIRECTORY ${MO_FILES_DIR}) |
| 182 | 182 | ||
| 183 | FOREACH(PO_FILE ${PO_FILES}) | 183 | FOREACH(PO_FILE ${PO_FILES}) |
com.samsung.dali-demo.xml
| @@ -187,6 +187,9 @@ | @@ -187,6 +187,9 @@ | ||
| 187 | <ui-application appid="ray-marching.example" exec="/usr/apps/com.samsung.dali-demo/bin/ray-marching.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true"> | 187 | <ui-application appid="ray-marching.example" exec="/usr/apps/com.samsung.dali-demo/bin/ray-marching.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true"> |
| 188 | <label>Ray Marching example</label> | 188 | <label>Ray Marching example</label> |
| 189 | </ui-application> | 189 | </ui-application> |
| 190 | + <ui-application appid="reflection-demo.example" exec="/usr/apps/com.samsung.dali-demo/bin/reflection-demo.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true"> | ||
| 191 | + <label>Reflection effect</label> | ||
| 192 | + </ui-application> | ||
| 190 | <ui-application appid="refraction-effect.example" exec="/usr/apps/com.samsung.dali-demo/bin/refraction-effect.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true"> | 193 | <ui-application appid="refraction-effect.example" exec="/usr/apps/com.samsung.dali-demo/bin/refraction-effect.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true"> |
| 191 | <label>Refraction effect</label> | 194 | <label>Refraction effect</label> |
| 192 | </ui-application> | 195 | </ui-application> |
demo/dali-demo.cpp
| @@ -50,6 +50,7 @@ int DALI_EXPORT_API main(int argc, char **argv) | @@ -50,6 +50,7 @@ int DALI_EXPORT_API main(int argc, char **argv) | ||
| 50 | demo.AddExample(Example("metaball-refrac.example", DALI_DEMO_STR_TITLE_METABALL_REFRAC)); | 50 | demo.AddExample(Example("metaball-refrac.example", DALI_DEMO_STR_TITLE_METABALL_REFRAC)); |
| 51 | demo.AddExample(Example("motion-blur.example", DALI_DEMO_STR_TITLE_MOTION_BLUR)); | 51 | demo.AddExample(Example("motion-blur.example", DALI_DEMO_STR_TITLE_MOTION_BLUR)); |
| 52 | demo.AddExample(Example("page-turn-view.example", DALI_DEMO_STR_TITLE_PAGE_TURN)); | 52 | demo.AddExample(Example("page-turn-view.example", DALI_DEMO_STR_TITLE_PAGE_TURN)); |
| 53 | + demo.AddExample(Example("reflection-demo.example", DALI_DEMO_STR_TITLE_REFLECTION)); | ||
| 53 | demo.AddExample(Example("refraction-effect.example", DALI_DEMO_STR_TITLE_REFRACTION)); | 54 | demo.AddExample(Example("refraction-effect.example", DALI_DEMO_STR_TITLE_REFRACTION)); |
| 54 | demo.AddExample(Example("renderer-stencil.example", DALI_DEMO_STR_TITLE_RENDERER_STENCIL)); | 55 | demo.AddExample(Example("renderer-stencil.example", DALI_DEMO_STR_TITLE_RENDERER_STENCIL)); |
| 55 | demo.AddExample(Example("shadows-and-lights.example", DALI_DEMO_STR_TITLE_LIGHTS_AND_SHADOWS)); | 56 | demo.AddExample(Example("shadows-and-lights.example", DALI_DEMO_STR_TITLE_LIGHTS_AND_SHADOWS)); |
examples/contact-cards/contact-card.h
| @@ -26,7 +26,7 @@ | @@ -26,7 +26,7 @@ | ||
| 26 | #include <dali/public-api/object/ref-object.h> | 26 | #include <dali/public-api/object/ref-object.h> |
| 27 | #include <dali-toolkit/public-api/controls/control.h> | 27 | #include <dali-toolkit/public-api/controls/control.h> |
| 28 | 28 | ||
| 29 | -class ContactCardLayoutInfo; | 29 | +struct ContactCardLayoutInfo; |
| 30 | 30 | ||
| 31 | /** | 31 | /** |
| 32 | * @brief Creates and sets up animations for a contact card | 32 | * @brief Creates and sets up animations for a contact card |
examples/point-mesh/point-mesh-example.cpp
| @@ -82,7 +82,7 @@ Geometry CreateGeometry() | @@ -82,7 +82,7 @@ Geometry CreateGeometry() | ||
| 82 | // Create vertices | 82 | // Create vertices |
| 83 | struct Vertex { Vector2 position; float hue; }; | 83 | struct Vertex { Vector2 position; float hue; }; |
| 84 | 84 | ||
| 85 | - unsigned int numSides = 20; | 85 | + const unsigned int numSides = 20; |
| 86 | Vertex polyhedraVertexData[numSides]; | 86 | Vertex polyhedraVertexData[numSides]; |
| 87 | float angle=0; | 87 | float angle=0; |
| 88 | float sectorAngle = 2.0f * Math::PI / (float) numSides; | 88 | float sectorAngle = 2.0f * Math::PI / (float) numSides; |
examples/reflection-demo/gltf-scene.cpp
0 → 100644
| 1 | +/* | ||
| 2 | + * Copyright (c) 2020 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/devel-api/adaptor-framework/file-stream.h> | ||
| 18 | + | ||
| 19 | +#include "gltf-scene.h" | ||
| 20 | + | ||
| 21 | +#include "pico-json.h" | ||
| 22 | + | ||
| 23 | +namespace | ||
| 24 | +{ | ||
| 25 | +// string contains enum type index encoded matching glTFAttributeType | ||
| 26 | +const std::vector<std::string> GLTF_STR_ATTRIBUTE_TYPE = { | ||
| 27 | + "POSITION", | ||
| 28 | + "NORMAL", | ||
| 29 | + "TEXCOORD_0" | ||
| 30 | +}; | ||
| 31 | + | ||
| 32 | +const std::vector<std::pair<std::string, uint32_t>> GLTF_STR_COMPONENT_TYPE = { | ||
| 33 | + std::make_pair( "VEC2", 2 ), | ||
| 34 | + std::make_pair( "VEC3", 3 ), | ||
| 35 | + std::make_pair( "VEC4", 4 ), | ||
| 36 | + std::make_pair( "SCALAR", 1 ) | ||
| 37 | +}; | ||
| 38 | + | ||
| 39 | +glTFAttributeType glTFAttributeTypeStrToEnum( const std::string& name ) | ||
| 40 | +{ | ||
| 41 | + int index = -1; | ||
| 42 | + auto iter = std::find_if( GLTF_STR_ATTRIBUTE_TYPE.begin(), GLTF_STR_ATTRIBUTE_TYPE.end(), | ||
| 43 | + [name, &index]( const std::string& val ) | ||
| 44 | + { | ||
| 45 | + index++; | ||
| 46 | + return val == name; | ||
| 47 | + }); | ||
| 48 | + if( iter == GLTF_STR_ATTRIBUTE_TYPE.end() ) | ||
| 49 | + { | ||
| 50 | + return glTFAttributeType::UNDEFINED; | ||
| 51 | + } | ||
| 52 | + | ||
| 53 | + return static_cast<glTFAttributeType>(index); | ||
| 54 | +} | ||
| 55 | + | ||
| 56 | +uint32_t glTFComponentTypeStrToNum( const std::string& name ) | ||
| 57 | +{ | ||
| 58 | + auto iter = std::find_if( GLTF_STR_COMPONENT_TYPE.begin(), GLTF_STR_COMPONENT_TYPE.end(), | ||
| 59 | + [name]( const std::pair<std::string, uint32_t>& val ) | ||
| 60 | + { | ||
| 61 | + return val.first == name; | ||
| 62 | + }); | ||
| 63 | + if( iter == GLTF_STR_COMPONENT_TYPE.end() ) | ||
| 64 | + { | ||
| 65 | + return 0; | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + return iter->second; | ||
| 69 | +} | ||
| 70 | + | ||
| 71 | +template<class T> | ||
| 72 | +struct JsonResult | ||
| 73 | +{ | ||
| 74 | + bool success; | ||
| 75 | + T result; | ||
| 76 | + operator T() const | ||
| 77 | + { | ||
| 78 | + return static_cast<T>(result); | ||
| 79 | + } | ||
| 80 | +}; | ||
| 81 | + | ||
| 82 | +template<> | ||
| 83 | +struct JsonResult<bool> | ||
| 84 | +{ | ||
| 85 | + bool success; | ||
| 86 | + bool result; | ||
| 87 | + | ||
| 88 | + operator bool() const | ||
| 89 | + { | ||
| 90 | + return result; | ||
| 91 | + } | ||
| 92 | +}; | ||
| 93 | + | ||
| 94 | +template<class Expected, class Converted = Expected> | ||
| 95 | +JsonResult<picojson::value> JsonFindValue( const picojson::object& object, const std::string& name ) | ||
| 96 | +{ | ||
| 97 | + auto iter = find_if(object.begin(), object.end(), [name](decltype(*object.begin())& item) | ||
| 98 | + { | ||
| 99 | + return item.first == name; | ||
| 100 | + }); | ||
| 101 | + | ||
| 102 | + if(iter == object.end()) | ||
| 103 | + { | ||
| 104 | + return {false}; | ||
| 105 | + } | ||
| 106 | + | ||
| 107 | + return {true, iter->second}; | ||
| 108 | +}; | ||
| 109 | + | ||
| 110 | + | ||
| 111 | +template<class Expected, class Converted = Expected> | ||
| 112 | +JsonResult<Converted> JsonGetValue( const picojson::value& val, const std::string& name, const Converted& onFail ) | ||
| 113 | +{ | ||
| 114 | + if( val.contains(name) ) | ||
| 115 | + { | ||
| 116 | + return {true, static_cast<Converted>(val.get(name).get<Expected>())}; | ||
| 117 | + } | ||
| 118 | + return {false, onFail}; | ||
| 119 | +} | ||
| 120 | + | ||
| 121 | +template<class Expected, class Converted = Expected> | ||
| 122 | +bool JsonGetValueOut( const picojson::value& val, const std::string& name, Converted& writeOut ) | ||
| 123 | +{ | ||
| 124 | + if( val.contains(name) ) | ||
| 125 | + { | ||
| 126 | + writeOut = static_cast<Converted>(val.get(name).get<Expected>()); | ||
| 127 | + return true; | ||
| 128 | + } | ||
| 129 | + return false; | ||
| 130 | +} | ||
| 131 | + | ||
| 132 | + | ||
| 133 | +/** | ||
| 134 | + * Safe json value accessor | ||
| 135 | + */ | ||
| 136 | +template<class Expected, class Converted = Expected> | ||
| 137 | +JsonResult<std::vector<Converted>> JsonGetArray( const picojson::value& val, const std::string& name, std::vector<Converted> valueOnFail = {} ) | ||
| 138 | +{ | ||
| 139 | + if(val.contains(name) ) | ||
| 140 | + { | ||
| 141 | + const auto& array = val.get(name).get<picojson::array>(); | ||
| 142 | + std::vector<Converted> result{}; | ||
| 143 | + for( const auto& item : array ) | ||
| 144 | + { | ||
| 145 | + result.emplace_back( static_cast<Converted>(item.get<Expected>()) ); | ||
| 146 | + } | ||
| 147 | + return {true, result}; | ||
| 148 | + } | ||
| 149 | + return {false, valueOnFail}; | ||
| 150 | +} | ||
| 151 | + | ||
| 152 | +} | ||
| 153 | + | ||
| 154 | +glTF::glTF(const std::string& filename) | ||
| 155 | +{ | ||
| 156 | + LoadFromFile(filename); | ||
| 157 | + ParseJSON(); | ||
| 158 | +} | ||
| 159 | + | ||
| 160 | +void glTF::LoadFromFile( const std::string& filename ) | ||
| 161 | +{ | ||
| 162 | + std::string jsonFile( filename ); | ||
| 163 | + jsonFile += ".gltf"; | ||
| 164 | + std::string binFile( filename ); | ||
| 165 | + binFile += ".bin"; | ||
| 166 | + | ||
| 167 | + // load binary | ||
| 168 | + | ||
| 169 | + GLTF_LOG("LoadFromFile: %s", binFile.c_str()); | ||
| 170 | + mBuffer = LoadFile(binFile); | ||
| 171 | + jsonBuffer = LoadFile(jsonFile); | ||
| 172 | + | ||
| 173 | + // Log errors | ||
| 174 | + if(mBuffer.empty()) | ||
| 175 | + { | ||
| 176 | + GLTF_LOG("Error, buffer empty!"); | ||
| 177 | + } | ||
| 178 | + else | ||
| 179 | + { | ||
| 180 | + GLTF_LOG( "GLTF[BIN]: %s loaded, size = %d", binFile.c_str(), int(mBuffer.size())); | ||
| 181 | + } | ||
| 182 | + if(jsonBuffer.empty()) | ||
| 183 | + { | ||
| 184 | + GLTF_LOG("Error, buffer GLTF empty!"); | ||
| 185 | + } | ||
| 186 | + else | ||
| 187 | + { | ||
| 188 | + GLTF_LOG( "GLTF: %s loaded, size = %d", binFile.c_str(), int(mBuffer.size())); | ||
| 189 | + } | ||
| 190 | + | ||
| 191 | + // Abort if errors | ||
| 192 | + if(jsonBuffer.empty() || mBuffer.empty()) | ||
| 193 | + { | ||
| 194 | + return; | ||
| 195 | + } | ||
| 196 | + | ||
| 197 | + // parse json | ||
| 198 | + auto err = picojson::parse(jsonNode, std::string(reinterpret_cast<char*>(jsonBuffer.data()))); | ||
| 199 | + if(!err.empty()) | ||
| 200 | + { | ||
| 201 | + GLTF_LOG( "GLTF: Error parsing %s, error: %s", jsonFile.c_str(), err.c_str()); | ||
| 202 | + return; | ||
| 203 | + } | ||
| 204 | + else | ||
| 205 | + { | ||
| 206 | + GLTF_LOG( "GLTF: %s loaded, size = %d", jsonFile.c_str(), int(jsonBuffer.size())); | ||
| 207 | + } | ||
| 208 | +} | ||
| 209 | + | ||
| 210 | +bool glTF::ParseJSON() | ||
| 211 | +{ | ||
| 212 | + if (!jsonNode.is<picojson::object>()) | ||
| 213 | + { | ||
| 214 | + return false; | ||
| 215 | + } | ||
| 216 | + | ||
| 217 | + // Add dummy first node to nodes (scene node) | ||
| 218 | + mNodes.emplace_back(); | ||
| 219 | + | ||
| 220 | + // Sources for textures to be resolved later | ||
| 221 | + std::vector<uint32_t> textureSources{}; | ||
| 222 | + std::vector<glTF_Texture> images{}; | ||
| 223 | + | ||
| 224 | + for( auto& val : jsonNode.get<picojson::object>() ) | ||
| 225 | + { | ||
| 226 | + GLTF_LOG( "node: %s", val.first.c_str()); | ||
| 227 | + | ||
| 228 | + // Parse bufferviews | ||
| 229 | + if( val.first == "bufferViews" ) | ||
| 230 | + { | ||
| 231 | + auto bufferViews = val.second; | ||
| 232 | + for( auto& view : bufferViews.get<picojson::array>() ) | ||
| 233 | + { | ||
| 234 | + auto bufferIndex = uint32_t(view.get("buffer").get<double>()); | ||
| 235 | + auto byteLength = uint32_t(view.get("byteLength").get<double>()); | ||
| 236 | + auto byteOffset = uint32_t(view.get("byteOffset").get<double>()); | ||
| 237 | + | ||
| 238 | + glTF_BufferView bufferView{}; | ||
| 239 | + bufferView.bufferIndex = bufferIndex; | ||
| 240 | + bufferView.byteLength = byteLength; | ||
| 241 | + bufferView.byteOffset = byteOffset; | ||
| 242 | + | ||
| 243 | + mBufferViews.emplace_back( bufferView ); | ||
| 244 | + } | ||
| 245 | + } | ||
| 246 | + | ||
| 247 | + // parse accessors | ||
| 248 | + else if( val.first == "accessors" ) | ||
| 249 | + { | ||
| 250 | + for( const auto& accessor : val.second.get<picojson::array>() ) | ||
| 251 | + { | ||
| 252 | + auto gltfAccessor = glTF_Accessor{}; | ||
| 253 | + gltfAccessor.bufferView = uint32_t(accessor.get( "bufferView" ).get<double>()); | ||
| 254 | + gltfAccessor.componentType = uint32_t(accessor.get( "componentType" ).get<double>()); | ||
| 255 | + gltfAccessor.count = uint32_t(accessor.get( "count" ).get<double>()); | ||
| 256 | + gltfAccessor.type = accessor.get( "type" ).get<std::string>(); | ||
| 257 | + gltfAccessor.componentSize = glTFComponentTypeStrToNum( gltfAccessor.type ); | ||
| 258 | + mAccessors.emplace_back( gltfAccessor ); | ||
| 259 | + } | ||
| 260 | + } | ||
| 261 | + | ||
| 262 | + // parse meshes | ||
| 263 | + else if( val.first == "meshes" ) | ||
| 264 | + { | ||
| 265 | + for( const auto& mesh : val.second.get<picojson::array>() ) | ||
| 266 | + { | ||
| 267 | + glTF_Mesh gltfMesh{}; | ||
| 268 | + gltfMesh.name = mesh.get( "name" ).get<std::string>(); | ||
| 269 | + | ||
| 270 | + // get primitives (in this implementation assuming single mesh consists of | ||
| 271 | + // one and only one primitive) | ||
| 272 | + const auto& primitive = mesh.get("primitives").get<picojson::array>()[0]; | ||
| 273 | + const auto& attrs = primitive.get("attributes").get<picojson::object>(); | ||
| 274 | + for( const auto& attr : attrs ) | ||
| 275 | + { | ||
| 276 | + auto type = glTFAttributeTypeStrToEnum( attr.first ); | ||
| 277 | + auto bvIndex = uint32_t(attr.second.get<double>()); | ||
| 278 | + gltfMesh.attributes.emplace_back( std::make_pair( type, bvIndex ) ); | ||
| 279 | + GLTF_LOG("GLTF: ATTR: type: %d, index: %d", int(type), int(bvIndex)); | ||
| 280 | + } | ||
| 281 | + | ||
| 282 | + gltfMesh.indices = uint32_t(primitive.get("indices").get<double>()); | ||
| 283 | + gltfMesh.material = uint32_t(primitive.get("material").get<double>()); | ||
| 284 | + mMeshes.emplace_back( gltfMesh ); | ||
| 285 | + } | ||
| 286 | + } | ||
| 287 | + // parse cameras | ||
| 288 | + else if( val.first == "cameras" ) | ||
| 289 | + { | ||
| 290 | + glTF_Camera tgifCamera{}; | ||
| 291 | + for( const auto& camera : val.second.get<picojson::array>() ) | ||
| 292 | + { | ||
| 293 | + tgifCamera.name = camera.get( "name" ).to_str(); | ||
| 294 | + tgifCamera.isPerspective = (camera.get( "type" ).to_str() == "perspective" ); | ||
| 295 | + if(tgifCamera.isPerspective) | ||
| 296 | + { | ||
| 297 | + const auto& perspective = camera.get( "perspective" ); | ||
| 298 | + tgifCamera.yfov = static_cast<float>(perspective.get( "yfov" ).get<double>()); | ||
| 299 | + tgifCamera.zfar = static_cast<float>(perspective.get( "zfar" ).get<double>()); | ||
| 300 | + tgifCamera.znear = static_cast<float>(perspective.get( "znear" ).get<double>()); | ||
| 301 | + } | ||
| 302 | + | ||
| 303 | + mCameras.emplace_back( tgifCamera ); | ||
| 304 | + } | ||
| 305 | + } | ||
| 306 | + // parse nodes | ||
| 307 | + else if( val.first == "nodes" ) | ||
| 308 | + { | ||
| 309 | + auto nodeIndex = 1u; | ||
| 310 | + for( const auto& node : val.second.get<picojson::array>() ) | ||
| 311 | + { | ||
| 312 | + glTF_Node gltfNode{}; | ||
| 313 | + gltfNode.name = node.get( "name" ).to_str(); | ||
| 314 | + auto rotation = JsonGetArray<double, float>( node, "rotation", {0.0f, 0.0f, 0.0f, 1.0f} ); | ||
| 315 | + auto translation = JsonGetArray<double, float>( node, "translation", {0.0f, 0.0f, 0.0f} ); | ||
| 316 | + auto scale = JsonGetArray<double, float>( node, "scale", {1.0f, 1.0f, 1.0f} ); | ||
| 317 | + std::copy( rotation.result.begin(), rotation.result.end(), gltfNode.rotationQuaternion ); | ||
| 318 | + std::copy( translation.result.begin(), translation.result.end(), gltfNode.translation ); | ||
| 319 | + std::copy( scale.result.begin(), scale.result.end(), gltfNode.scale ); | ||
| 320 | + | ||
| 321 | + auto children = JsonGetArray<double, uint32_t>( node, "children" ); | ||
| 322 | + if(children.success) | ||
| 323 | + { | ||
| 324 | + gltfNode.children = std::move(children.result); | ||
| 325 | + } | ||
| 326 | + gltfNode.index = nodeIndex; | ||
| 327 | + gltfNode.cameraId = 0xffffffff; | ||
| 328 | + gltfNode.meshId = 0xffffffff; | ||
| 329 | + | ||
| 330 | + auto cameraId = JsonGetValue<double, uint32_t>( node, "camera", 0xffffffff ); | ||
| 331 | + if( cameraId.success ) | ||
| 332 | + { | ||
| 333 | + gltfNode.cameraId = cameraId.result; | ||
| 334 | + } | ||
| 335 | + auto meshId = JsonGetValue<double, uint32_t>( node, "mesh", 0xffffffff ); | ||
| 336 | + if( meshId.success ) | ||
| 337 | + { | ||
| 338 | + gltfNode.meshId = meshId.result; | ||
| 339 | + } | ||
| 340 | + mNodes.emplace_back( gltfNode ); | ||
| 341 | + ++nodeIndex; | ||
| 342 | + } | ||
| 343 | + | ||
| 344 | + } | ||
| 345 | + // parse scenes, note: only first scene is being parsed | ||
| 346 | + else if( val.first == "scenes" ) | ||
| 347 | + { | ||
| 348 | + auto& sceneNode = mNodes[0]; | ||
| 349 | + const auto& scene = val.second.get<picojson::array>()[0]; | ||
| 350 | + sceneNode.name = JsonGetValue<std::string>( scene, "name", std::string() ); | ||
| 351 | + auto result = JsonGetArray<double, uint32_t>( scene, "nodes" ); | ||
| 352 | + sceneNode.children = result.result; | ||
| 353 | + sceneNode.index = 0; | ||
| 354 | + } | ||
| 355 | + else if( val.first == "materials" ) | ||
| 356 | + { | ||
| 357 | + for( const auto& node : val.second.get<picojson::array>() ) | ||
| 358 | + { | ||
| 359 | + // Get pbr material, base color texture | ||
| 360 | + glTF_Material material{}; | ||
| 361 | + material.doubleSided = JsonGetValue<bool>( node, "doubleSided", false ).result; | ||
| 362 | + material.name = JsonGetValue<std::string>( node, "name", std::string() ).result; | ||
| 363 | + if( node.contains("pbrMetallicRoughness") ) | ||
| 364 | + { | ||
| 365 | + const auto& node0 = node.get("pbrMetallicRoughness"); | ||
| 366 | + if(node0.contains("baseColorTexture")) | ||
| 367 | + { | ||
| 368 | + const auto& node1 = node0.get("baseColorTexture"); | ||
| 369 | + auto index = uint32_t(node1.get("index").get<double>()); | ||
| 370 | + auto texCoord = uint32_t(node1.get("texCoord").get<double>()); | ||
| 371 | + material.pbrMetallicRoughness.enabled = true; | ||
| 372 | + material.pbrMetallicRoughness.baseTextureColor.index = index; | ||
| 373 | + material.pbrMetallicRoughness.baseTextureColor.texCoord = texCoord; | ||
| 374 | + } | ||
| 375 | + } | ||
| 376 | + mMaterials.emplace_back( material ); | ||
| 377 | + } | ||
| 378 | + } | ||
| 379 | + else if( val.first == "textures" ) | ||
| 380 | + { | ||
| 381 | + for(const auto& item : val.second.get<picojson::array>() ) | ||
| 382 | + { | ||
| 383 | + auto source = JsonGetValue<double, uint32_t>( item, "source", 0xffffffff ); | ||
| 384 | + textureSources.emplace_back( source.result ); | ||
| 385 | + } | ||
| 386 | + } | ||
| 387 | + else if( val.first == "images" ) | ||
| 388 | + { | ||
| 389 | + for(const auto& item : val.second.get<picojson::array>() ) | ||
| 390 | + { | ||
| 391 | + glTF_Texture tex{}; | ||
| 392 | + JsonGetValueOut<std::string>( item, "name", tex.name ); | ||
| 393 | + JsonGetValueOut<std::string>( item, "uri", tex.uri ); | ||
| 394 | + images.emplace_back( tex ); | ||
| 395 | + } | ||
| 396 | + } | ||
| 397 | + } | ||
| 398 | + | ||
| 399 | + // Resolve cross-referencing | ||
| 400 | + for( const auto& source : textureSources ) | ||
| 401 | + { | ||
| 402 | + mTextures.emplace_back( images[source] ); | ||
| 403 | + } | ||
| 404 | + | ||
| 405 | + return true; | ||
| 406 | +} | ||
| 407 | + | ||
| 408 | +glTF_Buffer glTF::LoadFile( const std::string& filename ) | ||
| 409 | +{ | ||
| 410 | + Dali::FileStream fileStream( filename.c_str(), Dali::FileStream::READ | Dali::FileStream::BINARY ); | ||
| 411 | + FILE* fin = fileStream.GetFile(); | ||
| 412 | + std::vector<unsigned char> buffer; | ||
| 413 | + if( fin ) | ||
| 414 | + { | ||
| 415 | + fseek( fin, 0, SEEK_END ); | ||
| 416 | + auto size = ftell(fin); | ||
| 417 | + fseek( fin, 0, SEEK_SET ); | ||
| 418 | + buffer.resize(unsigned(size)); | ||
| 419 | + auto result = fread( buffer.data(), 1, size_t(size), fin ); | ||
| 420 | + if( result < 0 ) | ||
| 421 | + { | ||
| 422 | + GLTF_LOG("LoadFile: Result: %d", int(result)); | ||
| 423 | + // return empty buffer | ||
| 424 | + return {}; | ||
| 425 | + } | ||
| 426 | + } | ||
| 427 | + else | ||
| 428 | + { | ||
| 429 | + GLTF_LOG("LoadFile: Can't open file: errno = %d", errno); | ||
| 430 | + } | ||
| 431 | + | ||
| 432 | + return buffer; | ||
| 433 | +} | ||
| 434 | + | ||
| 435 | +std::vector<const glTF_Mesh*> glTF::GetMeshes() const | ||
| 436 | +{ | ||
| 437 | + std::vector<const glTF_Mesh*> retval; | ||
| 438 | + for( auto& mesh : mMeshes ) | ||
| 439 | + { | ||
| 440 | + retval.emplace_back( &mesh ); | ||
| 441 | + } | ||
| 442 | + return retval; | ||
| 443 | +} | ||
| 444 | + | ||
| 445 | +std::vector<const glTF_Camera*> glTF::GetCameras() | ||
| 446 | +{ | ||
| 447 | + std::vector<const glTF_Camera*> cameras; | ||
| 448 | + for( const auto& cam : mCameras ) | ||
| 449 | + { | ||
| 450 | + cameras.emplace_back( &cam ); | ||
| 451 | + } | ||
| 452 | + return cameras; | ||
| 453 | +} | ||
| 454 | + | ||
| 455 | +std::vector<unsigned char> glTF::GetMeshAttributeBuffer( const glTF_Mesh& mesh, const std::vector<glTFAttributeType>& attrTypes ) | ||
| 456 | +{ | ||
| 457 | + // find buffer views | ||
| 458 | + struct Data | ||
| 459 | + { | ||
| 460 | + uint32_t accessorIndex{0u}; | ||
| 461 | + uint32_t byteStride{0u}; | ||
| 462 | + char* srcPtr{ nullptr }; | ||
| 463 | + }; | ||
| 464 | + std::vector<Data> data{}; | ||
| 465 | + for( const auto& attrType : attrTypes ) | ||
| 466 | + { | ||
| 467 | + std::find_if( mesh.attributes.begin(), mesh.attributes.end(), [&data, &attrType]( const std::pair<glTFAttributeType, uint32_t>& item ){ | ||
| 468 | + if( item.first == attrType ) | ||
| 469 | + { | ||
| 470 | + data.emplace_back(); | ||
| 471 | + data.back().accessorIndex = item.second; | ||
| 472 | + } | ||
| 473 | + return false; | ||
| 474 | + }); | ||
| 475 | + } | ||
| 476 | + | ||
| 477 | + if(data.empty()) | ||
| 478 | + { | ||
| 479 | + return {}; | ||
| 480 | + } | ||
| 481 | + | ||
| 482 | + // number of attributes is same for the whole mesh so using very first | ||
| 483 | + // accessor | ||
| 484 | + | ||
| 485 | + glTF_Buffer retval{}; | ||
| 486 | + | ||
| 487 | + // data is interleaved | ||
| 488 | + if( data.size() > 1 ) | ||
| 489 | + { | ||
| 490 | + auto attributeCount = mAccessors[data[0].accessorIndex].count;// / mAccessors[data[0].accessorIndex].componentSize; | ||
| 491 | + uint32_t attributeStride = 0; | ||
| 492 | + // now find buffer view stride for particular accessor | ||
| 493 | + for( auto& item : data ) | ||
| 494 | + { | ||
| 495 | + auto& accessor = mAccessors[item.accessorIndex]; | ||
| 496 | + | ||
| 497 | + // Update byte stride for this buffer view | ||
| 498 | + auto& bufferView = mBufferViews[accessor.bufferView]; | ||
| 499 | + item.byteStride = bufferView.byteLength / attributeCount; | ||
| 500 | + attributeStride += item.byteStride; | ||
| 501 | + item.srcPtr = reinterpret_cast<char*>(mBuffer.data()) + bufferView.byteOffset; | ||
| 502 | + } | ||
| 503 | + | ||
| 504 | + // now allocate final buffer and interleave data | ||
| 505 | + retval.resize( attributeStride * attributeCount ); | ||
| 506 | + auto* dstPtr = retval.data(); | ||
| 507 | + for( auto i = 0u; i < attributeCount; ++i ) | ||
| 508 | + { | ||
| 509 | + for(auto& item : data ) | ||
| 510 | + { | ||
| 511 | + std::copy( item.srcPtr, | ||
| 512 | + item.srcPtr + item.byteStride, | ||
| 513 | + reinterpret_cast<char*>(dstPtr) ); | ||
| 514 | + dstPtr += item.byteStride; | ||
| 515 | + item.srcPtr += item.byteStride; | ||
| 516 | + } | ||
| 517 | + } | ||
| 518 | + } | ||
| 519 | + else // copy data directly as single buffer | ||
| 520 | + { | ||
| 521 | + auto& bufferView = mBufferViews[mAccessors[data[0].accessorIndex].bufferView]; | ||
| 522 | + retval.resize( bufferView.byteLength ); | ||
| 523 | + std::copy( mBuffer.begin() + bufferView.byteOffset, | ||
| 524 | + mBuffer.begin() + bufferView.byteOffset + bufferView.byteLength, | ||
| 525 | + retval.begin()); | ||
| 526 | + | ||
| 527 | + } | ||
| 528 | + return retval; | ||
| 529 | +} | ||
| 530 | + | ||
| 531 | + | ||
| 532 | +const glTF_Mesh* glTF::FindMeshByName( const std::string& name ) const | ||
| 533 | +{ | ||
| 534 | + for( const auto& mesh : mMeshes ) | ||
| 535 | + { | ||
| 536 | + if(mesh.name == name) | ||
| 537 | + return &mesh; | ||
| 538 | + } | ||
| 539 | + return nullptr; | ||
| 540 | +} | ||
| 541 | + | ||
| 542 | +uint32_t glTF::GetMeshAttributeCount( const glTF_Mesh* mesh ) const | ||
| 543 | +{ | ||
| 544 | + const auto& accessor = mAccessors[mesh->attributes[0].second]; | ||
| 545 | + return accessor.count;// / accessor.componentSize; | ||
| 546 | +} | ||
| 547 | + | ||
| 548 | +std::vector<uint16_t> glTF::GetMeshIndexBuffer( const glTF_Mesh* mesh ) const | ||
| 549 | +{ | ||
| 550 | + // check GL component type | ||
| 551 | + const auto& accessor = mAccessors[mesh->indices]; | ||
| 552 | + if( accessor.componentType == 0x1403 ) // GL_UNSIGNED_SHORT | ||
| 553 | + { | ||
| 554 | + std::vector<uint16_t> retval{}; | ||
| 555 | + retval.resize( accessor.count ); | ||
| 556 | + const auto& bufferView = mBufferViews[accessor.bufferView]; | ||
| 557 | + const auto* srcPtr = reinterpret_cast<const uint16_t*> | ||
| 558 | + (reinterpret_cast<const char*>(mBuffer.data()) + bufferView.byteOffset); | ||
| 559 | + std::copy( srcPtr, srcPtr + accessor.count, retval.data() ); | ||
| 560 | + return retval; | ||
| 561 | + } | ||
| 562 | + return {}; | ||
| 563 | +} | ||
| 564 | + | ||
| 565 | +const glTF_Node* glTF::FindNodeByName( const std::string& name ) const | ||
| 566 | +{ | ||
| 567 | + auto iter = std::find_if( mNodes.begin(), mNodes.end(), [name]( const glTF_Node& node ) | ||
| 568 | + { | ||
| 569 | + return !name.compare( node.name ); | ||
| 570 | + }); | ||
| 571 | + | ||
| 572 | + if(iter == mNodes.end()) | ||
| 573 | + { | ||
| 574 | + return nullptr; | ||
| 575 | + } | ||
| 576 | + | ||
| 577 | + return &*iter; | ||
| 578 | +} | ||
| 579 | + | ||
| 580 | +const std::vector<glTF_Material>& glTF::GetMaterials() const | ||
| 581 | +{ | ||
| 582 | + return mMaterials; | ||
| 583 | +} | ||
| 584 | + | ||
| 585 | +const std::vector<glTF_Texture>& glTF::GetTextures() const | ||
| 586 | +{ | ||
| 587 | + return mTextures; | ||
| 588 | +} |
examples/reflection-demo/gltf-scene.h
0 → 100644
| 1 | +/* | ||
| 2 | + * Copyright (c) 2020 Samsung Electronics Co., Ltd. | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + * | ||
| 16 | + */ | ||
| 17 | + | ||
| 18 | +#ifndef GLTF_SCENE_H | ||
| 19 | +#define GLTF_SCENE_H | ||
| 20 | + | ||
| 21 | +#include <dali/integration-api/debug.h> | ||
| 22 | + | ||
| 23 | +#include <string> | ||
| 24 | + | ||
| 25 | +#include "pico-json.h" | ||
| 26 | + | ||
| 27 | +#define GLTF_LOG(...) {DALI_LOG_ERROR( __VA_ARGS__ );} | ||
| 28 | + | ||
| 29 | +enum class glTFAttributeType | ||
| 30 | +{ | ||
| 31 | + POSITION = 0, | ||
| 32 | + NORMAL = 1, | ||
| 33 | + TEXCOORD_0 = 2, | ||
| 34 | + UNDEFINED, | ||
| 35 | +}; | ||
| 36 | + | ||
| 37 | +struct glTF_Camera | ||
| 38 | +{ | ||
| 39 | + std::string name; | ||
| 40 | + | ||
| 41 | + // perspective setup | ||
| 42 | + float yfov; | ||
| 43 | + float zfar; | ||
| 44 | + float znear; | ||
| 45 | + | ||
| 46 | + bool isPerspective; | ||
| 47 | +}; | ||
| 48 | + | ||
| 49 | +struct glTF_BufferView | ||
| 50 | +{ | ||
| 51 | + uint32_t bufferIndex; | ||
| 52 | + uint32_t byteLength; | ||
| 53 | + uint32_t byteOffset; | ||
| 54 | + void* data; | ||
| 55 | +}; | ||
| 56 | + | ||
| 57 | +struct glTF_Accessor | ||
| 58 | +{ | ||
| 59 | + uint32_t bufferView; | ||
| 60 | + uint32_t componentType; | ||
| 61 | + uint32_t count; | ||
| 62 | + uint32_t componentSize; | ||
| 63 | + std::string type; | ||
| 64 | +}; | ||
| 65 | + | ||
| 66 | +struct glTF_Mesh | ||
| 67 | +{ | ||
| 68 | + std::string name; | ||
| 69 | + std::vector<std::pair<glTFAttributeType, uint32_t>> attributes; | ||
| 70 | + uint32_t indices; | ||
| 71 | + uint32_t material; | ||
| 72 | +}; | ||
| 73 | + | ||
| 74 | +struct glTF_Texture | ||
| 75 | +{ | ||
| 76 | + std::string uri; | ||
| 77 | + std::string name; | ||
| 78 | +}; | ||
| 79 | + | ||
| 80 | +struct glTF_Material | ||
| 81 | +{ | ||
| 82 | + bool doubleSided; | ||
| 83 | + std::string name; | ||
| 84 | + struct pbrMetallicRoughness | ||
| 85 | + { | ||
| 86 | + bool enabled {false}; | ||
| 87 | + struct baseTextureColor | ||
| 88 | + { | ||
| 89 | + uint32_t index; | ||
| 90 | + uint32_t texCoord; | ||
| 91 | + } baseTextureColor; | ||
| 92 | + } pbrMetallicRoughness; | ||
| 93 | +}; | ||
| 94 | + | ||
| 95 | +struct glTF_Node | ||
| 96 | +{ | ||
| 97 | + uint32_t index{0u}; | ||
| 98 | + std::string name{}; | ||
| 99 | + uint32_t meshId { 0xffffffff }; | ||
| 100 | + uint32_t cameraId{ 0xffffffff }; | ||
| 101 | + glTF_Node* parent { nullptr }; | ||
| 102 | + std::vector<uint32_t> children {}; | ||
| 103 | + | ||
| 104 | + // Transform | ||
| 105 | + float rotationQuaternion[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; | ||
| 106 | + float translation[3] = { 0.0f, 0.0f, 0.0f }; | ||
| 107 | + float scale[3] = { 1.0f, 1.0f, 1.0f }; | ||
| 108 | +}; | ||
| 109 | + | ||
| 110 | +using glTF_Buffer = std::vector<unsigned char>; | ||
| 111 | + | ||
| 112 | +/** | ||
| 113 | + * Simple glTF parser | ||
| 114 | + * | ||
| 115 | + * This implementation requires 2 files (it doesn't decode Base64 embedded in json) | ||
| 116 | + */ | ||
| 117 | +struct glTF | ||
| 118 | +{ | ||
| 119 | + | ||
| 120 | + glTF( const std::string& filename ); | ||
| 121 | + ~glTF() = default; | ||
| 122 | + | ||
| 123 | + std::vector<const glTF_Mesh*> GetMeshes() const; | ||
| 124 | + | ||
| 125 | + std::vector<const glTF_Camera*> GetCameras(); | ||
| 126 | + | ||
| 127 | + const std::vector<glTF_Material>& GetMaterials() const; | ||
| 128 | + | ||
| 129 | + const std::vector<glTF_Texture>& GetTextures() const; | ||
| 130 | + | ||
| 131 | + const std::vector<glTF_Node>& GetNodes() const | ||
| 132 | + { | ||
| 133 | + return mNodes; | ||
| 134 | + } | ||
| 135 | + | ||
| 136 | + /** | ||
| 137 | + * MESH interface | ||
| 138 | + */ | ||
| 139 | + /** | ||
| 140 | + * Returns a copy of attribute buffer | ||
| 141 | + * @return | ||
| 142 | + */ | ||
| 143 | + std::vector<unsigned char> GetMeshAttributeBuffer( const glTF_Mesh& mesh, const std::vector<glTFAttributeType>& attrTypes ); | ||
| 144 | + uint32_t GetMeshAttributeCount( const glTF_Mesh* mesh ) const; | ||
| 145 | + const glTF_Mesh* FindMeshByName( const std::string& name ) const; | ||
| 146 | + | ||
| 147 | + /** | ||
| 148 | + * Returns a copy of index buffer | ||
| 149 | + * @return | ||
| 150 | + */ | ||
| 151 | + std::vector<uint16_t> GetMeshIndexBuffer( const glTF_Mesh* mesh ) const; | ||
| 152 | + | ||
| 153 | + const glTF_Node* FindNodeByName( const std::string& name ) const; | ||
| 154 | + | ||
| 155 | +private: | ||
| 156 | + | ||
| 157 | + void LoadFromFile( const std::string& filename ); | ||
| 158 | + | ||
| 159 | + glTF_Buffer LoadFile( const std::string& filename ); | ||
| 160 | + | ||
| 161 | + bool ParseJSON(); | ||
| 162 | + | ||
| 163 | + std::vector<glTF_Mesh> mMeshes; | ||
| 164 | + std::vector<glTF_Camera> mCameras; | ||
| 165 | + std::vector<glTF_BufferView> mBufferViews; | ||
| 166 | + std::vector<glTF_Accessor> mAccessors; | ||
| 167 | + std::vector<glTF_Node> mNodes; | ||
| 168 | + std::vector<glTF_Material> mMaterials; | ||
| 169 | + std::vector<glTF_Texture> mTextures; | ||
| 170 | + glTF_Buffer mBuffer; | ||
| 171 | + glTF_Buffer jsonBuffer; | ||
| 172 | + | ||
| 173 | + // json nodes | ||
| 174 | + picojson::value jsonNode; | ||
| 175 | +}; | ||
| 176 | + | ||
| 177 | + | ||
| 178 | +#endif //DALI_CMAKE_GLTF_SCENE_H |
examples/reflection-demo/pico-json.h
0 → 100644
| 1 | +/* | ||
| 2 | + * Copyright 2009-2010 Cybozu Labs, Inc. | ||
| 3 | + * Copyright 2011-2014 Kazuho Oku | ||
| 4 | + * All rights reserved. | ||
| 5 | + * | ||
| 6 | + * Redistribution and use in source and binary forms, with or without | ||
| 7 | + * modification, are permitted provided that the following conditions are met: | ||
| 8 | + * | ||
| 9 | + * 1. Redistributions of source code must retain the above copyright notice, | ||
| 10 | + * this list of conditions and the following disclaimer. | ||
| 11 | + * | ||
| 12 | + * 2. Redistributions in binary form must reproduce the above copyright notice, | ||
| 13 | + * this list of conditions and the following disclaimer in the documentation | ||
| 14 | + * and/or other materials provided with the distribution. | ||
| 15 | + * | ||
| 16 | + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
| 17 | + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 18 | + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 19 | + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | ||
| 20 | + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
| 21 | + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
| 22 | + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
| 23 | + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
| 24 | + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
| 25 | + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 26 | + * POSSIBILITY OF SUCH DAMAGE. | ||
| 27 | + */ | ||
| 28 | +#ifndef picojson_h | ||
| 29 | +#define picojson_h | ||
| 30 | + | ||
| 31 | +#include <algorithm> | ||
| 32 | +#include <cstdio> | ||
| 33 | +#include <cstdlib> | ||
| 34 | +#include <cstring> | ||
| 35 | +#include <cstddef> | ||
| 36 | +#include <iostream> | ||
| 37 | +#include <iterator> | ||
| 38 | +#include <limits> | ||
| 39 | +#include <map> | ||
| 40 | +#include <stdexcept> | ||
| 41 | +#include <string> | ||
| 42 | +#include <vector> | ||
| 43 | +#include <utility> | ||
| 44 | + | ||
| 45 | +// for isnan/isinf | ||
| 46 | +#if __cplusplus>=201103L | ||
| 47 | +# include <cmath> | ||
| 48 | +#else | ||
| 49 | +extern "C" { | ||
| 50 | +# ifdef _MSC_VER | ||
| 51 | +# include <float.h> | ||
| 52 | +# elif defined(__INTEL_COMPILER) | ||
| 53 | +# include <mathimf.h> | ||
| 54 | +# else | ||
| 55 | +# include <math.h> | ||
| 56 | +# endif | ||
| 57 | +} | ||
| 58 | +#endif | ||
| 59 | + | ||
| 60 | +#ifndef PICOJSON_USE_RVALUE_REFERENCE | ||
| 61 | +# if (defined(__cpp_rvalue_references) && __cpp_rvalue_references >= 200610) || (defined(_MSC_VER) && _MSC_VER >= 1600) | ||
| 62 | +# define PICOJSON_USE_RVALUE_REFERENCE 1 | ||
| 63 | +# else | ||
| 64 | +# define PICOJSON_USE_RVALUE_REFERENCE 0 | ||
| 65 | +# endif | ||
| 66 | +#endif//PICOJSON_USE_RVALUE_REFERENCE | ||
| 67 | + | ||
| 68 | + | ||
| 69 | +// experimental support for int64_t (see README.mkdn for detail) | ||
| 70 | +#ifdef PICOJSON_USE_INT64 | ||
| 71 | +# define __STDC_FORMAT_MACROS | ||
| 72 | +# include <errno.h> | ||
| 73 | +# include <inttypes.h> | ||
| 74 | +#endif | ||
| 75 | + | ||
| 76 | +// to disable the use of localeconv(3), set PICOJSON_USE_LOCALE to 0 | ||
| 77 | +#ifndef PICOJSON_USE_LOCALE | ||
| 78 | +# define PICOJSON_USE_LOCALE 1 | ||
| 79 | +#endif | ||
| 80 | +#if PICOJSON_USE_LOCALE | ||
| 81 | +extern "C" { | ||
| 82 | +# include <locale.h> | ||
| 83 | +} | ||
| 84 | +#endif | ||
| 85 | + | ||
| 86 | +#ifndef PICOJSON_ASSERT | ||
| 87 | +# define PICOJSON_ASSERT(e) do { if (! (e)) throw std::runtime_error(#e); } while (0) | ||
| 88 | +#endif | ||
| 89 | + | ||
| 90 | +#ifdef _MSC_VER | ||
| 91 | +#define SNPRINTF _snprintf_s | ||
| 92 | + #pragma warning(push) | ||
| 93 | + #pragma warning(disable : 4244) // conversion from int to char | ||
| 94 | + #pragma warning(disable : 4127) // conditional expression is constant | ||
| 95 | + #pragma warning(disable : 4702) // unreachable code | ||
| 96 | +#else | ||
| 97 | +#define SNPRINTF snprintf | ||
| 98 | +#endif | ||
| 99 | + | ||
| 100 | +namespace picojson { | ||
| 101 | + | ||
| 102 | +enum { | ||
| 103 | + null_type, | ||
| 104 | + boolean_type, | ||
| 105 | + number_type, | ||
| 106 | + string_type, | ||
| 107 | + array_type, | ||
| 108 | + object_type | ||
| 109 | +#ifdef PICOJSON_USE_INT64 | ||
| 110 | + , int64_type | ||
| 111 | +#endif | ||
| 112 | +}; | ||
| 113 | + | ||
| 114 | +enum { | ||
| 115 | + INDENT_WIDTH = 2 | ||
| 116 | +}; | ||
| 117 | + | ||
| 118 | +struct null {}; | ||
| 119 | + | ||
| 120 | +class value { | ||
| 121 | +public: | ||
| 122 | + typedef std::vector<value> array; | ||
| 123 | + typedef std::map<std::string, value> object; | ||
| 124 | + union _storage { | ||
| 125 | + bool boolean_; | ||
| 126 | + double number_; | ||
| 127 | +#ifdef PICOJSON_USE_INT64 | ||
| 128 | + int64_t int64_; | ||
| 129 | +#endif | ||
| 130 | + std::string* string_; | ||
| 131 | + array* array_; | ||
| 132 | + object* object_; | ||
| 133 | + }; | ||
| 134 | +protected: | ||
| 135 | + int type_; | ||
| 136 | + _storage u_; | ||
| 137 | +public: | ||
| 138 | + value(); | ||
| 139 | + value(int type, bool); | ||
| 140 | + explicit value(bool b); | ||
| 141 | +#ifdef PICOJSON_USE_INT64 | ||
| 142 | + explicit value(int64_t i); | ||
| 143 | +#endif | ||
| 144 | + explicit value(double n); | ||
| 145 | + explicit value(const std::string& s); | ||
| 146 | + explicit value(const array& a); | ||
| 147 | + explicit value(const object& o); | ||
| 148 | + explicit value(const char* s); | ||
| 149 | + value(const char* s, size_t len); | ||
| 150 | + ~value(); | ||
| 151 | + value(const value& x); | ||
| 152 | + value& operator=(const value& x); | ||
| 153 | +#if PICOJSON_USE_RVALUE_REFERENCE | ||
| 154 | + value(value&& x)throw(); | ||
| 155 | + value& operator=(value&& x)throw(); | ||
| 156 | +#endif | ||
| 157 | + void swap(value& x)throw(); | ||
| 158 | + template <typename T> bool is() const; | ||
| 159 | + template <typename T> const T& get() const; | ||
| 160 | + template <typename T> T& get(); | ||
| 161 | + template <typename T> void set(const T &); | ||
| 162 | +#if PICOJSON_USE_RVALUE_REFERENCE | ||
| 163 | + template <typename T> void set(T &&); | ||
| 164 | +#endif | ||
| 165 | + bool evaluate_as_boolean() const; | ||
| 166 | + const value& get(size_t idx) const; | ||
| 167 | + const value& get(const std::string& key) const; | ||
| 168 | + value& get(size_t idx); | ||
| 169 | + value& get(const std::string& key); | ||
| 170 | + | ||
| 171 | + bool contains(size_t idx) const; | ||
| 172 | + bool contains(const std::string& key) const; | ||
| 173 | + std::string to_str() const; | ||
| 174 | + template <typename Iter> void serialize(Iter os, bool prettify = false) const; | ||
| 175 | + std::string serialize(bool prettify = false) const; | ||
| 176 | +private: | ||
| 177 | + template <typename T> value(const T*); // intentionally defined to block implicit conversion of pointer to bool | ||
| 178 | + template <typename Iter> static void _indent(Iter os, int indent); | ||
| 179 | + template <typename Iter> void _serialize(Iter os, int indent) const; | ||
| 180 | + std::string _serialize(int indent) const; | ||
| 181 | + void clear(); | ||
| 182 | +}; | ||
| 183 | + | ||
| 184 | +typedef value::array array; | ||
| 185 | +typedef value::object object; | ||
| 186 | + | ||
| 187 | +inline value::value() : type_(null_type) {} | ||
| 188 | + | ||
| 189 | +inline value::value(int type, bool) : type_(type) { | ||
| 190 | + switch (type) { | ||
| 191 | +#define INIT(p, v) case p##type: u_.p = v; break | ||
| 192 | + INIT(boolean_, false); | ||
| 193 | + INIT(number_, 0.0); | ||
| 194 | +#ifdef PICOJSON_USE_INT64 | ||
| 195 | + INIT(int64_, 0); | ||
| 196 | +#endif | ||
| 197 | + INIT(string_, new std::string()); | ||
| 198 | + INIT(array_, new array()); | ||
| 199 | + INIT(object_, new object()); | ||
| 200 | +#undef INIT | ||
| 201 | + default: break; | ||
| 202 | + } | ||
| 203 | +} | ||
| 204 | + | ||
| 205 | +inline value::value(bool b) : type_(boolean_type) { | ||
| 206 | + u_.boolean_ = b; | ||
| 207 | +} | ||
| 208 | + | ||
| 209 | +#ifdef PICOJSON_USE_INT64 | ||
| 210 | +inline value::value(int64_t i) : type_(int64_type) { | ||
| 211 | + u_.int64_ = i; | ||
| 212 | + } | ||
| 213 | +#endif | ||
| 214 | + | ||
| 215 | +inline value::value(double n) : type_(number_type) { | ||
| 216 | + if ( | ||
| 217 | +#ifdef _MSC_VER | ||
| 218 | +! _finite(n) | ||
| 219 | +#elif __cplusplus>=201103L || !(defined(isnan) && defined(isinf)) | ||
| 220 | +std::isnan(n) || std::isinf(n) | ||
| 221 | +#else | ||
| 222 | + isnan(n) || isinf(n) | ||
| 223 | +#endif | ||
| 224 | + ) { | ||
| 225 | + throw std::overflow_error(""); | ||
| 226 | + } | ||
| 227 | + u_.number_ = n; | ||
| 228 | +} | ||
| 229 | + | ||
| 230 | +inline value::value(const std::string& s) : type_(string_type) { | ||
| 231 | + u_.string_ = new std::string(s); | ||
| 232 | +} | ||
| 233 | + | ||
| 234 | +inline value::value(const array& a) : type_(array_type) { | ||
| 235 | + u_.array_ = new array(a); | ||
| 236 | +} | ||
| 237 | + | ||
| 238 | +inline value::value(const object& o) : type_(object_type) { | ||
| 239 | + u_.object_ = new object(o); | ||
| 240 | +} | ||
| 241 | + | ||
| 242 | +inline value::value(const char* s) : type_(string_type) { | ||
| 243 | + u_.string_ = new std::string(s); | ||
| 244 | +} | ||
| 245 | + | ||
| 246 | +inline value::value(const char* s, size_t len) : type_(string_type) { | ||
| 247 | + u_.string_ = new std::string(s, len); | ||
| 248 | +} | ||
| 249 | + | ||
| 250 | +inline void value::clear() { | ||
| 251 | + switch (type_) { | ||
| 252 | +#define DEINIT(p) case p##type: delete u_.p; break | ||
| 253 | + DEINIT(string_); | ||
| 254 | + DEINIT(array_); | ||
| 255 | + DEINIT(object_); | ||
| 256 | +#undef DEINIT | ||
| 257 | + default: break; | ||
| 258 | + } | ||
| 259 | +} | ||
| 260 | + | ||
| 261 | +inline value::~value() { | ||
| 262 | + clear(); | ||
| 263 | +} | ||
| 264 | + | ||
| 265 | +inline value::value(const value& x) : type_(x.type_) { | ||
| 266 | + switch (type_) { | ||
| 267 | +#define INIT(p, v) case p##type: u_.p = v; break | ||
| 268 | + INIT(string_, new std::string(*x.u_.string_)); | ||
| 269 | + INIT(array_, new array(*x.u_.array_)); | ||
| 270 | + INIT(object_, new object(*x.u_.object_)); | ||
| 271 | +#undef INIT | ||
| 272 | + default: | ||
| 273 | + u_ = x.u_; | ||
| 274 | + break; | ||
| 275 | + } | ||
| 276 | +} | ||
| 277 | + | ||
| 278 | +inline value& value::operator=(const value& x) { | ||
| 279 | + if (this != &x) { | ||
| 280 | + value t(x); | ||
| 281 | + swap(t); | ||
| 282 | + } | ||
| 283 | + return *this; | ||
| 284 | +} | ||
| 285 | + | ||
| 286 | +#if PICOJSON_USE_RVALUE_REFERENCE | ||
| 287 | +inline value::value(value&& x)throw() : type_(null_type) { | ||
| 288 | + swap(x); | ||
| 289 | +} | ||
| 290 | +inline value& value::operator=(value&& x)throw() { | ||
| 291 | + swap(x); | ||
| 292 | + return *this; | ||
| 293 | +} | ||
| 294 | +#endif | ||
| 295 | +inline void value::swap(value& x)throw() { | ||
| 296 | + std::swap(type_, x.type_); | ||
| 297 | + std::swap(u_, x.u_); | ||
| 298 | +} | ||
| 299 | + | ||
| 300 | +#define IS(ctype, jtype) \ | ||
| 301 | + template <> inline bool value::is<ctype>() const { \ | ||
| 302 | + return type_ == jtype##_type; \ | ||
| 303 | + } | ||
| 304 | +IS(null, null) | ||
| 305 | +IS(bool, boolean) | ||
| 306 | +#ifdef PICOJSON_USE_INT64 | ||
| 307 | +IS(int64_t, int64) | ||
| 308 | +#endif | ||
| 309 | +IS(std::string, string) | ||
| 310 | +IS(array, array) | ||
| 311 | +IS(object, object) | ||
| 312 | +#undef IS | ||
| 313 | +template <> inline bool value::is<double>() const { | ||
| 314 | + return type_ == number_type | ||
| 315 | +#ifdef PICOJSON_USE_INT64 | ||
| 316 | + || type_ == int64_type | ||
| 317 | +#endif | ||
| 318 | + ; | ||
| 319 | +} | ||
| 320 | + | ||
| 321 | +#define GET(ctype, var) \ | ||
| 322 | + template <> inline const ctype& value::get<ctype>() const { \ | ||
| 323 | + PICOJSON_ASSERT("type mismatch! call is<type>() before get<type>()" \ | ||
| 324 | + && is<ctype>()); \ | ||
| 325 | + return var; \ | ||
| 326 | + } \ | ||
| 327 | + template <> inline ctype& value::get<ctype>() { \ | ||
| 328 | + PICOJSON_ASSERT("type mismatch! call is<type>() before get<type>()" \ | ||
| 329 | + && is<ctype>()); \ | ||
| 330 | + return var; \ | ||
| 331 | + } | ||
| 332 | +GET(bool, u_.boolean_) | ||
| 333 | +GET(std::string, *u_.string_) | ||
| 334 | +GET(array, *u_.array_) | ||
| 335 | +GET(object, *u_.object_) | ||
| 336 | +#ifdef PICOJSON_USE_INT64 | ||
| 337 | +GET(double, (type_ == int64_type && (const_cast<value*>(this)->type_ = number_type, const_cast<value*>(this)->u_.number_ = u_.int64_), u_.number_)) | ||
| 338 | + GET(int64_t, u_.int64_) | ||
| 339 | +#else | ||
| 340 | +GET(double, u_.number_) | ||
| 341 | +#endif | ||
| 342 | +#undef GET | ||
| 343 | + | ||
| 344 | +#define SET(ctype, jtype, setter) \ | ||
| 345 | + template <> inline void value::set<ctype>(const ctype &_val) { \ | ||
| 346 | + clear(); \ | ||
| 347 | + type_ = jtype##_type; \ | ||
| 348 | + setter \ | ||
| 349 | + } | ||
| 350 | +SET(bool, boolean, u_.boolean_ = _val;) | ||
| 351 | +SET(std::string, string, u_.string_ = new std::string(_val);) | ||
| 352 | +SET(array, array, u_.array_ = new array(_val);) | ||
| 353 | +SET(object, object, u_.object_ = new object(_val);) | ||
| 354 | +SET(double, number, u_.number_ = _val;) | ||
| 355 | +#ifdef PICOJSON_USE_INT64 | ||
| 356 | +SET(int64_t, int64, u_.int64_ = _val;) | ||
| 357 | +#endif | ||
| 358 | +#undef SET | ||
| 359 | + | ||
| 360 | +#if PICOJSON_USE_RVALUE_REFERENCE | ||
| 361 | +#define MOVESET(ctype, jtype, setter) \ | ||
| 362 | + template <> inline void value::set<ctype>(ctype &&_val) { \ | ||
| 363 | + clear(); \ | ||
| 364 | + type_ = jtype##_type; \ | ||
| 365 | + setter \ | ||
| 366 | + } | ||
| 367 | +MOVESET(std::string, string, u_.string_ = new std::string(std::move(_val));) | ||
| 368 | +MOVESET(array, array, u_.array_ = new array(std::move(_val));) | ||
| 369 | +MOVESET(object, object, u_.object_ = new object(std::move(_val));) | ||
| 370 | +#undef MOVESET | ||
| 371 | +#endif | ||
| 372 | + | ||
| 373 | +inline bool value::evaluate_as_boolean() const { | ||
| 374 | + switch (type_) { | ||
| 375 | + case null_type: | ||
| 376 | + return false; | ||
| 377 | + case boolean_type: | ||
| 378 | + return u_.boolean_; | ||
| 379 | + case number_type: | ||
| 380 | + return u_.number_ != 0; | ||
| 381 | +#ifdef PICOJSON_USE_INT64 | ||
| 382 | + case int64_type: | ||
| 383 | + return u_.int64_ != 0; | ||
| 384 | +#endif | ||
| 385 | + case string_type: | ||
| 386 | + return ! u_.string_->empty(); | ||
| 387 | + default: | ||
| 388 | + return true; | ||
| 389 | + } | ||
| 390 | +} | ||
| 391 | + | ||
| 392 | +inline const value& value::get(size_t idx) const { | ||
| 393 | + static value s_null; | ||
| 394 | + PICOJSON_ASSERT(is<array>()); | ||
| 395 | + return idx < u_.array_->size() ? (*u_.array_)[idx] : s_null; | ||
| 396 | +} | ||
| 397 | + | ||
| 398 | +inline value& value::get(size_t idx) { | ||
| 399 | + static value s_null; | ||
| 400 | + PICOJSON_ASSERT(is<array>()); | ||
| 401 | + return idx < u_.array_->size() ? (*u_.array_)[idx] : s_null; | ||
| 402 | +} | ||
| 403 | + | ||
| 404 | +inline const value& value::get(const std::string& key) const { | ||
| 405 | + static value s_null; | ||
| 406 | + PICOJSON_ASSERT(is<object>()); | ||
| 407 | + object::const_iterator i = u_.object_->find(key); | ||
| 408 | + return i != u_.object_->end() ? i->second : s_null; | ||
| 409 | +} | ||
| 410 | + | ||
| 411 | +inline value& value::get(const std::string& key) { | ||
| 412 | + static value s_null; | ||
| 413 | + PICOJSON_ASSERT(is<object>()); | ||
| 414 | + object::iterator i = u_.object_->find(key); | ||
| 415 | + return i != u_.object_->end() ? i->second : s_null; | ||
| 416 | +} | ||
| 417 | + | ||
| 418 | +inline bool value::contains(size_t idx) const { | ||
| 419 | + PICOJSON_ASSERT(is<array>()); | ||
| 420 | + return idx < u_.array_->size(); | ||
| 421 | +} | ||
| 422 | + | ||
| 423 | +inline bool value::contains(const std::string& key) const { | ||
| 424 | + PICOJSON_ASSERT(is<object>()); | ||
| 425 | + object::const_iterator i = u_.object_->find(key); | ||
| 426 | + return i != u_.object_->end(); | ||
| 427 | +} | ||
| 428 | + | ||
| 429 | +inline std::string value::to_str() const { | ||
| 430 | + switch (type_) { | ||
| 431 | + case null_type: return "null"; | ||
| 432 | + case boolean_type: return u_.boolean_ ? "true" : "false"; | ||
| 433 | +#ifdef PICOJSON_USE_INT64 | ||
| 434 | + case int64_type: { | ||
| 435 | + char buf[sizeof("-9223372036854775808")]; | ||
| 436 | + SNPRINTF(buf, sizeof(buf), "%" PRId64, u_.int64_); | ||
| 437 | + return buf; | ||
| 438 | + } | ||
| 439 | +#endif | ||
| 440 | + case number_type: { | ||
| 441 | + char buf[256]; | ||
| 442 | + double tmp; | ||
| 443 | + SNPRINTF(buf, sizeof(buf), fabs(u_.number_) < (1ULL << 53) && modf(u_.number_, &tmp) == 0 ? "%.f" : "%.17g", u_.number_); | ||
| 444 | +#if PICOJSON_USE_LOCALE | ||
| 445 | + char *decimal_point = localeconv()->decimal_point; | ||
| 446 | + if (strcmp(decimal_point, ".") != 0) { | ||
| 447 | + size_t decimal_point_len = strlen(decimal_point); | ||
| 448 | + for (char *p = buf; *p != '\0'; ++p) { | ||
| 449 | + if (strncmp(p, decimal_point, decimal_point_len) == 0) { | ||
| 450 | + return std::string(buf, p) + "." + (p + decimal_point_len); | ||
| 451 | + } | ||
| 452 | + } | ||
| 453 | + } | ||
| 454 | +#endif | ||
| 455 | + return buf; | ||
| 456 | + } | ||
| 457 | + case string_type: return *u_.string_; | ||
| 458 | + case array_type: return "array"; | ||
| 459 | + case object_type: return "object"; | ||
| 460 | + default: PICOJSON_ASSERT(0); | ||
| 461 | +#ifdef _MSC_VER | ||
| 462 | + __assume(0); | ||
| 463 | +#endif | ||
| 464 | + } | ||
| 465 | + return std::string(); | ||
| 466 | +} | ||
| 467 | + | ||
| 468 | +template <typename Iter> void copy(const std::string& s, Iter oi) { | ||
| 469 | + std::copy(s.begin(), s.end(), oi); | ||
| 470 | +} | ||
| 471 | + | ||
| 472 | +template <typename Iter> | ||
| 473 | +struct serialize_str_char { | ||
| 474 | + Iter oi; | ||
| 475 | + void operator()(char c) { | ||
| 476 | + switch (c) { | ||
| 477 | +#define MAP(val, sym) case val: copy(sym, oi); break | ||
| 478 | + MAP('"', "\\\""); | ||
| 479 | + MAP('\\', "\\\\"); | ||
| 480 | + MAP('/', "\\/"); | ||
| 481 | + MAP('\b', "\\b"); | ||
| 482 | + MAP('\f', "\\f"); | ||
| 483 | + MAP('\n', "\\n"); | ||
| 484 | + MAP('\r', "\\r"); | ||
| 485 | + MAP('\t', "\\t"); | ||
| 486 | +#undef MAP | ||
| 487 | + default: | ||
| 488 | + if (static_cast<unsigned char>(c) < 0x20 || c == 0x7f) { | ||
| 489 | + char buf[7]; | ||
| 490 | + SNPRINTF(buf, sizeof(buf), "\\u%04x", c & 0xff); | ||
| 491 | + copy(buf, buf + 6, oi); | ||
| 492 | + } else { | ||
| 493 | + *oi++ = c; | ||
| 494 | + } | ||
| 495 | + break; | ||
| 496 | + } | ||
| 497 | + } | ||
| 498 | +}; | ||
| 499 | + | ||
| 500 | +template <typename Iter> void serialize_str(const std::string& s, Iter oi) { | ||
| 501 | + *oi++ = '"'; | ||
| 502 | + serialize_str_char<Iter> process_char = { oi }; | ||
| 503 | + std::for_each(s.begin(), s.end(), process_char); | ||
| 504 | + *oi++ = '"'; | ||
| 505 | +} | ||
| 506 | + | ||
| 507 | +template <typename Iter> void value::serialize(Iter oi, bool prettify) const { | ||
| 508 | + return _serialize(oi, prettify ? 0 : -1); | ||
| 509 | +} | ||
| 510 | + | ||
| 511 | +inline std::string value::serialize(bool prettify) const { | ||
| 512 | + return _serialize(prettify ? 0 : -1); | ||
| 513 | +} | ||
| 514 | + | ||
| 515 | +template <typename Iter> void value::_indent(Iter oi, int indent) { | ||
| 516 | + *oi++ = '\n'; | ||
| 517 | + for (int i = 0; i < indent * INDENT_WIDTH; ++i) { | ||
| 518 | + *oi++ = ' '; | ||
| 519 | + } | ||
| 520 | +} | ||
| 521 | + | ||
| 522 | +template <typename Iter> void value::_serialize(Iter oi, int indent) const { | ||
| 523 | + switch (type_) { | ||
| 524 | + case string_type: | ||
| 525 | + serialize_str(*u_.string_, oi); | ||
| 526 | + break; | ||
| 527 | + case array_type: { | ||
| 528 | + *oi++ = '['; | ||
| 529 | + if (indent != -1) { | ||
| 530 | + ++indent; | ||
| 531 | + } | ||
| 532 | + for (array::const_iterator i = u_.array_->begin(); | ||
| 533 | + i != u_.array_->end(); | ||
| 534 | + ++i) { | ||
| 535 | + if (i != u_.array_->begin()) { | ||
| 536 | + *oi++ = ','; | ||
| 537 | + } | ||
| 538 | + if (indent != -1) { | ||
| 539 | + _indent(oi, indent); | ||
| 540 | + } | ||
| 541 | + i->_serialize(oi, indent); | ||
| 542 | + } | ||
| 543 | + if (indent != -1) { | ||
| 544 | + --indent; | ||
| 545 | + if (! u_.array_->empty()) { | ||
| 546 | + _indent(oi, indent); | ||
| 547 | + } | ||
| 548 | + } | ||
| 549 | + *oi++ = ']'; | ||
| 550 | + break; | ||
| 551 | + } | ||
| 552 | + case object_type: { | ||
| 553 | + *oi++ = '{'; | ||
| 554 | + if (indent != -1) { | ||
| 555 | + ++indent; | ||
| 556 | + } | ||
| 557 | + for (object::const_iterator i = u_.object_->begin(); | ||
| 558 | + i != u_.object_->end(); | ||
| 559 | + ++i) { | ||
| 560 | + if (i != u_.object_->begin()) { | ||
| 561 | + *oi++ = ','; | ||
| 562 | + } | ||
| 563 | + if (indent != -1) { | ||
| 564 | + _indent(oi, indent); | ||
| 565 | + } | ||
| 566 | + serialize_str(i->first, oi); | ||
| 567 | + *oi++ = ':'; | ||
| 568 | + if (indent != -1) { | ||
| 569 | + *oi++ = ' '; | ||
| 570 | + } | ||
| 571 | + i->second._serialize(oi, indent); | ||
| 572 | + } | ||
| 573 | + if (indent != -1) { | ||
| 574 | + --indent; | ||
| 575 | + if (! u_.object_->empty()) { | ||
| 576 | + _indent(oi, indent); | ||
| 577 | + } | ||
| 578 | + } | ||
| 579 | + *oi++ = '}'; | ||
| 580 | + break; | ||
| 581 | + } | ||
| 582 | + default: | ||
| 583 | + copy(to_str(), oi); | ||
| 584 | + break; | ||
| 585 | + } | ||
| 586 | + if (indent == 0) { | ||
| 587 | + *oi++ = '\n'; | ||
| 588 | + } | ||
| 589 | +} | ||
| 590 | + | ||
| 591 | +inline std::string value::_serialize(int indent) const { | ||
| 592 | + std::string s; | ||
| 593 | + _serialize(std::back_inserter(s), indent); | ||
| 594 | + return s; | ||
| 595 | +} | ||
| 596 | + | ||
| 597 | +template <typename Iter> class input { | ||
| 598 | +protected: | ||
| 599 | + Iter cur_, end_; | ||
| 600 | + bool consumed_; | ||
| 601 | + int line_; | ||
| 602 | +public: | ||
| 603 | + input(const Iter& first, const Iter& last) : cur_(first), end_(last), consumed_(false), line_(1) {} | ||
| 604 | + int getc() { | ||
| 605 | + if (consumed_) { | ||
| 606 | + if (*cur_ == '\n') { | ||
| 607 | + ++line_; | ||
| 608 | + } | ||
| 609 | + ++cur_; | ||
| 610 | + } | ||
| 611 | + if (cur_ == end_) { | ||
| 612 | + consumed_ = false; | ||
| 613 | + return -1; | ||
| 614 | + } | ||
| 615 | + consumed_ = true; | ||
| 616 | + return *cur_ & 0xff; | ||
| 617 | + } | ||
| 618 | + void ungetc() { | ||
| 619 | + consumed_ = false; | ||
| 620 | + } | ||
| 621 | + Iter cur() const { | ||
| 622 | + if (consumed_) { | ||
| 623 | + input<Iter> *self = const_cast<input<Iter>*>(this); | ||
| 624 | + self->consumed_ = false; | ||
| 625 | + ++self->cur_; | ||
| 626 | + } | ||
| 627 | + return cur_; | ||
| 628 | + } | ||
| 629 | + int line() const { return line_; } | ||
| 630 | + void skip_ws() { | ||
| 631 | + while (1) { | ||
| 632 | + int ch = getc(); | ||
| 633 | + if (! (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r')) { | ||
| 634 | + ungetc(); | ||
| 635 | + break; | ||
| 636 | + } | ||
| 637 | + } | ||
| 638 | + } | ||
| 639 | + bool expect(int expect) { | ||
| 640 | + skip_ws(); | ||
| 641 | + if (getc() != expect) { | ||
| 642 | + ungetc(); | ||
| 643 | + return false; | ||
| 644 | + } | ||
| 645 | + return true; | ||
| 646 | + } | ||
| 647 | + bool match(const std::string& pattern) { | ||
| 648 | + for (std::string::const_iterator pi(pattern.begin()); | ||
| 649 | + pi != pattern.end(); | ||
| 650 | + ++pi) { | ||
| 651 | + if (getc() != *pi) { | ||
| 652 | + ungetc(); | ||
| 653 | + return false; | ||
| 654 | + } | ||
| 655 | + } | ||
| 656 | + return true; | ||
| 657 | + } | ||
| 658 | +}; | ||
| 659 | + | ||
| 660 | +template<typename Iter> inline int _parse_quadhex(input<Iter> &in) { | ||
| 661 | + int uni_ch = 0, hex; | ||
| 662 | + for (int i = 0; i < 4; i++) { | ||
| 663 | + if ((hex = in.getc()) == -1) { | ||
| 664 | + return -1; | ||
| 665 | + } | ||
| 666 | + if ('0' <= hex && hex <= '9') { | ||
| 667 | + hex -= '0'; | ||
| 668 | + } else if ('A' <= hex && hex <= 'F') { | ||
| 669 | + hex -= 'A' - 0xa; | ||
| 670 | + } else if ('a' <= hex && hex <= 'f') { | ||
| 671 | + hex -= 'a' - 0xa; | ||
| 672 | + } else { | ||
| 673 | + in.ungetc(); | ||
| 674 | + return -1; | ||
| 675 | + } | ||
| 676 | + uni_ch = uni_ch * 16 + hex; | ||
| 677 | + } | ||
| 678 | + return uni_ch; | ||
| 679 | +} | ||
| 680 | + | ||
| 681 | +template<typename String, typename Iter> inline bool _parse_codepoint(String& out, input<Iter>& in) { | ||
| 682 | + int uni_ch; | ||
| 683 | + if ((uni_ch = _parse_quadhex(in)) == -1) { | ||
| 684 | + return false; | ||
| 685 | + } | ||
| 686 | + if (0xd800 <= uni_ch && uni_ch <= 0xdfff) { | ||
| 687 | + if (0xdc00 <= uni_ch) { | ||
| 688 | + // a second 16-bit of a surrogate pair appeared | ||
| 689 | + return false; | ||
| 690 | + } | ||
| 691 | + // first 16-bit of surrogate pair, get the next one | ||
| 692 | + if (in.getc() != '\\' || in.getc() != 'u') { | ||
| 693 | + in.ungetc(); | ||
| 694 | + return false; | ||
| 695 | + } | ||
| 696 | + int second = _parse_quadhex(in); | ||
| 697 | + if (! (0xdc00 <= second && second <= 0xdfff)) { | ||
| 698 | + return false; | ||
| 699 | + } | ||
| 700 | + uni_ch = ((uni_ch - 0xd800) << 10) | ((second - 0xdc00) & 0x3ff); | ||
| 701 | + uni_ch += 0x10000; | ||
| 702 | + } | ||
| 703 | + if (uni_ch < 0x80) { | ||
| 704 | + out.push_back(uni_ch); | ||
| 705 | + } else { | ||
| 706 | + if (uni_ch < 0x800) { | ||
| 707 | + out.push_back(0xc0 | (uni_ch >> 6)); | ||
| 708 | + } else { | ||
| 709 | + if (uni_ch < 0x10000) { | ||
| 710 | + out.push_back(0xe0 | (uni_ch >> 12)); | ||
| 711 | + } else { | ||
| 712 | + out.push_back(0xf0 | (uni_ch >> 18)); | ||
| 713 | + out.push_back(0x80 | ((uni_ch >> 12) & 0x3f)); | ||
| 714 | + } | ||
| 715 | + out.push_back(0x80 | ((uni_ch >> 6) & 0x3f)); | ||
| 716 | + } | ||
| 717 | + out.push_back(0x80 | (uni_ch & 0x3f)); | ||
| 718 | + } | ||
| 719 | + return true; | ||
| 720 | +} | ||
| 721 | + | ||
| 722 | +template<typename String, typename Iter> inline bool _parse_string(String& out, input<Iter>& in) { | ||
| 723 | + while (1) { | ||
| 724 | + int ch = in.getc(); | ||
| 725 | + if (ch < ' ') { | ||
| 726 | + in.ungetc(); | ||
| 727 | + return false; | ||
| 728 | + } else if (ch == '"') { | ||
| 729 | + return true; | ||
| 730 | + } else if (ch == '\\') { | ||
| 731 | + if ((ch = in.getc()) == -1) { | ||
| 732 | + return false; | ||
| 733 | + } | ||
| 734 | + switch (ch) { | ||
| 735 | +#define MAP(sym, val) case sym: out.push_back(val); break | ||
| 736 | + MAP('"', '\"'); | ||
| 737 | + MAP('\\', '\\'); | ||
| 738 | + MAP('/', '/'); | ||
| 739 | + MAP('b', '\b'); | ||
| 740 | + MAP('f', '\f'); | ||
| 741 | + MAP('n', '\n'); | ||
| 742 | + MAP('r', '\r'); | ||
| 743 | + MAP('t', '\t'); | ||
| 744 | +#undef MAP | ||
| 745 | + case 'u': | ||
| 746 | + if (! _parse_codepoint(out, in)) { | ||
| 747 | + return false; | ||
| 748 | + } | ||
| 749 | + break; | ||
| 750 | + default: | ||
| 751 | + return false; | ||
| 752 | + } | ||
| 753 | + } else { | ||
| 754 | + out.push_back(ch); | ||
| 755 | + } | ||
| 756 | + } | ||
| 757 | + return false; | ||
| 758 | +} | ||
| 759 | + | ||
| 760 | +template <typename Context, typename Iter> inline bool _parse_array(Context& ctx, input<Iter>& in) { | ||
| 761 | + if (! ctx.parse_array_start()) { | ||
| 762 | + return false; | ||
| 763 | + } | ||
| 764 | + size_t idx = 0; | ||
| 765 | + if (in.expect(']')) { | ||
| 766 | + return ctx.parse_array_stop(idx); | ||
| 767 | + } | ||
| 768 | + do { | ||
| 769 | + if (! ctx.parse_array_item(in, idx)) { | ||
| 770 | + return false; | ||
| 771 | + } | ||
| 772 | + idx++; | ||
| 773 | + } while (in.expect(',')); | ||
| 774 | + return in.expect(']') && ctx.parse_array_stop(idx); | ||
| 775 | +} | ||
| 776 | + | ||
| 777 | +template <typename Context, typename Iter> inline bool _parse_object(Context& ctx, input<Iter>& in) { | ||
| 778 | + if (! ctx.parse_object_start()) { | ||
| 779 | + return false; | ||
| 780 | + } | ||
| 781 | + if (in.expect('}')) { | ||
| 782 | + return true; | ||
| 783 | + } | ||
| 784 | + do { | ||
| 785 | + std::string key; | ||
| 786 | + if (! in.expect('"') | ||
| 787 | + || ! _parse_string(key, in) | ||
| 788 | + || ! in.expect(':')) { | ||
| 789 | + return false; | ||
| 790 | + } | ||
| 791 | + if (! ctx.parse_object_item(in, key)) { | ||
| 792 | + return false; | ||
| 793 | + } | ||
| 794 | + } while (in.expect(',')); | ||
| 795 | + return in.expect('}'); | ||
| 796 | +} | ||
| 797 | + | ||
| 798 | +template <typename Iter> inline std::string _parse_number(input<Iter>& in) { | ||
| 799 | + std::string num_str; | ||
| 800 | + while (1) { | ||
| 801 | + int ch = in.getc(); | ||
| 802 | + if (('0' <= ch && ch <= '9') || ch == '+' || ch == '-' | ||
| 803 | + || ch == 'e' || ch == 'E') { | ||
| 804 | + num_str.push_back(ch); | ||
| 805 | + } else if (ch == '.') { | ||
| 806 | +#if PICOJSON_USE_LOCALE | ||
| 807 | + num_str += localeconv()->decimal_point; | ||
| 808 | +#else | ||
| 809 | + num_str.push_back('.'); | ||
| 810 | +#endif | ||
| 811 | + } else { | ||
| 812 | + in.ungetc(); | ||
| 813 | + break; | ||
| 814 | + } | ||
| 815 | + } | ||
| 816 | + return num_str; | ||
| 817 | +} | ||
| 818 | + | ||
| 819 | +template <typename Context, typename Iter> inline bool _parse(Context& ctx, input<Iter>& in) { | ||
| 820 | + in.skip_ws(); | ||
| 821 | + int ch = in.getc(); | ||
| 822 | + switch (ch) { | ||
| 823 | +#define IS(ch, text, op) case ch: \ | ||
| 824 | + if (in.match(text) && op) { \ | ||
| 825 | + return true; \ | ||
| 826 | + } else { \ | ||
| 827 | + return false; \ | ||
| 828 | + } | ||
| 829 | + IS('n', "ull", ctx.set_null()); | ||
| 830 | + IS('f', "alse", ctx.set_bool(false)); | ||
| 831 | + IS('t', "rue", ctx.set_bool(true)); | ||
| 832 | +#undef IS | ||
| 833 | + case '"': | ||
| 834 | + return ctx.parse_string(in); | ||
| 835 | + case '[': | ||
| 836 | + return _parse_array(ctx, in); | ||
| 837 | + case '{': | ||
| 838 | + return _parse_object(ctx, in); | ||
| 839 | + default: | ||
| 840 | + if (('0' <= ch && ch <= '9') || ch == '-') { | ||
| 841 | + double f; | ||
| 842 | + char *endp; | ||
| 843 | + in.ungetc(); | ||
| 844 | + std::string num_str = _parse_number(in); | ||
| 845 | + if (num_str.empty()) { | ||
| 846 | + return false; | ||
| 847 | + } | ||
| 848 | +#ifdef PICOJSON_USE_INT64 | ||
| 849 | + { | ||
| 850 | + errno = 0; | ||
| 851 | + intmax_t ival = strtoimax(num_str.c_str(), &endp, 10); | ||
| 852 | + if (errno == 0 | ||
| 853 | + && std::numeric_limits<int64_t>::min() <= ival | ||
| 854 | + && ival <= std::numeric_limits<int64_t>::max() | ||
| 855 | + && endp == num_str.c_str() + num_str.size()) { | ||
| 856 | + ctx.set_int64(ival); | ||
| 857 | + return true; | ||
| 858 | + } | ||
| 859 | + } | ||
| 860 | +#endif | ||
| 861 | + f = strtod(num_str.c_str(), &endp); | ||
| 862 | + if (endp == num_str.c_str() + num_str.size()) { | ||
| 863 | + ctx.set_number(f); | ||
| 864 | + return true; | ||
| 865 | + } | ||
| 866 | + return false; | ||
| 867 | + } | ||
| 868 | + break; | ||
| 869 | + } | ||
| 870 | + in.ungetc(); | ||
| 871 | + return false; | ||
| 872 | +} | ||
| 873 | + | ||
| 874 | +class deny_parse_context { | ||
| 875 | +public: | ||
| 876 | + bool set_null() { return false; } | ||
| 877 | + bool set_bool(bool) { return false; } | ||
| 878 | +#ifdef PICOJSON_USE_INT64 | ||
| 879 | + bool set_int64(int64_t) { return false; } | ||
| 880 | +#endif | ||
| 881 | + bool set_number(double) { return false; } | ||
| 882 | + template <typename Iter> bool parse_string(input<Iter>&) { return false; } | ||
| 883 | + bool parse_array_start() { return false; } | ||
| 884 | + template <typename Iter> bool parse_array_item(input<Iter>&, size_t) { | ||
| 885 | + return false; | ||
| 886 | + } | ||
| 887 | + bool parse_array_stop(size_t) { return false; } | ||
| 888 | + bool parse_object_start() { return false; } | ||
| 889 | + template <typename Iter> bool parse_object_item(input<Iter>&, const std::string&) { | ||
| 890 | + return false; | ||
| 891 | + } | ||
| 892 | +}; | ||
| 893 | + | ||
| 894 | +class default_parse_context { | ||
| 895 | +protected: | ||
| 896 | + value* out_; | ||
| 897 | +public: | ||
| 898 | + default_parse_context(value* out) : out_(out) {} | ||
| 899 | + bool set_null() { | ||
| 900 | + *out_ = value(); | ||
| 901 | + return true; | ||
| 902 | + } | ||
| 903 | + bool set_bool(bool b) { | ||
| 904 | + *out_ = value(b); | ||
| 905 | + return true; | ||
| 906 | + } | ||
| 907 | +#ifdef PICOJSON_USE_INT64 | ||
| 908 | + bool set_int64(int64_t i) { | ||
| 909 | + *out_ = value(i); | ||
| 910 | + return true; | ||
| 911 | + } | ||
| 912 | +#endif | ||
| 913 | + bool set_number(double f) { | ||
| 914 | + *out_ = value(f); | ||
| 915 | + return true; | ||
| 916 | + } | ||
| 917 | + template<typename Iter> bool parse_string(input<Iter>& in) { | ||
| 918 | + *out_ = value(string_type, false); | ||
| 919 | + return _parse_string(out_->get<std::string>(), in); | ||
| 920 | + } | ||
| 921 | + bool parse_array_start() { | ||
| 922 | + *out_ = value(array_type, false); | ||
| 923 | + return true; | ||
| 924 | + } | ||
| 925 | + template <typename Iter> bool parse_array_item(input<Iter>& in, size_t) { | ||
| 926 | + array& a = out_->get<array>(); | ||
| 927 | + a.push_back(value()); | ||
| 928 | + default_parse_context ctx(&a.back()); | ||
| 929 | + return _parse(ctx, in); | ||
| 930 | + } | ||
| 931 | + bool parse_array_stop(size_t) { return true; } | ||
| 932 | + bool parse_object_start() { | ||
| 933 | + *out_ = value(object_type, false); | ||
| 934 | + return true; | ||
| 935 | + } | ||
| 936 | + template <typename Iter> bool parse_object_item(input<Iter>& in, const std::string& key) { | ||
| 937 | + object& o = out_->get<object>(); | ||
| 938 | + default_parse_context ctx(&o[key]); | ||
| 939 | + return _parse(ctx, in); | ||
| 940 | + } | ||
| 941 | +private: | ||
| 942 | + default_parse_context(const default_parse_context&); | ||
| 943 | + default_parse_context& operator=(const default_parse_context&); | ||
| 944 | +}; | ||
| 945 | + | ||
| 946 | +class null_parse_context { | ||
| 947 | +public: | ||
| 948 | + struct dummy_str { | ||
| 949 | + void push_back(int) {} | ||
| 950 | + }; | ||
| 951 | +public: | ||
| 952 | + null_parse_context() {} | ||
| 953 | + bool set_null() { return true; } | ||
| 954 | + bool set_bool(bool) { return true; } | ||
| 955 | +#ifdef PICOJSON_USE_INT64 | ||
| 956 | + bool set_int64(int64_t) { return true; } | ||
| 957 | +#endif | ||
| 958 | + bool set_number(double) { return true; } | ||
| 959 | + template <typename Iter> bool parse_string(input<Iter>& in) { | ||
| 960 | + dummy_str s; | ||
| 961 | + return _parse_string(s, in); | ||
| 962 | + } | ||
| 963 | + bool parse_array_start() { return true; } | ||
| 964 | + template <typename Iter> bool parse_array_item(input<Iter>& in, size_t) { | ||
| 965 | + return _parse(*this, in); | ||
| 966 | + } | ||
| 967 | + bool parse_array_stop(size_t) { return true; } | ||
| 968 | + bool parse_object_start() { return true; } | ||
| 969 | + template <typename Iter> bool parse_object_item(input<Iter>& in, const std::string&) { | ||
| 970 | + return _parse(*this, in); | ||
| 971 | + } | ||
| 972 | +private: | ||
| 973 | + null_parse_context(const null_parse_context&); | ||
| 974 | + null_parse_context& operator=(const null_parse_context&); | ||
| 975 | +}; | ||
| 976 | + | ||
| 977 | +// obsolete, use the version below | ||
| 978 | +template <typename Iter> inline std::string parse(value& out, Iter& pos, const Iter& last) { | ||
| 979 | + std::string err; | ||
| 980 | + pos = parse(out, pos, last, &err); | ||
| 981 | + return err; | ||
| 982 | +} | ||
| 983 | + | ||
| 984 | +template <typename Context, typename Iter> inline Iter _parse(Context& ctx, const Iter& first, const Iter& last, std::string* err) { | ||
| 985 | + input<Iter> in(first, last); | ||
| 986 | + if (! _parse(ctx, in) && err != NULL) { | ||
| 987 | + char buf[64]; | ||
| 988 | + SNPRINTF(buf, sizeof(buf), "syntax error at line %d near: ", in.line()); | ||
| 989 | + *err = buf; | ||
| 990 | + while (1) { | ||
| 991 | + int ch = in.getc(); | ||
| 992 | + if (ch == -1 || ch == '\n') { | ||
| 993 | + break; | ||
| 994 | + } else if (ch >= ' ') { | ||
| 995 | + err->push_back(ch); | ||
| 996 | + } | ||
| 997 | + } | ||
| 998 | + } | ||
| 999 | + return in.cur(); | ||
| 1000 | +} | ||
| 1001 | + | ||
| 1002 | +template <typename Iter> inline Iter parse(value& out, const Iter& first, const Iter& last, std::string* err) { | ||
| 1003 | + default_parse_context ctx(&out); | ||
| 1004 | + return _parse(ctx, first, last, err); | ||
| 1005 | +} | ||
| 1006 | + | ||
| 1007 | +inline std::string parse(value& out, const std::string& s) { | ||
| 1008 | + std::string err; | ||
| 1009 | + parse(out, s.begin(), s.end(), &err); | ||
| 1010 | + return err; | ||
| 1011 | +} | ||
| 1012 | + | ||
| 1013 | +inline std::string parse(value& out, std::istream& is) { | ||
| 1014 | + std::string err; | ||
| 1015 | + parse(out, std::istreambuf_iterator<char>(is.rdbuf()), | ||
| 1016 | + std::istreambuf_iterator<char>(), &err); | ||
| 1017 | + return err; | ||
| 1018 | +} | ||
| 1019 | + | ||
| 1020 | +template <typename T> struct last_error_t { | ||
| 1021 | + static std::string s; | ||
| 1022 | +}; | ||
| 1023 | +template <typename T> std::string last_error_t<T>::s; | ||
| 1024 | + | ||
| 1025 | +inline void set_last_error(const std::string& s) { | ||
| 1026 | + last_error_t<bool>::s = s; | ||
| 1027 | +} | ||
| 1028 | + | ||
| 1029 | +inline const std::string& get_last_error() { | ||
| 1030 | + return last_error_t<bool>::s; | ||
| 1031 | +} | ||
| 1032 | + | ||
| 1033 | +inline bool operator==(const value& x, const value& y) { | ||
| 1034 | + if (x.is<null>()) | ||
| 1035 | + return y.is<null>(); | ||
| 1036 | +#define PICOJSON_CMP(type) \ | ||
| 1037 | + if (x.is<type>()) \ | ||
| 1038 | + return y.is<type>() && x.get<type>() == y.get<type>() | ||
| 1039 | + PICOJSON_CMP(bool); | ||
| 1040 | + PICOJSON_CMP(double); | ||
| 1041 | + PICOJSON_CMP(std::string); | ||
| 1042 | + PICOJSON_CMP(array); | ||
| 1043 | + PICOJSON_CMP(object); | ||
| 1044 | +#undef PICOJSON_CMP | ||
| 1045 | + PICOJSON_ASSERT(0); | ||
| 1046 | +#ifdef _MSC_VER | ||
| 1047 | + __assume(0); | ||
| 1048 | +#endif | ||
| 1049 | + return false; | ||
| 1050 | +} | ||
| 1051 | + | ||
| 1052 | +inline bool operator!=(const value& x, const value& y) { | ||
| 1053 | + return ! (x == y); | ||
| 1054 | +} | ||
| 1055 | +} | ||
| 1056 | + | ||
| 1057 | +#if !PICOJSON_USE_RVALUE_REFERENCE | ||
| 1058 | +namespace std { | ||
| 1059 | + template<> inline void swap(picojson::value& x, picojson::value& y) | ||
| 1060 | + { | ||
| 1061 | + x.swap(y); | ||
| 1062 | + } | ||
| 1063 | +} | ||
| 1064 | +#endif | ||
| 1065 | + | ||
| 1066 | +inline std::istream& operator>>(std::istream& is, picojson::value& x) | ||
| 1067 | +{ | ||
| 1068 | + picojson::set_last_error(std::string()); | ||
| 1069 | + std::string err = picojson::parse(x, is); | ||
| 1070 | + if (! err.empty()) { | ||
| 1071 | + picojson::set_last_error(err); | ||
| 1072 | + is.setstate(std::ios::failbit); | ||
| 1073 | + } | ||
| 1074 | + return is; | ||
| 1075 | +} | ||
| 1076 | + | ||
| 1077 | +inline std::ostream& operator<<(std::ostream& os, const picojson::value& x) | ||
| 1078 | +{ | ||
| 1079 | + x.serialize(std::ostream_iterator<char>(os)); | ||
| 1080 | + return os; | ||
| 1081 | +} | ||
| 1082 | +#ifdef _MSC_VER | ||
| 1083 | +#pragma warning(pop) | ||
| 1084 | +#endif | ||
| 1085 | + | ||
| 1086 | +#endif |
examples/reflection-demo/reflection-example.cpp
0 → 100644
| 1 | +/* | ||
| 2 | + * Copyright (c) 2020 Samsung Electronics Co., Ltd. | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + * | ||
| 16 | + */ | ||
| 17 | + | ||
| 18 | +#include <dali-toolkit/dali-toolkit.h> | ||
| 19 | +#include <dali/devel-api/actors/camera-actor-devel.h> | ||
| 20 | +#include <dali/devel-api/adaptor-framework/file-stream.h> | ||
| 21 | + | ||
| 22 | +#include <map> | ||
| 23 | + | ||
| 24 | +#include "gltf-scene.h" | ||
| 25 | + | ||
| 26 | +using namespace Dali; | ||
| 27 | +using Dali::Toolkit::TextLabel; | ||
| 28 | + | ||
| 29 | +const char* VERTEX_SHADER = DALI_COMPOSE_SHADER( | ||
| 30 | + attribute mediump vec3 aPosition;\n | ||
| 31 | + attribute mediump vec3 aNormal;\n | ||
| 32 | + attribute mediump vec2 aTexCoord;\n | ||
| 33 | + uniform mediump mat4 uMvpMatrix;\n | ||
| 34 | + uniform mediump mat3 uNormalMatrix;\n | ||
| 35 | + uniform mediump vec3 uSize;\n | ||
| 36 | + \n | ||
| 37 | + varying mediump vec2 vTexCoord; \n | ||
| 38 | + varying mediump vec3 vNormal; \n | ||
| 39 | + varying mediump vec3 vPosition; \n | ||
| 40 | + void main()\n | ||
| 41 | +{\n | ||
| 42 | + mediump vec4 vertexPosition = vec4(aPosition, 1.0);\n | ||
| 43 | + vertexPosition.xyz *= uSize;\n | ||
| 44 | + vTexCoord = aTexCoord;\n | ||
| 45 | + vNormal = normalize(uNormalMatrix * aNormal);\n | ||
| 46 | + vPosition = aPosition; \n | ||
| 47 | + gl_Position = uMvpMatrix * vertexPosition;\n | ||
| 48 | +}\n | ||
| 49 | +); | ||
| 50 | + | ||
| 51 | +const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER( | ||
| 52 | + uniform lowp vec4 uColor;\n | ||
| 53 | + uniform sampler2D sTexture; \n | ||
| 54 | + varying mediump vec3 vNormal;\n | ||
| 55 | + varying mediump vec3 vPosition; \n | ||
| 56 | + varying mediump vec2 vTexCoord; \n | ||
| 57 | + \n | ||
| 58 | + void main()\n | ||
| 59 | +{\n | ||
| 60 | + gl_FragColor = texture2D(sTexture, vTexCoord) * 50.0;\n | ||
| 61 | +}\n | ||
| 62 | +); | ||
| 63 | + | ||
| 64 | +const char* FRAGMENT_SIMPLE_SHADER = DALI_COMPOSE_SHADER( | ||
| 65 | + uniform lowp vec4 uColor;\n | ||
| 66 | + uniform sampler2D sTexture; \n | ||
| 67 | + varying mediump vec3 vNormal;\n | ||
| 68 | + varying mediump vec3 vPosition; \n | ||
| 69 | + varying mediump vec2 vTexCoord; \n | ||
| 70 | + \n | ||
| 71 | + void main()\n | ||
| 72 | +{\n | ||
| 73 | + gl_FragColor = texture2D(sTexture, vTexCoord) * 2.0;\n | ||
| 74 | +}\n | ||
| 75 | +); | ||
| 76 | + | ||
| 77 | +const char* TEXTURED_FRAGMENT_SHADER = DALI_COMPOSE_SHADER( | ||
| 78 | + uniform lowp vec4 uColor;\n | ||
| 79 | + uniform sampler2D sTexture; \n | ||
| 80 | + uniform mediump vec2 uScreenSize;\n | ||
| 81 | + | ||
| 82 | + uniform mediump vec3 eyePos;\n | ||
| 83 | + uniform mediump vec3 lightDir;\n | ||
| 84 | + | ||
| 85 | + varying mediump vec3 vNormal;\n | ||
| 86 | + varying mediump vec3 vPosition; \n | ||
| 87 | + varying mediump vec2 vTexCoord; \n | ||
| 88 | + \n | ||
| 89 | + void main()\n | ||
| 90 | +{\n | ||
| 91 | + mediump vec3 n = normalize( vNormal );\n | ||
| 92 | + mediump vec3 l = normalize( lightDir );\n | ||
| 93 | + mediump vec3 e = normalize( eyePos );\n | ||
| 94 | + mediump float intensity = max(dot(n,l), 0.0);\n | ||
| 95 | + gl_FragColor = texture2D(sTexture, vTexCoord) * intensity;\n | ||
| 96 | +}\n | ||
| 97 | +); | ||
| 98 | + | ||
| 99 | +const char* PLASMA_FRAGMENT_SHADER = DALI_COMPOSE_SHADER( | ||
| 100 | + precision mediump float;\n | ||
| 101 | + uniform sampler2D sTexture; \n | ||
| 102 | + | ||
| 103 | + uniform float uTime; | ||
| 104 | + uniform float uKFactor; | ||
| 105 | + uniform mediump vec3 eyePos;\n | ||
| 106 | + uniform mediump vec3 lightDir;\n | ||
| 107 | + varying mediump vec3 vNormal;\n | ||
| 108 | + varying mediump vec3 vPosition; \n | ||
| 109 | + varying mediump vec2 vTexCoord; \n | ||
| 110 | + \n | ||
| 111 | + void main()\n | ||
| 112 | +{\n | ||
| 113 | + mediump vec3 n = normalize( vNormal );\n | ||
| 114 | + mediump vec3 l = normalize( lightDir );\n | ||
| 115 | + mediump vec3 e = normalize( eyePos );\n | ||
| 116 | + mediump float intensity = max(dot(n,l), 0.0);\n | ||
| 117 | +\n | ||
| 118 | + const mediump float PI = 3.1415926535897932384626433832795;\n | ||
| 119 | + mediump float v = 0.0;\n | ||
| 120 | + mediump vec2 c = vTexCoord * uKFactor - uKFactor/2.0;\n | ||
| 121 | + v += sin((c.x+uTime));\n | ||
| 122 | + v += sin((c.y+uTime)/2.0);\n | ||
| 123 | + v += sin((c.x+c.y+uTime)/2.0);\n | ||
| 124 | + c += uKFactor/2.0 * vec2(sin(uTime/3.0), cos(uTime/2.0));\n | ||
| 125 | + v += sin(sqrt(c.x*c.x+c.y*c.y+1.0)+uTime);\n | ||
| 126 | + v = v/2.0;\n | ||
| 127 | + mediump vec3 col = vec3(1, sin(PI*v), cos(PI*v));\n | ||
| 128 | + gl_FragColor = (texture2D(sTexture, vTexCoord)) * (((col.r+col.g+col.b)/3.0)+1.0+intensity);\n | ||
| 129 | +}\n | ||
| 130 | +); | ||
| 131 | + | ||
| 132 | +const char* TEX_FRAGMENT_SHADER = DALI_COMPOSE_SHADER( | ||
| 133 | + uniform lowp vec4 uColor;\n | ||
| 134 | + uniform sampler2D sTexture0; \n | ||
| 135 | + uniform sampler2D sTexture1; \n | ||
| 136 | + uniform mediump vec3 eyePos;\n | ||
| 137 | + uniform mediump vec3 lightDir;\n | ||
| 138 | + uniform mediump vec2 uScreenSize;\n | ||
| 139 | + varying mediump vec3 vNormal;\n | ||
| 140 | + varying mediump vec3 vPosition; \n | ||
| 141 | + varying mediump vec2 vTexCoord; \n | ||
| 142 | + \n | ||
| 143 | + | ||
| 144 | + mediump float rand(mediump vec2 co){\n | ||
| 145 | + return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);\n | ||
| 146 | + }\n | ||
| 147 | + \n | ||
| 148 | + void main()\n | ||
| 149 | +{\n | ||
| 150 | + mediump vec2 tx = (gl_FragCoord.xy / uScreenSize.xy);\n | ||
| 151 | + mediump vec3 n = normalize( vNormal );\n | ||
| 152 | + mediump vec3 l = normalize( lightDir );\n | ||
| 153 | + mediump vec3 e = normalize( eyePos );\n | ||
| 154 | + mediump float factor = gl_FragCoord.y / uScreenSize.y;\n | ||
| 155 | + mediump float intensity = max(dot(n,l), 0.0);\n | ||
| 156 | + mediump vec2 uv = tx;\n | ||
| 157 | + gl_FragColor = ((texture2D(sTexture0, vTexCoord) * factor ) + \n | ||
| 158 | + (texture2D(sTexture1, uv))) * intensity;\n | ||
| 159 | +}\n | ||
| 160 | +); | ||
| 161 | + | ||
| 162 | +struct Model | ||
| 163 | +{ | ||
| 164 | + Shader shader; | ||
| 165 | + Geometry geometry; | ||
| 166 | +}; | ||
| 167 | + | ||
| 168 | +// This example shows how to create and display mirrored reflection using CameraActor | ||
| 169 | +// | ||
| 170 | +class ReflectionExample : public ConnectionTracker | ||
| 171 | +{ | ||
| 172 | +public: | ||
| 173 | + | ||
| 174 | + ReflectionExample( Application& application ) | ||
| 175 | + : mApplication( application ) | ||
| 176 | + { | ||
| 177 | + // Connect to the Application's Init signal | ||
| 178 | + mApplication.InitSignal().Connect( this, &ReflectionExample::Create ); | ||
| 179 | + } | ||
| 180 | + | ||
| 181 | + ~ReflectionExample() = default; | ||
| 182 | + | ||
| 183 | +private: | ||
| 184 | + | ||
| 185 | + // The Init signal is received once (only) during the Application lifetime | ||
| 186 | + void Create( Application& application ) | ||
| 187 | + { | ||
| 188 | + // Get a handle to the stage | ||
| 189 | + Stage stage = Stage::GetCurrent(); | ||
| 190 | + uint32_t stageWidth = uint32_t(stage.GetSize().x); | ||
| 191 | + uint32_t stageHeight = uint32_t(stage.GetSize().y); | ||
| 192 | + | ||
| 193 | + stage.GetRenderTaskList().GetTask(0).SetClearEnabled(false); | ||
| 194 | + mLayer3D = Layer::New(); | ||
| 195 | + mLayer3D.SetSize( stageWidth, stageHeight ); | ||
| 196 | + stage.Add(mLayer3D); | ||
| 197 | + | ||
| 198 | + mLayer3D.SetAnchorPoint( AnchorPoint::CENTER ); | ||
| 199 | + mLayer3D.SetParentOrigin( ParentOrigin::CENTER ); | ||
| 200 | + mLayer3D.SetBehavior( Layer::LAYER_3D ); | ||
| 201 | + mLayer3D.SetDepthTestDisabled( false ); | ||
| 202 | + | ||
| 203 | + | ||
| 204 | + auto gltf = glTF(DEMO_GAME_DIR "/reflection"); | ||
| 205 | + | ||
| 206 | + // Define direction of light | ||
| 207 | + mLightDir = Vector3( 0.5, 0.5, -1 ); | ||
| 208 | + | ||
| 209 | + /** | ||
| 210 | + * Instantiate texture sets | ||
| 211 | + */ | ||
| 212 | + CreateTextureSetsFromGLTF( &gltf, DEMO_GAME_DIR ); | ||
| 213 | + | ||
| 214 | + /** | ||
| 215 | + * Create models | ||
| 216 | + */ | ||
| 217 | + CreateModelsFromGLTF( &gltf ); | ||
| 218 | + | ||
| 219 | + /** | ||
| 220 | + * Create scene nodes | ||
| 221 | + */ | ||
| 222 | + CreateSceneFromGLTF( stage, &gltf ); | ||
| 223 | + | ||
| 224 | + auto planeActor = mLayer3D.FindChildByName( "Plane" ); | ||
| 225 | + auto solarActor = mLayer3D.FindChildByName( "solar_root" ); | ||
| 226 | + auto backgroundActor = mLayer3D.FindChildByName( "background" ); | ||
| 227 | + ReplaceShader( backgroundActor, VERTEX_SHADER, FRAGMENT_SIMPLE_SHADER ); | ||
| 228 | + mCenterActor = mLayer3D.FindChildByName( "center" ); | ||
| 229 | + mCenterHorizActor = mLayer3D.FindChildByName( "center2" ); | ||
| 230 | + | ||
| 231 | + // Prepare Sun | ||
| 232 | + auto sun = mLayer3D.FindChildByName( "sun" ); | ||
| 233 | + ReplaceShader( sun, VERTEX_SHADER, PLASMA_FRAGMENT_SHADER ); | ||
| 234 | + mSunTimeUniformIndex = sun.RegisterProperty( "uTime", 0.0f ); | ||
| 235 | + mSunKFactorUniformIndex = sun.RegisterProperty( "uKFactor", 0.0f ); | ||
| 236 | + | ||
| 237 | + mTickTimer = Timer::New( 16 ); | ||
| 238 | + mTickTimer.TickSignal().Connect( this, &ReflectionExample::TickTimerSignal); | ||
| 239 | + | ||
| 240 | + // Milkyway | ||
| 241 | + auto milkyway = mLayer3D.FindChildByName( "milkyway" ); | ||
| 242 | + ReplaceShader( milkyway, VERTEX_SHADER, FRAGMENT_SHADER ); | ||
| 243 | + | ||
| 244 | + auto renderTaskSourceActor = mLayer3D.FindChildByName( "RenderTaskSource" ); | ||
| 245 | + | ||
| 246 | + /** | ||
| 247 | + * Access camera (it's a child of "Camera" node) | ||
| 248 | + */ | ||
| 249 | + auto camera = mLayer3D.FindChildByName( "Camera_Orientation" ); | ||
| 250 | + auto cameraRef = mLayer3D.FindChildByName( "CameraReflection_Orientation" ); | ||
| 251 | + | ||
| 252 | + auto cameraActor = CameraActor::DownCast( camera ); | ||
| 253 | + mCamera3D = cameraActor; | ||
| 254 | + | ||
| 255 | + auto cameraRefActor = CameraActor::DownCast( cameraRef ); | ||
| 256 | + cameraRefActor.SetProperty( DevelCameraActor::Property::REFLECTION_PLANE, Vector4(0.0f, -1.0f, 0.0f, 0.0f)); | ||
| 257 | + mReflectionCamera3D = cameraRefActor; | ||
| 258 | + | ||
| 259 | + auto task3D = stage.GetRenderTaskList().CreateTask(); | ||
| 260 | + task3D.SetSourceActor( mLayer3D ); | ||
| 261 | + task3D.SetViewport( Rect<int>(0, 0, stageWidth, stageHeight ) ); | ||
| 262 | + task3D.SetCameraActor( cameraActor ); | ||
| 263 | + task3D.SetClearColor( Color::BLACK ); | ||
| 264 | + task3D.SetClearEnabled( true ); | ||
| 265 | + task3D.SetExclusive( false ); | ||
| 266 | + task3D.SetCameraActor( cameraActor ); | ||
| 267 | + | ||
| 268 | + /** | ||
| 269 | + * Change shader to textured | ||
| 270 | + */ | ||
| 271 | + Shader texShader = CreateShader( VERTEX_SHADER, TEX_FRAGMENT_SHADER ); | ||
| 272 | + planeActor.RegisterProperty( "uScreenSize", Vector2(stageWidth, stageHeight) ); | ||
| 273 | + auto renderer = planeActor.GetRendererAt(0); | ||
| 274 | + auto textureSet = renderer.GetTextures(); | ||
| 275 | + renderer.SetShader( texShader ); | ||
| 276 | + | ||
| 277 | + Texture fbTexture = Texture::New(TextureType::TEXTURE_2D, Pixel::Format::RGBA8888, stageWidth, stageHeight ); | ||
| 278 | + textureSet.SetTexture( 1u, fbTexture ); | ||
| 279 | + | ||
| 280 | + auto fb = FrameBuffer::New(stageWidth, stageHeight, | ||
| 281 | + FrameBuffer::Attachment::DEPTH ); | ||
| 282 | + | ||
| 283 | + fb.AttachColorTexture( fbTexture ); | ||
| 284 | + | ||
| 285 | + auto renderTask = stage.GetRenderTaskList().CreateTask(); | ||
| 286 | + renderTask.SetFrameBuffer( fb ); | ||
| 287 | + renderTask.SetSourceActor( renderTaskSourceActor ); | ||
| 288 | + renderTask.SetViewport( Rect<int>(0, 0, stageWidth, stageHeight ) ); | ||
| 289 | + renderTask.SetCameraActor( cameraRefActor ); | ||
| 290 | + renderTask.SetClearColor( Color::BLACK ); | ||
| 291 | + renderTask.SetClearEnabled( true ); | ||
| 292 | + renderTask.SetExclusive( false ); | ||
| 293 | + | ||
| 294 | + mAnimation = Animation::New(30.0f ); | ||
| 295 | + mAnimation.AnimateBy(Property(solarActor, Actor::Property::ORIENTATION ), | ||
| 296 | + Quaternion( Degree(359), Vector3(0.0, 1.0, 0.0))); | ||
| 297 | + mAnimation.AnimateBy(Property(milkyway, Actor::Property::ORIENTATION ), | ||
| 298 | + Quaternion( Degree(-359), Vector3(0.0, 1.0, 0.0))); | ||
| 299 | + mAnimation.SetLooping(true ); | ||
| 300 | + mAnimation.Play(); | ||
| 301 | + | ||
| 302 | + Actor panScreen = Actor::New(); | ||
| 303 | + auto stageSize = stage.GetSize(); | ||
| 304 | + panScreen.SetSize( stageSize.width, stageSize.height ); | ||
| 305 | + panScreen.SetAnchorPoint( AnchorPoint::CENTER ); | ||
| 306 | + panScreen.SetParentOrigin( ParentOrigin::CENTER ); | ||
| 307 | + auto camera2d = stage.GetRenderTaskList().GetTask(0).GetCameraActor(); | ||
| 308 | + panScreen.SetPosition( 0, 0, camera2d.GetNearClippingPlane() ); | ||
| 309 | + camera2d.Add(panScreen); | ||
| 310 | + camera2d.RotateBy( Degree(180.0f), Vector3( 0.0, 1.0, 0.0 ) ); | ||
| 311 | + mPanGestureDetector = PanGestureDetector::New(); | ||
| 312 | + mPanGestureDetector.Attach( panScreen ); | ||
| 313 | + mPanGestureDetector.DetectedSignal().Connect( this, &ReflectionExample::OnPan ); | ||
| 314 | + | ||
| 315 | + // Respond to key events | ||
| 316 | + stage.KeyEventSignal().Connect( this, &ReflectionExample::OnKeyEvent ); | ||
| 317 | + | ||
| 318 | + mTickTimer.Start(); | ||
| 319 | + } | ||
| 320 | + | ||
| 321 | + void CreateSceneFromGLTF( Stage stage, glTF* gltf ) | ||
| 322 | + { | ||
| 323 | + const auto& nodes = gltf->GetNodes(); | ||
| 324 | + | ||
| 325 | + // for each node create nodes and children | ||
| 326 | + // resolve parents later | ||
| 327 | + std::vector<Actor> actors; | ||
| 328 | + actors.reserve( nodes.size() ); | ||
| 329 | + for( const auto& node : nodes ) | ||
| 330 | + { | ||
| 331 | + auto actor = node.cameraId != 0xffffffff ? CameraActor::New( stage.GetSize() ) : Actor::New(); | ||
| 332 | + | ||
| 333 | + actor.SetSize( 1, 1, 1 ); | ||
| 334 | + actor.SetName( node.name ); | ||
| 335 | + actor.SetAnchorPoint( AnchorPoint::CENTER ); | ||
| 336 | + actor.SetParentOrigin( ParentOrigin::CENTER ); | ||
| 337 | + actor.SetPosition( node.translation[0], node.translation[1], node.translation[2] ); | ||
| 338 | + actor.SetScale( node.scale[0], node.scale[1], node.scale[2] ); | ||
| 339 | + actor.SetOrientation( Quaternion(node.rotationQuaternion[3], | ||
| 340 | + node.rotationQuaternion[0], | ||
| 341 | + node.rotationQuaternion[1], | ||
| 342 | + node.rotationQuaternion[2])); | ||
| 343 | + | ||
| 344 | + actors.emplace_back( actor ); | ||
| 345 | + | ||
| 346 | + // Initially add each actor to the very first one | ||
| 347 | + if(actors.size() > 1) | ||
| 348 | + { | ||
| 349 | + actors[0].Add(actor); | ||
| 350 | + } | ||
| 351 | + | ||
| 352 | + // If mesh, create and add renderer | ||
| 353 | + if(node.meshId != 0xffffffff) | ||
| 354 | + { | ||
| 355 | + const auto& model = mModels[node.meshId].get(); | ||
| 356 | + auto renderer = Renderer::New( model->geometry, model->shader ); | ||
| 357 | + | ||
| 358 | + // if textured, add texture set | ||
| 359 | + auto materialId = gltf->GetMeshes()[node.meshId]->material; | ||
| 360 | + if( materialId != 0xffffffff ) | ||
| 361 | + { | ||
| 362 | + if( gltf->GetMaterials()[materialId].pbrMetallicRoughness.enabled ) | ||
| 363 | + { | ||
| 364 | + renderer.SetTextures( mTextureSets[materialId] ); | ||
| 365 | + } | ||
| 366 | + } | ||
| 367 | + | ||
| 368 | + actor.AddRenderer( renderer ); | ||
| 369 | + } | ||
| 370 | + | ||
| 371 | + // Reset and attach main camera | ||
| 372 | + if( node.cameraId != 0xffffffff ) | ||
| 373 | + { | ||
| 374 | + mCameraPos = Vector3(node.translation[0], node.translation[1], node.translation[2]); | ||
| 375 | + auto quatY = Quaternion( Degree(180.0f), Vector3( 0.0, 1.0, 0.0) ); | ||
| 376 | + auto cameraActor = CameraActor::DownCast( actor ); | ||
| 377 | + cameraActor.SetOrientation( Quaternion(node.rotationQuaternion[3], | ||
| 378 | + node.rotationQuaternion[0], | ||
| 379 | + node.rotationQuaternion[1], | ||
| 380 | + node.rotationQuaternion[2] ) | ||
| 381 | + * quatY | ||
| 382 | + ); | ||
| 383 | + cameraActor.SetProjectionMode( Camera::PERSPECTIVE_PROJECTION ); | ||
| 384 | + | ||
| 385 | + const auto camera = gltf->GetCameras()[node.cameraId]; | ||
| 386 | + cameraActor.SetNearClippingPlane( camera->znear ); | ||
| 387 | + cameraActor.SetFarClippingPlane( camera->zfar ); | ||
| 388 | + cameraActor.SetFieldOfView( camera->yfov ); | ||
| 389 | + | ||
| 390 | + cameraActor.SetProperty( CameraActor::Property::INVERT_Y_AXIS, true); | ||
| 391 | + cameraActor.SetAnchorPoint( AnchorPoint::CENTER ); | ||
| 392 | + cameraActor.SetParentOrigin( ParentOrigin::CENTER ); | ||
| 393 | + | ||
| 394 | + mCameras.emplace_back( cameraActor ); | ||
| 395 | + } | ||
| 396 | + } | ||
| 397 | + | ||
| 398 | + // Resolve hierarchy dependencies | ||
| 399 | + auto i = 0u; | ||
| 400 | + for( const auto& node : nodes ) | ||
| 401 | + { | ||
| 402 | + if(!node.children.empty()) | ||
| 403 | + { | ||
| 404 | + for(const auto& childId : node.children) | ||
| 405 | + { | ||
| 406 | + actors[i].Add( actors[childId+1] ); | ||
| 407 | + } | ||
| 408 | + } | ||
| 409 | + ++i; | ||
| 410 | + } | ||
| 411 | + | ||
| 412 | + mActors = std::move(actors); | ||
| 413 | + | ||
| 414 | + // Add root actor to the stage | ||
| 415 | + mLayer3D.Add( mActors[0] ); | ||
| 416 | + | ||
| 417 | + for( auto& actor : mActors ) | ||
| 418 | + { | ||
| 419 | + actor.RegisterProperty( "lightDir", mLightDir ); | ||
| 420 | + actor.RegisterProperty( "eyePos", mCameraPos ); | ||
| 421 | + } | ||
| 422 | + | ||
| 423 | + } | ||
| 424 | + | ||
| 425 | + /** | ||
| 426 | + * Creates models from glTF | ||
| 427 | + */ | ||
| 428 | + void CreateModelsFromGLTF( glTF* gltf ) | ||
| 429 | + { | ||
| 430 | + const auto& meshes = gltf->GetMeshes(); | ||
| 431 | + for( const auto& mesh : meshes ) | ||
| 432 | + { | ||
| 433 | + // change shader to use texture if material indicates that | ||
| 434 | + if(mesh->material != 0xffffffff && gltf->GetMaterials()[mesh->material].pbrMetallicRoughness.enabled) | ||
| 435 | + { | ||
| 436 | + mModels.emplace_back( CreateModel( *gltf, mesh, VERTEX_SHADER, TEXTURED_FRAGMENT_SHADER ) ); | ||
| 437 | + } | ||
| 438 | + else | ||
| 439 | + { | ||
| 440 | + mModels.emplace_back( CreateModel( *gltf, mesh, VERTEX_SHADER, FRAGMENT_SHADER ) ); | ||
| 441 | + } | ||
| 442 | + } | ||
| 443 | + } | ||
| 444 | + | ||
| 445 | + void CreateTextureSetsFromGLTF( glTF* gltf, const std::string& basePath ) | ||
| 446 | + { | ||
| 447 | + const auto& materials = gltf->GetMaterials(); | ||
| 448 | + const auto& textures = gltf->GetTextures(); | ||
| 449 | + | ||
| 450 | + std::map<std::string, Texture> textureCache{}; | ||
| 451 | + | ||
| 452 | + for(const auto& material : materials ) | ||
| 453 | + { | ||
| 454 | + TextureSet textureSet; | ||
| 455 | + if(material.pbrMetallicRoughness.enabled) | ||
| 456 | + { | ||
| 457 | + textureSet = TextureSet::New(); | ||
| 458 | + std::string filename( basePath ); | ||
| 459 | + filename += '/'; | ||
| 460 | + filename += textures[material.pbrMetallicRoughness.baseTextureColor.index].uri; | ||
| 461 | + Dali::PixelData pixelData = Dali::Toolkit::SyncImageLoader::Load( filename ); | ||
| 462 | + | ||
| 463 | + auto cacheKey = textures[material.pbrMetallicRoughness.baseTextureColor.index].uri; | ||
| 464 | + auto iter = textureCache.find(cacheKey); | ||
| 465 | + Texture texture; | ||
| 466 | + if(iter == textureCache.end()) | ||
| 467 | + { | ||
| 468 | + texture = Texture::New(TextureType::TEXTURE_2D, pixelData.GetPixelFormat(), pixelData.GetWidth(), | ||
| 469 | + pixelData.GetHeight()); | ||
| 470 | + texture.Upload(pixelData); | ||
| 471 | + texture.GenerateMipmaps(); | ||
| 472 | + textureCache[cacheKey] = texture; | ||
| 473 | + } | ||
| 474 | + else | ||
| 475 | + { | ||
| 476 | + texture = iter->second; | ||
| 477 | + } | ||
| 478 | + textureSet.SetTexture( 0, texture ); | ||
| 479 | + Dali::Sampler sampler = Dali::Sampler::New(); | ||
| 480 | + sampler.SetWrapMode( Dali::WrapMode::REPEAT, Dali::WrapMode::REPEAT, Dali::WrapMode::REPEAT ); | ||
| 481 | + sampler.SetFilterMode( Dali::FilterMode::LINEAR_MIPMAP_LINEAR, Dali::FilterMode::LINEAR ); | ||
| 482 | + textureSet.SetSampler( 0, sampler ); | ||
| 483 | + } | ||
| 484 | + mTextureSets.emplace_back( textureSet ); | ||
| 485 | + } | ||
| 486 | + } | ||
| 487 | + | ||
| 488 | + template<class T> | ||
| 489 | + bool LoadFile( const std::string& filename, std::vector<T>& bytes ) | ||
| 490 | + { | ||
| 491 | + Dali::FileStream fileStream( filename, Dali::FileStream::READ | Dali::FileStream::BINARY ); | ||
| 492 | + FILE* fin = fileStream.GetFile(); | ||
| 493 | + | ||
| 494 | + if( fin ) | ||
| 495 | + { | ||
| 496 | + if( fseek( fin, 0, SEEK_END ) ) | ||
| 497 | + { | ||
| 498 | + return false; | ||
| 499 | + } | ||
| 500 | + bytes.resize( uint32_t(ftell( fin )) ); | ||
| 501 | + std::fill( bytes.begin(), bytes.end(), 0 ); | ||
| 502 | + if( fseek( fin, 0, SEEK_SET ) ) | ||
| 503 | + { | ||
| 504 | + return false; | ||
| 505 | + } | ||
| 506 | + size_t result = fread( bytes.data(), 1, bytes.size(), fin ); | ||
| 507 | + return ( result != 0 ); | ||
| 508 | + } | ||
| 509 | + | ||
| 510 | + return false; | ||
| 511 | + } | ||
| 512 | + | ||
| 513 | + Shader CreateShader( const std::string& vsh, const std::string& fsh ) | ||
| 514 | + { | ||
| 515 | + std::vector<char> vshShaderSource; | ||
| 516 | + std::vector<char> fshShaderSource; | ||
| 517 | + | ||
| 518 | + // VSH | ||
| 519 | + if(vsh[0] == '/') | ||
| 520 | + { | ||
| 521 | + std::string vshPath( DEMO_GAME_DIR ); | ||
| 522 | + vshPath += '/'; | ||
| 523 | + vshPath += vsh; | ||
| 524 | + LoadFile( vshPath, vshShaderSource ); | ||
| 525 | + } | ||
| 526 | + else | ||
| 527 | + { | ||
| 528 | + vshShaderSource.insert(vshShaderSource.end(), vsh.begin(), vsh.end()); | ||
| 529 | + } | ||
| 530 | + | ||
| 531 | + // FSH | ||
| 532 | + if(fsh[0] == '/') | ||
| 533 | + { | ||
| 534 | + std::string fshPath( DEMO_GAME_DIR ); | ||
| 535 | + fshPath += '/'; | ||
| 536 | + fshPath += fsh; | ||
| 537 | + LoadFile( fshPath, fshShaderSource ); | ||
| 538 | + } | ||
| 539 | + else | ||
| 540 | + { | ||
| 541 | + fshShaderSource.insert(fshShaderSource.end(), fsh.begin(), fsh.end()); | ||
| 542 | + } | ||
| 543 | + | ||
| 544 | + vshShaderSource.emplace_back(0); | ||
| 545 | + fshShaderSource.emplace_back(0); | ||
| 546 | + return Shader::New( std::string(vshShaderSource.data()), std::string(fshShaderSource.data()) ); | ||
| 547 | + } | ||
| 548 | + | ||
| 549 | + std::unique_ptr<Model> CreateModel( glTF& gltf, | ||
| 550 | + const glTF_Mesh* mesh, | ||
| 551 | + const std::string& vertexShaderSource, | ||
| 552 | + const std::string& fragmentShaderSource ) | ||
| 553 | + { | ||
| 554 | + /* | ||
| 555 | + * Obtain interleaved buffer for first mesh with position and normal attributes | ||
| 556 | + */ | ||
| 557 | + auto positionBuffer = gltf.GetMeshAttributeBuffer( *mesh, | ||
| 558 | + { | ||
| 559 | + glTFAttributeType::POSITION, | ||
| 560 | + glTFAttributeType::NORMAL, | ||
| 561 | + glTFAttributeType::TEXCOORD_0 | ||
| 562 | + } ); | ||
| 563 | + | ||
| 564 | + auto attributeCount = gltf.GetMeshAttributeCount( mesh ); | ||
| 565 | + /** | ||
| 566 | + * Create matching property buffer | ||
| 567 | + */ | ||
| 568 | + auto vertexBuffer = PropertyBuffer::New( Property::Map() | ||
| 569 | + .Add("aPosition", Property::VECTOR3 ) | ||
| 570 | + .Add("aNormal", Property::VECTOR3) | ||
| 571 | + .Add("aTexCoord", Property::VECTOR2) | ||
| 572 | + ); | ||
| 573 | + | ||
| 574 | + // set vertex data | ||
| 575 | + vertexBuffer.SetData( positionBuffer.data(), attributeCount ); | ||
| 576 | + | ||
| 577 | + auto geometry = Geometry::New(); | ||
| 578 | + geometry.AddVertexBuffer( vertexBuffer ); | ||
| 579 | + auto indexBuffer = gltf.GetMeshIndexBuffer( mesh ); | ||
| 580 | + geometry.SetIndexBuffer( indexBuffer.data(), indexBuffer.size() ); | ||
| 581 | + geometry.SetType( Geometry::Type::TRIANGLES ); | ||
| 582 | + std::unique_ptr<Model> retval( new Model() ); | ||
| 583 | + retval->shader = CreateShader( vertexShaderSource, fragmentShaderSource ); | ||
| 584 | + retval->geometry = geometry; | ||
| 585 | + return retval; | ||
| 586 | + } | ||
| 587 | + | ||
| 588 | + void ReplaceShader( Actor& actor, const std::string& vsh, const std::string& fsh ) | ||
| 589 | + { | ||
| 590 | + auto renderer = actor.GetRendererAt(0); | ||
| 591 | + auto shader = CreateShader(vsh, fsh); | ||
| 592 | + renderer.SetShader( shader ); | ||
| 593 | + } | ||
| 594 | + | ||
| 595 | + void OnPan( Actor actor, const PanGesture& panGesture ) | ||
| 596 | + { | ||
| 597 | + auto displacement = panGesture.screenDisplacement; | ||
| 598 | + mCenterActor.RotateBy( Degree( displacement.y *0.1f ), Vector3( 0.0, 0.0, 1.0) ); | ||
| 599 | + mCenterActor.RotateBy( Degree( displacement.x *0.1f ), Vector3( 0.0, 1.0, 0.0) ); | ||
| 600 | + Quaternion q; | ||
| 601 | + mCenterActor.GetProperty( Actor::Property::ORIENTATION ).Get(q); | ||
| 602 | + Matrix m = Matrix::IDENTITY; | ||
| 603 | + m.SetTransformComponents( Vector3::ONE, q, Vector3::ZERO ); | ||
| 604 | + auto yAxis = m.GetYAxis() * -1.0f; | ||
| 605 | + | ||
| 606 | + yAxis.Normalize(); | ||
| 607 | + mReflectionCamera3D.SetProperty( DevelCameraActor::Property::REFLECTION_PLANE, Vector4(yAxis.x, yAxis.y, yAxis.z, 0.0f)); | ||
| 608 | + } | ||
| 609 | + | ||
| 610 | + void OnKeyEvent( const KeyEvent& event ) | ||
| 611 | + { | ||
| 612 | + if( event.state == KeyEvent::Down ) | ||
| 613 | + { | ||
| 614 | + if ( IsKey( event, Dali::DALI_KEY_ESCAPE ) || IsKey( event, Dali::DALI_KEY_BACK ) ) | ||
| 615 | + { | ||
| 616 | + mApplication.Quit(); | ||
| 617 | + } | ||
| 618 | + } | ||
| 619 | + } | ||
| 620 | + | ||
| 621 | + bool TickTimerSignal() | ||
| 622 | + { | ||
| 623 | + auto root = mLayer3D; | ||
| 624 | + static float rotationAngle = 0.0f; | ||
| 625 | + | ||
| 626 | + const auto ROTATION_ANGLE_STEP = 0.05f; | ||
| 627 | + const auto FRAME_DELTA_TIME = 0.016f; | ||
| 628 | + const auto PLASMA_K_FACTOR = 12.0f; // 'granularity' of plasma effect | ||
| 629 | + | ||
| 630 | + rotationAngle += ROTATION_ANGLE_STEP; | ||
| 631 | + mMockTime += FRAME_DELTA_TIME; | ||
| 632 | + mKFactor = PLASMA_K_FACTOR; | ||
| 633 | + | ||
| 634 | + auto sun = root.FindChildByName( "sun" ); | ||
| 635 | + sun.SetProperty( mSunTimeUniformIndex, mMockTime ); | ||
| 636 | + sun.SetProperty( mSunKFactorUniformIndex, mKFactor ); | ||
| 637 | + sun.SetOrientation( Quaternion( Radian(Degree(rotationAngle)), Vector3(0.0, 1.0, 0.0))); | ||
| 638 | + return true; | ||
| 639 | + } | ||
| 640 | + | ||
| 641 | +private: | ||
| 642 | + Application& mApplication; | ||
| 643 | + | ||
| 644 | + Layer mLayer3D; | ||
| 645 | + | ||
| 646 | + std::vector<Actor> mActors; | ||
| 647 | + std::vector<CameraActor> mCameras; | ||
| 648 | + std::vector<std::unique_ptr<Model>> mModels; | ||
| 649 | + std::vector<TextureSet> mTextureSets; | ||
| 650 | + | ||
| 651 | + Animation mAnimation; | ||
| 652 | + float mMockTime = 0.0f; | ||
| 653 | + float mKFactor = 0.0f; | ||
| 654 | + Property::Index mSunTimeUniformIndex; | ||
| 655 | + Property::Index mSunKFactorUniformIndex; | ||
| 656 | + PanGestureDetector mPanGestureDetector; | ||
| 657 | + | ||
| 658 | + Vector3 mCameraPos; | ||
| 659 | + Vector3 mLightDir; | ||
| 660 | + Timer mTickTimer; | ||
| 661 | + | ||
| 662 | + CameraActor mCamera3D; | ||
| 663 | + CameraActor mReflectionCamera3D; | ||
| 664 | + Actor mCenterActor; | ||
| 665 | + Actor mCenterHorizActor; | ||
| 666 | +}; | ||
| 667 | + | ||
| 668 | +int DALI_EXPORT_API main( int argc, char **argv ) | ||
| 669 | +{ | ||
| 670 | + Application application = Application::New( &argc, &argv ); | ||
| 671 | + ReflectionExample test( application ); | ||
| 672 | + application.MainLoop(); | ||
| 673 | + return 0; | ||
| 674 | +} |
examples/refraction-effect/refraction-effect-example.cpp
| @@ -23,6 +23,7 @@ | @@ -23,6 +23,7 @@ | ||
| 23 | 23 | ||
| 24 | #include <sstream> | 24 | #include <sstream> |
| 25 | #include <limits> | 25 | #include <limits> |
| 26 | +#include <cctype> | ||
| 26 | 27 | ||
| 27 | // INTERNAL INCLUDES | 28 | // INTERNAL INCLUDES |
| 28 | #include "shared/view.h" | 29 | #include "shared/view.h" |
| @@ -517,7 +518,8 @@ private: | @@ -517,7 +518,8 @@ private: | ||
| 517 | } | 518 | } |
| 518 | 519 | ||
| 519 | std::istringstream iss(line.substr(2), std::istringstream::in); | 520 | std::istringstream iss(line.substr(2), std::istringstream::in); |
| 520 | - unsigned int indices[ numOfInt ]; | 521 | + Dali::Vector<unsigned int> indices; |
| 522 | + indices.Resize(numOfInt); | ||
| 521 | unsigned int i=0; | 523 | unsigned int i=0; |
| 522 | while( iss >> indices[i++] && i < numOfInt); | 524 | while( iss >> indices[i++] && i < numOfInt); |
| 523 | unsigned int step = (i+1) / 3; | 525 | unsigned int step = (i+1) / 3; |
examples/simple-text-renderer/simple-text-renderer-example.cpp
| @@ -24,7 +24,7 @@ | @@ -24,7 +24,7 @@ | ||
| 24 | #include <dali/devel-api/adaptor-framework/pixel-buffer.h> | 24 | #include <dali/devel-api/adaptor-framework/pixel-buffer.h> |
| 25 | #include <dali-toolkit/dali-toolkit.h> | 25 | #include <dali-toolkit/dali-toolkit.h> |
| 26 | #include <dali-toolkit/devel-api/text/text-utils-devel.h> | 26 | #include <dali-toolkit/devel-api/text/text-utils-devel.h> |
| 27 | -#include <devel-api/adaptor-framework/image-loading.h> | 27 | +#include <dali/devel-api/adaptor-framework/image-loading.h> |
| 28 | 28 | ||
| 29 | using namespace std; | 29 | using namespace std; |
| 30 | using namespace Dali; | 30 | using namespace Dali; |
examples/web-view/web-view-example.cpp
| @@ -18,7 +18,6 @@ | @@ -18,7 +18,6 @@ | ||
| 18 | #include <dali-toolkit/dali-toolkit.h> | 18 | #include <dali-toolkit/dali-toolkit.h> |
| 19 | #include "dali-toolkit/devel-api/controls/web-view/web-view.h" | 19 | #include "dali-toolkit/devel-api/controls/web-view/web-view.h" |
| 20 | #include <dali/integration-api/debug.h> | 20 | #include <dali/integration-api/debug.h> |
| 21 | -#include <unistd.h> | ||
| 22 | 21 | ||
| 23 | using namespace Dali; | 22 | using namespace Dali; |
| 24 | 23 |
packaging/com.samsung.dali-demo.spec
| @@ -2,7 +2,7 @@ | @@ -2,7 +2,7 @@ | ||
| 2 | 2 | ||
| 3 | Name: com.samsung.dali-demo | 3 | Name: com.samsung.dali-demo |
| 4 | Summary: The OpenGLES Canvas Core Demo | 4 | Summary: The OpenGLES Canvas Core Demo |
| 5 | -Version: 1.9.4 | 5 | +Version: 1.9.5 |
| 6 | Release: 1 | 6 | Release: 1 |
| 7 | Group: System/Libraries | 7 | Group: System/Libraries |
| 8 | License: Apache-2.0 | 8 | License: Apache-2.0 |
resources/game/reflection.bin
0 → 100644
No preview for this file type
resources/game/reflection.gltf
0 → 100644
| 1 | +{ | ||
| 2 | + "asset" : { | ||
| 3 | + "generator" : "Khronos glTF Blender I/O v1.1.46", | ||
| 4 | + "version" : "2.0" | ||
| 5 | + }, | ||
| 6 | + "scene" : 0, | ||
| 7 | + "scenes" : [ | ||
| 8 | + { | ||
| 9 | + "name" : "Scene", | ||
| 10 | + "nodes" : [ | ||
| 11 | + 4, | ||
| 12 | + 26 | ||
| 13 | + ] | ||
| 14 | + } | ||
| 15 | + ], | ||
| 16 | + "nodes" : [ | ||
| 17 | + { | ||
| 18 | + "mesh" : 0, | ||
| 19 | + "name" : "background", | ||
| 20 | + "rotation" : [ | ||
| 21 | + 0.2561876177787781, | ||
| 22 | + 0, | ||
| 23 | + 0, | ||
| 24 | + 0.9666270613670349 | ||
| 25 | + ], | ||
| 26 | + "scale" : [ | ||
| 27 | + 41.288753509521484, | ||
| 28 | + 41.288753509521484, | ||
| 29 | + 41.288753509521484 | ||
| 30 | + ], | ||
| 31 | + "translation" : [ | ||
| 32 | + 0.6707069277763367, | ||
| 33 | + -66.81024932861328, | ||
| 34 | + -2.4491214752197266 | ||
| 35 | + ] | ||
| 36 | + }, | ||
| 37 | + { | ||
| 38 | + "camera" : 0, | ||
| 39 | + "name" : "CameraReflection_Orientation", | ||
| 40 | + "rotation" : [ | ||
| 41 | + -0.7071067690849304, | ||
| 42 | + 0, | ||
| 43 | + 0, | ||
| 44 | + 0.7071067690849304 | ||
| 45 | + ] | ||
| 46 | + }, | ||
| 47 | + { | ||
| 48 | + "children" : [ | ||
| 49 | + 1 | ||
| 50 | + ], | ||
| 51 | + "name" : "CameraReflection" | ||
| 52 | + }, | ||
| 53 | + { | ||
| 54 | + "camera" : 1, | ||
| 55 | + "name" : "Camera_Orientation", | ||
| 56 | + "rotation" : [ | ||
| 57 | + -0.7071067690849304, | ||
| 58 | + 0, | ||
| 59 | + 0, | ||
| 60 | + 0.7071067690849304 | ||
| 61 | + ] | ||
| 62 | + }, | ||
| 63 | + { | ||
| 64 | + "children" : [ | ||
| 65 | + 0, | ||
| 66 | + 2, | ||
| 67 | + 3 | ||
| 68 | + ], | ||
| 69 | + "name" : "Camera", | ||
| 70 | + "rotation" : [ | ||
| 71 | + 0.3552197515964508, | ||
| 72 | + 0.6114072799682617, | ||
| 73 | + -0.3552197515964508, | ||
| 74 | + 0.6114073395729065 | ||
| 75 | + ], | ||
| 76 | + "translation" : [ | ||
| 77 | + 25.934219360351562, | ||
| 78 | + 18.4041748046875, | ||
| 79 | + 0 | ||
| 80 | + ] | ||
| 81 | + }, | ||
| 82 | + { | ||
| 83 | + "mesh" : 1, | ||
| 84 | + "name" : "Cylinder", | ||
| 85 | + "scale" : [ | ||
| 86 | + 6.3863205909729, | ||
| 87 | + 1.160239815711975, | ||
| 88 | + 6.3863205909729 | ||
| 89 | + ], | ||
| 90 | + "translation" : [ | ||
| 91 | + 0, | ||
| 92 | + -2.19092059135437, | ||
| 93 | + 0 | ||
| 94 | + ] | ||
| 95 | + }, | ||
| 96 | + { | ||
| 97 | + "name" : "Empty", | ||
| 98 | + "rotation" : [ | ||
| 99 | + 0, | ||
| 100 | + -0.3826834261417389, | ||
| 101 | + 0.9238795042037964, | ||
| 102 | + -1.672762550697371e-08 | ||
| 103 | + ], | ||
| 104 | + "scale" : [ | ||
| 105 | + 8.46078109741211, | ||
| 106 | + 8.46078109741211, | ||
| 107 | + 8.46078109741211 | ||
| 108 | + ], | ||
| 109 | + "translation" : [ | ||
| 110 | + -10.59361743927002, | ||
| 111 | + -9.98163890838623, | ||
| 112 | + -0.23785686492919922 | ||
| 113 | + ] | ||
| 114 | + }, | ||
| 115 | + { | ||
| 116 | + "name" : "Empty.001", | ||
| 117 | + "rotation" : [ | ||
| 118 | + 0, | ||
| 119 | + 1, | ||
| 120 | + 0, | ||
| 121 | + -4.371138828673793e-08 | ||
| 122 | + ], | ||
| 123 | + "scale" : [ | ||
| 124 | + 8.46078109741211, | ||
| 125 | + 8.46078109741211, | ||
| 126 | + 8.46078109741211 | ||
| 127 | + ], | ||
| 128 | + "translation" : [ | ||
| 129 | + -10.59361743927002, | ||
| 130 | + -9.98163890838623, | ||
| 131 | + -0.23785686492919922 | ||
| 132 | + ] | ||
| 133 | + }, | ||
| 134 | + { | ||
| 135 | + "name" : "Light", | ||
| 136 | + "rotation" : [ | ||
| 137 | + 0.16907575726509094, | ||
| 138 | + 0.7558803558349609, | ||
| 139 | + -0.27217137813568115, | ||
| 140 | + 0.570947527885437 | ||
| 141 | + ], | ||
| 142 | + "translation" : [ | ||
| 143 | + -1.473832130432129, | ||
| 144 | + 4.775537014007568, | ||
| 145 | + -8.020967483520508 | ||
| 146 | + ] | ||
| 147 | + }, | ||
| 148 | + { | ||
| 149 | + "mesh" : 2, | ||
| 150 | + "name" : "Plane", | ||
| 151 | + "scale" : [ | ||
| 152 | + 6.463212966918945, | ||
| 153 | + 1.1742093563079834, | ||
| 154 | + 6.463212966918945 | ||
| 155 | + ], | ||
| 156 | + "translation" : [ | ||
| 157 | + 0, | ||
| 158 | + -2.19092059135437, | ||
| 159 | + 0 | ||
| 160 | + ] | ||
| 161 | + }, | ||
| 162 | + { | ||
| 163 | + "mesh" : 3, | ||
| 164 | + "name" : "column_0.000", | ||
| 165 | + "translation" : [ | ||
| 166 | + 4.034352779388428, | ||
| 167 | + 0, | ||
| 168 | + 3.406787395477295 | ||
| 169 | + ] | ||
| 170 | + }, | ||
| 171 | + { | ||
| 172 | + "mesh" : 3, | ||
| 173 | + "name" : "column_0.001", | ||
| 174 | + "translation" : [ | ||
| 175 | + 4.034352779388428, | ||
| 176 | + 0, | ||
| 177 | + -3.546769142150879 | ||
| 178 | + ] | ||
| 179 | + }, | ||
| 180 | + { | ||
| 181 | + "mesh" : 3, | ||
| 182 | + "name" : "column_0.002", | ||
| 183 | + "translation" : [ | ||
| 184 | + -0.7669124603271484, | ||
| 185 | + 0, | ||
| 186 | + -5.243768215179443 | ||
| 187 | + ] | ||
| 188 | + }, | ||
| 189 | + { | ||
| 190 | + "mesh" : 3, | ||
| 191 | + "name" : "column_0.003", | ||
| 192 | + "translation" : [ | ||
| 193 | + -0.7669124603271484, | ||
| 194 | + 0, | ||
| 195 | + 5.600468158721924 | ||
| 196 | + ] | ||
| 197 | + }, | ||
| 198 | + { | ||
| 199 | + "mesh" : 3, | ||
| 200 | + "name" : "column_0.004", | ||
| 201 | + "translation" : [ | ||
| 202 | + -5.40261697769165, | ||
| 203 | + 0, | ||
| 204 | + 1.7097878456115723 | ||
| 205 | + ] | ||
| 206 | + }, | ||
| 207 | + { | ||
| 208 | + "mesh" : 3, | ||
| 209 | + "name" : "column_0.005", | ||
| 210 | + "translation" : [ | ||
| 211 | + -5.40261697769165, | ||
| 212 | + 0, | ||
| 213 | + -2.0567219257354736 | ||
| 214 | + ] | ||
| 215 | + }, | ||
| 216 | + { | ||
| 217 | + "mesh" : 4, | ||
| 218 | + "name" : "dome", | ||
| 219 | + "translation" : [ | ||
| 220 | + 0, | ||
| 221 | + 10.846502304077148, | ||
| 222 | + 0 | ||
| 223 | + ] | ||
| 224 | + }, | ||
| 225 | + { | ||
| 226 | + "mesh" : 5, | ||
| 227 | + "name" : "milkyway", | ||
| 228 | + "scale" : [ | ||
| 229 | + 5.861281394958496, | ||
| 230 | + -0.5747091174125671, | ||
| 231 | + 5.861281394958496 | ||
| 232 | + ], | ||
| 233 | + "translation" : [ | ||
| 234 | + 0, | ||
| 235 | + 10.332517623901367, | ||
| 236 | + 0 | ||
| 237 | + ] | ||
| 238 | + }, | ||
| 239 | + { | ||
| 240 | + "mesh" : 6, | ||
| 241 | + "name" : "earth", | ||
| 242 | + "scale" : [ | ||
| 243 | + 0.3868779242038727, | ||
| 244 | + 0.3868779242038727, | ||
| 245 | + 0.3868779242038727 | ||
| 246 | + ], | ||
| 247 | + "translation" : [ | ||
| 248 | + 0.046428680419921875, | ||
| 249 | + 4.758791923522949, | ||
| 250 | + 1.4374182224273682 | ||
| 251 | + ] | ||
| 252 | + }, | ||
| 253 | + { | ||
| 254 | + "mesh" : 7, | ||
| 255 | + "name" : "saturn", | ||
| 256 | + "scale" : [ | ||
| 257 | + 0.8631472587585449, | ||
| 258 | + 0.8631472587585449, | ||
| 259 | + 0.8631472587585449 | ||
| 260 | + ], | ||
| 261 | + "translation" : [ | ||
| 262 | + 0.7704035043716431, | ||
| 263 | + 4.758791923522949, | ||
| 264 | + 3.2832906246185303 | ||
| 265 | + ] | ||
| 266 | + }, | ||
| 267 | + { | ||
| 268 | + "mesh" : 8, | ||
| 269 | + "name" : "saturn.001", | ||
| 270 | + "scale" : [ | ||
| 271 | + 0.630012571811676, | ||
| 272 | + 0.630012571811676, | ||
| 273 | + 0.630012571811676 | ||
| 274 | + ], | ||
| 275 | + "translation" : [ | ||
| 276 | + -2.5262279510498047, | ||
| 277 | + 3.7848119735717773, | ||
| 278 | + 2.0928404331207275 | ||
| 279 | + ] | ||
| 280 | + }, | ||
| 281 | + { | ||
| 282 | + "mesh" : 9, | ||
| 283 | + "name" : "saturn.002", | ||
| 284 | + "scale" : [ | ||
| 285 | + 0.5450682640075684, | ||
| 286 | + 0.5450682640075684, | ||
| 287 | + 0.5450682640075684 | ||
| 288 | + ], | ||
| 289 | + "translation" : [ | ||
| 290 | + 0.22096490859985352, | ||
| 291 | + 5.8246612548828125, | ||
| 292 | + -2.989466428756714 | ||
| 293 | + ] | ||
| 294 | + }, | ||
| 295 | + { | ||
| 296 | + "mesh" : 10, | ||
| 297 | + "name" : "saturn.003", | ||
| 298 | + "scale" : [ | ||
| 299 | + 0.9573714733123779, | ||
| 300 | + 0.9573714733123779, | ||
| 301 | + 0.9573714733123779 | ||
| 302 | + ], | ||
| 303 | + "translation" : [ | ||
| 304 | + 2.654115915298462, | ||
| 305 | + 1.1106147766113281, | ||
| 306 | + -0.8603012561798096 | ||
| 307 | + ] | ||
| 308 | + }, | ||
| 309 | + { | ||
| 310 | + "children" : [ | ||
| 311 | + 18, | ||
| 312 | + 19, | ||
| 313 | + 20, | ||
| 314 | + 21, | ||
| 315 | + 22 | ||
| 316 | + ], | ||
| 317 | + "name" : "solar_root" | ||
| 318 | + }, | ||
| 319 | + { | ||
| 320 | + "mesh" : 11, | ||
| 321 | + "name" : "sun", | ||
| 322 | + "scale" : [ | ||
| 323 | + 1.3610559701919556, | ||
| 324 | + 1.3610559701919556, | ||
| 325 | + 1.3610559701919556 | ||
| 326 | + ], | ||
| 327 | + "translation" : [ | ||
| 328 | + 0, | ||
| 329 | + 2.0611612796783447, | ||
| 330 | + 0 | ||
| 331 | + ] | ||
| 332 | + }, | ||
| 333 | + { | ||
| 334 | + "children" : [ | ||
| 335 | + 10, | ||
| 336 | + 11, | ||
| 337 | + 12, | ||
| 338 | + 13, | ||
| 339 | + 14, | ||
| 340 | + 15, | ||
| 341 | + 16, | ||
| 342 | + 17, | ||
| 343 | + 23, | ||
| 344 | + 24 | ||
| 345 | + ], | ||
| 346 | + "name" : "RenderTaskSource" | ||
| 347 | + }, | ||
| 348 | + { | ||
| 349 | + "children" : [ | ||
| 350 | + 5, | ||
| 351 | + 6, | ||
| 352 | + 7, | ||
| 353 | + 8, | ||
| 354 | + 9, | ||
| 355 | + 25 | ||
| 356 | + ], | ||
| 357 | + "name" : "center" | ||
| 358 | + } | ||
| 359 | + ], | ||
| 360 | + "cameras" : [ | ||
| 361 | + { | ||
| 362 | + "name" : "Camera.002", | ||
| 363 | + "perspective" : { | ||
| 364 | + "yfov" : 0.6911112070083618, | ||
| 365 | + "zfar" : 1000, | ||
| 366 | + "znear" : 0.0010000000474974513 | ||
| 367 | + }, | ||
| 368 | + "type" : "perspective" | ||
| 369 | + }, | ||
| 370 | + { | ||
| 371 | + "name" : "Camera.001", | ||
| 372 | + "perspective" : { | ||
| 373 | + "yfov" : 0.6911112070083618, | ||
| 374 | + "zfar" : 1000, | ||
| 375 | + "znear" : 0.0010000000474974513 | ||
| 376 | + }, | ||
| 377 | + "type" : "perspective" | ||
| 378 | + } | ||
| 379 | + ], | ||
| 380 | + "materials" : [ | ||
| 381 | + { | ||
| 382 | + "doubleSided" : true, | ||
| 383 | + "emissiveFactor" : [ | ||
| 384 | + 0, | ||
| 385 | + 0, | ||
| 386 | + 0 | ||
| 387 | + ], | ||
| 388 | + "name" : "background", | ||
| 389 | + "pbrMetallicRoughness" : { | ||
| 390 | + "baseColorTexture" : { | ||
| 391 | + "index" : 0, | ||
| 392 | + "texCoord" : 0 | ||
| 393 | + }, | ||
| 394 | + "metallicFactor" : 0, | ||
| 395 | + "roughnessFactor" : 0.5 | ||
| 396 | + } | ||
| 397 | + }, | ||
| 398 | + { | ||
| 399 | + "doubleSided" : true, | ||
| 400 | + "emissiveFactor" : [ | ||
| 401 | + 0, | ||
| 402 | + 0, | ||
| 403 | + 0 | ||
| 404 | + ], | ||
| 405 | + "name" : "sides", | ||
| 406 | + "pbrMetallicRoughness" : { | ||
| 407 | + "baseColorTexture" : { | ||
| 408 | + "index" : 1, | ||
| 409 | + "texCoord" : 0 | ||
| 410 | + }, | ||
| 411 | + "metallicFactor" : 0, | ||
| 412 | + "roughnessFactor" : 0.5 | ||
| 413 | + } | ||
| 414 | + }, | ||
| 415 | + { | ||
| 416 | + "doubleSided" : true, | ||
| 417 | + "emissiveFactor" : [ | ||
| 418 | + 0, | ||
| 419 | + 0, | ||
| 420 | + 0 | ||
| 421 | + ], | ||
| 422 | + "name" : "top", | ||
| 423 | + "pbrMetallicRoughness" : { | ||
| 424 | + "baseColorTexture" : { | ||
| 425 | + "index" : 2, | ||
| 426 | + "texCoord" : 0 | ||
| 427 | + }, | ||
| 428 | + "metallicFactor" : 0.8947368264198303, | ||
| 429 | + "roughnessFactor" : 0.0964912474155426 | ||
| 430 | + } | ||
| 431 | + }, | ||
| 432 | + { | ||
| 433 | + "doubleSided" : true, | ||
| 434 | + "emissiveFactor" : [ | ||
| 435 | + 0, | ||
| 436 | + 0, | ||
| 437 | + 0 | ||
| 438 | + ], | ||
| 439 | + "name" : "marble2", | ||
| 440 | + "pbrMetallicRoughness" : { | ||
| 441 | + "baseColorTexture" : { | ||
| 442 | + "index" : 3, | ||
| 443 | + "texCoord" : 0 | ||
| 444 | + }, | ||
| 445 | + "metallicFactor" : 0, | ||
| 446 | + "roughnessFactor" : 0.5 | ||
| 447 | + } | ||
| 448 | + }, | ||
| 449 | + { | ||
| 450 | + "doubleSided" : true, | ||
| 451 | + "emissiveFactor" : [ | ||
| 452 | + 0, | ||
| 453 | + 0, | ||
| 454 | + 0 | ||
| 455 | + ], | ||
| 456 | + "name" : "marble", | ||
| 457 | + "pbrMetallicRoughness" : { | ||
| 458 | + "baseColorTexture" : { | ||
| 459 | + "index" : 4, | ||
| 460 | + "texCoord" : 0 | ||
| 461 | + }, | ||
| 462 | + "metallicFactor" : 0, | ||
| 463 | + "roughnessFactor" : 0.5 | ||
| 464 | + } | ||
| 465 | + }, | ||
| 466 | + { | ||
| 467 | + "doubleSided" : true, | ||
| 468 | + "emissiveFactor" : [ | ||
| 469 | + 0, | ||
| 470 | + 0, | ||
| 471 | + 0 | ||
| 472 | + ], | ||
| 473 | + "name" : "milkyway", | ||
| 474 | + "pbrMetallicRoughness" : { | ||
| 475 | + "baseColorTexture" : { | ||
| 476 | + "index" : 5, | ||
| 477 | + "texCoord" : 0 | ||
| 478 | + }, | ||
| 479 | + "metallicFactor" : 0, | ||
| 480 | + "roughnessFactor" : 0.5 | ||
| 481 | + } | ||
| 482 | + }, | ||
| 483 | + { | ||
| 484 | + "doubleSided" : true, | ||
| 485 | + "emissiveFactor" : [ | ||
| 486 | + 0, | ||
| 487 | + 0, | ||
| 488 | + 0 | ||
| 489 | + ], | ||
| 490 | + "name" : "mat_earth", | ||
| 491 | + "pbrMetallicRoughness" : { | ||
| 492 | + "baseColorTexture" : { | ||
| 493 | + "index" : 6, | ||
| 494 | + "texCoord" : 0 | ||
| 495 | + }, | ||
| 496 | + "metallicFactor" : 0, | ||
| 497 | + "roughnessFactor" : 0.5 | ||
| 498 | + } | ||
| 499 | + }, | ||
| 500 | + { | ||
| 501 | + "doubleSided" : true, | ||
| 502 | + "emissiveFactor" : [ | ||
| 503 | + 0, | ||
| 504 | + 0, | ||
| 505 | + 0 | ||
| 506 | + ], | ||
| 507 | + "name" : "mat_saturn", | ||
| 508 | + "pbrMetallicRoughness" : { | ||
| 509 | + "baseColorTexture" : { | ||
| 510 | + "index" : 7, | ||
| 511 | + "texCoord" : 0 | ||
| 512 | + }, | ||
| 513 | + "metallicFactor" : 0.11403506994247437, | ||
| 514 | + "roughnessFactor" : 0.34210526943206787 | ||
| 515 | + } | ||
| 516 | + }, | ||
| 517 | + { | ||
| 518 | + "doubleSided" : true, | ||
| 519 | + "emissiveFactor" : [ | ||
| 520 | + 0, | ||
| 521 | + 0, | ||
| 522 | + 0 | ||
| 523 | + ], | ||
| 524 | + "name" : "mat_mars", | ||
| 525 | + "pbrMetallicRoughness" : { | ||
| 526 | + "baseColorTexture" : { | ||
| 527 | + "index" : 8, | ||
| 528 | + "texCoord" : 0 | ||
| 529 | + }, | ||
| 530 | + "metallicFactor" : 0, | ||
| 531 | + "roughnessFactor" : 0.5 | ||
| 532 | + } | ||
| 533 | + }, | ||
| 534 | + { | ||
| 535 | + "doubleSided" : true, | ||
| 536 | + "emissiveFactor" : [ | ||
| 537 | + 0, | ||
| 538 | + 0, | ||
| 539 | + 0 | ||
| 540 | + ], | ||
| 541 | + "name" : "mat_venus", | ||
| 542 | + "pbrMetallicRoughness" : { | ||
| 543 | + "baseColorTexture" : { | ||
| 544 | + "index" : 9, | ||
| 545 | + "texCoord" : 0 | ||
| 546 | + }, | ||
| 547 | + "metallicFactor" : 0, | ||
| 548 | + "roughnessFactor" : 0.5 | ||
| 549 | + } | ||
| 550 | + }, | ||
| 551 | + { | ||
| 552 | + "doubleSided" : true, | ||
| 553 | + "emissiveFactor" : [ | ||
| 554 | + 0, | ||
| 555 | + 0, | ||
| 556 | + 0 | ||
| 557 | + ], | ||
| 558 | + "name" : "mat_jupiter", | ||
| 559 | + "pbrMetallicRoughness" : { | ||
| 560 | + "baseColorTexture" : { | ||
| 561 | + "index" : 10, | ||
| 562 | + "texCoord" : 0 | ||
| 563 | + }, | ||
| 564 | + "metallicFactor" : 0, | ||
| 565 | + "roughnessFactor" : 0.5 | ||
| 566 | + } | ||
| 567 | + }, | ||
| 568 | + { | ||
| 569 | + "doubleSided" : true, | ||
| 570 | + "emissiveFactor" : [ | ||
| 571 | + 1, | ||
| 572 | + 1, | ||
| 573 | + 1 | ||
| 574 | + ], | ||
| 575 | + "name" : "mat_sun2", | ||
| 576 | + "pbrMetallicRoughness" : { | ||
| 577 | + "baseColorTexture" : { | ||
| 578 | + "index" : 11, | ||
| 579 | + "texCoord" : 0 | ||
| 580 | + }, | ||
| 581 | + "metallicFactor" : 0, | ||
| 582 | + "roughnessFactor" : 0.7368420958518982 | ||
| 583 | + } | ||
| 584 | + } | ||
| 585 | + ], | ||
| 586 | + "meshes" : [ | ||
| 587 | + { | ||
| 588 | + "name" : "Plane", | ||
| 589 | + "primitives" : [ | ||
| 590 | + { | ||
| 591 | + "attributes" : { | ||
| 592 | + "POSITION" : 0, | ||
| 593 | + "NORMAL" : 1, | ||
| 594 | + "TEXCOORD_0" : 2 | ||
| 595 | + }, | ||
| 596 | + "indices" : 3, | ||
| 597 | + "material" : 0 | ||
| 598 | + } | ||
| 599 | + ] | ||
| 600 | + }, | ||
| 601 | + { | ||
| 602 | + "name" : "Cylinder", | ||
| 603 | + "primitives" : [ | ||
| 604 | + { | ||
| 605 | + "attributes" : { | ||
| 606 | + "POSITION" : 4, | ||
| 607 | + "NORMAL" : 5, | ||
| 608 | + "TEXCOORD_0" : 6 | ||
| 609 | + }, | ||
| 610 | + "indices" : 7, | ||
| 611 | + "material" : 1 | ||
| 612 | + } | ||
| 613 | + ] | ||
| 614 | + }, | ||
| 615 | + { | ||
| 616 | + "name" : "Cylinder.001", | ||
| 617 | + "primitives" : [ | ||
| 618 | + { | ||
| 619 | + "attributes" : { | ||
| 620 | + "POSITION" : 8, | ||
| 621 | + "NORMAL" : 9, | ||
| 622 | + "TEXCOORD_0" : 10 | ||
| 623 | + }, | ||
| 624 | + "indices" : 11, | ||
| 625 | + "material" : 2 | ||
| 626 | + } | ||
| 627 | + ] | ||
| 628 | + }, | ||
| 629 | + { | ||
| 630 | + "name" : "Cylinder.002", | ||
| 631 | + "primitives" : [ | ||
| 632 | + { | ||
| 633 | + "attributes" : { | ||
| 634 | + "POSITION" : 12, | ||
| 635 | + "NORMAL" : 13, | ||
| 636 | + "TEXCOORD_0" : 14 | ||
| 637 | + }, | ||
| 638 | + "indices" : 15, | ||
| 639 | + "material" : 3 | ||
| 640 | + } | ||
| 641 | + ] | ||
| 642 | + }, | ||
| 643 | + { | ||
| 644 | + "name" : "Cylinder.003", | ||
| 645 | + "primitives" : [ | ||
| 646 | + { | ||
| 647 | + "attributes" : { | ||
| 648 | + "POSITION" : 16, | ||
| 649 | + "NORMAL" : 17, | ||
| 650 | + "TEXCOORD_0" : 18 | ||
| 651 | + }, | ||
| 652 | + "indices" : 19, | ||
| 653 | + "material" : 4 | ||
| 654 | + } | ||
| 655 | + ] | ||
| 656 | + }, | ||
| 657 | + { | ||
| 658 | + "name" : "Cylinder.004", | ||
| 659 | + "primitives" : [ | ||
| 660 | + { | ||
| 661 | + "attributes" : { | ||
| 662 | + "POSITION" : 20, | ||
| 663 | + "NORMAL" : 21, | ||
| 664 | + "TEXCOORD_0" : 22 | ||
| 665 | + }, | ||
| 666 | + "indices" : 23, | ||
| 667 | + "material" : 5 | ||
| 668 | + } | ||
| 669 | + ] | ||
| 670 | + }, | ||
| 671 | + { | ||
| 672 | + "name" : "Sphere", | ||
| 673 | + "primitives" : [ | ||
| 674 | + { | ||
| 675 | + "attributes" : { | ||
| 676 | + "POSITION" : 24, | ||
| 677 | + "NORMAL" : 25, | ||
| 678 | + "TEXCOORD_0" : 26 | ||
| 679 | + }, | ||
| 680 | + "indices" : 27, | ||
| 681 | + "material" : 6 | ||
| 682 | + } | ||
| 683 | + ] | ||
| 684 | + }, | ||
| 685 | + { | ||
| 686 | + "name" : "Sphere.002", | ||
| 687 | + "primitives" : [ | ||
| 688 | + { | ||
| 689 | + "attributes" : { | ||
| 690 | + "POSITION" : 28, | ||
| 691 | + "NORMAL" : 29, | ||
| 692 | + "TEXCOORD_0" : 30 | ||
| 693 | + }, | ||
| 694 | + "indices" : 27, | ||
| 695 | + "material" : 7 | ||
| 696 | + } | ||
| 697 | + ] | ||
| 698 | + }, | ||
| 699 | + { | ||
| 700 | + "name" : "Sphere.003", | ||
| 701 | + "primitives" : [ | ||
| 702 | + { | ||
| 703 | + "attributes" : { | ||
| 704 | + "POSITION" : 31, | ||
| 705 | + "NORMAL" : 32, | ||
| 706 | + "TEXCOORD_0" : 33 | ||
| 707 | + }, | ||
| 708 | + "indices" : 27, | ||
| 709 | + "material" : 8 | ||
| 710 | + } | ||
| 711 | + ] | ||
| 712 | + }, | ||
| 713 | + { | ||
| 714 | + "name" : "Sphere.004", | ||
| 715 | + "primitives" : [ | ||
| 716 | + { | ||
| 717 | + "attributes" : { | ||
| 718 | + "POSITION" : 34, | ||
| 719 | + "NORMAL" : 35, | ||
| 720 | + "TEXCOORD_0" : 36 | ||
| 721 | + }, | ||
| 722 | + "indices" : 27, | ||
| 723 | + "material" : 9 | ||
| 724 | + } | ||
| 725 | + ] | ||
| 726 | + }, | ||
| 727 | + { | ||
| 728 | + "name" : "Sphere.005", | ||
| 729 | + "primitives" : [ | ||
| 730 | + { | ||
| 731 | + "attributes" : { | ||
| 732 | + "POSITION" : 37, | ||
| 733 | + "NORMAL" : 38, | ||
| 734 | + "TEXCOORD_0" : 39 | ||
| 735 | + }, | ||
| 736 | + "indices" : 40, | ||
| 737 | + "material" : 10 | ||
| 738 | + } | ||
| 739 | + ] | ||
| 740 | + }, | ||
| 741 | + { | ||
| 742 | + "name" : "Sphere.001", | ||
| 743 | + "primitives" : [ | ||
| 744 | + { | ||
| 745 | + "attributes" : { | ||
| 746 | + "POSITION" : 41, | ||
| 747 | + "NORMAL" : 42, | ||
| 748 | + "TEXCOORD_0" : 43 | ||
| 749 | + }, | ||
| 750 | + "indices" : 44, | ||
| 751 | + "material" : 11 | ||
| 752 | + } | ||
| 753 | + ] | ||
| 754 | + } | ||
| 755 | + ], | ||
| 756 | + "textures" : [ | ||
| 757 | + { | ||
| 758 | + "source" : 0 | ||
| 759 | + }, | ||
| 760 | + { | ||
| 761 | + "source" : 0 | ||
| 762 | + }, | ||
| 763 | + { | ||
| 764 | + "source" : 0 | ||
| 765 | + }, | ||
| 766 | + { | ||
| 767 | + "source" : 0 | ||
| 768 | + }, | ||
| 769 | + { | ||
| 770 | + "source" : 0 | ||
| 771 | + }, | ||
| 772 | + { | ||
| 773 | + "source" : 0 | ||
| 774 | + }, | ||
| 775 | + { | ||
| 776 | + "source" : 0 | ||
| 777 | + }, | ||
| 778 | + { | ||
| 779 | + "source" : 0 | ||
| 780 | + }, | ||
| 781 | + { | ||
| 782 | + "source" : 0 | ||
| 783 | + }, | ||
| 784 | + { | ||
| 785 | + "source" : 0 | ||
| 786 | + }, | ||
| 787 | + { | ||
| 788 | + "source" : 0 | ||
| 789 | + }, | ||
| 790 | + { | ||
| 791 | + "source" : 0 | ||
| 792 | + } | ||
| 793 | + ], | ||
| 794 | + "images" : [ | ||
| 795 | + { | ||
| 796 | + "mimeType" : "image/png", | ||
| 797 | + "name" : "texture-atlas", | ||
| 798 | + "uri" : "texture-atlas.jpg" | ||
| 799 | + } | ||
| 800 | + ], | ||
| 801 | + "accessors" : [ | ||
| 802 | + { | ||
| 803 | + "bufferView" : 0, | ||
| 804 | + "componentType" : 5126, | ||
| 805 | + "count" : 4, | ||
| 806 | + "max" : [ | ||
| 807 | + 1, | ||
| 808 | + 0, | ||
| 809 | + 1 | ||
| 810 | + ], | ||
| 811 | + "min" : [ | ||
| 812 | + -1, | ||
| 813 | + 0, | ||
| 814 | + -1 | ||
| 815 | + ], | ||
| 816 | + "type" : "VEC3" | ||
| 817 | + }, | ||
| 818 | + { | ||
| 819 | + "bufferView" : 1, | ||
| 820 | + "componentType" : 5126, | ||
| 821 | + "count" : 4, | ||
| 822 | + "type" : "VEC3" | ||
| 823 | + }, | ||
| 824 | + { | ||
| 825 | + "bufferView" : 2, | ||
| 826 | + "componentType" : 5126, | ||
| 827 | + "count" : 4, | ||
| 828 | + "type" : "VEC2" | ||
| 829 | + }, | ||
| 830 | + { | ||
| 831 | + "bufferView" : 3, | ||
| 832 | + "componentType" : 5123, | ||
| 833 | + "count" : 6, | ||
| 834 | + "type" : "SCALAR" | ||
| 835 | + }, | ||
| 836 | + { | ||
| 837 | + "bufferView" : 4, | ||
| 838 | + "componentType" : 5126, | ||
| 839 | + "count" : 72, | ||
| 840 | + "max" : [ | ||
| 841 | + 1, | ||
| 842 | + 1, | ||
| 843 | + 1 | ||
| 844 | + ], | ||
| 845 | + "min" : [ | ||
| 846 | + -1, | ||
| 847 | + -1, | ||
| 848 | + -1 | ||
| 849 | + ], | ||
| 850 | + "type" : "VEC3" | ||
| 851 | + }, | ||
| 852 | + { | ||
| 853 | + "bufferView" : 5, | ||
| 854 | + "componentType" : 5126, | ||
| 855 | + "count" : 72, | ||
| 856 | + "type" : "VEC3" | ||
| 857 | + }, | ||
| 858 | + { | ||
| 859 | + "bufferView" : 6, | ||
| 860 | + "componentType" : 5126, | ||
| 861 | + "count" : 72, | ||
| 862 | + "type" : "VEC2" | ||
| 863 | + }, | ||
| 864 | + { | ||
| 865 | + "bufferView" : 7, | ||
| 866 | + "componentType" : 5123, | ||
| 867 | + "count" : 192, | ||
| 868 | + "type" : "SCALAR" | ||
| 869 | + }, | ||
| 870 | + { | ||
| 871 | + "bufferView" : 8, | ||
| 872 | + "componentType" : 5126, | ||
| 873 | + "count" : 32, | ||
| 874 | + "max" : [ | ||
| 875 | + 1, | ||
| 876 | + 1, | ||
| 877 | + 1 | ||
| 878 | + ], | ||
| 879 | + "min" : [ | ||
| 880 | + -1, | ||
| 881 | + 1, | ||
| 882 | + -1 | ||
| 883 | + ], | ||
| 884 | + "type" : "VEC3" | ||
| 885 | + }, | ||
| 886 | + { | ||
| 887 | + "bufferView" : 9, | ||
| 888 | + "componentType" : 5126, | ||
| 889 | + "count" : 32, | ||
| 890 | + "type" : "VEC3" | ||
| 891 | + }, | ||
| 892 | + { | ||
| 893 | + "bufferView" : 10, | ||
| 894 | + "componentType" : 5126, | ||
| 895 | + "count" : 32, | ||
| 896 | + "type" : "VEC2" | ||
| 897 | + }, | ||
| 898 | + { | ||
| 899 | + "bufferView" : 11, | ||
| 900 | + "componentType" : 5123, | ||
| 901 | + "count" : 90, | ||
| 902 | + "type" : "SCALAR" | ||
| 903 | + }, | ||
| 904 | + { | ||
| 905 | + "bufferView" : 12, | ||
| 906 | + "componentType" : 5126, | ||
| 907 | + "count" : 800, | ||
| 908 | + "max" : [ | ||
| 909 | + 0.9250403642654419, | ||
| 910 | + 10.267958641052246, | ||
| 911 | + 0.9250403642654419 | ||
| 912 | + ], | ||
| 913 | + "min" : [ | ||
| 914 | + -0.9250403642654419, | ||
| 915 | + -0.9530067443847656, | ||
| 916 | + -0.9250403642654419 | ||
| 917 | + ], | ||
| 918 | + "type" : "VEC3" | ||
| 919 | + }, | ||
| 920 | + { | ||
| 921 | + "bufferView" : 13, | ||
| 922 | + "componentType" : 5126, | ||
| 923 | + "count" : 800, | ||
| 924 | + "type" : "VEC3" | ||
| 925 | + }, | ||
| 926 | + { | ||
| 927 | + "bufferView" : 14, | ||
| 928 | + "componentType" : 5126, | ||
| 929 | + "count" : 800, | ||
| 930 | + "type" : "VEC2" | ||
| 931 | + }, | ||
| 932 | + { | ||
| 933 | + "bufferView" : 15, | ||
| 934 | + "componentType" : 5123, | ||
| 935 | + "count" : 1428, | ||
| 936 | + "type" : "SCALAR" | ||
| 937 | + }, | ||
| 938 | + { | ||
| 939 | + "bufferView" : 16, | ||
| 940 | + "componentType" : 5126, | ||
| 941 | + "count" : 716, | ||
| 942 | + "max" : [ | ||
| 943 | + 6.96999979019165, | ||
| 944 | + 1.0763102769851685, | ||
| 945 | + 6.67748498916626 | ||
| 946 | + ], | ||
| 947 | + "min" : [ | ||
| 948 | + -6.970000267028809, | ||
| 949 | + -1, | ||
| 950 | + -6.677481651306152 | ||
| 951 | + ], | ||
| 952 | + "type" : "VEC3" | ||
| 953 | + }, | ||
| 954 | + { | ||
| 955 | + "bufferView" : 17, | ||
| 956 | + "componentType" : 5126, | ||
| 957 | + "count" : 716, | ||
| 958 | + "type" : "VEC3" | ||
| 959 | + }, | ||
| 960 | + { | ||
| 961 | + "bufferView" : 18, | ||
| 962 | + "componentType" : 5126, | ||
| 963 | + "count" : 716, | ||
| 964 | + "type" : "VEC2" | ||
| 965 | + }, | ||
| 966 | + { | ||
| 967 | + "bufferView" : 19, | ||
| 968 | + "componentType" : 5123, | ||
| 969 | + "count" : 3444, | ||
| 970 | + "type" : "SCALAR" | ||
| 971 | + }, | ||
| 972 | + { | ||
| 973 | + "bufferView" : 20, | ||
| 974 | + "componentType" : 5126, | ||
| 975 | + "count" : 89, | ||
| 976 | + "max" : [ | ||
| 977 | + 1, | ||
| 978 | + 1, | ||
| 979 | + 1 | ||
| 980 | + ], | ||
| 981 | + "min" : [ | ||
| 982 | + -1, | ||
| 983 | + 1, | ||
| 984 | + -1 | ||
| 985 | + ], | ||
| 986 | + "type" : "VEC3" | ||
| 987 | + }, | ||
| 988 | + { | ||
| 989 | + "bufferView" : 21, | ||
| 990 | + "componentType" : 5126, | ||
| 991 | + "count" : 89, | ||
| 992 | + "type" : "VEC3" | ||
| 993 | + }, | ||
| 994 | + { | ||
| 995 | + "bufferView" : 22, | ||
| 996 | + "componentType" : 5126, | ||
| 997 | + "count" : 89, | ||
| 998 | + "type" : "VEC2" | ||
| 999 | + }, | ||
| 1000 | + { | ||
| 1001 | + "bufferView" : 23, | ||
| 1002 | + "componentType" : 5123, | ||
| 1003 | + "count" : 90, | ||
| 1004 | + "type" : "SCALAR" | ||
| 1005 | + }, | ||
| 1006 | + { | ||
| 1007 | + "bufferView" : 24, | ||
| 1008 | + "componentType" : 5126, | ||
| 1009 | + "count" : 541, | ||
| 1010 | + "max" : [ | ||
| 1011 | + 1.000000238418579, | ||
| 1012 | + 1, | ||
| 1013 | + 1.0000003576278687 | ||
| 1014 | + ], | ||
| 1015 | + "min" : [ | ||
| 1016 | + -0.9999998211860657, | ||
| 1017 | + -1, | ||
| 1018 | + -1 | ||
| 1019 | + ], | ||
| 1020 | + "type" : "VEC3" | ||
| 1021 | + }, | ||
| 1022 | + { | ||
| 1023 | + "bufferView" : 25, | ||
| 1024 | + "componentType" : 5126, | ||
| 1025 | + "count" : 541, | ||
| 1026 | + "type" : "VEC3" | ||
| 1027 | + }, | ||
| 1028 | + { | ||
| 1029 | + "bufferView" : 26, | ||
| 1030 | + "componentType" : 5126, | ||
| 1031 | + "count" : 541, | ||
| 1032 | + "type" : "VEC2" | ||
| 1033 | + }, | ||
| 1034 | + { | ||
| 1035 | + "bufferView" : 27, | ||
| 1036 | + "componentType" : 5123, | ||
| 1037 | + "count" : 2880, | ||
| 1038 | + "type" : "SCALAR" | ||
| 1039 | + }, | ||
| 1040 | + { | ||
| 1041 | + "bufferView" : 28, | ||
| 1042 | + "componentType" : 5126, | ||
| 1043 | + "count" : 541, | ||
| 1044 | + "max" : [ | ||
| 1045 | + 1.000000238418579, | ||
| 1046 | + 1, | ||
| 1047 | + 1.0000003576278687 | ||
| 1048 | + ], | ||
| 1049 | + "min" : [ | ||
| 1050 | + -0.9999998211860657, | ||
| 1051 | + -1, | ||
| 1052 | + -1 | ||
| 1053 | + ], | ||
| 1054 | + "type" : "VEC3" | ||
| 1055 | + }, | ||
| 1056 | + { | ||
| 1057 | + "bufferView" : 29, | ||
| 1058 | + "componentType" : 5126, | ||
| 1059 | + "count" : 541, | ||
| 1060 | + "type" : "VEC3" | ||
| 1061 | + }, | ||
| 1062 | + { | ||
| 1063 | + "bufferView" : 30, | ||
| 1064 | + "componentType" : 5126, | ||
| 1065 | + "count" : 541, | ||
| 1066 | + "type" : "VEC2" | ||
| 1067 | + }, | ||
| 1068 | + { | ||
| 1069 | + "bufferView" : 31, | ||
| 1070 | + "componentType" : 5126, | ||
| 1071 | + "count" : 541, | ||
| 1072 | + "max" : [ | ||
| 1073 | + 1.000000238418579, | ||
| 1074 | + 1, | ||
| 1075 | + 1.0000003576278687 | ||
| 1076 | + ], | ||
| 1077 | + "min" : [ | ||
| 1078 | + -0.9999998211860657, | ||
| 1079 | + -1, | ||
| 1080 | + -1 | ||
| 1081 | + ], | ||
| 1082 | + "type" : "VEC3" | ||
| 1083 | + }, | ||
| 1084 | + { | ||
| 1085 | + "bufferView" : 32, | ||
| 1086 | + "componentType" : 5126, | ||
| 1087 | + "count" : 541, | ||
| 1088 | + "type" : "VEC3" | ||
| 1089 | + }, | ||
| 1090 | + { | ||
| 1091 | + "bufferView" : 33, | ||
| 1092 | + "componentType" : 5126, | ||
| 1093 | + "count" : 541, | ||
| 1094 | + "type" : "VEC2" | ||
| 1095 | + }, | ||
| 1096 | + { | ||
| 1097 | + "bufferView" : 34, | ||
| 1098 | + "componentType" : 5126, | ||
| 1099 | + "count" : 541, | ||
| 1100 | + "max" : [ | ||
| 1101 | + 1.000000238418579, | ||
| 1102 | + 1, | ||
| 1103 | + 1.0000003576278687 | ||
| 1104 | + ], | ||
| 1105 | + "min" : [ | ||
| 1106 | + -0.9999998211860657, | ||
| 1107 | + -1, | ||
| 1108 | + -1 | ||
| 1109 | + ], | ||
| 1110 | + "type" : "VEC3" | ||
| 1111 | + }, | ||
| 1112 | + { | ||
| 1113 | + "bufferView" : 35, | ||
| 1114 | + "componentType" : 5126, | ||
| 1115 | + "count" : 541, | ||
| 1116 | + "type" : "VEC3" | ||
| 1117 | + }, | ||
| 1118 | + { | ||
| 1119 | + "bufferView" : 36, | ||
| 1120 | + "componentType" : 5126, | ||
| 1121 | + "count" : 541, | ||
| 1122 | + "type" : "VEC2" | ||
| 1123 | + }, | ||
| 1124 | + { | ||
| 1125 | + "bufferView" : 37, | ||
| 1126 | + "componentType" : 5126, | ||
| 1127 | + "count" : 539, | ||
| 1128 | + "max" : [ | ||
| 1129 | + 1.000000238418579, | ||
| 1130 | + 1, | ||
| 1131 | + 1.0000003576278687 | ||
| 1132 | + ], | ||
| 1133 | + "min" : [ | ||
| 1134 | + -0.9999998211860657, | ||
| 1135 | + -1, | ||
| 1136 | + -1 | ||
| 1137 | + ], | ||
| 1138 | + "type" : "VEC3" | ||
| 1139 | + }, | ||
| 1140 | + { | ||
| 1141 | + "bufferView" : 38, | ||
| 1142 | + "componentType" : 5126, | ||
| 1143 | + "count" : 539, | ||
| 1144 | + "type" : "VEC3" | ||
| 1145 | + }, | ||
| 1146 | + { | ||
| 1147 | + "bufferView" : 39, | ||
| 1148 | + "componentType" : 5126, | ||
| 1149 | + "count" : 539, | ||
| 1150 | + "type" : "VEC2" | ||
| 1151 | + }, | ||
| 1152 | + { | ||
| 1153 | + "bufferView" : 40, | ||
| 1154 | + "componentType" : 5123, | ||
| 1155 | + "count" : 2880, | ||
| 1156 | + "type" : "SCALAR" | ||
| 1157 | + }, | ||
| 1158 | + { | ||
| 1159 | + "bufferView" : 41, | ||
| 1160 | + "componentType" : 5126, | ||
| 1161 | + "count" : 559, | ||
| 1162 | + "max" : [ | ||
| 1163 | + 1.0000001192092896, | ||
| 1164 | + 1, | ||
| 1165 | + 1.0000001192092896 | ||
| 1166 | + ], | ||
| 1167 | + "min" : [ | ||
| 1168 | + -0.9999999403953552, | ||
| 1169 | + -1, | ||
| 1170 | + -1.000000238418579 | ||
| 1171 | + ], | ||
| 1172 | + "type" : "VEC3" | ||
| 1173 | + }, | ||
| 1174 | + { | ||
| 1175 | + "bufferView" : 42, | ||
| 1176 | + "componentType" : 5126, | ||
| 1177 | + "count" : 559, | ||
| 1178 | + "type" : "VEC3" | ||
| 1179 | + }, | ||
| 1180 | + { | ||
| 1181 | + "bufferView" : 43, | ||
| 1182 | + "componentType" : 5126, | ||
| 1183 | + "count" : 559, | ||
| 1184 | + "type" : "VEC2" | ||
| 1185 | + }, | ||
| 1186 | + { | ||
| 1187 | + "bufferView" : 44, | ||
| 1188 | + "componentType" : 5123, | ||
| 1189 | + "count" : 2880, | ||
| 1190 | + "type" : "SCALAR" | ||
| 1191 | + } | ||
| 1192 | + ], | ||
| 1193 | + "bufferViews" : [ | ||
| 1194 | + { | ||
| 1195 | + "buffer" : 0, | ||
| 1196 | + "byteLength" : 48, | ||
| 1197 | + "byteOffset" : 0 | ||
| 1198 | + }, | ||
| 1199 | + { | ||
| 1200 | + "buffer" : 0, | ||
| 1201 | + "byteLength" : 48, | ||
| 1202 | + "byteOffset" : 48 | ||
| 1203 | + }, | ||
| 1204 | + { | ||
| 1205 | + "buffer" : 0, | ||
| 1206 | + "byteLength" : 32, | ||
| 1207 | + "byteOffset" : 96 | ||
| 1208 | + }, | ||
| 1209 | + { | ||
| 1210 | + "buffer" : 0, | ||
| 1211 | + "byteLength" : 12, | ||
| 1212 | + "byteOffset" : 128 | ||
| 1213 | + }, | ||
| 1214 | + { | ||
| 1215 | + "buffer" : 0, | ||
| 1216 | + "byteLength" : 864, | ||
| 1217 | + "byteOffset" : 140 | ||
| 1218 | + }, | ||
| 1219 | + { | ||
| 1220 | + "buffer" : 0, | ||
| 1221 | + "byteLength" : 864, | ||
| 1222 | + "byteOffset" : 1004 | ||
| 1223 | + }, | ||
| 1224 | + { | ||
| 1225 | + "buffer" : 0, | ||
| 1226 | + "byteLength" : 576, | ||
| 1227 | + "byteOffset" : 1868 | ||
| 1228 | + }, | ||
| 1229 | + { | ||
| 1230 | + "buffer" : 0, | ||
| 1231 | + "byteLength" : 384, | ||
| 1232 | + "byteOffset" : 2444 | ||
| 1233 | + }, | ||
| 1234 | + { | ||
| 1235 | + "buffer" : 0, | ||
| 1236 | + "byteLength" : 384, | ||
| 1237 | + "byteOffset" : 2828 | ||
| 1238 | + }, | ||
| 1239 | + { | ||
| 1240 | + "buffer" : 0, | ||
| 1241 | + "byteLength" : 384, | ||
| 1242 | + "byteOffset" : 3212 | ||
| 1243 | + }, | ||
| 1244 | + { | ||
| 1245 | + "buffer" : 0, | ||
| 1246 | + "byteLength" : 256, | ||
| 1247 | + "byteOffset" : 3596 | ||
| 1248 | + }, | ||
| 1249 | + { | ||
| 1250 | + "buffer" : 0, | ||
| 1251 | + "byteLength" : 180, | ||
| 1252 | + "byteOffset" : 3852 | ||
| 1253 | + }, | ||
| 1254 | + { | ||
| 1255 | + "buffer" : 0, | ||
| 1256 | + "byteLength" : 9600, | ||
| 1257 | + "byteOffset" : 4032 | ||
| 1258 | + }, | ||
| 1259 | + { | ||
| 1260 | + "buffer" : 0, | ||
| 1261 | + "byteLength" : 9600, | ||
| 1262 | + "byteOffset" : 13632 | ||
| 1263 | + }, | ||
| 1264 | + { | ||
| 1265 | + "buffer" : 0, | ||
| 1266 | + "byteLength" : 6400, | ||
| 1267 | + "byteOffset" : 23232 | ||
| 1268 | + }, | ||
| 1269 | + { | ||
| 1270 | + "buffer" : 0, | ||
| 1271 | + "byteLength" : 2856, | ||
| 1272 | + "byteOffset" : 29632 | ||
| 1273 | + }, | ||
| 1274 | + { | ||
| 1275 | + "buffer" : 0, | ||
| 1276 | + "byteLength" : 8592, | ||
| 1277 | + "byteOffset" : 32488 | ||
| 1278 | + }, | ||
| 1279 | + { | ||
| 1280 | + "buffer" : 0, | ||
| 1281 | + "byteLength" : 8592, | ||
| 1282 | + "byteOffset" : 41080 | ||
| 1283 | + }, | ||
| 1284 | + { | ||
| 1285 | + "buffer" : 0, | ||
| 1286 | + "byteLength" : 5728, | ||
| 1287 | + "byteOffset" : 49672 | ||
| 1288 | + }, | ||
| 1289 | + { | ||
| 1290 | + "buffer" : 0, | ||
| 1291 | + "byteLength" : 6888, | ||
| 1292 | + "byteOffset" : 55400 | ||
| 1293 | + }, | ||
| 1294 | + { | ||
| 1295 | + "buffer" : 0, | ||
| 1296 | + "byteLength" : 1068, | ||
| 1297 | + "byteOffset" : 62288 | ||
| 1298 | + }, | ||
| 1299 | + { | ||
| 1300 | + "buffer" : 0, | ||
| 1301 | + "byteLength" : 1068, | ||
| 1302 | + "byteOffset" : 63356 | ||
| 1303 | + }, | ||
| 1304 | + { | ||
| 1305 | + "buffer" : 0, | ||
| 1306 | + "byteLength" : 712, | ||
| 1307 | + "byteOffset" : 64424 | ||
| 1308 | + }, | ||
| 1309 | + { | ||
| 1310 | + "buffer" : 0, | ||
| 1311 | + "byteLength" : 180, | ||
| 1312 | + "byteOffset" : 65136 | ||
| 1313 | + }, | ||
| 1314 | + { | ||
| 1315 | + "buffer" : 0, | ||
| 1316 | + "byteLength" : 6492, | ||
| 1317 | + "byteOffset" : 65316 | ||
| 1318 | + }, | ||
| 1319 | + { | ||
| 1320 | + "buffer" : 0, | ||
| 1321 | + "byteLength" : 6492, | ||
| 1322 | + "byteOffset" : 71808 | ||
| 1323 | + }, | ||
| 1324 | + { | ||
| 1325 | + "buffer" : 0, | ||
| 1326 | + "byteLength" : 4328, | ||
| 1327 | + "byteOffset" : 78300 | ||
| 1328 | + }, | ||
| 1329 | + { | ||
| 1330 | + "buffer" : 0, | ||
| 1331 | + "byteLength" : 5760, | ||
| 1332 | + "byteOffset" : 82628 | ||
| 1333 | + }, | ||
| 1334 | + { | ||
| 1335 | + "buffer" : 0, | ||
| 1336 | + "byteLength" : 6492, | ||
| 1337 | + "byteOffset" : 88388 | ||
| 1338 | + }, | ||
| 1339 | + { | ||
| 1340 | + "buffer" : 0, | ||
| 1341 | + "byteLength" : 6492, | ||
| 1342 | + "byteOffset" : 94880 | ||
| 1343 | + }, | ||
| 1344 | + { | ||
| 1345 | + "buffer" : 0, | ||
| 1346 | + "byteLength" : 4328, | ||
| 1347 | + "byteOffset" : 101372 | ||
| 1348 | + }, | ||
| 1349 | + { | ||
| 1350 | + "buffer" : 0, | ||
| 1351 | + "byteLength" : 6492, | ||
| 1352 | + "byteOffset" : 105700 | ||
| 1353 | + }, | ||
| 1354 | + { | ||
| 1355 | + "buffer" : 0, | ||
| 1356 | + "byteLength" : 6492, | ||
| 1357 | + "byteOffset" : 112192 | ||
| 1358 | + }, | ||
| 1359 | + { | ||
| 1360 | + "buffer" : 0, | ||
| 1361 | + "byteLength" : 4328, | ||
| 1362 | + "byteOffset" : 118684 | ||
| 1363 | + }, | ||
| 1364 | + { | ||
| 1365 | + "buffer" : 0, | ||
| 1366 | + "byteLength" : 6492, | ||
| 1367 | + "byteOffset" : 123012 | ||
| 1368 | + }, | ||
| 1369 | + { | ||
| 1370 | + "buffer" : 0, | ||
| 1371 | + "byteLength" : 6492, | ||
| 1372 | + "byteOffset" : 129504 | ||
| 1373 | + }, | ||
| 1374 | + { | ||
| 1375 | + "buffer" : 0, | ||
| 1376 | + "byteLength" : 4328, | ||
| 1377 | + "byteOffset" : 135996 | ||
| 1378 | + }, | ||
| 1379 | + { | ||
| 1380 | + "buffer" : 0, | ||
| 1381 | + "byteLength" : 6468, | ||
| 1382 | + "byteOffset" : 140324 | ||
| 1383 | + }, | ||
| 1384 | + { | ||
| 1385 | + "buffer" : 0, | ||
| 1386 | + "byteLength" : 6468, | ||
| 1387 | + "byteOffset" : 146792 | ||
| 1388 | + }, | ||
| 1389 | + { | ||
| 1390 | + "buffer" : 0, | ||
| 1391 | + "byteLength" : 4312, | ||
| 1392 | + "byteOffset" : 153260 | ||
| 1393 | + }, | ||
| 1394 | + { | ||
| 1395 | + "buffer" : 0, | ||
| 1396 | + "byteLength" : 5760, | ||
| 1397 | + "byteOffset" : 157572 | ||
| 1398 | + }, | ||
| 1399 | + { | ||
| 1400 | + "buffer" : 0, | ||
| 1401 | + "byteLength" : 6708, | ||
| 1402 | + "byteOffset" : 163332 | ||
| 1403 | + }, | ||
| 1404 | + { | ||
| 1405 | + "buffer" : 0, | ||
| 1406 | + "byteLength" : 6708, | ||
| 1407 | + "byteOffset" : 170040 | ||
| 1408 | + }, | ||
| 1409 | + { | ||
| 1410 | + "buffer" : 0, | ||
| 1411 | + "byteLength" : 4472, | ||
| 1412 | + "byteOffset" : 176748 | ||
| 1413 | + }, | ||
| 1414 | + { | ||
| 1415 | + "buffer" : 0, | ||
| 1416 | + "byteLength" : 5760, | ||
| 1417 | + "byteOffset" : 181220 | ||
| 1418 | + } | ||
| 1419 | + ], | ||
| 1420 | + "buffers" : [ | ||
| 1421 | + { | ||
| 1422 | + "byteLength" : 186980, | ||
| 1423 | + "uri" : "reflection.bin" | ||
| 1424 | + } | ||
| 1425 | + ] | ||
| 1426 | +} |
resources/game/texture-atlas-license.txt
0 → 100644
resources/game/texture-atlas.jpg
0 → 100644
476 KB
resources/po/en_GB.po
| @@ -175,6 +175,9 @@ msgstr "Radial Menu" | @@ -175,6 +175,9 @@ msgstr "Radial Menu" | ||
| 175 | msgid "DALI_DEMO_STR_TITLE_REFRACTION" | 175 | msgid "DALI_DEMO_STR_TITLE_REFRACTION" |
| 176 | msgstr "Refraction" | 176 | msgstr "Refraction" |
| 177 | 177 | ||
| 178 | +msgid "DALI_DEMO_STR_TITLE_REFLECTION" | ||
| 179 | +msgstr "Reflection" | ||
| 180 | + | ||
| 178 | msgid "DALI_DEMO_STR_TITLE_RENDERER_STENCIL" | 181 | msgid "DALI_DEMO_STR_TITLE_RENDERER_STENCIL" |
| 179 | msgstr "Renderer Stencil" | 182 | msgstr "Renderer Stencil" |
| 180 | 183 |
resources/po/en_US.po
| @@ -175,6 +175,9 @@ msgstr "Primitive Shapes" | @@ -175,6 +175,9 @@ msgstr "Primitive Shapes" | ||
| 175 | msgid "DALI_DEMO_STR_TITLE_RADIAL_MENU" | 175 | msgid "DALI_DEMO_STR_TITLE_RADIAL_MENU" |
| 176 | msgstr "Radial Menu" | 176 | msgstr "Radial Menu" |
| 177 | 177 | ||
| 178 | +msgid "DALI_DEMO_STR_TITLE_REFLECTION" | ||
| 179 | +msgstr "Reflection" | ||
| 180 | + | ||
| 178 | msgid "DALI_DEMO_STR_TITLE_REFRACTION" | 181 | msgid "DALI_DEMO_STR_TITLE_REFRACTION" |
| 179 | msgstr "Refraction" | 182 | msgstr "Refraction" |
| 180 | 183 |
shared/dali-demo-strings.h
| @@ -96,6 +96,7 @@ extern "C" | @@ -96,6 +96,7 @@ extern "C" | ||
| 96 | #define DALI_DEMO_STR_TITLE_PRIMITIVE_SHAPES dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_PRIMITIVE_SHAPES") | 96 | #define DALI_DEMO_STR_TITLE_PRIMITIVE_SHAPES dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_PRIMITIVE_SHAPES") |
| 97 | #define DALI_DEMO_STR_TITLE_PROGRESS_BAR dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_PROGRESS_BAR") | 97 | #define DALI_DEMO_STR_TITLE_PROGRESS_BAR dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_PROGRESS_BAR") |
| 98 | #define DALI_DEMO_STR_TITLE_PROPERTY_NOTIFICATION dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_PROPERTY_NOTIFICATION") | 98 | #define DALI_DEMO_STR_TITLE_PROPERTY_NOTIFICATION dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_PROPERTY_NOTIFICATION") |
| 99 | +#define DALI_DEMO_STR_TITLE_REFLECTION dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_REFLECTION") | ||
| 99 | #define DALI_DEMO_STR_TITLE_REFRACTION dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_REFRACTION") | 100 | #define DALI_DEMO_STR_TITLE_REFRACTION dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_REFRACTION") |
| 100 | #define DALI_DEMO_STR_TITLE_REMOTE_IMAGE dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_REMOTE_IMAGE") | 101 | #define DALI_DEMO_STR_TITLE_REMOTE_IMAGE dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_REMOTE_IMAGE") |
| 101 | #define DALI_DEMO_STR_TITLE_RENDERING_DRAW_LINE dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_RENDERING_DRAW_LINE") | 102 | #define DALI_DEMO_STR_TITLE_RENDERING_DRAW_LINE dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_RENDERING_DRAW_LINE") |
| @@ -195,6 +196,7 @@ extern "C" | @@ -195,6 +196,7 @@ extern "C" | ||
| 195 | #define DALI_DEMO_STR_TITLE_PRIMITIVE_SHAPES "Primitive Shapes" | 196 | #define DALI_DEMO_STR_TITLE_PRIMITIVE_SHAPES "Primitive Shapes" |
| 196 | #define DALI_DEMO_STR_TITLE_PROGRESS_BAR "Progress Bar" | 197 | #define DALI_DEMO_STR_TITLE_PROGRESS_BAR "Progress Bar" |
| 197 | #define DALI_DEMO_STR_TITLE_PROPERTY_NOTIFICATION "Property Notification" | 198 | #define DALI_DEMO_STR_TITLE_PROPERTY_NOTIFICATION "Property Notification" |
| 199 | +#define DALI_DEMO_STR_TITLE_REFLECTION "Reflection" | ||
| 198 | #define DALI_DEMO_STR_TITLE_REFRACTION "Refract Effect" | 200 | #define DALI_DEMO_STR_TITLE_REFRACTION "Refract Effect" |
| 199 | #define DALI_DEMO_STR_TITLE_REMOTE_IMAGE "Remote Image" | 201 | #define DALI_DEMO_STR_TITLE_REMOTE_IMAGE "Remote Image" |
| 200 | #define DALI_DEMO_STR_TITLE_RENDERING_DRAW_LINE "Draw Line" | 202 | #define DALI_DEMO_STR_TITLE_RENDERING_DRAW_LINE "Draw Line" |