Intersection with glTF model

Sean,

I think we're almost there. I think the snippet you provided mostly worked, however I had to store the buffer in a DataView object instead of a specific typed array. This is because I found that one of the source.buffer in my example tileset had a byteOffset that was odd (as in not even), even though the componentType indicated that it was an UNSIGNED_SHORT buffer. I assume that this is ok since it seems to come directly from the model. Here is what I ended up with in createIndexBuffer:

(By the way, how do you get code syntax highlighting/markdown in google groups?)

var loadResources = model._loadResources;
var bufferViews = model.gltf.bufferViews;
var bufferView = bufferViews[bufferViewId];
var uint8Array = loadResources.getBuffer(bufferView);
var source = model.gltf.buffers[bufferView.buffer].extras._pipeline.source;
var byteOffset = source.byteOffset + bufferView.byteOffset;
var length = uint8Array.byteLength / ComponentDatatype.getSizeInBytes(componentType)
var buffer = new DataView(source.buffer, byteOffset, length);

I did almost the exact same thing in createVertexBuffer, however I manually computed the length variable. This is because componentType is not passed in to createVertexBuffer. I've sort of assumed that the vertex buffer that I am using is of type FLOAT. This is just based on inspecting some of the .b3dm files. The componentType for the position buffer is not directly defined, however there is an accessor that references the position buffer whose component type is 5126 (FLOAT). This might be faulty logic, but float makes sense for this type anyways. Since I am assuming it is a FLOAT, I have manually calculated the length of the dataview:

var loadResources = model._loadResources;
var bufferViews = model.gltf.bufferViews;
var bufferView = bufferViews[bufferViewId];
var uint8Array = loadResources.getBuffer(bufferView);
var source = model.gltf.buffers[bufferView.buffer].extras._pipeline.source;
var byteOffset = source.byteOffset + bufferView.byteOffset;
var length = uint8Array.byteLength / 4;
var buffer = new DataView(source.buffer, byteOffset, length);

I also noticed something called a byteStride inside the bufferViews for both the index and vertex buffer. https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#bufferviewbytestride The byteStride for my indexBuffer is 2 which to me indicates a tightly packed Uint16Array, which is exactly how I am accessing the index array. The byteStride for the vertex buffer is 12, which indicates a not tightly packed array of something else. I just noticed the byteStride, so I am not sure how to handle it yet or if it is necessary.

Finally, I wanted to share the code I am using to index into the vertex buffer. I am pretty confident this is correct:

var indices = model.indexBuffer;
var length = model.indexBuffer.byteLength / 2;
var vertices = model.vertexBuffer;
for (var i = 1; i < length; i += 3) {
  var p0 = new Cesium.Cartesian3(
    vertices.getFloat32(12 * indices.getUint16(i*2)),
    vertices.getFloat32(12 * indices.getUint16(i*2) + 4),
    vertices.getFloat32(12 * indices.getUint16(i*2) + 8)
  );
  Cesium.Matrix4.multiplyByPoint(mat, p0, p0);
  if (rtc) {
    Cesium.Cartesian3.add(p0, rtc, p0)
  }

  var p1 = new Cesium.Cartesian3(
    vertices.getFloat32(12 * indices.getUint16((i+1)*2)),
    vertices.getFloat32(12 * indices.getUint16((i+1)*2) + 4),
    vertices.getFloat32(12 * indices.getUint16((i+1)*2) + 8)
  );
  Cesium.Matrix4.multiplyByPoint(mat, p1, p1);
  if (rtc) {
    Cesium.Cartesian3.add(p1, rtc, p1)
  }

  var p2 = new Cesium.Cartesian3(
    vertices.getFloat32(12 * indices.getUint16((i+2)*2)),
    vertices.getFloat32(12 * indices.getUint16((i+2)*2) + 4),
    vertices.getFloat32(12 * indices.getUint16((i+2)*2) + 8)
  );
  Cesium.Matrix4.multiplyByPoint(mat, p2, p2);
  if (rtc) {
    Cesium.Cartesian3.add(p2, rtc, p2)
  }
  model.triangles.push(p0);
  model.triangles.push(p1);
  model.triangles.push(p2);
}

With all of this combined, I am still not quite there. Currently I am running in to a RangeError: Offset is outside the bounds of the DataView after a call to vertices.getFloat32(). I am wondering if this could be because I am not accounting for the byteStride.

Anyways, I've learned a lot so far investigating this, and I appreciate your help.

Thanks,
Eric