`
ienown
  • 浏览: 6772 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

基础知识07镜头设计,及映射原理[转]

阅读更多
转载 原文为 http://www.pan3d.me/tutorial 作者 Pan3d.Me



先打开SWF。观察效果,

①.你会发现一直在绕着中间这张图片在旋转。留右上角 的红点,就是相当于镜头的坐标(俯视图 只能表现 X,Z)
程序解释。
private var _Cam:Object = { x:0, y:0, z:0, br:1000, angle_x:0, angle_y:0, angle_z:0 } //设计一个镜头

我们先来设计一个镜头(镜头这个东西自己领悟是什么意思,外事问GOOGLE,内事问百度,房事问天涯)

一般镜头都会由一个坐标, 在这里  它的   x,y,z,都初如为0 ,以及偏转角度,也应该是 三个角度的偏转角

在这个程序里,我们只针对绕 Y轴旋转的情况下的效果,另两个做为以后保留使用

②. 在这里我用了  v, u ,uv 来描述 这个矩形面片(由两个三角形组成), 它也是一个完整的贴图

(1)._v:Array = [ -50, 50, 0, -50, -50, 0, 50, -50, 0, 50, 50, 0];

我们把它分来 3个一组,就可以得到 4个点(x,y,z)的坐标, 他们的z都为0,说明这4个点都在同一深度上(世界坐标)。

试着想想,会是一个怎样的形状

(2)._u:Array = [0, 0, 0, 1, 1, 1, 1, 0];

贴图坐标,因为它是平面上的,所以只需要(x,y)两个坐标来修饰,我们把它二个一组同样可以得到4组数据 。

这里要说明一下贴图坐标他是相对于原始图片的坐标,跟据百分比来标记的(前几节教程里有测试过,与是为了统一所有

3D原文件的,以后3D模形数据无设是3DMAX,还是MAYA,等都是这样)。

(3)._uv:Array = [0, 0, 1, 1, 2, 2,0,0,2,2,3,3];

这是最关键的 贴图组合,并不难理解, 简单来说,一个3维中的点,对应该贴图中的一个点,

一个三角形由三个空间中的点来组成,同时这三个点,又对应该贴图的三个点。就需要6个点来表示一个带贴图的

三角形, 在这里一共有12位,也就是两个三角形,那我们接下来解释这些点是怎个对应的

0,0,1,1,2,2 分开       第一个为 0, 为3维中的坐标   在 v数级第1个点 (-50, 50, 0)

第二个为 0 ,   为贴图坐标   在 u数组第1 个点 (0,0)

第三个为 1, 这个又是3维中的坐标 相对应该 在 v数组的第2个点(-50, -50, 0)

…………….

0,0,2,2,3,3 第二个三角形,同上,   (你如果想试一个只有一个三角形的话,把这些数据删除就可以发现只有一个三角形)

③. 上一步的数据,DAE格式,就是传说中的3D模形的基本数据,格式适应所有的3D应该。都是通过这种方法互转换的

现在我们要做的是编入到FLASH里能识别的数据,

for (var i = 0; i < _v.length / 3;i++ ) {
var _obj:Object = new Object
_obj.x = _v[i * 3 + 0];
_obj.y = _v[i * 3 + 1];
_obj.z = _v[i * 3 + 2];
_obj.bx = 0;
_obj.by = 0;
_obj.bz = 0;
_vitem.push(_obj);
}


这点就是将原来的 v点整理放入 _vitem数组了,在这里他就只有4个长度了,不再向原始数据那样并列排在一个

数组中,每一个数据都是一个对象(object).  来解释一下一个3维的点应该怎么来表示,在这里,x,y,z为这个点在这个世界

中的真实坐标, bx,by,bz 为相对于镜头的坐标(它是由这个点在世界中的坐标相对于镜头坐标用角度而形成的,等会我们会

把它计算出来的)

④.为triangles补入原始数据

for (var j = 0; j < _uv.length / 2; j++ ) {
var v_id=(_uv[j*2+0])
var u_id=(_uv[j*2+1])
_triangles.vertices.push(0, 0);
_triangles.uvtData.push(_u[u_id*2+0],_u[u_id*2+1],1);
}


triangles为使用 Flash API 画3D 图形时所要的参数 (上几节有说过的)

我们跟据_uv的数据组合排列,对应出  vertices和uvtData的数据。注意 vertices的坐标在这次赋值都为 0 主要是为了

对应 uvtData贴图的的坐标,因为uvtData的坐标不会再有改变。所以在这里的赋值是真实有效的

特别注意,indices 在前面章节中我们有学到这个,他得贴图对应顺序,如果有数据,将会按着数据来画三角形,要是没有

他会默认为 0,1,2   3,4 5   也就是说他会从顺序, 在这里我们用默认,所以不设定他的数值

(学会用trace观察数据变化,现在才一两个三角形。试着去理解,最后在我写下一步说明前,你就能想到)

⑤. 画图的元件

_tempmc.x = 300;
_tempmc.y = 200;

_tempmc用来做画图的元件。为什么要把它的做标放在  300,200 就是为了FLASH 的坐标是于左上角的为0,0这个部

分说多了反面变得复杂,往简单想就对了

⑥ 镜头角度变化及坐标变化(这个例子里我们只针对绕Y转旋转)其它就忽例掉了以后补上

_Cam.angle_y++        //这个简单
_catch_cam(_Cam)

private function _catch_cam(_Cam) {
var _focus_3d:Vector3D = new Vector3D(0, 0, 0)
var rx = 0;
var ry = 0;
var rz = 500;
var view_angle_y = _Cam.angle_y-180
var tmp_angle_y = view_angle_y * Math.PI / 180;
var tmp_rx = rx;
rx = (Math.cos(tmp_angle_y) * tmp_rx + Math.sin(tmp_angle_y) * rz);
rz = (Math.sin(tmp_angle_y) * tmp_rx + Math.cos(tmp_angle_y) * rz);

mc_map.mc_cam.x = rx * 0.05;
mc_map.mc_cam.y = -rz * 0.05;

_Cam.x = rx;
_Cam.z = rz;
}

(1)._catch_cam 这个函数,我们用来计算 为了保证镜头角度_Cam.angle_y变化后,仍然看到0,0,0在前面,

所以要改变镜头的 x,y,z  在这里y 其实没有变会,只有 x,z在变,它的位置可以在右上角的俯视图中显示出来。

(在这里你可以将这个函数注消掉  //_catch_cam(_Cam) ,就只相当于镜头在自己转,变成4边形绕镜头转了)

最后更好新的 镜头坐标     _Cam.x = rx;   _Cam.z = rz;

⑦将世界中的间映射到镜头上

public function _up_data() {
for (var i in _vitem) {
math_change_point(_vitem[i])
}
for (var j = 0; j < _uv.length / 2; j++ ) {
var v_id = (_uv[j * 2 + 0])
_triangles.vertices[j * 2 + 0] = _vitem[v_id ].bx / (_vitem[v_id].bz + _Cam.br) * _Cam.br;
_triangles.vertices[j * 2 + 1] = -_vitem[v_id ].by / (_vitem[v_id].bz + _Cam.br) * _Cam.br;
}

_draw_pic()
}


(1).将所 vitem 中的 x,y,z 通过镜头的坐标角度转换为 相对于镜头的坐标。  用到的函数是math_change_point

public function math_change_point(_3dpoint) {
var rx = _3dpoint.x -_Cam.x
var ry = _3dpoint.y -_Cam.y
var rz = _3dpoint.z -_Cam.z
var sin_y = Math.sin(_Cam.angle_y *  Math.PI/180);
var cos_y = Math.cos(_Cam.angle_y *  Math.PI/180);
var tmp_rx = rx;
rx = cos_y * tmp_rx – sin_y * rz;
rz = sin_y * tmp_rx + cos_y * rz;
_3dpoint.bx = rx;
_3dpoint.by = ry;
_3dpoint.bz = rz;

}


先将 rx,ry,rz 赋值为两个坐标的相差置值,, 然后再根据  _Cam.angle_y进行角度旋转,就可以得到镜头坐标了

然后将值赋回给 _3dpoint.bx = rx;_3dpoint.by = ry;_3dpoint.bz = rz;

(2). 将对应该的点 的镜头坐标映射到屏幕上的去,

for (var j = 0; j < _uv.length / 2; j++ ) {
var v_id = (_uv[j * 2 + 0])
_triangles.vertices[j * 2 + 0] = _vitem[v_id ].bx / (_vitem[v_id].bz + _Cam.br) * _Cam.br;
_triangles.vertices[j * 2 + 1] = -_vitem[v_id ].by / (_vitem[v_id].bz + _Cam.br) * _Cam.br;
}


值得注意的是 _triangles.vertices[j * 2 + 0] = _vitem[v_id ].bx / (_vitem[v_id].bz + _Cam.br) * _Cam.br;

这是一个3维坐标转2维坐标的公或同理,y的坐标也是一样的,

你会发现为什么 _triangles.vertices[j * 2 + 1] = -_vitem[v_id ].by / (_vitem[v_id].bz + _Cam.br) * _Cam.br;

中为 -(负) ,因为FLASH舞台 y 坐标是向下+(正),在我们通常的3D图表中向上才是+(正)

最后,我们将图画出来

public function _draw_pic() {
_tempmc.graphics.clear()
_tempmc.graphics.beginBitmapFill(_Bmpsource);
_tempmc.graphics.lineStyle(1,0×4564587)
_tempmc.graphics.drawTriangles(_triangles.vertices, _triangles.indices, _triangles.uvtData, TriangleCulling.NONE ); /
}


先清除上次画的内容  clear()

贴图数据.beginBitmapFill(_Bmpsource);

提示边线lineStyle(1,0×4564587)    在这也可以注消掉的

接着画图 drawTriangles

附(多对比里面的数据,试着修改基本参数,查看效果
  • 大小: 12.8 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics