papervisoin3d essentials 第九章 【续】

     图片显示不出来:

【续】

其他章节有其他的人的人翻译:详情在下面这个网址:

http://lushisang.com/?p=36   

 

 

 

Layering your renders

为了增加3D对象的显示效果,可以增加多个三角形平面(即创建更多的segment),但它不是最好的解决方案。因为当多个三角形平面的顶点(vertex)投影到scene上时,三角形平面越多,投影到scene上的点也越多,因而消耗的cpu也越多 . 更好的解决办法是用viewport(视口) 层,这些viewport(视口)层被嵌套在viewport里(因为viewport可以多方位旋转,因而有多个viewport层)。 这些viewport(视口)层的概念与photoshopflash里层的概念一样,他们的工作原理一样 ,最上层的总是显示在最前面 。在photoshop里,每层只是放一种元素或者一种混合元素。在Pv3d里也是一样,每层只放一种元素。例如:我们可以将椅子放在某一层,然后将桌子放在另一层。每层的排列顺序可以通过pv3d

里算法实现。<该段主要是讲pv3d层的概念:每个层只能放一种元素,该元素既可以是单一的,也可以是混合的>

 

为了演示上述方法,我们将重用在第八章介绍过了的animatedMill模型。下面将展示一些Z-sorting(深度排序)的问题 。下面的代码将作为本章的模板。

 

 

package {

import flash.events.Event;

import org.papervision3d.core.animation.clip.AnimationClip3D;

import org.papervision3d.events.FileLoadEvent;

import org.papervision3d.materials.ColorMaterial;

import org.papervision3d.materials.WireframeMaterial;

import org.papervision3d.materials.special.CompositeMaterial;

import org.papervision3d.objects.parsers.DAE;

import org.papervision3d.objects.primitives.Plane;

import org.papervision3d.view.BasicView;

private class ViewportLayersExample extends BasicView

{

private var mill:DAE;

private var floor:Plane;

private var rotX:Number = 0.1;

private var rotY:Number = 0.1;

private var camPitch:Number = 90;

private var camYaw:Number = 270;

private var easeOut:Number = 0.1;

public function ViewportLayersExample()

{

stage.frameRate = 40;

init();

}

private function init():void

{

mill = new DAE(true,null,true);

mill.addEventListener(FileLoadEvent.LOAD_COMPLETE, modelLoaded);

mill.load("assets/animatedMill.dae");

var colorMat:ColorMaterial = new ColorMaterial(0x006600);

var wireMat:WireframeMaterial = new WireframeMaterial();

var floorMat:CompositeMaterial = new CompositeMaterial();

floorMat.addMaterial(colorMat);

floorMat.addMaterial(wireMat);

floorMat.doubleSided = true;

floor = new Plane(floorMat,1000,1000,1,1);

floor.y = -410;

scene.addChild(floor);

floor.rotationX = 90;

}

private function modelLoaded(e:FileLoadEvent):void

{

scene.addChild(mill);

var animationLeft:AnimationClip3D = new AnimationClip3D ("right",0,6);

var animationRight:AnimationClip3D = new AnimationClip3D ("left",6,12);

mill.animation.addClip(animationRight);

mill.animation.addClip(animationLeft);

mill.play("right");

startRendering();

}

override protected function onRenderTick(e:Event=null):void

{

var xDist:Number = mouseX - stage.stageWidth * 0.5;

var yDist:Number = mouseY - stage.stageHeight * 0.5;

camPitch += ((yDist * rotX) - camPitch + 90) * easeOut;

camYaw += ((xDist * rotY) - camYaw + 270) * easeOut;

camera.orbit(camPitch, camYaw);

super.onRenderTick();

}

}

}

 

 

 

init()方法里,我们加载了外部模型,并把它添加到了scene里。为地板floor对象添加了由WireframeMaterialColorMaterial组成的混合材质(floorMat)。

最后onRenderTick(e:Event=null)方法里的几段代码是创建鼠标的交互性。移动鼠标,Camera将会绕scene原点进行旋转 ,因而我们就能看到多个方位

 

