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; } } } }
/*---------------------------------------------------------------- | | 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, ¤t); /* 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); } }
/* 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, ¤t); /* 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); } }
/*------------------------------------------------------------------------ | | 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); }
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, ¤t); if (current != NULL) (*mesh)->ishidden = True3ds; else (*mesh)->ishidden = False3ds; FindNextChunk3ds(nobj->children, OBJ_VIS_LOFTER, ¤t); if (current != NULL) (*mesh)->isvislofter = True3ds; else (*mesh)->isvislofter = False3ds; FindNextChunk3ds(nobj->children, OBJ_DOESNT_CAST, ¤t); if (current != NULL) (*mesh)->isnocast = True3ds; else (*mesh)->isnocast = False3ds; FindNextChunk3ds(nobj->children, OBJ_MATTE, ¤t); if (current != NULL) (*mesh)->ismatte = True3ds; else (*mesh)->ismatte = False3ds; FindNextChunk3ds(nobj->children, OBJ_FAST, ¤t); if (current != NULL) (*mesh)->isfast = True3ds; else (*mesh)->isfast = False3ds; FindNextChunk3ds(nobj->children, OBJ_FROZEN, ¤t); if (current != NULL) (*mesh)->isfrozen = True3ds; else (*mesh)->isfrozen = False3ds; FindNextChunk3ds(nobj->children, OBJ_DONT_RCVSHADOW, ¤t); if (current != NULL) (*mesh)->isnorcvshad = True3ds; else (*mesh)->isnorcvshad = False3ds; FindNextChunk3ds(nobj->children, OBJ_PROCEDURAL, ¤t); if (current != NULL) (*mesh)->useproc = True3ds; else (*mesh)->useproc = False3ds; ReleaseChunk3ds(&nobj); }