将 gltf 从 HttpServlet 流式传输到 <web-viewer> 元素

Stream gltf from HttpServlet to <web-viewer> element

我有一个 Tomcat 运行 JavaWebApplication,我想使用 <model-viewer> 元素 (info here) 来显示带有 'changable' 的 3D 模型纹理。因此,我想从 Servlet 获取必要的 gltf 文件,这样我就可以对其产生影响,而不仅仅是访问文件。我知道,两者(gltf 结构以及我的 webapp 中的模型查看器)都可以工作,因为如果我这样引用 src,它可以完美地工作:

<model-viewer
    poster-color="black"
    poster="<%=
        "ressource?type=coloredmodelpic&key=" +
        model +
        "&ptype=" +
        type +
        "&color=" +
        color
        %>"
    camera-controls
    auto-rotate
    alt="<%= "A 3D model of " + model + "-" + type %>"
    src="data/RON-AA/RON-AA.gltf">

而显然 RON-AA.gltf 拥有 json 结构。对 poster 属性的调用也可以完美运行,但是当我想使用相同的 servlet('ressource' 引用)来流式传输数据时,它不会显示模型。

<model-viewer
    poster-color="black"
    poster="<%=
        "ressource?type=coloredmodelpic&key=" +
        model +
        "&ptype=" +
        type +
        "&color=" +
        color
        %>"
    camera-controls
    auto-rotate
    alt="<%= "A 3D model of " + model + "-" + type %>"
    src="<%=
        "ressource?type=gltf&key=" +
        model +
        "&ptype=" +
        type +
        "&color=" +
        color
        %>"
>

我知道调用本身正在运行,因为当我在任何浏览器中直接调用 url 时,我确实获得了要下载的正确 gltf。它也确实提供了正确的数据,因为当我在 vim 中查看下载时它似乎没问题。在 servlet 中,我提供这样的数据(不完全是因为它分布在一些方法上,但总体上是这样):

...
case "gltf":
    key = request.getParameter("key");
    ptype = request.getParameter("ptype");
    colorString = request.getParameter("color");
    response.setContentType("model/gltf+json");
    response.setHeader("Content-Type", "model/gltf+json");

    InputStream is;
    OutputStream os = response.getOutputStream();
    is = new FileInputStream(new File("...path to the same gltf... .gltf"));
    byte[] buffer = new byte[1024];
    int bytesRead;
    while ((bytesRead = is.read(buffer)) != -1) 
        os.write(buffer, 0, bytesRead);
        
    os.flush();
    os.close();
    is.close();

所以我确实设置了正确的 (?) mimetype 并访问了正确的 'template' 来测试流,因为 vim 中的结果是正确的数据。它甚至让我更加困惑,因为当我尝试为相同的模型查看器元素设置流式传输二进制文件而不是 gltf 时,它起作用了。所以以下工作正常:

...
case "glb":
    key = request.getParameter("key");
    ptype = request.getParameter("ptype");
    colorString = request.getParameter("color");
    response.setContentType("model/gltf-binary");
    response.setHeader("Content-Type", "model/gltf-binary");

    InputStream is;
    OutputStream os = response.getOutputStream();
    is = new FileInputStream(new File("...path to the glb... .glb"));
    byte[] buffer = new byte[1024];
    int bytesRead;
    while ((bytesRead = is.read(buffer)) != -1) 
        os.write(buffer, 0, bytesRead);
        
    os.flush();
    os.close();
    is.close();[info here][1]

有人可以给我提示吗,出了什么问题,因为我现在真的没有想法...

JSON *.gltf 文件本身可能包含也可能不包含模型的所有部分。它可以引用外部 .bin 文件,以及作为外部 .jpg.png 文件的纹理。 BIN 文件特别包含 32 位浮点顶点数据,因此如果没有该文件,您将看不到单个多边形。

您可以检查 .gltf 的内容以查看它是否存在:搜索 .bin.jpg.png.bin 将列在名为 buffers 的部分中,图像将列在名为 images.

的部分中

此外,检查 DevTools 网络选项卡,查看 <model-viewer> 是否实际请求了这些外部文件,以及每个文件的响应。

对于在网站上托管,.glb 通常是最好的形式,因为所有这些额外的部分都捆绑到一个下载中。 GLB 旨在提供 glTF 各种风格中的最佳网络性能。