测试代码,将会是下面这样的画面 ,下面的地板floor有一些Z-sorting(深度排序)问题。

 

因为从底部看,模型millfloor的后面,我们看不到mill模型 。为了能让我们在floor后面看到mill模型,下面我们用层的概念分析一下该问题

为了解决该问题,我们在此提出上面讲述了很多的层问题。 用层的方法可以解决mill模型不可见的问题 因为从底部看,模型millfloor的后面,即floor在最上层,而mill模型在floor的下一层,因而我们看不到mill模型。 为了使mill模型在从底部看可见,我们只需改变floormill模型 的顺序的即可 。下面有一些改变层顺序的方法:

 

useOwnContainer属性创建一个viewport

设置3D对象的useOwnContainertrue(3dDisplayObject. useOwnContainer=true),将会创建一个新的层,该层在所有层的上面(即该层在最上面)。并且该3d对象被画在了该层上。因而该3d对象将不会被遮住。

在上面的代码中为了使我们从底部看mill模型可见,只需在modelLoaded()方法里加上下面一句代码:

mill.useOwnContainer = true;

 

 

加上上句代码后再次测试,发现现在的效果更好,图片如下:

 

 

换多个方位看,我们会发现不存在Z-sorting问题了。其图片显示如下:右图是从较低的点的视口看的(即看它的底部)。

 

 

useOwnContainer设为true后,mill模型始终在最上层,因而我们始终能看到mill模型。但这是不符合真实的,

并且该属性很耗cpu。下面我们将介绍另外两种方法来代替useOwnContainer方法。下面的两种方法更符合现实。

 

getChildLayer方法创建viewport层并给viewport层排序

通过viewport3D类的getChildLayer方法得到ViewportLayer的实例。

var millLayer:ViewportLayer = viewport.getChildLayer(mill);

为了使它运行,我们还需要导入ViewportLayer类:

import org.papervision3d.view.layer.ViewportLayer;

getChildLayer()的三个参数:

 参数       数据类型               默认值                        用法描述    

 

do3d    DisplayObject3D        ————             获得的do3d的所在层

                                            或者为do3d创建一个新的

层(创建新的层需要第二个参数)

 

 

createNew     Boolean             true                 是否为do3d创建一个新的

viewport层(该值一般设

                                                 true,这样才能创建

                                            一个新的层,因为新层

                                            在所有层的最上面)

 

 

 

Recurse       Boolean           true                 是否将do3d里的子对象也

                                                  添加到该层

 

 

 

当你得到新的viewport层的实例,你也可以将其他的3D对象添加到同一个层中。例如我们可以将大量mill模型添加到同一层. 作为用法演示: 我们在先前的代码的基础上 ,将floor添加到millLayer 层里 。当然这是没有意义的,这和不用层得到的效果是一样的。因为添加floor以后,floor就又在最上面了。

我们在这里只是介绍用法:

       millLayer.addDisplayObject3D(floor);

 

 

 

实例化ViewportLayer来创建 viewport

下面是用法:

var millLayer:ViewportLayer = new ViewportLayer(viewport,null);

 

viewport.containerSprite.addLayer(millLayer);

 

millLayer.addDisplayObject3D(mill,true);

 

 

ViewportLayer类的构造函数的三个参数 :

 

 

 参数     数据类型        默认值          用法描述

 

 

Viewport    Viewport3D         ————          Viewport3D实例对象

 

do3d    DisplayObject3D      ————        被添加进层的3d对象

                                              getChildLayer()

                                              方法里可以设置Recurse

true,将3d对象的子对象全部添加到层中。但是在

ViewportLayer构造函数中并没有Recurse这个参数,因此

在上面的代码中将do3d属性设为null,然后用addDisplayObject3D() 方法将do3d对象添加到层,

addDisplayObject3D()方法的第二参数为Recurse ,故可以在这里进行设置

 

 

isDynamic Boolean      false     是否要去除层在接

下来的渲染。这个参数时pv3d内部决定的,不能在外部修改,只能在源码处进行修改

addDisplayObject3D()的一个参数为do3d 第二个为Recurse

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值