📄 t3dlib6.cpp
字号:
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 + -