123
This commit is contained in:
498
ResourceCompilerPC/StatCGFCompiler/CryStaticModel.cpp
Normal file
498
ResourceCompilerPC/StatCGFCompiler/CryStaticModel.cpp
Normal file
@@ -0,0 +1,498 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: crystaticmodel.cpp
|
||||
// Version: v1.00
|
||||
// Created: 28/5/2001 by Vladimir Kajalin
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description: load cgf file
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "CryStaticModel.h"
|
||||
|
||||
#include "baseobj.h"
|
||||
#include "node.h"
|
||||
#include "geom.h"
|
||||
#include "helper.h"
|
||||
#include "light.h"
|
||||
|
||||
#include "file.h"
|
||||
#include "IRCLog.h"
|
||||
|
||||
CryStaticModel::CryStaticModel()
|
||||
{
|
||||
memset( this,0,sizeof(*this) );
|
||||
}
|
||||
|
||||
CryStaticModel::~CryStaticModel()
|
||||
{
|
||||
for( int i=0; i<m_nNewObjs; i++)
|
||||
{
|
||||
CNodeCGF * pNode = (CNodeCGF*)m_ppNewObjs[i];
|
||||
delete pNode;
|
||||
}
|
||||
|
||||
if(m_ppNewObjs)
|
||||
free(m_ppNewObjs);
|
||||
m_ppNewObjs=0;
|
||||
}
|
||||
|
||||
void CryStaticModel::LoadMaterials(CXFile*f, int pos)
|
||||
{
|
||||
if(f->FSeek(pos,SEEK_SET))
|
||||
return;
|
||||
|
||||
CHUNK_HEADER ch;
|
||||
int res = f->FRead(&ch,1,sizeof(ch));
|
||||
if (ch.ChunkVersion == MTL_CHUNK_DESC_0746::VERSION)
|
||||
{
|
||||
f->FSeek(pos,SEEK_SET);
|
||||
MTL_CHUNK_DESC_0746 chunk;
|
||||
int res=f->FRead(&chunk,1,sizeof(chunk));
|
||||
if(res!=sizeof(chunk))
|
||||
return;
|
||||
|
||||
MAT_ENTITY me;
|
||||
memset(&me, 0, sizeof(MAT_ENTITY));
|
||||
me.opacity = 1.0f;
|
||||
me.alpharef = 0;
|
||||
me.m_New = 2;
|
||||
strcpy(me.name, chunk.name);
|
||||
switch (chunk.MtlType)
|
||||
{
|
||||
case MTL_STANDARD:
|
||||
me.IsStdMat = true;
|
||||
me.col_d = chunk.col_d;
|
||||
me.col_a = chunk.col_a;
|
||||
me.col_s = chunk.col_s;
|
||||
|
||||
me.specLevel = chunk.specLevel;
|
||||
me.specShininess = chunk.specShininess*100;
|
||||
me.opacity = chunk.opacity;
|
||||
me.selfIllum = chunk.selfIllum;
|
||||
me.flags = chunk.flags;
|
||||
if (me.flags & MTLFLAG_CRYSHADER)
|
||||
me.alpharef = chunk.alphaTest;
|
||||
|
||||
me.Dyn_Bounce = chunk.Dyn_Bounce;
|
||||
me.Dyn_StaticFriction = chunk.Dyn_StaticFriction;
|
||||
me.Dyn_SlidingFriction = chunk.Dyn_SlidingFriction;
|
||||
/* //Timur[10/24/2001]
|
||||
strcpy(me.map_a, chunk.tex_a.name);
|
||||
strcpy(me.map_d, chunk.tex_d.name);
|
||||
strcpy(me.map_o, chunk.tex_o.name);
|
||||
strcpy(me.map_b, chunk.tex_b.name);
|
||||
strcpy(me.map_s, chunk.tex_s.name);
|
||||
strcpy(me.map_g, chunk.tex_g.name);
|
||||
strcpy(me.map_c, chunk.tex_c.name);
|
||||
strcpy(me.map_e, chunk.tex_rl.name);
|
||||
strcpy(me.map_rr, chunk.tex_rr.name);
|
||||
strcpy(me.map_det, chunk.tex_det.name);
|
||||
*/
|
||||
me.map_a = chunk.tex_a;
|
||||
me.map_d = chunk.tex_d;
|
||||
me.map_o = chunk.tex_o;
|
||||
me.map_b = chunk.tex_b;
|
||||
me.map_s = chunk.tex_s;
|
||||
me.map_g = chunk.tex_g;
|
||||
me.map_detail = chunk.tex_fl;
|
||||
me.map_e = chunk.tex_rl;
|
||||
me.map_subsurf = chunk.tex_subsurf;
|
||||
me.map_displ = chunk.tex_det;
|
||||
|
||||
me.nChildren = chunk.nChildren;
|
||||
|
||||
m_lstMaterials.Add(me);
|
||||
break;
|
||||
|
||||
/* case MTL_MULTI:
|
||||
me.IsStdMat = 0;
|
||||
me.nChildren = chunk.nChildren;
|
||||
me.children = new int [chunk.nChildren];
|
||||
int res=f->FRead(me.children,sizeof(int),chunk.nChildren);
|
||||
if (res != chunk.nChildren)
|
||||
return;*/
|
||||
}
|
||||
}
|
||||
else
|
||||
if (ch.ChunkVersion == MTL_CHUNK_DESC_0745::VERSION)
|
||||
{
|
||||
f->FSeek(pos,SEEK_SET);
|
||||
MTL_CHUNK_DESC_0745 chunk;
|
||||
int res=f->FRead(&chunk,1,sizeof(chunk));
|
||||
if(res!=sizeof(chunk))
|
||||
return;
|
||||
|
||||
MAT_ENTITY me;
|
||||
memset(&me, 0, sizeof(MAT_ENTITY));
|
||||
me.opacity = 1.0f;
|
||||
me.alpharef = 0;
|
||||
me.m_New = 1;
|
||||
strcpy(me.name, chunk.name);
|
||||
switch (chunk.MtlType)
|
||||
{
|
||||
case MTL_STANDARD:
|
||||
me.IsStdMat = true;
|
||||
me.col_d = chunk.col_d;
|
||||
me.col_a = chunk.col_a;
|
||||
me.col_s = chunk.col_s;
|
||||
|
||||
me.specLevel = chunk.specLevel;
|
||||
me.specShininess = chunk.specShininess*100;
|
||||
me.opacity = chunk.opacity;
|
||||
me.selfIllum = chunk.selfIllum;
|
||||
me.flags = chunk.flags;
|
||||
|
||||
me.Dyn_Bounce = chunk.Dyn_Bounce;
|
||||
me.Dyn_StaticFriction = chunk.Dyn_StaticFriction;
|
||||
me.Dyn_SlidingFriction = chunk.Dyn_SlidingFriction;
|
||||
/* //Timur[10/24/2001]
|
||||
strcpy(me.map_a, chunk.tex_a.name);
|
||||
strcpy(me.map_d, chunk.tex_d.name);
|
||||
strcpy(me.map_o, chunk.tex_o.name);
|
||||
strcpy(me.map_b, chunk.tex_b.name);
|
||||
strcpy(me.map_s, chunk.tex_s.name);
|
||||
strcpy(me.map_g, chunk.tex_g.name);
|
||||
strcpy(me.map_c, chunk.tex_c.name);
|
||||
strcpy(me.map_e, chunk.tex_rl.name);
|
||||
strcpy(me.map_rr, chunk.tex_rr.name);
|
||||
strcpy(me.map_det, chunk.tex_det.name);
|
||||
*/
|
||||
me.map_a = chunk.tex_a;
|
||||
me.map_d = chunk.tex_d;
|
||||
me.map_o = chunk.tex_o;
|
||||
me.map_b = chunk.tex_b;
|
||||
me.map_s = chunk.tex_s;
|
||||
me.map_g = chunk.tex_g;
|
||||
me.map_detail = chunk.tex_c;
|
||||
me.map_e = chunk.tex_rl;
|
||||
me.map_subsurf = chunk.tex_subsurf;
|
||||
me.map_displ = chunk.tex_det;
|
||||
|
||||
me.nChildren = chunk.nChildren;
|
||||
|
||||
m_lstMaterials.Add(me);
|
||||
break;
|
||||
|
||||
/* case MTL_MULTI:
|
||||
me.IsStdMat = 0;
|
||||
me.nChildren = chunk.nChildren;
|
||||
me.children = new int [chunk.nChildren];
|
||||
int res=f->FRead(me.children,sizeof(int),chunk.nChildren);
|
||||
if (res != chunk.nChildren)
|
||||
return;*/
|
||||
}
|
||||
}
|
||||
else
|
||||
if (ch.ChunkVersion == MTL_CHUNK_DESC_0744::VERSION)
|
||||
{
|
||||
f->FSeek(pos,SEEK_SET);
|
||||
MTL_CHUNK_DESC_0744 chunk;
|
||||
int res=f->FRead(&chunk,1,sizeof(chunk));
|
||||
if(res!=sizeof(chunk))
|
||||
return;
|
||||
|
||||
MAT_ENTITY me;
|
||||
memset(&me, 0, sizeof(MAT_ENTITY));
|
||||
me.opacity = 1.0f;
|
||||
me.alpharef = 0;
|
||||
strcpy(me.name, chunk.name);
|
||||
switch (chunk.MtlType)
|
||||
{
|
||||
case MTL_STANDARD:
|
||||
me.IsStdMat = true;
|
||||
me.col_d = chunk.col_d;
|
||||
me.col_a = chunk.col_a;
|
||||
me.col_s = chunk.col_s;
|
||||
me.Dyn_Bounce = chunk.Dyn_Bounce;
|
||||
me.Dyn_StaticFriction = chunk.Dyn_StaticFriction;
|
||||
me.Dyn_SlidingFriction = chunk.Dyn_SlidingFriction;
|
||||
strcpy(me.map_d.name, chunk.tex_d.name);
|
||||
strcpy(me.map_o.name, chunk.tex_o.name);
|
||||
strcpy(me.map_b.name, chunk.tex_b.name);
|
||||
me.nChildren = chunk.nChildren;
|
||||
|
||||
m_lstMaterials.Add(me);
|
||||
break;
|
||||
|
||||
case MTL_MULTI:
|
||||
me.IsStdMat = 0;
|
||||
me.nChildren = chunk.nChildren;
|
||||
me.m_pMaterialChildren = new int [chunk.nChildren];//leak
|
||||
int res=f->FRead(me.m_pMaterialChildren,sizeof(int),chunk.nChildren);
|
||||
if (res != chunk.nChildren)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CryStaticModel::OnLoadgeom(char * FileName, const char * szGeomName, bool bLoadMats, bool bKeepInLocalSpace)
|
||||
{
|
||||
CXFile * f = new CXFile();
|
||||
|
||||
// preload all data
|
||||
if(!f->FLoad(FileName))
|
||||
{
|
||||
delete f; return 0;
|
||||
}
|
||||
|
||||
//read the file header
|
||||
FILE_HEADER fh;
|
||||
int res = f->FRead(&fh,sizeof(fh),1);
|
||||
if(res!=1)
|
||||
return 0;
|
||||
|
||||
if(fh.Version != GeomFileVersion)
|
||||
{
|
||||
f->FClose(); delete f; f=0;
|
||||
m_pLog->LogError("CryStaticModel::OnLoadgeom: CGF file version error: %s", FileName);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(fh.FileType != FileType_Geom)
|
||||
{
|
||||
f->FClose(); delete f; f=0;
|
||||
m_pLog->LogError("OnLoadgeom: CGF file type error: %s", FileName);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//read the chunk table
|
||||
f->FSeek(fh.ChunkTableOffset,SEEK_SET);
|
||||
int n_chunks=100000;
|
||||
res = f->FRead(&n_chunks,sizeof(n_chunks),1);
|
||||
if(res!=1)
|
||||
return 0;
|
||||
|
||||
if(n_chunks>=100000)
|
||||
{
|
||||
f->FClose(); delete f; f=0;
|
||||
m_pLog->LogError("CryStaticModel::OnLoadgeom: File corrupted: %s, (n_chunks>=100000)", FileName);
|
||||
return 0;
|
||||
}
|
||||
|
||||
CHUNK_HEADER * pChunks;
|
||||
pChunks=(CHUNK_HEADER *)malloc(sizeof(CHUNK_HEADER)*n_chunks);
|
||||
assert(pChunks);
|
||||
res = f->FRead(pChunks,sizeof(CHUNK_HEADER),n_chunks);
|
||||
if(res!=n_chunks)
|
||||
return 0;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Create and load objects
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
m_ppNewObjs = (CBaseObj **)malloc(n_chunks*sizeof(CBaseObj*));
|
||||
memset(m_ppNewObjs,0,n_chunks*sizeof(CBaseObj*));
|
||||
|
||||
assert(m_ppNewObjs);
|
||||
m_nNewObjs=0;
|
||||
|
||||
int nGeomToLoadID = -1;
|
||||
|
||||
int i;
|
||||
for(i=0;i<n_chunks;i++)
|
||||
{
|
||||
switch(pChunks[i].ChunkType)
|
||||
{
|
||||
case ChunkType_Node:
|
||||
m_ppNewObjs[m_nNewObjs]=new CNodeCGF();
|
||||
break;
|
||||
|
||||
case ChunkType_Mesh:
|
||||
if(!szGeomName || nGeomToLoadID == i)
|
||||
m_ppNewObjs[m_nNewObjs]=new CGeom();
|
||||
break;
|
||||
|
||||
case ChunkType_Helper:
|
||||
m_ppNewObjs[m_nNewObjs]=new CHelper();
|
||||
break;
|
||||
|
||||
case ChunkType_Light:
|
||||
m_ppNewObjs[m_nNewObjs]=new CLight();
|
||||
break;
|
||||
|
||||
case ChunkType_Mtl:
|
||||
if(bLoadMats)
|
||||
LoadMaterials(f,pChunks[i].FileOffset);
|
||||
break;
|
||||
}
|
||||
|
||||
if(m_ppNewObjs[m_nNewObjs])
|
||||
{
|
||||
m_ppNewObjs[m_nNewObjs]->Load(f,pChunks[i].FileOffset);
|
||||
|
||||
// find chunk id of needed geom
|
||||
if(pChunks[i].ChunkType == ChunkType_Node)
|
||||
if(szGeomName && strcmp(szGeomName,((CNodeCGF*)m_ppNewObjs[m_nNewObjs])->m_Chunk.name)==0)
|
||||
nGeomToLoadID = ((CNodeCGF*)m_ppNewObjs[m_nNewObjs])->m_Chunk.ObjectID;
|
||||
|
||||
m_nNewObjs++;
|
||||
}
|
||||
}
|
||||
|
||||
//Do pointer and name list bindings
|
||||
for(i=0;i<m_nNewObjs;i++)
|
||||
{
|
||||
if(!m_ppNewObjs[i])
|
||||
continue;
|
||||
m_ppNewObjs[i]->Bind(m_ppNewObjs, m_nNewObjs);
|
||||
}
|
||||
|
||||
f->FClose(); delete f; f=0;
|
||||
|
||||
if(pChunks)
|
||||
free(pChunks);
|
||||
pChunks=0;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Make objects
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
list2<NAME_ENTITY> lstOtherNames;
|
||||
|
||||
for( i=0; i<m_nNewObjs; i++)
|
||||
{
|
||||
CNodeCGF * pNode = (CNodeCGF*)m_ppNewObjs[i];
|
||||
|
||||
if(pNode->m_ChunkHeader.ChunkType != ChunkType_Node)
|
||||
continue;
|
||||
|
||||
// make list of mesh names
|
||||
NAME_ENTITY geomname;
|
||||
strcpy(geomname.name, pNode->m_Chunk.name);
|
||||
lstOtherNames.Add(geomname);
|
||||
|
||||
if(!pNode->m_pObj)
|
||||
continue;
|
||||
|
||||
if(pNode->m_pObj->m_nUsers>1)
|
||||
m_pLog->Log("WARNING: loading of instances from cgf not supported, geom skipped: %s, %s",FileName, pNode->GetName());
|
||||
|
||||
// Accumulate this and all parent nodes transformations
|
||||
// TODO: get rid of the obsolete CryMatrix here
|
||||
|
||||
//CHANGED_BY_IVO
|
||||
//CryMatrix matNodeMatrix = pNode->m_Chunk.tm;
|
||||
Matrix44 matNodeMatrix = pNode->m_Chunk.tm;
|
||||
|
||||
for(CNodeCGF * pCurNode = pNode->m_pParent; pCurNode; pCurNode = pCurNode->m_pParent)
|
||||
//CHANGED_BY_IVO
|
||||
//matNodeMatrix = matNodeMatrix * (CryMatrix&)(pCurNode->m_Chunk.tm);
|
||||
matNodeMatrix = matNodeMatrix * (pCurNode->m_Chunk.tm);
|
||||
|
||||
if(pNode->m_pObj->m_ChunkHeader.ChunkType == ChunkType_Mesh)
|
||||
if(pNode->m_pObj->m_nUsers<=1)
|
||||
{ // geoms
|
||||
// make list of mesh names
|
||||
NAME_ENTITY geomname;
|
||||
strcpy(geomname.name, pNode->m_Chunk.name);
|
||||
m_lstGeomNames.Add(geomname);
|
||||
lstOtherNames.DeleteLast();
|
||||
|
||||
CGeom * pGeom = (CGeom*)pNode->m_pObj;
|
||||
|
||||
// transform geometry from this node space into CGFs space
|
||||
if(!bKeepInLocalSpace)
|
||||
for(int v=0; v<pGeom->m_Chunk.nVerts; v++)
|
||||
{
|
||||
//CHANGED_BY_IVO
|
||||
//pGeom->m_pVertices[v].p = matNodeMatrix*pGeom->m_pVertices[v].p;
|
||||
//pGeom->m_pVertices[v].n = matNodeMatrix/pGeom->m_pVertices[v].n;
|
||||
pGeom->m_pVertices[v].p = matNodeMatrix.TransformPointOLD(pGeom->m_pVertices[v].p);
|
||||
pGeom->m_pVertices[v].n = matNodeMatrix.TransformVectorOLD(pGeom->m_pVertices[v].n);
|
||||
}
|
||||
|
||||
if(!szGeomName || strcmp(pNode->GetName(),szGeomName)==0)
|
||||
m_lstGeoms.Add(pGeom);
|
||||
}
|
||||
|
||||
if(pNode->m_pObj->m_ChunkHeader.ChunkType == ChunkType_Light)
|
||||
{ // make light
|
||||
CLight * pLight = (CLight*)pNode->m_pObj;
|
||||
|
||||
LightInstance inst;
|
||||
memcpy(&inst.Chunk,&pLight->m_Chunk,sizeof(LIGHT_CHUNK_DESC));
|
||||
inst.Chunk = pLight->m_Chunk;
|
||||
|
||||
if(bKeepInLocalSpace)
|
||||
|
||||
//inst.vPos.Set(&pNode->m_Chunk.pos.x);
|
||||
inst.vPos.Set(pNode->m_Chunk.pos[0],pNode->m_Chunk.pos[1],pNode->m_Chunk.pos[2]);
|
||||
|
||||
else
|
||||
//CHANGED_BY_IVO
|
||||
//inst.vPos = Vec3d(matNodeMatrix.data[3]);
|
||||
inst.vPos = matNodeMatrix.GetTranslationOLD();
|
||||
|
||||
if(!pNode->m_pParent)
|
||||
assert( IsEquivalent(pNode->m_Chunk.pos,inst.vPos,VEC_EPSILON) );
|
||||
|
||||
strncpy(inst.szName,pNode->m_Chunk.name, sizeof(inst.szName));
|
||||
|
||||
// load proj texture
|
||||
if(inst.Chunk.szLightImage[0])
|
||||
{
|
||||
assert(0);
|
||||
inst.pLightImage = 0;//GetRenderer()->EF_LoadTexture(inst.Chunk.szLightImage, FT_CLAMP, FT2_FORCECUBEMAP, eTT_Cubemap);
|
||||
if (!inst.pLightImage->IsTextureLoaded())
|
||||
inst.pLightImage = NULL;
|
||||
}
|
||||
else
|
||||
inst.pLightImage = NULL;
|
||||
|
||||
m_lstLights.Add(inst);
|
||||
}
|
||||
|
||||
if(pNode->m_pObj->m_ChunkHeader.ChunkType == ChunkType_Helper)
|
||||
{ // make helper
|
||||
CHelper * pHelper = (CHelper*)pNode->m_pObj;
|
||||
|
||||
HelperInstance inst;
|
||||
inst.Chunk = pHelper->m_Chunk;
|
||||
|
||||
if(bKeepInLocalSpace)
|
||||
inst.tMat.SetIdentity();
|
||||
else
|
||||
//CHANGED_BY_IVO
|
||||
//inst.tMat = Matrix(matNodeMatrix.matrix);
|
||||
inst.tMat = matNodeMatrix;
|
||||
|
||||
/*
|
||||
if(!pNode->m_pParent)
|
||||
{
|
||||
assert(inst.vPos == pNode->m_Chunk.pos);
|
||||
float dot = inst.qRot.Dot(pNode->m_Chunk.rot);
|
||||
dot=dot;
|
||||
}
|
||||
*/
|
||||
strncpy(inst.szName,pNode->m_Chunk.name, sizeof(inst.szName));
|
||||
m_lstHelpers.Add(inst);
|
||||
}
|
||||
}
|
||||
|
||||
m_lstGeomNames.AddList (lstOtherNames);
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
CHelperInstance * CryStaticModel::GetHelper(const char * name)
|
||||
{
|
||||
for(int i=0; i<m_Helpers.Count(); i++)
|
||||
{
|
||||
if(!strcmp(m_Helpers[i].name,name))
|
||||
return &m_Helpers[i];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
// this timer measures the time spent in the CGF Loader
|
||||
//double g_dTimeLoadCGF;
|
||||
Reference in New Issue
Block a user