[dali_2.3.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-scene3d / public-api / loader / utils.cpp
1 /*
2  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali-scene3d/public-api/loader/utils.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/public-api/animation/constraints.h>
23 #include <dali/public-api/common/vector-wrapper.h>
24 #include <stdarg.h>
25 #include <cstring>
26 #include <fstream>
27 #include <iostream>
28
29 namespace Dali::Scene3D::Loader
30 {
31 namespace
32 {
33 thread_local char sExceptionFlingerMessageBuffer[ExceptionFlinger::MESSAGE_BUFFER_SIZE]{};
34 }
35
36 StreamBuffer::StreamBuffer(char* buffer, size_t size) noexcept(true)
37 {
38   setp(buffer, buffer + size);
39 }
40
41 ExceptionFlinger::Impl::~Impl() noexcept(false)
42 {
43   throw DaliException(mLocation, GetMessageBuffer());
44 }
45
46 ExceptionFlinger::ExceptionFlinger(const char* location) noexcept(true)
47 : mImpl{location},
48   mStreamBuffer(GetMessageBuffer(), MESSAGE_BUFFER_SIZE - 1),
49   mStream(&mStreamBuffer)
50 {
51 }
52
53 ExceptionFlinger::~ExceptionFlinger() noexcept(false)
54 {
55   operator<<('\0');
56 }
57
58 char* ExceptionFlinger::GetMessageBuffer() noexcept(true)
59 {
60   return sExceptionFlingerMessageBuffer;
61 }
62
63 std::string FormatString(const char* format, ...)
64 {
65   va_list vl;
66   va_start(vl, format);
67   va_list vl2;
68   va_copy(vl2, vl);
69
70   std::string result;
71   int32_t     length = vsnprintf(nullptr, 0, format, vl);
72   va_end(vl);
73
74   if(length >= 0)
75   {
76     size_t sizeRequired = static_cast<size_t>(length);
77     ++sizeRequired;
78     std::string formatString(sizeRequired, '\0');
79     vsnprintf(&formatString[0], sizeRequired, format, vl2);
80     result = formatString;
81   }
82   va_end(vl2);
83   return result;
84 }
85
86 std::string LoadTextFile(const char* path, bool* fail)
87 {
88   std::ifstream inFile(path);
89   if(inFile)
90   {
91     std::istreambuf_iterator<char> eos;
92     std::istreambuf_iterator<char> i(inFile.rdbuf());
93     return std::string(i, eos);
94   }
95   else if(fail)
96   {
97     *fail = true;
98   }
99   return std::string();
100 }
101
102 Geometry MakeTexturedQuadGeometry(TexturedQuadOptions::Type options)
103 {
104   Property::Map properties;
105   properties.Insert("aPosition", Property::VECTOR3);
106   properties.Insert("aTexCoord", Property::VECTOR2);
107
108   std::vector<uint8_t> bytes;
109   size_t               stride   = 0;
110   size_t               uvOffset = 0;
111   struct
112   {
113     Vector3 aPosition;
114     Vector2 aTexCoord;
115   } vertices[] = {
116     {Vector3(-0.5f, 0.5f, 0.0f), Vector2(0.0f, .0f)},
117     {Vector3(0.5f, 0.5f, 0.0f), Vector2(1.0f, .0f)},
118     {Vector3(-0.5f, -0.5f, 0.0f), Vector2(0.0f, 1.0f)},
119     {Vector3(0.5f, -0.5f, 0.0f), Vector2(1.0f, 1.0f)}};
120
121   bytes.resize(sizeof(vertices));
122   stride   = sizeof(vertices[0]);
123   uvOffset = reinterpret_cast<const uint8_t*>(&vertices[0].aTexCoord) - reinterpret_cast<const uint8_t*>(&vertices[0]);
124
125   std::memcpy(bytes.data(), vertices, sizeof(vertices));
126
127   if(MaskMatch(options, TexturedQuadOptions::FLIP_VERTICAL))
128   {
129     Vector2* uv = reinterpret_cast<Vector2*>(reinterpret_cast<uint8_t*>(bytes.data()) + uvOffset);
130     for(int i = 0; i < 4; ++i)
131     {
132       uv->y = 1.0f - uv->y;
133       uv    = reinterpret_cast<Vector2*>(reinterpret_cast<uint8_t*>(uv) + stride);
134     }
135   }
136
137   VertexBuffer vertexBuffer = VertexBuffer::New(properties);
138   vertexBuffer.SetData(bytes.data(), bytes.size() / stride);
139
140   Geometry geometry = Geometry::New();
141   geometry.AddVertexBuffer(vertexBuffer);
142   geometry.SetType(Geometry::TRIANGLE_STRIP);
143   return geometry;
144 }
145
146 void ToUnixFileSeparators(std::string& path)
147 {
148   std::replace(path.begin(), path.end(), '\\', '/');
149 }
150
151 } // namespace Dali::Scene3D::Loader