[dali_2.1.32] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-scene3d / public-api / loader / utils.cpp
1 /*
2  * Copyright (c) 2022 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 // INTERNAL
19 #include "dali-scene3d/public-api/loader/utils.h"
20
21 // EXTERNAL
22 #include <stdarg.h>
23 #include <cstring>
24 #include <fstream>
25 #include <iostream>
26 #include "dali/public-api/animation/constraints.h"
27 #include "dali/public-api/common/vector-wrapper.h"
28
29 namespace Dali
30 {
31 namespace Scene3D
32 {
33 namespace Loader
34 {
35 namespace
36 {
37 thread_local char sExceptionFlingerMessageBuffer[ExceptionFlinger::MESSAGE_BUFFER_SIZE]{};
38 }
39
40 StreamBuffer::StreamBuffer(char* buffer, size_t size) noexcept(true)
41 {
42   setp(buffer, buffer + size);
43 }
44
45 ExceptionFlinger::Impl::~Impl() noexcept(false)
46 {
47   throw DaliException(mLocation, GetMessageBuffer());
48 }
49
50 ExceptionFlinger::ExceptionFlinger(const char* location) noexcept(true)
51 : mImpl{location},
52   mStreamBuffer(GetMessageBuffer(), MESSAGE_BUFFER_SIZE - 1),
53   mStream(&mStreamBuffer)
54 {
55 }
56
57 ExceptionFlinger::~ExceptionFlinger() noexcept(false)
58 {
59   operator<<('\0');
60 }
61
62 char* ExceptionFlinger::GetMessageBuffer() noexcept(true)
63 {
64   return sExceptionFlingerMessageBuffer;
65 }
66
67 std::string FormatString(const char* format, ...)
68 {
69   va_list vl;
70   va_start(vl, format);
71   va_list vl2;
72   va_copy(vl2, vl);
73
74   size_t sizeRequired = vsnprintf(nullptr, 0, format, vl);
75   va_end(vl);
76
77   ++sizeRequired;
78   std::string result(sizeRequired, '\0');
79   vsnprintf(&result[0], sizeRequired, format, vl2);
80   va_end(vl2);
81
82   return result;
83 }
84
85 std::string LoadTextFile(const char* path, bool* fail)
86 {
87   std::ifstream inFile(path);
88   if(inFile)
89   {
90     std::istreambuf_iterator<char> eos;
91     std::istreambuf_iterator<char> i(inFile.rdbuf());
92     return std::string(i, eos);
93   }
94   else if(fail)
95   {
96     *fail = true;
97   }
98   return std::string();
99 }
100
101 Geometry MakeTexturedQuadGeometry(TexturedQuadOptions::Type options)
102 {
103   Property::Map properties;
104   properties.Insert("aPosition", Property::VECTOR3);
105   properties.Insert("aTexCoord", Property::VECTOR2);
106
107   std::vector<uint8_t> bytes;
108   size_t               stride   = 0;
109   size_t               uvOffset = 0;
110   struct
111   {
112     Vector3 aPosition;
113     Vector2 aTexCoord;
114   } vertices[] = {
115     {Vector3(-0.5f, 0.5f, 0.0f), Vector2(0.0f, .0f)},
116     {Vector3(0.5f, 0.5f, 0.0f), Vector2(1.0f, .0f)},
117     {Vector3(-0.5f, -0.5f, 0.0f), Vector2(0.0f, 1.0f)},
118     {Vector3(0.5f, -0.5f, 0.0f), Vector2(1.0f, 1.0f)}};
119
120   bytes.resize(sizeof(vertices));
121   stride   = sizeof(vertices[0]);
122   uvOffset = reinterpret_cast<const uint8_t*>(&vertices[0].aTexCoord) - reinterpret_cast<const uint8_t*>(&vertices[0]);
123
124   std::memcpy(bytes.data(), vertices, sizeof(vertices));
125
126   if(MaskMatch(options, TexturedQuadOptions::FLIP_VERTICAL))
127   {
128     Vector2* uv = reinterpret_cast<Vector2*>(reinterpret_cast<uint8_t*>(bytes.data()) + uvOffset);
129     for(int i = 0; i < 4; ++i)
130     {
131       uv->y = 1.0f - uv->y;
132       uv    = reinterpret_cast<Vector2*>(reinterpret_cast<uint8_t*>(uv) + stride);
133     }
134   }
135
136   VertexBuffer vertexBuffer = VertexBuffer::New(properties);
137   vertexBuffer.SetData(bytes.data(), bytes.size() / stride);
138
139   Geometry geometry = Geometry::New();
140   geometry.AddVertexBuffer(vertexBuffer);
141   geometry.SetType(Geometry::TRIANGLE_STRIP);
142   return geometry;
143 }
144
145 void ToUnixFileSeparators(std::string& path)
146 {
147   std::replace(path.begin(), path.end(), '\\', '/');
148 }
149
150 } // namespace Loader
151 } // namespace Scene3D
152 } // namespace Dali