教材提供    Flash8.net 教材区首页 最新教材列表

玩转Flash AS 3D之贴图篇 （3）

作者：tiger_0309   类型:原创   来源:闪吧

第1页 第1页 （1）

第2页 （2）

第3页 （3）

所有的立体图形贴图都是由一小块的正方形或者三角形组成，比如圆柱体，我们可以把它看成许多块矩形组成的，我下面的例子就是一个简单的圆柱体，不过我只是用了十个矩形组成的，要让它更逼真可以把它分割成更多的矩形，这里我还要提醒一点，分的越多，你的cpu负担就越重，有人说这是flash做3d的缺点，认为其它专门的3d软件就不会有这中现象，其实我认为不然，3d软件在渲染的时候占用cpu更大，只不过导出图象序列后就不占用cpu，可是那是静态图象，而flash只所以占用cpu大，是因为它把这渲染和输出合二为一了。
代码：

Point = function (x, y, z) {
this.x = x;
this.y = y;
this.z = z;
};
Transform3DPointsTo2DPoints = function (pts, angles) {
var tps = new Array();
var sx = Math.sin(angles.x);
var cx = Math.cos(angles.x);
var sy = Math.sin(angles.y);
var cy = Math.cos(angles.y);
var sz = Math.sin(angles.z);
var cz = Math.cos(angles.z);
var p, xy, xz, yx, yz, zx, zy;
var i = pts.length;
while (i--) {
p = pts;
xy = cx*p.y-sx*p.z;
xz = sx*p.y+cx*p.z;
yz = cy*xz-sy*p.x;
yx = sy*xz+cy*p.x;
zx = cz*yx-sz*xy;
zy = sz*yx+cz*xy;
x=275+zx;
y=200-zy;
z=yz;
tps = new Point(x, y, z);
}
return tps;
};
var points3D = [
new Point(100*Math.cos(2*Math.PI/10*0), 100, 100*Math.sin(2*Math.PI/10*0)),
new Point(100*Math.cos(2*Math.PI/10*1), 100, 100*Math.sin(2*Math.PI/10*1)),
new Point(100*Math.cos(2*Math.PI/10*2), 100, 100*Math.sin(2*Math.PI/10*2)),
new Point(100*Math.cos(2*Math.PI/10*3), 100, 100*Math.sin(2*Math.PI/10*3)),
new Point(100*Math.cos(2*Math.PI/10*4), 100, 100*Math.sin(2*Math.PI/10*4)),
new Point(100*Math.cos(2*Math.PI/10*5), 100, 100*Math.sin(2*Math.PI/10*5)),
new Point(100*Math.cos(2*Math.PI/10*6), 100, 100*Math.sin(2*Math.PI/10*6)),
new Point(100*Math.cos(2*Math.PI/10*7), 100, 100*Math.sin(2*Math.PI/10*7)),
new Point(100*Math.cos(2*Math.PI/10*8), 100, 100*Math.sin(2*Math.PI/10*8)),
new Point(100*Math.cos(2*Math.PI/10*9), 100, 100*Math.sin(2*Math.PI/10*9)),
new Point(100*Math.cos(2*Math.PI/10*0), -100, 100*Math.sin(2*Math.PI/10*0)),
new Point(100*Math.cos(2*Math.PI/10*1), -100, 100*Math.sin(2*Math.PI/10*1)),
new Point(100*Math.cos(2*Math.PI/10*2), -100, 100*Math.sin(2*Math.PI/10*2)),
new Point(100*Math.cos(2*Math.PI/10*3), -100, 100*Math.sin(2*Math.PI/10*3)),
new Point(100*Math.cos(2*Math.PI/10*4), -100, 100*Math.sin(2*Math.PI/10*4)),
new Point(100*Math.cos(2*Math.PI/10*5), -100, 100*Math.sin(2*Math.PI/10*5)),
new Point(100*Math.cos(2*Math.PI/10*6), -100, 100*Math.sin(2*Math.PI/10*6)),
new Point(100*Math.cos(2*Math.PI/10*7), -100, 100*Math.sin(2*Math.PI/10*7)),
new Point(100*Math.cos(2*Math.PI/10*8), -100, 100*Math.sin(2*Math.PI/10*8)),
new Point(100*Math.cos(2*Math.PI/10*9), -100, 100*Math.sin(2*Math.PI/10*9))
];

