Papervision3D
PV3D是一個開源的遵循MIT協(xié)議的使用AS3代碼寫成的3D引擎。這篇文章旨在教會各位如何使用PV3D完成一個HELLOWORD式的3D程序,同時也是這篇教程的最近更新。PV3D2.0 Alpha(也稱GW)對于初學(xué)者來說使用PV3D最大的障礙在于如何安裝PV3D,由于對版本控制軟件不熟是造成無法完成PV3D安裝的主要原因,第一部分的三節(jié)闡述了這個問題,但是不是這篇文章的主要內(nèi)容,如果你對版本控制軟件不熟悉的話,那么你可以看看這部分。
【筆者注:】安裝PV3D完全沒有必要使用版本控制軟件,PV3D說白了就是一個FLEX的庫,如果你知道如何在FLEX中使用和導(dǎo)入庫,那么你完全沒有必要使用版本控制軟件,筆者的做法是到GOOGLE CODE網(wǎng)站去下載一個ZIP包,軟后解壓縮到一個文件夾,將該文件夾包含在我的項目的庫目錄中就可以了,至于說更新,那么重新下載一個就搞定了。
再者版本控制軟件的使用教程,網(wǎng)上多如牛毛,我在這里也就不再累述了。第一節(jié)的三個部分都不做翻譯,在譯文中直接略去,望大家諒解
省略PV3D安裝部分。
Papervision3D at the following link then skip to the “Foundation of Papervision3D” section:
· Revision 435: /trunk/branches/GreatWhite/src
If you don’t know what to do with that link, then continue on reading the links in the first three sections.
Download
First, you need to download Papervision3D using subversion. Follow the instructions at either of these sites:
· How Can I Download Papervision3D?
· Downloading Papervision3D Alpha Great White
Classpath類路徑
:為PV3D設(shè)置一個源代碼文件夾
· 如果使用的是Flash:
· 關(guān)于如何設(shè)置和修改源文件路徑
· 如果使用的是FLEX:
· 準(zhǔn)備一個PV3D的項目
Document Class文件類
Create a document class to hold the required ActionScript:創(chuàng)建一個源文件
· 如果使用的是Flash:
· 使用AS3.0創(chuàng)建一個新的文檔類
· Using Flex: 如果使用的是FLEX:
· 創(chuàng)建一個新的AS工程
· 使用FLASHDEVELOP 集成環(huán)境
· 創(chuàng)建一個PV3D項目
Foundation of Papervision3D PV3D基礎(chǔ)
.我盡量使得代碼看起來簡單以適應(yīng)那些新上手AS3.0的用戶,但是我還是要假定你們知道類的基礎(chǔ),如何寫方法,如何實例化對象等等,如果還不懂得這些的話,那么你可以參看OREILY的AS3.0編程基礎(chǔ)一書,對你非常有幫助,當(dāng)我實例化對象的時候,我同時還假定了你自己會去導(dǎo)入那些我遺漏的包。
:每一個PV3D應(yīng)用程序都至少要包含這四個類:Viewport3D, Scene3D, Camera3D/ BasicRenderEngine(可選),在我進行詳細(xì)的講解之前請先瀏覽一下下面的代碼。

















































Viewport3D視口
可以將Viewport3D視口看成是PV3D的一扇窗戶,透過這扇窗戶我們才能看見PV3D世界里的東西。僅此而已,視口沒有其他的功能,你可以將窗口開在墻上,可以決定窗口的大小,僅此而已。使用這個類之要記得創(chuàng)建之后將其加入舞臺就可以了。看看下面的代碼




作為參考我將視口的缺省屬性列在下面,當(dāng)然用戶可以根據(jù)各自的喜好進行修改。在未來的文章中我們將討論autoClipping 和 autoCulling






繼續(xù)我們的窗口比喻,Scene3D通過窗口展示所有你能看見的3D物體:天空,大地,以及這之間的一切。然而Scene3D只是一個空的場景。要顯示的內(nèi)容需要創(chuàng)建后逐一添加到場景,場景如下創(chuàng)建:
private var scene:Scene3D = new Scene3D();
Camera3D鏡頭
如果沒有一個人來欣賞著窗戶和窗戶外的美景的話,那真的是沒有什么價值。很幸運,PV3D的開發(fā)者創(chuàng)建了鏡頭來捕捉動作,鏡頭也與許你設(shè)置X,Y,Z坐標(biāo)來確定你從哪個角度來欣賞這個美景,想象一個第一人稱設(shè)計或者飛行游戲,你移動著你的位置來觀察現(xiàn)有的場景,對于Camera3D來說也是這樣的,你移動鏡頭,那么整個Scene3D根據(jù)你當(dāng)前的位置調(diào)整
Papervision3D provides three cameras with varying functionalities:PV3D提供了3只能夠鏡頭來適應(yīng)你不同的需求
· •要求目標(biāo)朝著而且永遠(yuǎn)朝著對象看,而不管他自己當(dāng)前的位置
· •提供了自由的可以在空間任意角度方向觀察的方法,例如yaw(), pitch(), 和 roll()來調(diào)整鏡頭的角度,而moveForward(), moveBackward(); moveLeft(), moveRight(), moveUp(), 和 moveDown()來調(diào)整鏡頭的位置,例如如果你要將鏡頭放置在直接朝向某人臉部的話那么你需要調(diào)用moveBackward(),雖然你一直盯著那個人的臉看,但是你離他越來越遠(yuǎn)。換個角度說,如果你把鏡頭放在那個人的頭上,調(diào)用pitch()對著那個人看,然后再調(diào)用moveBackward(),這時雖然你在空中慢慢上升,但是你仍然朝著那個人看。
· •截鏡頭-能夠像FreeCamera3D自由鏡頭那樣移動,但是它只能渲染你所決定的近距離或者是遠(yuǎn)距離的物體。
BasicRenderEngine基本渲染引擎
:在PV3D的世界里,你就是上帝,也就是說你得來決定世界什么時候開始存在,如果沒有BasicRenderEngine來渲染你的世界,那么你的世界就不會存在,因此你可以自己有的決定這個引擎的開始和結(jié)束,BasicRenderEngine通過你設(shè)置的鏡頭的位置來渲染你的場景里的所有的物品









即使你有許多的場景,視口,或者鏡頭你還是只需要一個渲染引擎來渲染所有的東西






3D Objects3D物體
3D Coordinates3D坐標(biāo)
在我們進入創(chuàng)建對象之前,讓我們先了解一下物體在3D的空間里,是如何放置的。
在FLASH的2D世界里,你在舞臺里放置對象的時候,坐標(biāo)系是傳統(tǒng)的計算機坐標(biāo)系:左上角是原點,X軸向右增加,Y軸向下增加,然而在PV3D的世界里這一切就被顛覆了,原點位于場景的中心,鏡頭默認(rèn)放置在(0,0,-1000)位置處。
【筆者注:】我想3D的坐標(biāo)系對于我們中國的開發(fā)者來說就不必累述了吧,我們在高中學(xué)過的立體幾何遠(yuǎn)比這個復(fù)雜許多,外國人的數(shù)學(xué)一般都比較爛,所以他們需要詳細(xì)的學(xué)習(xí)這方面的知識,但是對于中國人來說真的是可以免了。
同時也要記住,你能看見的物體移動的距離和你鏡頭放置的位置是很有關(guān)系的,越近物體看起來就移動的越多,你不能在依賴于你在傳統(tǒng)的2D世界里積累起來的項目或是經(jīng)驗,鏡頭放置在缺省的位置上再來考慮下面的例子
· • x = 10; //也就是場景中心右方10個單位
· • x = -10; //場景中心左方10個單位
· • y = -10; //場景中心下方10個單位
· • z = -10; //場景中心前方(離鏡頭近)10個單位
如果你非要弄清楚在2D的屏幕上3D是怎么實現(xiàn)的,那么準(zhǔn)備你肚子里的數(shù)學(xué)貨色去閱讀下面的文章
http://en.wikipedia.org/wiki/Quarterion
http://www.adobe.com/devnet/flash/articles/3d_classes_03.html
http://www.isner.com/tutorials/quatSpells/quaternion_spells_14.htm
即使你不懂得文章中提到的數(shù)學(xué)知識,你應(yīng)該大致懂得了3D對象是在3D坐標(biāo)的基礎(chǔ)上創(chuàng)建起來的,這些3D的坐標(biāo)或者說是頂點是通過三角形,傾斜之后的繪制使得物體看上去具有3D效果的。PV3D使用畫家算法來排序那些三角形的可見度,對于FP來說畫家算法效率很高,但是如果三角形發(fā)生重疊的話,畫家算法就會失效,要解決這個問題只有創(chuàng)建更多的段來減少三角形重疊的問題
Plane平面
我認(rèn)為對于PV3D來說屏幕是所有項目中最有用的3D物體,特別是如果該項目是交互式的,但是奇怪的是,嚴(yán)格的來說平面不能被稱為3D物體因為他沒有厚度,PV3D里平面的形象表示是兩個直角三角形沾在一塊兒就成了一塊平面,記住場景保存了你所能觀察到的所有的物體,如果你要使用平面,那么不要忘了,創(chuàng)建了它之后將其添加到場景里去




