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

📄 t3dlib7.cpp

📁 3D游戏编程大师技巧第九章的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        // average radii,  the ONLY reason we do this is to keep the function
        // fast, you may want to recompute the radii if you need the accuracy

    for (int curr_frame = 0; curr_frame < obj->num_frames; curr_frame++)
        {
        // find max scaling factor
        float scale = MAX(vs->x, vs->y);
        scale = MAX(scale, vs->z);

        // now scale
        obj->max_radius[curr_frame]*=scale;
        obj->avg_radius[curr_frame]*=scale;
        } // for

   } // end else
                      
// now scale the polygon normals
for (int poly=0; poly < obj->num_polys; poly++)
    {
    obj->plist[poly].nlength*=(vs->x * vs->y * vs->z);
    } // end for poly

} // end Scale_OBJECT4DV2

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

void Transform_OBJECT4DV2(OBJECT4DV2_PTR obj,  // object to transform
                          MATRIX4X4_PTR mt,    // transformation matrix
                          int coord_select,    // selects coords to transform
                          int transform_basis, // flags if vector orientation
                                               // should be transformed too
                          int all_frames)      // should all frames be transformed

{
// this function simply transforms all of the vertices in the local or trans
// array by the sent matrix, since the object may have multiple frames, it
// takes that into consideration
// also vertex normals are rotated, however, if there is a translation factor
// in the sent matrix that will corrupt the normals, later we might want to
// null out the last row of the matrix before transforming the normals?
// future optimization: set flag in object attributes, and objects without 
// vertex normals can be rotated without the test in line


// single frame or all frames?
if (!all_frames)
{
// what coordinates should be transformed?
switch(coord_select)
      {
      case TRANSFORM_LOCAL_ONLY:
      {
      // transform each local/model vertex of the object mesh in place
      for (int vertex=0; vertex < obj->num_vertices; vertex++)
          {
          POINT4D presult; // hold result of each transformation

          // transform point
          Mat_Mul_VECTOR4D_4X4(&obj->vlist_local[vertex].v, mt, &presult);

          // store result back
          VECTOR4D_COPY(&obj->vlist_local[vertex].v, &presult); 
 
          // transform vertex normal if needed
          if (obj->vlist_local[vertex].attr & VERTEX4DTV1_ATTR_NORMAL)
             {
             // transform normal
             Mat_Mul_VECTOR4D_4X4(&obj->vlist_local[vertex].n, mt, &presult);

             // store result back
             VECTOR4D_COPY(&obj->vlist_local[vertex].n, &presult); 
             } // end if

          } // end for index
      } break;
 
      case TRANSFORM_TRANS_ONLY:
      {
      // transform each "transformed" vertex of the object mesh in place
      // remember, the idea of the vlist_trans[] array is to accumulate
      // transformations
      for (int vertex=0; vertex < obj->num_vertices; vertex++)
          {
          POINT4D presult; // hold result of each transformation

          // transform point
          Mat_Mul_VECTOR4D_4X4(&obj->vlist_trans[vertex].v, mt, &presult);

          // store result back
          VECTOR4D_COPY(&obj->vlist_trans[vertex].v, &presult); 

          // transform vertex normal if needed
          if (obj->vlist_trans[vertex].attr & VERTEX4DTV1_ATTR_NORMAL)
             {
             // transform normal
             Mat_Mul_VECTOR4D_4X4(&obj->vlist_trans[vertex].n, mt, &presult);

             // store result back
             VECTOR4D_COPY(&obj->vlist_trans[vertex].n, &presult); 
             } // end if

          } // end for index

      } break;

      case TRANSFORM_LOCAL_TO_TRANS:
      {
      // transform each local/model vertex of the object mesh and store result
      // in "transformed" vertex list
      for (int vertex=0; vertex < obj->num_vertices; vertex++)
          {
          POINT4D presult; // hold result of each transformation

          // transform point
          Mat_Mul_VECTOR4D_4X4(&obj->vlist_local[vertex].v, mt, &obj->vlist_trans[vertex].v);

          // transform vertex normal if needed
          if (obj->vlist_local[vertex].attr & VERTEX4DTV1_ATTR_NORMAL)
             {
             // transform point
             Mat_Mul_VECTOR4D_4X4(&obj->vlist_local[vertex].n, mt, &obj->vlist_trans[vertex].n);
             } // end if

          } // end for index
      } break;

      default: break;

      } // end switch

} // end if single frame
else // transform all frames
{
// what coordinates should be transformed?
switch(coord_select)
      {
      case TRANSFORM_LOCAL_ONLY:
      {
      // transform each local/model vertex of the object mesh in place
      for (int vertex=0; vertex < obj->total_vertices; vertex++)
          {
          POINT4D presult; // hold result of each transformation

          // transform point
          Mat_Mul_VECTOR4D_4X4(&obj->head_vlist_local[vertex].v, mt, &presult);

          // store result back
          VECTOR4D_COPY(&obj->head_vlist_local[vertex].v, &presult); 

          // transform vertex normal if needed
          if (obj->head_vlist_local[vertex].attr & VERTEX4DTV1_ATTR_NORMAL)
             {
             // transform normal
             Mat_Mul_VECTOR4D_4X4(&obj->head_vlist_local[vertex].n, mt, &presult);

             // store result back
             VECTOR4D_COPY(&obj->head_vlist_local[vertex].n, &presult); 
             } // end if


          } // end for index
      } break;
 
      case TRANSFORM_TRANS_ONLY:
      {
      // transform each "transformed" vertex of the object mesh in place
      // remember, the idea of the vlist_trans[] array is to accumulate
      // transformations
      for (int vertex=0; vertex < obj->total_vertices; vertex++)
          {
          POINT4D presult; // hold result of each transformation

          // transform point
          Mat_Mul_VECTOR4D_4X4(&obj->head_vlist_trans[vertex].v, mt, &presult);

          // store result back
          VECTOR4D_COPY(&obj->head_vlist_trans[vertex].v, &presult); 

          // transform vertex normal if needed
          if (obj->head_vlist_trans[vertex].attr & VERTEX4DTV1_ATTR_NORMAL)
             {
             // transform normal
             Mat_Mul_VECTOR4D_4X4(&obj->head_vlist_trans[vertex].n, mt, &presult);

             // store result back
             VECTOR4D_COPY(&obj->head_vlist_trans[vertex].n, &presult); 
             } // end if

          } // end for index

      } break;

      case TRANSFORM_LOCAL_TO_TRANS:
      {
      // transform each local/model vertex of the object mesh and store result
      // in "transformed" vertex list
      for (int vertex=0; vertex < obj->total_vertices; vertex++)
          {
          POINT4D presult; // hold result of each transformation

          // transform point
          Mat_Mul_VECTOR4D_4X4(&obj->head_vlist_local[vertex].v, mt, &obj->head_vlist_trans[vertex].v);

          // transform vertex normal if needed
          if (obj->head_vlist_local[vertex].attr & VERTEX4DTV1_ATTR_NORMAL)
             {
             // transform point
             Mat_Mul_VECTOR4D_4X4(&obj->head_vlist_local[vertex].n, mt, &obj->head_vlist_trans[vertex].n);
             } // end if

          } // end for index
      } break;

      default: break;

      } // end switch

} // end else multiple frames

// finally, test if transform should be applied to orientation basis
// hopefully this is a rotation, otherwise the basis will get corrupted
if (transform_basis)
   {
   // now rotate orientation basis for object
   VECTOR4D vresult; // use to rotate each orientation vector axis

   // rotate ux of basis
   Mat_Mul_VECTOR4D_4X4(&obj->ux, mt, &vresult);
   VECTOR4D_COPY(&obj->ux, &vresult); 

   // rotate uy of basis
   Mat_Mul_VECTOR4D_4X4(&obj->uy, mt, &vresult);
   VECTOR4D_COPY(&obj->uy, &vresult); 

   // rotate uz of basis
   Mat_Mul_VECTOR4D_4X4(&obj->uz, mt, &vresult);
   VECTOR4D_COPY(&obj->uz, &vresult); 
   } // end if

} // end Transform_OBJECT4DV2

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

