//////////////////////////////////////////////////////////////////////////// // // Crytek Engine Source File. // Copyright (C), Crytek Studios, 2002. // ------------------------------------------------------------------------- // File name: savecfg.cpp // Version: v1.00 // Created: 28/5/2002 by Andrey // Compilers: Visual Studio.NET // Description: cgf file writer // ------------------------------------------------------------------------- // History: // //////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "3dEngine.h" #include "CryStaticModel.h" #include "statobj.h" #include "MeshIdx.h" bool C3DEngine::WriteMaterials(TArray& Chunks, TArray& Shaders, FILE *out, int &MatChunk) { CHUNK_HEADER ch; // the type and version of the material chunk typedef MTL_CHUNK_DESC_0745 MTL_CHUNK_TYPE; MTL_CHUNK_TYPE chunk; memset (&chunk, 0, sizeof(chunk)); int Offs = ftell(out); ch.ChunkType = ChunkType_Mtl; ch.ChunkID = Chunks.Num(); MatChunk = ch.ChunkID; ch.ChunkVersion = MTL_CHUNK_TYPE::VERSION; ch.FileOffset = Offs; Offs += sizeof(chunk) + sizeof(int) * Shaders.Num(); Chunks.AddElem(ch); int i=0; for (i=0; iGetName()); if (sh->GetTemplates()) { SEfTemplates *eft = sh->GetTemplates(); for (int j=0; j<16; j++) { if (!eft->m_TexInfo[j].m_Name.empty()) { switch (j) { case EFTT_DECAL: strcpy(chunk.tex_d.name, eft->m_TexInfo[j].m_Name); break; case EFTT_BUMP: case EFTT_DSDTBUMP: strcpy(chunk.tex_b.name, eft->m_TexInfo[j].m_Name); break; case EFTT_GLOSS: strcpy(chunk.tex_g.name, eft->m_TexInfo[j].m_Name); break; case EFTT_OPACITY: strcpy(chunk.tex_o.name, eft->m_TexInfo[j].m_Name); break; case EFTT_ENVIRONMENT: case EFTT_REFLECTION: strcpy(chunk.tex_rl.name, eft->m_TexInfo[j].m_Name); break; case EFTT_REFRACTION: strcpy(chunk.tex_rr.name, eft->m_TexInfo[j].m_Name); break; case EFTT_CUBEMAP: strcpy(chunk.tex_c.name, eft->m_TexInfo[j].m_Name); break; case EFTT_SPECULAR: strcpy(chunk.tex_s.name, eft->m_TexInfo[j].m_Name); break; case EFTT_DETAIL: strcpy(chunk.tex_det.name, eft->m_TexInfo[j].m_Name); break; } } } } else strcpy(chunk.tex_d.name, chunk.name); chunk.Dyn_Bounce = 1; chunk.Dyn_StaticFriction = 1; chunk.Dyn_SlidingFriction = 1; chunk.nChildren = -1; fwrite(&chunk, 1, sizeof(chunk), out); }*/ return true; } struct SNodeInfo { int bGlobals; int Sector; CStatObj *pObj; char name[64]; }; bool C3DEngine::WriteNodes(TArray& Chunks, TArray& Nodes, FILE *out, TArray& NI, int& MatChunk, int& ExpFrame, std::vector& pObjs) { CHUNK_HEADER ch; int numMeshs = 0; NODE_CHUNK_DESC nd; SNodeInfo ni; int i; NI.Free(); ExpFrame++; int nChildren; std::vector::iterator n; for (n=pObjs.begin();n!=pObjs.end();n++) { IStatObj *io = (*n); CStatObj *co = (CStatObj *)io; memset(&nd, 0, sizeof(NODE_CHUNK_DESC)); strcpy(nd.name, co->m_szGeomName); nd.tm.SetIdentity(); nd.scl = Vec3(1.0,1.0,1.0); nd.MatID = MatChunk; nd.ObjectID = numMeshs++; int nnd = Nodes.Num(); Nodes.AddElem(nd); ni.bGlobals = 1; ni.pObj = co; strcpy(ni.name, nd.name); NI.AddElem(ni); nChildren = 0; Nodes[nnd].nChildren = nChildren; } memset(&ch, 0, sizeof(CHUNK_HEADER)); int no = Chunks.Num() + Nodes.Num(); for (i=0; i& Shaders, TArray& NI, CStatObj *pObj) { TArray Verts; TArray Faces; TArray UVs; TArray TFaces; TArray Colors; int i, j; SNodeInfo *ni = &NI[nNode]; CIndexedMesh *pMesh = pObj->GetTriData(); for (i=0; im_nFaceCount; i++) { CryFace fc; CryTexFace tf; fc.v0 = pMesh->m_pFaces[i].v[0]; fc.v1 = pMesh->m_pFaces[i].v[1]; fc.v2 = pMesh->m_pFaces[i].v[2]; tf.t0 = pMesh->m_pFaces[i].t[0]; tf.t1 = pMesh->m_pFaces[i].t[1]; tf.t2 = pMesh->m_pFaces[i].t[2]; int ns = pMesh->m_pFaces[i].shader_id; IShader *sh = pMesh->m_lstMatTable[ns].shaderItem.m_pShader; for (j=0; jGetName(), Shaders[j]->GetName())) break; } assert (j != Shaders.Num()); fc.MatID = j; fc.SmGroup = 0; Faces.AddElem(fc); TFaces.AddElem(tf); } for (i=0; im_nVertCount; i++) { CryVertex vr; CryIRGB rgb; vr.p[0] = pMesh->m_pVerts[i].x * 100.0f; vr.p[1] = pMesh->m_pVerts[i].y * 100.0f; vr.p[2] = pMesh->m_pVerts[i].z * 100.0f; vr.n[0] = pMesh->m_pNorms[i].x; vr.n[1] = pMesh->m_pNorms[i].y; vr.n[2] = pMesh->m_pNorms[i].z; rgb.r = pMesh->m_pColor[i].r; rgb.g = pMesh->m_pColor[i].g; rgb.b = pMesh->m_pColor[i].b; Verts.AddElem(vr); Colors.AddElem(rgb); } for (i=0; im_nCoorCount; i++) { CryUV uv; uv.u = pMesh->m_pCoors[i].s; uv.v = pMesh->m_pCoors[i].t; UVs.AddElem(uv); } chunk->nFaces = Faces.Num(); chunk->nTVerts = UVs.Num(); chunk->nVerts = Verts.Num(); chunk->VertAnimID = 0; if (Colors.Num()) chunk->HasVertexCol = 1; else chunk->HasVertexCol = 0; fwrite(chunk, 1, sizeof(MESH_CHUNK_DESC), out); fwrite(&Verts[0], sizeof(CryVertex), chunk->nVerts, out); fwrite(&Faces[0], sizeof(CryFace), chunk->nFaces, out); fwrite(&UVs[0], sizeof(CryUV), chunk->nTVerts, out); fwrite(&TFaces[0], sizeof(CryTexFace), chunk->nFaces, out); if (chunk->HasVertexCol) fwrite(&Colors[0], sizeof(CryIRGB), chunk->nVerts, out); return true; } bool C3DEngine::WriteMesh(TArray& Chunks, TArray& Nodes, TArray& Shaders, FILE *out, TArray& NI, int& MatChunk, int& ExpFrame) { MESH_CHUNK_DESC chunk; CHUNK_HEADER ch; ExpFrame++; for (int i=0; ipObj); } return true; } bool C3DEngine::WriteLights(TArray& Chunks, TArray& Nodes, FILE *out, std::vector& pObjs) { LIGHT_CHUNK_DESC lcd; CHUNK_HEADER ch; NODE_CHUNK_DESC nd; std::vector::iterator n; for (n=pObjs.begin();n!=pObjs.end();n++) { IStatObj *io = (*n); CStatObj *co = (CStatObj *)io; // CIndexedMesh *im = co->GetTriData(); for (int j=0; jm_lstLSources.Count(); j++) { CDLight *dl = &co->m_lstLSources[j]; memset(&lcd, 0, sizeof(LIGHT_CHUNK_DESC)); memset(&ch, 0, sizeof(CHUNK_HEADER)); memset(&nd, 0, sizeof(NODE_CHUNK_DESC)); int no = Chunks.Num(); ch.ChunkType = ChunkType_Node; ch.ChunkID = Chunks.Num(); ch.ChunkVersion = NODE_CHUNK_DESC_VERSION; ch.FileOffset = ftell(out); Chunks.AddElem(ch); nd.chdr = ch; nd.ObjectID = Chunks.Num(); if (dl->m_Name) strcpy(nd.name, dl->m_Name); else nd.name[0] = 0; Vec3d Org; /* if (dl->m_OrigLight) Org = dl->m_OrigLight->m_Origin; else Org = dl->m_Origin; */ nd.pos.x = Org[0] * 100.0f; nd.pos.y = Org[1] * 100.0f; nd.pos.z = Org[2] * 100.0f; nd.tm.SetIdentity(); nd.tm[3][0] = nd.pos.x; nd.tm[3][1] = nd.pos.y; nd.tm[3][2] = nd.pos.z; nd.scl = Vec3(1.0f, 1.0f, 1.0f); fwrite(&nd, sizeof(NODE_CHUNK_DESC), 1, out); // Light ch.ChunkType = ChunkType_Light; ch.ChunkID = Chunks.Num(); ch.ChunkVersion = LIGHT_CHUNK_DESC_VERSION; ch.FileOffset = ftell(out); Chunks.AddElem(ch); lcd.chdr = ch; lcd.intens = dl->m_fRadius * 100.0f; if (lcd.intens <= 0) lcd.intens = 500; lcd.attenEnd = lcd.intens; UCol col; col.dcolor = dl->m_Color.GetTrue(); lcd.color.r = col.bcolor[0]; lcd.color.g = col.bcolor[1]; lcd.color.b = col.bcolor[2]; lcd.vDirection = dl->m_ProjAngles; lcd.fallsize = dl->m_fLightFrustumAngle; if (dl->m_pLightImage) { strcpy(lcd.szLightImage, dl->m_pLightImage->GetName()); lcd.type = LT_OMNI; } else if (dl->m_Flags & DLF_DIRECTIONAL) lcd.type = LT_DIRECT; else if (dl->m_Flags & DLF_POINT) { lcd.useAtten = true; lcd.type = LT_OMNI; } fwrite(&lcd, sizeof(LIGHT_CHUNK_DESC), 1, out); } } return true; } bool C3DEngine::SaveCGF(std::vector& pObjs) { TArray Chunks; TArray Nodes; TArray Shaders; TArray NI; int ExpFrame = 0; char fName[1024]; int res; int i, j; int MatChunk; if (pObjs.empty()) return false; IStatObj *io = pObjs.front(); CStatObj *so = (CStatObj *)io; // Remove extension char *in = so->m_szFileName; char *o = fName; char c; while (*in) { if (*in=='.') { c = in[1]; if (c!='.' && c!='/' && c!='\\') break; } *o++ = *in++; } *o = 0; // Add default extension strcat(fName, ".cgf"); FILE *out = fxopen(fName, "wb"); if (!out) return false; FILE_HEADER hd; strcpy(hd.Signature, FILE_SIGNATURE); hd.Version = GeomFileVersion; hd.FileType = FileType_Geom; //write the header res = fwrite(&hd, sizeof(hd), 1, out); if(res != 1) return false; std::vector::iterator n; for (n=pObjs.begin();n!=pObjs.end();n++) { IStatObj *io = (*n); CStatObj *co = (CStatObj *)io; CLeafBuffer *lb = co->GetLeafBuffer(); // Prepare shaders for write for (i=0; im_pMats->Count(); i++) { IShader *e = (*lb->m_pMats)[i].shaderItem.m_pShader; if (!e) continue; for (j=0; jGetName(), Shaders[j]->GetName())) break; } if (j == Shaders.Num()) Shaders.AddElem(e); } } WriteMaterials(Chunks, Shaders, out, MatChunk); WriteNodes(Chunks, Nodes, out, NI, MatChunk, ExpFrame, pObjs); WriteMesh(Chunks, Nodes, Shaders, out, NI, MatChunk, ExpFrame); Nodes.Free(); WriteLights(Chunks, Nodes, out, pObjs); hd.ChunkTableOffset = ftell(out); int nn = Chunks.Num(); fwrite(&nn, sizeof(int), 1, out); for (i=0; i