Skip to content

Commit

Permalink
improve gltf
Browse files Browse the repository at this point in the history
  • Loading branch information
PredatorCZ committed May 9, 2024
1 parent 1c614d5 commit 5f2a8a7
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 18 deletions.
33 changes: 32 additions & 1 deletion include/spike/gltf.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ struct SavedIndices {

struct GLTFModel : GLTF {
std::optional<es::Matrix44> transform;
bool quantizeMesh = false;

SavedIndices GLTF_EXTERN SaveIndices(const void *data, size_t numIndices,
size_t indexSize = 2);
Expand Down Expand Up @@ -143,6 +142,17 @@ struct GLTFModel : GLTF {
return Stream(indexStream);
}

GLTFStream &GetVt16() {
if (vt16Stream < 0) {
auto &str = NewStream("vtStride16", 16);
str.target = gltf::BufferView::TargetType::ArrayBuffer;
vt16Stream = str.slot;
return str;
}

return Stream(vt16Stream);
}

GLTFStream &GetVt12() {
if (vt12Stream < 0) {
auto &str = NewStream("vtStride12", 12);
Expand Down Expand Up @@ -176,9 +186,30 @@ struct GLTFModel : GLTF {
return Stream(vt4Stream);
}

void FinishAndSave(BinWritterRef wr, const std::string &docPath) {
if (useMeshQuantize) {
if (!quantizeFake) {
extensionsRequired.emplace_back("KHR_mesh_quantization");
}
extensionsUsed.emplace_back("KHR_mesh_quantization");
}

GLTF::FinishAndSave(wr, docPath);
}

void QuantizeMesh(bool fake) {
quantizeMesh = true;
quantizeFake = fake;
}

bool quantizeMesh = false;
bool useMeshQuantize = false;

private:
bool quantizeFake = false;
int32 ibmStream = -1;
int32 indexStream = -1;
int32 vt16Stream = -1;
int32 vt12Stream = -1;
int32 vt8Stream = -1;
int32 vt4Stream = -1;
Expand Down
71 changes: 54 additions & 17 deletions src/gltf/gltf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,7 @@ SavedIndices GLTFModel::SaveIndices(const void *data, size_t numIndices,

size_t WritePositions16s(GLTFModel &main,
uni::FormatCodec::fvec &basePosition) {
main.useMeshQuantize = true;
auto &stream = main.GetVt8();
auto [acc, index] = main.NewAccessor(stream, 4);
acc.count = basePosition.size();
Expand All @@ -404,6 +405,7 @@ size_t WritePositions16s(GLTFModel &main,

size_t WritePositions16u(GLTFModel &main,
uni::FormatCodec::fvec &basePosition) {
main.useMeshQuantize = true;
auto &stream = main.GetVt8();
auto [acc, index] = main.NewAccessor(stream, 4);
acc.count = basePosition.size();
Expand Down Expand Up @@ -467,10 +469,10 @@ size_t WriteNormals32(GLTFModel &main, uni::FormatCodec::fvec &normals) {
}

size_t WriteTangents32(GLTFModel &main, uni::FormatCodec::fvec &tangents) {
auto &stream = main.GetVt12();
auto &stream = main.GetVt16();
auto [acc, index] = main.NewAccessor(stream, 4);
acc.count = tangents.size();
acc.type = gltf::Accessor::Type::Vec3;
acc.type = gltf::Accessor::Type::Vec4;
acc.componentType = gltf::Accessor::ComponentType::Float;

for (auto &v : tangents) {
Expand All @@ -484,6 +486,7 @@ size_t WriteTangents32(GLTFModel &main, uni::FormatCodec::fvec &tangents) {
}

size_t WriteNormals16(GLTFModel &main, uni::FormatCodec::fvec &normals) {
main.useMeshQuantize = true;
auto &stream = main.GetVt8();
auto [acc, index] = main.NewAccessor(stream, 4);
acc.count = normals.size();
Expand All @@ -504,6 +507,7 @@ size_t WriteNormals16(GLTFModel &main, uni::FormatCodec::fvec &normals) {
}

size_t WriteNormals8(GLTFModel &main, uni::FormatCodec::fvec &normals) {
main.useMeshQuantize = true;
auto &stream = main.GetVt4();
auto [acc, index] = main.NewAccessor(stream, 4);
acc.count = normals.size();
Expand All @@ -524,6 +528,7 @@ size_t WriteNormals8(GLTFModel &main, uni::FormatCodec::fvec &normals) {
}

size_t WriteTexcoord16s(GLTFModel &main, uni::FormatCodec::fvec &coords) {
main.useMeshQuantize = true;
auto &stream = main.GetVt4();
auto [acc, index] = main.NewAccessor(stream, 4);
acc.count = coords.size();
Expand Down Expand Up @@ -657,32 +662,37 @@ size_t SaveTangents(GLTFModel &main, const char *data, size_t numVertices,
return WriteTangents32(main, tangents);
}

switch (attribute.type) {
case uni::DataType::R8G8B8A8:
return WriteNormals8(main, tangents);
default:
return WriteNormals16(main, tangents);
}
size_t accIndex = [&] {
switch (attribute.type) {
case uni::DataType::R8G8B8A8:
return WriteNormals8(main, tangents);
default:
return WriteNormals16(main, tangents);
}
}();

main.accessors.at(accIndex).type = gltf::Accessor::Type::Vec4;
return accIndex;
}

size_t SaveTexcoords(GLTFModel &main, const char *data, size_t numVertices,
Attribute attribute, size_t stride) {
uni::FormatCodec::fvec coords =
SampleAttribute(data, numVertices, attribute, stride);

if (!main.quantizeMesh ||
(attribute.customCodec && !attribute.customCodec->IsNormalized())) {
if (attribute.customCodec && !attribute.customCodec->IsNormalized()) {
return WriteTexcoord32(main, coords);
}

switch (attribute.format) {
case uni::FormatType::NORM:
return WriteTexcoord16s(main, coords);
case uni::FormatType::UNORM:
if (attribute.format == uni::FormatType::UNORM) {
return WriteTexcoord16u(main, coords);
default:
return WriteTexcoord32(main, coords);
}

if (main.quantizeMesh && attribute.format == uni::FormatType::NORM) {
return WriteTexcoord16s(main, coords);
}

return WriteTexcoord32(main, coords);
}

size_t SaveColor(GLTFModel &main, const char *data, size_t numVertices,
Expand Down Expand Up @@ -938,6 +948,33 @@ gltf::Attributes GLTFModel::SaveVertices(const void *data, size_t numVertices,
}
}

if (weightElement > 1) {
for (size_t idx = 0; auto &bw : weightsBuffer) {
BWBuffer &bones = bonesBuffer.at(idx++);
BWBuffer newBones{};
BWBuffer newWeights{};
uint8 curBone = 0;

for (int16 ci = -1; uint8 c : bones.data) {
if (c == 0xff || bw.data[++ci] == 0) {
continue;
}

for (uint8 b = 0; b < 8; b++) {
if (bones.data[b] == c) {
bones.data[b] = -1;
newWeights.data[curBone] += bw.data[b];
}
}

newBones.data[curBone++] = c;
}

bw = newWeights;
bones = newBones;
}
}

if (boneElement > 4) {
auto &stream = GetVt8();
auto [acc0, index0] = NewAccessor(stream, 4);
Expand Down Expand Up @@ -981,7 +1018,7 @@ gltf::Attributes GLTFModel::SaveVertices(const void *data, size_t numVertices,
acc1.componentType = gltf::Accessor::ComponentType::UnsignedByte;
acc1.type = gltf::Accessor::Type::Vec4;

if (weightElement == 0) {
if (weightsBuffer.empty()) {
for (size_t v = 0; v < numVertices; v++) {
stream.wr.Write(0xff);
}
Expand Down

0 comments on commit 5f2a8a7

Please sign in to comment.