我创建了一个简单的盒子模型,并使用纹理贴图创建了颜色插值图像。我使用
中的代码将模型导出到 fxml我有一个我尝试导出的彩色模型的 jpeg 以及生成的导入模型,但我是 Stack Overflow 的新手,目前还不允许发布图像。
我也找不到附加导出的 FXML 文件内容的方法,但我很乐意分享它。
当我使用标准 FXMLLoader 将 fxml 文件导入回我的应用程序时,颜色映射不可见。不知道是导出不完整还是导入不正确。 FXML 文件似乎具有正确的网格和纹理贴图指针,但我没有看到纹理贴图的表示。我使用 PhongMaterial setDiffuseMap 方法将图像分配给使用 WritableImage 和 PixelWriter 构造的 Material 对象,以创建颜色带。有谁知道FXMLExporter是否支持导出以这种方式构造的PhongMaterial对象,或者FXMLImporter是否不支持导入这样的颜色图?
根据 Jose 的建议,我对代码进行了更改,但遇到了一些问题。
我将两个立方体的每个面定义为一个单独的 TriangleMesh,认为最终我希望在选择场景中的对象时能够区分每个面。我有一个 PhongMaterial 对象,其图像为漫反射贴图。我已为两个立方体的每个面分配了相同的 Material 。
当我导出模型时,导出方法会尝试写入图像文件 12 次。似乎应该有一种方法来向模型定义传达正在使用单个 phong Material 并且它基于单色图像。
我在导出方法中添加了代码,以记住用于导出 FXML 文件的文件名,以便我可以根据 FXML 文件名(传递给 exportImage() 的完整路径名)为图像文件分配一个名称。如果没有路径,图像文件将存储在我的 Eclipse 工作区中,而不是与 FXML 文件存储在同一文件夹中。我不确定应该给 fxmlImage.addProperty("url",filename) 起什么名字。应该是完整路径名还是文件名?如果我使用完整路径名,那么 FXML 文件内就会有一个硬编码路径,这似乎是一个坏主意。我尝试保存带有或不带有完整路径的 URL 名称,并且两种方式都得到了相同的结果...即当我导入 FXML 文件时没有出现模型。我也尝试过带或不带前导@,结果相同。有谁知道我可能做错了什么?
最佳答案
如果您查看 OpenJFX 上 3DViewer
项目中的 FXMLExporter
类的最新版本,您将看到 Material 仅导出漫反射颜色:
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>
我们还需要导出图像 URL。这可以通过 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>
关于3d - javafx 3d 向 fxml 导出/导入不正确或不完整,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29595664/