javafx 3d导出/导入到fxml的错误或不完整

时间:2015-04-12 23:01:53

标签: 3d javafx export fxml javafx-3d

我创建了一个简单的盒子模型,并使用纹理贴图创建了一个颜色插值图像。我使用

中的代码将模型导出到fxml

FXML export code

我有一个我试图导出的彩色模型的jpeg和导致的导入模型,但我是Stack Overflow的新手,我不允许发布图片。

我也找不到附加导出的FXML文件内容的方法,但我很乐意与大家分享。

当我使用标准FXMLLoader将fxml文件导回我的应用程序时,颜色映射不可见。我不知道导出是不完整还是导入不正确。 FXML文件似乎具有正确的网格和纹理贴图指针,但我没有看到纹理贴图的表示。我使用PhongMaterial setDiffuseMap方法将图像分配给使用WritableImage和PixelWriter构造的材质对象,以创建颜色带。有没有人知道FXMLExporter是否支持以这种方式构建的PhongMaterial对象的导出,或者FXMLImporter是否不支持导入这样的颜色映射?

根据Jose的建议,我对代码进行了更改,但是我遇到了一些问题。

我将我的两个立方体的每个面定义为一个单独的TriangleMesh,认为最终我希望能够在场景中选择对象时区分每个面。我有一个PhongMaterial对象,它将图像作为漫反射贴图。我已经为我的两个立方体的每个面分配了相同的材料。

导出模型时,导出方法会尝试将图像文件写入12次。似乎应该有一种方法来向模型定义传达单个phong材料正在被使用并且它基于单个彩色图像。

我在导出方法中添加了代码以记住用于导出FXML文件的文件名,以便我可以根据FXML文件名(传递给exportImage()的完整路径名)为图像文件指定名称。如果没有路径,图像文件将存储在Eclipse工作区内,而不是存储在与FXML文件相同的文件夹中。我不确定应该给fxmlImage.addProperty(“url”,filename)赋予什么名称。它应该是完整路径名还是文件名?如果我使用完整路径名,那么我在FXML文件中有一个硬编码路径,这似乎是一个坏主意。我尝试使用和不使用完整路径保存URL名称,并且两种方式都得到相同的结果...这是我导入FXML文件时没有出现的模型。我也尝试使用和不使用前导@,结果相同。有没有人知道我可能做错了什么?

1 个答案:

答案 0 :(得分:1)

如果您查看OpenJFXFXMLExporter项目中3DViewer课程的最新版本,您会看到仅对材质导出漫反射颜色:

if (PhongMaterial.class.isAssignableFrom(aClass)) {
    res.add(new Property(aClass.getMethod("getDiffuseColor"), "diffuseColor"));
}

你提到的项目也是如此。

您可以添加以下这一行:

res.add(new Property(aClass.getMethod("getDiffuseMap"), "diffuseMap"));

getProperties()

if (PhongMaterial.class.isAssignableFrom(aClass)) {
    res.add(new Property(aClass.getMethod("getDiffuseColor"), "diffuseColor"));
    res.add(new Property(aClass.getMethod("getDiffuseMap"), "diffuseMap"));
}

因此,当您导出3D形状时,这将添加到fxml文件中:

<Box id="box" width="100.0" height="100.0" depth="100.0">
  <material>
    <PhongMaterial diffuseColor="0xffffffff">
      <diffuseMap>
        <Image/>
      </diffuseMap>
    </PhongMaterial>
  </material>
</Box>

我们还需要导出图片网址。这可以通过exportToFXML方法完成。

由于漫反射贴图中的Image不存储任何路径,因此诀窍是将图像保存到导出fxml的同一路径。这是一个快速实现:

private FXML exportToFXML(Object object) {
    ...

    for (Property property : properties) {
        try {
            Object[] parameters = new Object[property.getter.getParameterTypes().length];
            Object value = property.getter.invoke(object, parameters);
            if (value != null) {
                ...
                } else if (value instanceof Image) {
                    FXML container = fxml.addContainer(property.name);
                    FXML fxmlImage=exportToFXML(value);
                    container.addChild(fxmlImage);
                    exportImage((Image)value,"image.png");
                    fxmlImage.addProperty("url","@image.png");
                } else {
                    FXML container = fxml.addContainer(property.name);
                    container.addChild(exportToFXML(value));
                }
            }
        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
            Logger.getLogger(FXMLExporter.class.getName()).
                    log(Level.SEVERE, null, ex);
        }
    }

    return fxml;
}

private void exportImage(Image image, String fileName){
    try {
        ImageIO.write(SwingFXUtils.fromFXImage(image, null), "png", new File(fileName));
    } catch (IOException ex) { 
        System.out.println("Error saving image");
    }
}

如果你现在运行,这就是你将得到的:

<Box id="box" width="100.0" height="100.0" depth="100.0">
  <material>
    <PhongMaterial diffuseColor="0xffffffff">
      <diffuseMap>
        <Image url="@image.png"/>
      </diffuseMap>
    </PhongMaterial>
  </material>
</Box>