PV3D绘制3D线条 - 3DMAX插件AS3GeomClassExporter导出顶点到AS类
我们分析一下这些代码,其中v开头的,是顶点坐标,uv开头的是面,f是对应的顶点和面的信息,用于添加到一个geometry.faces数组,然后根据这个数组的点面信息绘制图形。这时,如果你需要实例化这个类,直接addChild到场景,物件就会绘制出来了。
如果用到线条绘制这个"V",我们需要怎么做呢?十分简单。我们只需要他的顶点信息,也就是v开头的东西了。我们把这些信息复制出来,提供给Lines3D类使用。利用Lines3D里的addNewLine方法把线条按照顶点座标画出来。
Preview:http://niuniuzhu.cn/p/3DText
利用AS3GeomClassExporter能够方便的得到一个3D物件的顶点和面信息。而且它为我们导出一个完整的类。
首先我们在3DMAX里面输入文本:
让它“站起来”:
然后选择修改选项卡,拉下修改器列表,选择如下:
到工具选项卡,打开AS3GeomClassExporter的面板,设置package和class,然后export:
导出后我们得到一个AS文件,打开看看吧,这是里面的代码:
Code
package view.text
{
import org.papervision3d.core.*;
import org.papervision3d.core.geom.*;
import org.papervision3d.core.geom.renderables.Triangle3D;
import org.papervision3d.core.geom.renderables.Vertex3D;
import org.papervision3d.core.math.NumberUV;
import org.papervision3d.core.proto.*;
public class Text3D extends TriangleMesh3D
{
public var verts :Array;
public var faceAr:Array;
public var uvs :Array;
private function v(x:Number,y:Number,z:Number):void
{
verts.push(new Vertex3D(x,y,z));
}
private function uv(u:Number,v:Number):void
{
uvs.push(new NumberUV(u,v));
}
private function f(vn0:int, vn1:int, vn2:int, uvn0:int, uvn1:int,uvn2:int):void
{
faceAr.push( new Triangle3D( this, [verts[vn0],verts[vn1],verts[vn2] ], null, [uvs[uvn0],uvs[uvn1],uvs[uvn2]] ) );
}
public function Text3D( material:MaterialObject3D=null, initObject:Object=null )
{
super( material, new Array(), new Array(), null, initObject );
verts = this.geometry.vertices;
faceAr= this.geometry.faces;
uvs =new Array();
v(4.29922,0.0,0.0);
v(29.3289,64.1,-2.8019e-006);
v(20.6617,64.1,-2.8019e-006);
v(3.36328,17.5422,-7.66793e-007);
v(2.81146,16.0431,-7.01267e-007);
v(2.27922,14.5441,-6.35743e-007);
v(1.76656,13.0452,-5.70222e-007);
v(1.27348,11.5463,-5.04703e-007);
v(0.799983,10.0475,-4.39188e-007);
v(0.346061,8.54869,-3.73675e-007);
v(-0.0882816,7.05,-3.08165e-007);
v(-0.489588,8.46336,-3.69945e-007);
v(-0.917617,9.90523,-4.32971e-007);
v(-1.37237,11.3756,-4.97244e-007);
v(-1.85384,12.8745,-5.62762e-007);
v(-2.36204,14.4019,-6.29526e-007);
v(-2.89696,15.9578,-6.97537e-007);
v(-3.4586,17.5422,-7.66793e-007);
v(-20.1383,64.1,-2.8019e-006);
v(-29.3289,64.1,-2.8019e-006);
v(-4.56172,0.0,0.0);
uv(8.25781,-17.0422);
uv(33.2875,47.0578);
uv(24.6203,47.0578);
uv(7.32188,0.499999);
uv(6.77006,-0.999076);
uv(6.23782,-2.49809);
uv(5.72516,-3.99704);
uv(5.23208,-5.49592);
uv(4.75858,-6.99474);
uv(4.30465,-8.49349);
uv(3.87031,-9.99219);
uv(3.469,-8.57883);
uv(3.04098,-7.13696);
uv(2.58623,-5.66658);
uv(2.10475,-4.1677);
uv(1.59656,-2.64031);
uv(1.06164,-1.08441);
uv(0.5,0.500001);
uv(-16.1797,47.0578);
uv(-25.3703,47.0578);
uv(-0.603129,-17.0422);
f(0,1,2,0,1,2);
f(0,2,3,0,2,3);
f(0,3,4,0,3,4);
f(0,4,5,0,4,5);
f(0,5,6,0,5,6);
f(0,6,7,0,6,7);
f(0,7,8,0,7,8);
f(0,8,9,0,8,9);
f(0,9,10,0,9,10);
f(20,0,10,20,0,10);
f(19,20,10,19,20,10);
f(19,10,11,19,10,11);
f(19,11,12,19,11,12);
f(19,12,13,19,12,13);
f(19,13,14,19,13,14);
f(19,14,15,19,14,15);
f(19,15,16,19,15,16);
f(19,16,17,19,16,17);
f(19,17,18,19,17,18);
this.geometry.ready = true;
}
}
}
package view.text
{
import org.papervision3d.core.*;
import org.papervision3d.core.geom.*;
import org.papervision3d.core.geom.renderables.Triangle3D;
import org.papervision3d.core.geom.renderables.Vertex3D;
import org.papervision3d.core.math.NumberUV;
import org.papervision3d.core.proto.*;
public class Text3D extends TriangleMesh3D
{
public var verts :Array;
public var faceAr:Array;
public var uvs :Array;
private function v(x:Number,y:Number,z:Number):void
{
verts.push(new Vertex3D(x,y,z));
}
private function uv(u:Number,v:Number):void
{
uvs.push(new NumberUV(u,v));
}
private function f(vn0:int, vn1:int, vn2:int, uvn0:int, uvn1:int,uvn2:int):void
{
faceAr.push( new Triangle3D( this, [verts[vn0],verts[vn1],verts[vn2] ], null, [uvs[uvn0],uvs[uvn1],uvs[uvn2]] ) );
}
public function Text3D( material:MaterialObject3D=null, initObject:Object=null )
{
super( material, new Array(), new Array(), null, initObject );
verts = this.geometry.vertices;
faceAr= this.geometry.faces;
uvs =new Array();
v(4.29922,0.0,0.0);
v(29.3289,64.1,-2.8019e-006);
v(20.6617,64.1,-2.8019e-006);
v(3.36328,17.5422,-7.66793e-007);
v(2.81146,16.0431,-7.01267e-007);
v(2.27922,14.5441,-6.35743e-007);
v(1.76656,13.0452,-5.70222e-007);
v(1.27348,11.5463,-5.04703e-007);
v(0.799983,10.0475,-4.39188e-007);
v(0.346061,8.54869,-3.73675e-007);
v(-0.0882816,7.05,-3.08165e-007);
v(-0.489588,8.46336,-3.69945e-007);
v(-0.917617,9.90523,-4.32971e-007);
v(-1.37237,11.3756,-4.97244e-007);
v(-1.85384,12.8745,-5.62762e-007);
v(-2.36204,14.4019,-6.29526e-007);
v(-2.89696,15.9578,-6.97537e-007);
v(-3.4586,17.5422,-7.66793e-007);
v(-20.1383,64.1,-2.8019e-006);
v(-29.3289,64.1,-2.8019e-006);
v(-4.56172,0.0,0.0);
uv(8.25781,-17.0422);
uv(33.2875,47.0578);
uv(24.6203,47.0578);
uv(7.32188,0.499999);
uv(6.77006,-0.999076);
uv(6.23782,-2.49809);
uv(5.72516,-3.99704);
uv(5.23208,-5.49592);
uv(4.75858,-6.99474);
uv(4.30465,-8.49349);
uv(3.87031,-9.99219);
uv(3.469,-8.57883);
uv(3.04098,-7.13696);
uv(2.58623,-5.66658);
uv(2.10475,-4.1677);
uv(1.59656,-2.64031);
uv(1.06164,-1.08441);
uv(0.5,0.500001);
uv(-16.1797,47.0578);
uv(-25.3703,47.0578);
uv(-0.603129,-17.0422);
f(0,1,2,0,1,2);
f(0,2,3,0,2,3);
f(0,3,4,0,3,4);
f(0,4,5,0,4,5);
f(0,5,6,0,5,6);
f(0,6,7,0,6,7);
f(0,7,8,0,7,8);
f(0,8,9,0,8,9);
f(0,9,10,0,9,10);
f(20,0,10,20,0,10);
f(19,20,10,19,20,10);
f(19,10,11,19,10,11);
f(19,11,12,19,11,12);
f(19,12,13,19,12,13);
f(19,13,14,19,13,14);
f(19,14,15,19,14,15);
f(19,15,16,19,15,16);
f(19,16,17,19,16,17);
f(19,17,18,19,17,18);
this.geometry.ready = true;
}
}
}
我们分析一下这些代码,其中v开头的,是顶点坐标,uv开头的是面,f是对应的顶点和面的信息,用于添加到一个geometry.faces数组,然后根据这个数组的点面信息绘制图形。这时,如果你需要实例化这个类,直接addChild到场景,物件就会绘制出来了。
如果用到线条绘制这个"V",我们需要怎么做呢?十分简单。我们只需要他的顶点信息,也就是v开头的东西了。我们把这些信息复制出来,提供给Lines3D类使用。利用Lines3D里的addNewLine方法把线条按照顶点座标画出来。
我利用了一个导航球,“带领”着线条的移动,一下是这个导航球的代码,其中的trailList就是顶点座标数组:
Code
public function SimpleLine(lineSize:int, trailSize:int, color:uint, trailList:Array, speed:Number, name:String=null)
{
super(lineSize, trailSize, color, name);
newTrailList = analyzeTrailList(trailList, speed);
trailObj.x = newTrailList[0].x;
trailObj.y = newTrailList[0].y;
trailObj.z = newTrailList[0].z;
oldVertex3D = new Vertex3D(newTrailList[0].x, newTrailList[0].y, newTrailList[0].z);
}
private function analyzeTrailList(trailList:Array, speed:Number):Array
{
var newArray:Array = [];
for (var i:int = 0; i < trailList.length - 1; i ++)
{
var ii:int = i + 1;
var dx:Number = trailList[ii].x - trailList[i].x;
var dy:Number = trailList[ii].y - trailList[i].y;
var d:Number = Math.sqrt(dx * dx + dy * dy);
var speedX:Number = Math.cos(Math.atan2(dy, dx)) * speed;
var speedY:Number = Math.sin(Math.atan2(dy, dx)) * speed;
var per:Number = d / speed;
for (var j:int = 0; j < per - 1; j ++)
{
var x:Number = trailList[i].x + speedX * j;
var y:Number = trailList[i].y + speedY * j;
newArray.push(new Vertex3D(x, y, 0));
}
newArray.push(new Vertex3D(trailList[ii].x, trailList[ii].y, 0));
}
return newArray;
}
public function renderLine(i:int = 0):void
{
if (i < newTrailList.length - 1)
{
var ii:int = i + 1;
TweenLite.to(trail, .005, {x:newTrailList[ii].x, y:newTrailList[ii].y, z:newTrailList[ii].z, onComplete:renderLine, onCompleteParams:[ii], ease:Linear.easeOut});
}
else
{
tweenComplete();
}
}
public function SimpleLine(lineSize:int, trailSize:int, color:uint, trailList:Array, speed:Number, name:String=null)
{
super(lineSize, trailSize, color, name);
newTrailList = analyzeTrailList(trailList, speed);
trailObj.x = newTrailList[0].x;
trailObj.y = newTrailList[0].y;
trailObj.z = newTrailList[0].z;
oldVertex3D = new Vertex3D(newTrailList[0].x, newTrailList[0].y, newTrailList[0].z);
}
private function analyzeTrailList(trailList:Array, speed:Number):Array
{
var newArray:Array = [];
for (var i:int = 0; i < trailList.length - 1; i ++)
{
var ii:int = i + 1;
var dx:Number = trailList[ii].x - trailList[i].x;
var dy:Number = trailList[ii].y - trailList[i].y;
var d:Number = Math.sqrt(dx * dx + dy * dy);
var speedX:Number = Math.cos(Math.atan2(dy, dx)) * speed;
var speedY:Number = Math.sin(Math.atan2(dy, dx)) * speed;
var per:Number = d / speed;
for (var j:int = 0; j < per - 1; j ++)
{
var x:Number = trailList[i].x + speedX * j;
var y:Number = trailList[i].y + speedY * j;
newArray.push(new Vertex3D(x, y, 0));
}
newArray.push(new Vertex3D(trailList[ii].x, trailList[ii].y, 0));
}
return newArray;
}
public function renderLine(i:int = 0):void
{
if (i < newTrailList.length - 1)
{
var ii:int = i + 1;
TweenLite.to(trail, .005, {x:newTrailList[ii].x, y:newTrailList[ii].y, z:newTrailList[ii].z, onComplete:renderLine, onCompleteParams:[ii], ease:Linear.easeOut});
}
else
{
tweenComplete();
}
}
Preview:http://niuniuzhu.cn/p/3DText