var points2D = new Array();
var rotation = new Point(0, 0, 0);
function skewObj(obj, mcW, mcH, pt0, ptH, ptW) {
function distance(pt1, pt2) {
var dy = pt2.y-pt1.y;
var dx = pt2.x-pt1.x;
var side = Math.sqrt(dy*dy+dx*dx);
return side;
}
var z=(ptH.z+ptW.z+pt0.z)/3;
obj.swapDepths(Math.round(10000+z*100));
obj._x = pt0.x;
obj._y = pt0.y;
obj._yscale = 100;
var angleP2 = Math.atan2(ptW.y-pt0.y, ptW.x-pt0.x);
var angleP1 = Math.atan2(ptH.y-pt0.y, ptH.x-pt0.x);
var dAngle = (angleP1-angleP2)/2;
var arm = Math.sqrt(2)/2/Math.cos(dAngle);
// original a 100x100 model , now use 1x1 model
obj._rotation = (180/Math.PI)*(angleP1-dAngle);
obj.mc._rotation = -45;
obj._yscale = 100*Math.tan(dAngle);
obj.mc._xscale = distance(ptW, pt0)*100/arm/mcW;
obj.mc._yscale = distance(ptH, pt0)*100/arm/mcH;
}
for(var i=0;i<10;i++){

_root.attachMovie("obj"+(i+1),"obj"+(i+1),i+1);

H1 = obj1.mc._height;
W1 = obj1.mc._width;
H2 = obj2.mc._height;
W2 = obj2.mc._width;
H3 = obj3.mc._height;
W3 = obj3.mc._width;
H4 = obj4.mc._height;
W4 = obj4.mc._width;
H5 = obj5.mc._height;
W5 = obj5.mc._width;
H6 = obj6.mc._height;
W6 = obj6.mc._width;
H7 = obj7.mc._height;
W7 = obj7.mc._width;
H8 = obj8.mc._height;
W8 = obj8.mc._width;
H9 = obj9.mc._height;
W9 = obj9.mc._width;
H10 = obj10.mc._height;
W10 = obj10.mc._width;

}
onEnterFrame = function () {
rotation.x -= _ymouse/5000;
rotation.y += _xmouse/5000;
points2D = Transform3DPointsTo2DPoints(points3D, rotation);
skewObj(obj1, W1, H1, points2D[0], points2D[10], points2D[1]);
skewObj(obj2, W2, H2, points2D[1], points2D[11], points2D[2]);
skewObj(obj3, W3, H3, points2D[2], points2D[12], points2D[3]);
skewObj(obj4, W4, H4, points2D[3], points2D[13], points2D[4]);
skewObj(obj5, W5, H5, points2D[4], points2D[14], points2D[5]);
skewObj(obj6, W6, H6, points2D[5], points2D[15], points2D[6]);
skewObj(obj7, W7, H7, points2D[6], points2D[16], points2D[7]);
skewObj(obj8, W8, H8, points2D[7], points2D[17], points2D[8]);
skewObj(obj9, W9, H9, points2D[8], points2D[18], points2D[9]);
skewObj(obj10, W10, H10, points2D[9], points2D[19], points2D[0]);

};
(3d贴图3.swf):
/UploadTeach/200706/20070622124321529.swf

光有矩形贴图还不够，有时候还需要三角形，三角形的原理也来自矩形，如下图，我们把矩形也看成正方形，通过给出的三角形pH的坐标可以算出ptH的坐标，

function getPH(pt0,pH,ptW){
var pt=new Object();
pt.x=pH.x-(ptW.x-pt0.x)/2;
pt.y=pH.y-(ptW.y-pt0.y)/2
pt.z=pH.z-(ptW.z-pt0.z)/2;
return pt;
}
//这个函数不用解释也能看懂吧
那么上面的函数就变成这样了：
skewObj(clip, 100, 100, rp0, getPH(rp0,rpH,rpW), rpW);
其中100我是按照正方形来计算的，如果你不是用的正方形，那么应该是这样了
skewObj(clip, mcW, mcH, rp0, getPH(rp0,rpH,rpW), rpW);
mcW和mcH分别是矩形的长和宽
这是四面体的三维坐标：
pointsArray = [
new Point(-50, 29, 29),
new Point(0, 29, -58),
new Point(50, 29, 29),
new Point(0, -58, 0)];
具体的原代码我就不给了，大家只需把坐标和上面的函数换一下就好了，如果实在做不出，把我的swf反编译也行，所有的文件都没有加密。(3d贴图4.swf):
/UploadTeach/200706/20070622124445205.swf

图片附件: 003. gif

然后我们再看看上面的哪个圆柱体，给它加个盖和底，说到这里我有要提一下闪客帝国有名的哪个3d易拉罐，当时看的时候怎么也看不懂，并且原文件加密了，现在再想想其实也不难，它只不过把它分割成一个个的三角形而已。(3d贴图5.swf):
/UploadTeach/200706/20070622124554150.swf
写到这里理论上我们可以给任意的立体图形贴图了，只要你有耐心，你的配置足够高（主要是cpu).
回顾上面的例子，不知道你注意到没有，所有的贴图还有个致命的缺陷，就是做出来的三维图形不是真正意义上的透视图形，为什么呢？那是因为在flash8之前还不能操作位图，所有的坐标都没有进行透视处理，你可以试一下坐标透视处理后会出现下面状况，把上面坐标转化函数改成这样：

scaleFactor = focalLength/(focalLength+yz);
x = zx*scaleFactor;
y = zy*scaleFactor;
z = yz;
不过庆幸的是在flash8中我们可以做到真正的透视3d了，最后的一个例子我就是用flash8做的，你可以和上面的比较一下，看有什么不同，在这个原文件我应用了ditortimage类，老外写的类，很不错。(3d贴图6.swf):
/UploadTeach/200706/20070622124659979.swf

1

2

3

责任编辑:silvia    时间:2007年6月22日

上一篇:

FLASH网游通过XMLSocket与VB后台通信教

下一篇:

FLASH内部复制粘贴图形

相关教材

玩转Flash AS 3D之贴图篇

最近更新

查看所有评论