/*-------------------------------------------------------------------------- | InitLight3ds | | Initializes the light3ds structure. If *light is null, | memory is also allocated for it. Note that the *spot field is | ignored when an existing structure is used. | +--------------------------------------------------------------------------*/ void InitLight3ds(light3ds **light) { if (light == NULL) SET_ERROR_RETURN(ERR_INVALID_ARG); /* If (*light) a null pointer, then alloc new memory for the pointer */ if (*light == NULL){ *light = malloc(sizeof(light3ds)); if(*light == NULL) SET_ERROR_RETURN(ERR_NO_MEM); /* Set all fields with pointer to NULL as well */ (*light)->spot = NULL; (*light)->exclude = NULL; } (*light)->name[0] = 0; (*light)->pos.x = 0.0F; (*light)->pos.y = 0.0F; (*light)->pos.z = 0.0F; (*light)->color.r = 0.708852F; (*light)->color.g = 0.708852F; (*light)->color.b = 0.708852F; (*light)->multiplier = 1.0F; (*light)->dloff = False3ds; (*light)->attenuation.on = False3ds; (*light)->attenuation.inner = 10.0F; (*light)->attenuation.outer = 100.0F; if ((*light)->exclude != NULL) ReleaseNameList3ds(&((*light)->exclude)); InitNameList3ds( &((*light)->exclude), (long3ds)0); }
/*-------------------------------------------------------------------------- | | GetOmnilightNameList3ds | Searches *db to construct **list, a list of omnilight names within | the database | | db: The database bing searched. | list: The resulting namelist pairs, if *list is null, then a namelist | structure will be allocated. | +--------------------------------------------------------------------------*/ void GetOmnilightNameList3ds(database3ds *db, namelist3ds **list) { chunk3ds *lite, *spot; ulong3ds omnilightcount, i, j; if (db == NULL || list == NULL) SET_ERROR_RETURN(ERR_INVALID_ARG); /* Update the index to named objects if the list has changed recently */ UpdateNamedObjectList3ds(db); /* Get the number of omnilights contained in the named object list */ omnilightcount = GetOmnilightCount3ds(db); /* Initilize the namelist array */ InitNameList3ds(list, omnilightcount); /* Scan through the list of named objects */ for (i = 0, j = 0; (i < db->objlist->count) && (j < omnilightcount); i++) { /* Search each named object for a light chunk */ FindChunk3ds(db->objlist->list[i].chunk, N_DIRECT_LIGHT, &lite); /* if its a light chunk, check to see if its a spotlight */ if (lite != NULL) { FindChunk3ds(lite, DL_SPOTLIGHT, &spot); /* If its not a spot */ if (spot == NULL) { /* Copy the name into the list */ (*list)->list[j].name = strdup(db->objlist->list[i].name); j++; /* increment the omnilight counter */ } } } }
/*-------------------------------------------------------------------------- | | GetSpotlightNameList3ds | Searches *db to construct **list, a list of spotlight names within | the database | | db: The database bing searched. | list: The resulting namelist pairs, if *list is null, then a namelist | structure will be allocated. | +--------------------------------------------------------------------------*/ void GetSpotlightNameList3ds(database3ds *db, namelist3ds **list) { chunk3ds *spot; ulong3ds spotlightcount, i, j; if (db == NULL || list == NULL) SET_ERROR_RETURN(ERR_INVALID_ARG); /* Update the index to named objects if the list has changed recently */ UpdateNamedObjectList3ds(db); /* Get the number of spotlights contained in the named object list */ spotlightcount = GetSpotlightCount3ds(db); /* Initilize the namelist array */ InitNameList3ds(list, spotlightcount); /* Scan through the list of named objects */ for (i = 0, j = 0; (i < db->objlist->count) && (j < spotlightcount); i++) { /* Search each named object for a direct light chunk */ FindChunk3ds(db->objlist->list[i].chunk, N_DIRECT_LIGHT, &spot); /* Search each direct light for a spotlight chunk */ if (spot != NULL) FindChunk3ds(spot, DL_SPOTLIGHT, &spot); /* If it is a spotlight chunk */ if (spot != NULL) { /* Copy the name into the list */ (*list)->list[j].name = strdup(db->objlist->list[i].name); j++; } } }
/* Searches *db to construct **list, a list of mesh names associated with their chunk definition. */ void GetMeshNameList3ds(database3ds *db, /* The chunk database being searched */ namelist3ds **list /* The resulting namelist pairs, if *list is null, then a namelist structure will be allocated */ ) { chunk3ds *current=NULL, *nobj=NULL, *ntri; ulong3ds meshcount, i, j; if (db == NULL || list == NULL) SET_ERROR_RETURN(ERR_INVALID_ARG); /* Update the index to named objects if the list has changed recently */ UpdateNamedObjectList3ds(db); /* Get the number of meshes contained in the named object list */ meshcount = GetMeshCount3ds(db); /* Initilize the namelist array */ InitNameList3ds(list, meshcount); /* Scan through the list of named objects */ for (i = 0, j = 0; (i < db->objlist->count) && (j < meshcount); i++) { /* Search each named object for a mesh chunk */ FindChunk3ds(db->objlist->list[i].chunk, N_TRI_OBJECT, &ntri); /* If it is a mesh chunk */ if (ntri != NULL) { /* Copy the name into the list */ (*list)->list[j].name = strdup(db->objlist->list[i].name); j++; } } }
/*------------------------------------------------------------------------ | | 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); }