* picomodel: fix md2 loader

duplicates management algorithm isn't as quick, as in old code, but quick nuff + working
This commit is contained in:
Garux 2019-02-22 23:29:04 +03:00
parent aa6e80f5a4
commit ff4260c75a

View File

@ -64,17 +64,8 @@ typedef struct index_LUT_s
{ {
short Vert; short Vert;
short ST; short ST;
struct index_LUT_s *next;
} index_LUT_t; } index_LUT_t;
typedef struct index_DUP_LUT_s
{
short ST;
short OldVert;
} index_DUP_LUT_t;
typedef struct typedef struct
{ {
short s; short s;
@ -329,9 +320,8 @@ static int _md2_canload( PM_PARAMS_CANLOAD ){
static picoModel_t *_md2_load( PM_PARAMS_LOAD ){ static picoModel_t *_md2_load( PM_PARAMS_LOAD ){
int i, j, dups, dup_index; int i, j, k, dups;
index_LUT_t *p_index_LUT, *p_index_LUT2, *p_index_LUT3; index_LUT_t *p_index_LUT;
index_DUP_LUT_t *p_index_LUT_DUPS;
md2Triangle_t *p_md2Triangle; md2Triangle_t *p_md2Triangle;
char skinname[ MD2_MAX_SKINNAME + 1 ]; char skinname[ MD2_MAX_SKINNAME + 1 ];
@ -481,9 +471,10 @@ static picoModel_t *_md2_load( PM_PARAMS_LOAD ){
{ {
p_index_LUT[i].Vert = -1; p_index_LUT[i].Vert = -1;
p_index_LUT[i].ST = -1; p_index_LUT[i].ST = -1;
p_index_LUT[i].next = NULL;
} }
index_LUT_t* p_index_LUT_dups = _pico_alloc( sizeof( index_LUT_t ) * md2->numTris * 3 ); //overallocating
// Fill in Look Up Table, and allocate/fill Linked List from vert array as needed for dup STs per Vert. // Fill in Look Up Table, and allocate/fill Linked List from vert array as needed for dup STs per Vert.
dups = 0; dups = 0;
for ( i = 0; i < md2->numTris; i++ ) for ( i = 0; i < md2->numTris; i++ )
@ -491,78 +482,37 @@ static picoModel_t *_md2_load( PM_PARAMS_LOAD ){
p_md2Triangle = (md2Triangle_t *) ( bb + md2->ofsTris + ( sizeof( md2Triangle_t ) * i ) ); p_md2Triangle = (md2Triangle_t *) ( bb + md2->ofsTris + ( sizeof( md2Triangle_t ) * i ) );
for ( j = 0; j < 3; j++ ) for ( j = 0; j < 3; j++ )
{ {
if ( p_index_LUT[p_md2Triangle->index_xyz[j]].ST == -1 ) { // No Main Entry const short iXYZ = p_md2Triangle->index_xyz[j];
p_index_LUT[p_md2Triangle->index_xyz[j]].ST = p_md2Triangle->index_st[j]; const short iST = p_md2Triangle->index_st[j];
if ( p_index_LUT[iXYZ].ST == -1 ) { // No Main Entry
p_index_LUT[iXYZ].ST = iST;
p_index_LUT[iXYZ].Vert = iXYZ;
} }
else if ( p_md2Triangle->index_st[j] == p_index_LUT[p_md2Triangle->index_xyz[j]].ST ) { // Equal to Main Entry else if ( iST == p_index_LUT[iXYZ].ST && iXYZ == p_index_LUT[iXYZ].Vert ) { // Equal to Main Entry
continue; continue;
} }
else if ( ( p_index_LUT[p_md2Triangle->index_xyz[j]].next == NULL ) ) { // Not equal to Main entry, and no LL entry else{
// Add first entry of LL from Main for( k = 0; k < dups; k++ ){ //search in dups
p_index_LUT2 = (index_LUT_t *)_pico_alloc( sizeof( index_LUT_t ) ); if( iST == p_index_LUT_dups[k].ST && iXYZ == p_index_LUT_dups[k].Vert ){
if ( p_index_LUT2 == NULL ) { p_md2Triangle->index_xyz[j] = k + md2->numXYZ; // Make change in Tri hunk
_pico_printf( PICO_ERROR," Couldn't allocate memory!\n" ); p_md2Triangle->index_st[j] = k + md2->numXYZ; // Make change in Tri hunk
break;
} }
p_index_LUT[p_md2Triangle->index_xyz[j]].next = (index_LUT_t *)p_index_LUT2; }
p_index_LUT2->Vert = dups;
p_index_LUT2->ST = p_md2Triangle->index_st[j]; if( k == dups ){ //add new
p_index_LUT2->next = NULL; p_index_LUT_dups[dups].ST = iST;
p_index_LUT_dups[dups].Vert = iXYZ;
p_md2Triangle->index_xyz[j] = dups + md2->numXYZ; // Make change in Tri hunk p_md2Triangle->index_xyz[j] = dups + md2->numXYZ; // Make change in Tri hunk
dups++; p_md2Triangle->index_st[j] = dups + md2->numXYZ; // Make change in Tri hunk
} ++dups;
else // Try to find in LL from Main Entry
{
p_index_LUT3 = p_index_LUT2 = p_index_LUT[p_md2Triangle->index_xyz[j]].next;
while ( ( p_index_LUT2 != NULL ) && ( p_md2Triangle->index_xyz[j] != p_index_LUT2->Vert ) ) // Walk down LL
{
p_index_LUT3 = p_index_LUT2;
p_index_LUT2 = p_index_LUT2->next;
}
p_index_LUT2 = p_index_LUT3;
if ( p_md2Triangle->index_st[j] == p_index_LUT2->ST ) { // Found it
p_md2Triangle->index_xyz[j] = p_index_LUT2->Vert + md2->numXYZ; // Make change in Tri hunk
continue;
}
if ( p_index_LUT2->next == NULL ) { // Didn't find it. Add entry to LL.
// Add the Entry
p_index_LUT3 = (index_LUT_t *)_pico_alloc( sizeof( index_LUT_t ) );
if ( p_index_LUT3 == NULL ) {
_pico_printf( PICO_ERROR," Couldn't allocate memory!\n" );
}
p_index_LUT2->next = (index_LUT_t *)p_index_LUT3;
p_index_LUT3->Vert = p_md2Triangle->index_xyz[j];
p_index_LUT3->ST = p_md2Triangle->index_st[j];
p_index_LUT3->next = NULL;
p_md2Triangle->index_xyz[j] = dups + md2->numXYZ; // Make change in Tri hunk
dups++;
} }
} }
} }
} }
// malloc and build array for Dup STs
p_index_LUT_DUPS = (index_DUP_LUT_t *)_pico_alloc( sizeof( index_DUP_LUT_t ) * dups );
if ( p_index_LUT_DUPS == NULL ) {
_pico_printf( PICO_ERROR," Couldn't allocate memory!\n" );
}
dup_index = 0;
for ( i = 0; i < md2->numXYZ; i++ )
{
p_index_LUT2 = p_index_LUT[i].next;
while ( p_index_LUT2 != NULL )
{
p_index_LUT_DUPS[p_index_LUT2->Vert].OldVert = i;
p_index_LUT_DUPS[p_index_LUT2->Vert].ST = p_index_LUT2->ST;
dup_index++;
p_index_LUT2 = p_index_LUT2->next;
}
}
// Build Picomodel // Build Picomodel
triangle = (md2Triangle_t *) ( (picoByte_t *) ( bb + md2->ofsTris ) ); triangle = (md2Triangle_t *) ( (picoByte_t *) ( bb + md2->ofsTris ) );
texCoord = (md2St_t*) ( (picoByte_t *) ( bb + md2->ofsST ) ); texCoord = (md2St_t*) ( (picoByte_t *) ( bb + md2->ofsST ) );
@ -597,53 +547,35 @@ static picoModel_t *_md2_load( PM_PARAMS_LOAD ){
PicoSetSurfaceColor( picoSurface, 0, i, picoColor_white ); PicoSetSurfaceColor( picoSurface, 0, i, picoColor_white );
} }
if ( dups ) {
for ( i = 0; i < dups; i++ ) for ( i = 0; i < dups; i++ )
{ {
j = p_index_LUT_DUPS[i].OldVert; const int surfN = i + md2->numXYZ;
vertex = &frame->verts[p_index_LUT_dups[i].Vert];
/* set vertex origin */ /* set vertex origin */
xyz[ 0 ] = frame->verts[j].v[0] * frame->scale[0] + frame->translate[0]; xyz[ 0 ] = vertex->v[0] * frame->scale[0] + frame->translate[0];
xyz[ 1 ] = frame->verts[j].v[1] * frame->scale[1] + frame->translate[1]; xyz[ 1 ] = vertex->v[1] * frame->scale[1] + frame->translate[1];
xyz[ 2 ] = frame->verts[j].v[2] * frame->scale[2] + frame->translate[2]; xyz[ 2 ] = vertex->v[2] * frame->scale[2] + frame->translate[2];
PicoSetSurfaceXYZ( picoSurface, i + md2->numXYZ, xyz ); PicoSetSurfaceXYZ( picoSurface, surfN, xyz );
/* set normal */ /* set normal */
normal[ 0 ] = md2_normals[frame->verts[j].lightnormalindex][0]; normal[ 0 ] = md2_normals[vertex->lightnormalindex][0];
normal[ 1 ] = md2_normals[frame->verts[j].lightnormalindex][1]; normal[ 1 ] = md2_normals[vertex->lightnormalindex][1];
normal[ 2 ] = md2_normals[frame->verts[j].lightnormalindex][2]; normal[ 2 ] = md2_normals[vertex->lightnormalindex][2];
PicoSetSurfaceNormal( picoSurface, i + md2->numXYZ, normal ); PicoSetSurfaceNormal( picoSurface, surfN, normal );
j = p_index_LUT_dups[i].ST;
/* set st coords */ /* set st coords */
st[ 0 ] = ( ( texCoord[p_index_LUT_DUPS[i].ST].s ) / ( (float)md2->skinWidth ) ); st[ 0 ] = ( ( texCoord[j].s ) / ( (float)md2->skinWidth ) );
st[ 1 ] = ( texCoord[p_index_LUT_DUPS[i].ST].t / ( (float)md2->skinHeight ) ); st[ 1 ] = ( texCoord[j].t / ( (float)md2->skinHeight ) );
PicoSetSurfaceST( picoSurface, 0, i + md2->numXYZ, st ); PicoSetSurfaceST( picoSurface, 0, surfN, st );
/* set color */ /* set color */
PicoSetSurfaceColor( picoSurface, 0, i + md2->numXYZ, picoColor_white ); PicoSetSurfaceColor( picoSurface, 0, surfN, picoColor_white );
}
}
// Free up malloc'ed LL entries
for ( i = 0; i < md2->numXYZ; i++ )
{
if ( p_index_LUT[i].next != NULL ) {
p_index_LUT2 = p_index_LUT[i].next;
do {
p_index_LUT3 = p_index_LUT2->next;
_pico_free( p_index_LUT2 );
p_index_LUT2 = p_index_LUT3;
dups--;
} while ( p_index_LUT2 != NULL );
}
}
if ( dups ) {
_pico_printf( PICO_WARNING, " Not all LL mallocs freed\n" );
} }
// Free malloc'ed LUTs // Free malloc'ed LUTs
_pico_free( p_index_LUT ); _pico_free( p_index_LUT );
_pico_free( p_index_LUT_DUPS ); _pico_free( p_index_LUT_dups );
/* return the new pico model */ /* return the new pico model */
_pico_free( bb0 ); _pico_free( bb0 );