mirror of
https://github.com/lighttransport/tinyusdz.git
synced 2026-01-18 01:11:17 +01:00
Refactor codes.
Adding some Material/Shader/Texture related codes. Add Roboto font for GUI.
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
* primvars:st : usually vec2f[] varying
|
||||
* primvars:st:indices : usually int[] varying
|
||||
* velocities : usually vec3f[]
|
||||
* texcoord: usually `texCoord2f[]` (Texcoord bound to Mesh prim)
|
||||
|
||||
|
||||
### Mesh property
|
||||
@@ -58,6 +59,12 @@
|
||||
* inputs:fallback : fallback color(Usually vec4f)
|
||||
* inputs:file : @filename@
|
||||
|
||||
### Texcoord reader
|
||||
|
||||
`UsdPrimvarReader_float2`
|
||||
|
||||
* inputs:varname(token) : Name of UV coordinate primvar in Mesh primitive.
|
||||
* outputs:<name>(float2) : Output connection name. Usually `outputs:result`
|
||||
|
||||
## TODO
|
||||
|
||||
|
||||
@@ -5,6 +5,11 @@
|
||||
Seems USDA(ASCII) is not supported(yet?).
|
||||
USDC only.
|
||||
|
||||
## Mesh
|
||||
|
||||
attribute with `texCoord2f[]` type: Can be used as explicit texture coordinate
|
||||
attribute with `float2[]` type: Specify texture UV attribute from TexCoordReader(UsdPrimvarReader) with `inputs:varname` attribute.
|
||||
|
||||
## Material/Shader
|
||||
|
||||
It looks USDZ tool(e.g. ARKit) only supports UsdPreviewSurface
|
||||
|
||||
3
examples/common/LICENSE.roboto_mono_embed.md
Normal file
3
examples/common/LICENSE.roboto_mono_embed.md
Normal file
@@ -0,0 +1,3 @@
|
||||
Roboto icons : Apache 2.0 License.
|
||||
Roboto : Apache 2.0 License.
|
||||
|
||||
1676
examples/common/roboto_mono_embed.inc.h
Normal file
1676
examples/common/roboto_mono_embed.inc.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -24,6 +24,8 @@
|
||||
#include "tinyusdz.hh"
|
||||
#include "trackball.h"
|
||||
|
||||
#include "roboto_mono_embed.inc.h"
|
||||
|
||||
// sdlviewer
|
||||
#include "gui.hh"
|
||||
|
||||
@@ -53,7 +55,7 @@ struct GUIContext {
|
||||
bool ctrl_pressed = false;
|
||||
bool tab_pressed = false;
|
||||
|
||||
float yaw = 90.0f; // for Z up scene
|
||||
float yaw = 90.0f; // for Z up scene
|
||||
float pitch = 0.0f;
|
||||
float roll = 0.0f;
|
||||
|
||||
@@ -361,6 +363,19 @@ int main(int argc, char** argv) {
|
||||
|
||||
ImGui::CreateContext();
|
||||
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImFontConfig roboto_config;
|
||||
strcpy(roboto_config.Name, "Roboto");
|
||||
|
||||
float font_size = 18.0f;
|
||||
io.Fonts->AddFontFromMemoryCompressedTTF(roboto_mono_compressed_data,
|
||||
roboto_mono_compressed_size,
|
||||
font_size, &roboto_config);
|
||||
}
|
||||
|
||||
|
||||
ImGuiSDL::Initialize(renderer, 1600, 800);
|
||||
// ImGui_ImplGlfw_InitForOpenGL(window, true);
|
||||
// ImGui_ImplOpenGL2_Init();
|
||||
@@ -457,7 +472,7 @@ int main(int argc, char** argv) {
|
||||
bool update = false;
|
||||
|
||||
bool update_display = false;
|
||||
|
||||
|
||||
if (example::ImGuiComboUI("aov", aov_name, aov_list)) {
|
||||
gui_ctx.aov_mode = aov_list[aov_name];
|
||||
update_display = true;
|
||||
|
||||
28
experimental/serialize/Makefile
Normal file
28
experimental/serialize/Makefile
Normal file
@@ -0,0 +1,28 @@
|
||||
CXX=clang++
|
||||
CXXFLAGS=-std=c++11 -I../../src -fsanitize=address -Weverything -Wall -Wno-padded -Wno-c++98-compat -Wno-c++98-compat-pedantic
|
||||
LINKFLAGS=-fsanitize=address
|
||||
|
||||
all: serializer
|
||||
|
||||
serializer: tinyusdz.o serializer.o integerCoding.o lz4-compression.o lz4.o
|
||||
$(CXX) $(LINKFLAGS) -o serializer $^
|
||||
|
||||
serializer.o: ../../src/tinyusdz.cc ../../src/tinyusdz.hh serializer.cc
|
||||
$(CXX) $(CXXFLAGS) -c -o serializer.o serializer.cc
|
||||
|
||||
tinyusdz.o: ../../src/tinyusdz.cc ../../src/tinyusdz.hh
|
||||
$(CXX) $(CXXFLAGS) -c -o tinyusdz.o ../../src/tinyusdz.cc
|
||||
|
||||
integerCoding.o: ../../src/integerCoding.cpp
|
||||
$(CXX) $(CXXFLAGS) -c -o integerCoding.o ../../src/integerCoding.cpp
|
||||
|
||||
lz4-compression.o: ../../src/lz4-compression.cc
|
||||
$(CXX) $(CXXFLAGS) -c -o lz4-compression.o ../../src/lz4-compression.cc
|
||||
|
||||
lz4.o: ../../src/pxrLZ4/lz4.cpp
|
||||
$(CXX) $(CXXFLAGS) -c -o lz4.o ../../src/pxrLZ4/lz4.cpp
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
clean:
|
||||
rm -rf serializer lz4.o serializer.o integerCoding.o tinyusdz.o lz4-compression.o
|
||||
6
experimental/serialize/README.md
Normal file
6
experimental/serialize/README.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# Experimental USDC, USDZ serializer
|
||||
|
||||
## Status
|
||||
|
||||
Nothing yet
|
||||
|
||||
20
experimental/serialize/serializer.cc
Normal file
20
experimental/serialize/serializer.cc
Normal file
@@ -0,0 +1,20 @@
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "usdc_serializer.hh"
|
||||
|
||||
namespace tinyusdz {
|
||||
|
||||
bool WriteUSDCHeader(std::vector<uint8_t> *output) {
|
||||
// header = 88bytes
|
||||
|
||||
}
|
||||
|
||||
|
||||
} // namespace tinyusdz
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
};
|
||||
34
experimental/serialize/usdc_serializer.hh
Normal file
34
experimental/serialize/usdc_serializer.hh
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Syoyo Fujita
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <tinyusdz.hh>
|
||||
|
||||
namespace tinyusdz {
|
||||
|
||||
bool SerializeUSDCToMemory(std::vector<uint8_t> *output);
|
||||
|
||||
|
||||
} // namespace tinyusdz
|
||||
668
src/tinyusdz.cc
668
src/tinyusdz.cc
@@ -39,8 +39,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
// local debug flag
|
||||
#define TINYUSDZ_LOCAL_DEBUG_PRINT (1)
|
||||
// local debug flag(now defined in tinyusdz.hh)
|
||||
//#define TINYUSDZ_LOCAL_DEBUG_PRINT (1)
|
||||
|
||||
#include "integerCoding.h"
|
||||
#include "lz4-compression.hh"
|
||||
@@ -828,12 +828,32 @@ class Parser {
|
||||
|
||||
bool _BuildLiveFieldSets();
|
||||
|
||||
///
|
||||
/// Parse node's attribute from FieldValuePairVector.
|
||||
///
|
||||
bool _ParseAttribute(const FieldValuePairVector &fvs, PrimAttrib *attr,
|
||||
const std::string &prop_name);
|
||||
|
||||
bool _ReconstructGeomMesh(const Node &node,
|
||||
const FieldValuePairVector &fields,
|
||||
const std::unordered_map<uint32_t, uint32_t>
|
||||
&path_index_to_spec_index_map,
|
||||
GeomMesh *mesh);
|
||||
|
||||
bool _ReconstructMaterial(const Node &node,
|
||||
const FieldValuePairVector &fields,
|
||||
const std::unordered_map<uint32_t, uint32_t>
|
||||
&path_index_to_spec_index_map,
|
||||
Material *material);
|
||||
|
||||
///
|
||||
/// NOTE: Currently we only support UsdPreviewSurface
|
||||
///
|
||||
bool _ReconstructShader(const Node &node, const FieldValuePairVector &fields,
|
||||
const std::unordered_map<uint32_t, uint32_t>
|
||||
&path_index_to_spec_index_map,
|
||||
PreviewSurface *shader);
|
||||
|
||||
bool _ReconstructSceneRecursively(int parent_id, int level,
|
||||
const std::unordered_map<uint32_t, uint32_t>
|
||||
&path_index_to_spec_index_map,
|
||||
@@ -1725,7 +1745,6 @@ bool Parser::_UnpackValueRep(const ValueRep &rep, Value *value) {
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
} else if (ty.id == VALUE_TYPE_FLOAT) {
|
||||
assert((!rep.IsCompressed()) && (!rep.IsArray()));
|
||||
float f;
|
||||
@@ -2346,7 +2365,6 @@ bool Parser::_UnpackValueRep(const ValueRep &rep, Value *value) {
|
||||
<< "\n";
|
||||
#endif
|
||||
value->SetVec3d(v);
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -2406,11 +2424,10 @@ bool Parser::_UnpackValueRep(const ValueRep &rep, Value *value) {
|
||||
}
|
||||
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cout << "value.quatf = " << v[0] << ", " << v[1] << ", " << v[2] << ", " << v[3]
|
||||
<< "\n";
|
||||
std::cout << "value.quatf = " << v[0] << ", " << v[1] << ", " << v[2]
|
||||
<< ", " << v[3] << "\n";
|
||||
#endif
|
||||
value->SetQuatf(v);
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -2480,7 +2497,8 @@ bool Parser::_UnpackValueRep(const ValueRep &rep, Value *value) {
|
||||
} else {
|
||||
// TODO(syoyo)
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cerr << "[" << __LINE__ << "] TODO: " << GetValueTypeRepr(rep.GetType()) << "\n";
|
||||
std::cerr << "[" << __LINE__
|
||||
<< "] TODO: " << GetValueTypeRepr(rep.GetType()) << "\n";
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
@@ -3208,14 +3226,185 @@ bool Parser::_BuildLiveFieldSets() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Parser::_ParseAttribute(const FieldValuePairVector &fvs, PrimAttrib *attr,
|
||||
const std::string &prop_name) {
|
||||
bool success = false;
|
||||
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cout << "fvs.size = " << fvs.size() << "\n";
|
||||
#endif
|
||||
|
||||
|
||||
bool has_connection{false};
|
||||
|
||||
Variability variability{VariabilityVarying};
|
||||
bool facevarying{false};
|
||||
|
||||
//
|
||||
// Parse properties
|
||||
//
|
||||
for (const auto &fv : fvs) {
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cout << "=== fvs.first " << fv.first
|
||||
<< ", second: " << fv.second.GetTypeName() << "\n";
|
||||
#endif
|
||||
if ((fv.first == "typeName") && (fv.second.GetTypeName() == "Token")) {
|
||||
attr->type_name = fv.second.GetToken();
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cout << "aaa: typeName: " << attr->type_name << "\n";
|
||||
#endif
|
||||
|
||||
} else if (fv.first == "connectionPaths") {
|
||||
// e.g. connection to texture file.
|
||||
const ListOp<Path> paths = fv.second.GetPathListOp();
|
||||
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
paths.Print();
|
||||
#endif
|
||||
|
||||
// Currently we only support single explicit path.
|
||||
if ((paths.GetExplicitItems().size() == 1)) {
|
||||
const Path &path = paths.GetExplicitItems()[0];
|
||||
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cout << "full path: " << path.full_path_name() << "\n";
|
||||
std::cout << "local path: " << path.local_path_name() << "\n";
|
||||
#endif
|
||||
|
||||
attr->path = path;
|
||||
attr->basic_type = "path";
|
||||
|
||||
has_connection = true;
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else if ((fv.first == "variablity") &&
|
||||
(fv.second.GetTypeName() == "Variability")) {
|
||||
variability = fv.second.GetVariability();
|
||||
} else if ((fv.first == "interpolation") &&
|
||||
(fv.second.GetTypeName() == "Token")) {
|
||||
if (fv.second.GetToken() == "faceVarying") {
|
||||
facevarying = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
attr->facevarying = facevarying;
|
||||
attr->variability = variability;
|
||||
|
||||
//
|
||||
// Decode value(stored in "default" field)
|
||||
//
|
||||
for (const auto &fv : fvs) {
|
||||
if (fv.first == "default") {
|
||||
attr->name = prop_name;
|
||||
attr->basic_type = std::string();
|
||||
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cout << "fv.second.GetTypeName = " << fv.second.GetTypeName()
|
||||
<< "\n";
|
||||
#endif
|
||||
if (fv.second.GetTypeName() == "Float") {
|
||||
attr->floatVal = fv.second.GetFloat();
|
||||
attr->basic_type = "float";
|
||||
success = true;
|
||||
|
||||
} else if (fv.second.GetTypeName() == "Bool") {
|
||||
if (!fv.second.GetBool(&attr->boolVal)) {
|
||||
_err += "Failed to decode Int data";
|
||||
return false;
|
||||
}
|
||||
|
||||
attr->basic_type = "bool";
|
||||
success = true;
|
||||
|
||||
} else if (fv.second.GetTypeName() == "Int") {
|
||||
if (!fv.second.GetInt(&attr->intVal)) {
|
||||
_err += "Failed to decode Int data";
|
||||
return false;
|
||||
}
|
||||
|
||||
attr->basic_type = "int";
|
||||
success = true;
|
||||
} else if (fv.second.GetTypeName() == "Vec3f") {
|
||||
attr->buffer.Set(BufferData::BUFFER_DATA_TYPE_FLOAT, 3,
|
||||
/* stride */ sizeof(float), fv.second.GetData());
|
||||
// attr->variability = variability;
|
||||
// attr->facevarying = facevarying;
|
||||
success = true;
|
||||
|
||||
} else if (fv.second.GetTypeName() == "FloatArray") {
|
||||
attr->buffer.Set(BufferData::BUFFER_DATA_TYPE_FLOAT, 1,
|
||||
/* stride */ sizeof(float), fv.second.GetData());
|
||||
attr->variability = variability;
|
||||
attr->facevarying = facevarying;
|
||||
success = true;
|
||||
} else if (fv.second.GetTypeName() == "Vec2fArray") {
|
||||
attr->buffer.Set(BufferData::BUFFER_DATA_TYPE_FLOAT, 2,
|
||||
/* stride */ sizeof(float) * 2, fv.second.GetData());
|
||||
attr->variability = variability;
|
||||
attr->facevarying = facevarying;
|
||||
success = true;
|
||||
} else if (fv.second.GetTypeName() == "Vec3fArray") {
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cout << "fv.second.data.size = " << fv.second.GetData().size()
|
||||
<< "\n";
|
||||
#endif
|
||||
attr->buffer.Set(BufferData::BUFFER_DATA_TYPE_FLOAT, 3,
|
||||
/* stride */ sizeof(float) * 3, fv.second.GetData());
|
||||
attr->variability = variability;
|
||||
attr->facevarying = facevarying;
|
||||
success = true;
|
||||
} else if (fv.second.GetTypeName() == "Vec4fArray") {
|
||||
attr->buffer.Set(BufferData::BUFFER_DATA_TYPE_FLOAT, 4,
|
||||
/* stride */ sizeof(float) * 4, fv.second.GetData());
|
||||
attr->variability = variability;
|
||||
attr->facevarying = facevarying;
|
||||
success = true;
|
||||
} else if (fv.second.GetTypeName() == "IntArray") {
|
||||
attr->buffer.Set(BufferData::BUFFER_DATA_TYPE_INT, 1,
|
||||
/* stride */ sizeof(int32_t), fv.second.GetData());
|
||||
attr->variability = variability;
|
||||
attr->facevarying = facevarying;
|
||||
success = true;
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cout << "IntArray"
|
||||
<< "\n";
|
||||
|
||||
const int32_t *ptr =
|
||||
reinterpret_cast<const int32_t *>(attr->buffer.data.data());
|
||||
for (size_t i = 0; i < attr->buffer.GetNumElements(); i++) {
|
||||
std::cout << "[" << i << "] = " << ptr[i] << "\n";
|
||||
}
|
||||
#endif
|
||||
} else if (fv.second.GetTypeName() == "Token") {
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cout << "bbb: token: " << fv.second.GetToken() << "\n";
|
||||
#endif
|
||||
attr->stringVal = fv.second.GetToken();
|
||||
attr->basic_type = "string";
|
||||
// attr->variability = variability;
|
||||
// attr->facevarying = facevarying;
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!success && has_connection) {
|
||||
// Attribute has a connection(has a path and no `default` field)
|
||||
success = true;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool Parser::_ReconstructGeomMesh(
|
||||
const Node &node, const FieldValuePairVector &fields,
|
||||
const std::unordered_map<uint32_t, uint32_t> &path_index_to_spec_index_map,
|
||||
GeomMesh *mesh) {
|
||||
(void)mesh;
|
||||
|
||||
bool has_position{false};
|
||||
|
||||
#if 0
|
||||
// TODO(syoyo): Move to Parser's method.
|
||||
auto ParseGeomMeshAttribute = [](const FieldValuePairVector &fvs,
|
||||
PrimAttrib *attr,
|
||||
const std::string &prop_name) -> bool {
|
||||
@@ -3225,21 +3414,19 @@ bool Parser::_ReconstructGeomMesh(
|
||||
std::cout << "fvs.size = " << fvs.size() << "\n";
|
||||
#endif
|
||||
|
||||
std::string type_name;
|
||||
Variability variability{VariabilityVarying};
|
||||
bool facevarying{false};
|
||||
|
||||
for (const auto &fv : fvs) {
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cout << " fvs.first " << fv.first << "\n";
|
||||
std::cout << " fvs.first " << fv.first << ", second: " << fv.second.GetTypeName() << "\n";
|
||||
#endif
|
||||
if ((fv.first == "typeName") && (fv.second.GetTypeName() == "Token")) {
|
||||
type_name = fv.second.GetToken();
|
||||
attr->type_name = fv.second.GetToken();
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cout << "aaa: typeName: " << type_name << "\n";
|
||||
std::cout << "aaa: typeName: " << attr->type_name << "\n";
|
||||
#endif
|
||||
|
||||
(void)attr;
|
||||
} else if ((fv.first == "variablity") &&
|
||||
(fv.second.GetTypeName() == "Variability")) {
|
||||
variability = fv.second.GetVariability();
|
||||
@@ -3306,7 +3493,7 @@ bool Parser::_ReconstructGeomMesh(
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cout << "bbb: token: " << fv.second.GetToken() << "\n";
|
||||
#endif
|
||||
attr->tokenString = fv.second.GetToken();
|
||||
attr->stringVal = fv.second.GetToken();
|
||||
attr->variability = variability;
|
||||
attr->facevarying = facevarying;
|
||||
success = true;
|
||||
@@ -3316,6 +3503,9 @@ bool Parser::_ReconstructGeomMesh(
|
||||
|
||||
return success;
|
||||
};
|
||||
#endif
|
||||
|
||||
bool has_position{false};
|
||||
|
||||
for (const auto &fv : fields) {
|
||||
if (fv.first == "properties") {
|
||||
@@ -3332,10 +3522,12 @@ bool Parser::_ReconstructGeomMesh(
|
||||
}
|
||||
}
|
||||
|
||||
// Disable has_position check for a while, since Mesh may not have "points", but "position"
|
||||
|
||||
//if (!has_position) {
|
||||
// _err += "No `position` field exist for Mesh node: " + node.GetLocalPath() +
|
||||
// Disable has_position check for a while, since Mesh may not have "points",
|
||||
// but "position"
|
||||
|
||||
// if (!has_position) {
|
||||
// _err += "No `position` field exist for Mesh node: " + node.GetLocalPath()
|
||||
// +
|
||||
// ".\n";
|
||||
// return false;
|
||||
//}
|
||||
@@ -3390,7 +3582,7 @@ bool Parser::_ReconstructGeomMesh(
|
||||
std::string prop_name = path.GetPropPart();
|
||||
|
||||
PrimAttrib attr;
|
||||
bool ret = ParseGeomMeshAttribute(child_fields, &attr, prop_name);
|
||||
bool ret = _ParseAttribute(child_fields, &attr, prop_name);
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cout << "prop: " << prop_name << ", ret = " << ret << "\n";
|
||||
#endif
|
||||
@@ -3405,20 +3597,43 @@ bool Parser::_ReconstructGeomMesh(
|
||||
(attr.buffer.GetNumCoords() == 3)) {
|
||||
mesh->points = std::move(attr);
|
||||
}
|
||||
} else if (prop_name == "doubleSided") {
|
||||
if (attr.basic_type == "bool") {
|
||||
mesh->doubleSided = attr.boolVal;
|
||||
}
|
||||
} else if (prop_name == "extent") {
|
||||
// vec3f[2]
|
||||
if ((attr.buffer.GetDataType() ==
|
||||
BufferData::BUFFER_DATA_TYPE_FLOAT) &&
|
||||
(attr.buffer.GetNumElements() == 2) &&
|
||||
(attr.buffer.GetNumCoords() == 3)) {
|
||||
|
||||
std::vector<float> buf = attr.buffer.GetAsVec3fArray();
|
||||
mesh->extent.lower[0] = buf[0];
|
||||
mesh->extent.lower[1] = buf[1];
|
||||
mesh->extent.lower[2] = buf[2];
|
||||
|
||||
mesh->extent.upper[0] = buf[3];
|
||||
mesh->extent.upper[1] = buf[4];
|
||||
mesh->extent.upper[2] = buf[5];
|
||||
}
|
||||
} else if (prop_name == "normals") {
|
||||
if ((attr.buffer.GetDataType() ==
|
||||
BufferData::BUFFER_DATA_TYPE_FLOAT) &&
|
||||
(attr.buffer.GetNumCoords() == 3)) {
|
||||
mesh->normals = std::move(attr);
|
||||
}
|
||||
} else if (prop_name == "primvars:UVMap") {
|
||||
// TODO(syoyo): Write PrimVar parser
|
||||
|
||||
} else if ((prop_name == "primvars:UVMap") &&
|
||||
(attr.type_name == "texCoord2f[]")) {
|
||||
// Explicit UV coord attribute.
|
||||
// TODO(syoyo): Write PrimVar parser
|
||||
|
||||
// Currently we only support vec2f for uv coords.
|
||||
if ((attr.buffer.GetDataType() == BufferData::BUFFER_DATA_TYPE_FLOAT) &&
|
||||
if ((attr.buffer.GetDataType() ==
|
||||
BufferData::BUFFER_DATA_TYPE_FLOAT) &&
|
||||
(attr.buffer.GetNumCoords() == 2)) {
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cout << "got UVCoords\n";
|
||||
std::cout << "got explicit UVCoords!\n";
|
||||
#endif
|
||||
mesh->st.buffer = attr.buffer;
|
||||
mesh->st.variability = attr.variability;
|
||||
@@ -3480,22 +3695,376 @@ bool Parser::_ReconstructGeomMesh(
|
||||
}
|
||||
} else if (prop_name == "subdivisionScheme") {
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cout << "subdivisionScheme:" << attr.tokenString << "\n";
|
||||
std::cout << "subdivisionScheme:" << attr.stringVal << "\n";
|
||||
#endif
|
||||
if (attr.tokenString.size()) {
|
||||
if ((attr.tokenString.compare("none") == 0)) {
|
||||
if (attr.stringVal.size()) {
|
||||
if ((attr.stringVal.compare("none") == 0)) {
|
||||
mesh->subdivisionScheme = SubdivisionSchemeNone;
|
||||
} else if (attr.tokenString.compare("catmullClark") == 0) {
|
||||
} else if (attr.stringVal.compare("catmullClark") == 0) {
|
||||
mesh->subdivisionScheme = SubdivisionSchemeCatmullClark;
|
||||
} else if (attr.tokenString.compare("bilinear") == 0) {
|
||||
} else if (attr.stringVal.compare("bilinear") == 0) {
|
||||
mesh->subdivisionScheme = SubdivisionSchemeBilinear;
|
||||
} else if (attr.tokenString.compare("loop") == 0) {
|
||||
} else if (attr.stringVal.compare("loop") == 0) {
|
||||
mesh->subdivisionScheme = SubdivisionSchemeLoop;
|
||||
} else {
|
||||
_err += "Unknown subdivision scheme: " + attr.tokenString + "\n";
|
||||
_err += "Unknown subdivision scheme: " + attr.stringVal + "\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Assume Primvar.
|
||||
if (mesh->attrs.count(prop_name)) {
|
||||
_err += "Duplicated property name found: " + prop_name + "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cout << "add [" << prop_name << "] to generic attrs\n";
|
||||
#endif
|
||||
|
||||
mesh->attrs[prop_name] = std::move(attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Parser::_ReconstructMaterial(
|
||||
const Node &node, const FieldValuePairVector &fields,
|
||||
const std::unordered_map<uint32_t, uint32_t> &path_index_to_spec_index_map,
|
||||
Material *material) {
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cout << "Parse mateiral\n";
|
||||
#endif
|
||||
|
||||
for (const auto &fv : fields) {
|
||||
if (fv.first == "properties") {
|
||||
if (fv.second.GetTypeName() != "TokenArray") {
|
||||
_err += "`properties` attribute must be TokenArray type\n";
|
||||
return false;
|
||||
}
|
||||
assert(fv.second.IsArray());
|
||||
|
||||
for (size_t i = 0; i < fv.second.GetStringArray().size(); i++) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// NOTE: Currently we assume one deeper node has Material's attribute
|
||||
//
|
||||
for (size_t i = 0; i < node.GetChildren().size(); i++) {
|
||||
int child_index = int(node.GetChildren()[i]);
|
||||
if ((child_index < 0) || (child_index >= int(_nodes.size()))) {
|
||||
_err += "Invalid child node id: " + std::to_string(child_index) +
|
||||
". Must be in range [0, " + std::to_string(_nodes.size()) + ")\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
// const Node &child_node = _nodes[size_t(child_index)];
|
||||
|
||||
if (!path_index_to_spec_index_map.count(uint32_t(child_index))) {
|
||||
// No specifier assigned to this child node.
|
||||
_err += "No specifier found for node id: " + std::to_string(child_index) +
|
||||
"\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t spec_index =
|
||||
path_index_to_spec_index_map.at(uint32_t(child_index));
|
||||
if (spec_index >= _specs.size()) {
|
||||
_err += "Invalid specifier id: " + std::to_string(spec_index) +
|
||||
". Must be in range [0, " + std::to_string(_specs.size()) + ")\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
const Spec &spec = _specs[spec_index];
|
||||
|
||||
Path path = GetPath(spec.path_index);
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cout << "Path prim part: " << path.GetPrimPart()
|
||||
<< ", prop part: " << path.GetPropPart()
|
||||
<< ", spec_index = " << spec_index << "\n";
|
||||
#endif
|
||||
|
||||
if (!_live_fieldsets.count(spec.fieldset_index)) {
|
||||
_err += "FieldSet id: " + std::to_string(spec.fieldset_index.value) +
|
||||
" must exist in live fieldsets.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
const FieldValuePairVector &child_fields =
|
||||
_live_fieldsets.at(spec.fieldset_index);
|
||||
|
||||
{
|
||||
std::string prop_name = path.GetPropPart();
|
||||
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cout << "prop: " << prop_name << "\n";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Parser::_ReconstructShader(
|
||||
const Node &node, const FieldValuePairVector &fields,
|
||||
const std::unordered_map<uint32_t, uint32_t> &path_index_to_spec_index_map,
|
||||
PreviewSurface *shader) {
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cout << "Parse shader\n";
|
||||
#endif
|
||||
|
||||
for (const auto &fv : fields) {
|
||||
if (fv.first == "properties") {
|
||||
if (fv.second.GetTypeName() != "TokenArray") {
|
||||
_err += "`properties` attribute must be TokenArray type\n";
|
||||
return false;
|
||||
}
|
||||
assert(fv.second.IsArray());
|
||||
|
||||
for (size_t i = 0; i < fv.second.GetStringArray().size(); i++) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
auto ParseAttribute = [](const FieldValuePairVector &fvs, PrimAttrib *attr,
|
||||
const std::string &prop_name) -> bool {
|
||||
bool success = false;
|
||||
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cout << "fvs.size = " << fvs.size() << "\n";
|
||||
#endif
|
||||
|
||||
std::string type_name;
|
||||
Variability variability{VariabilityVarying};
|
||||
bool facevarying{false};
|
||||
|
||||
for (const auto &fv : fvs) {
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cout << " fvs.first " << fv.first
|
||||
<< ", second: " << fv.second.GetTypeName() << "\n";
|
||||
#endif
|
||||
if ((fv.first == "typeName") && (fv.second.GetTypeName() == "Token")) {
|
||||
type_name = fv.second.GetToken();
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cout << "aaa: typeName: " << type_name << "\n";
|
||||
#endif
|
||||
|
||||
(void)attr;
|
||||
} else if (fv.first == "connectionPaths") {
|
||||
// e.g. connection to texture file.
|
||||
const ListOp<Path> paths = fv.second.GetPathListOp();
|
||||
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
paths.Print();
|
||||
#endif
|
||||
|
||||
// Currently we only support single explicit path.
|
||||
if ((paths.GetExplicitItems().size() == 1)) {
|
||||
const Path &path = paths.GetExplicitItems()[0];
|
||||
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cout << "full path: " << path.full_path_name() << "\n";
|
||||
std::cout << "local path: " << path.local_path_name() << "\n";
|
||||
#endif
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else if ((fv.first == "variablity") &&
|
||||
(fv.second.GetTypeName() == "Variability")) {
|
||||
variability = fv.second.GetVariability();
|
||||
} else if ((fv.first == "interpolation") &&
|
||||
(fv.second.GetTypeName() == "Token")) {
|
||||
if (fv.second.GetToken() == "faceVarying") {
|
||||
facevarying = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Decode value(stored in "default" field)
|
||||
for (const auto &fv : fvs) {
|
||||
if (fv.first == "default") {
|
||||
attr->name = prop_name;
|
||||
attr->basic_type = std::string();
|
||||
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cout << "fv.second.GetTypeName = " << fv.second.GetTypeName()
|
||||
<< "\n";
|
||||
#endif
|
||||
if (fv.second.GetTypeName() == "Float") {
|
||||
attr->floatVal = fv.second.GetFloat();
|
||||
attr->basic_type = "float";
|
||||
success = true;
|
||||
|
||||
} else if (fv.second.GetTypeName() == "Int") {
|
||||
if (!fv.second.GetInt(&attr->intVal)) {
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
|
||||
attr->basic_type = "int";
|
||||
success = true;
|
||||
} else if (fv.second.GetTypeName() == "Vec3f") {
|
||||
attr->buffer.Set(BufferData::BUFFER_DATA_TYPE_FLOAT, 3,
|
||||
/* stride */ sizeof(float), fv.second.GetData());
|
||||
// attr->variability = variability;
|
||||
// attr->facevarying = facevarying;
|
||||
success = true;
|
||||
|
||||
} else if (fv.second.GetTypeName() == "FloatArray") {
|
||||
attr->buffer.Set(BufferData::BUFFER_DATA_TYPE_FLOAT, 1,
|
||||
/* stride */ sizeof(float), fv.second.GetData());
|
||||
attr->variability = variability;
|
||||
attr->facevarying = facevarying;
|
||||
success = true;
|
||||
} else if (fv.second.GetTypeName() == "Vec2fArray") {
|
||||
attr->buffer.Set(BufferData::BUFFER_DATA_TYPE_FLOAT, 2,
|
||||
/* stride */ sizeof(float) * 2, fv.second.GetData());
|
||||
attr->variability = variability;
|
||||
attr->facevarying = facevarying;
|
||||
success = true;
|
||||
} else if (fv.second.GetTypeName() == "Vec3fArray") {
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cout << "fv.second.data.size = " << fv.second.GetData().size()
|
||||
<< "\n";
|
||||
#endif
|
||||
attr->buffer.Set(BufferData::BUFFER_DATA_TYPE_FLOAT, 3,
|
||||
/* stride */ sizeof(float) * 3, fv.second.GetData());
|
||||
attr->variability = variability;
|
||||
attr->facevarying = facevarying;
|
||||
success = true;
|
||||
} else if (fv.second.GetTypeName() == "Vec4fArray") {
|
||||
attr->buffer.Set(BufferData::BUFFER_DATA_TYPE_FLOAT, 4,
|
||||
/* stride */ sizeof(float) * 4, fv.second.GetData());
|
||||
attr->variability = variability;
|
||||
attr->facevarying = facevarying;
|
||||
success = true;
|
||||
} else if (fv.second.GetTypeName() == "IntArray") {
|
||||
attr->buffer.Set(BufferData::BUFFER_DATA_TYPE_INT, 1,
|
||||
/* stride */ sizeof(int32_t), fv.second.GetData());
|
||||
attr->variability = variability;
|
||||
attr->facevarying = facevarying;
|
||||
success = true;
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cout << "IntArray"
|
||||
<< "\n";
|
||||
|
||||
const int32_t *ptr =
|
||||
reinterpret_cast<const int32_t *>(attr->buffer.data.data());
|
||||
for (size_t i = 0; i < attr->buffer.GetNumElements(); i++) {
|
||||
std::cout << "[" << i << "] = " << ptr[i] << "\n";
|
||||
}
|
||||
#endif
|
||||
} else if (fv.second.GetTypeName() == "Token") {
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cout << "bbb: token: " << fv.second.GetToken() << "\n";
|
||||
#endif
|
||||
attr->stringVal = fv.second.GetToken();
|
||||
attr->basic_type = "string";
|
||||
// attr->variability = variability;
|
||||
// attr->facevarying = facevarying;
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
};
|
||||
#endif
|
||||
|
||||
//
|
||||
// NOTE: Currently we assume one deeper node has Material's attribute
|
||||
//
|
||||
for (size_t i = 0; i < node.GetChildren().size(); i++) {
|
||||
int child_index = int(node.GetChildren()[i]);
|
||||
if ((child_index < 0) || (child_index >= int(_nodes.size()))) {
|
||||
_err += "Invalid child node id: " + std::to_string(child_index) +
|
||||
". Must be in range [0, " + std::to_string(_nodes.size()) + ")\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
// const Node &child_node = _nodes[size_t(child_index)];
|
||||
|
||||
if (!path_index_to_spec_index_map.count(uint32_t(child_index))) {
|
||||
// No specifier assigned to this child node.
|
||||
_err += "No specifier found for node id: " + std::to_string(child_index) +
|
||||
"\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t spec_index =
|
||||
path_index_to_spec_index_map.at(uint32_t(child_index));
|
||||
if (spec_index >= _specs.size()) {
|
||||
_err += "Invalid specifier id: " + std::to_string(spec_index) +
|
||||
". Must be in range [0, " + std::to_string(_specs.size()) + ")\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
const Spec &spec = _specs[spec_index];
|
||||
|
||||
Path path = GetPath(spec.path_index);
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cout << "Path prim part: " << path.GetPrimPart()
|
||||
<< ", prop part: " << path.GetPropPart()
|
||||
<< ", spec_index = " << spec_index << "\n";
|
||||
#endif
|
||||
|
||||
if (!_live_fieldsets.count(spec.fieldset_index)) {
|
||||
_err += "FieldSet id: " + std::to_string(spec.fieldset_index.value) +
|
||||
" must exist in live fieldsets.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
const FieldValuePairVector &child_fields =
|
||||
_live_fieldsets.at(spec.fieldset_index);
|
||||
|
||||
{
|
||||
std::string prop_name = path.GetPropPart();
|
||||
|
||||
PrimAttrib attr;
|
||||
|
||||
bool ret = _ParseAttribute(child_fields, &attr, prop_name);
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cout << "prop: " << prop_name << ", ret = " << ret << "\n";
|
||||
#endif
|
||||
|
||||
if (ret) {
|
||||
// Currently we only support predefined PBR attributes.
|
||||
|
||||
if (prop_name.compare("outputs:surface") == 0) {
|
||||
// Surface shader output available
|
||||
} else if (prop_name.compare("outputs:displacement") == 0) {
|
||||
// Displacement shader output available
|
||||
} else if (prop_name.compare("inputs:metallic") == 0) {
|
||||
// type: float
|
||||
if ((attr.buffer.GetDataType() ==
|
||||
BufferData::BUFFER_DATA_TYPE_FLOAT) &&
|
||||
(attr.buffer.GetNumElements() == 1) &&
|
||||
(attr.buffer.GetNumCoords() == 1)) {
|
||||
shader->metallic.value = attr.buffer.GetAsFloat();
|
||||
}
|
||||
} else if (prop_name.compare("inputs:diffuseColor") == 0) {
|
||||
if ((attr.buffer.GetDataType() ==
|
||||
BufferData::BUFFER_DATA_TYPE_FLOAT) &&
|
||||
(attr.buffer.GetNumElements() == 1) &&
|
||||
(attr.buffer.GetNumCoords() == 3)) {
|
||||
shader->diffuseColor.color = attr.buffer.GetAsColor3f();
|
||||
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cout << "diffuseColor: " << shader->diffuseColor.color[0]
|
||||
<< ", " << shader->diffuseColor.color[1] << ", "
|
||||
<< shader->diffuseColor.color[2] << "\n";
|
||||
#endif
|
||||
}
|
||||
} else if (prop_name.compare("inputs:diffuseColor.connect") == 0) {
|
||||
// Currently we assume texture is assigned to this attribute.
|
||||
shader->diffuseColor.path = attr.stringVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3672,6 +4241,27 @@ bool Parser::_ReconstructSceneRecursively(
|
||||
return false;
|
||||
}
|
||||
scene->geom_meshes.push_back(mesh);
|
||||
} else if (node_type == "Material") {
|
||||
Material material;
|
||||
if (!_ReconstructMaterial(node, fields, path_index_to_spec_index_map,
|
||||
&material)) {
|
||||
_err += "Failed to reconstruct Material.\n";
|
||||
return false;
|
||||
}
|
||||
scene->materials.push_back(material);
|
||||
} else if (node_type == "Shader") {
|
||||
PreviewSurface shader;
|
||||
if (!_ReconstructShader(node, fields, path_index_to_spec_index_map,
|
||||
&shader)) {
|
||||
_err += "Failed to reconstruct PreviewSurface(Shader).\n";
|
||||
return false;
|
||||
}
|
||||
scene->shaders.push_back(shader);
|
||||
} else {
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cout << "TODO or we can ignore this node: node_type: " << node_type
|
||||
<< "\n";
|
||||
#endif
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < node.GetChildren().size(); i++) {
|
||||
@@ -4542,7 +5132,6 @@ bool GeomMesh::GetFacevaryingNormals(std::vector<float> *v) const {
|
||||
std::cout << "fvnormal numelements = " << n << ", numcoords = " << c << "\n";
|
||||
#endif
|
||||
|
||||
|
||||
memcpy(v->data(), normals.buffer.data.data(), n * c * sizeof(float));
|
||||
|
||||
return true;
|
||||
@@ -4558,8 +5147,7 @@ bool GeomMesh::GetFacevaryingTexcoords(std::vector<float> *v) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((st.buffer.GetNumCoords() < 0) ||
|
||||
(st.buffer.GetNumCoords() != 2)) {
|
||||
if ((st.buffer.GetNumCoords() < 0) || (st.buffer.GetNumCoords() != 2)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -4573,10 +5161,10 @@ bool GeomMesh::GetFacevaryingTexcoords(std::vector<float> *v) const {
|
||||
v->resize(n * c);
|
||||
|
||||
#ifdef TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
std::cout << "fvtexcoords numelements = " << n << ", numcoords = " << c << "\n";
|
||||
std::cout << "fvtexcoords numelements = " << n << ", numcoords = " << c
|
||||
<< "\n";
|
||||
#endif
|
||||
|
||||
|
||||
memcpy(v->data(), st.buffer.data.data(), n * c * sizeof(float));
|
||||
|
||||
return true;
|
||||
|
||||
184
src/tinyusdz.hh
184
src/tinyusdz.hh
@@ -35,7 +35,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <map>
|
||||
#include <limits>
|
||||
|
||||
//#define TINYUSDZ_LOCAL_DEBUG_PRINT (1)
|
||||
#define TINYUSDZ_LOCAL_DEBUG_PRINT (1)
|
||||
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
#include <iostream> // dbg
|
||||
@@ -259,6 +259,17 @@ class ListOp
|
||||
ordered_items = v;
|
||||
}
|
||||
|
||||
#if TINYUSDZ_LOCAL_DEBUG_PRINT
|
||||
void Print() const {
|
||||
std::cout << "is_explicit:" << is_explicit << "\n";
|
||||
std::cout << "# of explicit_items" << explicit_items.size() << "\n";
|
||||
std::cout << "# of added_items" << added_items.size() << "\n";
|
||||
std::cout << "# of prepended_items" << prepended_items.size() << "\n";
|
||||
std::cout << "# of deleted_items" << deleted_items.size() << "\n";
|
||||
std::cout << "# of ordered_items" << ordered_items.size() << "\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
bool is_explicit{false};
|
||||
@@ -386,7 +397,7 @@ class Path {
|
||||
|
||||
void SetLocalPath(const Path &rhs) {
|
||||
//assert(rhs.valid == true);
|
||||
|
||||
|
||||
this->local_part = rhs.local_part;
|
||||
this->valid = rhs.valid;
|
||||
}
|
||||
@@ -1022,6 +1033,10 @@ class Value {
|
||||
path_list_op = d;
|
||||
}
|
||||
|
||||
const ListOp<Path> &GetPathListOp() const {
|
||||
return path_list_op;
|
||||
}
|
||||
|
||||
// Getter for frequently used types.
|
||||
Specifier GetSpecifier() const {
|
||||
if (dtype.id == VALUE_TYPE_SPECIFIER) {
|
||||
@@ -1039,6 +1054,20 @@ class Value {
|
||||
return NumVariabilities; // invalid
|
||||
}
|
||||
|
||||
bool GetBool(bool *ret) const {
|
||||
if (ret == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dtype.id == VALUE_TYPE_BOOL) {
|
||||
uint8_t d = *reinterpret_cast<const uint8_t *>(data.data());
|
||||
(*ret) = bool(d);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
double GetDouble() const {
|
||||
if (dtype.id == VALUE_TYPE_DOUBLE) {
|
||||
double d = *reinterpret_cast<const double *>(data.data());
|
||||
@@ -1046,7 +1075,29 @@ class Value {
|
||||
} else if (dtype.id == VALUE_TYPE_FLOAT) {
|
||||
float d = *reinterpret_cast<const float *>(data.data());
|
||||
return static_cast<double>(d);
|
||||
}
|
||||
}
|
||||
return std::numeric_limits<double>::quiet_NaN(); // invalid
|
||||
}
|
||||
|
||||
bool GetInt(int *ret) const {
|
||||
|
||||
if (ret == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dtype.id == VALUE_TYPE_INT) {
|
||||
float d = *reinterpret_cast<const int *>(data.data());
|
||||
(*ret) = d;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
float GetFloat() const {
|
||||
if (dtype.id == VALUE_TYPE_FLOAT) {
|
||||
float d = *reinterpret_cast<const float *>(data.data());
|
||||
return d;
|
||||
}
|
||||
return std::numeric_limits<double>::quiet_NaN(); // invalid
|
||||
}
|
||||
|
||||
@@ -1160,7 +1211,7 @@ struct BufferData
|
||||
if (data_type == BUFFER_DATA_TYPE_INVALID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return (data.size() > 0) && (num_coords > 0);
|
||||
}
|
||||
|
||||
@@ -1191,7 +1242,7 @@ struct BufferData
|
||||
return GetDataTypeByteSize(data_type) * size_t(num_coords);
|
||||
}
|
||||
|
||||
size_t GetNumElements() const {
|
||||
size_t GetNumElements() const {
|
||||
if (num_coords <= 0) {
|
||||
// TODO(syoyo): Report error
|
||||
return 0;
|
||||
@@ -1218,8 +1269,33 @@ struct BufferData
|
||||
return stride;
|
||||
}
|
||||
|
||||
//
|
||||
// Utility functions
|
||||
//
|
||||
|
||||
float GetAsFloat() const {
|
||||
|
||||
if (((GetStride() == 0) || (GetStride() == sizeof(float))) &&
|
||||
(GetNumCoords() == 1) &&
|
||||
(GetDataType() == BUFFER_DATA_TYPE_FLOAT) &&
|
||||
(GetNumElements() == 1)) {
|
||||
|
||||
return *(reinterpret_cast<const float *>(data.data()));
|
||||
}
|
||||
}
|
||||
|
||||
std::array<float, 3> GetAsColor3f() const {
|
||||
std::array<float, 3> buf;
|
||||
|
||||
if (((GetStride() == 0) || (GetStride() == 3 * sizeof(float))) &&
|
||||
(GetNumCoords() == 3) &&
|
||||
(GetDataType() == BUFFER_DATA_TYPE_FLOAT)) {
|
||||
memcpy(buf.data(), data.data(), buf.size() * sizeof(float));
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
// Return empty array when required type mismatches.
|
||||
//
|
||||
std::vector<uint32_t> GetAsUInt32Array() const {
|
||||
@@ -1301,19 +1377,49 @@ struct BufferData
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
// We treat PrimVar as PrimAttrib(attributes) at the moment.
|
||||
struct PrimAttrib
|
||||
{
|
||||
std::string name;
|
||||
BufferData buffer;
|
||||
std::string name; // attrib name
|
||||
|
||||
std::string type_name; // name of attrib type(e.g. "float', "color3f")
|
||||
|
||||
// For array data types(e.g. FloatArray)
|
||||
BufferData buffer; // raw buffer data
|
||||
Variability variability;
|
||||
bool facevarying{false};
|
||||
|
||||
// For TokenString
|
||||
std::string tokenString;
|
||||
|
||||
// For basic types(e.g. Bool, Float).
|
||||
|
||||
// "bool", "string", "float", "int", "uint", "int64", "uint64", "double" or "path"
|
||||
// empty = array data type
|
||||
std::string basic_type;
|
||||
|
||||
// TODO: Use union struct
|
||||
bool boolVal;
|
||||
int intVal;
|
||||
uint32_t uintVal;
|
||||
int64_t int64Val;
|
||||
uint64_t uint64Val;
|
||||
float floatVal;
|
||||
double doubleVal;
|
||||
std::string stringVal; // token, string
|
||||
Path path;
|
||||
|
||||
};
|
||||
|
||||
// UsdPrimvarReader.
|
||||
// Currently for UV texture coordinate
|
||||
struct PrimvarReader
|
||||
{
|
||||
std::string output_type = "float2"; // currently "float2" only.
|
||||
|
||||
int32_t input_id{-1}; // inputs:varname. Index to PrimVar in Primitive
|
||||
};
|
||||
|
||||
// Predefined node class
|
||||
@@ -1333,15 +1439,6 @@ struct Xform
|
||||
|
||||
};
|
||||
|
||||
// Vertex attributes. e.g. UV coords, vertex colors, etc.
|
||||
struct PrimVar
|
||||
{
|
||||
std::string name;
|
||||
BufferData buffer;
|
||||
Variability variability;
|
||||
bool facevarying{false};
|
||||
};
|
||||
|
||||
struct UVCoords
|
||||
{
|
||||
std::string name;
|
||||
@@ -1354,17 +1451,17 @@ struct UVCoords
|
||||
|
||||
struct Extent
|
||||
{
|
||||
std::array<float, 3> lower = {{
|
||||
Vec3f lower{
|
||||
std::numeric_limits<float>::infinity(),
|
||||
std::numeric_limits<float>::infinity(),
|
||||
std::numeric_limits<float>::infinity()
|
||||
}};
|
||||
};
|
||||
|
||||
std::array<float, 3> upper = {{
|
||||
Vec3f upper{
|
||||
-std::numeric_limits<float>::infinity(),
|
||||
-std::numeric_limits<float>::infinity(),
|
||||
-std::numeric_limits<float>::infinity()
|
||||
}};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@@ -1395,14 +1492,14 @@ struct GeomMesh
|
||||
bool GetPoints(std::vector<float> *v) const;
|
||||
|
||||
// Get `normals` as float3 array + facevarying
|
||||
// Return false if `normals` is neither float3[] type nor `varying`
|
||||
// Return false if `normals` is neither float3[] type nor `varying`
|
||||
bool GetFacevaryingNormals(std::vector<float> *v) const;
|
||||
|
||||
// Get `texcoords` as float2 array + facevarying
|
||||
// Return false if `texcoords` is neither float2[] type nor `varying`
|
||||
// Return false if `texcoords` is neither float2[] type nor `varying`
|
||||
bool GetFacevaryingTexcoords(std::vector<float> *v) const;
|
||||
|
||||
// PrimVar
|
||||
// PrimVar(TODO: Remove)
|
||||
UVCoords st;
|
||||
|
||||
PrimAttrib velocitiess; // Usually float3[], varying
|
||||
@@ -1420,7 +1517,6 @@ struct GeomMesh
|
||||
Visibility visibility{VisibilityInherited};
|
||||
Purpose purpose{PurposeDefault};
|
||||
|
||||
|
||||
//
|
||||
// SubD attribs.
|
||||
//
|
||||
@@ -1434,11 +1530,8 @@ struct GeomMesh
|
||||
SubdivisionScheme subdivisionScheme;
|
||||
|
||||
|
||||
// User defined attribs
|
||||
std::map<std::string, PrimAttrib> custom_attrs;
|
||||
|
||||
// List of Primitive variables.
|
||||
std::map<std::string, PrimVar> primvars;
|
||||
// List of Primitive attributes(primvars)
|
||||
std::map<std::string, PrimAttrib> attrs;
|
||||
|
||||
};
|
||||
|
||||
@@ -1467,6 +1560,8 @@ struct Color3OrTexture
|
||||
}
|
||||
|
||||
std::array<float, 3> color{{0.0f, 0.0f, 0.0f}};
|
||||
|
||||
std::string path; // path to .connect(We only support texture file connection at the moment)
|
||||
int64_t texture_id{-1};
|
||||
|
||||
bool HasTexture() const {
|
||||
@@ -1482,6 +1577,8 @@ struct FloatOrTexture
|
||||
}
|
||||
|
||||
float value{0.0f};
|
||||
|
||||
std::string path; // path to .connect(We only support texture file connection at the moment)
|
||||
int64_t texture_id{-1};
|
||||
|
||||
bool HasTexture() const {
|
||||
@@ -1510,6 +1607,7 @@ struct UsdTranform2d {
|
||||
// UsdUvTexture
|
||||
struct UVTexture {
|
||||
|
||||
std::string asset; // asset name(usually file path)
|
||||
int64_t image_id{-1}; // TODO(syoyo): Consider UDIM `@textures/occlusion.<UDIM>.tex@`
|
||||
|
||||
std::array<float, 2> st; // texture coordinate orientation. https://graphics.pixar.com/usd/docs/UsdPreviewSurface-Proposal.html#UsdPreviewSurfaceProposal-TextureCoordinateOrientationinUSD
|
||||
@@ -1521,6 +1619,13 @@ struct UVTexture {
|
||||
std::array<float, 4> bias{{0.0f, 0.0f, 0.0f, 0.0f}}; // bias to be applied to output texture value
|
||||
|
||||
UsdTranform2d texture_transfom;
|
||||
|
||||
// key = connection name: e.g. "outputs:rgb"
|
||||
// item = pair<type, name> : example: <"float3", "outputs:rgb">
|
||||
std::map<std::string, std::pair<std::string, std::string>> outputs;
|
||||
|
||||
// UsdPrimvarReader_float2.
|
||||
PrimvarReader texcoord_reader;
|
||||
};
|
||||
|
||||
|
||||
@@ -1612,7 +1717,7 @@ struct Scene
|
||||
std::vector<Node> nodes; // Node hierarchies
|
||||
|
||||
// Scene global setting
|
||||
std::string upAxis = "Y";
|
||||
std::string upAxis = "Y";
|
||||
std::string defaultPrim; // prim node name
|
||||
double metersPerUnit = 1.0; // default [m]
|
||||
double timeCodesPerSecond = 24.0; // default 24 fps
|
||||
@@ -1628,7 +1733,7 @@ struct Scene
|
||||
std::vector<Group> groups;
|
||||
|
||||
// TODO(syoyo): User defined custom layer data
|
||||
// "customLayerData"
|
||||
// "customLayerData"
|
||||
|
||||
};
|
||||
|
||||
@@ -1644,13 +1749,22 @@ struct USDLoadOptions
|
||||
// This feature would be helpful if you want to load USDZ model in mobile device.
|
||||
int32_t max_memory_limit_in_mb{10000}; // in [mb] Default 10GB
|
||||
|
||||
///
|
||||
/// Loads asset data(e.g. texture image, audio). Default is true.
|
||||
/// If you want to load asset data in your own way or don't need asset data to be loaded,
|
||||
/// Set this false.
|
||||
///
|
||||
bool load_assets{true};
|
||||
|
||||
};
|
||||
|
||||
#if 0 // TODO
|
||||
//struct USDWriteOptions
|
||||
//{
|
||||
//
|
||||
//
|
||||
//};
|
||||
#endif
|
||||
|
||||
///
|
||||
/// Load USDZ(zip) from a file.
|
||||
|
||||
Reference in New Issue
Block a user