⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 t3dlib5.cpp

📁 3D游戏编程大师技巧第十章的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:

         default: break;
         } // end switch

    // finally set the polygon to active
    obj->plist[poly].state = POLY4DV1_STATE_ACTIVE;    

    } // end for poly

// close the file
fclose(fp);

// return success
return(1);

} // end Load_OBJECT4DV1_PLG

//////////////////////////////////////////////////////////////

void Translate_OBJECT4DV1(OBJECT4DV1_PTR obj, VECTOR4D_PTR vt) 
{
// NOTE: Not matrix based
// this function translates an object without matrices,
// simply updates the world_pos
VECTOR4D_Add(&obj->world_pos, vt, &obj->world_pos);

} // end Translate_OBJECT4DV1

/////////////////////////////////////////////////////////////

void Scale_OBJECT4DV1(OBJECT4DV1_PTR obj, VECTOR4D_PTR vs)
{
// NOTE: Not matrix based
// this function scales and object without matrices 
// modifies the object's local vertex list 
// additionally the radii is updated for the object

// for each vertex in the mesh scale the local coordinates by
// vs on a componentwise basis, that is, sx, sy, sz
for (int vertex=0; vertex < obj->num_vertices; vertex++)
    {
    obj->vlist_local[vertex].x*=vs->x;
    obj->vlist_local[vertex].y*=vs->y;
    obj->vlist_local[vertex].z*=vs->z;
    // leave w unchanged, always equal to 1

    } // end for vertex

// now since the object is scaled we have to do something with 
// the radii calculation, but we don't know how the scaling
// factors relate to the original major axis of the object,
// therefore for scaling factors all ==1 we will simple multiply
// which is correct, but for scaling factors not equal to 1, we
// must take the largest scaling factor and use it to scale the
// radii with since it's the worst case scenario of the new max and
// average radii

// find max scaling factor
float scale = MAX(vs->x, vs->y);
scale = MAX(scale, vs->z);

// now scale
obj->max_radius*=scale;
obj->avg_radius*=scale;

} // end Scale_OBJECT4DV1

/////////////////////////////////////////////////////////////

void Build_XYZ_Rotation_MATRIX4X4(float theta_x, // euler angles
                                  float theta_y, 
                                  float theta_z,
                                  MATRIX4X4_PTR mrot) // output 
{
// this helper function takes a set if euler angles and computes
// a rotation matrix from them, usefull for object and camera
// work, also  we will do a little testing in the function to determine
// the rotations that need to be performed, since there's no
// reason to perform extra matrix multiplies if the angles are
// zero!

MATRIX4X4 mx, my, mz, mtmp;       // working matrices
float sin_theta=0, cos_theta=0;   // used to initialize matrices
int rot_seq = 0;                  // 1 for x, 2 for y, 4 for z

// step 0: fill in with identity matrix
MAT_IDENTITY_4X4(mrot);

// step 1: based on zero and non-zero rotation angles, determine
// rotation sequence
if (fabs(theta_x) > EPSILON_E5) // x
   rot_seq = rot_seq | 1;

if (fabs(theta_y) > EPSILON_E5) // y
   rot_seq = rot_seq | 2;

if (fabs(theta_z) > EPSILON_E5) // z
   rot_seq = rot_seq | 4;

// now case on sequence
switch(rot_seq)
      {
      case 0: // no rotation
      {
      // what a waste!
      return;
      } break;

      case 1: // x rotation
      {
      // compute the sine and cosine of the angle
      cos_theta = Fast_Cos(theta_x);
      sin_theta = Fast_Sin(theta_x);

      // set the matrix up 
      Mat_Init_4X4(&mx, 1,    0,          0,         0,
                        0,    cos_theta,  sin_theta, 0,
                        0,   -sin_theta, cos_theta, 0,
                        0,    0,          0,         1);

      // that's it, copy to output matrix
      MAT_COPY_4X4(&mx, mrot);
      return;

      } break;

      case 2: // y rotation
      {
      // compute the sine and cosine of the angle
      cos_theta = Fast_Cos(theta_y);
      sin_theta = Fast_Sin(theta_y);

      // set the matrix up 
      Mat_Init_4X4(&my,cos_theta, 0, -sin_theta, 0,  
                       0,         1,  0,         0,
                       sin_theta, 0, cos_theta,  0,
                       0,         0, 0,          1);


      // that's it, copy to output matrix
      MAT_COPY_4X4(&my, mrot);
      return;

      } break;

      case 3: // xy rotation
      {
      // compute the sine and cosine of the angle for x
      cos_theta = Fast_Cos(theta_x);
      sin_theta = Fast_Sin(theta_x);

      // set the matrix up 
      Mat_Init_4X4(&mx, 1,    0,          0,         0,
                        0,    cos_theta,  sin_theta, 0,
                        0,   -sin_theta, cos_theta, 0,
                        0,    0,          0,         1);

      // compute the sine and cosine of the angle for y
      cos_theta = Fast_Cos(theta_y);
      sin_theta = Fast_Sin(theta_y);

      // set the matrix up 
      Mat_Init_4X4(&my,cos_theta, 0, -sin_theta, 0,  
                       0,         1,  0,         0,
                       sin_theta, 0, cos_theta,  0,
                       0,         0, 0,          1);

      // concatenate matrices 
      Mat_Mul_4X4(&mx, &my, mrot);
      return;

      } break;

      case 4: // z rotation
      {
      // compute the sine and cosine of the angle
      cos_theta = Fast_Cos(theta_z);
      sin_theta = Fast_Sin(theta_z);

      // set the matrix up 
      Mat_Init_4X4(&mz, cos_theta, sin_theta, 0, 0,  
                       -sin_theta, cos_theta, 0, 0,
                        0,         0,         1, 0,
                        0,         0,         0, 1);


      // that's it, copy to output matrix
      MAT_COPY_4X4(&mz, mrot);
      return;

      } break;

      case 5: // xz rotation
      {
      // compute the sine and cosine of the angle x
      cos_theta = Fast_Cos(theta_x);
      sin_theta = Fast_Sin(theta_x);

      // set the matrix up 
      Mat_Init_4X4(&mx, 1,    0,          0,         0,
                        0,    cos_theta,  sin_theta, 0,
                        0,   -sin_theta, cos_theta, 0,
                        0,    0,          0,         1);

      // compute the sine and cosine of the angle z
      cos_theta = Fast_Cos(theta_z);
      sin_theta = Fast_Sin(theta_z);

      // set the matrix up 
      Mat_Init_4X4(&mz, cos_theta, sin_theta, 0, 0,  
                       -sin_theta, cos_theta, 0, 0,
                        0,         0,         1, 0,
                        0,         0,         0, 1);

      // concatenate matrices 
      Mat_Mul_4X4(&mx, &mz, mrot);
      return;

      } break;

      case 6: // yz rotation
      {
      // compute the sine and cosine of the angle y
      cos_theta = Fast_Cos(theta_y);
      sin_theta = Fast_Sin(theta_y);

      // set the matrix up 
      Mat_Init_4X4(&my,cos_theta, 0, -sin_theta, 0,  
                       0,         1,  0,         0,
                       sin_theta, 0, cos_theta,  0,
                       0,         0, 0,          1);

      // compute the sine and cosine of the angle z
      cos_theta = Fast_Cos(theta_z);
      sin_theta = Fast_Sin(theta_z);

      // set the matrix up 
      Mat_Init_4X4(&mz, cos_theta, sin_theta, 0, 0,  
                       -sin_theta, cos_theta, 0, 0,
                        0,         0,         1, 0,
                        0,         0,         0, 1);

      // concatenate matrices 
      Mat_Mul_4X4(&my, &mz, mrot);
      return;

      } break;

      case 7: // xyz rotation
      {
      // compute the sine and cosine of the angle x
      cos_theta = Fast_Cos(theta_x);
      sin_theta = Fast_Sin(theta_x);

      // set the matrix up 
      Mat_Init_4X4(&mx, 1,    0,         0,         0,
                        0,    cos_theta, sin_theta, 0,
                        0,   -sin_theta, cos_theta, 0,
                        0,    0,         0,         1);

      // compute the sine and cosine of the angle y
      cos_theta = Fast_Cos(theta_y);
      sin_theta = Fast_Sin(theta_y);

      // set the matrix up 
      Mat_Init_4X4(&my,cos_theta, 0, -sin_theta, 0,  
                       0,         1,  0,         0,
                       sin_theta, 0,  cos_theta,  0,
                       0,         0,  0,          1);

      // compute the sine and cosine of the angle z
      cos_theta = Fast_Cos(theta_z);
      sin_theta = Fast_Sin(theta_z);

      // set the matrix up 
      Mat_Init_4X4(&mz, cos_theta, sin_theta, 0, 0,  
                       -sin_theta, cos_theta, 0, 0,
                        0,         0,         1, 0,
                        0,         0,         0, 1);

      // concatenate matrices, watch order!
      Mat_Mul_4X4(&mx, &my, &mtmp);
      Mat_Mul_4X4(&mtmp, &mz, mrot);

      } break;

      default: break;
      
      } // end switch

} // end Build_XYZ_Rotation_MATRIX4X4                                    
 
