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

Javascript 如何正确解析WebGL的collada文件?(包括示例),javascript,xml,parsing,webgl,collada,Javascript,Xml,Parsing,Webgl,Collada,这是我目前的结果: 正如你所看到的,这些模型中有很多漏洞。我的猜测是,为什么会发生这种情况,我需要在元素中包含数据,该元素用于确定每个平面的顶点计数(?)。由于WebGL只能绘制三面多边形,因此这似乎不起作用。如果到目前为止我的假设是正确的,我需要将所有四边形切成两个三角形 我已经用WebGL对collada解析做了很多研究,但几乎每个网站都将我重定向到几个已经实现了此类功能的WebGL库(所以请不要这样做)。我总是从自己编写所有核心功能开始,以便更好地掌握内部工作方式 下面是我的解析函数:

这是我目前的结果:

正如你所看到的,这些模型中有很多漏洞。我的猜测是,为什么会发生这种情况,我需要在
元素中包含
数据,该元素用于确定每个平面的顶点计数(?)。由于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;
}
function load\u collada(总帐、程序、路径){
var request=new XMLHttpRequest(),
缓冲区={
vbo:gl.createBuffer(),
nbo:gl.createBuffer(),
ibo:gl.createBuffer(),
aVertex:gl.GetAttriblLocation(程序,“aVertex”),
异常:gl.getAttribLocation(程序,“异常”)
},
网格
顶点,
指标清单,
法线=[],
指数=[];
打开(“获取”,路径,false);
请求。重写emimetype(“text/xml”);
request.send();
mesh=request.responseXML.querySelector(“mesh”);
顶点=mesh.querySelectorAll(“浮点数组”)[0].textContent.split(“”);
normals=mesh.querySelectorAll(“浮点数组”)[1].textContent.split(“”);
indicesList=mesh.queryselectoral(“polylist p”)[0].textContent.split(“”);
对于(i=0;i
我也不太清楚为什么法线也有索引,但我忽略了它们,只添加了
索引列表中的每秒值

我的绘图例程只是
gl.drawerelements(gl.TRIANGLE\u STRIP,program.models[i].ibo.count,gl.UNSIGNED\u SHORT,0)

对于这个问题的任何解决方案或建议,我都非常感激



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

找到了一个可能的解决方案。在blender中导出模型之前,需要添加一个
decimate
修改器。选中
triangulate
,并将
比率设置为
0.9900
(单击左箭头)

编辑:实际上有一个
triangulate
修改器,因此请使用此修改器

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


即使你不使用,比如说,three.js,为什么不看看他们做了什么?它在那里很好,结构也很好,所以读起来很简单。看看它是否符合您对COLLADA多边形的理解。您的图像看起来像是在每个四边形上绘制两个三角形,但对于具有顶点ABCD的四边形,您绘制的是ABC和DBC,而不是ABC和DBCCDA@bjorke好吧,祝你好运,在这个4k行脚本中找到了解决方案:我现在真的不需要解析场景和动画,只想正确解析网格。尝试随机着色三角形,或每隔一段红蓝。。。看看我的第二条评论是否正确。你是说你不必费心去看正确运行的代码,但你希望其他人扩展、安装和调试你可能大小相同的坏代码?我的整个代码几乎没有这个文件那么大。我只是提供给其他人看他们对我上面粘贴的解析函数所做的潜在更改。我只是不明白这个插件中发生了什么,特别是因为我还不知道three.js。此外,我不能只给“黑色”三角形上色,因为我必须先分割四边形(或者扩展它们)。不知道这有多容易,但如果我的消费是正确的,我现在就试试。Blender 2.68a中的新功能-Collada exporter在导出过程中自动三角化网格,而不改变网格本身。这样可以避免手动执行该步骤。更有用的是,它在网格中保留四边形(例如,立方体为6个四边形)。因此,您可以根据需要进行建模,并让导出器在导出操作期间“以不可见和神奇的方式”对其进行三角剖分。