// Saves the given mesh to the given file. void SaveMesh(const utf8_ntri &file, const Mesh &mesh, uint4 flags) { const MeshImpl &meshImpl = static_cast<const MeshImpl&>(mesh); lean::raw_file meshFile(file, lean::file::readwrite, lean::file::overwrite); // Mesh ChunkInfo meshChunk; BeginChunk(meshFile, beScene::MeshDataChunk::Header, meshChunk); // Mesh name { const aiNode &rootNode = *meshImpl.GetScene()->mRootNode; if (rootNode.mName.length > 0) meshChunk.Size += WriteStringChunk(meshFile, beScene::MeshDataChunk::Name, rootNode.mName.data, static_cast<uint4>(rootNode.mName.length)); } // Mesh subsets { meshChunk.Size += SaveSubsets(meshFile, *meshImpl.GetScene(), flags); } EndChunk(meshFile, meshChunk); }
/************* * DESCRIPTION: read a material-chunk * INPUT: pointer to chunk * OUTPUT: - *************/ static void ParsePropMat(HANDLER_DATA *data, CHUNK *mainchunk) { CHUNK chunk; SURFACE *surf; float perc; COLOR color, diffuse; char buf[80]; surf = data->link->SurfaceAdd(data->rc); if (!surf) { data->err = ERR_MEM; return; } do { BeginChunk(data, &chunk); switch (chunk.id) { case ID_PROPNAME: ReadASCIIZ(data, buf); if (!data->link->SurfaceName(data->rc, surf,buf)) { data->err = ERR_MEM; return; } break; case ID_AMBIENT: ParseColor(data, &color); data->link->SurfaceAmbient(data->rc, surf,color.r,color.g,color.b); break; case ID_DIFFUSE: ParseColor(data, &diffuse); data->link->SurfaceDiffuse(data->rc, surf,diffuse.r,diffuse.g,diffuse.b); break; case ID_SPECULAR: ParseColor(data, &color); data->link->SurfaceSpecular(data->rc, surf,color.r,color.g,color.b); break; case ID_SHININESS: perc = ParsePercentage(data); data->link->SurfaceRefPhong(data->rc, surf,perc*100.f); break; case ID_TRANSPARENCY: perc = ParsePercentage(data); data->link->SurfaceTranspar(data->rc, surf,perc*diffuse.r,perc*diffuse.g,perc*diffuse.b); break; } EndChunk(data, &chunk); } while (INCHUNK); }
/************* * DESCRIPTION: parse a 3DS file * INPUT: pointer to chunk * OUTPUT: - *************/ static void Parse3DS(HANDLER_DATA *data, CHUNK *mainchunk) { CHUNK chunk; do { BeginChunk(data, &chunk); switch (chunk.id) { case ID_MESHBLOCK: ParseMData(data, &chunk); break; } EndChunk(data, &chunk); if(data->SetProgress) data->SetProgress(data->rc, (float)ftell(data->hFile)/(float)data->filesize); } while (INCHUNK); }
/************* * DESCRIPTION: parse main data * INPUT: pointer to chunk * OUTPUT: - *************/ static void ParseMData(HANDLER_DATA *data, CHUNK *mainchunk) { CHUNK chunk; do { BeginChunk(data, &chunk); switch (chunk.id) { case ID_PROPMATENTRY: ParsePropMat(data, &chunk); break; case ID_OBJECTDESC: ParseNamedObject(data, &chunk); break; } EndChunk(data, &chunk); } while (INCHUNK); }
/************* * DESCRIPTION: read a percent value * INPUT: - * OUTPUT: float (0..1) *************/ static float ParsePercentage(HANDLER_DATA *data) { CHUNK chunk; float percent = 0.f; BeginChunk(data, &chunk); switch (chunk.id) { case ID_PERCENT100: ReadFloat(data, &percent, 1); percent*= 0.01f; break; case ID_PERCENT1: ReadChunkBytes(data, &percent, 1); break; } EndChunk(data, &chunk); return percent; }
/************* * DESCRIPTION: read an object consisting of * triangles * INPUT: pointer to chunk * OUTPUT: - *************/ static void ParseTriObject(HANDLER_DATA *data, CHUNK *mainchunk) { CHUNK chunk; do { BeginChunk(data, &chunk); switch (chunk.id) { case ID_POINTS: ParsePoints(data); break; case ID_FACES: ParseFaces(data, &chunk); break; case ID_MAPPINGCOORS: ParseMapping(data); break; case ID_TRANSMATRIX: ReadFloat(data, &data->transm[0], 12); data->transmatrix.m[0] = data->transm[0]; data->transmatrix.m[1] = data->transm[1]; data->transmatrix.m[2] = data->transm[2]; data->transmatrix.m[4] = data->transm[3]; data->transmatrix.m[5] = data->transm[4]; data->transmatrix.m[6] = data->transm[5]; data->transmatrix.m[8] = data->transm[6]; data->transmatrix.m[9] = data->transm[7]; data->transmatrix.m[10] = data->transm[8]; data->transmatrix.m[12] = data->transm[9]; data->transmatrix.m[13] = data->transm[10]; data->transmatrix.m[14] = data->transm[11]; break; } EndChunk(data, &chunk); } while (INCHUNK); }
/************* * DESCRIPTION: read a color * INPUT: color pointer to color * OUTPUT: - *************/ static void ParseColor(HANDLER_DATA *data, COLOR *color) { CHUNK chunk; UBYTE c[3]; BeginChunk(data, &chunk); switch (chunk.id) { case ID_COLOR1: ReadFloat(data, &color->r, 1); ReadFloat(data, &color->g, 1); ReadFloat(data, &color->b, 1); break; case ID_COLOR255: ReadChunkBytes(data, &c, 3); color->r = c[0]/255.0f; color->g = c[1]/255.0f; color->b = c[2]/255.0f; break; } EndChunk(data, &chunk); }
int WriteOutDTD(struct DTDesc *TheDTDesc) { struct IFFHandle *IH; struct FileDataTypeHeader FileDTH; int i; if(!TheDTDesc) { return(FALSE); } if(strlen(TheDTDesc->Name)==0) { return(FALSE); } if(strlen(TheDTDesc->BaseName)==0) { return(FALSE); } #if 0 if(TheDTDesc->DTH.dth_MaskLen==0) { return(FALSE); } #endif if(strlen(TheDTDesc->Pattern)==0) { TheDTDesc->Pattern[0]='#'; TheDTDesc->Pattern[1]='?'; TheDTDesc->Pattern[2]='\0'; } IH=NewIFF(TheDTDesc->OutputName, MAKE_ID('D','T','Y','P')); if(!IH) { return(FALSE); } if(!NewChunk(IH, MAKE_ID('N','A','M','E'))) { CloseIFF(IH); remove(TheDTDesc->Name); return(FALSE); } if(WriteChunkData(IH, TheDTDesc->Name, (strlen(TheDTDesc->Name)+1))<=0) { EndChunk(IH); CloseIFF(IH); remove(TheDTDesc->Name); return(FALSE); } EndChunk(IH); if(strlen(TheDTDesc->Version) > 0) { if(!NewChunk(IH, MAKE_ID('F','V','E','R'))) { CloseIFF(IH); remove(TheDTDesc->Name); return(FALSE); } if(WriteChunkData(IH, TheDTDesc->Version, (strlen(TheDTDesc->Version)+1))<=0) { EndChunk(IH); CloseIFF(IH); remove(TheDTDesc->Name); return(FALSE); } EndChunk(IH); } if(!NewChunk(IH, MAKE_ID('D','T','H','D'))) { CloseIFF(IH); remove(TheDTDesc->Name); return(FALSE); } FileDTH.dth_Name = (((unsigned int) sizeof(struct FileDataTypeHeader))); FileDTH.dth_BaseName = (((unsigned int) FileDTH.dth_Name) + strlen(TheDTDesc->DTH.dth_Name) + 1); FileDTH.dth_Pattern = (((unsigned int) FileDTH.dth_BaseName) + strlen(TheDTDesc->DTH.dth_BaseName) + 1); FileDTH.dth_Mask = (((unsigned int) FileDTH.dth_Pattern) + strlen(TheDTDesc->DTH.dth_Pattern) + 1); FileDTH.dth_GroupID = TheDTDesc->DTH.dth_GroupID; FileDTH.dth_ID = TheDTDesc->DTH.dth_ID; FileDTH.dth_MaskLen = TheDTDesc->DTH.dth_MaskLen; FileDTH.dth_Pad = TheDTDesc->DTH.dth_Pad; FileDTH.dth_Flags = TheDTDesc->DTH.dth_Flags; FileDTH.dth_Priority = TheDTDesc->DTH.dth_Priority; FileDTH.dth_Name = Swap32IfLE(((uint32_t) FileDTH.dth_Name)); FileDTH.dth_BaseName = Swap32IfLE(((uint32_t) FileDTH.dth_BaseName)); FileDTH.dth_Pattern = Swap32IfLE(((uint32_t) FileDTH.dth_Pattern)); FileDTH.dth_Mask = Swap32IfLE(((uint32_t) FileDTH.dth_Mask)); FileDTH.dth_GroupID = Swap32IfLE(FileDTH.dth_GroupID); FileDTH.dth_ID = Swap32IfLE(FileDTH.dth_ID); FileDTH.dth_MaskLen = Swap16IfLE(FileDTH.dth_MaskLen); FileDTH.dth_Pad = Swap16IfLE(FileDTH.dth_Pad); FileDTH.dth_Flags = Swap16IfLE(FileDTH.dth_Flags); FileDTH.dth_Priority = Swap16IfLE(FileDTH.dth_Priority); if(WriteChunkData(IH, (char *) &FileDTH, sizeof(struct FileDataTypeHeader))<=0) { EndChunk(IH); CloseIFF(IH); remove(TheDTDesc->Name); return(FALSE); } if(WriteChunkData(IH, TheDTDesc->DTH.dth_Name, (strlen(TheDTDesc->DTH.dth_Name)+1))<=0) { EndChunk(IH); CloseIFF(IH); remove(TheDTDesc->Name); return(FALSE); } if(WriteChunkData(IH, TheDTDesc->DTH.dth_BaseName, (strlen(TheDTDesc->DTH.dth_BaseName)+1))<=0) { EndChunk(IH); CloseIFF(IH); remove(TheDTDesc->Name); return(FALSE); } if(WriteChunkData(IH, TheDTDesc->DTH.dth_Pattern, (strlen(TheDTDesc->DTH.dth_Pattern)+1))<=0) { EndChunk(IH); CloseIFF(IH); remove(TheDTDesc->Name); return(FALSE); } for(i=0; i<TheDTDesc->DTH.dth_MaskLen; i++) { TheDTDesc->DTH.dth_Mask[i]=Swap16IfLE(TheDTDesc->DTH.dth_Mask[i]); } if (TheDTDesc->DTH.dth_MaskLen) { if(WriteChunkData(IH, (char *) TheDTDesc->DTH.dth_Mask, TheDTDesc->DTH.dth_MaskLen*sizeof(uint16_t))<=0) { EndChunk(IH); CloseIFF(IH); remove(TheDTDesc->Name); return(FALSE); } } EndChunk(IH); CloseIFF(IH); return(TRUE); }
void sXSILoader::ScanMesh(sInt indent,sXSIModel *model) { sChar buffer[256]; sChar chunk[XSISIZE]; sChar name[XSISIZE]; sChar *cmd; sInt supports,i,j,k,max; sInt fcount; sInt vcount; sXSICluster *cluster; sInt cr,cg,cb,ca; sInt set,set2; sInt PosCount; sVector *Pos; sInt NormCount; sVector *Norm; sInt ColorCount; sU32 *Color; sInt UVCount[sXSI_MAXUV]; sF32 *UV[sXSI_MAXUV]; sChar UVName[sXSI_MAXUV][XSISIZE]; // init shape holder PosCount = 0; Pos = 0; NormCount = 0; Norm = 0; ColorCount = 0; Color = 0; for(i=0;i<sXSI_MAXUV;i++) { UVCount[i] = 0; UV[i] = 0; } while(*Scan!=0 && *Scan!='}' && !Error) { ScanChunk(indent,chunk,name); if(sCmpString(chunk,"SI_Shape")==0) { supports = ScanInt(); ScanString(buffer,sizeof(buffer)); if(sCmpString(buffer,"ORDERED")!=0) Error = sTRUE; for(i=0;i<supports && !Error;i++) { max = ScanInt(); ScanString(buffer,sizeof(buffer)); if(sCmpString(buffer,"POSITION")==0) { sVERIFY(Pos==0); PosCount = max; Pos = new sVector[max]; for(j=0;j<max;j++) { Pos[j].x = ScanFloat(); Pos[j].y = ScanFloat(); Pos[j].z = ScanFloat(); } } else if(sCmpString(buffer,"NORMAL")==0) { sVERIFY(Norm==0); NormCount = max; Norm = new sVector[max]; for(j=0;j<max;j++) { Norm[j].x = ScanFloat(); Norm[j].y = ScanFloat(); Norm[j].z = ScanFloat(); } } else if(sCmpString(buffer,"COLOR")==0) { sVERIFY(Color==0); ColorCount = max; Color = new sU32[max]; for(j=0;j<max;j++) { cr = sRange<sInt>(ScanFloat()*255,255,0); cg = sRange<sInt>(ScanFloat()*255,255,0); cb = sRange<sInt>(ScanFloat()*255,255,0); ca = sRange<sInt>(ScanFloat()*256,255,0); Color[j] = (ca<<24)|(cb<<16)|(cg<<8)|(cr); } } else if(sCmpString(buffer,"TEX_COORD_UV")==0) { set = 0; sVERIFY(UV[set]==0); UVCount[set] = max; UV[set] = new sF32[max*2]; for(j=0;j<max;j++) { UV[set][j*2+0] = ScanFloat(); UV[set][j*2+1] = 1.0f-ScanFloat(); } } else if(sCmpMem(buffer,"TEX_COORD_UV",12)==0) { j=12; set = 0; while(buffer[j]>='0' && buffer[j]<='9') set = set*10 + (buffer[j++]-'0'); sVERIFY(set>=0 && set<sXSI_MAXUV); sVERIFY(UV[set]==0); ScanString(UVName[set],sizeof(UVName[set])); UVCount[set] = max; UV[set] = new sF32[max*2]; for(j=0;j<max;j++) { UV[set][j*2+0] = ScanFloat(); UV[set][j*2+1] = 1.0f-ScanFloat(); } } else { Error = sTRUE; } } EndChunk(); } else if(sCmpString(chunk,"SI_PolygonList")==0) { cluster = new sXSICluster; fcount = ScanInt(); sCopyString(buffer,"|POSITION|",sizeof(buffer)); i = sGetStringLen(buffer); ScanString(buffer+i,sizeof(buffer)-i); #if DUMPCHUNK sDPrintF(" %s",buffer); #endif ScanString(name,sizeof(name)); cluster->Material = FindMaterial(name); vcount = ScanInt(); cluster->VertexCount = vcount; cluster->IndexCount = vcount; cluster->Vertices = new sXSIVertex[vcount]; cluster->Faces = new sInt[vcount*2]; model->Clusters->Add(cluster); j = 0; for(i=0;i<fcount;i++) { max = ScanInt(); cluster->Vertices[j].Init(); cluster->Faces[j*2+0] = max; cluster->Faces[j*2+1] = j; j++; for(k=1;k<max;k++) { cluster->Vertices[j].Init(); cluster->Faces[j*2+0] = 0; cluster->Faces[j*2+1] = j; j++; } } sVERIFY(j==vcount); cmd = buffer; while(!Error && *cmd) { if(sCmpMem(cmd,"|POSITION",9)==0) { cmd+=9; sVERIFY(Pos); for(i=0;i<vcount;i++) { j = ScanInt(); cluster->Vertices[i].Pos = Pos[j]; cluster->Vertices[i].Index = j; } } else if(sCmpMem(cmd,"|NORMAL",7)==0) { cmd+=7; sVERIFY(Norm); for(i=0;i<vcount;i++) { j = ScanInt(); cluster->Vertices[i].Normal = Norm[j]; cluster->Vertices[i].Normal.Init(0,0,0,1); } } else if(sCmpMem(cmd,"|COLOR",6)==0) { cmd+=6; sVERIFY(Color); for(i=0;i<vcount;i++) { j = ScanInt(); cluster->Vertices[i].Color = Color[j]; } } else if(sCmpMem(cmd,"|TEX_COORD_UV",13)==0) { cmd+=13; set = 0; if(*cmd>='0' && *cmd<='9') { while(*cmd>='0' && *cmd<='9') set = set*10 + ((*cmd++)-'0'); sVERIFY(set>=0 && set<sXSI_MAXUV); sVERIFY(UV[set]) for(set2=0;set2<4;set2++) if(sCmpString(TSName[cluster->Material->TUV[set2]],UVName[set])==0) break; } else { set2 = 0; } for(i=0;i<vcount;i++) { j = ScanInt(); if(set2>=0 && set2<2) { cluster->Vertices[i].UV[set2][0] = 0.0f;// UV[set][j*2+0]; cluster->Vertices[i].UV[set2][1] = 0.0f;// UV[set][j*2+1]; } } } else {
void sXSILoader::ScanMatLib(sInt indent) { sChar chunk[XSISIZE]; sChar name[XSISIZE]; sChar texname[256]; sChar buffer[XSISIZE]; sChar pname[XSISIZE]; sChar tname[XSISIZE]; sChar tsup[2][XSISIZE]; sInt texena[2]; sXSIMaterial *mat; sXSITexture *tex; sInt i,max; sInt pcount,ccount; sInt ival; sF32 fval; ScanInt(); while(*Scan!=0 && *Scan!='}' && !Error) { ScanChunk(indent,chunk,name); if(sCmpString(chunk,"SI_Material")==0) { mat = new sXSIMaterial; sCopyString(mat->Name,name,sizeof(mat->Name)); mat->Flags |= 0; Materials->Add(mat); ScanFloat(); ScanFloat(); ScanFloat(); ScanFloat(); ScanFloat(); ScanFloat(); ScanFloat(); ScanFloat(); ScanFloat(); ScanFloat(); ScanFloat(); ScanInt(); ScanFloat(); ScanFloat(); ScanFloat(); sScanSpace(Scan); while(*Scan!=0 && *Scan!='}' && !Error) { ScanChunk(indent+1,chunk,name); if(sCmpString(chunk,"SI_Texture2D")==0) { ScanString(texname,sizeof(texname)); ScanInt(); ScanInt(); ScanInt(); ScanInt(); ScanInt(); ScanInt(); ScanInt(); ScanInt(); ScanInt(); ScanInt(); ScanInt(); ScanInt(); ScanFloat(); ScanFloat(); ScanFloat(); ScanFloat(); ScanFloat(); ScanFloat(); ScanFloat(); ScanFloat(); ScanFloat(); ScanFloat(); ScanFloat(); ScanFloat(); ScanFloat(); ScanFloat(); ScanFloat(); ScanFloat(); ScanFloat(); ScanFloat(); ScanFloat(); ScanFloat(); ScanInt(); ScanFloat(); ScanFloat(); ScanFloat(); ScanFloat(); ScanFloat(); ScanFloat(); ScanFloat(); EndChunk(); if(mat->Tex[0] == 0) { tex = FindTexture(texname); if(tex) mat->Tex[0] = tex; } } else { SkipChunk(); } sScanSpace(Scan); } EndChunk(); } else if(sCmpString(chunk,"XSI_Material")==0) { mat = new sXSIMaterial; sCopyString(mat->Name,name,sizeof(mat->Name)); mat->TFlags[0] = 0; mat->TFlags[1] = 0; mat->Flags |= 0; sDPrintF("%08x:<%s>\n",Scan,name); Materials->Add(mat); max = ScanInt(); for(i=0;i<max;i++) { ScanString(buffer,sizeof(buffer)); ScanString(buffer,sizeof(buffer)); } sScanSpace(Scan); tsup[0][0]=0; tsup[0][1]=0; texena[0] = 0; texena[1] = 0; while(*Scan!=0 && *Scan!='}' && !Error) { ScanChunk(indent+1,chunk,name); if(sCmpString(chunk,"XSI_Shader")==0) { ScanString(buffer,sizeof(buffer)); ScanInt(); pcount = ScanInt(); ccount = ScanInt(); for(i=0;i<pcount;i++) { ScanString(pname,sizeof(pname)); ScanString(tname,sizeof(tname)); if(sCmpString(tname,"STRING")==0) { ScanString(buffer,sizeof(buffer)); if(sCmpString(pname,"tspace_id1")==0) sCopyString(tsup[0],buffer,sizeof(tsup[0])); if(sCmpString(pname,"tspace_id" )==0) sCopyString(tsup[0],buffer,sizeof(tsup[0])); if(sCmpString(pname,"tspace_id2")==0) sCopyString(tsup[1],buffer,sizeof(tsup[1])); } else if(sCmpString(tname,"FLOAT")==0) { fval = ScanFloat(); ival = sRange<sInt>(255*fval,255,0); if(sCmpString(pname,"Ambient.red")==0) mat->Ambient.r = ival; if(sCmpString(pname,"Ambient.green")==0) mat->Ambient.g = ival; if(sCmpString(pname,"Ambient.blue")==0) mat->Ambient.b = ival; if(sCmpString(pname,"Diffuse.red")==0) mat->Diffuse.r = ival; if(sCmpString(pname,"Diffuse.green")==0) mat->Diffuse.g = ival; if(sCmpString(pname,"Diffuse.blue")==0) mat->Diffuse.b = ival; if(sCmpString(pname,"Specular.red")==0) mat->Specular.r = ival; if(sCmpString(pname,"Specular.green")==0) mat->Specular.g = ival; if(sCmpString(pname,"Specular.blue")==0) mat->Specular.b = ival; if(sCmpString(pname,"Shininess")==0) mat->Specularity = fval; } else if(sCmpString(tname,"INTEGER")==0) { ival = ScanInt(); } else if(sCmpString(tname,"BOOLEAN")==0) { ival = ScanInt(); if(ival!=0) { // if(sCmpString(pname,"WrapS1")==0) mat->TFlags[0] |= sMTF_TILE; // if(sCmpString(pname,"WrapT1")==0) mat->TFlags[0] |= sMTF_TILE; if(sCmpString(pname,"Refmap1")==0) mat->TFlags[0] |= sMTF_UVENVI; if(sCmpString(pname,"Texture_1_Enable")==0) texena[0]=1; // if(sCmpString(pname,"WrapS2")==0) mat->TFlags[1] |= sMTF_TILE; // if(sCmpString(pname,"WrapT2")==0) mat->TFlags[1] |= sMTF_TILE; if(sCmpString(pname,"Refmap2")==0) mat->TFlags[1] |= sMTF_UVENVI; if(sCmpString(pname,"Texture_2_Enable")==0) texena[1]=1; } else { if(sCmpString(pname,"Enable_Ambient")==0) mat->Ambient = 0xffffffff; if(sCmpString(pname,"Enable_Diffuse")==0) mat->Diffuse = 0xffffffff; if(sCmpString(pname,"Enable_Specular")==0) mat->Specular = 0xffffffff; if(sCmpString(pname,"Enable_Shininess")==0) mat->Specularity = 0; // if(sCmpString(pname,"Enable_Lighting")==0) mat->Flags &= ~sMF_LIGHTMASK; } } else { Error = sTRUE; } } for(i=0;i<ccount;i++) { ScanString(pname,sizeof(pname)); ScanString(buffer,sizeof(buffer)); ScanString(tname,sizeof(tname)); if(sCmpString(tname,"IMAGE")==0) { if((sCmpString(pname,"Texture_1")==0 || sCmpString(pname,"tex")==0) && texena[0]) { if(mat->Tex[0] == 0 && (tsup[0][0]!=0 || (mat->TFlags[0]&sMTF_UVMASK)==sMTF_UVENVI) && TSCount<sXSI_MAXTS) { tex = FindTexture(buffer); if(tex) { mat->Tex[0] = tex; mat->Mode = sMBM_TEX; sCopyString(TSName[TSCount],tsup[0],XSISIZE); mat->TUV[0] = TSCount++; } } } if(sCmpString(pname,"Texture_2")==0 && texena[1]) { if(mat->Tex[1] == 0 && (tsup[1][0]!=0 || (mat->TFlags[1]&sMTF_UVMASK)==sMTF_UVENVI) && TSCount<sXSI_MAXTS) { tex = FindTexture(buffer); if(tex) { mat->Tex[1] = tex; mat->Mode = sMBM_MUL; // mat->TFlags[1] = sMTF_FILTER|sMTF_MIPMAP;//|sMTF_UVENVI; sCopyString(TSName[TSCount],tsup[1],XSISIZE); mat->TUV[1] = TSCount++; } } } } } sScanSpace(Scan); while(*Scan!=0 && *Scan!='}' && !Error) { ScanChunk(indent+1,chunk,name); SkipChunk(); sScanSpace(Scan); } EndChunk(); } else { SkipChunk(); } sScanSpace(Scan); } if((mat->TFlags[1] & sMTF_UVMASK)==0) mat->TFlags[1] |= sMTF_UV1; if(mat->Specularity>0.0001f || mat->Ambient!=0xffffffff || mat->Diffuse != 0xffffffff || mat->Specular != 0xffffffff) { // mat->Flags = (mat->Flags & (~sMF_LIGHTMASK)) | sMF_LIGHTMAT; // sDPrintF("extlight: %08x %08x %08x\n",mat->Diffuse.Color,mat->Ambient.Color,mat->Specular.Color); } else { // mat->Flags |= sMF_COLBOTH; } mat->TFlags[0] |= sMTF_FILTERMIN | sMTF_FILTERMAG | sMTF_MIPMAP; mat->TFlags[1] |= sMTF_FILTERMIN | sMTF_FILTERMAG | sMTF_MIPMAP; EndChunk(); } else { SkipChunk(); } sScanSpace(Scan); } EndChunk(); }
/************* * DESCRIPTION: read a 3DS-file * INPUT: rc context * filename name of 3DS-file * link link structure * pos object position * ox, oy, oz object orientation * actor pointer to actor * replacesurf surface to replace object surface with * version version of file * OUTPUT: NULL if ok, else error string *************/ extern "C" char* SAVEDS objRead(rsiCONTEXT *rc_, char* filename, OBJLINK *link_, const VECTOR *pos, const VECTOR *ox, const VECTOR *oy, const VECTOR *oz, const VECTOR *scale, ACTOR *actor, SURFACE *replacesurf, ULONG *version, void (*SetProgress)(rsiCONTEXT*, float)) { CHUNK chunk; HANDLER_DATA data; data.link = link_; data.rc = rc_; data.pointcount = 0; data.points = NULL; data.mapping = NULL; data.VertNorms = NULL; data.face = NULL; data.facecount = 0; data.material = NULL; data.defaultsurface = NULL; data.replacesurface = NULL; data.smooth_angle = 0.5235987f; data.TriNorms = NULL; data.TriSmooth = NULL; data.TriList = NULL; data.cos_smooth_angle = (float)cos(data.smooth_angle); data.mainactor = NULL; data.SetProgress = SetProgress; data.size_done = 0; data.transmatrix.IdentityMatrix(); data.matrix.SetSOTMatrix(scale, ox, oy, oz, pos); data.alignmatrix.SetOMatrix(ox, oy, oz); data.err = OK; data.hFile = Open3DS(filename); if (!data.hFile) { Cleanup3DS(&data); return errors[ERR_OPEN]; } BeginChunk(&data, &chunk); data.filesize = chunk.end; // test if 3ds file if (chunk.id != ID_PRIMARY) { Cleanup3DS(&data); return errors[ERR_NO3DS]; } data.mainactor = actor; data.replacesurface = replacesurf; Parse3DS(&data, &chunk); EndChunk(&data, &chunk); if(data.SetProgress) data.SetProgress(data.rc, (float)ftell(data.hFile)/(float)data.filesize); Cleanup3DS(&data); return errors[data.err]; }
/************* * DESCRIPTION: - * INPUT: pointer to chunk * OUTPUT: - *************/ static void ParseNamedObject(HANDLER_DATA *data, CHUNK *mainchunk) { CHUNK chunk; TRIANGLE *triangle; TRILIST *ph1,*ph2; float angle; UWORD p1, p2, p3; UWORD *edges; int i, h; ReadASCIIZ(data, data->ObjName); do { BeginChunk(data, &chunk); switch (chunk.id) { case ID_TRIANGLE: ParseTriObject(data, &chunk); break; } EndChunk(data, &chunk); } while (INCHUNK); if (data->TriList && (data->link->type == LINK_RENDERER)) { // go through all vertices and calculate normals (only for renderer) for (i = 0; i < data->pointcount; i++) { data->VertNorms[i].x = data->VertNorms[i].y = data->VertNorms[i].z = 0.f; ph1 = data->TriList[i]; while (ph1) { for (ph2 = ph1->next; ph2 != NULL; ph2 = ph2->next) { if (!ph1->flag || !ph2->flag) { // test angle between two triangles angle = VecAngle(data->TriNorms[ph1->tri], data->TriNorms[ph2->tri]); // if (angle < 2*PI && angle > /*cos_*/smooth_angle) if (angle >0 && angle < /*cos_*/data->smooth_angle) { if (!ph1->flag) { VecAdd(&data->VertNorms[i], &data->TriNorms[ph1->tri], &data->VertNorms[i]); ph1->flag = TRUE; data->TriSmooth[ph1->tri] = TRUE; } if (!ph2->flag) { VecAdd(&data->VertNorms[i], &data->TriNorms[ph2->tri], &data->VertNorms[i]); ph2->flag = TRUE; data->TriSmooth[ph2->tri] = TRUE; } } } } ph2 = ph1; ph1 = ph1->next; delete ph2; } VecNormalize(&data->VertNorms[i]); } } if (data->face) { data->link->ObjectBegin(data->rc); data->defaultsurface = data->link->SurfaceAdd(data->rc); if (!data->defaultsurface) { data->err = ERR_MEM; return; } data->link->SurfaceName(data->rc, data->defaultsurface, "default"); data->link->SurfaceDiffuse(data->rc, data->defaultsurface, 0.9f, 0.9f, 0.9f); data->link->SurfaceAmbient(data->rc, data->defaultsurface, 0.1f, 0.1f, 0.1f); data->link->SurfaceRefPhong(data->rc, data->defaultsurface, 49.f); triangle = data->link->TriangleAdd(data->rc, data->facecount,data->defaultsurface,data->mainactor); if (!triangle) { data->err = ERR_MEM; return; } if (data->link->type == LINK_SCENARIO) { // modeler needs points,edges and faces seperate if (data->link->TriangleAddPoints(data->rc, data->pointcount,data->points) == -1) { data->err = ERR_MEM; return; } edges = new UWORD[data->facecount*6]; if (!edges) { data->err = ERR_MEM; return; } for (i = 0; i < data->facecount; i++) { h = i*6; edges[h++] = data->face[i].p1; edges[h++] = data->face[i].p2; edges[h++] = data->face[i].p2; edges[h++] = data->face[i].p3; edges[h++] = data->face[i].p3; edges[h++] = data->face[i].p1; } if (data->link->TriangleAddEdges(data->rc, data->facecount*3,edges) == -1) { delete edges; data->err = ERR_MEM; return; } delete edges; } for (i = 0; i < data->facecount; i++) { p1 = data->face[i].p1; p2 = data->face[i].p3; p3 = data->face[i].p2; if(data->replacesurface) data->link->TriangleSurface(data->rc, triangle, data->replacesurface); else { if(!data->material[i]) data->link->TriangleSurface(data->rc, triangle, data->defaultsurface); else data->link->TriangleSurface(data->rc, triangle, data->material[i]); } if (data->link->type == LINK_SCENARIO) { // modeler needs edges data->link->TriangleSetEdges(data->rc, triangle,i*3,i*3+1,i*3+2); } else { // raystorm renderer needs triangles and normals data->link->TrianglePoints(data->rc, triangle,&data->points[p1],&data->points[p2],&data->points[p3]); if (!VecZero(data->TriNorms[i])) { // generate smooth triangle when smooth flag is set if (data->TriSmooth[i]) { data->link->TriangleVNorm(data->rc, triangle, VecZero(data->VertNorms[p1]) ? &data->TriNorms[i] : &data->VertNorms[p1], VecZero(data->VertNorms[p2]) ? &data->TriNorms[i] : &data->VertNorms[p2], VecZero(data->VertNorms[p3]) ? &data->TriNorms[i] : &data->VertNorms[p3]); } } if(data->mapping) { data->link->TriangleUV(data->rc, triangle, &data->mapping[p1], &data->mapping[p2], &data->mapping[p3]); } } // next triangle triangle = data->link->TriangleGetNext(data->rc, triangle); } data->link->ObjectEnd(data->rc); } CleanupMesh(data); }
/************* * DESCRIPTION: read faces of object * INPUT: pointer to chunk * OUTPUT: - *************/ static void ParseFaces(HANDLER_DATA *data, CHUNK *mainchunk) { CHUNK chunk; UWORD i, matcount, index, p1, p2, p3; VECTOR e1, e2; SURFACE *s; TRILIST *hp; char buf[80]; ReadWord(data, (WORD *)&data->facecount, 1); // read number of faces if (data->facecount == 0) return; data->face = new FACE3DS[data->facecount]; if (!data->face) { data->err = ERR_MEM; return; } if (!data->replacesurface) { data->material = (SURFACE **)malloc(sizeof(SURFACE *)*data->facecount); if (!data->material) { data->err = ERR_MEM; return; } } ReadWord(data, (WORD *)data->face, 4*data->facecount); // read faces if (data->link->type == LINK_RENDERER) { // do it for renderer only data->VertNorms = new VECTOR[data->pointcount]; if (!data->VertNorms) { data->err = ERR_MEM; return; } data->TriNorms = new VECTOR[data->facecount]; if (!data->TriNorms) { data->err = ERR_MEM; return; } memset(data->VertNorms, 0, sizeof(VECTOR)*data->pointcount); // Init normals data->TriSmooth = new UBYTE[data->facecount]; if (!data->TriSmooth) { data->err = ERR_MEM; return; } for (i = 0; i < data->facecount; i++) { if (data->replacesurface) data->material[i] = data->replacesurface; else data->material[i] = NULL; data->TriSmooth[i] = FALSE; // get three points for the triangle p1 = data->face[i].p1; p2 = data->face[i].p3; p3 = data->face[i].p2; hp = new TRILIST; if (!hp) { data->err = ERR_MEM; return; } hp->next = data->TriList[p1]; hp->tri = i; hp->flag = FALSE; data->TriList[p1] = hp; hp = new TRILIST; if (!hp) { data->err = ERR_MEM; return; } hp->next = data->TriList[p2]; hp->tri = i; hp->flag = FALSE; data->TriList[p2] = hp; hp = new TRILIST; if (!hp) { data->err = ERR_MEM; return; } hp->next = data->TriList[p3]; hp->tri = i; hp->flag = FALSE; data->TriList[p3] = hp; // calculate normal of triangle VecSub(&data->points[p3], &data->points[p1], &e1); VecSub(&data->points[p2], &data->points[p1], &e2); VecNormCross(&e1, &e2, &data->TriNorms[i]); } } do { BeginChunk(data, &chunk); switch (chunk.id) { case ID_MSHMATGROUP: if (!data->replacesurface) { ReadASCIIZ(data, buf); s = data->link->SurfaceGetByName(data->rc, buf); ReadWord(data, (WORD*)&matcount, 1); for (i = 0; i < matcount; i++) { ReadWord(data, (WORD*)&index, 1); data->material[index] = s; } } break; case ID_SMOOTHGROUP: // no info about this group break; } EndChunk(data, &chunk); } while (INCHUNK); }
BOOL CGrdLandIO::Read(FILE *Stream) { CHECKTRUE(StartChunk(Stream,"GrdLand")); fpos_t Pos; int PosOk; PosOk = fgetpos(Stream, &Pos ); if(!ReadLong(Stream,"Version",(LONG*)&Version)) { PosOk = fsetpos(Stream, &Pos ); DebugPrint("No Version Number\n"); Version = 0; } m_Version = Version; CHECKTRUE(ReadFloat(Stream,"3DPosition",&m_CameraXPos)); CHECKTRUE(ReadFloat(Stream,NULL,&m_CameraYPos)); CHECKTRUE(ReadFloat(Stream,NULL,&m_CameraZPos)); CHECKTRUE(ReadFloat(Stream,"3DRotation",&m_CameraXRot)); CHECKTRUE(ReadFloat(Stream,NULL,&m_CameraYRot)); CHECKTRUE(ReadFloat(Stream,NULL,&m_CameraZRot)); CHECKTRUE(ReadLong(Stream,"2DPosition",(LONG*)&m_ScrollX)); CHECKTRUE(ReadLong(Stream,NULL,(LONG*)&m_ScrollY)); if(Version >= 1) { CHECKTRUE(ReadLong(Stream,"CustomSnap",(LONG*)&m_SnapX)); CHECKTRUE(ReadLong(Stream,NULL,(LONG*)&m_SnapZ)); CHECKTRUE(ReadLong(Stream,"SnapMode",(LONG*)&m_SnapMode)); CHECKTRUE(ReadLong(Stream,"Gravity",(LONG*)&m_EnableGravity)); } else { m_SnapMode = 0; m_SnapX = 256; m_SnapZ = 256; m_EnableGravity = 1; } CHECKTRUE(ReadLong(Stream,"HeightScale",(LONG*)&m_HeightScale)); CHECKTRUE(ReadLong(Stream,"MapWidth",(LONG*)&m_MapWidth)); CHECKTRUE(ReadLong(Stream,"MapHeight",(LONG*)&m_MapHeight)); CHECKTRUE(ReadLong(Stream,"TileWidth",(LONG*)&m_TileWidth)); CHECKTRUE(ReadLong(Stream,"TileHeight",(LONG*)&m_TileHeight)); if(Version >= 3) { CHECKTRUE(ReadLong(Stream,"SeaLevel",(LONG*)&m_SeaLevel)); } else { m_SeaLevel = 100; } CHECKTRUE(ReadLong(Stream,"TextureWidth",(LONG*)&m_TextureWidth)); CHECKTRUE(ReadLong(Stream,"TextureHeight",(LONG*)&m_TextureHeight)); DWORD NumTextures; DWORD i; CHECKTRUE(ReadLong(Stream,"NumTextures",(LONG*)&NumTextures)); SetNumTextures(NumTextures); CHECKTRUE(StartChunk(Stream,"Textures")); for(i=0; i<NumTextures; i++) { CHECKTRUE(ReadStringAlloc(Stream,NULL,&m_TextureNames[i])); } CHECKTRUE(EndChunk(Stream)); CHECKTRUE(ReadLong(Stream,"NumTiles",(LONG*)&m_NumTiles)); m_Tiles = new CGrdTileIO*[m_NumTiles]; CHECKTRUE(StartChunk(Stream,"Tiles")); for(i=0; i<m_NumTiles; i++) { m_Tiles[i] = new CGrdTileIO; m_Tiles[i]->Read(Stream); } CHECKTRUE(EndChunk(Stream)); CHECKTRUE(EndChunk(Stream)); return TRUE; }