首页 > 解决方案 > 从 HttpServlet 流式传输 gltf 到元素

问题描述

我有一个运行 JavaWebApplication 的 Tomcat,我想使用该<model-viewer>元素(此处的信息)来显示具有“可变”纹理的 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 结构。对海报属性的调用也可以完美运行,但是当我想使用相同的 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并访问正确的“模板”来测试流,因为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]

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

标签: javaservletsgltf

解决方案


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

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

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

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


推荐阅读