Comments (7)
This would be great - gltfpack doesn't support sparse data atm either. Transparent support would be much appreciated.
I see two ways to do it:
-
Provide a function to convert from sparse to dense storage. Clients would call it first, and then read_float would work as is. There's a memory cost to that, but the implementation gets to be very simple.
-
Automatically extract sparse data. The indices in sparse accessors are sorted so a simple implementation could involve a binary search through indices. If we wanted to optimize this further, we could cache the last accessed index and start by checking if the index requested is between this and the next one, but probably binary search alone is reasonably practical.
Also read_float currently fails for zero-filled accessors (you can specify an accessor without a buffer view even in absence of sparse data), which would be great to fix as well.
from cgltf.
I like your option 1. Maybe we keep read_float as-is and add a slightly higher-level API that looks like this:
cgltf_size cgltf_accessor_unpack_floats(const cgltf_accessor* accessor,
cgltf_float* out, cgltf_size count);
Clients could call this instead of the one-at-a-time API, and they could do so without even bothering to check if the accessor is sparse or non-sparse.
The primary purpose of the count is to verify that enough space exists at the destination address. It could also be used to extract only the first few elements but that's just a side effect. As per our February discussion, we don't need to support a custom range (i.e. an offset), since it's best to keep the API simple.
Some details: the returned count is the number of floats actually written, which might be less than the provided count. If out
is null, this function returns the number of required floats (which is cgltf_num_components(accessor->type) * accessor->count
).
from cgltf.
With unpack_floats, what would the count
argument mean? Component count of each element?
For gltfpack use, there's three key areas where read_float is utilized right now:
- Reading vertex component data - this can be trivially converted to unpack_floats, if it takes a custom element count (4 in this case) as an input.
for (size_t i = 0; i < attr.data->count; ++i)
cgltf_accessor_read_float(attr.data, i, s.data[i].f, 4);
- Reading skin matrices - this reads a matrix at a time right now but can be converted to unpack_floats without too much trouble:
cgltf_accessor_read_float(skin.inverse_bind_matrices, j, transform, 16);
- Reading animation data. This code is really complex :-/ it can probably benefit from using unpack_floats if the entire animation track is unpacked first - I think this would work. This is the only part that isn't very straightforward because the code is reading one animated element at a time at indices that are complex, e.g.
case cgltf_interpolation_type_cubic_spline:
{
Attr v0 = {};
Attr b0 = {};
Attr a1 = {};
Attr v1 = {};
cgltf_accessor_read_float(sampler.output, (cursor * 3 + 1) * components + j, v0.f, 4);
cgltf_accessor_read_float(sampler.output, (cursor * 3 + 2) * components + j, b0.f, 4);
cgltf_accessor_read_float(sampler.output, (cursor * 3 + 3) * components + j, a1.f, 4);
cgltf_accessor_read_float(sampler.output, (cursor * 3 + 4) * components + j, v1.f, 4);
data.push_back(interpolateHermite(v0, b0, v1, a1, t, range, type));
}
from cgltf.
Count is the requested number of floats. To read one 4x4 matrix, it would be 16. The actual number of floats written would be the min of the number of requested floats and required floats.
from cgltf.
This would require knowing the component count - note that cgltf_num_components isn't exposed right now.
from cgltf.
Yes, I think we should also expose the num_components function (which, incidentally, is also useful for users of the existing one-at-a-time API). Also, note that clients can pass null to the unpack function to get a total float count.
from cgltf.
Good news: this will be only ~25 lines of code.
However one issue is that the glTF spec is unclear in how to treat accessor->sparse.values_byte_offset
: does it add to or replace the offset in the base accessor?
EDIT: It must be replace since the buffer view is replaced as well; the source val array is decoupled from the dest val array.
from cgltf.
Related Issues (20)
- cgltf_parse_file can crash with custom file_open, should not call memory_free HOT 6
- KHR_texture_transform: how to check existence of texCoord? HOT 3
- _ftelli64 does not compile on Windows when using zig cc (clang, mingw64) HOT 3
- Handling escaped json strings HOT 2
- Improved error output HOT 9
- cgltf_load_buffer_base64 returns cgltf_result_io_error for what seems to valid base64 HOT 1
- [Feature] add new KHR_mesh_quantization extension HOT 5
- cgltf_image::buffer_view::data is null HOT 2
- glb binary texture data HOT 4
- cgltf_write accessor is missing stride property HOT 1
- cgltf_write to buffer ignores options -> can't create an in-memory GLB
- write buffer_view should write TARGET
- The reference information regarding the use of cgltf_load_buffer_base64 is unclear
- Extras for cgltf_light are ignored while writing
- 2 GB+ json parser support HOT 5
- Loading this file causes a crash. HOT 4
- Suggestion: store indices instead of pointers in the data structures HOT 4
- Add support for MSFT_texture_dds extension HOT 1
- Potential Undefined Behaviour in "cgltf_component_read_index"
- How to enable draco support? HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cgltf.