Skip to content

Commit

Permalink
Merge pull request #538 from CesiumGS/custom-vertex-attributes
Browse files Browse the repository at this point in the history
Add support for custom vertex attributes
  • Loading branch information
lilleyse authored Nov 3, 2023
2 parents dca3ab4 + 6e4d9ce commit f8329b6
Show file tree
Hide file tree
Showing 13 changed files with 673 additions and 174 deletions.
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Change Log

### v0.14.0 - 2023-12-01

* Added support for custom vertex attributes. Custom attributes can be accessed by their glTF attribute name with the primvar lookup functions in MDL, e.g. `data_lookup_int` and `data_lookup_float`.

### v0.13.0 - 2023-11-01

* Changing certain tileset properties no longer triggers a tileset reload.
Expand Down
2 changes: 1 addition & 1 deletion exts/cesium.omniverse/mdl/cesium.mdl
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ float4 compute_base_color(

auto base_color = base_color_texture.valid ? base_color_texture.value : float4(1.0);
base_color *= float4(base_color_factor_float3.x, base_color_factor_float3.y, base_color_factor_float3.z, base_alpha);
base_color *= ::scene::data_lookup_float4("vertexColor", float4(1.0));
base_color *= ::scene::data_lookup_float4("COLOR_0", float4(1.0));
base_color = alpha_blend(imagery_layers_texture.value, base_color);
base_color *= tile_color;

Expand Down
7 changes: 7 additions & 0 deletions src/core/include/cesium/omniverse/FabricGeometryDefinition.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#pragma once

#include "cesium/omniverse/GltfUtil.h"

#include <cstdint>
#include <set>

namespace CesiumGltf {
struct MeshPrimitive;
Expand All @@ -19,13 +22,17 @@ class FabricGeometryDefinition {
[[nodiscard]] bool hasNormals() const;
[[nodiscard]] bool hasVertexColors() const;
[[nodiscard]] uint64_t getTexcoordSetCount() const;
[[nodiscard]] const std::set<VertexAttributeInfo>& getCustomVertexAttributes() const;

bool operator==(const FabricGeometryDefinition& other) const;

private:
bool _hasNormals{false};
bool _hasVertexColors{false};
uint64_t _texcoordSetCount{0};

// std::set is sorted which is important for checking FabricGeometryDefinition equality
std::set<VertexAttributeInfo> _customVertexAttributes;
};

} // namespace cesium::omniverse
26 changes: 25 additions & 1 deletion src/core/include/cesium/omniverse/GltfAccessors.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once

#include "cesium/omniverse/VertexAttributeType.h"

#ifdef CESIUM_OMNI_MSVC
#pragma push_macro("OPAQUE")
#undef OPAQUE
Expand Down Expand Up @@ -89,7 +91,14 @@ class VertexColorsAccessor {
VertexColorsAccessor(const CesiumGltf::AccessorView<glm::fvec3>& float32Vec3View);
VertexColorsAccessor(const CesiumGltf::AccessorView<glm::fvec4>& float32Vec4View);

void fill(const gsl::span<glm::fvec4>& values) const;
/**
* @brief Copy accessor values to the given output values, including any data transformations.
*
* @param values The output values.
* @param repeat Indicates how many times each value in the accessor should be repeated in the output. Typically repeat is 1, but for voxel point clouds repeat is 8.
*/
void fill(const gsl::span<glm::fvec4>& values, uint64_t repeat = 1) const;

[[nodiscard]] uint64_t size() const;

private:
Expand All @@ -115,4 +124,19 @@ class FaceVertexCountsAccessor {
uint64_t _size;
};

template <VertexAttributeType T> class VertexAttributeAccessor {
public:
VertexAttributeAccessor();
VertexAttributeAccessor(const CesiumGltf::AccessorView<GetNativeType<T>>& view, bool normalized);

void fill(const gsl::span<GetFabricType<T>>& values, uint64_t repeat = 1) const;

[[nodiscard]] uint64_t size() const;

private:
CesiumGltf::AccessorView<GetNativeType<T>> _view;
uint64_t _size;
bool _normalized;
};

} // namespace cesium::omniverse
24 changes: 24 additions & 0 deletions src/core/include/cesium/omniverse/GltfUtil.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
#pragma once

#include "cesium/omniverse/GltfAccessors.h"
#include "cesium/omniverse/VertexAttributeType.h"

#include <CesiumGltf/Accessor.h>
#include <glm/glm.hpp>
#include <omni/fabric/core/FabricTypes.h>

#include <set>

namespace CesiumGltf {
struct ImageCesium;
Expand Down Expand Up @@ -49,6 +54,16 @@ struct MaterialInfo {
bool operator==(const MaterialInfo& other) const;
};

struct VertexAttributeInfo {
VertexAttributeType type;
omni::fabric::Token fabricAttributeName;
std::string gltfAttributeName;

// Make sure to update this function when adding new fields to the struct
bool operator==(const VertexAttributeInfo& other) const;
bool operator<(const VertexAttributeInfo& other) const;
};

} // namespace cesium::omniverse

namespace cesium::omniverse::GltfUtil {
Expand Down Expand Up @@ -81,11 +96,20 @@ getImageryTexcoords(const CesiumGltf::Model& model, const CesiumGltf::MeshPrimit
VertexColorsAccessor
getVertexColors(const CesiumGltf::Model& model, const CesiumGltf::MeshPrimitive& primitive, uint64_t setIndex);

template <VertexAttributeType T>
VertexAttributeAccessor<T> getVertexAttributeValues(
const CesiumGltf::Model& model,
const CesiumGltf::MeshPrimitive& primitive,
const std::string& attributeName);

const CesiumGltf::ImageCesium*
getBaseColorTextureImage(const CesiumGltf::Model& model, const CesiumGltf::MeshPrimitive& primitive);

MaterialInfo getMaterialInfo(const CesiumGltf::Model& model, const CesiumGltf::MeshPrimitive& primitive);

std::set<VertexAttributeInfo>
getCustomVertexAttributes(const CesiumGltf::Model& model, const CesiumGltf::MeshPrimitive& primitive);

MaterialInfo getDefaultMaterialInfo();
TextureInfo getDefaultTextureInfo();

Expand Down
4 changes: 2 additions & 2 deletions src/core/include/cesium/omniverse/Tokens.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ __pragma(warning(push)) __pragma(warning(disable : 4003))
((primvars_st_7, "primvars:st_7")) \
((primvars_st_8, "primvars:st_8")) \
((primvars_st_9, "primvars:st_9")) \
((primvars_vertexColor, "primvars:vertexColor")) \
((primvars_COLOR_0, "primvars:COLOR_0")) \
((xformOp_transform_cesium, "xformOp:transform:cesium"))

TF_DECLARE_PUBLIC_TOKENS(UsdTokens, USD_TOKENS);
Expand Down Expand Up @@ -250,7 +250,7 @@ const omni::fabric::Type primvarInterpolations(omni::fabric::BaseDataType::eToke
const omni::fabric::Type primvars(omni::fabric::BaseDataType::eToken, 1, 1, omni::fabric::AttributeRole::eNone);
const omni::fabric::Type primvars_normals(omni::fabric::BaseDataType::eFloat, 3, 1, omni::fabric::AttributeRole::eNormal);
const omni::fabric::Type primvars_st(omni::fabric::BaseDataType::eFloat, 2, 1, omni::fabric::AttributeRole::eTexCoord);
const omni::fabric::Type primvars_vertexColor(omni::fabric::BaseDataType::eFloat, 4, 1, omni::fabric::AttributeRole::eNone);
const omni::fabric::Type primvars_COLOR_0(omni::fabric::BaseDataType::eFloat, 4, 1, omni::fabric::AttributeRole::eNone);
const omni::fabric::Type Shader(omni::fabric::BaseDataType::eTag, 1, 0, omni::fabric::AttributeRole::ePrimTypeName);
const omni::fabric::Type subdivisionScheme(omni::fabric::BaseDataType::eToken, 1, 0, omni::fabric::AttributeRole::eNone);
const omni::fabric::Type _cesium_localToEcefTransform(omni::fabric::BaseDataType::eDouble, 16, 0, omni::fabric::AttributeRole::eMatrix);
Expand Down
89 changes: 89 additions & 0 deletions src/core/include/cesium/omniverse/VertexAttributeType.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#pragma once

#include <glm/glm.hpp>
#include <omni/fabric/FabricTypes.h>

#include <optional>
#include <string>

namespace cesium::omniverse {

enum class VertexAttributeType {
UINT8,
INT8,
UINT16,
INT16,
FLOAT32,
VEC2_UINT8,
VEC2_INT8,
VEC2_UINT16,
VEC2_INT16,
VEC2_FLOAT32,
VEC3_UINT8,
VEC3_INT8,
VEC3_UINT16,
VEC3_INT16,
VEC3_FLOAT32,
VEC4_UINT8,
VEC4_INT8,
VEC4_UINT16,
VEC4_INT16,
VEC4_FLOAT32,
};

std::optional<VertexAttributeType> getVertexAttributeTypeFromGltf(const std::string& type, int32_t componentType);
omni::fabric::Type getFabricType(VertexAttributeType type);

template <VertexAttributeType T> struct GetNativeTypeImpl;
template <> struct GetNativeTypeImpl<VertexAttributeType::UINT8> { using Type = glm::u8vec1; };
template <> struct GetNativeTypeImpl<VertexAttributeType::INT8> { using Type = glm::i8vec1; };
template <> struct GetNativeTypeImpl<VertexAttributeType::UINT16> { using Type = glm::u16vec1; };
template <> struct GetNativeTypeImpl<VertexAttributeType::INT16> { using Type = glm::i16vec1; };
template <> struct GetNativeTypeImpl<VertexAttributeType::FLOAT32> { using Type = glm::f32vec1; };
template <> struct GetNativeTypeImpl<VertexAttributeType::VEC2_UINT8> { using Type = glm::u8vec2; };
template <> struct GetNativeTypeImpl<VertexAttributeType::VEC2_INT8> { using Type = glm::i8vec2; };
template <> struct GetNativeTypeImpl<VertexAttributeType::VEC2_UINT16> { using Type = glm::u16vec2; };
template <> struct GetNativeTypeImpl<VertexAttributeType::VEC2_INT16> { using Type = glm::i16vec2; };
template <> struct GetNativeTypeImpl<VertexAttributeType::VEC2_FLOAT32> { using Type = glm::f32vec2; };
template <> struct GetNativeTypeImpl<VertexAttributeType::VEC3_UINT8> { using Type = glm::u8vec3; };
template <> struct GetNativeTypeImpl<VertexAttributeType::VEC3_INT8> { using Type = glm::i8vec3; };
template <> struct GetNativeTypeImpl<VertexAttributeType::VEC3_UINT16> { using Type = glm::u16vec3; };
template <> struct GetNativeTypeImpl<VertexAttributeType::VEC3_INT16> { using Type = glm::i16vec3; };
template <> struct GetNativeTypeImpl<VertexAttributeType::VEC3_FLOAT32> { using Type = glm::f32vec3; };
template <> struct GetNativeTypeImpl<VertexAttributeType::VEC4_UINT8> { using Type = glm::u8vec4; };
template <> struct GetNativeTypeImpl<VertexAttributeType::VEC4_INT8> { using Type = glm::i8vec4; };
template <> struct GetNativeTypeImpl<VertexAttributeType::VEC4_UINT16> { using Type = glm::u16vec4; };
template <> struct GetNativeTypeImpl<VertexAttributeType::VEC4_INT16> { using Type = glm::i16vec4; };
template <> struct GetNativeTypeImpl<VertexAttributeType::VEC4_FLOAT32> { using Type = glm::f32vec4; };

// Integer primvar lookup doesn't seem to work so cast all data types to float. This is safe to do since
// FLOAT32 can represent all possible UINT8, INT8, UINT16, and INT16 values. Also not a significant memory
// overhead since Fabric doesn't support INT8, UINT16, and INT16 types anyways.
//
// Float is also a convenient data type for storing normalized attributes, which are normalized prior to Fabric upload
template <VertexAttributeType T> struct GetFabricTypeImpl;
template <> struct GetFabricTypeImpl<VertexAttributeType::UINT8> { using Type = glm::f32vec1; };
template <> struct GetFabricTypeImpl<VertexAttributeType::INT8> { using Type = glm::f32vec1; };
template <> struct GetFabricTypeImpl<VertexAttributeType::UINT16> { using Type = glm::f32vec1; };
template <> struct GetFabricTypeImpl<VertexAttributeType::INT16> { using Type = glm::f32vec1; };
template <> struct GetFabricTypeImpl<VertexAttributeType::FLOAT32> { using Type = glm::f32vec1; };
template <> struct GetFabricTypeImpl<VertexAttributeType::VEC2_UINT8> { using Type = glm::f32vec2; };
template <> struct GetFabricTypeImpl<VertexAttributeType::VEC2_INT8> { using Type = glm::f32vec2; };
template <> struct GetFabricTypeImpl<VertexAttributeType::VEC2_UINT16> { using Type = glm::f32vec2; };
template <> struct GetFabricTypeImpl<VertexAttributeType::VEC2_INT16> { using Type = glm::f32vec2; };
template <> struct GetFabricTypeImpl<VertexAttributeType::VEC2_FLOAT32> { using Type = glm::f32vec2; };
template <> struct GetFabricTypeImpl<VertexAttributeType::VEC3_UINT8> { using Type = glm::f32vec3; };
template <> struct GetFabricTypeImpl<VertexAttributeType::VEC3_INT8> { using Type = glm::f32vec3; };
template <> struct GetFabricTypeImpl<VertexAttributeType::VEC3_UINT16> { using Type = glm::f32vec3; };
template <> struct GetFabricTypeImpl<VertexAttributeType::VEC3_INT16> { using Type = glm::f32vec3; };
template <> struct GetFabricTypeImpl<VertexAttributeType::VEC3_FLOAT32> { using Type = glm::f32vec3; };
template <> struct GetFabricTypeImpl<VertexAttributeType::VEC4_UINT8> { using Type = glm::f32vec4; };
template <> struct GetFabricTypeImpl<VertexAttributeType::VEC4_INT8> { using Type = glm::f32vec4; };
template <> struct GetFabricTypeImpl<VertexAttributeType::VEC4_UINT16> { using Type = glm::f32vec4; };
template <> struct GetFabricTypeImpl<VertexAttributeType::VEC4_INT16> { using Type = glm::f32vec4; };
template <> struct GetFabricTypeImpl<VertexAttributeType::VEC4_FLOAT32> { using Type = glm::f32vec4; };

template <VertexAttributeType T> using GetNativeType = typename GetNativeTypeImpl<T>::Type;
template <VertexAttributeType T> using GetFabricType = typename GetFabricTypeImpl<T>::Type;

} // namespace cesium::omniverse
Loading

0 comments on commit f8329b6

Please sign in to comment.