2014年2月20日星期四(DEMO7-5)

这个DEMO与上个DEMO的区别在于

1, 相机是UVN相机,而不是欧拉相机,变成全屏的了。

没有2.

 

UVN相机模型,就是在知道准确坐标的时候进行聚焦。欧拉相机是知道大概方向时的扫描。

其中,N是指相机位置指向目标位置的向量,相当于Z轴;V指的是上向量,相当于Y轴,假设v=<0,1,0>;接着求U,U相当于右向量X,计算方法是U=V×N,接着计算V的正确值V=N×U。

可见,U,V,N三向量互相垂直

首先,坦克个数换为16个,

#define NUM_OBJECTS     16

摄像机位置发生改变

POINT4D  cam_pos = {0,0,0,1};

并增加了目标物体的位置

POINT4D  cam_target = {0,0,0,1};

并在GAME_INIT()中作相应改变

 

 

         liushuixian.Init_CAM4DV1( *math, &cam,      // the camera object

                  CAM_MODEL_UVN, // euler camera model

                  &cam_pos,  // initial camera position

                  &cam_dir,  // initial camera angles

                  &cam_target,      // no initial target

                  50.0,      // near and far clipping planes

                  8000.0,

                  90.0,      // field of view in degrees

                  WINDOW_WIDTH,   // size of final screen viewport

                  WINDOW_HEIGHT);

                 

模型默认位置的Z坐标也改变了

obj.world_pos.z                                                              = 0;

由于这里要做的是改变摄像机位置和朝向,对着固定目标。让摄像机做圆周运动。

摄像机的各个参数设置

static float view_ang                                                      = 0;

static float camera_distance                                           = 1750;

static VECTOR4D pos                                                   = {0 ,0,0};

 

在局部坐标系中,进行局部坐标变换

         liushuixian.Transform_OBJECT4DV1( & obj, & mrot, TRANSFORM_LOCAL_ONLY, 1);

下一步设置摄像机的位置

 

         cam.pos.x                                                      = camera_distance * cosf( view_ang );

         cam.pos.y                                                      = camera_distance * sinf( view_ang );

         cam.pos.z                                                      = 2 * camera_distance * sinf( view_ang );

 

         if ( ( view_ang += 1) > 360 )

         {

                  view_ang                                              = 0;

         }

紧接着是进行UVN模型相机函数的调用,这里有个简单模式UVN_MODE_SIMPLE和和球面坐标模式UVN_MODE_SPHERICAL。简单模式就是提供目标位置和观察参考点;球面坐标模式的分量X和Y被用作观察向量的方位角和仰角。

先定义UVN的两个模式

 

#define     UVN_MODE_SIMPLE                                       0

#define UVN_MODE_SPHERICAL                                    1

 

4D向量的归一化函数加上。类似于3D向量

void ddraw_math::VECTOR4D_Normalize( VECTOR4D_PTR va )

{

         float length                                  = sqrtf( va->x * va->x + va->y * va->y + va->z * va->z );

         if ( length < EPSILON_E5 )

         {

                  return;

         }

 

         float length_inv                  = 1 / length;

 

         va->x                                                    *= length_inv;

         va->y                                                    *= length_inv;

         va->z                                                    *= length_inv;

         va->z                                                    = 1;

}

 

 

 

构建UVN相机矩阵

 

void ddraw_liushuixian::Build_CAM4DV1_Matrix_UVN( ddraw_math math2,CAM4DV1_PTR cam, int mode )

{

         MATRIX4X4                              mt_inv,                                //相机平移矩阵的逆矩阵

                                                             mt_uvn,                               //UVN相机变换矩阵

                                                             mtmp;                                  //用于存储临时矩阵

 

         //1步,根据相机位置计算相机平移矩阵的逆矩阵

         math2.Mat_Init_4X4( & mt_inv, 1, 0, 0, 0,

                  0, 1, 0, 0,

                  0, 0, 1, 0,

                  -cam->pos.x, -cam->pos.y, -cam->pos.z, 1 );

 

         if ( mode == UVN_MODE_SPHERICAL )

         {

                  //使用球面坐标模式,需要重新计算目标点

                  //提取方位角和仰角

                  float                   phi                                       = cam->dir.x;                      //仰角

                  float                   theta                           = cam->dir.y;                      //方位角

 

                  //计算三角函数

                  float                   sin_phi                                = sinf( phi );

                  float                   cos_phi                                = cosf( phi );

                 

                  float                   sin_theta                     = sinf( theta );

                  float                   cos_theta                    = cosf( theta );

 

                  //计算目标点在单位球面上的位置(X,Y,Z)

                  cam->target.x                                                = -1 * sin_phi * sin_theta;

                  cam->target.y                                                = 1 * cos_phi;

                  cam->target.z                                                = 1 * sin_phi * cos_theta;

         }

         //根据观察点和摄像机位置构建UVN

         math2.VECTOR4D_Build( & cam->pos, & cam->target, & cam->n );

         math2.VECTOR4D_INITXYZ( & cam->v, 0, 1, 0 );

         math2.VECTOR4D_CROSS( & cam->v, & cam->n, & cam->u );

         math2.VECTOR4D_CROSS( & cam->n, & cam->u, & cam->v );

        

         //归一化

         math2.VECTOR4D_Normalize( & cam->u );

         math2.VECTOR4D_Normalize( & cam->v );

         math2.VECTOR4D_Normalize( & cam->n );

 

         //UVN代入,得到UVN旋转矩阵

         math2.Mat_Init_4X4( & mt_uvn, cam->u.x, cam->v.x, cam->n.x, 0,

                                                                        cam->u.y, cam->v.y, cam->n.y, 0,

                                                                        cam->u.z, cam->v.z, cam->n.z, 0,

                                                                        0, 0, 0, 1 );

 

         //将平移矩阵乘以矩阵UVN矩阵,并将结果存储到相机变换矩阵mcam

         math2.Mat_Mul_4X4( & mt_inv, & mt_uvn, & cam->mcam );

 

 

}

 

继续,在GAME_MAIN()中

创建UVN相机坐标系

 

         liushuixian.Build_CAM4DV1_Matrix_UVN( math, & cam, UVN_MODE_SIMPLE );

物体的Z轴改了

         obj.world_pos.z                           = z * OBJECT_SPACING + OBJECT_SPACING / 2;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值