Add some Tydra utility functions.

This commit is contained in:
Syoyo Fujita
2022-11-23 04:03:43 +09:00
parent 8db6695ca7
commit 1a7acdd86d
8 changed files with 206 additions and 2 deletions

View File

@@ -306,6 +306,7 @@ set(TINYUSDZ_SOURCES
${PROJECT_SOURCE_DIR}/src/image-loader.cc
${PROJECT_SOURCE_DIR}/src/pprinter.cc
${PROJECT_SOURCE_DIR}/src/stage.cc
${PROJECT_SOURCE_DIR}/src/tydra/prim-apply.cc
${PROJECT_SOURCE_DIR}/src/tydra/scene-access.cc
${PROJECT_SOURCE_DIR}/src/tydra/shader-network.cc
${PROJECT_SOURCE_DIR}/src/tydra/render-data.cc)

View File

@@ -533,6 +533,8 @@ include src/tinyusdz.hh
include src/tiny-variant.hh
include src/token-type.hh
include src/tydra/README.md
include src/tydra/prim-apply.cc
include src/tydra/prim-apply.hh
include src/tydra/render-data.cc
include src/tydra/render-data.hh
include src/tydra/scene-access.cc

View File

@@ -294,8 +294,9 @@ list(
../../src/ascii-parser-timesamples-array.cc
../../src/usdc-reader.cc
../../src/usda-reader.cc
#../../src/usda-writer.cc
../../src/usda-writer.cc
../../src/image-loader.cc
../../src/linear-algebra.cc
../../src/value-types.cc
../../src/value-pprint.cc
../../src/tiny-format.cc
@@ -308,6 +309,8 @@ list(
../../src/linear-algebra.cc
../../src/tydra/render-data.cc
../../src/tydra/scene-access.cc
../../src/tydra/shader-network.cc
../../src/tydra/prim-apply.cc
)
set(TINYUSDZ_DEP_SOURCES

46
src/tydra/prim-apply.cc Normal file
View File

@@ -0,0 +1,46 @@
#include "prim-apply.hh"
#include "prim-types.hh"
#include "usdGeom.hh"
namespace tinyusdz {
namespace tydra {
bool ApplyToGPrim(
const Stage &stage, const Prim &prim,
std::function<bool(const Stage &stage, const GPrim *gprim)> fn) {
(void)stage;
if ((value::TypeId::TYPE_ID_GPRIM <= prim.type_id() &&
(value::TypeId::TYPE_ID_GEOM_END > prim.type_id()))) {
// gprim
} else {
return false;
}
#define APPLY_FUN(__ty) { \
const auto *v = prim.as<__ty>(); \
if (v) { \
return fn(stage, v); \
} \
}
APPLY_FUN(GPrim)
APPLY_FUN(Xform)
APPLY_FUN(GeomMesh)
APPLY_FUN(GeomSphere)
APPLY_FUN(GeomCapsule)
APPLY_FUN(GeomCube)
APPLY_FUN(GeomPoints)
APPLY_FUN(GeomCylinder)
APPLY_FUN(GeomBasisCurves)
#undef APPLY_FUN
return false;
}
} // namespace tydra
} // namespace tinyusdz

22
src/tydra/prim-apply.hh Normal file
View File

@@ -0,0 +1,22 @@
#pragma once
// utility to apply function to a Prim.
// Internal use expected(not intended for Public Tydra API).
#include <functional>
namespace tinyusdz {
// forward decl.
class Stage;
class Prim;
struct GPrim;
namespace tydra {
bool ApplyToGPrim(
const Stage &stage, const Prim &prim,
std::function<bool(const Stage &stage, const GPrim *gprim)> fn);
} // namespace tydra
} // namespace tinyusdz

View File

@@ -1,9 +1,12 @@
#include "shader-network.hh"
#include "prim-apply.hh"
#include "prim-types.hh"
#include "usdShade.hh"
#include "pprinter.hh"
#include "prim-pprint.hh"
#include "value-pprint.hh"
#include "stage.hh"
namespace tinyusdz {
namespace tydra {
@@ -129,5 +132,102 @@ INSTANCIATE_EVAL_SHADER(value::matrix4d);
// instanciations
namespace {
bool GetSinglePath(const Relationship &rel, Path *path) {
if (!path) {
return false;
}
if (rel.is_path()) {
(*path) = rel.targetPath;
return true;
} else if (rel.is_pathvector()) {
if (rel.targetPathVector.size() > 0) {
(*path) = rel.targetPathVector[0];
return true;
}
}
return false;
}
} // namespace local
bool GetBoundMaterial(
const Stage &_stage,
const Prim &prim,
const std::string &suffix,
tinyusdz::Path *materialPath,
const Material **material,
std::string *err) {
if (materialPath == nullptr) {
return false;
}
(void)err;
auto apply_fun = [&](const Stage &stage, const GPrim *gprim) -> bool {
if (suffix.empty()) {
if (gprim->materialBinding.has_value()) {
if (GetSinglePath(gprim->materialBinding.value(), materialPath)) {
const Prim *p;
if (stage.find_prim_at_path(*materialPath, p, err)) {
if (p->is<Material>() && (material != nullptr)) {
(*material) = p->as<Material>();
} else {
(*material) = nullptr;
}
}
return true;
}
}
} else if (suffix == "correction") {
if (gprim->materialBindingCorrection.has_value()) {
if (GetSinglePath(gprim->materialBindingCorrection.value(), materialPath)) {
const Prim *p;
if (stage.find_prim_at_path(*materialPath, p, err)) {
if (p->is<Material>() && (material != nullptr)) {
(*material) = p->as<Material>();
} else {
(*material) = nullptr;
}
}
return true;
}
}
} else if (suffix == "preview") {
if (gprim->materialBindingPreview.has_value()) {
if (GetSinglePath(gprim->materialBindingPreview.value(), materialPath)) {
const Prim *p;
if (stage.find_prim_at_path(*materialPath, p, err)) {
if (p->is<Material>() && (material != nullptr)) {
(*material) = p->as<Material>();
} else {
(*material) = nullptr;
}
}
return true;
}
}
} else {
return false;
}
return false;
};
bool ret = ApplyToGPrim(_stage, prim, apply_fun);
return ret;
}
} // namespace tydra
} // namespace tinyusdz

View File

@@ -10,9 +10,12 @@
namespace tinyusdz {
// forward decl of usdShade
// forward decl of prim-types.hh
class Path;
class Stage;
class Prim;
// forward decl of usdShade
struct Material;
struct Shader;
@@ -62,5 +65,28 @@ bool EvaluateShaderAttribute(
// Currently float2 only
//std::vector<UsdPrimvarReader_float2> ExtractPrimvarReadersFromMaterialNode(const Prim &node);
///
/// Get material:binding target Path.
/// The bahavior is:
///
/// 1. If material:binding is assigned to given Prim, return it
/// 2. Look into parent Prim's material:binding
///
/// @param[in] stage Prim
/// @param[in] prim Prim
/// @param[in] suffix extra suffix(e.g. empty string is given, look into `material:binding`. `correction` is given, look into `material:binding:correction`.)
/// @param[out] materialPath Found target Path.
/// @param[out] material THe pointer to found Material object in Stage(if no Material object found in Stage, returns nullptr)
/// @return true when bound Material Path is found.
///
bool GetBoundMaterial(
const Stage &stage,
const Prim &prim,
const std::string &suffix,
tinyusdz::Path *materialPath,
const Material **material,
std::string *err);
} // namespace tydra
} // namespace tinyusdz

View File

@@ -25,6 +25,10 @@ constexpr auto kGeomSphere = "Sphere";
constexpr auto kGeomCamera = "Camera";
constexpr auto kPointInstancer = "PointInstancer";
constexpr auto kMaterialBinding = "material:binding";
constexpr auto kMaterialBindingCorrection = "material:binding:correction";
constexpr auto kMaterialBindingPreview = "material:binding:preview";
struct GPrim;
bool IsSupportedGeomPrimvarType(uint32_t tyid);