-
Notifications
You must be signed in to change notification settings - Fork 0
Description
When decoding a Draco-encoded mesh that includes additional vertex attributes (e.g., normals, colors), decoding fails with:
java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 48819
at dev.fileformat.drako.MeshAttributeCornerTable.vertex(MeshAttributeCornerTable.java:288)
at dev.fileformat.drako.MeshEdgeBreakerDecoderImpl.assignPointsToCorners(MeshEdgeBreakerDecoderImpl.java:783)
at dev.fileformat.drako.MeshEdgeBreakerDecoderImpl.decodeConnectivity(MeshEdgeBreakerDecoderImpl.java:692)
...
(Number of positions: 23960,
Number of normals: 23960,
Number of indices: 48819
…)
Encoding and decoding the same mesh with only positions and indices works correctly. Adding any additional attribute (e.g., normals or colors) consistently causes this failure.
Environment
Library: dev.fileformat:drako:1.4.1/1.4.2
JDK 17
Platform: Windows 10
Observed Behavior
If only positions + indices are encoded → decoding succeeds.
Adding any extra attribute (e.g., normals, colors) → decoding throws the exception.
Removing any 7 indices (reducing index count from 48,819 to 48,812) → decoding succeeds again.
The same behavior occurs across multiple library versions.
Debug Findings
The error occurs inside MeshEdgeBreakerDecoderImpl.decodeConnectivity(), specifically in assignPointsToCorners() around this loop:
for (int v = 0; v < this.cornerTable.getNumVertices(); ++v) {
int c = this.cornerTable.leftMostCorner(v);
...
for (int i = 0; i < this.attributeData.length; ++i) {
if (this.attributeData[i].connectivityData.isCornerOnSeam(c)) {
int vertId = this.attributeData[i].connectivityData.vertex(c);
int actC = this.cornerTable.swingRight(c);
for (boolean seamFound = false; actC != c; actC = this.cornerTable.swingRight(actC)) {
if (this.attributeData[i].connectivityData.vertex(actC) != vertId) {
deduplicationFirstCorner = actC;
seamFound = true;
break;
}
}
...
}
}
}
In the failing case, actC becomes -1 when calling cornerTable.swingRight(actC).
This leads to accessing cornerToVertexMap[-1] → exception.
The fact that decoding succeeds when only positions are present suggests that the attribute connectivity (or corner-to-vertex mapping) becomes inconsistent across attributes.
Hypothesis
The bug appears to stem from a missing guard or incorrect assumption in assignPointsToCorners() — it assumes that swingRight() always returns a valid corner index (>= 0), but when geometry or attribute connectivity degenerates, it can return -1.
Expected Outcome
The decoder should be able to decode the DracoMesh object encoded by itself.