DevSecOps

8 abr, 2010

Utilizando Papervision 3D nos seus projetos: objetos primitivos

Publicidade

Leia o artigo anterior

Utilizando Papervision 3D nos seus projetos

*

Olá, pessoal. Espero
que estejam gostando da série de artigos sobre Papervision.
Continuando, veremos agora os objetos primitivos 3D.

A atual versão do
Papervision 2 nos oferece seis objetos primitivos nativos, ou seja,
seis formas básicas em 3D que são a base para tudo o que seja
inserido em seu ambiente 3D.

Por exemplo: para
colocarmos uma simples imagem PNG em nosso ambiente 3D, precisaremos
de um plano (Plane) como forma de base, para logo em seguida
aplicarmos um material neste plano com o respectivo bitmap.

Em resumo, com exceção
de arquivos 3D carregados externamente, sempre precisaremos de alguma
forma primitiva para termos objetos 3D em nosso ambiente 3D.

Os seis objetos
primitivos nativos são:

  • Plano (Plane)
  • Esfera (Sphere)
  • Cubo (Cube)
  • Cone (Cone)
  • Cilindro
    (Cylinder)
  • Avião de Papel (PlanePaper)

Inserindo objetos

Basicamente, para
inserir objetos primitivos em nosso ambiente precisamos de três
etapas:

  • Importar a classe do primitivo desejado;
  • Criar uma variável que armazenará o objeto;
  • Inseri-lo dentro do ambiente 3D, mais precisamente no Scene.
import org.papervision3d.objects.primitives.Plane;

var plano = new Plane(null, 50, 50);

view.scene.addChild( plano );

Simples,
não?

Agora vamos tornar as
coisas um pouco mais divertidas, vamos configurar e modelar nossos
objetos primitivos.

Antes de tudo, é muito
importante que entendamos quais parâmetros devemos passar para a
chamada de nosso objeto e o que eles representam, conforme a
documentação oficial do Papervision. Lembrando que esses parâmetros
podem variar conforme o objeto, porém a linha de raciocínio é
sempre a mesma:

Para o objeto Plane
temos:

new Plane(material:MaterialObject3D, largura:Number, altura:Number, segmentosHorizontais:Number, segmentosVerticais:Number)
  • material – O
    objeto de material 3D que será aplicado no plano (veremos isto em
    detalhes no próximo artigo).
  • largura – A largura do
    plano em pixels.
  • altura – A altura do plano em
    pixels.
  • segmentosHorizontais – Quantos segmentos
    horizontais farão a composição do plano.
  • segmentosVerticais – Quantos segmentos verticais farão a composição do plano.

Entendendo os
segmentos

O elemento base de
construção de objetos 3D pelo Papervision é o triângulo. A junção
de vários triângulos em diferentes posições X, Y e Z no espaço
3D geram a ilusão de um objeto sólido, essa é a grande mágica do
efeito 3D. E temos que ter sempre em mente: quanto mais triângulos
formando um objeto, mais perfeito ele é, aumentando, em contrapartida, o consumo de processamento em sua renderização.

Portanto, definir
quantos segmentos de triângulos terá o nosso objeto é um ponto
extremamente importante, tanto para a qualidade final da exibição
quanto para o desempenho de seu SWF 3D.

Perceba que, na imagem
acima, com um plano renderizado em aramado (wireframe), podemos ver
claramente os polígonos que o compõem, em uma matriz de segmentos
4×3.

Por padrão, caso você
omita os parâmetros dos segmentos, o Papervision toma como base uma
matriz de 1×1. Mas quantos eu devo utilizar? Isso vai depender muito
do material que será aplicado em seu objeto ou o contexto onde ele
será utilizado. Veremos com mais calma nos próximos artigos, mas de
imediato posso sugerir uma matriz básica de 3×3.

Para o objeto Sphere
temos:

new Sphere(material:MaterialObject3D,raio:Number, segmentosHorizontais:Number, segmentosVerticais:Number)

