]> de.git.xonotic.org Git - voretournament/voretournament.git/blobdiff - misc/mediasource/extra/netradiant-src/libs/picomodel/lwo/vmap.c
Include netRadiant source in this GIT
[voretournament/voretournament.git] / misc / mediasource / extra / netradiant-src / libs / picomodel / lwo / vmap.c
diff --git a/misc/mediasource/extra/netradiant-src/libs/picomodel/lwo/vmap.c b/misc/mediasource/extra/netradiant-src/libs/picomodel/lwo/vmap.c
new file mode 100644 (file)
index 0000000..69f87cf
--- /dev/null
@@ -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;
+}