Papervision3D学习基础教程

要使用PV3D,其中有四个元素少不了,Scene3D, Viewport3D, Camera3D , BasicRenderEngine,以下是官方文档的介绍和本人拙劣的翻译。
 
  Scene3D:
Package org.papervision3d.scenes
Class public class Scene3D
Inheritance Scene3D SceneObject3D DisplayObjectContainer3D flash.events.EventDispatcher
  The Scene3D class lets you create a scene where all objects are rendered in the same container.
A scene is the place where objects are placed, it contains the 3D environment.
  一个Scene3D实例是这个3D场景中所有物体的容器,它包括了整个3D场景,Scene3D这个类让所有创建在其中的3D物体得到渲染。  
  简单的说,Scene3D就是包含所有3D场景中物体的容器,物体要显示,该物体或它的父类首先要加入到Scene3D的实例中。注意,虽然要显示的物体都要加入到Scene3D的实例中,但它并不是一个显示对象,也就是说它并不直接显示物体.而真正显示物体的是Viewport3D,接着看下一个:
 
 
  Viewport3D:
Package org.papervision3d.view
Class public class Viewport3D
Inheritance Viewport3D flash.display.Sprite
Implements IViewport3D
Subclasses BitmapViewport3D
 
  Viewport3D,viewport是视口的意思,我们可以理解为显示物体的一个窗口或矩形显示区域,它继承自Sprite,所以说它可以直接被加入到显示列表中,我们PV3D中所看到的物体就是通过Viewport3D呈现的。同时它还实现了IViewport3D接口。
 
构造函数
Viewport3D (viewportWidth:Number = 640, viewportHeight:Number = 480, autoScaleToStage:Boolean = false, interactive:Boolean = false, autoClipping:Boolean = true, autoCulling:Boolean = true)
 
viewportWidth:Number (default = 640) — Width of the viewport
视口宽度
 
viewportHeight:Number (default = 480) — Height of the viewport
视口高度
 
autoScaleToStage:Boolean (default = false) — Determines whether the viewport should resize when the stage resizes
是否随舞台大小改变而调整视口大小
 
interactive:Boolean (default = false) — Determines whether the viewport should listen for Mouse events by creating an InteractiveSceneManager
是否接受交互,需要接受交互事件时需将其设为true
 
autoClipping:Boolean (default = true) — Determines whether DisplayObject3Ds outside the rectangle of the viewport should be rendered
是否不渲染视口外的物体,true不渲染,false渲染,没特殊要求默认设为true,提高效率
 
autoCulling:Boolean (default = true) — Detemines whether only the objects in front of the camera should be rendered. In other words, if a triangle is hidden by another triangle from the camera, it will not be rendered.
被遮挡的物体是否不渲染,true不渲染,false渲染,没特殊要求默认设为true,提高效率
 
 
再然后是Camera3D:
  Camera3D:
Package org.papervision3d.cameras
Class public class Camera3D
Inheritance Camera3D CameraObject3D DisplayObject3D DisplayObjectContainer3D flash.events.EventDispatcher
Subclasses DebugCamera3D, SpringCamera3D
 
  Camera3D is the basic camera used by Papervision3D
  Camera3D是PV3D中基本的摄像机。
  
  我们可以把它理解为一个3D空间中的摄像机的镜头,我们在Viewport3D中所看到的东西就是这个镜头中所拍到的,当然我们就可以通过改变这个镜头的位置,角度,焦距等属性,来显示不同的场景或做镜头移动的动画。
 
构造函数
Camera3D(fov:Number = 60, near:Number = 10, far:Number = 5000, useCulling:Boolean = false, useProjection:Boolean = false)
 
fov:Number (default = 60) — This value is the vertical Field Of View (FOV) in degrees.
镜头视角的垂直角度
 
  
  最后来看BasicRenderEngine:
  BasicRenderEngine:
