This is my current result:
As you can see the models have a bunch of gaps in them. My guess, why this happens would be, that I somehow need to include the <vcount>
data in the <polylist>
element, which is supposed to determine the vertex count for each plane(?). Since WebGL can only draw 3 sided polygons, this can't seem to work. If my assumption so far is correct, I'd need to slice all the quadrilaterals into two triangles each.
I've already done a lot of research on collada parsing with WebGL, but almost every site redirected me to several WebGL libraries which have such functionality already implemented (so please don't do the same). I always start out by writing all the core functionality myself to get a better grasp on how things internally work.
Here is my parse function:
function load_collada(gl, program, path) {
var request = new XMLHttpRequest(),
buffers = {
vbo: gl.createBuffer(),
nbo: gl.createBuffer(),
ibo: gl.createBuffer(),
aVertex: gl.getAttribLocation(program, "aVertex"),
aNormal: gl.getAttribLocation(program, "aNormal")
},
mesh,
vertices,
indicesList,
normals = [],
indices = [];
request.open("GET", path, false);
request.overrideMimeType("text/xml");
request.send();
mesh = request.responseXML.querySelector("mesh");
vertices = mesh.querySelectorAll("float_array")[0].textContent.split(" ");
normals = mesh.querySelectorAll("float_array")[1].textContent.split(" ");
indicesList = mesh.querySelectorAll("polylist p")[0].textContent.split(" ");
for (i=0 ; i < indicesList.length; i+=2) { indices.push(indicesList[i]); }
buffers.vbo.count = parseInt(mesh.querySelectorAll("float_array")[0].getAttribute("count"), 10);
buffers.nbo.count = normals.length;
buffers.ibo.count = indices.length;
gl.bindBuffer(gl.ARRAY_BUFFER, buffers.vbo);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
gl.vertexAttribPointer(buffers.aVertex, 3, gl.FLOAT, true, 0, 0);
gl.enableVertexAttribArray(buffers.aVertex);
gl.bindBuffer(gl.ARRAY_BUFFER, buffers.nbo);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(normals), gl.STATIC_DRAW);
gl.vertexAttribPointer(buffers.aNormal, 3, gl.FLOAT, true, 0, 0);
gl.enableVertexAttribArray(buffers.aNormal);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffers.ibo);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
return buffers;
}
I'm also not quite sure why the normals have indices aswell, but I'm ignoring them by adding only each second value from the indicesList
.
My draw routine is simply gl.drawElements(gl.TRIANGLE_STRIP, program.models[i].ibo.count, gl.UNSIGNED_SHORT, 0);
.
I'd greatly appriciate any solutions or advices on this problem.
Update: After playing around with this parser again, I noticed, that the parse function above (even with correctly exported models) won't won't display the normals correctly. You'd have to alter the data so that the vertices are defined per face and not per unique position.