如何正确解析WebGL的collada文件?(包括示例)

6 javascript xml parsing collada webgl

这是我目前的结果:

错误的collada模型解析

正如您所看到的,模型中存在许多空白.我的猜测,为什么会发生这种情况,我不知何故需要<vcount><polylist>元素中包含数据,这应该确定每个平面的顶点数(?).由于WebGL只能绘制三边形多边形,因此这似乎无法工作.如果到目前为止我的假设是正确的,我需要将所有四边形切成两个三角形.

我已经用WebGL对collada解析做了很多研究,但几乎每个站点都将我重定向到几个已经实现了这些功能的WebGL库(所以请不要这样做).我总是首先编写所有核心功能,以便更好地掌握内部工作方式.

这是我的解析函数:

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;
}
Run Code Online (Sandbox Code Playgroud)

我也不太清楚为什么法线也有索引,但是我只是通过添加每个第二个值来忽略它们indicesList.

我的绘制程序很简单gl.drawElements(gl.TRIANGLE_STRIP, program.models[i].ibo.count, gl.UNSIGNED_SHORT, 0);.

我会对这个问题提出任何解决方案或建议.


更新:再次使用此解析器之后,我注意到,上面的解析函数(即使使用正确导出的模型)也不会正确显示法线.您必须更改数据,以便按面定义顶点,而不是按唯一位置定义顶点.

小智 0

找到了一个潜在的解决方案。在搅拌机中导出模型之前,您需要添加decimate修改器。检查triangulate并将其设置ratio0.9900(单击左侧箭头)。

编辑:实际上有一个triangulate修饰符,所以请使用这个修饰符。

因此,最终您的球体网格将如下所示:

在此输入图像描述

  • Blender 2.68a 中的新增功能 - Collada 导出器在导出过程中自动对网格进行三角测量,而无需更改网格本身。这避免了需要手动执行该步骤。更有用的是,它保留了网格中的四边形(例如,立方体的 6 个四边形)。因此,您可以根据需要进行建模,并让导出器在导出操作期间“无形且神奇地”对其进行三角测量。 (2认同)