const RWGltf_JsonValue* aTypeStr = findObjectMember (theAccessor, "type");
const RWGltf_JsonValue* aBufferViewName = findObjectMember (theAccessor, "bufferView");
const RWGltf_JsonValue* aByteOffset = findObjectMember (theAccessor, "byteOffset");
- const RWGltf_JsonValue* aByteStride = findObjectMember (theAccessor, "byteStride");
+ const RWGltf_JsonValue* aByteStride = findObjectMember (theAccessor, "byteStride"); // byteStride was part of bufferView in glTF 1.0
const RWGltf_JsonValue* aCompType = findObjectMember (theAccessor, "componentType");
const RWGltf_JsonValue* aCount = findObjectMember (theAccessor, "count");
if (aTypeStr == NULL
const RWGltf_JsonValue* aBufferName = findObjectMember (theBufferView, "buffer");
const RWGltf_JsonValue* aByteLength = findObjectMember (theBufferView, "byteLength");
const RWGltf_JsonValue* aByteOffset = findObjectMember (theBufferView, "byteOffset");
+ const RWGltf_JsonValue* aByteStride = findObjectMember (theBufferView, "byteStride"); // byteStride is part of bufferView since glTF 2.0
const RWGltf_JsonValue* aTarget = findObjectMember (theBufferView, "target");
if (aBufferName == NULL)
{
aBuffView.ByteLength = aByteLength != NULL && aByteLength->IsNumber()
? (int64_t )aByteLength->GetDouble()
: 0;
+ aBuffView.ByteStride = aByteStride != NULL && aByteStride->IsInt()
+ ? aByteStride->GetInt()
+ : 0;
if (aTarget != NULL && aTarget->IsInt())
{
aBuffView.Target = (RWGltf_GltfBufferViewTarget )aTarget->GetInt();
reportGltfError ("BufferView '" + theName + "' defines invalid byteOffset.");
return false;
}
+ else if (aBuffView.ByteStride < 0
+ || aBuffView.ByteStride > 255)
+ {
+ reportGltfError ("BufferView '" + theName + "' defines invalid byteStride.");
+ return false;
+ }
const RWGltf_JsonValue* aBuffer = myGltfRoots[RWGltf_GltfRootElement_Buffers].FindChild (*aBufferName);
if (aBuffer == NULL
const RWGltf_JsonValue* anUriVal = findObjectMember (theBuffer, "uri");
int64_t anOffset = theView.ByteOffset + theAccessor.ByteOffset;
+ const int32_t aByteStride = theAccessor.ByteStride != 0 ? theView.ByteStride : theView.ByteStride;
bool isBinary = false;
if (myIsBinary)
{
RWGltf_GltfPrimArrayData& aData = theMeshData->AddPrimArrayData (theType);
aData.Accessor = theAccessor;
+ aData.Accessor.ByteStride = aByteStride;
aData.StreamOffset = anOffset;
aData.StreamUri = myFilePath;
return true;
{
RWGltf_GltfPrimArrayData& aData = theMeshData->AddPrimArrayData (theType);
aData.Accessor = theAccessor;
+ aData.Accessor.ByteStride = aByteStride;
aData.StreamOffset = anOffset;
if (!myDecodedBuffers.Find (theName, aData.StreamData))
{
RWGltf_GltfPrimArrayData& aData = theMeshData->AddPrimArrayData (theType);
aData.Accessor = theAccessor;
+ aData.Accessor.ByteStride = aByteStride;
aData.StreamOffset = anOffset;
aData.StreamUri = myFolder + anUri;
if (myExternalFiles != NULL)
--- /dev/null
+puts "========"
+puts "0031332: Data Exchange - RWGltf_CafReader ignores bufferView.byteStride within glTF 2.0"
+puts "========"
+
+# glTF file content
+set cubeGltf {
+{
+"asset": {"generator": "","version": "2.0"},
+"scene": 0,
+"scenes": [{"nodes": [0]}],
+"nodes": [{"children": [1],"matrix": [1.0,0.0,0.0,0.0,0.0,0.0,-1.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,1.0]},{"mesh": 0}],
+"meshes": [{"primitives": [{"attributes": {"NORMAL": 1,"POSITION": 2},"indices": 0,"mode": 4,"material": 0}],"name": "Mesh"}],
+"accessors": [
+{"bufferView": 0,"byteOffset": 0, "componentType": 5123,"count": 36,"max": [23],"min": [0],"type": "SCALAR"},
+{"bufferView": 1,"byteOffset": 0, "componentType": 5126,"count": 24,"max": [1.0,1.0,1.0],"min": [-1.0,-1.0,-1.0],"type": "VEC3"},
+{"bufferView": 1,"byteOffset": 12,"componentType": 5126,"count": 24,"max": [0.5,0.5,0.5],"min": [-0.5,-0.5,-0.5],"type": "VEC3"}
+],
+"materials": [{"pbrMetallicRoughness": {"baseColorFactor": [0.800000011920929,0.0,0.0,1.0]}}],
+"bufferViews": [
+{"buffer": 0,"byteOffset": 576,"byteLength": 72,"target": 34963},
+{"buffer": 0,"byteOffset": 0, "byteLength": 576,"byteStride": 24,"target": 34962}
+],
+"buffers": [{"byteLength": 648,"uri": "data:application/octet-stream;base64,AAAAAAAAAAAAAIA/AAAAvwAAAL8AAAA/AAAAAAAAAAAAAIA/AAAAPwAAAL8AAAA/AAAAAAAAAAAAAIA/AAAAvwAAAD8AAAA/AAAAAAAAAAAAAIA/AAAAPwAAAD8AAAA/AAAAAAAAgL8AAAAAAAAAPwAAAL8AAAA/AAAAAAAAgL8AAAAAAAAAvwAAAL8AAAA/AAAAAAAAgL8AAAAAAAAAPwAAAL8AAAC/AAAAAAAAgL8AAAAAAAAAvwAAAL8AAAC/AACAPwAAAAAAAAAAAAAAPwAAAD8AAAA/AACAPwAAAAAAAAAAAAAAPwAAAL8AAAA/AACAPwAAAAAAAAAAAAAAPwAAAD8AAAC/AACAPwAAAAAAAAAAAAAAPwAAAL8AAAC/AAAAAAAAgD8AAAAAAAAAvwAAAD8AAAA/AAAAAAAAgD8AAAAAAAAAPwAAAD8AAAA/AAAAAAAAgD8AAAAAAAAAvwAAAD8AAAC/AAAAAAAAgD8AAAAAAAAAPwAAAD8AAAC/AACAvwAAAAAAAAAAAAAAvwAAAL8AAAA/AACAvwAAAAAAAAAAAAAAvwAAAD8AAAA/AACAvwAAAAAAAAAAAAAAvwAAAL8AAAC/AACAvwAAAAAAAAAAAAAAvwAAAD8AAAC/AAAAAAAAAAAAAIC/AAAAvwAAAL8AAAC/AAAAAAAAAAAAAIC/AAAAvwAAAD8AAAC/AAAAAAAAAAAAAIC/AAAAPwAAAL8AAAC/AAAAAAAAAAAAAIC/AAAAPwAAAD8AAAC/AAABAAIAAwACAAEABAAFAAYABwAGAAUACAAJAAoACwAKAAkADAANAA4ADwAOAA0AEAARABIAEwASABEAFAAVABYAFwAWABUA"}]
+}
+}
+
+set fd [open ${imagedir}/${casename}.gltf w]
+fconfigure $fd -translation lf
+puts $fd $cubeGltf
+close $fd
+
+ReadGltf D ${imagedir}/${casename}.gltf
+XGetOneShape s D
+checknbshapes s -face 1 -compound 0
+checktrinfo s -tri 12 -nod 24