与PaperVision3D, Away3D等相对成熟的Flash 3D引擎不同,Alternativa3D 7.6在原生的swc包中没有提供3D线的绘制功能。而对于一些非游戏的应用,比如路径分析的展示,往往需要用到 3DLine这种极简单的Primitive类型。 本文利用A3D 中的Mesh来模拟3D 线的绘制。
package
{
import alternativa.engine3d.controllers.SimpleObjectController;
import alternativa.engine3d.core.Camera3D;
import alternativa.engine3d.core.Object3DContainer;
import alternativa.engine3d.core.Vertex;
import alternativa.engine3d.core.View;
import alternativa.engine3d.materials.FillMaterial;
import alternativa.engine3d.objects.Mesh;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.geom.Vector3D;
public class DrawLine extends Sprite
{
private var controller:SimpleObjectController;
private var rootContainer:Object3DContainer=new Object3DContainer();
private var camera:Camera3D
public function DrawLine()
{
//引擎基本设置
stage.align=StageAlign.TOP_LEFT;
stage.scaleMode=StageScaleMode.NO_SCALE;
camera=new Camera3D();
camera.view=new View(stage.stageWidth, stage.stageHeight);
camera.z=-300;
addChild(camera.view);
rootContainer.addChild(camera);
controller=new SimpleObjectController(stage, camera, 200);
controller.unbindAll();
//调用绘制3D线的函数
drawLine(new Vector3D(0, 0, 0), new Vector3D(100, 0, 0), 0xFFAA11, 5);
drawLine(new Vector3D(100, 0, 0), new Vector3D(0, 100, 0), 0xFF00, 2);
drawLine(new Vector3D(-100, 0, 0), new Vector3D(-100, 150, 200), 0xFF0000, 5);
stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
stage.addEventListener(Event.RESIZE, onResize);
}
private function onEnterFrame(e:Event):void
{
controller.update();
camera.render();
}
private function onResize(e:Event=null):void
{
camera.view.width=stage.stageWidth;
camera.view.height=stage.stageHeight;
}
//绘制3DLine的小技巧
public function drawLine(from:Vector3D, to:Vector3D, lineColor:int, lineWidth:Number):void
{
var line:Mesh=new Mesh();
var v1:Vertex=line.addVertex(from.x, from.y, from.z);
var v2:Vertex=line.addVertex(to.x, to.y, to.z);
//根据第二个Vertex设置一个在Z轴上偏移量极小的Vertex,使得三角形视觉上变形为直线
var v3:Vertex=line.addVertex(to.x, to.y, to.z + 1e-9);
line.addFace(Vector.<Vertex>([v1, v2, v3]), new FillMaterial(lineColor, 1, lineWidth, lineColor));
line.addFace(Vector.<Vertex>([v3, v2, v1]), new FillMaterial(lineColor, 1, lineWidth, lineColor));
//需要调用mesh的calculateNormals来计算Normal方向,否则无法绘制成功
line.calculateNormals(true);
rootContainer.addChild(line);
}
}
}