Пример #1
0
void CopyBackground3ds(database3ds *destdb, database3ds *srcdb)
{
   chunk3ds *srcmdata, *destmdata, *srcchunk, *destchunk;
   
   if ((destdb == NULL) || (srcdb == NULL))
      SET_ERROR_RETURN(ERR_INVALID_ARG);
   if ((srcdb->topchunk == NULL) || (destdb->topchunk == NULL))
      SET_ERROR_RETURN(ERR_INVALID_DATABASE);
   if ((srcdb->topchunk->tag != M3DMAGIC) && (srcdb->topchunk->tag != CMAGIC))
      SET_ERROR_RETURN(ERR_WRONG_DATABASE);
   if ((destdb->topchunk->tag != M3DMAGIC) && (destdb->topchunk->tag != CMAGIC))
      SET_ERROR_RETURN(ERR_WRONG_DATABASE);

   /* Find source mesh section */
   FindChunk3ds(srcdb->topchunk, MDATA, &srcmdata);

   /* If found */
   if (srcmdata != NULL)
   {
      /* Find or create destination mesh section */
      FindChunk3ds(destdb->topchunk, MDATA, &destmdata);
      if (destmdata == NULL)
      {
	 InitChunkAs3ds(&destmdata, MDATA);
	 AddChildOrdered3ds(destdb->topchunk, destmdata);
      }

      /* Scan the source mdata section looking for background setting chunks */
      for (srcchunk = srcmdata->children; srcchunk != NULL; srcchunk = srcchunk->sibling)
      {
	 switch(srcchunk->tag)
	 {
	 case V_GRADIENT:
	 case SOLID_BGND:
	 case BIT_MAP:
	 case USE_SOLID_BGND:
	 case USE_V_GRADIENT:
	 case USE_BIT_MAP:
	    /* if the same chunk exists in the destination, then delete it */
	    FindNextChunk3ds(destmdata->children, srcchunk->tag, &destchunk);
	    if (destchunk != NULL)
	       DeleteChunk3ds(destchunk);

	    /* Copy and add the chunk */
	    CopyChunk3ds(srcchunk, &destchunk);
	    AddChildOrdered3ds(destmdata, destchunk);
	    break;
	 default:
	    break;
	 }
      }
   }
}
Пример #2
0
ulong3ds GetMeshMatCount3ds(chunk3ds *current)
{
   chunk3ds *datachunk;
   ushort3ds meshmatcount=0;

   FindChunk3ds(current, MSH_MAT_GROUP, &datachunk);
   
   while(datachunk != NULL)
   {
      meshmatcount++;
      FindNextChunk3ds(datachunk->sibling, MSH_MAT_GROUP, &datachunk);
   }
   return(meshmatcount);
}
Пример #3
0
/* Retreaves the background settings from the chunk database */
void GetBackground3ds(database3ds *db, /* the database being searched */
		      background3ds **bgnd /* the background settings
					      destination.  If *atmo is NULL,
					      then a new structure will be
					      allocated */
		      )
{
   chunk3ds *mdata, *chunk;
   
   if (db == NULL || bgnd == NULL)
     SET_ERROR_RETURN(ERR_INVALID_ARG); 

   /* Find the MDATA chunk */
   FindChunk3ds(db->topchunk, MDATA, &mdata);

   /* only continue with structure filling if an MDATA chunk is found */
   if (mdata != NULL)
   {
      InitBackground3ds(bgnd);

      /* Search for bitmap chunk */
      FindChunk3ds(mdata, BIT_MAP, &chunk);
      if (chunk != NULL)
      {
	 BitMap *bitmap;

	 /* Read the chunk information */
	 ReadChunkData3ds(chunk);

	 /* Alias the data */
	 bitmap = chunk->data;

	 /* Copy the bitmap filename to the structure */
	 if (bitmap->bitmap != NULL) (*bgnd)->bitmap.name = strdup(bitmap->bitmap);
	 else (*bgnd)->bitmap.name = strdup("");
      }

      FindChunk3ds(mdata, SOLID_BGND, &chunk);
      if (chunk != NULL)
      {
	 chunk3ds *cc;

	 FindChunk3ds(chunk, COLOR_F, &cc);
	 if (cc != NULL)
	 {
	    ColorF *cd;
	    
	    cd = ReadChunkData3ds(cc);
	    (*bgnd)->solid.color.r = cd->red;
	    (*bgnd)->solid.color.g = cd->green;
	    (*bgnd)->solid.color.b = cd->blue;
	 }

	 FindChunk3ds(chunk, LIN_COLOR_F, &cc);
	 if (cc != NULL)
	 {
	    LinColorF *cd;
	    
	    cd = ReadChunkData3ds(cc);
	    (*bgnd)->solid.color.r = cd->red;
	    (*bgnd)->solid.color.g = cd->green;
	    (*bgnd)->solid.color.b = cd->blue;
	 }
      }

      FindChunk3ds(mdata, V_GRADIENT, &chunk);
      if (chunk != NULL)
      {
	 chunk3ds *topcolor, *midcolor, *botcolor;

	 /* The COLOR_F chunks are the old, non-gamma corrected colors */
	 ReadChunkData3ds(chunk);
	 (*bgnd)->vgradient.gradpercent = ((VGradient *)(chunk->data))->gradpercent;
	 FindChunk3ds(chunk, COLOR_F, &topcolor);
	 if (topcolor != NULL)
	 {
	    ReadChunkData3ds(topcolor);
	    (*bgnd)->vgradient.top.r = ((ColorF *)(topcolor->data))->red;
	    (*bgnd)->vgradient.top.g = ((ColorF *)(topcolor->data))->green;
	    (*bgnd)->vgradient.top.b = ((ColorF *)(topcolor->data))->blue;
	    FindNextChunk3ds(topcolor->sibling, COLOR_F, &midcolor);
	    if (midcolor != NULL)
	    {
	       ReadChunkData3ds(midcolor);
	       (*bgnd)->vgradient.mid.r = ((ColorF *)(midcolor->data))->red;
	       (*bgnd)->vgradient.mid.g = ((ColorF *)(midcolor->data))->green;
	       (*bgnd)->vgradient.mid.b = ((ColorF *)(midcolor->data))->blue;
	       FindNextChunk3ds(midcolor->sibling, COLOR_F, &botcolor);
	       if (botcolor != NULL)
	       {
		  ReadChunkData3ds(botcolor);
		  (*bgnd)->vgradient.bottom.r = ((ColorF *)(botcolor->data))->red;
		  (*bgnd)->vgradient.bottom.g = ((ColorF *)(botcolor->data))->green;
		  (*bgnd)->vgradient.bottom.b = ((ColorF *)(botcolor->data))->blue;
	       }
	    }
	 }

	 /* If the newer, gamma correct colors are available, then use them instead */
	 FindChunk3ds(chunk, LIN_COLOR_F, &topcolor);
	 if (topcolor != NULL)
	 {
	    ReadChunkData3ds(topcolor);
	    (*bgnd)->vgradient.top.r = ((ColorF *)(topcolor->data))->red;
	    (*bgnd)->vgradient.top.g = ((ColorF *)(topcolor->data))->green;
	    (*bgnd)->vgradient.top.b = ((ColorF *)(topcolor->data))->blue;
	    FindNextChunk3ds(topcolor->sibling, LIN_COLOR_F, &midcolor);
	    if (midcolor != NULL)
	    {
	       ReadChunkData3ds(midcolor);
	       (*bgnd)->vgradient.mid.r = ((ColorF *)(midcolor->data))->red;
	       (*bgnd)->vgradient.mid.g = ((ColorF *)(midcolor->data))->green;
	       (*bgnd)->vgradient.mid.b = ((ColorF *)(midcolor->data))->blue;
	       FindNextChunk3ds(midcolor->sibling, LIN_COLOR_F, &botcolor);
	       if (botcolor != NULL)
	       {
		  ReadChunkData3ds(botcolor);
		  (*bgnd)->vgradient.bottom.r = ((ColorF *)(botcolor->data))->red;
		  (*bgnd)->vgradient.bottom.g = ((ColorF *)(botcolor->data))->green;
		  (*bgnd)->vgradient.bottom.b = ((ColorF *)(botcolor->data))->blue;
	       }
	    }
	 }
      }
      
      /* Search for use_bitmap, use_solid_bgnd, or use_v_gradient */
      FindChunk3ds(mdata, USE_BIT_MAP, &chunk);
      if (chunk != NULL)
      {
	 (*bgnd)->bgndused = UseBitmapBgnd;
      } else
      {
	 FindChunk3ds(mdata, USE_SOLID_BGND, &chunk);
	 if (chunk != NULL)
	 {
	    (*bgnd)->bgndused = UseSolidBgnd;
	 } else
	 {
	    FindChunk3ds(mdata, USE_V_GRADIENT, &chunk);
	    if (chunk != NULL)
	    {
	       (*bgnd)->bgndused = UseVGradientBgnd;
	    } else
	    {
	       (*bgnd)->bgndused = NoBgnd;
	    }
	 }
      }
   }
}
Пример #4
0
/*------------------------------------------------------------------------
  |
  | GetLightEntryChunk3ds
  | Fills out the *light structure with the light pointed to 
  | by *chunk
  |
  +-----------------------------------------------------------------------*/
