mirror of
https://github.com/id-Software/GtkRadiant.git
synced 2026-03-20 08:59:32 +01:00
The GtkRadiant sources as originally released under the GPL license.
This commit is contained in:
243
libs/picomodel/lwo/vmap.c
Normal file
243
libs/picomodel/lwo/vmap.c
Normal file
@@ -0,0 +1,243 @@
|
||||
/*
|
||||
======================================================================
|
||||
vmap.c
|
||||
|
||||
Vertex map functions for an LWO2 reader.
|
||||
|
||||
Ernie Wright 17 Sep 00
|
||||
====================================================================== */
|
||||
|
||||
#include "../picointernal.h"
|
||||
#include "lwo2.h"
|
||||
|
||||
|
||||
/*
|
||||
======================================================================
|
||||
lwFreeVMap()
|
||||
|
||||
Free memory used by an lwVMap.
|
||||
====================================================================== */
|
||||
|
||||
void lwFreeVMap( lwVMap *vmap )
|
||||
{
|
||||
if ( vmap ) {
|
||||
if ( vmap->name ) _pico_free( vmap->name );
|
||||
if ( vmap->vindex ) _pico_free( vmap->vindex );
|
||||
if ( vmap->pindex ) _pico_free( vmap->pindex );
|
||||
if ( vmap->val ) {
|
||||
if ( vmap->val[ 0 ] ) _pico_free( vmap->val[ 0 ] );
|
||||
_pico_free( vmap->val );
|
||||
}
|
||||
_pico_free( vmap );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
======================================================================
|
||||
lwGetVMap()
|
||||
|
||||
Read an lwVMap from a VMAP or VMAD chunk in an LWO2.
|
||||
====================================================================== */
|
||||
|
||||
lwVMap *lwGetVMap( picoMemStream_t *fp, int cksize, int ptoffset, int poloffset,
|
||||
int perpoly )
|
||||
{
|
||||
unsigned char *buf, *bp;
|
||||
lwVMap *vmap;
|
||||
float *f;
|
||||
int i, j, npts, rlen;
|
||||
|
||||
|
||||
/* read the whole chunk */
|
||||
|
||||
set_flen( 0 );
|
||||
buf = getbytes( fp, cksize );
|
||||
if ( !buf ) return NULL;
|
||||
|
||||
vmap = _pico_calloc( 1, sizeof( lwVMap ));
|
||||
if ( !vmap ) {
|
||||
_pico_free( buf );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* initialize the vmap */
|
||||
|
||||
vmap->perpoly = perpoly;
|
||||
|
||||
bp = buf;
|
||||
set_flen( 0 );
|
||||
vmap->type = sgetU4( &bp );
|
||||
vmap->dim = sgetU2( &bp );
|
||||
vmap->name = sgetS0( &bp );
|
||||
rlen = get_flen();
|
||||
|
||||
/* count the vmap records */
|
||||
|
||||
npts = 0;
|
||||
while ( bp < buf + cksize ) {
|
||||
i = sgetVX( &bp );
|
||||
if ( perpoly )
|
||||
i = sgetVX( &bp );
|
||||
bp += vmap->dim * sizeof( float );
|
||||
++npts;
|
||||
}
|
||||
|
||||
/* allocate the vmap */
|
||||
|
||||
vmap->nverts = npts;
|
||||
vmap->vindex = _pico_calloc( npts, sizeof( int ));
|
||||
if ( !vmap->vindex ) goto Fail;
|
||||
if ( perpoly ) {
|
||||
vmap->pindex = _pico_calloc( npts, sizeof( int ));
|
||||
if ( !vmap->pindex ) goto Fail;
|
||||
}
|
||||
|
||||
if ( vmap->dim > 0 ) {
|
||||
vmap->val = _pico_calloc( npts, sizeof( float * ));
|
||||
if ( !vmap->val ) goto Fail;
|
||||
f = _pico_alloc( npts * vmap->dim * sizeof( float ));
|
||||
if ( !f ) goto Fail;
|
||||
for ( i = 0; i < npts; i++ )
|
||||
vmap->val[ i ] = f + i * vmap->dim;
|
||||
}
|
||||
|
||||
/* fill in the vmap values */
|
||||
|
||||
bp = buf + rlen;
|
||||
for ( i = 0; i < npts; i++ ) {
|
||||
vmap->vindex[ i ] = sgetVX( &bp );
|
||||
if ( perpoly )
|
||||
vmap->pindex[ i ] = sgetVX( &bp );
|
||||
for ( j = 0; j < vmap->dim; j++ )
|
||||
vmap->val[ i ][ j ] = sgetF4( &bp );
|
||||
}
|
||||
|
||||
_pico_free( buf );
|
||||
return vmap;
|
||||
|
||||
Fail:
|
||||
if ( buf ) _pico_free( buf );
|
||||
lwFreeVMap( vmap );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
======================================================================
|
||||
lwGetPointVMaps()
|
||||
|
||||
Fill in the lwVMapPt structure for each point.
|
||||
====================================================================== */
|
||||
|
||||
int lwGetPointVMaps( lwPointList *point, lwVMap *vmap )
|
||||
{
|
||||
lwVMap *vm;
|
||||
int i, j, n;
|
||||
|
||||
/* count the number of vmap values for each point */
|
||||
|
||||
vm = vmap;
|
||||
while ( vm ) {
|
||||
if ( !vm->perpoly )
|
||||
for ( i = 0; i < vm->nverts; i++ )
|
||||
++point->pt[ vm->vindex[ i ]].nvmaps;
|
||||
vm = vm->next;
|
||||
}
|
||||
|
||||
/* allocate vmap references for each mapped point */
|
||||
|
||||
for ( i = 0; i < point->count; i++ ) {
|
||||
if ( point->pt[ i ].nvmaps ) {
|
||||
point->pt[ i ].vm = _pico_calloc( point->pt[ i ].nvmaps, sizeof( lwVMapPt ));
|
||||
if ( !point->pt[ i ].vm ) return 0;
|
||||
point->pt[ i ].nvmaps = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* fill in vmap references for each mapped point */
|
||||
|
||||
vm = vmap;
|
||||
while ( vm ) {
|
||||
if ( !vm->perpoly ) {
|
||||
for ( i = 0; i < vm->nverts; i++ ) {
|
||||
j = vm->vindex[ i ];
|
||||
n = point->pt[ j ].nvmaps;
|
||||
point->pt[ j ].vm[ n ].vmap = vm;
|
||||
point->pt[ j ].vm[ n ].index = i;
|
||||
++point->pt[ j ].nvmaps;
|
||||
}
|
||||
}
|
||||
vm = vm->next;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
======================================================================
|
||||
lwGetPolyVMaps()
|
||||
|
||||
Fill in the lwVMapPt structure for each polygon vertex.
|
||||
====================================================================== */
|
||||
|
||||
int lwGetPolyVMaps( lwPolygonList *polygon, lwVMap *vmap )
|
||||
{
|
||||
lwVMap *vm;
|
||||
lwPolVert *pv;
|
||||
int i, j;
|
||||
|
||||
/* count the number of vmap values for each polygon vertex */
|
||||
|
||||
vm = vmap;
|
||||
while ( vm ) {
|
||||
if ( vm->perpoly ) {
|
||||
for ( i = 0; i < vm->nverts; i++ ) {
|
||||
for ( j = 0; j < polygon->pol[ vm->pindex[ i ]].nverts; j++ ) {
|
||||
pv = &polygon->pol[ vm->pindex[ i ]].v[ j ];
|
||||
if ( vm->vindex[ i ] == pv->index ) {
|
||||
++pv->nvmaps;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
vm = vm->next;
|
||||
}
|
||||
|
||||
/* allocate vmap references for each mapped vertex */
|
||||
|
||||
for ( i = 0; i < polygon->count; i++ ) {
|
||||
for ( j = 0; j < polygon->pol[ i ].nverts; j++ ) {
|
||||
pv = &polygon->pol[ i ].v[ j ];
|
||||
if ( pv->nvmaps ) {
|
||||
pv->vm = _pico_calloc( pv->nvmaps, sizeof( lwVMapPt ));
|
||||
if ( !pv->vm ) return 0;
|
||||
pv->nvmaps = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* fill in vmap references for each mapped point */
|
||||
|
||||
vm = vmap;
|
||||
while ( vm ) {
|
||||
if ( vm->perpoly ) {
|
||||
for ( i = 0; i < vm->nverts; i++ ) {
|
||||
for ( j = 0; j < polygon->pol[ vm->pindex[ i ]].nverts; j++ ) {
|
||||
pv = &polygon->pol[ vm->pindex[ i ]].v[ j ];
|
||||
if ( vm->vindex[ i ] == pv->index ) {
|
||||
pv->vm[ pv->nvmaps ].vmap = vm;
|
||||
pv->vm[ pv->nvmaps ].index = i;
|
||||
++pv->nvmaps;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
vm = vm->next;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
Reference in New Issue
Block a user