It's a function that transforms vertices from a specific model and adds them to the ordering table.
Not optimized yet and messy due to constant format changes and idea changes and it's format specific.
Code: Select all
u_char * SGM_UpdateModel(SGM_MDL * model, u_char * packet_ptr, u_long * ot) {
int i;
SGM_FILE * data = model->file;
SGM_DATAHEADER * dh = data->dh;
u_short tpageid;
u_short clutid;
// Transformation Data
long p, otz, opz, flg;
int temp, temp2, temp3;
int isfront;
DIVPOLYGON4 divprop;
POLY_GT4_VERTEX * vtx_src_gt4;
POLY_GT4_TEX * tex_src_gt4;
POLY_GT4_COLOR * col_src_gt4;
POLY_GT3_VERTEX * vtx_src_gt3;
POLY_GT3_TEX * tex_src_gt3;
POLY_GT3_COLOR * col_src_gt3;
POLY_GT4 * vtx_dest_gt4;
POLY_GT3 * vtx_dest_gt3;
POLY_G4 * vtx_dest_g4;
POLY_G3 * vtx_dest_g3;
u_char * packet = packet_ptr;
divprop.pih = SCREEN_W;
divprop.piv = SCREEN_H;
divprop.ndiv = 1;
vtx_dest_gt4 = (POLY_GT4*)packet;
tpageid = getTPage(1, 0, 0,0);
clutid = GetClut(0,256);
vtx_src_gt4 = data->pgt4_vtx;
for(i = 0; i < model->file->dh->poly_gt4_count; i++, vtx_src_gt4++) {
// Initialize destination poly
setPolyGT4(vtx_dest_gt4);
// Transform destination poly
gte_RotAverageNclip3(
(SVECTOR*)&vtx_src_gt4->v0,
(SVECTOR*)&vtx_src_gt4->v1,
(SVECTOR*)&vtx_src_gt4->v2,
(long *)&vtx_dest_gt4->x0, (long *)&vtx_dest_gt4->x1,
(long *)&vtx_dest_gt4->x2, &p, &otz, &flg, &isfront);
otz = otz >> 1;
// Check side
if(isfront <= 0) continue;
// Only transform 4th vector if facing towards the view
gte_RotTransPers((SVECTOR*)&vtx_src_gt4->v3,(long *)&vtx_dest_gt4->x3, &temp2, &temp3, &temp);
// Clip quads that are offscreen
if(quad_clip(&G.screen_rect,
(DVECTOR*)&vtx_dest_gt4->x0,
(DVECTOR*)&vtx_dest_gt4->x1,
(DVECTOR*)&vtx_dest_gt4->x2,
(DVECTOR*)&vtx_dest_gt4->x3)) continue;
// If on screen, now process the rest of the primitive.
tex_src_gt4 = &data->pgt4_uv[i];
col_src_gt4 = &data->pgt4_col[i];
// Set Vertex Colors
memcpy(&vtx_dest_gt4->r0, &col_src_gt4->r0, sizeof(u_char) * 3);
memcpy(&vtx_dest_gt4->r1, &col_src_gt4->r1, sizeof(u_char) * 3);
memcpy(&vtx_dest_gt4->r2, &col_src_gt4->r2, sizeof(u_char) * 3);
memcpy(&vtx_dest_gt4->r3, &col_src_gt4->r3, sizeof(u_char) * 3);
// Set Texture Coordinates
memcpy(&vtx_dest_gt4->u0, &tex_src_gt4->u0, sizeof(u_char) * 2);
memcpy(&vtx_dest_gt4->u1, &tex_src_gt4->u1, sizeof(u_char) * 2);
memcpy(&vtx_dest_gt4->u2, &tex_src_gt4->u2, sizeof(u_char) * 2);
memcpy(&vtx_dest_gt4->u3, &tex_src_gt4->u3, sizeof(u_char) * 2);
// Set CLUT
vtx_dest_gt4->clut = clutid;
// Set Texture Page
vtx_dest_gt4->tpage = tpageid;
if (otz > 0 && otz < OTSIZE)
{
// Check for subdivision
if( otz < 600 ) {
if(otz > 300) {
divprop.ndiv = 1;
debug_face_count += 8;
} else {
divprop.ndiv = 1;
debug_face_count += 8;
}
debug_subdiv_count += 1;
// Subdivide poly
vtx_dest_gt4 = DivideGT4(
(SVECTOR*)&vtx_src_gt4->v0, (SVECTOR*)&vtx_src_gt4->v1, (SVECTOR*)&vtx_src_gt4->v2, (SVECTOR*)&vtx_src_gt4->v3,
(u_long*)&vtx_dest_gt4->u0, (u_long*)&vtx_dest_gt4->u1, (u_long*)&vtx_dest_gt4->u2, (u_long*)&vtx_dest_gt4->u3,
(CVECTOR*)&vtx_dest_gt4->r0, (CVECTOR*)&vtx_dest_gt4->r1, (CVECTOR*)&vtx_dest_gt4->r2, (CVECTOR*)&vtx_dest_gt4->r3,
vtx_dest_gt4, (u_long *)(ot+otz), &divprop);
} else {
// Add primitive to Ordering Table and advance pointer
// to point to the next primitive to be processed.
AddPrim(ot+otz, vtx_dest_gt4++);
debug_face_count += 2;
}
}
}
vtx_dest_gt3 = (POLY_GT3*)vtx_dest_gt4;
vtx_src_gt3 = data->pgt3_vtx;
for(i = 0; i < model->file->dh->poly_gt3_count; i++, vtx_src_gt3++) {
// Initialize destination poly
setPolyGT3(vtx_dest_gt3);
// Transform destination poly
gte_RotAverageNclip3(
(SVECTOR*)&vtx_src_gt3->v0,
(SVECTOR*)&vtx_src_gt3->v1,
(SVECTOR*)&vtx_src_gt3->v2,
(long *)&vtx_dest_gt3->x0, (long *)&vtx_dest_gt3->x1,
(long *)&vtx_dest_gt3->x2, &p, &otz, &flg, &isfront);
otz = otz >> 1;
// Check side
if(isfront <= 0) continue;
// Clip quads that are offscreen
if(tri_clip(&G.screen_rect,
(DVECTOR*)&vtx_dest_gt3->x0,
(DVECTOR*)&vtx_dest_gt3->x1,
(DVECTOR*)&vtx_dest_gt3->x2)) continue;
// If on screen, now process the rest of the primitive.
tex_src_gt3 = &data->pgt3_uv[i];
col_src_gt3 = &data->pgt3_col[i];
// Set Vertex Colors
memcpy(&vtx_dest_gt3->r0, &col_src_gt3->r0, sizeof(u_char) * 3);
memcpy(&vtx_dest_gt3->r1, &col_src_gt3->r1, sizeof(u_char) * 3);
memcpy(&vtx_dest_gt3->r2, &col_src_gt3->r2, sizeof(u_char) * 3);
// Set Texture Coordinates
memcpy(&vtx_dest_gt3->u0, &tex_src_gt3->u0, sizeof(u_char) * 2);
memcpy(&vtx_dest_gt3->u1, &tex_src_gt3->u1, sizeof(u_char) * 2);
memcpy(&vtx_dest_gt3->u2, &tex_src_gt3->u2, sizeof(u_char) * 2);
// Set CLUT
vtx_dest_gt3->clut = clutid;
// Set Texture Page
vtx_dest_gt3->tpage = tpageid;
if (otz > 0 && otz < OTSIZE)
{
// Add primitive to Ordering Table and advance pointer
// to point to the next primitive to be processed.
AddPrim(ot+otz, vtx_dest_gt3++);
debug_face_count += 1;
}
}
vtx_dest_g4 = (POLY_G4 *) vtx_dest_gt3;
vtx_src_gt4 = data->pg4_vtx;
for(i = 0; i < model->file->dh->poly_g4_count; i++, vtx_src_gt4++) {
// Initialize destination poly
setPolyG4(vtx_dest_g4);
// Transform destination poly
gte_RotAverageNclip3(
(SVECTOR*)&vtx_src_gt4->v0,
(SVECTOR*)&vtx_src_gt4->v1,
(SVECTOR*)&vtx_src_gt4->v2,
(long *)&vtx_dest_g4->x0, (long *)&vtx_dest_g4->x1,
(long *)&vtx_dest_g4->x2, &p, &otz, &flg, &isfront);
otz = otz >> 1;
// Check side
if(isfront <= 0) continue;
// Only transform 4th vector if facing towards the view
gte_RotTransPers((SVECTOR*)&vtx_src_gt4->v3,(long *)&vtx_dest_g4->x3, &temp2, &temp3, &temp);
// Clip quads that are offscreen
if(quad_clip(&G.screen_rect,
(DVECTOR*)&vtx_dest_g4->x0,
(DVECTOR*)&vtx_dest_g4->x1,
(DVECTOR*)&vtx_dest_g4->x2,
(DVECTOR*)&vtx_dest_g4->x3)) continue;
// If on screen, now process the rest of the primitive.
col_src_gt4 = &data->pg4_col[i];
// Set Vertex Colors
memcpy(&vtx_dest_g4->r0, &col_src_gt4->r0, sizeof(u_char) * 3);
memcpy(&vtx_dest_g4->r1, &col_src_gt4->r1, sizeof(u_char) * 3);
memcpy(&vtx_dest_g4->r2, &col_src_gt4->r2, sizeof(u_char) * 3);
memcpy(&vtx_dest_g4->r3, &col_src_gt4->r3, sizeof(u_char) * 3);
if (otz > 0 && otz < OTSIZE)
{
// Add primitive to Ordering Table and advance pointer
// to point to the next primitive to be processed.
AddPrim(ot+otz, vtx_dest_g4++);
debug_face_count += 2;
}
}
vtx_dest_g3 = (POLY_G3*)vtx_dest_g4;
vtx_src_gt3 = data->pg3_vtx;
for(i = 0; i < model->file->dh->poly_g3_count; i++, vtx_src_gt3++) {
// Initialize destination poly
setPolyG3(vtx_dest_g3);
// Transform destination poly
gte_RotAverageNclip3(
(SVECTOR*)&vtx_src_gt3->v0,
(SVECTOR*)&vtx_src_gt3->v1,
(SVECTOR*)&vtx_src_gt3->v2,
(long *)&vtx_dest_g3->x0, (long *)&vtx_dest_g3->x1,
(long *)&vtx_dest_g3->x2, &p, &otz, &flg, &isfront);
otz = otz >> 1;
// Check side
if(isfront <= 0) continue;
// Clip quads that are offscreen
if(tri_clip(&G.screen_rect,
(DVECTOR*)&vtx_dest_g3->x0,
(DVECTOR*)&vtx_dest_g3->x1,
(DVECTOR*)&vtx_dest_g3->x2)) continue;
// If on screen, now process the rest of the primitive.
col_src_gt3 = &data->pg3_col[i];
// Set Vertex Colors
memcpy(&vtx_dest_g3->r0, &col_src_gt3->r0, sizeof(u_char) * 3);
memcpy(&vtx_dest_g3->r1, &col_src_gt3->r1, sizeof(u_char) * 3);
memcpy(&vtx_dest_g3->r2, &col_src_gt3->r2, sizeof(u_char) * 3);
if (otz > 0 && otz < OTSIZE)
{
// Add primitive to Ordering Table and advance pointer
// to point to the next primitive to be processed.
AddPrim(ot+otz, vtx_dest_g3++);
debug_face_count += 1;
}
}
packet = (u_char *) vtx_dest_g3;
// return the updated packet pointer
return packet;
}
It initializes new polygons on the fly it can be used for instancing, like the wiggling boxes I made, they are the same model.