首页 文章

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

提问于
浏览
2

我创建了一个简单的盒子模型,并使用纹理贴图创建了一个颜色插值图像 . 我使用在的代码将模型导出到fxml

FXML export code

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

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

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

基于Jose的建议,我对代码进行了更改,但是我遇到了一些问题 .

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

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

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

1 回答

  • 1

    如果您查看OpenJFX3DViewer 项目的 FXMLExporter 类的最后一个版本,您将看到仅对材质导出漫反射颜色:

    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>
    

相关问题