Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Byte offset greater than byte length #34

Closed
milosrs opened this issue Mar 25, 2019 · 4 comments
Closed

Byte offset greater than byte length #34

milosrs opened this issue Mar 25, 2019 · 4 comments

Comments

@milosrs
Copy link

milosrs commented Mar 25, 2019

I'm trying to read data from scene.bin file into memory. I am achieving this with this piece of code.

`

		if (bufferInfo.buffersAccessors.buffer.uri.length() > 0 || bufferInfo.buffersAccessors.buffer.byteLength > 0) {
		Microsoft::glTF::Buffer buffer = bufferInfo.buffersAccessors.buffer;
		
		path += bufferInfo.buffersAccessors.buffer.uri;
		path = std::filesystem::absolute(path);
		buffer.uri = path.string();

		std::shared_ptr<StreamReader> streamReader = std::make_shared<StreamReader>(path);
		Microsoft::glTF::GLTFResourceReader reader(streamReader);

		stream = reader.ReadBinaryData<T>(buffer, bufferInfo.buffersAccessors.view);
	}`

Then I simply do this.

`

	const size_t bufferDataOffset = mainPart.accessor.byteOffset + mainPart.view.byteOffset;

	bufferData.erase(bufferData.begin(), bufferData.begin() + bufferDataOffset);

	bufferInfo.bufferData = bufferData;`

When I'm trying to read attribute TEXCOORD_0 of MeshPrimitive from scene.bin file, I always get a situation where ByteOfsset is greater than ByteLength. This results in a crash at bufferData.erase(). What should I do in these situations? Is my offset calculation even correct?

@chriche-ms
Copy link
Member

If you just want to read MeshPrimitive attribute data then I would suggest using the ReadBinaryData overload that accepts an Accessor parameter. The code looks like:

std::string accessorId;

if (meshPrimitive.TryGetAttributeAccessorId(ACCESSOR_TEXCOORD_0, accessorId))
{
    const Accessor& accessor = document.accessors.Get(accessorId);
    const auto data = resourceReader.ReadBinaryData<T>(document, accessor);
}

Where data is a vector containing the accessor's data. This way you can let the glTF SDK do all the offset calculations for you.

Also, I recommend that you do any path manipulation in your StreamReader implementation and avoid modifying the Document whenever possible.

@agrittmsft
Copy link
Contributor

You could also use MeshPrimitiveUtils::GetTexCoords(_0):

std::vector<float> GetTexCoords(const Document& doc, const GLTFResourceReader& reader, const Accessor& accessor);
std::vector<float> GetTexCoords_0(const Document& doc, const GLTFResourceReader& reader, const MeshPrimitive& meshPrimitive);

@milosrs
Copy link
Author

milosrs commented Mar 26, 2019

Both work like a charm. Thanks!

@chriche-ms
Copy link
Member

Original code snippet is mixing byte offsets with vector element indices. Solution is to either add bufferDataOffset / sizeof(T) or use higher level functionality such as MeshPrimitiveUtils::GetTexCoords

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants