Exemplo n.º 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;
	 }
      }
   }
}
Exemplo n.º 2
0
/*----------------------------------------------------------------
 |
 | PutLight3ds
 |
 |  Put chunks in database from light3ds structure.
 |
 +-----------------------------------------------------------------*/
void PutLight3ds(database3ds *db, light3ds *light)
{
  chunk3ds *pMdata, *pNamed, *pLight, *pSpot, *current, *xdata;

  if (db == NULL || light == NULL) SET_ERROR_RETURN(ERR_INVALID_ARG);
  if (db->topchunk == NULL) SET_ERROR_RETURN(ERR_INVALID_DATABASE);
  if (!(db->topchunk->tag == M3DMAGIC || db->topchunk->tag == CMAGIC))
     SET_ERROR_RETURN(ERR_WRONG_DATABASE);

  FindChunk3ds(db->topchunk, MDATA, &pMdata);
  if (pMdata == NULL) 
    {
      InitChunk3ds(&pMdata);
      pMdata->tag = MDATA;
      AddChildOrdered3ds(db->topchunk, pMdata);
    }
  
  /* Discover if the named object already exists */
  FindNamedObject3ds(db, light->name, &pNamed);
  
  /* If it does, then delete it */
  if (pNamed != NULL)
    {
      /* First, rescue the xdata chunk if there is one */
      FindChunk3ds(pNamed, XDATA_SECTION, &current);
      
      /* If there is one */
      if (current != NULL)
    {
      /* Then make a copy of it to reintroduce later */
     CopyChunk3ds(current, &xdata);
      }
      
      /* Delete the chunk's children and data, 
     leaving it in the same list order */
      DeleteChunk3ds(pNamed);
      pNamed->tag = NAMED_OBJECT; /* retag the chunk */

   } else /* else pNamed needs to be initialized and added */
   {
      InitChunkAs3ds(&pNamed, NAMED_OBJECT);
      AddChildOrdered3ds(pMdata, pNamed);
   }

  { /*--- NAME */
    NamedObject *d;

    d = InitChunkData3ds(pNamed);
    d->name = strdup(light->name);
    MakeNamedObjectListDirty3ds(db);
  }
  
  {  /*--- N_DIRECT_LIGHT & POSITION  */
    NDirectLight *d;

    pLight = kfPutGenericNode(N_DIRECT_LIGHT, pNamed);
    d = InitChunkData3ds(pLight);
    memcpy(&(d->lightpos), &(light->pos), sizeof(point3ds));
   }

  /*
   | Add children to DIRECT_LIGHT 
   */

  /*--- COLOR */
  {
    ColorF *d;
    chunk3ds *pChunk;

    pChunk = kfPutGenericNode(COLOR_F, pLight);
    d = InitChunkData3ds(pChunk);

    d->red = light->color.r;
    d->green = light->color.g;
    d->blue = light->color.b;
  }

  putTagFloat(pLight, DL_OUTER_RANGE, &light->attenuation.outer);
  ON_ERROR_RETURN;
  
  putTagFloat(pLight, DL_INNER_RANGE, &light->attenuation.inner);
  ON_ERROR_RETURN;
  
  putTagFloat(pLight, DL_MULTIPLIER, &light->multiplier);
  ON_ERROR_RETURN;

  if (light->dloff == True3ds)
    kfPutGenericNode(DL_OFF, pLight);

  if  (light->attenuation.on == True3ds)
    kfPutGenericNode(DL_ATTENUATE, pLight);

  /*--- DL_EXCLUDE */
  if (light->exclude != NULL && light->exclude->count > 0){
    chunk3ds *pChunk;
    ulong3ds i;
    DlExclude *d;

    for(i=0; i<light->exclude->count; i++){
      pChunk = kfPutGenericNode(DL_EXCLUDE, pLight);
      d = InitChunkData3ds(pChunk);
      d->name = strdup((light->exclude->list)[i].name);
    }
  }


  /*-----------------------
   |  SPOTLIGHT SECTION 
   +-----------------------*/
  if (light->spot == NULL)
    return;
  
  {
    DlSpotlight *d;

    pSpot = kfPutGenericNode(DL_SPOTLIGHT, pLight);
    d = InitChunkData3ds(pSpot);
    memcpy(&d->spotlighttarg, &light->spot->target, sizeof(point3ds));
    d->hotspotangle = light->spot->hotspot;
    d->falloffangle = light->spot->falloff;
  }
  
  putTagFloat(pSpot, DL_SPOT_ROLL, &light->spot->roll);  

  if (light->spot->aspect != 1.0F)
    putTagFloat(pSpot, DL_SPOT_ASPECT, &light->spot->aspect);  

  /*--- SHADOWS */
  if (light->spot->shadows.cast == True3ds)
    kfPutGenericNode(DL_SHADOWED, pSpot);
  
  if (light->spot->shadows.type == UseRayTraceShadow)
    kfPutGenericNode(DL_RAYSHAD, pSpot);
  
  putTagFloat(pSpot, DL_RAY_BIAS, &light->spot->shadows.raybias);

  /*--- DL_LOCAL_SHADOW2 */
  if (light->spot->shadows.local == True3ds)
  {
    DlLocalShadow2 *d;
    chunk3ds *pChunk;

    kfPutGenericNode(DL_LOCAL_SHADOW, pSpot);
    pChunk = kfPutGenericNode(DL_LOCAL_SHADOW2, pSpot);
    d = InitChunkData3ds(pChunk);

    d->localshadowbias = light->spot->shadows.bias;
    d->localshadowfilter = light->spot->shadows.filter;
    d->localshadowmapsize = light->spot->shadows.mapsize;
  }
  

  /*--- CONE */
  if (light->spot->cone.type == Rectangular)
    kfPutGenericNode(DL_SPOT_RECTANGULAR, pSpot);
  if (light->spot->cone.show == True3ds)
    kfPutGenericNode(DL_SEE_CONE, pSpot);
  if (light->spot->cone.overshoot == True3ds)
    kfPutGenericNode(DL_SPOT_OVERSHOOT, pSpot);

  /*--- PROJECTOR */
  if (light->spot->projector.use == True3ds)
  {
    DlSpotProjector *d;
    chunk3ds *pChunk;

    pChunk = kfPutGenericNode(DL_SPOT_PROJECTOR, pSpot);
    d = InitChunkData3ds(pChunk);

    d->name = strdup(light->spot->projector.bitmap);
  }
}
Exemplo n.º 3
0
/* Puts a mesh3ds into the chunk database.  Note that this routine will clobber
   named objects of the same name, except that it will transfer the old xdata onto
   the new object. If the developer wants to wipe out the XDATA too, he'll have
   to explicitly delete using the DeleteMesh3ds function */
