-
Notifications
You must be signed in to change notification settings - Fork 3
Description
First of all: Thanks for providing this library! This library is the only promising solution for decoding Draco in Java that I found until now. The context where I'm trying to use this library is for decoding Draco data from glTF assets. And I managed to decode several test assets. But there are two things that do not seem to work right now.
(I have not yet "deeply" investigated this - eventually, this issue may have to be split up into two separate issues).
Here is an archive that contains two Draco encoded files:
opeinize-drako-java issue data 2026-01-28.zip
They are extracted from the following glTF Sample Assets:
- https://github.com/KhronosGroup/glTF-Sample-Assets/tree/main/Models/RiggedSimple
- https://github.com/KhronosGroup/glTF-Sample-Assets/tree/main/Models/SunglassesKhronos
The files contain the data of the buffer view (as mentioned in their name) that contains the encoded data.
The following is a small test for reading these files and printing the corresponding draco meshes:
package de.javagl.jme.draco;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import dev.fileformat.drako.Draco;
import dev.fileformat.drako.DracoMesh;
import dev.fileformat.drako.PointAttribute;
public class JmeDracoTestOnly {
public static void main(String[] args) throws Exception {
readAndPrint("./data/RiggedSimple_bufferView4.bin");
readAndPrint("./data/SunglassesKhronos_bufferView0.bin");
}
private static void readAndPrint(String fileName) throws Exception
{
byte[] bytes = Files.readAllBytes(Paths.get(fileName));
DracoMesh dracoMesh = (DracoMesh) Draco.decode(bytes);
System.out.println("dracoMesh " + dracoMesh);
if (dracoMesh == null) {
return;
}
int n = dracoMesh.getNumAttributes();
for (int i = 0; i < n; i++) {
PointAttribute attribute = dracoMesh.attribute(i);
System.out.println("Attribute " + i + " is " + attribute);
byte[] rawData = attribute.getBuffer().getBuffer();
System.out.println(" First 100 bytes of raw data: " + Arrays.toString(Arrays.copyOf(rawData, 100)));
}
}
}For the RiggedSimple_bufferView4.bin, the issue is that the data of the first attribute does not seem to be decoded. In particular, this is the data that is the JOINTS_0 attribute from the glTF file. So it is not one of the simple (position/normal/texcoord...) attributes. Instead, it is an attribute that contains the joint indices for vertex skinning, as unsigned short values. It prints
Attribute 0 is #0 4 : 4[4]
First 100 bytes of raw data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
I.e. the decoded data seems to be all zeros.
Note that this applies to all models that contain vertex skinning. So apparently, this type of data/attribute is not handled properly.
For the SunglassesKhronos_bufferView0.bin, there is another issue: Trying to read this data will return null. With some debugging, I found that the reason is that the quantizationBits that are read in SequentialQuantizationAttributeDecoder#decodeQuantizedDataInfo are invalid - they are -88 (turning into 168 with the signed conversion).
To my understanding, this part should reflect the ParseQuantizationBits from the spec, which is a U8, but I don't know where the wrong value is coming from right now.
One thing that will also (likely) prevent this data from being read properly: There is a bug in Unsafe#toFloatArray. The for-loop is checking i < ret.length, but that should be d < ret.length. For example, for a 3-element float[] ret array, it will only decode the first value.
(I could open a PR for this, but would wait for further feedback or thoughts here...)