void GetLightEntryChunk3ds(chunk3ds *chunk, light3ds **light)
{
  chunk3ds *nobj, *dlite, *spot, *current;
  
   if (light  == NULL) SET_ERROR_RETURN(ERR_INVALID_ARG);

  FindNextChunk3ds(chunk->children, N_DIRECT_LIGHT, &dlite);
  if (dlite == NULL) SET_ERROR_RETURN(ERR_WRONG_OBJECT);
		   
  CopyChunk3ds(chunk, &nobj);
      
  FindChunk3ds(nobj, N_DIRECT_LIGHT, &dlite);
      
  FindChunk3ds(nobj, DL_SPOTLIGHT, &spot);
      
  if (dlite != NULL)
  {
     NamedObject *nobjd;
     NDirectLight *ndl;
      
     /* Initilize **light properly */
     if (spot == NULL)
        InitLight3ds(light);
     else
        InitSpotlight3ds(light);
      
     /* Copy the object name */
     nobjd = ReadChunkData3ds(nobj);
     strcpy((*light)->name, nobjd->name);
      
     /* Copy the light postion */
     ndl = ReadChunkData3ds(dlite);
     (*light)->pos = ndl->lightpos;
      
     /* scan all the chunks the light contains */
     for (current = dlite->children; current != NULL; current = current->sibling)
     {
	switch(current->tag)
        {
        case COLOR_F:   /* The color of the light */
	   {
	      ColorF *d;
	      d = ReadChunkData3ds(current);
	      (*light)->color.r = d->red;
	      (*light)->color.g = d->green;
	      (*light)->color.b = d->blue;
	   }
	   break;
        case COLOR_24:          /* The color of the (*light) */
	   {
	      Color24 *d;
	      d = ReadChunkData3ds(current);
	      (*light)->color.r = (float3ds)d->red / 255.0F;
	      (*light)->color.g = (float3ds)d->green / 255.0F;
	      (*light)->color.b = (float3ds)d->blue / 255.0F;
	   }
	   break;
        case DL_MULTIPLIER:     /* The light intensity */
	   {
	      DlMultiplier *d;
	      d = ReadChunkData3ds(current);
	      (*light)->multiplier = d->multiple;
	   }
	   break;
        case DL_INNER_RANGE:
	   {
	      DlInnerRange *d;
	      
	      d = ReadChunkData3ds(current);
	      /* assuming since there is a value it is on */
	      (*light)->attenuation.inner = d->range;
	   }
	   break;
        case DL_OUTER_RANGE:
	   {
	      DlOuterRange *d;
	      
	      d = ReadChunkData3ds(current);
	      /* assuming since there is a value it is on */
	      (*light)->attenuation.outer = d->range;
	   }
	   break;
        case DL_EXCLUDE:
	   {
	      DlExclude *d;
	      char3ds *name;
	      
	      d = ReadChunkData3ds(current);
	      if ((*light)->exclude == NULL)
		 InitNameList3ds(&((*light)->exclude), 0);

	      name = d->name;
	      d->name = NULL;
	      
	      AddToNameList3ds(&((*light)->exclude), name);
	      free(name);
	   }
	   break;
        case DL_OFF:
	   (*light)->dloff = True3ds;
	   break;
        case DL_ATTENUATE:
	   (*light)->attenuation.on = True3ds;
	   break;
        }
     }
      
     /*--- DL_SPOTLIGHT chunk */
     if (spot != NULL){
        DlSpotlight *d;
        
        /*--- Read spotlight data */
        d = ReadChunkData3ds(spot);
        (*light)->spot->target = d->spotlighttarg;
        (*light)->spot->hotspot = d->hotspotangle;
        (*light)->spot->falloff = d->falloffangle;
        
        /* scan all the chunks the spotlight contains */
        for (current = spot->children; 
	     current != NULL; 
	     current = current->sibling)
	{
	   switch(current->tag)
	   {
	   case DL_SPOT_ROLL:
	      {
		 DlSpotRoll *d;
		 
		 d = ReadChunkData3ds(current);
		 (*light)->spot->roll = d->angle;
	      }
	      break;
	   case DL_LOCAL_SHADOW:
	      (*light)->spot->shadows.cast = True3ds;
	      break;
	   case DL_LOCAL_SHADOW2:
	      {
		 DlLocalShadow2 *d;
		 d = ReadChunkData3ds(current);
		 
		 (*light)->spot->shadows.bias = d->localshadowbias;
		 (*light)->spot->shadows.filter = d->localshadowfilter;
		 (*light)->spot->shadows.mapsize = d->localshadowmapsize;
		 (*light)->spot->shadows.local = True3ds;
	      }
	      break;
	   case DL_SHADOWED:
	      (*light)->spot->shadows.cast = True3ds;
	      break;
	   case DL_SPOT_RECTANGULAR:
	      (*light)->spot->cone.type = Rectangular;
	      break;
	   case DL_SEE_CONE:
	      (*light)->spot->cone.show = True3ds;
	      break;
	   case DL_SPOT_OVERSHOOT:
	      (*light)->spot->cone.overshoot = True3ds;
	      break;
	   case DL_SPOT_ASPECT:
	      {
		 DlSpotAspect *d;
		 
		 d = ReadChunkData3ds(current);
		 (*light)->spot->aspect = d->aspect;
	      }
	      break;
	   case DL_RAY_BIAS:
	      {
		 DlRayBias *d;
		 
		 d = ReadChunkData3ds(current);
		 (*light)->spot->shadows.raybias = d->bias;
	      }
	      break;
	   case DL_RAYSHAD:
	      {
		 (*light)->spot->shadows.type = UseRayTraceShadow;
		 break;
	      }
	   case DL_SPOT_PROJECTOR:
	      {
		 DlSpotProjector *d;
		 d = ReadChunkData3ds(current);
		 (*light)->spot->projector.bitmap = d->name;
		 (*light)->spot->projector.use = True3ds;
		 d->name = NULL;
	      }
	      break;
            
	   } 
	} 
     } 
  }
  ReleaseChunk3ds(&nobj);
       
}
Пример #5
0
void GetMeshEntryChunk3ds(chunk3ds *chunk, mesh3ds **mesh)
{
    chunk3ds *nobj=NULL, *datachunk=NULL, *ntrichunk, *current;
    void *data = NULL;
    ushort3ds    meshmatcount=0;

    if (chunk == NULL || mesh == NULL)
       SET_ERROR_RETURN(ERR_INVALID_ARG);
   
    FindNextChunk3ds(chunk->children, N_TRI_OBJECT, &ntrichunk);
    if (ntrichunk == NULL)
       SET_ERROR_RETURN(ERR_WRONG_OBJECT);

    InitMeshObj3ds(mesh,0,0,0);

    /* Copy the mesh chunk into a temporary chunk */
    CopyChunk3ds(chunk, &nobj);
    ON_ERROR_RETURN;

    /* Get the N_TRI_OBJECT part out of it. */
    FindNextChunk3ds(nobj->children, N_TRI_OBJECT, &ntrichunk);
    
   /* Get the mesh name. */
   {
       NamedObject *d;
       d = ReadChunkData3ds(nobj);
       strcpy((*mesh)->name, d->name);
   }
   
   for (current = ntrichunk->children; current != NULL; current = current->sibling)
   {
       switch(current->tag)
       {
      case POINT_ARRAY:
      {
	 PointArray *d;
	 d = ReadChunkData3ds(current);
	 (*mesh)->nvertices = d->vertices;
	 (*mesh)->vertexarray = d->pointlist;
	 d->pointlist = NULL;
	 break;
      }
      case POINT_FLAG_ARRAY:
      {
	 PointFlagArray *flags;

	 flags = ReadChunkData3ds(current);
	 (*mesh)->nvflags = flags->flags;
	 (*mesh)->vflagarray = flags->flaglist;
	 flags->flaglist = NULL;
	 break;
      }
	    
      case FACE_ARRAY:
      {
	 FaceArray *d;
	 
	 d = ReadChunkData3ds(current);
	 (*mesh)->nfaces = d->faces;
	 (*mesh)->facearray = d->facelist;
	 d->facelist = NULL;

	 if (current->children != NULL)
	 {
	    /* begin search for MESH_MAT_GROUP and SMOOTH_GROUP */
	    chunk3ds *facearraychunk=current;
             
	    /* create a list of all mesh mat groups */

	    FindChunk3ds(facearraychunk, MSH_MAT_GROUP, &datachunk);
	    if (datachunk != NULL)
	    {
	       ulong3ds index;
	       
	       meshmatcount = (ushort3ds)GetMeshMatCount3ds(datachunk);
	       (*mesh)->nmats = meshmatcount;
	       (*mesh)->matarray = calloc(meshmatcount, sizeof(objmat3ds));

	       for (index = 0; index < (*mesh)->nmats; index++)
	       {
		  MshMatGroup *omat = NULL;
	     
		  omat = ReadChunkData3ds(datachunk);
	   	     
		  strcpy((*mesh)->matarray[index].name, omat->matname);
		  (*mesh)->matarray[index].nfaces = omat->faces;

		  (*mesh)->matarray[index].faceindex = omat->facelist;
		  omat->facelist = NULL;
	       
		  FindNextChunk3ds(datachunk->sibling, MSH_MAT_GROUP, &datachunk);

	       }
	    }
	 
	    FindNextChunk3ds(facearraychunk->children, SMOOTH_GROUP, &datachunk);
	    if (datachunk != NULL) {
	       SmoothGroup *sm;
	       long3ds smelements;
	       
	       sm = ReadChunkData3ds(datachunk);
	       smelements = (datachunk->size - 6)/LongSize3ds;
	       
	       (*mesh)->smootharray =  sm->grouplist;
	       sm->grouplist = NULL;
	    }

	    FindNextChunk3ds(facearraychunk->children, MSH_BOXMAP, &datachunk);
	    if (datachunk != NULL)
	    {
	       MshBoxmap *bm;
	       ushort3ds i;
	 
	       ReadChunkData3ds(datachunk);
	       bm = datachunk->data;
	       for (i = 0; i < 6; i++) strcpy((*mesh)->boxmap[i], bm->matnames[i]);
	       (*mesh)->useboxmap = True3ds;
	    }
      
	 }
	 break;
      }

      case TEX_VERTS:
      {
	 TexVerts *tv;
	 
	 ReadChunkData3ds(current);
	 tv = current->data;

	 (*mesh)->ntextverts = tv->numcoords;
	 (*mesh)->textarray = tv->textvertlist;
	 tv->textvertlist = NULL;
	 break;
      }

      case MESH_MATRIX:
      {
	 ReadChunkData3ds(current);
	 data = current->data;
	 memcpy((*mesh)->locmatrix ,((MeshMatrix *)data)->xmatrix, 12*sizeof(float3ds));
	 break;
      }
      case MESH_TEXTURE_INFO:
      {
	 (*mesh)->usemapinfo = True3ds;
	 ReadChunkData3ds(current);
	 data = current->data;
	 (*mesh)->map.maptype = ((MeshTextureInfo *)data)->maptype;
	 (*mesh)->map.tilex   = ((MeshTextureInfo *)data)->xtiling;
	 (*mesh)->map.tiley   = ((MeshTextureInfo *)data)->ytiling;
	 (*mesh)->map.cenx    = ((MeshTextureInfo *)data)->iconpos.x;
	 (*mesh)->map.ceny    = ((MeshTextureInfo *)data)->iconpos.y;
	 (*mesh)->map.cenz    = ((MeshTextureInfo *)data)->iconpos.z;
	 (*mesh)->map.scale   = ((MeshTextureInfo *)data)->iconscaling;
	 memcpy((*mesh)->map.matrix , ((MeshTextureInfo *)data)->xmatrix, 12*sizeof(float3ds));
	 (*mesh)->map.pw   = ((MeshTextureInfo *)data)->iconwidth;
	 (*mesh)->map.ph   = ((MeshTextureInfo *)data)->iconheight;
	 (*mesh)->map.ch   = ((MeshTextureInfo *)data)->cyliconheight;
	 break;
      }
      case PROC_NAME:
      {
	 ReadChunkData3ds(current);
	 data = current->data;
	 strcpy((*mesh)->procname, ((ProcName *)data)->name);
	 break;
      }
      case PROC_DATA:
      {
			IpasData *d;	
			d = ReadChunkData3ds(current);
	 		(*mesh)->procsize = d->size;
	 		(*mesh)->procdata = d->data;
	 		d->data = NULL; /* CCJ */
	 		break;
      }
      case MESH_COLOR:
      {
	 ReadChunkData3ds(current);
	 (*mesh)->meshcolor = ((MeshColor *)(current->data))->color;
	 break;
      }
      }
      
   }

   FindNextChunk3ds(nobj->children, OBJ_HIDDEN, &current);
   if (current != NULL) (*mesh)->ishidden = True3ds;
   else (*mesh)->ishidden = False3ds;

   FindNextChunk3ds(nobj->children, OBJ_VIS_LOFTER, &current);
   if (current != NULL) (*mesh)->isvislofter = True3ds;
   else (*mesh)->isvislofter = False3ds;

   FindNextChunk3ds(nobj->children, OBJ_DOESNT_CAST, &current);
   if (current != NULL) (*mesh)->isnocast = True3ds;
   else (*mesh)->isnocast = False3ds;

   FindNextChunk3ds(nobj->children, OBJ_MATTE, &current);
   if (current != NULL) (*mesh)->ismatte = True3ds;
   else (*mesh)->ismatte = False3ds;
      
   FindNextChunk3ds(nobj->children, OBJ_FAST, &current);
   if (current != NULL) (*mesh)->isfast = True3ds;
   else (*mesh)->isfast = False3ds;
   
   FindNextChunk3ds(nobj->children, OBJ_FROZEN, &current);
   if (current != NULL) (*mesh)->isfrozen = True3ds;
   else (*mesh)->isfrozen = False3ds;

   FindNextChunk3ds(nobj->children, OBJ_DONT_RCVSHADOW, &current);
   if (current != NULL) (*mesh)->isnorcvshad = True3ds;
   else (*mesh)->isnorcvshad = False3ds;

	FindNextChunk3ds(nobj->children, OBJ_PROCEDURAL, &current);
	if (current != NULL) (*mesh)->useproc = True3ds;
	else (*mesh)->useproc = False3ds;

   ReleaseChunk3ds(&nobj);
}