Reactor Animatable<T>.

Fix syntax of prim-meta-add-variantSets-000.usda
This commit is contained in:
Syoyo Fujita
2022-10-25 05:17:10 +09:00
parent ac68933a15
commit 50d03e8f72
10 changed files with 263 additions and 89 deletions

View File

@@ -212,11 +212,15 @@ std::string print_animatable(const Animatable<T> &v, const uint32_t indent = 0)
std::stringstream ss;
if (v.is_timesamples()) {
ss << print_typed_timesamples(v.ts, indent);
ss << print_typed_timesamples(v.get_timesamples(), indent);
} else if (v.is_blocked()) {
ss << "None";
} else if (v.is_scalar()) {
ss << v.value;
T a;
if (!v.get(&a)) {
return "[Animatable: InternalError]";
}
ss << a;
} else {
return "[FIXME: Invalid Animatable]";
}
@@ -229,11 +233,15 @@ std::string print_animatable_token(const Animatable<T> &v, const uint32_t indent
std::stringstream ss;
if (v.is_timesamples()) {
ss << print_typed_token_timesamples(v.ts, indent);
ss << print_typed_token_timesamples(v.get_timesamples(), indent);
} else if (v.is_blocked()) {
ss << "None";
} else if (v.is_scalar()) {
ss << quote(to_string(v.value));
T a;
if (!v.get(&a)) {
return "[Animatable: InternalError]";
}
ss << quote(to_string(a));
} else {
return "[FIXME: Invalid Animatable]";
}
@@ -516,9 +524,14 @@ std::string print_typed_attr(const TypedAttribute<Animatable<T>> &attr, const st
if (pv) {
if (pv.value().is_timesamples()) {
ss << ".timeSamples = " << print_typed_timesamples(pv.value().ts, indent+1);
ss << ".timeSamples = " << print_typed_timesamples(pv.value().get_timesamples(), indent+1);
} else {
ss << " = " << pv.value().value;
T a;
if (pv.value().get(&a)) {
ss << " = " << a;
} else {
ss << " = [InternalError]";
}
}
}
}

View File

@@ -86,8 +86,7 @@ static nonstd::optional<Animatable<T>> ConvertToAnimatable(const primvar::PrimVa
if (var.is_scalar()) {
if (auto pv = var.get_value<T>()) {
dst.value = pv.value();
dst.blocked = false;
dst.set(pv.value());
return std::move(dst);
}
@@ -97,9 +96,9 @@ static nonstd::optional<Animatable<T>> ConvertToAnimatable(const primvar::PrimVa
// Attribute Block?
if (auto pvb = var.get_ts_value<value::ValueBlock>(i)) {
dst.ts.add_blocked_sample(t);
dst.add_blocked_sample(t);
} else if (auto pv = var.get_ts_value<T>(i)) {
dst.ts.add_sample(t, pv.value());
dst.add_sample(t, pv.value());
} else {
// Type mismatch
DCOUT(i << "/" << var.var().times.size() << " type mismatch.");
@@ -133,8 +132,7 @@ nonstd::optional<Animatable<Extent>> ConvertToAnimatable(const primvar::PrimVar
ext.lower = pv.value()[0];
ext.upper = pv.value()[1];
dst.value = ext;
dst.blocked = false;
dst.set(ext);
} else {
return nonstd::nullopt;
@@ -148,13 +146,13 @@ nonstd::optional<Animatable<Extent>> ConvertToAnimatable(const primvar::PrimVar
// Attribute Block?
if (auto pvb = var.get_ts_value<value::ValueBlock>(i)) {
dst.ts.add_blocked_sample(t);
dst.add_blocked_sample(t);
} else if (auto pv = var.get_ts_value<std::vector<value::float3>>(i)) {
if (pv.value().size() == 2) {
Extent ext;
ext.lower = pv.value()[0];
ext.upper = pv.value()[1];
dst.ts.add_sample(t, ext);
dst.add_sample(t, ext);
} else {
DCOUT(i << "/" << var.var().times.size() << " array size mismatch.");
return nonstd::nullopt;

View File

@@ -767,7 +767,7 @@ struct TypedTimeSamples {
bool empty() const { return _samples.empty(); }
void Update() {
void update() const {
std::sort(_samples.begin(), _samples.end(),
[](const Sample &a, const Sample &b) { return a.t < b.t; });
@@ -782,7 +782,7 @@ struct TypedTimeSamples {
bool get(
T *dst,
double t = value::TimeCode::Default(),
TimeSampleInterpolationType interp = TimeSampleInterpolationType::Held) {
TimeSampleInterpolationType interp = TimeSampleInterpolationType::Held) const {
if (!dst) {
return false;
@@ -793,7 +793,7 @@ struct TypedTimeSamples {
}
if (_dirty) {
Update();
update();
}
if (value::TimeCode(t).is_default()) {
@@ -806,7 +806,6 @@ struct TypedTimeSamples {
_samples.begin(), _samples.end(), t,
[](const Sample &a, double tval) { return a.t < tval; });
// TODO: Support other interpolation method for example cubic?
if (interp == TimeSampleInterpolationType::Linear) {
size_t idx0 = size_t(std::max(
int64_t(0),
@@ -856,7 +855,7 @@ struct TypedTimeSamples {
_dirty = true;
}
void add_sample(const double t, T &v) {
void add_sample(const double t, const T &v) {
Sample s;
s.t = t;
s.value = v;
@@ -872,55 +871,124 @@ struct TypedTimeSamples {
_dirty = true;
}
const std::vector<Sample> &get_samples() const { return _samples; }
std::vector<Sample> &samples() { return _samples; }
const std::vector<Sample> &get_samples() const {
if (_dirty) {
update();
}
return _samples; }
std::vector<Sample> &samples() {
if (_dirty) {
update();
}
return _samples;
}
private:
// Need to be sorted when look up the value.
std::vector<Sample> _samples;
bool _dirty{false};
// Need to be sorted when looking up the value.
mutable std::vector<Sample> _samples;
mutable bool _dirty{false};
};
//
// Scalar or TimeSamples.
//
template <typename T>
struct Animatable {
// scalar
T value;
bool blocked{false};
public:
// timesamples
TypedTimeSamples<T> ts;
bool is_blocked() const { return _blocked; }
bool is_timesamples() const { return !ts.empty(); }
bool is_scalar() const { return ts.empty(); }
bool is_blocked() const { return blocked; }
#if 0 // TODO
T Get() const { return value; }
T Get(double t) {
if (IsTimeSampled()) {
// TODO: lookup value by t
return timeSamples.Get(t);
bool is_timesamples() const {
if (is_blocked()) {
return false;
}
return value;
return !_ts.empty();
}
#endif
bool is_scalar() const {
if (is_blocked()) {
return false;
}
return _ts.empty();
}
///
/// Get value at specific time.
///
bool get(double t, T *v, const TimeSampleInterpolationType tinerp = TimeSampleInterpolationType::Held) const {
if (!v) {
return false;
}
if (is_blocked()) {
return false;
} else if (is_scalar()) {
(*v) = _value;
return true;
} else { // timesamples
return _ts.get(v, t, tinerp);
}
}
///
/// Get scalar value. For timesamples value, fetch the value at Default time.
///
bool get(T *v) const {
if (!v) {
return false;
}
if (is_blocked()) {
return false;
} else if (is_scalar()) {
(*v) = _value;
return true;
} else { // timesamples
return get(value::TimeCode::Default(), v);
}
}
// TimeSamples
void set(double t, const T &v);
//void set(double t, const T &v);
void add_sample(const double t, const T &v) {
_ts.add_sample(t, v);
}
// Add None(ValueBlock) sample to timesamples
void add_blocked_sample(const double t) {
_ts.add_blocked_sample(t);
}
// Scalar
void set(const T &v) {
value = v;
_value = v;
_blocked = false;
}
const TypedTimeSamples<T> &get_timesamples() const {
return _ts;
}
Animatable() {}
Animatable(const T &v) : value(v) {}
Animatable(const T &v) : _value(v) {}
// TODO: Init with timesamples
private:
// scalar
T _value;
bool _blocked{false};
// timesamples
TypedTimeSamples<T> _ts;
};
///

View File

@@ -413,14 +413,17 @@ void ToProperty(const TypedAttribute<Animatable<T>> &input, Property &output) {
nonstd::optional<Animatable<T>> aval = input.get_value();
if (aval) {
if (aval.value().is_scalar()) {
value::Value val(aval.value().value);
primvar::PrimVar pvar;
pvar.set_scalar(val);
Attribute attr;
attr.set_var(std::move(pvar));
attr.variability() = Variability::Uniform;
output = Property(attr, /* custom */ false);
return;
T a;
if (aval.value().get(&a)) {
value::Value val(a);
primvar::PrimVar pvar;
pvar.set_scalar(val);
Attribute attr;
attr.set_var(std::move(pvar));
attr.variability() = Variability::Uniform;
output = Property(attr, /* custom */ false);
return;
}
} else if (aval.value().is_blocked()) {
Attribute attr;
attr.set_type_name(value::TypeTraits<T>::type_name());
@@ -484,11 +487,16 @@ void ToProperty(
primvar::PrimVar pvar;
if (v.is_timesamples()) {
value::TimeSamples ts = ToTypelessTimeSamples(v.ts);
value::TimeSamples ts = ToTypelessTimeSamples(v.get_timesamples());
pvar.set_timesamples(ts);
} else if (v.is_scalar()) {
value::Value val(v.value);
pvar.set_scalar(val);
T a;
if (v.get(&a)) {
value::Value val(a);
pvar.set_scalar(val);
} else {
DCOUT("??? Invalid Animatable value.");
}
} else {
DCOUT("??? Invalid Animatable value.");
}

View File

@@ -25,9 +25,11 @@ bool EvaluateUsdPreviewSurfaceAttribute(
if (shader.diffuseColor.authored()) {
} else {
value::color3f col = shader.diffuseColor.get_value().value;
out_val = col;
return true;
value::color3f col;
if (shader.diffuseColor.get_value().get(&col)) {
out_val = col;
return true;
}
}
}

View File

@@ -37,13 +37,9 @@ const std::vector<value::point3f> GeomMesh::GetPoints(
}
if (auto pv = points.get_value()) {
if (pv.value().is_timesamples()) {
std::vector<value::point3f> v;
if (pv.value().ts.get(&v, time, interp)) {
dst = v;
}
} else if (pv.value().is_scalar()) {
dst = pv.value().value;
std::vector<value::point3f> val;
if (pv.value().get(time, &val, interp)) {
dst = std::move(val);
}
}
@@ -81,14 +77,11 @@ const std::vector<value::normal3f> GeomMesh::GetNormals(
}
if (normals.get_value()) {
if (normals.get_value().value().is_timesamples()) {
// TODO
(void)time;
(void)interp;
return dst;
}
dst = normals.get_value().value().value;
std::vector<value::normal3f> val;
if (normals.get_value().value().get(time, &val, interp)) {
dst = std::move(val);
}
}
}
@@ -123,7 +116,11 @@ const std::vector<int32_t> GeomMesh::GetFaceVertexCounts() const {
}
if (auto pv = faceVertexCounts.get_value()) {
dst = pv.value().value;
std::vector<int32_t> val;
// TOOD: timesamples
if (pv.value().get(&val)) {
dst = std::move(val);
}
}
return dst;
}
@@ -141,7 +138,11 @@ const std::vector<int32_t> GeomMesh::GetFaceVertexIndices() const {
}
if (auto pv = faceVertexIndices.get_value()) {
dst = pv.value().value;
std::vector<int32_t> val;
// TOOD: timesamples
if (pv.value().get(&val)) {
dst = std::move(val);
}
}
return dst;
}
@@ -252,8 +253,17 @@ nonstd::expected<bool, std::string> GeomMesh::ValidateGeomSubset() {
if (faceVertexCounts.get_value()) {
const auto fvp = faceVertexCounts.get_value();
const auto &fv = fvp.value().value;
size_t n = fv.size();
std::vector<int32_t> fvc;
if (fvp.value().is_timesamples()) {
return nonstd::make_unexpected("TODO: faceVertexCounts.timeSamples\n");
}
if (!fvp.value().get(&fvc)) {
return nonstd::make_unexpected("Failed to get faceVertexCounts data.");
}
size_t n = fvc.size();
// Currently we only check if face ids are valid.
for (size_t i = 0; i < geom_subset_children.size(); i++) {

View File

@@ -26,8 +26,8 @@ bool SkelAnimation::get_blendShapeWeights(
const TimeSampleInterpolationType tinterp) {
Animatable<std::vector<float>> v;
if (blendShapeWeights.get_value(&v)) {
// Evaluate at time `tc` with `tinterp` interpolation
return v.ts.get(vals, t, tinterp);
// Evaluate at time `t` with `tinterp` interpolation
return v.get(t, vals, tinterp);
}
return false;
@@ -38,8 +38,8 @@ bool SkelAnimation::get_rotations(std::vector<value::quatf> *vals,
const TimeSampleInterpolationType tinterp) {
Animatable<std::vector<value::quatf>> v;
if (rotations.get_value(&v)) {
// Evaluate at time `tc` with `tinterp` interpolation
return v.ts.get(vals, t, tinterp);
// Evaluate at time `t` with `tinterp` interpolation
return v.get(t, vals, tinterp);
}
return false;
@@ -49,8 +49,8 @@ bool SkelAnimation::get_scales(std::vector<value::half3> *vals, const double t,
const TimeSampleInterpolationType tinterp) {
Animatable<std::vector<value::half3>> v;
if (scales.get_value(&v)) {
// Evaluate at time `tc` with `tinterp` interpolation
return v.ts.get(vals, t, tinterp);
// Evaluate at time `t` with `tinterp` interpolation
return v.get(t, vals, tinterp);
}
return false;
@@ -61,8 +61,8 @@ bool SkelAnimation::get_translations(
const TimeSampleInterpolationType tinterp) {
Animatable<std::vector<value::float3>> v;
if (translations.get_value(&v)) {
// Evaluate at time `tc` with `tinterp` interpolation
return v.ts.get(vals, t, tinterp);
// Evaluate at time `t` with `tinterp` interpolation
return v.get(t, vals, tinterp);
}
return false;

View File

@@ -279,9 +279,63 @@ inline value::float4 operator*(const value::float4 &a, const float b) {
return {a[0] * b, a[1] * b, a[2] * b, a[3] * b};
}
// normal
inline value::normal3f operator+(const value::normal3f &a, const value::normal3f &b) {
return {a[0] + b[0], a[1] + b[1], a[2] + b[2]};
}
inline value::normal3f operator+(const float a, const value::normal3f &b) {
return {a + b[0], a + b[1], a + b[2]};
}
inline value::normal3f operator+(const value::normal3f &a, const float b) {
return {a[0] + b, a[1] + b, a[2] + b};
}
inline value::normal3f operator-(const value::normal3f &a, const value::normal3f &b) {
return {a[0] - b[0], a[1] - b[1], a[2] - b[2]};
}
inline value::normal3f operator-(const float a, const value::normal3f &b) {
return {a - b[0], a - b[1], a - b[2]};
}
inline value::normal3f operator-(const value::normal3f &a, const float b) {
return {a[0] - b, a[1] - b, a[2] - b};
}
inline value::normal3f operator*(const value::normal3f &a, const value::normal3f &b) {
return {a[0] * b[0], a[1] * b[1], a[2] * b[2]};
}
inline value::normal3f operator*(const float a, const value::normal3f &b) {
return {a * b[0], a * b[1], a * b[2]};
}
inline value::normal3f operator*(const value::normal3f &a, const float b) {
return {a[0] * b, a[1] * b, a[2] * b};
}
inline value::normal3f operator/(const value::normal3f &a, const value::normal3f &b) {
return {a[0] / b[0], a[1] / b[1], a[2] / b[2]};
}
inline value::normal3f operator/(const float a, const value::normal3f &b) {
return {a / b[0], a / b[1], a / b[2]};
}
inline value::normal3f operator/(const value::normal3f &a, const float b) {
return {a[0] / b, a[1] / b, a[2] / b};
}
// -- lerp
// no lerp by default
template <typename T>
inline T lerp(const T &a, const T &b, const double t) {
return (1.0 - t) * a + t * b;
(void)b;
(void)t;
return a;
}
template <>
@@ -319,6 +373,11 @@ inline value::float3 lerp(const value::float3 &a, const value::float3 &b, const
return float(1.0 - t) * a + float(t) * b;
}
template <>
inline value::normal3f lerp(const value::normal3f &a, const value::normal3f &b, const double t) {
return float(1.0 - t) * a + float(t) * b;
}
template <>
inline value::float4 lerp(const value::float4 &a, const value::float4 &b, const double t) {
return float(1.0 - t) * a + float(t) * b;

View File

@@ -673,42 +673,49 @@ struct quatd {
struct vector3h {
half x, y, z;
half operator[](size_t idx) const { return *(&x + idx); }
half operator[](size_t idx) { return *(&x + idx); }
};
struct vector3f {
float x, y, z;
float operator[](size_t idx) const { return *(&x + idx); }
float operator[](size_t idx) { return *(&x + idx); }
};
struct vector3d {
double x, y, z;
double operator[](size_t idx) const { return *(&x + idx); }
double operator[](size_t idx) { return *(&x + idx); }
};
struct normal3h {
half x, y, z;
half operator[](size_t idx) const { return *(&x + idx); }
half operator[](size_t idx) { return *(&x + idx); }
};
struct normal3f {
float x, y, z;
float operator[](size_t idx) const { return *(&x + idx); }
float operator[](size_t idx) { return *(&x + idx); }
};
struct normal3d {
double x, y, z;
double operator[](size_t idx) const { return *(&x + idx); }
double operator[](size_t idx) { return *(&x + idx); }
};
struct point3h {
half x, y, z;
half operator[](size_t idx) const { return *(&x + idx); }
half operator[](size_t idx) { return *(&x + idx); }
};
@@ -796,6 +803,7 @@ inline point3h operator/(const point3h &a, const point3h &b) {
struct point3f {
float x, y, z;
float operator[](size_t idx) const { return *(&x + idx); }
float operator[](size_t idx) { return *(&x + idx); }
};
@@ -883,6 +891,7 @@ inline point3f operator/(const point3f &a, const point3f &b) {
struct point3d {
double x, y, z;
double operator[](size_t idx) const { return *(&x + idx); }
double operator[](size_t idx) { return *(&x + idx); }
};
@@ -891,6 +900,7 @@ struct color3h {
// C++11 or later, struct is tightly packed, so use the pointer offset is
// valid.
half operator[](size_t idx) const { return *(&r + idx); }
half operator[](size_t idx) { return *(&r + idx); }
};
@@ -899,6 +909,7 @@ struct color3f {
// C++11 or later, struct is tightly packed, so use the pointer offset is
// valid.
float operator[](size_t idx) const{ return *(&r + idx); }
float operator[](size_t idx) { return *(&r + idx); }
};
@@ -907,6 +918,7 @@ struct color4h {
// C++11 or later, struct is tightly packed, so use the pointer offset is
// valid.
half operator[](size_t idx) const { return *(&r + idx); }
half operator[](size_t idx) { return *(&r + idx); }
};
@@ -915,6 +927,7 @@ struct color4f {
// C++11 or later, struct is tightly packed, so use the pointer offset is
// valid.
float operator[](size_t idx) const { return *(&r + idx); }
float operator[](size_t idx) { return *(&r + idx); }
};
@@ -923,6 +936,7 @@ struct color3d {
// C++11 or later, struct is tightly packed, so use the pointer offset is
// valid.
double operator[](size_t idx) const { return *(&r + idx); }
double operator[](size_t idx) { return *(&r + idx); }
};
@@ -931,6 +945,7 @@ struct color4d {
// C++11 or later, struct is tightly packed, so use the pointer offset is
// valid.
double operator[](size_t idx) const { return *(&r + idx); }
double operator[](size_t idx) { return *(&r + idx); }
};

View File

@@ -10,4 +10,5 @@ def Xform "Bottle" (
string modelingVariant = "Tall"
}
add variantSets = "modelingVariant"
)
) {
}