http://code.google.com/p/papervision3d/。目前最新版本是2.0a(Greate White)。下面对PV3D 1.5版进行简单的源代码分析,希望对学习PV3D的同志能有所帮助。
下图是PV3D 1.5的引擎类图(截自于一韩国网友的博客):
以下是我去年看PV3D 1.5引擎源代码时所做的简单的分析,由于是直接从WORD文件上拷贝到博客上,所以排版可能不是很美观,还请见谅 :)
---------------------------------------------------------------华丽的分割线--------------------------------------------------------
一、Papervision3D.as
一些全局设置,还有log函数
二、core
1.Number3D.as
Number3D类:3D坐标系中的一个值
(1)属性:x,y,z:Number:浮点数
(2)方法:clone()
modulo():长度
add()
sub()
dot()
cross()
normalize()
get ZERO():(0,0,0)
toString()
2. NumberUV.as
NumberUV类:UV坐标系中的一个值
(1)属性:u,v:Number
(2)方法:clone()
get ZERO()
toString()
3. Matrix3D.as
Matrix3D类:4×3矩阵
import flash.geom.Matrix;
(1)属性:n11,n12,n13,n14,
n21,n22,n23,n24,
n31,n32,n33,n34
(2)方法:IDENTITY()
toString()
calculateMultiply( a:Matrix3D, b:Matrix3D ) :void:矩阵a和矩阵b相乘
multiply( a:Matrix3D, b:Matrix3D ):Matrix3D:矩阵a和矩阵b相乘,返回值为结果
calculateMultiply3x3 ( a:Matrix3D, b:Matrix3D ):void:3×3矩阵相乘
public static function multiply3x3( a:Matrix3D, b:Matrix3D ):Matrix3D:3×3矩阵相乘,返回值为结果
calculateAdd( a:Matrix3D, b:Matrix3D ):void
public static function add( a:Matrix3D, b:Matrix3D ):Matrix3D
public function calculateInverse( m:Matrix3D ):void
public static function inverse( m:Matrix3D ):Matrix3D:逆
get det():行列式(3×3)
get trace()
copy( m:Matrix3D ):Matrix3D
copy3x3( m:Matrix3D ):Matrix3D
clone( m:Matrix3D ):Matrix3D
multiplyVector( m:Matrix3D, v:Number3D ):void
multiplyVector3x3( m:Matrix3D, v:Number3D ):void
rotateAxis( m:Matrix3D, v:Number3D ):void
rotationX( rad:Number ):Matrix3D
rotationY( rad:Number ):Matrix3D
rotationZ( rad:Number ):Matrix3D
rotationMatrix( x:Number, y:Number, z:Number, rad:Number ):Matrix3D
rotationMatrixWithReference( axis:Number3D, rad:Number, ref:Number3D ):Matrix3D:ref-参考点
translationMatrix( x:Number, y:Number, z:Number ):Matrix3D
scaleMatrix( x:Number, y:Number, z:Number ):Matrix3D
static private var toDEGREES :Number = 180/Math.PI;
static private var toRADIANS :Number = Math.PI/180;
4.proto. DisplayObjectContainer3D
DisplayObjectContainer3D类:继承自EventDispatcher,可作为DisplayObject3D容器的所有对象的基类。每个DisplayObjectContainer3D对象有自己的child list。
(1)属性:
protected var _children :Dictionary; //以children作为索引的名字列表
protected var _childrenByName :Object; //以名字作为索引的children列表
private var _childrenTotal :int; // children数目
5.objects.DisplayObject3D(不属于core,属于objects!!!)
DisplayObject3D类:继承自DisplayObjectContainer3D,表示场景中的3D对象(也包括摄像机和其目标)
提供x,y,z,rotationX,rotationY,rotationZ,scaleX,scaleY.scaleZ,visible,transform Matrix3D
(1)属性:visible:Boolean:是否可见
name:String:对象名(可选)
id:int:对象标识
extra :Object:包含用户定义属性的对象
container :Sprite:绘制到的sprite
material :MaterialObject3D:材质
materials :MaterialsList:材质列表
scene :SceneObject3D:对象所属的场景
parent :DisplayObjectContainer3D:包含该对象的容器(只读)
MESH_SORT_CENTER:String = "meshSortCenter":告诉Mesh3D的render()方法如何排序
MESH_SORT_FAR:String = "meshSortFar":
MESH_SORT_CLOSE:String = "meshSortClose"
相对方向:
static private var FORWARD :Number3D = new Number3D( 0, 0, 1 );
static private var BACKWARD :Number3D = new Number3D( 0, 0, -1 );
static private var LEFT :Number3D = new Number3D( -1, 0, 0 );
static private var RIGHT :Number3D = new Number3D( 1, 0, 0 );
static private var UP :Number3D = new Number3D( 0, 1, 0 );
static private var DOWN :Number3D = new Number3D( 0, -1, 0 );
由此可见,PV3D的坐标系是左手系(和D3D一样)
transform :Matrix3D:变换矩阵(scaling,translation,rotation)
var view :Matrix3D:摄像机变换矩阵
projected :Dictionary:
faces :Array = new Array():面
geometry :GeometryObject3D:包含该对象的3D几何定义(instances:不同的对象共享相同的几何形体,也就是相同的对象显示多次,instance技术可以节省内存)
screenZ :Number:变换后的物体中心的深度值(Z坐标),也就是到camera的距离。
(2)方法:
addGeometry( geometry:GeometryObject3D=null ):void:增加几何定义
distanceTo( obj:DisplayObject3D ):Number:与obj的距离
hitTestPoint( x:Number, y:Number, z:Number ):Boolean:是否与指定点相交(与物体的边界球的半径相比较)
hitTestObject( obj:DisplayObject3D, multiplier:Number=1 ):Boolean:与obj是否相交(边界球),multiplier-边界球组(貌似还没实现)
getMaterialByName( name:String ):MaterialObject3D:获得材质
materialsList():String:材质列表中的材质名
project( parent :DisplayObject3D, camera :CameraObject3D, sorted :Array=null ):Number:投影
render( scene :SceneObject3D ):void:渲染
moveForward(distance:Number)
moveBackward()
moveLeft()
moveRight()
moveUp()
moveDown()
translate( distance:Number, axis:Number3D ):void:沿给定方向移动物体
pitch( angle:Number ):void:(绕X轴旋转)
yaw( angle:Number ):void:偏航角(绕Y轴旋转)
roll( angle:Number ):void:绕Z轴旋转
lookAt( targetObject:DisplayObject3D, upAxis:Number3D=null ):void:让物体看着某一指定位置(upAxis:向上方向,一般是Y轴正向)
copyPosition( reference:* ):void:拷贝位置(reference可以为DisplayObject3D或Matrix3D)
copyTransform( reference:* ):void:拷贝变换矩阵
updateTransform():void:更新变换矩阵
内部使用的属性:
protected var _transformDirty :Boolean = false; //Dirty技术。变换时就设为true
private var _rotationX :Number;
private var _rotationY :Number;
private var _rotationZ :Number;
private var _rotationDirty :Boolean = false; //Dirty技术。旋转时就设为true
private var _scaleX :Number;
private var _scaleY :Number;
private var _scaleZ :Number;
private var _scaleDirty :Boolean = false; //Dirty技术。缩放时就设为true
protected var _sorted :Array;
static private var _totalDisplayObjects :int = 0; // id
6.proto.CameraObject3D
CameraObject3D类:继承自DisplayObject3D,所有摄像机的基类
(1)属性:
zoom :Number:要渲染的物体的缩放,值越大,则场景就放大,距离就缩小,将它与focus一起使用
focus :Number:正数,表示观察者到近平面的距离,这是任何物体与camera的最近距离,将它与zoom一起使用(高focus值可以放大物体之间的距离,这样就可以允许更大的深度域,模拟广角镜的效果,或鱼眼)
sort :Boolean:渲染时物体是否排序
var DEFAULT_POS :Number3D = new Number3D( 0, 0, -1000 ):新摄像机的默认位置
(2)方法:
transformView( transform:Matrix3D=null ):void:world space--->camera space
_flipY :Matrix3D = Matrix3D.scaleMatrix( 1, -1, 1 ); //y值倒转
tilt( angle:Number ):void:摄像机绕x轴转动
pan( angle:Number ):void:摄像机绕y轴转动
7.proto. SceneObject3D(场景管理)
SceneObject3D类:继承自DisplayObjectContainer3D,是所有场景的基类
场景是放置物体的地方,它包含3D环境
场景管理所有渲染的物体,它扩展了DisplayObjectContainer3D类来分配显示物体
SceneObject3D是抽象基类,因此不能实例化
(1)属性:
container :Sprite:你绘制到的地方
geometries :Dictionary:场景中的几何体列表
stats :Object:总体和当前统计信息(points,polys,triangles,performance,rendered)
objects :Array:场景中的物体列表
materials :MaterialsList:场景中的材质列表
(2)方法:
addChild( child:DisplayObject3D, name:String=null ):DisplayObject3D
removeChild( child:DisplayObject3D ):DisplayObject3D
renderCamera( camera :CameraObject3D ):void:渲染,流程如下:
<1> Render performance stats;
<2> Materials: MovieMaterial.updateAnimatedBitmaps();
<3> 3D projection:
1> Transform camera: camera.transformView();
2> Project objects:
<4> Z sort: this.objects.sortOn( 'screenZ', Array.NUMERIC );
<5> Render objects: renderObjects( camera.sort );
8.proto. GeometryObject3D
GeometryObject3D类:继承自EventDispatcher,包含一对象的MESH定义
(1)属性:
material: MaterialObject3D:材质
materials:材质列表
boundingSphere2:边界球半径的平方
faces :Array:MESH的面
vertices :Array:顶点
transformVertices(transformation:Matrix3D):貌似未实现
(2)方法:
transformUV( material:MaterialObject3D ):void:
getBoundingSphere2():Number
9.proto. MaterialObject3D
MaterialObject3D类:继承自EventDispatcher,所有材质的基类。是抽象基类,故不能实例化
(1)属性:
bitmap :BitmapData:透明或不透明的BitmapData纹理
smooth :Boolean:绘制BitmapData纹理时是否要平滑
lineColor :Number:面的outline的RGB颜色
lineAlpha :Number:面的outline的8位的alpha值(若为0,则不绘制outline)
fillColor :Number:面的填充颜色(只有无纹理时才有效)
fillAlpha :Number:alpha值(8位)
get doubleSided():是否双面shade
oneSide :Boolean:是否单面shade
invisible :Boolean:是否不可见(不画)
opposite :Boolean:是否相反(只用于双面shade)
scene :SceneObject3D:所属的scene
static public var DEFAULT_COLOR :int = 0x000000;:材质的默认颜色(黑色)
static public var DEBUG_COLOR :int = 0xFF00FF;:DEBUG材质的颜色
name :String:材质名
id :Number:材质ID
maxU :Number
maxV :Number
geom目录
10. Vertex2D类:2D projected vertices
(1)属性:
x,y,z
extra:Object
visible :Boolean:设置该顶点在经过投影后是否可见。若为false,则表示该顶点在摄像机平面的后面
11. Vertex3D类:3D顶点
同10
12. Vertices3D类:继承自DisplayObject3D类,顶点组
方法:
project( parent :DisplayObject3D, camera :CameraObject3D, sorted :Array=null ):Number:将3d坐标投影到2d平面
boundingBox():Object:计算包围盒,返回{minX, maxX, minY, maxY, minZ, maxZ}
transformVertices( transformation:Matrix3D ):void:变换顶点
13. Mesh3D类:继承自Vertices3D类,创建和显示由顶点和三角形组成的3D物体
方法:
project( parent :DisplayObject3D, camera :CameraObject3D, sorted :Array=null ):Number
projectTexture( u:String="x", v:String="y" ):void:从指定平面的平面投影(u-纹理水平轴,v-纹理垂直轴)
14. Face3D类:渲染线性采样的纹理贴图的三角形,也支持颜色填充和轮廓线(绘制代码就在这里!!!)
(1)属性:
vertices :Array:一个三角形的3个顶点
materialName :String:材质名
uv :Array:每个三角形顶点的UV坐标
screenZ :Number:转换后的三角形的平均深度
visible :Boolean:面是否可见
id :Number:面ID
存储三角形顶点的引用:
private var v0:Vertex3D;
private var v1:Vertex3D;
private var v2:Vertex3D;
(2)方法:
transformUV( instance:DisplayObject3D=null ):Matrix:应用更新后的UV纹理映射值到三角形上,这用来加速渲染
render( instance:DisplayObject3D, container:Sprite ): Number:渲染三角形
渲染流程:
<1>.内部
有纹理:
graphics.beginBitmapFill( texture, _localMatrix, true, material.smooth);
无纹理:
graphics.beginFill( material.fillColor, fillAlpha );
<2>.轮廓线
lineAlpha>0:
graphics.lineStyle( 0, material.lineColor, lineAlpha );
lineAlpha=0:
graphics.lineStyle();
<3>.画三角形
// Draw triangle
graphics.moveTo( x0, y0 );
graphics.lineTo( x1, y1 );
graphics.lineTo( x2, y2 );
<4>.显示出来
graphics.lineTo( x0, y0 ); //画轮廓线
graphics.endFill(); //显示三角形
三、cameras
1. Camera3D类:继承自CameraObject3D类,creates a camera that views the area around a target object
(1)属性
target :DisplayObject3D:目标
goto :Number3D:指定camera要去的位置
(2)方法
transformView( transform:Matrix3D=null ):world space--->camera space
hover( type:Number, mouseX:Number, mouseY:Number ):void:用户移动鼠标时移动camera
2. FreeCamera3D类::继承自CameraObject3D类。creates a camera that views the area in the direction the camera is aimed
(1)方法
transformView( transform:Matrix3D=null ):void
四、scenes
1. Scene3D类:继承自SceneObject3D类。create a scene where all objects are rendered in the same container
(1)方法:
renderObjects( sort:Boolean ):void
2. FlexScene3D类:继承自Scene3D类。
private var containerList : Array;
private var spriteList : Dictionary;
3. MovieScene3D类:继承自Scene3D类。create a scene where each object is rendered in its own container(注意与Scene3D类的不同)
(1)方法:
addChild( child :DisplayObject3D, name :String=null ):DisplayObject3D
getSprite(child:DisplayObject3D):Sprite
renderObjects( sort:Boolean ):void
五、events
1. FileLoadEvent类:继承自event类。represents events that are dispatched when files are loaded
public class FileLoadEvent extends Event
{
public static var LOAD_COMPLETE :String = "loadComplete"; //加载完毕
public static var LOAD_ERROR :String = "loadError"; //加载错误
public static var COLLADA_MATERIALS_DONE:String = "colladaMaterialsDone";
//collada材质加载完毕
public var file:String;
public function FileLoadEvent( type:String, p_file:String="", bubbles:Boolean=false, cancelable:Boolean=false )
{
super( type, bubbles, cancelable );
file = p_file;
}
}
六、materials
1. BitmapMaterial类:继承自MaterialObject3D类。creates a texture from a BitmapData object
(1)属性
AUTO_MIP_MAPPING :Boolean = true;:是否mipmap
MIP_MAP_DEPTH :Number = 8:mipmap等级
get texture():* //texture object
set texture( asset:* ):void
(2)方法
createBitmap( asset:* ):BitmapData:创建位图
correctBitmap( bitmap :BitmapData, dispose :Boolean ):BitmapData:CORRECT BITMAP FOR MIP MAPPING
extendBitmapEdges( bmp:BitmapData, originalWidth:Number, originalHeight:Number ):
2. ColorMaterial类:继承自MaterialObject3D类。creates a solid color material
public function ColorMaterial( color:Number=0xFF00FF, alpha:Number = 100, initObject:Object=null )
{
super( initObject );
this.fillColor = color; //填充颜色
this.fillAlpha = alpha; //
}
3. WireframeMaterial类:继承自MaterialObject3D类。creates a wireframe material, where only the outlines of the faces are drawn.
public function WireframeMaterial( color:Number=0xFF00FF, alpha:Number=100, initObject:Object=null )
{
super( initObject );
this.lineColor = color; //线颜色
this.lineAlpha = alpha; //
this.doubleSided = true;
}
4. BitmapAssetMaterial类:继承自BitmapMaterial类。creates a texture from a Bitmap library symbol
createBitmap( asset:* ):BitmapData
5. BitmapFileMaterial类:继承自BitmapMaterial类。creates a texture by loading a bitmap from an external file.
(1)属性
var url :String = "":The URL that has been requested.
loaded :Boolean:纹理是否已被加载
callback :Function:上张图片被加载完的回调
LOADING_COLOR :int = MaterialObject3D.DEFAULT_COLOR;:加载完成前材质的颜色
(2)方法
public function BitmapFileMaterial( url :String, initObject :Object=null )
{
super( url, initObject );
this.url = url;
this.loaded = false;
// Loading color
this.fillAlpha = 1;
this.fillColor = LOADING_COLOR;
}
BitmapFileMaterial类就是将外部图片文件加载进flash Bitmap library。
6. MaterialsList类:材质列表
(1)属性
materialsByName :Dictionary:以name索引的材质列表
get numMaterials():int:孩子的数目
【内部使用】
_materials :Dictionary
_materialsTotal :int
(2)方法:
addMaterial( material:MaterialObject3D, name:String=null ):MaterialObject3D
removeMaterial( material:MaterialObject3D ):MaterialObject3D
getMaterialByName( name:String ):MaterialObject3D
removeMaterialByName( name:String ):MaterialObject3D
clone():MaterialsList
7. MovieMaterial类:继承自BitmapMaterial类。creates a texture from an existing MovieClip instance
该纹理可以是动画的和/或者透明的。MovieClip实例的当前的缩放和颜色值将会被使用,但旋转则会被舍弃。
MovieClip的内容需要放在注册点(the registration point)的左上角
(1)属性
movie :MovieClip:用作纹理的MovieClip
movieTransparent :Boolean:MovieClip是否透明,默认为false(这样很快)
get animated():Boolean:纹理是否是动画
set animated( status:Boolean ):void
(2)方法
updateBitmap():void:更新动画的MovieClip的bitmap
createBitmap( asset:* ):BitmapData
updateAnimatedBitmaps():void:更新所有的动画MovieMaterial实例的bitmap
8. VideoStreamMaterial类:继承自MovieMaterial类。creates
a texture from an existing Video instance and is for use with a Video
and NetStream objects with an RTMP stream. The texture can be animated
and/or transparent.
(1)属性
stream:NetStream:用作纹理的NetStream
video:Video:用做纹理的Video
(2)方法
initMaterial ( video:Video, stream:NetStream ):void
createBitmap( asset:* ):BitmapData
updateBitmap ():void
onStreamStatus ( event:NetStatusEvent ):void:当NetStream对象状态改变时执行
9. MovieAssetMaterial类:继承自MovieMaterial类。creates a texture from a MovieClip library symbol
七、objects
1.Plane类:继承自Mesh3D类。create and display flat rectangle objects
长方形可以划分为更小的segment。这通常用来减少线性采样贴图的失真
在透视的方向上切分平面可以改善这个问题
(1)属性
segmentsW :Number:水平方向的segment数
segmentsH :Number:垂直方向的segment数
DEFAULT_SIZE :Number = 500:默认大小(若无纹理)
DEFAULT_SCALE :Number = 1:默认缩放(若无纹理)
DEFAULT_SEGMENTS :Number = 1:gridX的默认值
(2)方法
Plane( material:MaterialObject3D=null, width:Number=0,
height:Number=0, segmentsW:Number=0, segmentsH:Number=0,
initObject:Object=null ):
特别说明一下参数width:
[optional] - Desired width or scaling factor if there's bitmap texture in material and no height is supplied.
参数width一般是宽度。但如果有纹理并且没指定height参数,则参数width是缩放因子
buildPlane( width:Number, height:Number ):void:构建平面(1个格子2个三角形)
2. PaperPlane类:继承自Mesh3D类。Paper planes are useful for testing, when you want to know the direction an object is facing.