`
txf2004
  • 浏览: 6866445 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Papervision3D基础I

阅读更多

(简称PV3D

Papervision3D

PV3D是一个开源的遵循MIT协议的使用AS3代码写成的3D引擎。这篇文章旨在教会各位如何使用PV3D完成一个HELLOWORD式的3D程序,同时也是这篇教程的最近更新。PV3D2.0 Alpha(也称GW)对于初学者来说使用PV3D最大的障碍在于如何安装PV3D,由于对版本控制软件不熟是造成无法完成PV3D安装的主要原因,第一部分的三节阐述了这个问题,但是不是这篇文章的主要内容,如果你对版本控制软件不熟悉的话,那么你可以看看这部分。

【笔者注:】安装PV3D完全没有必要使用版本控制软件,PV3D说白了就是一个FLEX的库,如果你知道如何在FLEX中使用和导入库,那么你完全没有必要使用版本控制软件,笔者的做法是到GOOGLE CODE网站去下载一个ZIP包,软后解压缩到一个文件夹,将该文件夹包含在我的项目的库目录中就可以了,至于说更新,那么重新下载一个就搞定了。

再者版本控制软件的使用教程,网上多如牛毛,我在这里也就不再累述了。第一节的三个部分都不做翻译,在译文中直接略去,望大家谅解

省略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设置一个源代码文件夹

· 如果使用的是Flash:

· 关于如何设置和修改源文件路径

· 如果使用的是FLEX

· 准备一个PV3D的项目

Document Class文件类

Create a document class to hold the required ActionScript:创建一个源文件

· 如果使用的是Flash:

· 使用AS3.0创建一个新的文档类

· Using Flex: 如果使用的是FLEX

· 创建一个新的AS工程

· 使用FLASHDEVELOP 集成环境

· 创建一个PV3D项目

Foundation of Papervision3D PV3D基础

.我尽量使得代码看起来简单以适应那些新上手AS3.0的用户,但是我还是要假定你们知道类的基础,如何写方法,如何实例化对象等等,如果还不懂得这些的话,那么你可以参看OREILYAS3.0编程基础一书,对你非常有帮助,当我实例化对象的时候,我同时还假定了你自己会去导入那些我遗漏的包。

:每一个PV3D应用程序都至少要包含这四个类:Viewport3D, Scene3D, Camera3D/ BasicRenderEngine(可选),在我进行详细的讲解之前请先浏览一下下面的代码。

package...{

importflash.display.Sprite;

importorg.papervision3d.cameras.Camera3D;

importorg.papervision3d.render.BasicRenderEngine;

importorg.papervision3d.scenes.Scene3D;

importorg.papervision3d.view.Viewport3D;

publicclassMainextendsSprite...{

privatevarviewport:Viewport3D;

privatevarscene:Scene3D;

privatevarcamera:Camera3D;

privatevarrenderer:BasicRenderEngine;

publicfunctionMain()...{

initPapervision3D();

}


privatefunctioninitPapervision3D():void...{

viewport
=newViewport3D();

addChild(viewport);

scene
=newScene3D();

camera
=newCamera3D();

renderer
=newBasicRenderEngine();

renderer.renderScene(scene,camera,viewport);

}


}


}


Viewport3D视口

可以将Viewport3D视口看成是PV3D的一扇窗户,透过这扇窗户我们才能看见PV3D世界里的东西。仅此而已,视口没有其他的功能,你可以将窗口开在墙上,可以决定窗口的大小,仅此而已。使用这个类之要记得创建之后将其加入舞台就可以了。看看下面的代码

privatevarviewport:Viewport3D=newViewport3D();
addChild(viewport);

作为参考我将视口的缺省属性列在下面,当然用户可以根据各自的喜好进行修改。在未来的文章中我们将讨论autoClipping autoCulling

Viewport3D(viewportWidth:Number=640,viewportHeight:Number=480,

autoScaleToStage:Boolean
=false,interactive:Boolean=false,

autoClipping:Boolean
=true,autoCulling:Boolean=true)

Scene3D场景

继续我们的窗口比喻,Scene3D通过窗口展示所有你能看见的3D物体:天空,大地,以及这之间的一切。然而Scene3D只是一个空的场景。要显示的内容需要创建后逐一添加到场景,场景如下创建:

private var scene:Scene3D = new Scene3D();

Camera3D镜头

如果没有一个人来欣赏着窗户和窗户外的美景的话,那真的是没有什么价值。很幸运,PV3D的开发者创建了镜头来捕捉动作,镜头也与许你设置X,Y,Z坐标来确定你从哪个角度来欣赏这个美景,想象一个第一人称设计或者飞行游戏,你移动着你的位置来观察现有的场景,对于Camera3D来说也是这样的,你移动镜头,那么整个Scene3D根据你当前的位置调整

Papervision3D provides three cameras with varying functionalities:PV3D提供了3只能够镜头来适应你不同的需求

· 要求目标朝着而且永远朝着对象看,而不管他自己当前的位置

· 提供了自由的可以在空间任意角度方向观察的方法,例如yaw(), pitch(), roll()来调整镜头的角度,而moveForward(), moveBackward(); moveLeft(), moveRight(), moveUp(), moveDown()来调整镜头的位置,例如如果你要将镜头放置在直接朝向某人脸部的话那么你需要调用moveBackward(),虽然你一直盯着那个人的脸看,但是你离他越来越远。换个角度说,如果你把镜头放在那个人的头上,调用pitch()对着那个人看,然后再调用moveBackward(),这时虽然你在空中慢慢上升,但是你仍然朝着那个人看。

· 截镜头-能够像FreeCamera3D自由镜头那样移动,但是它只能渲染你所决定的近距离或者是远距离的物体。

BasicRenderEngine基本渲染引擎

:PV3D的世界里,你就是上帝,也就是说你得来决定世界什么时候开始存在,如果没有BasicRenderEngine来渲染你的世界,那么你的世界就不会存在,因此你可以自己有的决定这个引擎的开始和结束,BasicRenderEngine通过你设置的镜头的位置来渲染你的场景里的所有的物品

privatevarrenderer:BasicRenderEngine=newBasicRenderEngine();

//UsuallywithinanEvent.ENTER_FRAMEhandlersothescene

renders
ineachframe
renderer.renderScene(scene,camera,

viewport);

即使你有许多的场景,视口,或者镜头你还是只需要一个渲染引擎来渲染所有的东西

//Asnippetofmultiplescenes,cameras,andviewporthandledbyone

rendererrenderer.renderScene(scene,camera,viewport);

renderer.renderScene(scene2,camera2,viewport2);

3D Objects3D物体

3D Coordinates3D坐标

在我们进入创建对象之前,让我们先了解一下物体在3D的空间里,是如何放置的。

FLASH2D世界里,你在舞台里放置对象的时候,坐标系是传统的计算机坐标系:左上角是原点,X轴向右增加,Y轴向下增加,然而在PV3D的世界里这一切就被颠覆了,原点位于场景的中心,镜头默认放置在(00-1000)位置处。

【笔者注:】我想3D的坐标系对于我们中国的开发者来说就不必累述了吧,我们在高中学过的立体几何远比这个复杂许多,外国人的数学一般都比较烂,所以他们需要详细的学习这方面的知识,但是对于中国人来说真的是可以免了。

<shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></path><lock aspectratio="t" v:ext="edit"></lock></shapetype><shape id="_x0000_i1032" style="WIDTH: 4in; HEIGHT: 4in" alt="" type="#_x0000_t75"><imagedata o:href="file:///F:\DOCUME~1\WangZhen\LOCALS~1\Temp\msohtml1\01\clip_image001.gif" src="file:///F:%5CDOCUME~1%5CWangZhen%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image001.gif"></imagedata></shape>

同时也要记住,你能看见的物体移动的距离和你镜头放置的位置是很有关系的,越近物体看起来就移动的越多,你不能在依赖于你在传统的2D世界里积累起来的项目或是经验,镜头放置在缺省的位置上再来考虑下面的例子

· • x = 10; //也就是场景中心右方10个单位

· • x = -10; //场景中心左方10个单位

· • y = -10; //场景中心下方10个单位

· • z = -10; //场景中心前方(离镜头近)10个单位

如果你非要弄清楚在2D的屏幕上3D是怎么实现的,那么准备你肚子里的数学货色去阅读下面的文章

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

即使你不懂得文章中提到的数学知识,你应该大致懂得了3D对象是在3D坐标的基础上创建起来的,这些3D的坐标或者说是顶点是通过三角形,倾斜之后的绘制使得物体看上去具有3D效果的。PV3D使用画家算法来排序那些三角形的可见度,对于FP来说画家算法效率很高,但是如果三角形发生重叠的话,画家算法就会失效,要解决这个问题只有创建更多的段来减少三角形重叠的问题

Plane平面

<shape id="_x0000_i1025" style="WIDTH: 163.5pt; HEIGHT: 168pt" alt="" type="#_x0000_t75"><imagedata o:href="file:///F:\DOCUME~1\WangZhen\LOCALS~1\Temp\msohtml1\01\clip_image002.gif" src="file:///F:%5CDOCUME~1%5CWangZhen%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image002.gif"></imagedata></shape>

我认为对于PV3D来说屏幕是所有项目中最有用的3D物体,特别是如果该项目是交互式的,但是奇怪的是,严格的来说平面不能被称为3D物体因为他没有厚度,PV3D里平面的形象表示是两个直角三角形沾在一块儿就成了一块平面,记住场景保存了你所能观察到的所有的物体,如果你要使用平面,那么不要忘了,创建了它之后将其添加到场景里去

varplane:Plane=newPlane();

scene.addChild(plane);

平面缺省使用了线帧材料(在以后的文章里讨论)并且宽和高都是500,因此上面的代码会创建一个放置在场景中心的(000DE 宽和高都是500面对着镜头的平面,代码如下:

SegmentsW segmentsH,以及“段”数目,宽,高,更多数量的端避免了平面在旋转的时候扭曲等错误,下面的例子展示了SW,SH两个属性分别为43时候的情况

Plane(material:MaterialObject3D=null,width:Number=0,

height:Number
=0,segmentsW:Number=0,segmentsH:Number=0,

initObject:Object
=null)

材料,宽,高,这些属性很容易就能理解。在平面的方法里分别设置其“段”的

<shape id="_x0000_i1026" style="WIDTH: 147.75pt; HEIGHT: 151.5pt" alt="" type="#_x0000_t75"><imagedata o:href="file:///F:\DOCUME~1\WangZhen\LOCALS~1\Temp\msohtml1\01\clip_image003.gif" src="file:///F:%5CDOCUME~1%5CWangZhen%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image003.gif"></imagedata></shape>

如果你创建了许多的平面,而且每一个都要进行SEGMENT的设置的话,那你可能要抓狂了,(但是SEGMENT确实提高了平面的细节程度)FP要处理的三角形的个数依赖于你的程序,但是尽量避免使这个数目超过2000

最后一个可选的属性参数,initObject同样能够存储3D对象的x, y, z, rotationX, rotationY, rotationZ, scaleX, scaleY, scaleZ,属性,在创建了3D对象之后你可以直接设置这个值,下面的例子快速的展现了这一点

PV3D PLANE

varm:WireframeMaterial=newWireframeMaterial();

//widthandheight

varw:Number
=800;

varh:Number
=800;

//segmentsWandsegmentsH

varsW:Number
=1;

varsH:Number
=1;

varinitObject:Object
=newObject();

initObject.x
=100;

initObject.rotationY
=30;

initObject.scaleZ
=20;

//Option#1usinginitObject可选1使用initObject

varplane:Plane
=newPlane(m,w,h,sW,sH,initObject);

scene.addChild(plane);

//Option#2settingpropertiesdirectly可选2直接设置

varplane:Plane
=newPlane(m,w,h,sW,sH,initObject);

plane.x
=100;

plane.rotationY
=30;

plane.scaleZ
=20;

scene.addChild(plane);

.关于平面的最后一点,如果你钉住一个平面,你就会注意到从屏幕的另一侧来看的时候平面就消失了,如果你有平面的双面纹理材料那么你需要设置平面的doubleSided属性,如下:

material.doubleSided = true;

Sphere球体

你可以和创建屏幕非常类似的那样来创建一个球体

PV3D SPHERE

<shape id="_x0000_i1033" style="WIDTH: 98.25pt; HEIGHT: 103.5pt" alt="" type="#_x0000_t75"><imagedata o:href="file:///F:\DOCUME~1\WangZhen\LOCALS~1\Temp\msohtml1\01\clip_image004.gif" src="file:///F:%5CDOCUME~1%5CWangZhen%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image004.gif"></imagedata></shape>

varsphere:Sphere=newSphere();

scene.addChild(sphere);

球体的缺省参数和平面很相似,球体初始化的时候只需要一个半径参数,这一点和平面是不同的,【BLUR,BLUR BLUR球体的俄数学知识介绍 译者注】缺省参数如下:

Sphere(material:MaterialObject3D=null,radius:Number=100,

segmentsW:
int=8,segmentsH:int=6,

initObject:Object
=null)

为了简单起见,锥体和柱体就简单的列出了创建方法了,原理和上面描述的也差不多:

<shape id="_x0000_i1034" style="WIDTH: 88.5pt; HEIGHT: 83.25pt" alt="" type="#_x0000_t75"><imagedata o:href="file:///F:\DOCUME~1\WangZhen\LOCALS~1\Temp\msohtml1\01\clip_image006.gif" src="file:///F:%5CDOCUME~1%5CWangZhen%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image006.gif"></imagedata></shape>

Cone(material:MaterialObject3D=null,radius:Number
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics