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

📄 t3dlib6.cpp

📁 3D游戏编程大师技巧第九章的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
          obj->plist[poly].color = RGB16Bit(r, g, b);
          Write_Error("\nPolygon 16-bit");
          } // end if 
       else
          {
          // 8 bit mode
          SET_BIT(obj->plist[poly].attr,POLY4DV1_ATTR_8BITCOLOR);
          obj->plist[poly].color = RGBto8BitIndex(r,g,b, palette, 0);
          Write_Error("\nPolygon 8-bit, index=%d", obj->plist[poly].color);
          } // end else

       // for now manually set shading mode
       //SET_BIT(obj->plist[poly].attr, POLY4DV1_ATTR_SHADE_MODE_PURE);
       //SET_BIT(obj->plist[poly].attr, POLY4DV1_ATTR_SHADE_MODE_GOURAUD);
       //SET_BIT(obj->plist[poly].attr, POLY4DV1_ATTR_SHADE_MODE_PHONG);
       SET_BIT(obj->plist[poly].attr, POLY4DV1_ATTR_SHADE_MODE_FLAT);

       // set polygon to active
       obj->plist[poly].state = POLY4DV1_STATE_ACTIVE;    
       
       // found the material, break out of while for another pass
       break;

       } // end if
 
     } // end while      

     Write_Error("\nPolygon %d:", poly);
     Write_Error("\nSurface Desc = [RGB]=[%d, %d, %d], vert_indices [%d, %d, %d]", 
                                                         r,g,b,
                                                         obj->plist[poly].vert[0],
                                                         obj->plist[poly].vert[1],
                                                         obj->plist[poly].vert[2]);

    } // end for poly

// return success
return(1);

} // end Load_OBJECT4DV1_3DASC

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