void PutMesh3ds(database3ds *db, mesh3ds *mesh)
{
   chunk3ds *mdata, *nobj, *ntri, *current;
   NamedObject *nobjdata;
   chunk3ds *xdata = NULL;
   long3ds i;


   if (db == NULL || mesh == NULL) SET_ERROR_RETURN(ERR_INVALID_ARG);
   if (db->topchunk == NULL) SET_ERROR_RETURN(ERR_INVALID_DATABASE);
   if (!(db->topchunk->tag == M3DMAGIC || db->topchunk->tag == CMAGIC))
      SET_ERROR_RETURN(ERR_WRONG_DATABASE);

   FindChunk3ds(db->topchunk, MDATA, &mdata);

   if (mdata == NULL) 
   {
      InitChunk3ds(&mdata);
      ADD_ERROR_RETURN(ERR_PUT_FAIL);
      mdata->tag = MDATA;
      AddChildOrdered3ds(db->topchunk, mdata);
   }

   /* Discover if the named object already exists */
   FindNamedObject3ds(db, mesh->name, &nobj);
   ON_ERROR_RETURN;
   
   /* If it does, then delete it */
   if (nobj != NULL)
   {
      /* First, rescue the xdata chunk if there is one */
      FindChunk3ds(nobj, XDATA_SECTION, &current);

      /* If there is one */
      if (current != NULL)
      {
	 /* Then make a copy of it to reintroduce later */
	 CopyChunk3ds(current, &xdata);
	 ADD_ERROR_RETURN(ERR_PUT_FAIL);
      }
      
      /* Delete the chunk's children and data, leaving it in the same list order */
      DeleteChunk3ds(nobj);
      nobj->tag = NAMED_OBJECT; /* retag the chunk */

   } else /* else nobj needs to be initialized and added */
   {
      InitChunkAs3ds(&nobj, NAMED_OBJECT);
      ADD_ERROR_RETURN(ERR_PUT_FAIL);

      AddChildOrdered3ds(mdata, nobj);
      
   }
   

   /* Copy the mesh name into the chunk */
   nobjdata = InitChunkData3ds(nobj);
   ADD_ERROR_RETURN(ERR_PUT_FAIL);
   nobjdata->name = strdup(mesh->name);
   MakeNamedObjectListDirty3ds(db);

   InitChunk3ds(&ntri);
   ADD_ERROR_RETURN(ERR_PUT_FAIL);
   ntri->tag = N_TRI_OBJECT;
   AddChildOrdered3ds(nobj, ntri);

   if ((mesh->nvertices > 0) && (mesh->vertexarray != NULL))
   { /* Add the point array */
      PointArray *d;
      chunk3ds *temp = NULL;
      
      InitChunk3ds(&temp);
      ADD_ERROR_RETURN(ERR_PUT_FAIL);
      temp->tag = POINT_ARRAY;
      d = InitChunkData3ds(temp);
      ADD_ERROR_RETURN(ERR_PUT_FAIL);
      d->vertices = mesh->nvertices;
      d->pointlist = malloc(sizeof(point3ds)*d->vertices);
      if (d->pointlist == NULL) SET_ERROR_RETURN(ERR_NO_MEM);
      memcpy(d->pointlist, mesh->vertexarray, sizeof(point3ds)*d->vertices);
      AddChildOrdered3ds(ntri, temp);
   }

   if (mesh->ntextverts > 0)
   {
      TexVerts *d;
      chunk3ds *temp = NULL;
      
      InitChunk3ds(&temp);
      ADD_ERROR_RETURN(ERR_PUT_FAIL);
      temp->tag = TEX_VERTS;
      d = InitChunkData3ds(temp);
      ADD_ERROR_RETURN(ERR_PUT_FAIL);
      d->numcoords = mesh->ntextverts;
      d->textvertlist = malloc(sizeof(textvert3ds)*d->numcoords);
      if (d->textvertlist == NULL) SET_ERROR_RETURN(ERR_NO_MEM);
      memcpy(d->textvertlist, mesh->textarray, sizeof(textvert3ds)*d->numcoords);
      AddChildOrdered3ds(ntri, temp);
   }

   if (mesh->usemapinfo)
   {
      MeshTextureInfo *d;
      chunk3ds *temp;

      InitChunk3ds(&temp);
      ADD_ERROR_RETURN(ERR_PUT_FAIL);
      temp->tag = MESH_TEXTURE_INFO;
      d = InitChunkData3ds(temp);
      ADD_ERROR_RETURN(ERR_PUT_FAIL);

      d->maptype = mesh->map.maptype;
      d->xtiling = mesh->map.tilex;
      d->ytiling = mesh->map.tiley;      
      d->iconpos.x = mesh->map.cenx;
      d->iconpos.y = mesh->map.ceny;
      d->iconpos.z = mesh->map.cenz;
      d->iconscaling = mesh->map.scale;
      memcpy(d->xmatrix, mesh->map.matrix, sizeof(float3ds)*12);
      d->iconwidth = mesh->map.pw;
      d->iconheight = mesh->map.ph;
      d->cyliconheight = mesh->map.ch;
      AddChildOrdered3ds(ntri, temp);
   }
   
   if ((mesh->nvflags > 0) && (mesh->vflagarray != NULL))
   {
      PointFlagArray *d;
      chunk3ds *temp = NULL;
      
      InitChunk3ds(&temp);
      ADD_ERROR_RETURN(ERR_PUT_FAIL);
      temp->tag = POINT_FLAG_ARRAY;
      d = InitChunkData3ds(temp);
      ADD_ERROR_RETURN(ERR_PUT_FAIL);
      d->flags = mesh->nvflags;
      d->flaglist = malloc(sizeof(ushort3ds)*d->flags);
      if (d->flaglist == NULL) SET_ERROR_RETURN(ERR_NO_MEM);
      memcpy(d->flaglist, mesh->vflagarray, sizeof(ushort3ds)*d->flags);
      AddChildOrdered3ds(ntri, temp);
   }

   
   {
      MeshMatrix *d;
      chunk3ds *temp = NULL;

      InitChunk3ds(&temp);
      ADD_ERROR_RETURN(ERR_PUT_FAIL);
      temp->tag = MESH_MATRIX;
      d = InitChunkData3ds(temp);
      ADD_ERROR_RETURN(ERR_PUT_FAIL);
      memcpy(d->xmatrix, mesh->locmatrix, sizeof(float3ds)*12);
      AddChildOrdered3ds(ntri, temp);
   }
   

   {
      chunk3ds *temp = NULL;

      InitChunk3ds(&temp);
      ADD_ERROR_RETURN(ERR_PUT_FAIL);
      temp->tag = MESH_COLOR;
      InitChunkData3ds(temp);
      ADD_ERROR_RETURN(ERR_PUT_FAIL);
      ((MeshColor *)(temp->data))->color = mesh->meshcolor;
      AddChildOrdered3ds(ntri, temp);
   }

   if (mesh->nfaces > 0)
   {
      chunk3ds *farr = NULL;
      FaceArray *d;

      InitChunk3ds(&farr);
      ADD_ERROR_RETURN(ERR_PUT_FAIL);
      farr->tag = FACE_ARRAY;
      d = InitChunkData3ds(farr);
      ADD_ERROR_RETURN(ERR_PUT_FAIL);
      farr->data = d;
      d->faces = mesh->nfaces;
      d->facelist = malloc(sizeof(face3ds)*d->faces);
      if (d->facelist == NULL) SET_ERROR_RETURN(ERR_NO_MEM);
      memcpy(d->facelist, mesh->facearray, sizeof(face3ds)*d->faces);
      AddChildOrdered3ds(ntri, farr);

      if (mesh->nmats > 0)
      {
	 chunk3ds *matgroup;
	 ushort3ds x;
	 MshMatGroup *d;
	 
	 for (x = 0; x < mesh->nmats; x++)
	 {
	    matgroup = NULL;
	    InitChunk3ds(&matgroup);
	    ADD_ERROR_RETURN(ERR_PUT_FAIL);
	    matgroup->tag = MSH_MAT_GROUP;
	    d = InitChunkData3ds(matgroup);
	    ADD_ERROR_RETURN(ERR_PUT_FAIL);
	    d->matname = strdup(mesh->matarray[x].name);
	    d->faces = mesh->matarray[x].nfaces;
	    if (d->faces > 0)
	    {
	       d->facelist = malloc(sizeof(short3ds)*d->faces);
	       if (d->facelist == NULL) SET_ERROR_RETURN(ERR_NO_MEM);
	       memcpy(d->facelist, mesh->matarray[x].faceindex, sizeof(short3ds)*d->faces);
	    } else
	    {
	       d->facelist = NULL;
	    }
	    AddChildOrdered3ds(farr, matgroup);
	 }
      }
      
      if (mesh->smootharray != NULL)
      {
	 chunk3ds *smooth = NULL;
	 SmoothGroup *d;
	 
	 InitChunk3ds(&smooth);
	 ADD_ERROR_RETURN(ERR_PUT_FAIL);
	 smooth->tag = SMOOTH_GROUP;
	 d = InitChunkData3ds(smooth);
	 ADD_ERROR_RETURN(ERR_PUT_FAIL);

	 d->groups = mesh->nfaces;
	 d->grouplist = malloc(sizeof(long3ds)*d->groups);
	 if (d->grouplist == NULL) SET_ERROR_RETURN(ERR_NO_MEM);
	 memcpy(d->grouplist, mesh->smootharray, sizeof(long3ds)*d->groups);
	 AddChildOrdered3ds(farr, smooth);
      }
      
      if (mesh->useboxmap)
      {
	 chunk3ds *boxmap = NULL;
	 MshBoxmap *d;

	 InitChunk3ds(&boxmap);
	 ADD_ERROR_RETURN(ERR_PUT_FAIL);
	 boxmap->tag = MSH_BOXMAP;
	 d = InitChunkData3ds(boxmap);
	 ADD_ERROR_RETURN(ERR_PUT_FAIL);

	 for (i = 0; i < 6; i++)
	 {
	    d->matnames[i] = strdup(mesh->boxmap[i]);
	 }
	 AddChildOrdered3ds(farr, boxmap);
      }
   }
   
   if (mesh->procdata != NULL)
   {
      chunk3ds *procname, *procdata;
      ProcName *pname;
      IpasData *pdata;

      InitChunk3ds(&procname);
      ADD_ERROR_RETURN(ERR_PUT_FAIL);
      InitChunk3ds(&procdata);
      ADD_ERROR_RETURN(ERR_PUT_FAIL);
      procname->tag = PROC_NAME;
      procdata->tag = PROC_DATA;
      pname = InitChunkData3ds(procname);
      ADD_ERROR_RETURN(ERR_PUT_FAIL);
      pdata = InitChunkData3ds(procdata);
      ADD_ERROR_RETURN(ERR_PUT_FAIL);
      
      pname->name = strdup(mesh->procname);
      pdata->size = mesh->procsize;
      pdata->data = malloc(pdata->size);
      if (pdata->data == NULL) SET_ERROR_RETURN(ERR_NO_MEM);
      memcpy(pdata->data, mesh->procdata, pdata->size);
      AddChildOrdered3ds(ntri, procname);
      AddChildOrdered3ds(ntri, procdata);
   }

   if (mesh->ishidden)
   {
      chunk3ds *temp;
      InitChunk3ds(&temp);
      ADD_ERROR_RETURN(ERR_PUT_FAIL);
      temp->tag = OBJ_HIDDEN;
      AddChildOrdered3ds(nobj, temp);
   }

   if (mesh->isvislofter)
   {
      chunk3ds *temp;
      InitChunk3ds(&temp);
      ADD_ERROR_RETURN(ERR_PUT_FAIL);
      temp->tag = OBJ_VIS_LOFTER;
      AddChildOrdered3ds(nobj, temp);
   }

   if (mesh->ismatte)
   {
      chunk3ds *temp;
      InitChunk3ds(&temp);
      ADD_ERROR_RETURN(ERR_PUT_FAIL);
      temp->tag = OBJ_MATTE;
      AddChildOrdered3ds(nobj, temp);
   }

   if (mesh->isnocast)
   {
      chunk3ds *temp;
      InitChunk3ds(&temp);
      ADD_ERROR_RETURN(ERR_PUT_FAIL);
      temp->tag = OBJ_DOESNT_CAST;
      AddChildOrdered3ds(nobj, temp);
   }

   if (mesh->isfast)
   {
      chunk3ds *temp;
      InitChunk3ds(&temp);
      ADD_ERROR_RETURN(ERR_PUT_FAIL);
      temp->tag = OBJ_FAST;
      AddChildOrdered3ds(nobj, temp);
   }

   if (mesh->isnorcvshad)
   {
      chunk3ds *temp;
      InitChunk3ds(&temp);
      ADD_ERROR_RETURN(ERR_PUT_FAIL);
      temp->tag = OBJ_DONT_RCVSHADOW;
      AddChildOrdered3ds(nobj, temp);
   }

   if (mesh->isfrozen)
   {
      chunk3ds *temp;
      InitChunk3ds(&temp);
      ADD_ERROR_RETURN(ERR_PUT_FAIL);
      temp->tag = OBJ_FROZEN;
      AddChildOrdered3ds(nobj, temp);
   }

   if ((mesh->useproc==True3ds) && (mesh->procdata != NULL))
   {
      chunk3ds *temp;
      InitChunk3ds(&temp);
      ADD_ERROR_RETURN(ERR_PUT_FAIL);
      temp->tag = OBJ_PROCEDURAL;
      AddChildOrdered3ds(nobj, temp);
   }

   if (xdata != NULL)
   {
      AddChildOrdered3ds(ntri, xdata);
   }
    }
Exemplo n.º 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);
       
}
Exemplo n.º 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);
}