2015-04-12 39 views
2

我創建了一個盒子的簡單模型和創建使用紋理貼圖的彩色插值圖像。我導出模型使用中發現的代碼FXML在JavaFX的3D導入/導出/從FXML是不正確或不完整

FXML export code

我有彩色模式,我想出口的JPEG和所產生的進口模式,但我新的堆棧溢出,我不能讓發佈圖片呢。

我還不能找到一種方法,這是導出的FXML文件的內容附加,但我會很樂意分享。

當我導入FXML文件回用標準FXMLLoader我的應用程序,該顏色映射是不可見的。我不知道出口是不完整還是進口不正確。 FXML文件似乎具有正確的網格和紋理貼圖指針,但我看不到紋理貼圖的表示。我使用PhongMaterial setDiffuseMap方法將圖像分配給使用WritableImage和PixelWriter構造的材質對象以創建一個顏色帶。有誰知道FXMLExporter是否支持以這種方式構造的PhongMaterial對象的導出,或者FXMLImporter是否不支持導入這樣的顏色映射?

基於由何塞我修改了我的代碼的建議,但我遇到了一些問題。

我在我的兩個立方體的每個面定義爲一個單獨的TriangleMesh,以爲最終我希望能夠在場景中選擇對象時,每個面區分。我有一個單獨的PhongMaterial對象,它具有作爲漫反射貼圖的圖像。我已將相同的材料分配給我的兩個立方體的每個面。

當我導出我的模型,導出方法試圖寫入圖像文件12次。似乎應該有一種方法可以向模型定義傳達一個單一的phong材質正在被使用,並且它是基於一個單色圖像。

我將代碼添加到導出方法中以記住用於導出FXML文件的文件名,以便我可以根據FXML文件名(傳遞給exportImage()的完整路徑名)爲映像文件分配一個名稱。沒有路徑,圖像文件存儲在我的Eclipse工作區內,而不是存儲在與我的FXML文件相同的文件夾中。我不知道應該給fxmlImage.addProperty(「url」,filename)命名。它應該是完整的路徑名還是文件名?如果我使用完整的路徑名,那麼我在FXML文件中有一個硬編碼路徑,這似乎是一個壞主意。我嘗試使用和不使用完整路徑來保存URL名稱,並獲得了同樣的結果......這是我導入FXML文件時沒有模型出現的情況。我也嘗試過和沒有領先的@,結果相同。有沒有人有一個想法,我可能會做錯什麼?

回答

1

如果你看一下從3DViewer項目上OpenJFXFXMLExporter類的最後一個版本,你會看到,材料僅漫反射顏色輸出:

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> 
+0

非常感謝您的建議。我遇到了一些問題。我將我的兩個立方體的每個面定義爲一個單獨的TriangleMesh,認爲最終我希望能夠在場景中選擇對象時區分每個面。我已將相同的材質分配給兩個立方體的每個面,導出嘗試將圖像文件寫入12次。看起來應該有一種方法可以向模型定義傳達所有圖像都是相同的。 – bluemonkey

+0

即使在您有幾個3D形狀但使用相同材質的情況下,也可以執行一些檢查以避免再次導出圖像。如果你有不同的紋理,你需要添加一些計數器來使用不同的圖像。正如我所說,這是一個快速實施,所以你可以處理細節。 –

+0

我同意我可以跟蹤不同的圖像。真正的問題在於我對原始文章的編輯中所描述的......目前還不清楚如何控制圖像的位置以及導入不再起作用。 – bluemonkey