somehow broke and fixed mesh quantization breaking again after streaming mesh data (need to dequantize first because naively just resetting the descriptors is wrong) (although I might need to update RP3D because collision breaks only when streaming mesh data and DC uses an older version)

This commit is contained in:
ecker 2025-08-15 00:07:13 -05:00
parent ab9aa0ae13
commit d5e58ccb9b
4 changed files with 43 additions and 26 deletions

View File

@ -79,8 +79,8 @@
"tag": "worldspawn",
"player": "info_player_spawn",
"enabled": true, // "auto",
"radius": 32,
"every": 4
"radius": 16,
"every": 1
}
}
}

View File

@ -161,7 +161,6 @@ namespace uf {
// crunge, but it's better this way
uf::stl::vector<uf::stl::string> buffer_paths;
uf::stl::vector<ext::RENDERER::AttributeDescriptor> buffer_descriptors;
protected:
void _destroy( uf::Mesh::Input& input );
void _bind( bool interleaved = uf::Mesh::defaultInterleaved );
@ -303,42 +302,44 @@ namespace uf {
template<typename From, typename To>
void convert() {
// if mesh data is interleaved, skip conversion
if ( this->isInterleaved() ) {
UF_MSG_DEBUG("Downcasting/upcasting requested yet mesh is interleaved, ignoring...");
return;
}
auto fromEnum = uf::renderer::typeToEnum<From>();
auto toEnum = uf::renderer::typeToEnum<To>();
auto toEnum = uf::renderer::typeToEnum<To>();
if ( toEnum == fromEnum ) return;
for ( auto& attribute : this->vertex.attributes ) {
if ( attribute.descriptor.type == toEnum ) continue;
if ( attribute.descriptor.type != fromEnum ) continue;
size_t elementCount = this->vertex.count * attribute.descriptor.components;
size_t elements = this->vertex.count * attribute.descriptor.components;
size_t bytes = elements * sizeof(To);
auto& srcBuffer = this->buffers[attribute.buffer];
if ( srcBuffer.empty() ) continue;
uf::stl::vector<uint8_t> dstBuffer( elementCount * sizeof(To) );
uf::stl::vector<uint8_t> dstBuffer( bytes );
const From* srcPtr = (const From*) (srcBuffer.data());
From* srcPtr = (From*) (srcBuffer.data());
To* dstPtr = (To*) (dstBuffer.data());
if ( toEnum == uf::renderer::enums::Type::USHORT )
for ( size_t i = 0; i < elementCount; ++i ) dstPtr[i] = uf::quant::quantize_f32u16(srcPtr[i]);
else if ( fromEnum == uf::renderer::enums::Type::USHORT )
for ( size_t i = 0; i < elementCount; ++i) dstPtr[i] = uf::quant::dequantize_u16f32(srcPtr[i]);
else
for ( size_t i = 0; i < elementCount; ++i ) dstPtr[i] = (To) srcPtr[i];
if ( toEnum == uf::renderer::enums::Type::USHORT ) {
for ( size_t i = 0; i < elements; ++i ) dstPtr[i] = uf::quant::quantize_f32u16(srcPtr[i]);
} else if ( fromEnum == uf::renderer::enums::Type::USHORT ) {
for ( size_t i = 0; i < elements; ++i ) dstPtr[i] = uf::quant::dequantize_u16f32(srcPtr[i]);
} else {
for ( size_t i = 0; i < elements; ++i ) dstPtr[i] = srcPtr[i];
}
srcBuffer.swap( dstBuffer );
attribute.pointer = (uint8_t*) ( srcBuffer.data() );
attribute.descriptor.type = toEnum;
attribute.descriptor.size = sizeof(To) * attribute.descriptor.components;
attribute.length = sizeof(To) * elementCount;
attribute.length = sizeof(To) * elements;
if ( toEnum == uf::renderer::enums::Type::FLOAT ) {
switch ( attribute.descriptor.components ) {
@ -347,16 +348,14 @@ namespace uf {
case 3: attribute.descriptor.format = uf::renderer::enums::Format::R32G32B32_SFLOAT; break;
case 4: attribute.descriptor.format = uf::renderer::enums::Format::R32G32B32A32_SFLOAT; break;
}
}
else if ( toEnum == uf::renderer::enums::Type::FLOAT16 ) {
} else if ( toEnum == uf::renderer::enums::Type::FLOAT16 ) {
switch ( attribute.descriptor.components ) {
case 1: attribute.descriptor.format = uf::renderer::enums::Format::R16_SFLOAT; break;
case 2: attribute.descriptor.format = uf::renderer::enums::Format::R16G16_SFLOAT; break;
case 3: attribute.descriptor.format = uf::renderer::enums::Format::R16G16B16_SFLOAT; break;
case 4: attribute.descriptor.format = uf::renderer::enums::Format::R16G16B16A16_SFLOAT; break;
}
}
else if ( toEnum == uf::renderer::enums::Type::USHORT ) {
} else if ( toEnum == uf::renderer::enums::Type::USHORT ) {
switch ( attribute.descriptor.components ) {
case 1: attribute.descriptor.format = uf::renderer::enums::Format::R16_UINT; break;
case 2: attribute.descriptor.format = uf::renderer::enums::Format::R16G16_UINT; break;

View File

@ -231,7 +231,6 @@ namespace {
attribute.offset = value["offset"].as(attribute.offset);\
attribute.stride = value["stride"].as(attribute.stride);\
attribute.length = value["length"].as(attribute.length);\
mesh.buffer_descriptors.emplace_back(attribute.descriptor);\
});\
}
@ -242,7 +241,6 @@ namespace {
mesh.buffers.reserve( json["buffers"].size() );
mesh.buffer_paths.reserve( json["buffers"].size() );
mesh.buffer_descriptors.reserve( json["buffers"].size() );
ext::json::forEach( json["buffers"], [&]( ext::json::Value& value ){
const uf::stl::string filename = value.as<uf::stl::string>();
const uf::stl::string directory = uf::io::directory( graph.name );

View File

@ -2127,6 +2127,28 @@ void uf::graph::reload( pod::Graph& graph, pod::Node& node ) {
}
graph.settings.stream.hash = drawCommandHash;
graph.settings.stream.lastUpdate = uf::physics::time::current;
// needs to be dequantized first, naively copying the descriptor settings just doesn't work
{
#if UF_ENV_DREAMCAST && GL_QUANTIZED_SHORT
mesh.convert<uint16_t, float>();
#else
auto conversion = graph.metadata["decode"]["conversion"].as<uf::stl::string>();
if ( conversion != "" ) {
#if UF_USE_FLOAT16
if ( conversion == "float16" ) mesh.convert<float16, float>();
else if ( conversion == "float" ) mesh.convert<float, float16>();
#endif
#if UF_USE_BFLOAT16
if ( conversion == "bfloat16" ) mesh.convert<bfloat16, float>();
else if ( conversion == "float" ) mesh.convert<float, bfloat16>();
#endif
if ( conversion == "uint16_t" ) mesh.convert<uint16_t, float>();
else if ( conversion == "float" ) mesh.convert<float, uint16_t>();
}
#endif
}
// read from disk
#if UF_GRAPH_SPARSE_READ_MESH
// reset counts
@ -2178,7 +2200,6 @@ void uf::graph::reload( pod::Graph& graph, pod::Node& node ) {
if ( ranges.count(attribute.buffer) <= 0 ) { \
mesh.buffers[attribute.buffer].clear();\
} else {\
attribute.descriptor = mesh.buffer_descriptors[attribute.buffer];\
mesh.buffers[attribute.buffer] = uf::io::readAsBuffer( mesh.buffer_paths[attribute.buffer], ranges[attribute.buffer] );\
}\
}
@ -2204,7 +2225,6 @@ void uf::graph::reload( pod::Graph& graph, pod::Node& node ) {
#define STREAM_MESH_DATA( N ) \
for ( auto& attribute : mesh.N.attributes ) {\
if ( !mesh.buffers[attribute.buffer].empty() || mesh.buffer_paths.empty() ) continue;\
attribute.descriptor = mesh.buffer_descriptors[attribute.buffer];\
mesh.buffers[attribute.buffer] = uf::io::readAsBuffer( mesh.buffer_paths[attribute.buffer] );\
}