Add type-erased helper class PrimValue.

This commit is contained in:
Syoyo Fujita
2020-11-13 22:24:29 +09:00
parent 0d7592d80b
commit ddf69ce4ab
7 changed files with 233 additions and 20 deletions

View File

@@ -56,6 +56,7 @@ endif()
set(TINYUSDZ_SOURCES
${PROJECT_SOURCE_DIR}/src/tinyusdz.cc
${PROJECT_SOURCE_DIR}/src/usda-writer.cc
)
set(TINYUSDZ_DEP_SOURCES

View File

@@ -150,6 +150,7 @@ See [prim_format.md](doc/prim_format.md) and [preview_surface.md](doc/preview_su
## TODO
* [ ] Support Crate(binary) version 0.8.0(USD v20.11 default)
* [ ] Write parser based on the schema definition.
* [ ] Subdivision surface using OpenSubdiv.
* [ ] Replace OpenSubdiv with our own subdiv library or embree3's one.

24
doc/TODO.md Normal file
View File

@@ -0,0 +1,24 @@
# USDC parser
Base implementation in TinyUSDZ: v0.7.0
* [ ] v0.8.0 support
* [ ] PayloadListOp/Payload + layer offsets
* [ ] LayerOffset
* [ ] v0.9.0 support
* [ ] TimeCode, TimeCode[]
# USDA parser
* [ ] USDA parser
# USDC writer
* [ ] USDC writer
# USDA writer
* [ ] USDA writer
EoL.

View File

@@ -7,6 +7,20 @@
=> total 88 bytes
## Version
From pxr/usd/usd/crateFile.cpp
```
// Version history:
// 0.9.0: Added support for the timecode and timecode[] value types.
// 0.8.0: Added support for SdfPayloadListOp values and SdfPayload values with
// layer offsets.
// 0.7.0: Array sizes written as 64 bit ints.
```
* 0.8.0(USD v20.11)
## Compression
version 0.4.0 or later uses LZ4 for compression and interger compression(pxr original? compression. its backend still uses LZ4) for index arrays.

View File

@@ -44,6 +44,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace tinyusdz {
constexpr int version_major = 0;
constexpr int version_minor = 7;
constexpr int version_micro = 0;
// Simple image class.
// No colorspace conversion will be applied when decoding image data(e.g. from
// .jpg, .png).
@@ -433,6 +437,30 @@ class Path {
bool valid{false};
};
class TimeCode {
TimeCode(double tm = 0.0) : _time(tm) {}
size_t hash() const { return std::hash<double>{}(_time); }
double value() const { return _time; }
private:
double _time;
};
class LayerOffset {
private:
double _offset;
double _scale;
};
class Payload {
private:
std::string _asset_path;
Path _prim_path;
LayerOffset _layer_offset;
};
enum ValueTypeId {
VALUE_TYPE_INVALID = 0,
@@ -585,6 +613,99 @@ struct TimeSamples {
std::vector<Value> values;
};
///
/// Simple type-erased primitive value class for frequently used data types(e.g. `float[]`)
///
template <class dtype>
struct TypeTrait;
// TODO(syoyo): Support `Token` type
template <>
struct TypeTrait<std::string> {
static constexpr auto type_name = "string";
static constexpr ValueTypeId type_id = VALUE_TYPE_STRING;
};
template <>
struct TypeTrait<int> {
static constexpr auto type_name = "int";
static constexpr ValueTypeId type_id = VALUE_TYPE_INT;
};
template <>
struct TypeTrait<float16> {
static constexpr auto type_name = "half";
static constexpr ValueTypeId type_id = VALUE_TYPE_HALF;
};
template <>
struct TypeTrait<Vec2f> {
static constexpr auto type_name = "vec2f";
static constexpr ValueTypeId type_id = VALUE_TYPE_VEC2F;
};
template <>
struct TypeTrait<Vec3f> {
static constexpr auto type_name = "vec3f";
static constexpr ValueTypeId type_id = VALUE_TYPE_VEC3F;
};
template <>
struct TypeTrait<Vec4f> {
static constexpr auto type_name = "vec4f";
static constexpr ValueTypeId type_id = VALUE_TYPE_VEC3F;
};
template <>
struct TypeTrait<Matrix4d> {
static constexpr auto type_name = "matrix4d";
static constexpr ValueTypeId type_id = VALUE_TYPE_MATRIX4D;
};
template <class T>
class PrimValue {
private:
T m_value;
public:
T value() const { return m_value; }
template <typename U, typename std::enable_if<std::is_same<T, U>::value>::type
* = nullptr>
PrimValue<T> &operator=(const U &u) {
m_value = u;
return (*this);
}
std::string type_name() { return std::string(TypeTrait<T>::type_name); }
bool is_array() const { return false; }
};
///
/// array of PrimmValue
/// multi-dimensional type is not supported(e.g. float[][])
///
template <class T>
class PrimValue<std::vector<T>> {
private:
std::vector<T> m_value;
template <typename U, typename std::enable_if<std::is_same<T, U>::value>::type
* = nullptr>
PrimValue<T> &operator=(const std::vector<U> &u) {
m_value = u;
return (*this);
}
std::string type_name() {
return std::string(TypeTrait<T>::type_name) + "[]";
}
bool is_array() const { return true; }
};
///
/// Represent value.
/// multi-dimensional type is not supported(e.g. float[][])
@@ -1519,8 +1640,7 @@ struct BlendShape {
// values in `offsets` and `normalOffsets`.
};
struct SkelRoot
{
struct SkelRoot {
Extent extent;
Purpose purpose{PurposeDefault};
Visibility visibility{VisibilityInherited};
@@ -1531,15 +1651,16 @@ struct SkelRoot
};
// Skelton
struct Skelton
{
std::vector<Matrix4d> bindTransforms; // bind-pose transform of each joint in world coordinate.
struct Skelton {
std::vector<Matrix4d>
bindTransforms; // bind-pose transform of each joint in world coordinate.
Extent extent;
std::vector<std::string> jointNames;
std::vector<std::string> joints;
std::vector<Matrix4d> restTransforms; // rest-pose transforms of each joint in local coordinate.
std::vector<Matrix4d> restTransforms; // rest-pose transforms of each joint
// in local coordinate.
Purpose purpose{PurposeDefault};
Visibility visibility{VisibilityInherited};
@@ -1549,28 +1670,29 @@ struct Skelton
// ref proxyPrim
};
struct SkelAnimation
{
struct SkelAnimation {
std::vector<std::string> blendShapes;
std::vector<float> blendShapeWeights;
std::vector<std::string> joints;
std::vector<Quatf> rotations; // Joint-local unit quaternion rotations
std::vector<Vec3f> scales; // Joint-local scaling. pxr USD schema uses half3, but we use float3 for convenience.
std::vector<Vec3f> translations; // Joint-local translation.
std::vector<Quatf> rotations; // Joint-local unit quaternion rotations
std::vector<Vec3f> scales; // Joint-local scaling. pxr USD schema uses half3,
// but we use float3 for convenience.
std::vector<Vec3f> translations; // Joint-local translation.
};
// W.I.P.
struct SkelBindingAPI {
Matrix4d geomBindTransform; // primvars:skel:geomBindTransform
std::vector<int> jointIndices; // primvars:skel:jointIndices
std::vector<float> jointWeights; // primvars:skel:jointWeights
std::vector<std::string> blendShapes; // optional?
std::vector<std::string> joints; // optional
Matrix4d geomBindTransform; // primvars:skel:geomBindTransform
std::vector<int> jointIndices; // primvars:skel:jointIndices
std::vector<float> jointWeights; // primvars:skel:jointWeights
std::vector<std::string> blendShapes; // optional?
std::vector<std::string> joints; // optional
int64_t animationSource{-1}; // index to Scene.animations. ref skel:animationSource
int64_t blendShapeTargets{-1}; // index to Scene.blendshapes. ref skel:bindShapeTargets
int64_t skeleton{-1}; // index to Scene.skeltons. // ref skel:skelton
int64_t animationSource{
-1}; // index to Scene.animations. ref skel:animationSource
int64_t blendShapeTargets{
-1}; // index to Scene.blendshapes. ref skel:bindShapeTargets
int64_t skeleton{-1}; // index to Scene.skeltons. // ref skel:skelton
};
// Polygon mesh geometry

39
src/usda-writer.cc Normal file
View File

@@ -0,0 +1,39 @@
#include "usda-writer.hh"
#include <sstream>
namespace tinyusdz {
namespace {
// TODO
bool WriteNode(std::ostream &ofs, const Node &node, int indent) {
return false;
}
}
bool SaveAsUSDA(const std::string &filename, const Scene &scene, std::string *warn, std::string *err) {
std::stringstream ss;
ss << "#usda 1.0\n";
ss << "(\n";
ss << " doc = \"TinyUSDZ v" << tinyusdz::version_major << "." << tinyusdz::version_minor << "." << tinyusdz::version_micro << "\"\n";
ss << " metersPerUnit = 1\n";
ss << " upAxis = \"Z\"\n";
ss << ")\n";
// TODO
for (const auto &node : scene.nodes) {
if (!WriteNode(ss, node, 0)) {
return false;
}
}
return false;
}
} // namespace tinyusdz

12
src/usda-writer.hh Normal file
View File

@@ -0,0 +1,12 @@
#pragma once
#include "tinyusdz.hh"
namespace tinyusdz {
///
/// Save scene as USDA(ASCII)
///
bool SaveAsUSDA(const std::string &filename, const Scene &scene, std::string *warn, std::string *err);
} // namespace tinyusdz