O único parâmetro que
muda para a esfera é que não definimos altura e largura, mas apenas
o raio da circunferência.

  • material – O
    objeto de material 3D que será aplicado na esfera.
  • raio –
    O raio da circunferência da esfera em pixels.
  • segmentosHorizontais – Quantos segmentos horizontais farão a composição da
    esfera.
  • segmentosVerticais – Quantos segmentos verticais
    farão a composição da esfera.

Para o objeto Cube
temos:

new Cube(material:MaterialsList, largura:Number, profundidade:Number, altura:Number, segmentosHorizontais:Number, segmentosProfundidade:Number, segmentosVerticais:Number, facesDeDentro:int, excluirFaces:int)

Aqui temos mudanças
significativas:

  • materialsList –
    O objeto de lista de materiais 3D que será aplicado no cubo. Aqui
    usamos uma lista de vários materiais, pois como temos seis faces,
    precisamos definir o material de cada uma:
 var materials:MaterialsList = new MaterialsList(
{
front: new ColorMaterial(0xFFFFFF, 1),
back: new ColorMaterial(0xFF0000, 1),
right: new ColorMaterial(0x00FF00, 1),
left: new ColorMaterial(0x333333, 1),
top: new ColorMaterial(0x0000FF, 1),
bottom: new ColorMaterial(0xFFFF00, 1)
} );
  • largura –
    A largura do cubo em pixels.
  • profundidade – Um cubo tem
    seis faces opostas que geram uma extrusão, logo temos de definir o
    valor de sua profundidade em pixels.
  • altura – A altura do
    cubo em pixels.
  • segmentosHorizontais – Quantos segmentos
    horizontais farão a composição do cubo.
  • segmentosProfundidade – Quantos segmentos em profundidade farão a composição do
    cubo.
  • segmentosVerticais – Quantos segmentos verticais
    farão a composição do cubo.
  • facesDeDentro – Aqui
    podemos definir também as faces de dentro do cubo. Usando o valor
    Cube.ALL, todas as faces também serão internas. Caso queira
    definir faces específicas, podemos usar o método de somar ou
    subtrair as faces que queremos: Cube.FRONT + Cube.BACK +
    Cube.TOP (Faces frente, trás e topo) ou Cube.ALL –
    Cube.TOP (Todas as faces, menos a do topo), e assim por
    diante.
  • excluirFaces – Aqui utilizamos a mesma lógica
    acima, sendo que para definir quais faces externas serão excluídas
    na montagem do cubo.

Para o objeto Cone
temos:

new Cone(material:MaterialObject3D, raio:Number, altura:Number, segmentosHorizontais:Number, segmentosVerticais:Number)

Os parâmetros são
quase iguais ao objeto esfera, sendo que temos de definir sua altura.

  • material – O
    objeto de material 3D que será aplicado no cone.
  • raio – O
    raio da circunferência da base do cone em pixels.
  • altura – A altura do cone em pixels.
  • segmentosHorizontais – Quantos
    segmentos horizontais farão a composição do
    cone.
  • segmentosVerticais – Quantos segmentos verticais
    farão a composição do cone.

Para o objeto
Cylinder temos:

new Cylinder(material:MaterialObject3D, raio:Number, altura:Number, segmentosHorizontais:Number, segmentosVerticais:Number, raioDoTopo:Number, faceDoTopo:Boolean, faceDaBase:Boolean)
  • material – O
    objeto de material 3D que será aplicado no cilindro.
  • raio – O raio da circunferência do cilindro em pixels.
  • altura – A altura do cilindro em pixels.
  • segmentosHorizontais –
    Quantos segmentos horizontais farão a composição do
    cilindro.
  • segmentosVerticais – Quantos segmentos
    verticais farão a composição do cilindro.
  • raioDoTopo –
    O valor de raio extra caso queira um cilindro que não seja um
    círculo perfeito. O valor -1 mantém o padrão que é manter o valor
    do raio definido anteriormente.
  • faceDoTopo – true
    ou false, define se o cilindro terá uma face no
    topo.
  • faceDaBase – true ou false, define se
    o cilindro terá uma face na base.