平面缺省使用了線幀材料(在以后的文章里討論)并且寬和高都是500,因此上面的代碼會創(chuàng)建一個放置在場景中心的(0,0,0)DE 寬和高都是500面對著鏡頭的平面,代碼如下:
SegmentsW 和 segmentsH,以及“段”數(shù)目,寬,高,更多數(shù)量的端避免了平面在旋轉(zhuǎn)的時候扭曲等錯誤,下面的例子展示了SW,SH兩個屬性分別為4和3時候的情況





材料,寬,高,這些屬性很容易就能理解。在平面的方法里分別設(shè)置其“段”的
如果你創(chuàng)建了許多的平面,而且每一個都要進行SEGMENT的設(shè)置的話,那你可能要抓狂了,(但是SEGMENT確實提高了平面的細(xì)節(jié)程度)FP要處理的三角形的個數(shù)依賴于你的程序,但是盡量避免使這個數(shù)目超過2000
最后一個可選的屬性參數(shù),initObject同樣能夠存儲3D對象的x, y, z, rotationX, rotationY, rotationZ, scaleX, scaleY, scaleZ,屬性,在創(chuàng)建了3D對象之后你可以直接設(shè)置這個值,下面的例子快速的展現(xiàn)了這一點








































.關(guān)于平面的最后一點,如果你釘住一個平面,你就會注意到從屏幕的另一側(cè)來看的時候平面就消失了,如果你有平面的雙面紋理材料那么你需要設(shè)置平面的doubleSided屬性,如下:
material.doubleSided = true;
Sphere球體
你可以和創(chuàng)建屏幕非常類似的那樣來創(chuàng)建一個球體




球體的缺省參數(shù)和平面很相似,球體初始化的時候只需要一個半徑參數(shù),這一點和平面是不同的,【BLUR,BLUR BLUR球體的俄數(shù)學(xué)知識介紹譯者注】缺省參數(shù)如下:






為了簡單起見,錐體和柱體就簡單的列出了創(chuàng)建方法了,原理和上面描述的也差不多:















Cube正方體
如果拿出6個平面并將其組裝為一個盒子,你能像到什么?一個立方體
到現(xiàn)在你已經(jīng)懂得了如何創(chuàng)建3d對象,除了立方體引入了一個MaterialsList(稍侯討論),閱讀一下如何創(chuàng)建一個立方體你大概就明白了如何創(chuàng)建一個MaterialsList






























如果鏡頭缺省設(shè)置的話,立方體渲染的時候看起來是劇中的,鏡頭直對著立方體,沒有任何角度的話,立方體看起來就像一個平面,你可以通過設(shè)置立方體的rotation屬性來觀察立方體的全部效果,下面是立方體的全部缺省參數(shù)
Cube( materials:MaterialsList, width:Number=500, depth:Number=500,
height:Number=500, segmentsS:int=1, segmentsT:int=1, segmentsH:int=1,
insideFaces:int=0, excludeFaces:int=0, initObject:Object=null )
段需要稍加解釋,然而函數(shù)和平面的段是基本一致的。
· • segmentS -段徑向的數(shù)目(如果是平面的話就是和寬垂直)默認(rèn)為1
· • segmentsT -. 段縱向的數(shù)量(如果是平面的話就是和厚度垂直),缺省和sS一樣
· • segmentsH -水平方向的段數(shù)量(平面的話就是和高垂直)缺省和sS一樣
insideFaces參數(shù)決定了立方體內(nèi)部的面是如何渲染的,這對于將鏡頭放在立方體內(nèi)部是有效的,使用以下的立方體的靜態(tài)參數(shù)來確定你想要包含的面
· • Cube.NONE
· • Cube.FRONT
· • Cube.BACK
· • Cube.LEFT
· • Cube.RIGHT
· • Cube.TOP
· • Cube.BOTTOM
· • Cube.ALL
只需要簡單的創(chuàng)建一個insideFaces整型常量然后將其添加到合適的地方。例如:如果你只要立方體的內(nèi)部的上面那么可以這么寫
var insideFaces:int = Cube.TOP;
var cube:Material = new Cube(m, w, d, h, sS, sT, sH, insideFaces);
如果你需要立方體內(nèi)的左和右面那么可以這么寫
var insideFaces:int = Cube.LEFT + Cube.RIGHT + Cube.BOTTOM;
var cube:Material = new Cube(m, w, d, h, sS, sT, sH, insideFaces);
如果你想要所有的面除了前面,那么可以這么寫
var insideFaces:int = Cube.ALL - Cube.FRONT;
var cube:Material = new Cube(m, w, d, h, sS, sT, sH, insideFaces);
下一個參數(shù)excludeFaces原理是一樣的,但是它的作用是排除那些你不想要的面
Collada3DMAX支持的文件
這才是PV3D使人興奮的地方,你可以通過你熟悉的3D工具創(chuàng)建你想要的3D模型,然后將其到處為COLLADA文件然后通過PV3D的DAE類進行裝載,不幸的是這一點的討論足足需要一篇文章,但是如果你想看看的話,可以點擊下面的例子
Loading Collada Files into Papervision3D
Testing Kinematics with Papervision3D Collada
DCC Tutorials
Enough Talk, Let’s See Code!談的夠多了,看看代碼吧
我打賭你一定覺得學(xué)的夠多了,而迫不及待的要敲擊鍵盤了,下面我們就給出一個完整的PV3D的例子




















































































