Package org.papervision3d.render
Class public class BasicRenderEngineInheritance BasicRenderEngine AbstractRenderEngine flash.events.EventDispatcherImplements IRenderEngineSubclasses LazyRenderEngine, QuadrantRenderEngine    BasicRenderEngine links Viewport3Ds, Scene3D, and Camera3Ds together by gathering in all of their data, rendering the data, then calling the necessary functions to update from the rendered data  BasicRenderEngine翻译为基础渲染引擎,它有将Viewport3Ds, Scene3D 和 Camera3Ds整合在一起协同工作的功能,形象的说,就是它通过镜头的位置角度等属性,读取Scene3D中需要渲染的物体的信息,通过计算(即渲染)后得到得数据提交给Viewport3D呈现出来。   这里我们先学习它的一个最常用的方法renderScene(scene:SceneObject3D, camera:CameraObject3D, viewPort:Viewport3D):RenderStatistics  scene:SceneObject3D — The CameraObject3D looking at the scene需要渲染的场景 camera:CameraObject3D — The Scene3D holding the DisplayObject3D’s you want rendered镜头 viewPort:Viewport3D — The Viewport3D that will display your scene呈现渲染结果的视口(显示区域) RenderStatistics — RenderStatistics The RenderStatistics objectholds all the data from the last render渲染返回结果  注意下Viewport3D和BasicRenderEngine的destroy()方法,内存没被回收的根源也许就在这里        介绍完了这些,我们先来看一段代码  首先我们在setupPV3D()中初始化了四个基本元素,接着在setupShere()中向scene添加了一个球体,最后用addEventListener(Event.ENTER_FRAME, onRenderLoop)添加一个逐帧的监听,在侦听器中每帧将球体的rotationY增加2以达到旋转的效果并且每帧进行渲染_renderer.renderScene(_scene, _camera, _viewport)。---------------------------------------------------------------------------------------------------package cn.antscript.HelloWorld{ import flash.display.Sprite; import flash.events.Event; import org.papervision3d.cameras.Camera3D; import org.papervision3d.materials.WireframeMaterial; import org.papervision3d.objects.primitives.Sphere; import org.papervision3d.render.BasicRenderEngine; import org.papervision3d.scenes.Scene3D; import org.papervision3d.view.Viewport3D; [SWF(width = "640", height = "480", backgroundColor = "#000000", frameRate = "30")] public class Main extends Sprite { private var _scene:Scene3D; private var _viewport:Viewport3D; private var _camera:Camera3D; private var _renderer:BasicRenderEngine; private var _sphere:Sphere; public function Main():void { init(); } private function init(e:Event = null):void { setupPV3D(); setupShere(); addEventListener(Event.ENTER_FRAME, onRenderLoop); } //setup PV3D method private function setupPV3D():void { _scene = new Scene3D(); _viewport = new Viewport3D(); addChild(_viewport); _camera = new Camera3D(); _renderer = new BasicRenderEngine(); } //setup shere private function setupShere():void { _sphere = new Sphere(new WireframeMaterial()); _scene.addChild(_sphere); } //renderer every frame private function onRenderLoop(e:Event):void { _sphere.rotationY += 2; _renderer.renderScene(_scene, _camera, _viewport); } } }//end

这篇我们来看一下BasicView这个类,它可以让我们非常方便的创造出一个包含前面所说的那四个基本元素的3D世界。你只需要实例化它并加入到显示列表中即可,但我们更常用的是通过继承它来直接使用这个3D世界,现在先看一下它的文档。
 
BasicView
Package org.papervision3d.view
Class public class BasicView
Inheritance BasicView AbstractView flash.display.Sprite
Implements IView
Subclasses ReflectionView
  
  BasicView provides a simple template for quickly setting up basic Papervision3D projects by creating a viewport, scene, camera, and renderer for you. Because BasicView is a subclass of Sprite, it can be added to any DisplayObject.
  BasicView为我们提供了一个包含viewport, scene, camera, 和renderer,可以 快速创建PV3D项目的模版,而且它是Sprite的子类,可以直接添加到任何DO里面。
 

构造方法
BasicView(viewportWidth:Number = 640, viewportHeight:Number = 480, scaleToStage:Boolean = true, interactive:Boolean = false, cameraType:String = “Target”)
参数应该能理解吧,不理解的看看前面那篇笔记。
然后看几个它继承自AbstractView的比较有用的属性和方法
camera : CameraObject3D
renderer : BasicRenderEngine
scene : Scene3D
viewport : Viewport3D
viewportHeight : Number
viewportWidth : Number
这些属性不清楚的看下前面的笔记
 
方法:
singleRender():void
渲染一次
startRendering():void
开始每帧渲染
stopRendering(reRender:Boolean = false, cacheAsBitmap:Boolean = false):void
结束每帧渲染
 
了解了这些属性和方法,我们来看一段代码,这段代码实现了和前面教程完全一样的效果。


------------------------------------------------------------------------------------------------------------------------------------------

package { import flash.events.Event; import org.papervision3d.materials.WireframeMaterial; import org.papervision3d.objects.primitives.Sphere; import org.papervision3d.view.BasicView; [SWF(width="640",height="480",backgroundColor="#000000",frameRate="30")] public class BasicViewExample extends BasicView { private var _sphere:Sphere; public function BasicViewExample() { super(); init(); } private function init():void { setupSphere(); startRendering(); } private function setupSphere():void { _sphere=new Sphere(new WireframeMaterial ); scene.addChild(_sphere); } override protected function onRenderTick(event:Event=null):void { _sphere.rotationY+=2; renderer.renderScene(scene,camera,viewport); } } }--------------------------------------------------------------------------------------------------



记得上中学的时候学立体几何,老师提到过左手坐标系右手坐标系什么的,不过现在已经基本忘记了,从头再来吧。
 
  首先运行一段代码看看,这段代码的作用是创建颜色分别为红绿蓝的三条线,起点都为坐标原点,终点分别指向XYZ轴的正方向,我们需要用到Line3D,Lines3D,LineMeterial以及Vertex3D这四个类,这四个类会在后面详细介绍,这里只要知道作用是什么就可以了。
  
  Lines3D可以看作是Line3D的一个容器,Line3D本身不能作为3D显示对象被直接加入到Scene3D中,只能通过Lines3D的addLine(line:Line3D)方法先加入到Lines3D以后,再把Lines3D加入到Scene3D里呈现,Lines3D还有一个方法就是addNewLine(size:Number, x0:Number, y0:Number, z0:Number, x1:Number, y1:Number, z1:Number)这个方法允许Lines3D直接绘制出线段,如果初始化时候没有给Lines3D材质的话默认是红色的线,而且一个Lines3D用addNewLine方法绘制的线条只能有一种颜色,所以我们这里需要重新加入3条不同颜色的Line3D。
-----------------------------------------------------------------------------------------------------------------------------------------

package {
import flash.events.Event;
import org.papervision3d.core.geom.Lines3D;
import org.papervision3d.core.geom.renderables.Line3D;
import org.papervision3d.core.geom.renderables.Vertex3D;
import org.papervision3d.materials.special.LineMaterial;
import org.papervision3d.view.BasicView;



[SWF(width="640",height="480",backgroundColor="#000000",frameRate="30")]

public class CoordinateSystem extends BasicView {

private var _lines:Lines3D;
private var _xAxis:Line3D;
private var _yAxis:Line3D;
private var _zAxis:Line3D;

public function CoordinateSystem() {
init();
}

private function init():void {

setupCoordinateSystem();

addEventListener(Event.ENTER_FRAME,onEnterFrame);
}

private function setupCoordinateSystem():void {
_lines=new Lines3D ;
scene.addChild(_lines);

var origin:Vertex3D=new Vertex3D ;

_xAxis=new Line3D(_lines,new LineMaterial(0xff0000),1,origin,new Vertex3D(200,0,0));
_lines.addLine(_xAxis);

_yAxis=new Line3D(_lines,new LineMaterial(0x00ff00),1,origin,new Vertex3D(0,200,0));
_lines.addLine(_yAxis);

_zAxis=new Line3D(_lines,new LineMaterial(0x0000ff),1,origin,new Vertex3D(0,0,200));
_lines.addLine(_zAxis);

}

private function onEnterFrame(event:Event=null):void {
_lines.rotationY+=1;
_lines.rotationX+=1;
singleRender();

if (Math.round(_lines.rotationX%360)==0&&Math.round(_lines.rotationY%360)==0) {
removeEventListener(Event.ENTER_FRAME,onEnterFrame);
trace("stoped!");
}
}

}

}

-------------------------------------------------------------------------------------------------------------------------------------------


DisplayObject3D相当于FLASH中的DisplayObject,任何在屏幕上被渲染出来的3D物体都是它的子类,它的子类有以下这些:CameraObject3D, Collada, DAE, LightObject3D, Max3DS, Mouse3D, SimpleLevelOfDetail, Sketchup, SketchupCollada, Sound3D, Vertices3D,它们根据各自的实现或功能的不同分成了不同的类或者派生出不同的子类,这些以后再细看。
 
  现在我们只要知道DisplayObject3D的一些常用属性和方法,不清楚的查下文档自己试验一下。
  
scaleX
scaleY
scaleZ
scale 有这个就方便多了^_^
 
rotationX
rotationY
rotationZ
 
pitch()  对应rotationX
yaw()  对应rotationY
roll()  对应rotationZ
 
moveForward()  z正方向移动
moveBackward()  z反方向移动
  
moveRight()  x正方向移动
moveLeft()  x反方向移动
  
moveUp()  y正方向移动
moveDown()  y反方向移动
 
上面这些都是做运动时比较常用的,牢牢记住吧。
 
我们注意一下有个root的属性,有时可能会用到,如果在scene里的话root就是scene,否则为null。
 
另外看几个暂时不用但以后会很有用的:
transform : Matrix3D
被用于该显示对象的3D变换矩阵
   
translate(distance:Number, axis:Number3D):void
沿给定的矢量方向(axis:Number3D)移动给定的距离(distance:Number);
这里的Number3D所表示的只是一个方向,它的模的大小和移动的距离无关
  
transformVertices (transformation:Matrix3D) : void
试验的时候发现这个文档里面没有的方法,测试了一下,和transform的作用差不多,只是这个是累加的。


还是看下文档先:
Line3D:Package org.papervision3d.core.geom.renderables
Class public class Line3D
Inheritance Line3D AbstractRenderable
Implements IRenderable
  
Line3D is used by Lines3D to store and render the lines.
Line3D被用来在Lines3D中创建出可以被渲染的线条
 
构造函数
Line3D(instance:Lines3D, material:LineMaterial, size:Number, vertex0:Vertex3D, vertex1:Vertex3D)
instance:Lines3D — The containing Lines3D object
要加入到的Lines3D实例
material:LineMaterial — The material for the line
材质
size:Number — The line weight
粗细
vertex0:Vertex3D — The start vertex
起点
vertex1:Vertex3D — The end vertex
终点
  
再看下它常用的属性和方法:

cV : Vertex3D 控制点
material : LineMaterial 材质
size : Number 粗细
v0 : Vertex3D 起点
v1 : Vertex3D 终点
  
addControlVertex(cx:Number, cy:Number, cz:Number):void
给线条添加一个控制点,感觉好像就是贝塞尔曲线里面那种控制点
  
Lines3D:Package org.papervision3d.core.geom
Class public class Lines3D
Inheritance Lines3D Vertices3D DisplayObject3D DisplayObjectContainer3D flash.events.EventDispatcher
Subclasses UCS

  Lines3D是继承了DisplayObject3D,所以可以直接添加到scene或者其他3D显示对象容器中渲染显示。我们可以把Line3D的实例添加到Lines3D中(使用addLine()方法),也可以直接在Lines3D中画线(使用addNewLine()方法),前一种方法可以添加许多颜色不同的线,而后一种方法只可以画预先定义好材质的线
 
构造函数
Lines3D(material:LineMaterial = null, name:String = null)
material:LineMaterial (default = null)
使用addNewLine()方法添加进来的线条材质
name:String (default = null)
名字
 
属性
lines:Array Lines3D中所有线条的数组
 
方法
addLine(line:Line3D):void
添加一条线
addNewLine(size:Number, x0:Number, y0:Number, z0:Number, x1:Number, y1:Number, z1:Number):Line3D
添加一条线,使用Lines3D中定义的材质,默认为纯红色0xff0000
removeAllLines():void
删除里面的所有线条
removeLine(line:Line3D):void
删除线条
  
下面我们来看一段代码.
  首先我们用addLine()方法画圆,画完以后使用removeAllLines()方法删除刚才画的圆,然后又画了一条线,添加了一个控制点,同时开始用addNewLine()开始重新画圆。
运行代码看效果,然后自己动手做一些练习吧!

----------------------------------------------------------------------------------------------------------------------------------------

package
{
import flash.events.Event;
import org.papervision3d.core.geom.Lines3D;
import org.papervision3d.core.geom.renderables.Line3D;
import org.papervision3d.core.geom.renderables.Vertex3D;
import org.papervision3d.materials.special.LineMaterial;
import org.papervision3d.view.BasicView;


public class DrawCircle extends BasicView
{
private static var _segment:int=500;
private static var _radius:Number=400;
private static var _offset:int=0;
private static var _beginVertex:Vertex3D;
private static var _endVertex:Vertex3D;
private static var _lineMaterial:LineMaterial;

private var _lines:Lines3D;


public function DrawCircle()
{
init();
}

private function init():void
{
createLines();
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}

private function createLines():void
{
_lines = new Lines3D();
_lines.addNewLine(10, 0, _radius, 0, 0, -_radius, 0);
scene.addChild(_lines);

_lineMaterial = new LineMaterial(Math.random() * 0xffffff);
_beginVertex = new Vertex3D(Math.sin(2*Math.PI*_offset/_segment)*_radius, Math.cos(2*Math.PI*_offset/_segment)*_radius, 0);
}

private function drawCircle():void {
_offset += 1;
_endVertex=new Vertex3D(Math.sin(2*Math.PI*_offset/_segment)*_radius, Math.cos(2*Math.PI*_offset/_segment)*_radius, 0);
_lines.addLine(new Line3D(_lines, _lineMaterial, 10, _beginVertex, _endVertex));
_beginVertex = _endVertex;
}


private function onEnterFrame(e:Event):void
{


if (_offset < _segment) {
drawCircle();
}else {
_lines.pitch(1);
}

singleRender();
}


}

}

---------------------------------------------------------------------------------------------------------------------------------------


PV3D中材质的种类非常多,都是MaterialObject3D的子类,每个显示对象都需要材质才能显示。我们先来大致看一下所有的材质类:
MaterialObject3D
————LineMaterial
————ParticleMaterial
————————BitmapParticleMaterial
————————MovieAssetParticleMaterial
————TriangleMaterial
————————AbstractLightShadeMaterial
————————————AbstractSmoothShadeMaterial
————————————————EnvMapMaterial
————————————————————CellMaterial
————————————————————PhongMaterial
————————————————GouraudMaterial
————————————FlatShadeMaterial
————————BitmapMaterial
————————————BitmapAssetMaterial
————————————BitmapColorMaterial
————————————BitmapFileMaterial
————————————BitmapViewportMaterial
————————————MovieMaterial
————————————————MovieAssetMaterial
————————————————VideoStreamMaterial
————————BitmapWireframeMaterial
————————ColorMaterial
————————CompositeMaterial
————————ShadedMaterial
————————WireframeMaterial
————VectorShapeMaterial
————————Letter3DMaterial

  上面列出了PV3D中所有的材质,大家可以先看一下,有个印象,以后用到的话方便查文档。下面看一下比较常用的几个。

ColorMaterial
  ColorMaterial是最常用的一个材质,它只有单纯的颜色和透明度,看下构造函数
ColorMaterial (color:Number = 0xFF00FF, alpha:Number = 1, interactive:Boolean = false)
主要说下interactive这个参数,如果你需要你的三维物体接收交互(例如鼠标点击)的话要将它设为true,还有就是经常问到的一个问题,怎么实现鼠标手型,首先要将viewport的interactive设为true,然后将材质的interactive也设为true以后,在显示对象上监听InteractiveScene3DEvent.OBJECT_OVER事件,监听器中将viewport的buttonMode设为true(前面说过viewport是Sprite的子类,所以可以设置buttonMode),鼠标离开事件里再设为false就可以了,关于交互以后会专门学习下给大家分享。
  照例上代码:

---------------------------------------------------------------------------------------------------------------------------------------

package
{
import gs.TweenLite;
import org.papervision3d.events.InteractiveScene3DEvent;
import org.papervision3d.materials.ColorMaterial;
import org.papervision3d.objects.primitives.Plane;
import org.papervision3d.view.BasicView;


public class InteractivePlane extends BasicView
{
private var _plane:Plane
private var _material:ColorMaterial;

public function InteractivePlane()
{
super();
init()
}

private function init():void
{
initPanel();
startRendering();
}

private function initPanel():void
{

_material = new ColorMaterial(0x1D9DAD, 1, true);
_material.interactive = true;
_plane = new Plane(_material,500,500);
_plane.rotationX = 45;

scene.addChild(_plane);
viewport.interactive = true;

_plane.addEventListener(InteractiveScene3DEvent.OBJECT_OVER, onOver);
_plane.addEventListener(InteractiveScene3DEvent.OBJECT_OUT, onOut);
_plane.addEventListener(InteractiveScene3DEvent.OBJECT_CLICK, onClick);

}

private function onClick(e:InteractiveScene3DEvent):void
{
_material.fillColor = Math.random() * 0xffffff;
}

private function onOver(e:InteractiveScene3DEvent):void
{
viewport.buttonMode = true;
TweenLite.to(_plane, 1, { rotationX:0 } );
}

private function onOut(e:InteractiveScene3DEvent):void
{
viewport.buttonMode = false;
TweenLite.to(_plane, 1, { rotationX:45 } );
}


}

}

---------------------------------------------------------------------------------------------------------------------------------------

代码中创建了一个平面,然后给它了一个ColorMaterial的材质,然后监听鼠标的OVER,OUT,CLICK事件,当鼠标移上去的时候平面转动一定角度并出现手型,移开的话转动复原手型消失,当点击的时候给ColorMaterial的fillColor属性重新赋值改变平面颜色。

你可能感兴趣的:(pv3d,flex,Papervision3D)