Para o objeto
PaperPlane temos:

newPaperPlane(material:MaterialObject3D,escala:Number)

PaperPlane cria um
objeto inusitado: um avião de papel. Ele é útil para fins de
teste, quando você quer saber, por exemplo, a direção que um
objeto esteja apontando. PaperPlane tem apenas 2 parâmetros simples:

  • material – O
    objeto de material 3D que será aplicado no avião.
  • escala –
    A escala de tamanho do avião em percentual, onde 1 = 100%.

E, por fim, vamos a um
exemplo prático que insere em nosso ambiente 3D um avião de papel
(PaperPlane) apontando para um caixa aberta (Cube) girando. Vamos
pegar a mesma base de código do artigo anterior que gera nosso
ambiente 3D e complementar com nossos primitivos:

package {

import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.*;

import org.papervision3d.cameras.Camera3D;
import org.papervision3d.materials.ColorMaterial;
import org.papervision3d.materials.WireframeMaterial;
import org.papervision3d.materials.utils.MaterialsList;
import org.papervision3d.materials.special.CompositeMaterial;
import org.papervision3d.objects.primitives.Cube;
import org.papervision3d.objects.primitives.PaperPlane;
import org.papervision3d.view.BasicView;

[SWF(frameRate="30", width="800", height="500", backgroundColor="0xFFFFFF")]

public class Primitivos extends Sprite {

private var view:BasicView;
private var caixa:Cube;
private var aviao:PaperPlane;
private var materialAviao:CompositeMaterial;
private var materialFaces:MaterialsList;
private var materialCor:CompositeMaterial;

public function Primitivos() {

init();

}

private function init():void {

stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;

view = new BasicView(800, 500, true, false);
view.camera.zoom = 12;
view.camera.focus = 100;
addChild(view);


materialCor = new CompositeMaterial();
materialCor.doubleSided = true;
materialCor.addMaterial(new ColorMaterial(0xff0000, 0.5));
materialCor.addMaterial(new WireframeMaterial(0xCCCCCC))

materialFaces = new MaterialsList({
front: materialCor,
back: materialCor,
left: materialCor,
right: materialCor,
top: materialCor,
bottom: materialCor});

caixa = new Cube( materialFaces, 150, 130, 150, 5, 5, 5, 0, Cube.BACK );
caixa.rotationZ = 45;
caixa.rotationX = 45;
caixa.x = -150;
caixa.y = -50;


materialAviao = new CompositeMaterial();
materialAviao.doubleSided = true;
materialAviao.addMaterial(new ColorMaterial(0x000000, 0.5));
materialAviao.addMaterial(new WireframeMaterial(0x000000));

aviao = new PaperPlane( materialAviao, .7);
aviao.rotationZ = -40;
aviao.rotationY = -40;
aviao.rotationX = 50;
aviao.x = 350;
aviao.y = 150;


view.scene.addChild( caixa );
view.scene.addChild( aviao );

addEventListener( Event.ENTER_FRAME, enterFrameHandler );

}

private function enterFrameHandler( event : Event ):void {

aviao.z += 2;
aviao.x -= 1;
aviao.y -= 1;

caixa.rotationX += 1;
caixa.rotationY += 1;
caixa.rotationZ += 1;

aviao.lookAt(caixa);

view.singleRender();

}

}

}

Bom,
com isso fechamos a parte de objetos primitivos do Papervision. Caso
esteja achando o número de objetos nativos pequeno e limitado, você
pode aproveitar 17 novos objetos criados por Mike Lively disponíveis
no link
http://professionalpapervision.wordpress.com/2009/02/11/23-papervision3d-primitives-17-new-ones/

A
lista inclui a “Esfera Geodésica”, que tem uma junção de
segmentos aprimorada, gerando uma esfera mais perfeita do que a
nativa do Papervision.

Você pode baixar aqui o exemplo completo.

Vejo
vocês na próxima parte do artigo, onde falarei dos materiais que
serão aplicados nos objetos primitivos. Até lá!