常見的錯誤:救命!我看不見任何東西
· 1.你恰當(dāng)?shù)膶?dǎo)入了所有的類嗎?
·
2.你將場景加入容器了嗎?
addChild(viewport);
·
3.你將所有的對象都加入到了場景里嗎?
scene.addChild(cube);
·
4.你渲染了你的場景嗎?
renderer.renderScene(scene,
camera, viewport);
Just Getting Started僅僅是開始
我希望你認(rèn)識到這篇文章所觸及的不過是冰山的一角,下面的文章將討論紋理方面的知識,這樣你就可以做出更加好,更加漂亮的3D對象了
Thanks致謝
我想要謝謝PV3D的所有開發(fā)人員,給予我們這樣優(yōu)秀的PV3D產(chǎn)品,我也要謝謝郵件列表中,開源社區(qū)的所有人,你們共同制造了這樣的一個優(yōu)秀產(chǎn)品
· Core team
· Carlos Ulloa
· John Grden
· Ralph Hauwert
· Tim Knip
· Andy Zupko
· Committer team
· Mr.doob
· De'Angelo Richardson
· Tink
· Seb-Lee Delisle
· Contributors
· Patrick Pietens
· Ron Valstar
源文檔 <http://www.insideria.com/2008/02/papervision3d-part-1-foundatio.html>
Papervision3D
Papervision3D is an open-source, MIT licensed 3D engine written in ActionScript 3.0 for Flash. This article will teach you how to set up your first Papervision3D application with the most recent revision as of this writing, Papervision3D 2.0 Alpha, otherwise known as “Great White.” The great barrier for beginners is usually “installing” Papervision3D as they are unfamiliar with subversion, classpaths, and documents classes. The first three sections address these issues with off-site tutorials as that process is not within the scope of this article. So if you’re familiar with the subversion process and setting up an ActionScript 3.0 project, check out Papervision3D at the following link then skip to the “Foundation of Papervision3D” section:
· Revision 435: /trunk/branches/GreatWhite/src
If you don’t know what to do with that link, then continue on reading the links in the first three sections.
Download
First, you need to download Papervision3D using subversion. Follow the instructions at either of these sites:
· How Can I Download Papervision3D?
· Downloading Papervision3D Alpha Great White
Classpath
Set up a classpath that points to the Great White “src” directory:
· Using Flash:
· About Setting and Modifying the Classpath
· Using Flex:
· Preparing a Papervision3D Project
Document Class
Create a document class to hold the required ActionScript:
· Using Flash:
· Creating a Document Class with ActionScript 3.0
· Using Flex:
· New -> ActionScript Project”
· Using FlashDevelop:
· Preparing a Papervision3D Project
Foundation of Papervision3D
I’ll keep the code as simple as I can for those of you new to ActionScript 3.0, but I will assume you have a basic understanding of importing classes, declaring/instantiating variables, and writing/calling methods. If not, O’Reilly’s “Essential ActionScript 3.0” is a great place to start. When I instantiate objects in code snippets, I’ll assume you understand you need to import the relevant classes.
Every Papervision3D application requires four classes: Viewport3D, Scene3D, Camera3D (or alternatives), and BasicRenderEngine (or alternative). Glance at the following typical set up of a Papervision3D project before I dive into a full explanation:
package{
import flash.display.Sprite;
import org.papervision3d.cameras.Camera3D;
import org.papervision3d.render.BasicRenderEngine;
import org.papervision3d.scenes.Scene3D;
import org.papervision3d.view.Viewport3D;
public class Main extends Sprite{
private var viewport:Viewport3D;
private var scene:Scene3D;
private var camera:Camera3D;
private var renderer:BasicRenderEngine;
public function Main(){
initPapervision3D();
}
private function initPapervision3D():void{
viewport = new Viewport3D();
addChild(viewport);
scene = new Scene3D();
camera = new Camera3D();
renderer = new BasicRenderEngine();
renderer.renderScene(scene, camera, viewport);
}
}
}
Viewport3D
Think of a Viewport3D as a window to the world of Papervision3D. Windows allow you to see outside, but they serve no other function. You can position a window on the wall or change its width and height, but that’s really about it. The same is true with Viewport3D. You can change the “x”, “y”, “width”, and “height” of the Viewport3D, but its only true functionality is to let you look at the 3d scene inside of it. To use a viewport, create it then add it to the stage.
private var viewport:Viewport3D = new Viewport3D();
addChild(viewport);
For reference, the default parameters of Viewport3D, which you can adjust to your liking, are as follows. I’ll cover interactive, autoClipping, and autoCulling in a future article:
Viewport3D(viewportWidth:Number = 640, viewportHeight:Number = 480,
autoScaleToStage:Boolean = false, interactive:Boolean = false,
autoClipping:Boolean = true, autoCulling:Boolean = true)
Scene3D
To continue with the window metaphor, a Scene3D would hold everything you could see looking through the window: the ground, the sky, and everything in-between. Yet the Scene3D is still just empty 3D space. You have to add the ground, the sky, the trees, etc., by adding 3d objects to your Scene3D. A scene3D is created as follows:
private var scene:Scene3D = new Scene3D();
Camera3D
A window and an outside world are pretty worthless if there’s no one there to witness their beauty. Luckily for you, the developers of Papervision3D created cameras to capture all the action. A Camera3D allows you to set the x, y, and z coordinates from where you want to capture the action. Imagine a first-person shooter or flight simulator. You move your character around and the surrounding area adjusts to your current position. The same idea applies to Camera3D movement: you move the camera and the entire Scene3D adjusts to its current position.
Papervision3D provides three cameras with varying functionalities:
· • Camera3D- requires a target to “look at” and will always “look at” that target regardless of position
· • FreeCamera3D- moves freely through 3D space in every angle and direction. Includes methods such as yaw(), pitch(), and roll() to adjust the camera’s viewing angle as well as moveForward(), moveBackward(); moveLeft(), moveRight(), moveUp(), and moveDown() to adjust the camera’s position based on its viewing angle. For example, if you position the camera looking straight at someone’s face then call moveBackward(), you will move farther and farther back from that person’s face while still looking straight their face. On the other hand, if you position the camera above the person, pitch() the camera to look straight down at their hair, and then call the same moveBackward() method, you will lift the camera higher into the sky while continuing to look at the person’s hair.
· • FrustumCamera3D- moves like FreeCamera3D, but only renders the objects within a field of view, far distance, and near distance that you determine.
BasicRenderEngine
In the world of Papervision3D, you’re God. That means you get to decide when the world exists. Without the BasicRenderEngine class rendering your world, it just won’t exist. So you can start and stop the engine as you please. The BasicRenderEngine renders a Scene3D from the Camera3D position through the Viewport3D that you choose:
private var renderer:BasicRenderEngine = new BasicRenderEngine();
//Usually within an Event.ENTER_FRAME handler so the scene
renders
in each frame
renderer.renderScene( scene, camera,
viewport );
Even if you have multiple scenes, viewports, or cameras, you still only need one BasicRenderEngine to handle all of the rendering:
//A snippet of multiple scenes, cameras, and viewport handled by one
renderer renderer.renderScene( scene, camera, viewport );
renderer.renderScene( scene2, camera2, viewport2 );
3D Objects
3D Coordinates
Before diving into creating objects, let’s take a look at how objects are positioned in 3D space as opposed to traditional Flash projects.
In Flash, you position an object on the stage based on x:0 and y:0 being in the upper-left corner. Increasing x moves an object to the right and increasing y moves an object down. Conversely, in Papervison3D x:0, y:0, and z:0 are in the center (not the upper-left) of the Scene3D. Since the Camera3D defaults to x:0, y:0, z:-1000 and points at the origin (x:0, y:0, z:0), increasing x moves the object right, increasing y moves the object up, and increasing z moves the object toward the horizon.
Also, remember the amount of movement you will see is based on how close the camera is to the 3d object. The closer the camera the more objects will appear to move. You cannot rely on pixels like you can in a traditional two dimensional Flash project. Consider the following examples based on the default camera position:
· • x = 10; //means 10 units right of Scene3D’s center
· • x = -10; //means 10 units left of Scene3D’s center
· • y = -10; //means 10 units below Scene3D’s center
· • z = -10; //means 10 units closer to the camera from Scene3D’s center (remember Camera3D defaults to z:-1000 so moving from 0 to -10 brings the object closer to -1000.)
If you’re the type of person who must understand how 3D coordinates are possible within in a 2D Flash Player, put on your math hat and read up on quarterions:
http://en.wikipedia.org/wiki/Quarterion
http://www.adobe.com/devnet/flash/articles/3d_classes_03.html
http://www.isner.com/tutorials/quatSpells/quaternion_spells_14.htm
Even if you don’t understand the math involved in those articles, you probably understand that 3D objects are made up groups of 3D coordinates. These 3D coordinates (also known as vertices) form triangles. The triangles form a polygon mesh or, in layman’s terms, a 3D object.
On a side note, Papervision3D uses the Painter’s Algorithm to sort the visibility of those triangles. The Painter’s Algorithm evaluates the sorting quickly (ideal for Flash Player), but can fail if triangles overlap. You typically resolve this issue by creating more segments in your 3D object to give less chance that the triangles overlap.
Plane
I consider Planes to be the most useful 3D objects for most Papervision3D projects, especially if the project is interactive. Oddly enough, a Plane does not technically qualify as a 3D object as it has no depth. A Plane is simply two triangles stuck together to form a rectangle. Remember, the Scene3D holds all of your 3D objects. So to use a plane, create it then add it to the Scene3D.
var plane:Plane = new Plane();
scene.addChild(plane);
A Plane defaults to a WireFrameMaterial (discussed in a later article) with a width of 500 and height of 500. So using the above code will result in a wireframe Plane centered at x:0, y:0, and z:0 with a width and height of 500 facing the camera (assuming the camera is in its default position discussed earlier). When you pass a material with an image inside it, the Plane will default to the width and height of the bitmap of that image. The parameters available for a Plane are as follows:
Plane( material:MaterialObject3D=null, width:Number=0,
height:Number=0, segmentsW:Number=0, segmentsH:Number=0,
initObject:Object=null )
Material, width, and height are pretty self-explanatory. SegmentsW and segmentsH set the number of segments in the width and height of the Plane respectively. Multiple segments help to avoid the distortion of an image when the Plane starts rotating as well as the depth sorting of the triangles as mentioned earlier. The screenshot below demonstrates a Plane with four segmentsW and three segmentsH.
Be wary when creating many Planes as each additional width or height segment you create tacks on two more triangles (essentially forming another rectangle inside the Plane to give the plane more detail). The number of triangles Flash Player can handle varies depending on your application, but generally try and keep the triangle count below 2000.
The last optional parameter, initObject, can store the initial x, y, z, rotationX, rotationY, rotationZ, scaleX, scaleY, scaleZ, and “extra” parameters. Alternatively, you can directly set the listed properties after instantiating your Plane. A quick example will explain nicely:
var m:WireframeMaterial = new WireframeMaterial();
//width and height
var w:Number = 800;
var h:Number = 800;
//segmentsW and segmentsH
var sW:Number = 1;
var sH:Number = 1;
var initObject:Object = new Object();
initObject.x = 100;
initObject.rotationY = 30;
initObject.scaleZ = 20;
//Option #1 using initObject
var plane:Plane = new Plane(m, w, h, sW, sH, initObject);
scene.addChild(plane);
//Option #2 setting properties directly
var plane:Plane = new Plane(m, w, h, sW, sH, initObject);
plane.x = 100;
plane.rotationY = 30;
plane.scaleZ = 20;
scene.addChild(plane);
One final note about Planes: if you spin a Plane, you’ll notice the plane will disappear once you look at the other side. If you want to have a texture on both sides of the Plane, you will need to enable the “doubleSided” property of your material you pass into your Plane.
material.doubleSided = true;
Sphere
You create a Sphere very similarly to the way you create a Plane:
var sphere:Sphere = new Sphere();
scene.addChild(sphere);
A Sphere’s default parameters closely resemble a Plane’s parameters as well. The Sphere just takes a radius parameter instead of width and height. If you think back to high school, you will probably recall the radius being the distance from the center of the circle to the outer edge. As opposed to the simplicity of width and height of a Plane, the Sphere now uses the radius to calculate the distance between the center and the edges to create groups of three vertices that make groups of triangles that make the Sphere. Pretty neat, huh? The default parameters are as follows:
Sphere( material:MaterialObject3D=null, radius:Number=100,
segmentsW:int=8, segmentsH:int=6,
initObject:Object=null )
For brevity’s sake, a Cone and a Cylinder can be created similarly with the following default parameters:
Cone( material:MaterialObject3D=null, radius:Number=100,
height:Number=100, segmentsW:int=8, segmentsH:int=6,
initObject:Object=null )
Cylinder( material:MaterialObject3D=null, radius:Number=100,
height:Number=100, segmentsW:int=8, segmentsH:int=6,
topRadius:Number=-1,
initObject:Object=null )
Cube
What do you get when you take six Planes and organize them into the shape of a box? A Cube!
By now you should be getting the hang of creating 3D objects, but the Cube throws in a curve ball by requiring a MaterialsList (discussed in a later article). You will probably get the gist of how to use a MaterialsList by reading how to create a Cube:
var frontMaterial:WireframeMaterial = new WireframeMaterial();
var backMaterial:WireframeMaterial = new WireframeMaterial();
var leftMaterial:WireframeMaterial = new WireframeMaterial();
var rightMaterial:WireframeMaterial = new WireframeMaterial();
var topMaterial:WireframeMaterial = new WireframeMaterial();
var bottomMaterial:WireframeMaterial = new WireframeMaterial();
var materialsList:MaterialsList = new MaterialsList();
materialsList.addMaterial(frontMaterial, "front");
materialsList.addMaterial(backMaterial, "back");
materialsList.addMaterial(leftMaterial, "left");
materialsList.addMaterial(rightMaterial, "right");
materialsList.addMaterial(topMaterial, "top");
materialsList.addMaterial(bottomMaterial, "bottom");
var cube:Cube = new Cube(materialsList);
scene.addChild(cube);
The Cube faces forward when rendered meaning, with the camera in the default z:-1000 looking at x:0, y:0, z:0 position, you will be looking directly at the back of the Cube. Without any perspective, it will look exactly like a Plane. You can easily set any of the Cube’s rotation properties to see the full effect (the earlier Cube image was rotated slightly to show perspective). Now let’s cover the default parameters of a cube:
Cube( materials:MaterialsList, width:Number=500, depth:Number=500,
height:Number=500, segmentsS:int=1, segmentsT:int=1, segmentsH:int=1,
insideFaces:int=0, excludeFaces:int=0, initObject:Object=null )
The segments require a little explaining, yet function in the same fashion as Plane’s segments:
· • segmentS - Number of segments sagitally (plane perpendicular to width). Defaults to 1.
· • segmentsT - Number of segments transversally (plane perpendicular to depth). Defaults to segmentsS.
· • segmentsH - Number of segments horizontally (plane perpendicular to height). Defaults to segmentsS.
The insideFaces parameter determines which faces will be rendered on the inside of the Cube. This is useful if you want to have the camera inside of the Cube for the illusion of being trapped in a room. To set the faces you want to include, use the following static public variables of Cube:
· • Cube.NONE
· • Cube.FRONT
· • Cube.BACK
· • Cube.LEFT
· • Cube.RIGHT
· • Cube.TOP
· • Cube.BOTTOM
· • Cube.ALL
Simply create an insideFaces integer that describes which faces you want to see on the inside and pass it as a parameter where appropriate. For example, if you want just the top of the inside of the Cube to be rendered, write the following:
var insideFaces:int = Cube.TOP;
var cube:Material = new Cube(m, w, d, h, sS, sT, sH, insideFaces);
For just the left, right, and bottom face:
var insideFaces:int = Cube.LEFT + Cube.RIGHT + Cube.BOTTOM;
var cube:Material = new Cube(m, w, d, h, sS, sT, sH, insideFaces);
For all the faces except the front face:
var insideFaces:int = Cube.ALL - Cube.FRONT;
var cube:Material = new Cube(m, w, d, h, sS, sT, sH, insideFaces);
The next parameter, excludeFaces, works exactly the same way, but excludes the faces you don’t want. Think of it like taking the lid of a shoebox.
Collada
This is where Papervision3D gets really exciting: you create a model in your preferred 3D modeling program (3ds max, Maya, Blender, Swift3D, etc.), export it as a Collada file, and load it using the Papervision3D DAE class. Unfortunately, this topic deserves an article unto itself, but here are a few demos to get you on the right track:
Loading Collada Files into Papervision3D
Testing Kinematics with Papervision3D Collada
DCC Tutorials
Enough Talk, Let’s See Code!
I bet you’re anxious to start tickling the keyboard to see if it laughs out a working Papervision3D project. So let’s make a Cube and spin it using the Cube yaw() and pitch() methods (Don’t fret, I’ll cover the details of yaw, pitch, roll, etc. in future articles):
package {
import flash.display.Sprite;
import flash.events.Event;
import org.papervision3d.cameras.Camera3D;
import org.papervision3d.materials.WireframeMaterial;
import org.papervision3d.materials.utils.MaterialsList;
import org.papervision3d.objects.primitives.Cube;
import org.papervision3d.render.BasicRenderEngine;
import org.papervision3d.scenes.Scene3D;
import org.papervision3d.view.Viewport3D;
[SWF ( width = '640', height = '480', backgroundColor = '#ffffff',
frameRate = '31' ) ]
public class RotatingCubeExample extends Sprite {
private var viewport:Viewport3D;
private var scene:Scene3D;
private var camera:Camera3D;
private var renderer:BasicRenderEngine;
private var cube:Cube;
public function RotatingCubeExample(){
'initPapervision3D();
createCube();
beginRender();
}
private function initPapervision3D():void{
viewport = new Viewport3D();
addChild(viewport);
scene = new Scene3D();
camera = new Camera3D();
renderer = new BasicRenderEngine();
}
private function createCube():void{
var allM:WireframeMaterial = new WireframeMaterial();
var m:MaterialsList = new MaterialsList();
m.addMaterial(allM, "all");
//width, depth, height
var w:Number = 300;
var d:Number = 500;
var h:Number = 700;
//segments S, T, and H
var sS:int = 2;
var sT:int = 3;
var sH:int = 4;
cube = new Cube(m, w, d, h, sS, sT, sH);
scene.addChild(cube);
}
private function beginRender():void{
//calls the render function every frame
addEventListener(Event.ENTER_FRAME, render);
}
private function render(e:Event):void{
//rotates around the vertical axis
cube.yaw(2);
//rotates around the lateral axis
cube.pitch(1);
renderer.renderScene(scene, camera, viewport);
}
}
}
Common Mistakes: Help! I Don’t See Anything!
· 1. Did you properly import the Papervision3D classes?
·
2.
Did you “addChild()” your viewport?
addChild(viewport);
·
3.
Did you “scene.addChild()” your 3D Object?
scene.addChild(cube);
·
4.
Did you render your scene?
renderer.renderScene(scene, camera,
viewport);
Just Getting Started
I hope you realize that this article barely touched the tip of the Papervision3D iceberg. The next article will cover the materials (sometimes known as textures) so you can make your 3D objects look nice and pretty.
Thanks
I’d like to thank all of the members of the Papervision3D team, everyone who has ever helped anyone on the Papervision3D mailing list, and the community for making such a wonderful open-source product:
· Core team
· Carlos Ulloa
· John Grden
· Ralph Hauwert
· Tim Knip
· Andy Zupko
· Committer team
· Mr.doob
· De'Angelo Richardson
· Tink
· Seb-Lee Delisle
· Contributors
· Patrick Pietens
· Ron Valstar