///////////////////////////////////////////////////////////

void Build_Model_To_World_MATRIX4X4(VECTOR4D_PTR vpos, MATRIX4X4_PTR m)
{
// this function builds up a general local to world 
// transformation matrix that is really nothing more than a translation
// of the origin by the amount specified in vpos

Mat_Init_4X4(m, 1,       0,       0,       0, 
                0,       1,       0,       0, 
                0,       0,       1,       0,
                vpos->x, vpos->y, vpos->z, 1 );

} // end Build_Model_To_World_MATRIX4X4

//////////////////////////////////////////////////////////

void Build_Camera_To_Perspective_MATRIX4X4(CAM4DV1_PTR cam, MATRIX4X4_PTR m)
{
// this function builds up a camera to perspective transformation
// matrix, in most cases the camera would have a 2x2 normalized
// view plane with a 90 degree FOV, since the point of the having
// this matrix must be to also have a perspective to screen (viewport)
// matrix that scales the normalized coordinates, also the matrix
// assumes that you are working in 4D homogenous coordinates and at 
// some point there will be a 4D->3D conversion, it might be immediately
// after this transform is applied to vertices, or after the perspective
// to screen transform

Mat_Init_4X4(m, cam->view_dist, 0,                                0, 0, 
                0,              cam->view_dist*cam->aspect_ratio, 0, 0, 
                0,              0,                                1, 1,
                0,              0,                                0, 0);

} // end Build_Camera_To_Perspective_MATRIX4X4

///////////////////////////////////////////////////////////

void Build_Perspective_To_Screen_4D_MATRIX4X4(CAM4DV1_PTR cam, MATRIX4X4_PTR m)
{
// this function builds up a perspective to screen transformation
// matrix, the function assumes that you want to perform the
// transform in homogeneous coordinates and at raster time there will be 
// a 4D->3D homogenous conversion and of course only the x,y points
// will be considered for the 2D rendering, thus you would use this
// function's matrix is your perspective coordinates were still 
// in homgeneous form whene this matrix was applied, additionally
// the point of this matrix to to scale and translate the perspective
// coordinates to screen coordinates, thus the matrix is built up
// assuming that the perspective coordinates are in normalized form for
// a (2x2)/aspect_ratio viewplane, that is, x: -1 to 1, y:-1/aspect_ratio to 1/aspect_ratio

float alpha = (0.5*cam->viewport_width-0.5);
float beta  = (0.5*cam->viewport_height-0.5);

Mat_Init_4X4(m, alpha,   0,     0,    0, 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -