Java 3D API官方教程
click here!!
目錄
1 第一章、入門
1.1 什么是Java 3D API?
1.2 Java 3D API
1.3 構建場景圖
1.3.1 高端Java 3D API的類層次
1.4 編寫Java3D程序的一般步驟
1.5 一些Java 3D術語
1.6 簡單方法示例: Hello
1.6.1 Hello中所用到的類
1.7 旋轉立方體
第一章、入門
本章目標:
學習了本章之后,你能:
•能用一些基本術語解釋什么是Java3D
•能描述出Java3D程序的基本結構。
•能識別出Java3D API中的許多類。
•能編寫出簡單的Java3D動畫程序。
Java 3D API是一個用于編寫顯示和交互操作三維圖形對象的程序的接口。Java 3D也是在Java2 Java開發包
(JDK)上的標準擴展。這個API提供了用于創建和操縱3D圖形的高端構成方法以及渲染該圖形的一些數據結構。
Java3D 提供了創建圖片、可視化、動畫以及3D交互圖形應用程序的函數。
1.1 什么是Java 3D API?
Java 3D API是作為復雜三維圖形和聲音渲染系統的接口的一系列層次的JAVA類的統稱。
程序員可以用Java3D開發創建和操縱3D圖形對象的高端應用。這個圖形對象處于一個被渲染了的虛擬世界
(VirtualUniverse)中。這個API就是用設計來用于靈活方便地創建精確的各種大小的虛擬環境,可以大到大空物體,小到
比原子還小。
除了這些功能之外,API的使用也很直接,API能自動處理渲染的細節,由于利用了Java線程機制的優勢,所以Java3D的
渲染器的工作是并行進行的。并且渲染器也能自動地優化并提高渲染性能。
一個Java3D程序創建了Java3D對象的實際,并將其置之于場景圖數據結構中。在這個場景圖中,所有3D對象用完全指定
了虛擬世界內容和其如何被渲染的樹形結構存儲,Java3D程序能寫成能獨立運行的應用程序,或者寫成能嵌入在瀏覽器中運
行的Applets,或者二者兼備。
1.2 Java 3D API
每一個Java3D 程序至少部分地集成了來自Java類層次中的對象,這些對象的集合稱做虛擬世界(virtual universe),
這就是將要被渲染的對象。此API在javax.media.j3d包中定義了超過100多個類,這些類我們平常稱做Java3D核心類。
在Java3D API中有數以百計的屬性和方法。盡管如此,一個包含動畫功能的簡單的虛擬世界的構建僅僅需要幾個類就行。
本章討論了用盡少的對象集合和交互來渲染一個簡單虛擬世界。
本章包含了一個簡單但是完全的叫Hello的程序的開發過程,這個程序顯示了一個能旋轉的立方體,這個示例程序
是逐步開發完成的,因此這個程序用了很多版本來展示Java 3D編程過程中的每一部分。本教程中的所有程序都可以
獲得電子的版本。更多的信息請見前言中的"獲得本教程"[http://java.sun.com/products/java-media/3D/collateral/]。
除了Java3D核心包之外,Java3D程序設計也會用到其它的包,比如com.sun.j3d.utils,這個包通常稱做Java3D工具
類,核心類中僅僅包含了在Java3D編程中必段的最底層的類,而工具類是對核心類方便而強大的補充。
工具類主要分為四類:內容加載器、場景圖構建輔助類、圖形類和方便的一些工具類。將來還有一些功能,比如nurbs
[non-uniform rational B-spline,非均勻有理B樣條],也會加到工具類,而不是Java3D核心包中。而一些工具類在
Java 3D API 將來的版本中也可能會移到核心包中去。 利用工具類大大地減少了Java3D程序中的代碼行數。除Java3D
核心類和工具類包之外,每一個Java3D程序還引用了java.awt包和javax.vecmath包中的類. java.awt包就是Abstract
WindowingToolkit (AWT). AWT類用于創建顯示和渲染場景和窗口。而javax.vecmath包則定義了對點、矢量、矩陣以及
其他數學對象進行數學運算的類。
在接下來的教程中,可視對象(visual object)就是場景圖中的對象比如一個立方體或者球體。對象(object)則
是指一個類的實例。而內容(content)指的是一個場景圖中全部的可視對象。
1.3構建場景圖 一個Java3D的虛擬世界創建自一個場景圖,而場景圖就是由Java3D類的實例構建而成.場景圖集成了定義圖形、聲音、
光線、位置、方向以及可視物體和聲音對象的表面屬性等對象。 一個通常的圖形定義是一個由結點和弧邊組成的數據結構。一個結點是一個數據元素,而邊則是數據元素之間的關系。場景圖中的結點就是Java3D類的實例,而邊展示了這些Java 3D實例之間的兩種關系。最為通用的關系是就是父子關系(parent-child relationship),一組結點可以有任意數目的孩子卻只能有一個雙親。一個葉子結果可以有一個雙親但是沒有孩子。
另一個關系是引用(reference)。一個引用與場景圖結點中的結點組件(NodeComponent)對象相關聯。結點組件定義了用于渲染可視對象的圖形和表面屬性。
Java 3D場景圖就是由一堆具有父子關系的結點構建成的樹形結構。在樹形結構里,其中有且僅有一個結點是根結點,共他結點都可以順著從根開始的弧邊可以訪問到,樹形結構中的結點是沒有回路的。一個場景圖就是由植根于本地(Locale)對象的樹而形成的。結點組件和引用弧邊都不是場景圖樹的組成部分。
在樹形結構中,從根結點到葉子結點有且僅有一條路徑,因此,從場景圖的根到其每個葉子結點也僅有一條路徑。從場景圖根結點到到特點葉子結果的路徑我們稱之為該葉子結點的場景圖路徑(scene graph path)。因此,一條場景圖路徑恰恰只通向了一個葉子結點。而在場景圖中從根到每個葉子結點都有一條這樣的路徑。在Java3D場景圖中的每一條場景圖路徑也完全地定義了路徑的葉子的狀態信息。狀態信息包括位置、方向、可視對象的大小。由此可見,每一個可視對象的可視屬性僅僅由其場景圖路私決定。Java3D渲染利用這點,以僅可能有效地按它所定義的順序來渲染葉子對象。Java 3D程序員一般情況下不用控制渲染對象的順序。[原注:Java3D 程序員僅僅可以用來控制渲染對象順序的是OrderedGroup類結點,在本教程中對此部分未加論述,請參見Java3D API規范文檔]
在樹形結構中,從根結點到葉子結點有且僅有一條路徑,因此,從場景圖的根到其每個葉子結點也僅有一條路徑。從場景圖根結點到到特點葉子結果的路徑我們稱之為該葉子結點的場景圖路徑(scene graph path)。因此,一條場景圖路徑恰恰只通向了一個葉子結點。而在場景圖中從根到每個葉子結點都有一條這樣的路徑。在Java3D場景圖中的每一條場景圖路徑也完全地定義了路徑的葉子的狀態信息。狀態信息包括位置、方向、可視對象的大小。由此可見,每一個可視對象的可視屬性僅僅由其場景圖路私決定。Java3D渲染利用這點,以僅可能有效地按它所定義的順序來渲染葉子對象。Java 3D程序員一般情況下不用控制渲染對象的順序。[原注:Java3D 程序員僅僅可以用來控制渲染對象順序的是OrderedGroup類結點,在本教程中對此部分未加論述,請參見Java3D API規范文檔]
場景圖的圖形表示可以當作設計工具或者Java3D程序的文檔。場景圖一般用一些標準的圖形標記來繪制,如圖1-1所示。Java 3D程序可能不止有包含場景圖中的這些對象。
可以用以上標志集合來設計一個Java3D虛擬世界場景圖。等設計上的事情完成后,場景圖的設計就是程序設計的規范。等到程序也設計完成,同一個場景圖就是程序的精解表現(假設程序是依照設計的圖來進行的話)。一個從已有程序繪制成的場景圖可以做創建程序場景圖的文檔。
可以用以上標志集合來設計一個Java3D虛擬世界場景圖。等設計上的事情完成后,場景圖的設計就是程序設計的規范。等到程序也設計完成,同一個場景圖就是程序的精解表現(假設程序是依照設計的圖來進行的話)。一個從已有程序繪制成的場景圖可以做創建程序場景圖的文檔。
VirtualUniversee和Locale類的對象,下面的三個則常常用于標注特定對象[譯者注:Group子類的對象等]的子類,最后一個標記用于表示其它類的對象。實線箭頭表示兩個所連接的對象之間存在父子關系。而虛線箭頭則表求一個對象是另一個對象的引用。引用的對象可以供一個場景圖中的不同的分支所共享。
在平時,創建一個錯誤的場景圖也是可能的,場景圖之所以不合理是因為它與有向無環圖(Directed Acyclic Graph Or DAG)的規則相沖突.問題存在于兩個TransformGroup對象都以同樣的Shape3D葉子對象作為其孩子。請記住,一個葉子結點只能一個雙親,也就是,從Locale對象到葉子結點只能有一條路徑(或者從葉子結點到Locale對象只能有一條路徑)。你也許會認為,圖1-3圖所示的場景在虛擬世界中定義了三個可視對象。它看起來好像是這個場景圖通過重用圖形右邊的可視對象(Shape3D)而定義了兩個對象。從概念上講,每一個TransformGroup 對象都作為共享的那個Shape3D的雙親,這個Shape3D的可視化對象可以允許在不同地方放置一張圖片。盡管如此,由于父子邊之間的關系構不成樹形結構,所以這個場景圖是不合法的。在這個例子中,表現為Shape3D對象有多于一個以上的雙親。對樹形結構和有向無環圖的討論是正確的,然而,Java 3D運行時系統會報告這類父子關系之間的錯誤。樹形結構存在的限制是每一個Shape3D 對象只能有一個雙親。,‘多親'異常會在運行時報告出來。這種不合法場景圖的解決辦法,每一個Shape3D只有一個雙親。一個定義了不合理(法)場景圖的Java3D程序可能通過編譯,但是不會在運行時渲染。當一個定義了不合法場景圖的Java3D程序運行時,Java3D系統會檢測到這個問題,從而會報告一個異常。程序還會繼續運行,但是結果是,應該被關閉,沒有任何渲染好的圖象生成。每一個場景圖有一個唯一的VirtualUniverse,這個VirtualUniverse有一系列 Locale 對象。 一個Locale對象,提供了虛擬世界中的一個參考點。可以把Locale對象看作是在虛擬世界中定義可視對象位置的標
志。一個Java3D程序有多于一個的VirtualUniverse對象,技術上是可行的,因此,可以在虛擬世界中定義多個Locale對象,然而,在多個虛擬世界之間沒有內在的溝通方式,更進一步講,一個場景圖不能存于多個虛擬世界中。同時,我們強烈建議在一個Java 3D程序中只同時擁有有且僅有一個VirtualUniverse。而一個VirtualUniverse 可能在多個Locale對象中引用,但是更多的Java 3D程序只有一個Locale對象,每一個Locale對象,可以作為場景圖中多個子圖的根結點。參考圖1- 2作為場景圖的例子,注意到圖中的Locale對象有兩個子圖分支。 一個BranchGroup對象是子圖的根結點,或者是分支圖的根結點。場景子圖可以分為兩類,視圖分支圖(the view branch graph)和內容分支圖( the content branch graph.)。內容分支圖指定了虛擬世界的內容——圖形,表面,動作,位置,聲音以及光線等。視圖分支子圖指定了視圖參數比如觀看位置和方向。總的來說,兩類子圖指定了很多渲染要完成的工作。圖1-5顯示了Java 3D API類層次中的前面三個層次。
1.3.1高端Java 3D API的類層次
VirtualUniverse, Locale, Group, 和 Leaf 類處于類層次中的這部分。除了VirtualUniverse 和Locale對象,場景圖中余下的部分由SceneGraphObject 對象構成。SceneGraphObject 幾乎是Java3D類中每一個核心類和工具類的超類 [譯者注:超類即上層類,可以是父類或者祖先類]。
SceneGraphObject 有兩個子類: Node 類NodeComponent.類,Node子類提供了場景圖中的絕大部分對象,一個Node對象可以是一個Group,也可是一個Leaf結點對象。
Group 和Leaf是一系列類的超類。這里可以一目了然地看到Node類的子類,它有兩個子類,而 NodeComponent 類,在這些背景知識介紹之后,在Java3D程序的構建中會解釋到。
Node 類
Node是Group和Leaf類的一個抽象超類. Node 為其子類定義了一些公共的重要的方法。某些方法的信息會在更多的背景知識介紹了之后提到。Node 的子類構成了子圖。
Group 類
Group 類是用于在虛擬世界中指定可視對象位置和方向的類的超類。Group類的兩個下層類是 BranchGroup是 TransformGroup. 在場景圖的圖形表現中,Group標記 (用圓表示)。而其中BranchGroups注為GB, TransformGroups 注為TG,等等。具體例子請見圖1-2。
Leaf 類
Leaf是用于指定虛擬世界中可視對象的形狀,聲音和,動作的類的超類。Leaf的一些子類如Shape3D, Light, Behavior, 和 Sound. 這些對象不能有自己的孩子,并且可能引用NodeComponents對象。
NodeComponent 類
NodeComponent 類是用于指定Shape3D (Leaf)結點對象的圖形,表面,紋理和材質屬性的類的超類。NodeComponents 不是場景圖的組成部分,但是為其所引用。一個NodeComponent 對象可能為多個Shape3D對象所引用(同一個材質對象可以賦予多個shape3D對象)。
1.4編寫Java3D程序的一般步驟
SceneGraphObject類的子類就是集成構建場景圖的模塊,一個Java3D程序的開發大略可以分為七步(把它們聚在一起,在Java 3D API 規范中和這里稱之為步驟(recipe)),具體如下列表所示,這些方法可用于裝配許多的Java3D程序。
1. 創建一個Canvas3D對象。
2. 創建一個VirtualUniverse對象。
3. 創建一個Locale 對象,并使之與VirtualUniverse相關聯。
4. 構建一個視圖子圖。
a. 創建一個View 對象。
b. 創建一個ViewPlatform對象。
c. 創建一個PhysicalBody對象。
d. 創建一個PhysicalEnvironment對象。
e. 把 ViewPlatform, PhysicalBody, PhysicalEnvironment, 和Canvas3D對象與View 對象相關聯。
5. 構建一個或多個內容子圖。
6. 編譯所有子圖。
7. 把子圖加到Locale對象中。
表 1-1 編寫Java3D程序的一般步驟
這些步驟忽略了細節但是解釋了Java 3D編程中的基本概念。創建場景圖中的子圖是編程的主要部分。但我們并沒有展開這些步驟詳細討論,本教程的下一部分解釋了一種用更少的代碼更容易的手段來構建一個非常簡單的場景圖的方法。 1.4.1 編寫Java 3D程序的一個簡單方法
用基本方法編寫具有視圖分支圖的Java 3D programs程序的結構有其唯一性,構建視圖分支子圖結構的規則可以通過SimpleUniverse工具類來實現. SimpleUniverse 的實例承擔了構建場景圖的基本步驟中的第2, 3以及第4步。利用SimpleUniverse類來進行Java3D編程,可以大大減少創建視圖分支圖的時間和精力,從而,程序員可以有更多的時間來構建內容分支子圖,這才是真正與Java3D程序事關重大的。
SimpleUniverse類對于Java 3D編程而言真是一個很好的起點,因為它允許程序員暫時忽略視圖子圖的存在.盡管如此,SimpleUniverse 中也不允許同一個虛擬世界存在多個視圖。
本教程的所有例子程序都用到了SimpleUniverse類,因此,如果程序員想獲得更多的關于View, ViewPlatform, PhysicalBody, 和PhysicalEnvironment 類的信息請參考其它參考資料,附錄B有詳細的參考資料列表。
SimpleUniverse類 SimpleUniverse 對象的構造函數創建了包含VirtualUniverse 、Locale對象以及一個完整的視圖子圖在內的場景圖,SimpleUniverse創建的視圖子圖是用了ViewingPlatform 和Viewer 便利類的實例來代替了其它核心類來創建視圖子圖。注意到SimpleUniverse僅僅是沒有直接用到 Java3D核心類中的View和ViewPlatform對象的。SimpleUniverse 對象提供了圖1-7中大方框中的所有功能。com.sun.j3d.utils.universe包包括了 SimpleUniverse, ViewingPlatform, 和Viewer convenience工具類
利用一個SimpleUniverse 對象可以使構造Java3D程序的基本步驟更加簡單,表1-2展示了簡單的方法。這是用SimpleUniverse 對象之后構建Java3D程序所需的步驟,上文所提到的基本步驟的第2, 3,和4步已經被本方法的第2步所替代。 1. 創建一個Canvas3D對象。
2. 創建一個SimpleUniverse對象,并添加對先前創建的Canvas3D 對象的引用。
a. 定制SimpleUniverse對象。
3. 構建內容子圖。
4. 編譯內容分支子圖。
5. 把內容子圖添加到SimpleUniverse的Locale中。
表1-2 用SimpleUniverse創建Java3D程序的簡單步驟 下面的灰框中的內容是本教程中參考模塊的第一次出現。參考模塊一般對一個類的構造函數、方法和屬性作了個列表。使用參考模塊的目的在于使讀者能在手頭上沒有其他參考資料的情況下能學到基本的Java 3D API編程知識。本教程中的參考塊并沒有涉及到每一個類的構造函數和方法,由于這個原因,很多的Java 3D API 類都沒有列出參考塊。因此,本教程的文檔本不能替代Java 3D API規范的位置,盡管如此,列出了構造函數、方法和屬性的參考塊的這些類,本教程所提供的信息往往比Java 3D API規范所提供的信息更加詳實。
SimpleUniverse 構造函數 包: com.sun.j3d.utils.universe
這個類構建了一個盡可能小的用戶環境,以使Java3D程序能盡快盡簡單地運轉起來。這個工具類創建了視圖子圖中所必需的所有對象。特別是創建了Locale, VirtualUniverse, ViewingPlatform, 和Viewer對象, (構建這些對象時統統使用默認值).這些對象以恰當的關系構成了視圖子圖。
SimpleUniverse 提供了許多基本的Java 3D應用程序所必需的全部功能. Viewer和ViewingPlatform都是很方便的工具類.這些類用到了View 和ViewPlatform 核心類。
SimpleUniverse() 構建一個包含視圖子圖的簡單虛擬世界。.
SimpleUniverse(Canvas3D canvas3D) 構建一個簡單虛擬世界并與指定的Canvas3D對象建立關聯。建一個簡單虛擬世界并與指定的Canvas3D對象建立關聯。
SimpleUniverse對象創建了虛擬世界中一個完全的視圖分支子圖。這個視圖分支圖包括一個圖板(image plate)。Java
3D把場景內容投影到圖板塊上形成一個渲染圖象。Canvas3D 對象,提供了在計算機的窗口上顯示圖象,就可以看做圖板。
圖1-9,顯示了圖象圖板,觀察者位置和虛擬世界的關系。 觀察者在圖板后面。而可視對象在圖板之前并能在圖板上進行渲染。渲染就可以看作是可視對象到圖板上的投影。這個觀點就如圖中的四個方向上的投影儀(虛線所示)

默認地,圖板位置SimpleUniverse原始位置的中心,默認的方向是從Z軸從上往下看的。從這個位置上看,X軸是一條正向在右邊的水平穿過圖板的直線,而Y軸是垂直穿過圖板中心、正向在上方的直線。因此,點 (0,0,0)就處于圖板的正中央。 一般的Java3D程序,都把視圖往后退(Z軸正向)(譯者注:物體前移,往Z軸正向移,或往圖外移),以使物體處于或者離原始視圖比較近。SimpleUniverse類有一個ViewingPlatform的類的實例作為成員對象,ViewingPlatform類也有一個setNominalViewingTransform的方法來設置觀察者(眼睛)的位置,使之位于 (0, 0, 2.41)(looking in the negative z direction toward the origin?).
ViewingPlatform setNominalViewingTransform() 方法
包: com.sun.j3d.utils.universe ViewingPlatform 類用于設置SimpleUniverse 對象中Java 3D場景圖的視圖分支圖。這個方法一般用SimpleUniverse 類的getViewingPlatform方法來進行連接。
void setNominalViewingTransform() 把SimpleUniverse對象中的象征性的觀察者設置約2.41米的距離變化。在這個距離上,視圖的默認屬性,2米高和寬的對象大約都會恰好與圖板符合。
創建了Canvas3D和Simple Universe對象后,下一步就是創建內容子圖。對視圖子圖中的常規結構的應用,從而導致應用SimpleUniverse類的這一套,對內容子圖并不適合,因為內容子圖在每一個程序中都各有不同,因而也就不可能給出構建一個內容子圖的通用的詳細方法。這也意味著你想集成的任何虛擬世界中并不存在簡單內容類("simple content")。 創建內容子圖是第1.6,1.7和1.9節的主題,在1.8節中討論了內容了圖的編譯。如果你迫不及待地想看代碼以找出個究竟,請參考代碼段1-1,這就是一個應用SimpleUniverse 類的例子。
創建了內容子圖之后,可以用addBranchGraph把內容子圖加到SimpleUniverse對象中. addBranchGraph方法把BranchGroup 的實例作為唯一的傳入參數。BranchGroup作為SimpleUniverse 對象所創建的Locale對象的孩子加到場景圖中。
SimpleUniverse 的方法 (只列出了部分) 包: com.sun.j3d.utils.universe
void addBranchGraph(BranchGroup bg) 用于往SimpleUniverse對象所創建的Locale對象的場景圖中。用這個方法把內容子圖添加到虛擬世界中。
ViewingPlatform getViewingPlatform() 用于獲取SimpleUniverse 實例化后的ViewingPlatform 對象。這個方法再附加調用setNominalViewingTransform()方法來調整視圖的位置。
1.5一些Java 3D術語
開始創內容分支圖的主題之前,我們先定義兩個Java3D的術語. 即live 和 compiled . 把一個分支圖插入到Locale就使Locale被激活。結果,分支圖中的每一個對象都是活的。一個對象如果變活會導致一些結果。激活的對象就是要被渲染的對象。同時,激活的對象的參數一般是不能修改的,除非相應的能力(capability)在對象成為激活的對象之前就已經特定地設置好了。與能力相關的知識第1.8.2節也作了討論。 BranchGroup 對象都是可以編譯的(compiled)。 編譯一個BranchGroup 可以把一個BranchGroup對象和其所有祖先變成一種渲染器所能更高效地渲染的格式。推薦編譯一個BranchGroup對象在使之變為活對象之前的最后一步進行,并且最好只編譯一遍插入Locale中的所有BranchGroup。在1.8節和1.8.1節更進一步討論了編譯問題。
BranchGroup compile() 方法 void compile() 通過創建和緩存一個編譯過的場景圖來把與這個對象相關聯的源BranchGroup進行編譯。
編譯和變活的概念是SceneGraphObject中實現的。與這些概念相關的SceneGraphObject 類的兩個方法在SceneGraphObject的方法的參考框中得到說明。
SceneGraphObject 方法 (部分列出) SceneGraphObject幾乎是Group中創建場景圖的每一個對象的超類。包括Leaf和NodeComponent。SceneGraphObject 為其子類提供了一些通用的方法和屬性。這里說明了兩個。SceneGraphObject的方法是與"編譯"關聯的,在第1.8節講到了一些基本的東西。 boolean isCompiled() 返回一個布爾型標記,表時場景圖中的結點是否已經編譯過。 boolean isLive() 返回一個布爾型標記,表時場景圖中的結點是否已經被激活。
注意在基本和簡單的方法中都沒有"啟動渲染器"這一項。當一個包含了視圖實例的分支圖在虛擬世界中被激活的時候,Java 3D 渲染器開始以無限循環的方式運行。一旦啟動,Java 3D渲染器在概念上來講就執行如下偽碼中的操作。 while(true) { //永遠執行 Process input //處理輸入 If (request to exit) break //如果程序要求 Perform Behaviors //執行交互動作 Traverse the scene graph //遍歷場景圖以渲染各個可視對象 and render visual objects } Cleanup and exit //清理退出
上一節講述了在沒有內容分支圖時構建一個簡單的虛擬世界,而創建內容子圖是下面幾節的主題,對創建內容子圖的講述是通過示例程序來進行的。
簡單方法示例: Hello
典型的Java 3D程序以定義一個擴展Applet類的新類作為起始,示例的程序文件Hello.java 可以在 examples/HelloJava3D 目錄中找到。Hello這個類擴展了 Applet類。一些Java3D程序寫成應用程序,但是用 Applet也可以有很容易的方法使之轉型成為帶有窗口的應用程序。
Java 3D程序的主類一般都定義一個方法來構建內容分支圖。在Hello示例中,就定義了這樣的方法,并聲明為 createSceneGraph ()。用簡單分法所創建場景圖的全部步驟都在Hello 構造函數類中得到了實現。
第1步、創建一個Canvas3D對象。具體見程序的第4行到第6行。
第2步、創建一個SimpleUniverse對象,是在第13行。.第2a步, 定制SimpleUniverse 對象,到第17行就完成了.
第3步,構建內容分支圖,就是通過調用createSceneGraph()方法來完成的。
第4步,編譯內容子圖,代碼見第 10行。
最后第5步,把內容子圖插入到SimpleUniverse的Lacale中,這個操作見第19行。
1. public class Hello extends Applet {
2. public Hello() {
3. setLayout(new BorderLayout());
4. GraphicsConfiguration config =
5. SimpleUniverse.getPreferredConfiguration();
6. Canvas3D canvas3D = new Canvas3D(config);
7. add("Center", canvas3D);
8.
9. BranchGroup scene = createSceneGraph();
10. scene.compile();
11. 12. // SimpleUniverse類是一個很方便的工具類
13. SimpleUniverse simpleU = new SimpleUniverse(canvas3D);
14.
15. // 這把ViewPlatform往后移一點點,
16. //以使場景中的對象能被看到。
17. simpleU.getViewingPlatform().setNominalViewingTransform();
18.
19. simpleU.addBranchGraph(scene);
20. } // Hello (構造函數)結束
//代碼段1-1 Class Hello
/**簡單方法的第3步是創建內容分支圖。創建內容分支圖的具體代碼見代碼段1-2. 這也可能是再簡單不過的內容分支圖了。在代碼段1-2中創建的內容分支圖包括了一個靜態的圖形對象,即帶有顏色的立方體。這個帶色立方體位于虛擬世界坐標系統中初始位置。按照視圖提供的位置和方向,那個渲染后的立方體看起來像一個矩形。具體效果如圖1-12所示。 */
1. public BranchGroup createSceneGraph() {
2. // 創建分支子圖的根結點
3. BranchGroup objRoot = new BranchGroup(); 4. 5. // 創建一個簡單的圖形葉子結點,并把其加到場景圖中
6. // ColorCube也是一個很方便的工具類
7. objRoot.addChild(new ColorCube(0.4)); 8. 9. return objRoot;
10. } // Hello 的創建場景圖的方法createSceneGraph結束
11. } // Hello類結束
/**代碼段1-2 Hello 類的用于創建場景圖的createSceneGraph方法
Hello類是從Applet類繼承而來的,但是這個程序由于運用了MainFrame類也是可以作為應用程序獨立運行的。
Applet 類是用于寫在窗口式的易于運行的Java 3D程序的基本類。MainFrame 提供了一個AWT 框架(frame )(即窗
體) ,以使applet能嵌入從而像應用程序一樣運行。 結果程序的窗口的大小是在運用MainFrame類構建時時候指定的。代碼段 1-3 說明了Hello.java中所用到的MainFrame 類的用法。
MainFrame 構造函數 (列出部分)
包: com.sun.j3d.utils.applet MainFrame 類把一個小程序Applet轉換成一個應用程序。從而繼承自applet類的對象調用了MainFrame構造函數后都有一個 main()方法。MainFrame擴展了java.awt.Frame類并且實現了java.lang.Runnable, java.applet.AppletStub, 和java.applet.AppletContext. MainFrame 類是受版權保護的,由Jef Poskanzer 在1996-1998到年間創建。Email: jef@acme.com http://www.acme.com/java/ MainFrame(java.applet.Applet applet, int width, int height)
創建一個MainFrame對象,以使一個Applet能作為一個應用程序獨立運行。參數: applet - 繼承自applet類的構造函數。MainFrame為applet提供了一個AWT框架。 width - 窗體寬度象素值。 height - 窗體高度象素值。 */
1. // 下面的代碼允許Applet程序結果
2. //作為應用程序運行。
3.
4. public static void main(String[] args) {
5. Frame frame = new MainFrame(new Hello(), 256, 256);
6. } // main結束 (Hello的方法)
代碼段1-3 Hello 類的Main()方法調用MainFrame
前面的三個代碼段 (1-1, 1-2, and 1-3)再加上相應的import語句就組成了一個完整的Java3D應用程序。以下import語句在編譯Hello這個類時是必須的。
Java 3D編程所用到的最常用的類在包javax.media.j3d或者 javax.vecmath中,在這個例子里, ColorCube工具類就在包com.sun.j3d.utils.geometry中. 從而,大多數Java 3D程序都會有代碼段1-4中除引入ColorCube類之外所示的import 語句。
1. import java.applet.Applet;
2. import java.awt.BorderLayout;
3. import java.awt.Frame;
4. import java.awt.event.*;
5. import com.sun.j3d.utils.applet.MainFrame;
6. import com.sun.j3d.utils.universe.*;
7. import com.sun.j3d.utils.geometry.ColorCube;
8. import javax.media.j3d.*;
9. import javax.vecmath.*;
//代碼段 1-4 Hello.java的import語句
在Hello.java示例程序中,在唯一的locale對象中放置了唯一的圖形對象。這個場景圖如圖1-11所示。

前面四個代碼段 (1-1, 1-2, 1-3, 與 1-4) 組成了完整的示例程序Hello.java文件。用命令javac Hello.java來編譯代碼,用java Hello來運行代碼。運行結果如圖1-12所示。

而在Hello示例中不是每一行代碼我們都進行了解釋。如果通讀了整個示例,集成Java3D程序的基本概念應該清晰明了了。下面這一小節通過說明上面程序中所用到的類來彌補了說明不足的缺陷。為了更進一步了解Java 3D API 和 Hello程序,Hello例子中所用到的每一個Java 3D API類在這里都作了一個說明。BranchGroup 類
這種類型的對象是用于構建建場景圖的, BranchGroup的實例是子圖的根結點, BranchGroup對象也是唯一能成為Locale對象的孩子對象的對象。BranchGroup對象可以有多個孩子, BranchGroup對象的孩子對象可以是Group和Leaf對象。
BranchGroup 默認構造函數
BranchGroup()
BranchGroup的實例,作為場景圖分支的根結點,BranchGroup 對象也是能唯一插入到Locale對象中的對象。
Canvas3D類
Canvas3D 類繼承自Abstract Windowing Toolkit