void Rotate_XYZ_OBJECT4DV2(OBJECT4DV2_PTR obj, // object to rotate
                          float theta_x,       // euler angles
                          float theta_y, 
                          float theta_z,
                          int all_frames) // process all frames
{
// this function rotates and object parallel to the
// XYZ axes in that order or a subset thereof, without
// matrices (at least externally sent)
// modifies the object's local vertex list 
// additionally it rotates the unit directional vectors
// that track the objects orientation, also note that each
// time this function is called it calls the rotation generation
// function, this is wastefull if a number of object are being rotated
// by the same matrix, therefore, if that's the case, then generate the
// rotation matrix, store it, and call the general Transform_OBJECT4DV2()
// with the matrix
// also vertex normals are rotated by the matrix

// future optimization: set flag in object attributes, and objects without 
// vertex normals can be rotated without the test in line
 
MATRIX4X4 mrot; // used to store generated rotation matrix

// generate rotation matrix, no way to avoid rotation with a matrix
// too much math to do manually!
Build_XYZ_Rotation_MATRIX4X4(theta_x, theta_y, theta_z, &mrot);

// single or multi frames
if (!all_frames)
{
// now simply rotate each point of the mesh in local/model coordinates
for (int vertex=0; vertex < obj->num_vertices; vertex++)
    {
    POINT4D presult; // hold result of each transformation

    // transform point
    Mat_Mul_VECTOR4D_4X4(&obj->vlist_local[vertex].v, &mrot, &presult);

    // store result back
    VECTOR4D_COPY(&obj->vlist_local[vertex].v, &presult); 

    // test for vertex normal
    if (obj->vlist_local[vertex].attr & VERTEX4DTV1_ATTR_NORMAL)
       {
       // transform point
       Mat_Mul_VECTOR4D_4X4(&obj->vlist_local[vertex].n, &mrot, &presult);

       // store result back
       VECTOR4D_COPY(&obj->vlist_local[vertex].n, &presult); 
       } // end if

    } // end for index

} // end if single frame
else
{ // process all frames
// now simply rotate each point of the mesh in local/model coordinates
for (int vertex=0; vertex < obj->total_vertices; vertex++)
    {
    POINT4D presult; // hold result of each transformation

    // transform point
    Mat_Mul_VECTOR4D_4X4(&obj->head_vlist_local[vertex].v, &mrot, &presult);

    // store result back
    VECTOR4D_COPY(&obj->head_vlist_local[vertex].v, &presult); 

    // test for vertex normal
    if (obj->head_vlist_local[vertex].attr & VERTEX4DTV1_ATTR_NORMAL)
       {
       // transform point
       Mat_Mul_VECTOR4D_4X4(&obj->head_vlist_local[vertex].n, &mrot, &presult);

       // store result back
       VECTOR4D_COPY(&obj->head_vlist_local[vertex].n, &presult); 
       } // end if

    } // end for index

} // end else all frames

// now rotate orientation basis for object
VECTOR4D vresult; // use to rotate each orientation vector axis

// rotate ux of basis
Mat_Mul_VECTOR4D_4X4(&obj->ux, &mrot, &vresult);
VECTOR4D_COPY(&obj->ux, &vresult); 

// rotate uy of basis
Mat_Mul_VECTOR4D_4X4(&obj->uy, &mrot, &vresult);
VECTOR4D_COPY(&obj->uy, &vresult); 

// rotate uz of basis
Mat_Mul_VECTOR4D_4X4(&obj->uz, &mrot, &vresult);
VECTOR4D_COPY(&obj->uz, &vresult); 

} // end Rotate_XYZ_OBJECT4DV2

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

void Model_To_World_OBJECT4DV2(OBJECT4DV2_PTR obj, 
                               int coord_select, 

⌨️ 快捷键说明

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