int Load_OBJECT4DV1_COB(OBJECT4DV1_PTR obj,   // pointer to object
                        char *filename,       // filename of Caligari COB file
                        VECTOR4D_PTR scale,   // initial scaling factors
                        VECTOR4D_PTR pos,     // initial position
                        VECTOR4D_PTR rot,     // initial rotations
                        int vertex_flags)     // flags to re-order vertices 
                                              // and perform transforms
{
// this function loads a Caligari TrueSpace .COB file object in off disk, additionally
// it allows the caller to scale, position, and rotate the object
// to save extra calls later for non-dynamic objects, note that this function 
// works with a OBJECT4DV1 which has no support for textures, or materials, etc, however we will
// still parse them and get them ready for the next incarnation objects, so we can
// re-use this code to support those features

// create a parser object
CPARSERV1 parser; 

char seps[16];          // seperators for token scanning
char token_buffer[256]; // used as working buffer for token
char *token;            // pointer to next token

int r,g,b;              // working colors

// cache for texture vertices
VERTEX2DF texture_vertices[1024];

int num_texture_vertices = 0;

MATRIX4X4 mat_local,  // storage for local transform if user requests it in cob format
          mat_world;  // "   " for local to world " "

// initialize matrices
MAT_IDENTITY_4X4(&mat_local);
MAT_IDENTITY_4X4(&mat_world);

// Step 1: clear out the object and initialize it a bit
memset(obj, 0, sizeof(OBJECT4DV1));

// set state of object to active and visible
obj->state = OBJECT4DV1_STATE_ACTIVE | OBJECT4DV1_STATE_VISIBLE;

// set position of object is caller requested position
if (pos)
   {
   // set position of object
   obj->world_pos.x = pos->x;
   obj->world_pos.y = pos->y;
   obj->world_pos.z = pos->z;
   obj->world_pos.w = pos->w;
   } // end 
else
   {
   // set it to (0,0,0,1)
   obj->world_pos.x = 0;
   obj->world_pos.y = 0;
   obj->world_pos.z = 0;
   obj->world_pos.w = 1;
   } // end else

// Step 2: open the file for reading using the parser
if (!parser.Open(filename))
   {
   Write_Error("Couldn't open .COB file %s.", filename);
   return(0);
   } // end if

// Step 3: 

// lets find the name of the object first 
while(1)
     {
     // get the next line, we are looking for "Name"
     if (!parser.Getline(PARSER_STRIP_EMPTY_LINES | PARSER_STRIP_WS_ENDS))
        {
        Write_Error("Image 'name' not found in .COB file %s.", filename);
        return(0);
        } // end if
    
     // check for pattern?  
     if ( parser.Pattern_Match(parser.buffer, "['Name'] [s>0]") )
        {
        // name should be in second string variable, index 1
        strcpy(obj->name, parser.pstrings[1]);          
        Write_Error("\nCOB Reader Object Name: %s", obj->name);

        break;    
        } // end if

     } // end while


// step 4: get local and world transforms and store them

// center 0 0 0
// x axis 1 0 0
// y axis 0 1 0
// z axis 0 0 1

while(1)
     {
     // get the next line, we are looking for "center"
     if (!parser.Getline(PARSER_STRIP_EMPTY_LINES | PARSER_STRIP_WS_ENDS))
        {
        Write_Error("Center not found in .COB file %s.", filename);
        return(0);
        } // end if
    
     // check for pattern?  
     if ( parser.Pattern_Match(parser.buffer, "['center'] [f] [f] [f]") )
        {
        // the "center" holds the translation factors, so place in
        // last row of homogeneous matrix, note that these are row vectors
        // that we need to drop in each column of matrix
        mat_local.M[3][0] = -parser.pfloats[0]; // center x
        mat_local.M[3][1] = -parser.pfloats[1]; // center y
        mat_local.M[3][2] = -parser.pfloats[2]; // center z

        // ok now, the next 3 lines should be the x,y,z transform vectors
        // so build up   

        // "x axis" 
        parser.Getline(PARSER_STRIP_EMPTY_LINES | PARSER_STRIP_WS_ENDS);
        parser.Pattern_Match(parser.buffer, "['x'] ['axis'] [f] [f] [f]");
      
        // place row in x column of transform matrix
        mat_local.M[0][0] = parser.pfloats[0]; // rxx
        mat_local.M[1][0] = parser.pfloats[1]; // rxy
        mat_local.M[2][0] = parser.pfloats[2]; // rxz

        // "y axis" 
        parser.Getline(PARSER_STRIP_EMPTY_LINES | PARSER_STRIP_WS_ENDS);
        parser.Pattern_Match(parser.buffer, "['y'] ['axis'] [f] [f] [f]");
      
        // place row in y column of transform matrix
        mat_local.M[0][1] = parser.pfloats[0]; // ryx
        mat_local.M[1][1] = parser.pfloats[1]; // ryy
        mat_local.M[2][1] = parser.pfloats[2]; // ryz

        // "z axis" 
        parser.Getline(PARSER_STRIP_EMPTY_LINES | PARSER_STRIP_WS_ENDS);
        parser.Pattern_Match(parser.buffer, "['z'] ['axis'] [f] [f] [f]");
      
        // place row in z column of transform matrix
        mat_local.M[0][2] = parser.pfloats[0]; // rzx
        mat_local.M[1][2] = parser.pfloats[1]; // rzy
        mat_local.M[2][2] = parser.pfloats[2]; // rzz

        Print_Mat_4X4(&mat_local, "Local COB Matrix:");

        break;    
        } // end if

     } // end while

// now "Transform"
while(1)
     {
     // get the next line, we are looking for "Transform"
     if (!parser.Getline(PARSER_STRIP_EMPTY_LINES | PARSER_STRIP_WS_ENDS))
        {
        Write_Error("Transform not found in .COB file %s.", filename);
        return(0);
        } // end if
    
     // check for pattern?  
     if ( parser.Pattern_Match(parser.buffer, "['Transform']") )
        {

        // "x axis" 
        parser.Getline(PARSER_STRIP_EMPTY_LINES | PARSER_STRIP_WS_ENDS);
        parser.Pattern_Match(parser.buffer, "[f] [f] [f]");
      
        // place row in x column of transform matrix
        mat_world.M[0][0] = parser.pfloats[0]; // rxx
        mat_world.M[1][0] = parser.pfloats[1]; // rxy
        mat_world.M[2][0] = parser.pfloats[2]; // rxz

        // "y axis" 
        parser.Getline(PARSER_STRIP_EMPTY_LINES | PARSER_STRIP_WS_ENDS);
        parser.Pattern_Match(parser.buffer, "[f] [f] [f]");
      
        // place row in y column of transform matrix
        mat_world.M[0][1] = parser.pfloats[0]; // ryx
        mat_world.M[1][1] = parser.pfloats[1]; // ryy
        mat_world.M[2][1] = parser.pfloats[2]; // ryz

        // "z axis" 
        parser.Getline(PARSER_STRIP_EMPTY_LINES | PARSER_STRIP_WS_ENDS);
        parser.Pattern_Match(parser.buffer, "[f] [f] [f]");
      
        // place row in z column of transform matrix
        mat_world.M[0][2] = parser.pfloats[0]; // rzx
        mat_world.M[1][2] = parser.pfloats[1]; // rzy
        mat_world.M[2][2] = parser.pfloats[2]; // rzz

        Print_Mat_4X4(&mat_world, "World COB Matrix:");

        // no need to read in last row, since it's always 0,0,0,1 and we don't use it anyway
        break;    

        } // end if

     } // end while

// step 6: get number of vertices and polys in object
while(1)
     {
     // get the next line, we are looking for "World Vertices" 
     if (!parser.Getline(PARSER_STRIP_EMPTY_LINES | PARSER_STRIP_WS_ENDS))
        {
        Write_Error("'World Vertices' line not found in .COB file %s.", filename);
        return(0);
        } // end if
    
     // check for pattern?  
     if (parser.Pattern_Match(parser.buffer, "['World'] ['Vertices'] [i]") )
        {
        // simply extract the number of vertices from the pattern matching 
        // output arrays
        obj->num_vertices = parser.pints[0];

        Write_Error("\nCOB Reader Num Vertices: %d", obj->num_vertices);
        break;    
 
        } // end if

     } // end while

// Step 7: load the vertex list
// now read in vertex list, format:
// "d.d d.d d.d"
 for (int vertex = 0; vertex < obj->num_vertices; vertex++)
     {
     // hunt for vertex
     while(1)
     {
     // get the next vertex
     if (!parser.Getline(PARSER_STRIP_EMPTY_LINES | PARSER_STRIP_WS_ENDS))
        {
        Write_Error("\nVertex list ended abruptly! in .COB file %s.", filename);
        return(0);
        } // end if
    
     // check for pattern?  
     if (parser.Pattern_Match(parser.buffer, "[f] [f] [f]"))
        {
        // at this point we have the x,y,z in the the pfloats array locations 0,1,2
        obj->vlist_local[vertex].x = parser.pfloats[0];
        obj->vlist_local[vertex].y = parser.pfloats[1];
        obj->vlist_local[vertex].z = parser.pfloats[2];
        obj->vlist_local[vertex].w = 1;

        // do vertex swapping right here, allow muliple swaps, why not!
        // defines for vertex re-ordering flags

        //#define VERTEX_FLAGS_INVERT_X   1    // inverts the Z-coordinates
        //#define VERTEX_FLAGS_INVERT_Y   2    // inverts the Z-coordinates
        //#define VERTEX_FLAGS_INVERT_Z   4    // inverts the Z-coordinates
        //#define VERTEX_FLAGS_SWAP_YZ    8    // transforms a RHS model to a LHS model
        //#define VERTEX_FLAGS_SWAP_XZ    16   // ???
        //#define VERTEX_FLAGS_SWAP_XY    32
        //#define VERTEX_FLAGS_INVERT_WINDING_ORDER 64  // invert winding order from cw to ccw or ccw to cc
        //#define VERTEX_FLAGS_TRANSFORM_LOCAL         512   // if file format has local transform then do it!
        //#define VERTEX_FLAGS_TRANSFORM_LOCAL_WORLD  1024  // if file format has local to world then do it!

        VECTOR4D temp_vector; // temp for calculations

        // now apply local and world transformations encoded in COB format
        if (vertex_flags & VERTEX_FLAGS_TRANSFORM_LOCAL )
           {
           Mat_Mul_VECTOR4D_4X4(&obj->vlist_local[vertex], &mat_local, &temp_vector);
           VECTOR4D_COPY(&obj->vlist_local[vertex], &temp_vector); 
           } // end if 

        if (vertex_flags & VERTEX_FLAGS_TRANSFORM_LOCAL_WORLD )
           {
           Mat_Mul_VECTOR4D_4X4(&obj->vlist_local[vertex], &mat_world, &temp_vector);
           VECTOR4D_COPY(&obj->vlist_local[vertex], &temp_vector); 
           } // end if 

        float temp_f; // used for swapping

        // invert signs?
        if (vertex_flags & VERTEX_FLAGS_INVERT_X)
           obj->vlist_local[vertex].x=-obj->vlist_local[vertex].x;

        if (vertex_flags & VERTEX_FLAGS_INVERT_Y)
           obj->vlist_local[vertex].y=-obj->vlist_local[vertex].y;

        if (vertex_flags & VERTEX_FLAGS_INVERT_Z)
           obj->vlist_local[vertex].z=-obj->vlist_local[vertex].z;

        // swap any axes?
        if (vertex_flags & VERTEX_FLAGS_SWAP_YZ)
           SWAP(obj->vlist_local[vertex].y, obj->vlist_local[vertex].z, temp_f);
        
        if (vertex_flags & VERTEX_FLAGS_SWAP_XZ)
           SWAP(obj->vlist_local[vertex].x, obj->vlist_local[vertex].z, temp_f);

        if (vertex_flags & VERTEX_FLAGS_SWAP_XY)
           SWAP(obj->vlist_local[vertex].x, obj->vlist_local[vertex].y, temp_f);

        // scale vertices
        if (scale)
           {
           obj->vlist_local[vertex].x*=scale->x;
           obj->vlist_local[vertex].y*=scale->y;
           obj->vlist_local[vertex].z*=scale->z;
           } // end if

          Write_Error("\nVertex %d = %f, %f, %f, %f", vertex,
                                           obj->vlist_local[vertex].x, 
                                           obj->vlist_local[vertex].y, 
                                           obj->vlist_local[vertex].z,
                                           obj->vlist_local[vertex].w);

        // found vertex, break out of while for next pass
        break;

        } // end if

    } // end while

    } // end for vertex

// compute average and max radius
Compute_OBJECT4DV1_Radius(obj);

Write_Error("\nObject average radius = %f, max radius = %f", 
            obj->avg_radius, obj->max_radius);


// step 8: get number of texture vertices
while(1)
     {
     // get the next line, we are looking for "Texture Vertices ddd" 
     if (!parser.Getline(PARSER_STRIP_EMPTY_LINES | PARSER_STRIP_WS_ENDS))
        {
        Write_Error("'Texture Vertices' line not found in .COB file %s.", filename);
        return(0);
        } // end if
    
     // check for pattern?  
     if (parser.Pattern_Match(parser.buffer, "['Texture'] ['Vertices'] [i]") )
        {
        /

⌨️ 快捷键说明

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