#include #include #include "gintex.h" #include "Maths.h" using namespace std; /*****************************************************************************/ /*****************************************************************************/ /*****************************************************************************/ // Unconditional string compare // REturns 1 on equal int IsStrSame(char *Str0,char *Str1,int Len) { if (Len==-1) { Len=strlen(Str0); if (strlen(Str1)!=Len) return(0); } for (int Loop=0;Loop='a' && C0<='z') C0+='A'-'a'; if (C1>='a' && C1<='z') C1+='A'-'a'; if (C0!=C1) return(0); } return(1); } /*****************************************************************************/ /*****************************************************************************/ /*****************************************************************************/ int CMat4::GetTexId(int v) { int NumOfTextures; NumOfTextures=Mats.size(); if (v>=NumOfTextures) { GObject::Error(ERR_WARNING,"erroneous material id of %d\n",v); v = 0; } if (v>=NumOfTextures) GObject::Error(ERR_FATAL,"material asked for when none exists",v); return Mats[v].TexId; } /*****************************************************************************/ /*****************************************************************************/ /*****************************************************************************/ void CMat4::Load(Gifstream & In) { int m = In.Get32(); int o = In.Get32(); Mats.resize(m); for (int i=0; i Str; bool Done; Str.reserve(200); Done=false; In.Align(4); while (!Done) { char c; c=In.get(); if (!c) Done=true; Str.push_back(c); } Names.push_back(&Str[0]); } } /*****************************************************************************/ /*****************************************************************************/ /*****************************************************************************/ void CGinTree::Load(Gifstream & In) { LoadTree(In,-1); } /*****************************************************************************/ void CGinTree::LoadTree(Gifstream & In,int Parent) { CNode ThisNode; In.Align(4); In.read(ThisNode.Name, 32); In.read((char*)&ThisNode.XPos, 4); In.read((char*)&ThisNode.YPos, 4); In.read((char*)&ThisNode.ZPos, 4); In.read((char*)&ThisNode.XAng, 4); In.read((char*)&ThisNode.YAng, 4); In.read((char*)&ThisNode.ZAng, 4); In.read((char*)&ThisNode.WAng, 4); In.read((char*)&ThisNode.Xapk, 4); In.read((char*)&ThisNode.Yapk, 4); In.read((char*)&ThisNode.Zapk, 4); In.read((char*)&ThisNode.Xapu, 4); In.read((char*)&ThisNode.Yapu, 4); In.read((char*)&ThisNode.Zapu, 4); In.read((char*)&ThisNode.Wapu, 4); int ChildCount= In.Get32(); SceneTree[0].AddChild( SceneTree,ThisNode,Parent); int Idx=ThisNode.Idx; for (int Loop=0;Loop &VersionChunk=GinFile.GetVersionChunk(); std::vector &TexNamesChunk=GinFile.GetTexNamesChunk(); std::vector &MatChunk=GinFile.GetMatChunk(); std::vector &MshChunk=GinFile.GetMshChunk(); std::vector &PointsChunk=GinFile.GetPointsChunk(); std::vector &TrisChunk=GinFile.GetTrisChunk(); std::vector &VColTrisChunk=GinFile.GetVColTrisChunk(); std::vector &UVtrisChunk=GinFile.GetUVtrisChunk(); std::vector &SceneTreeChunk=GinFile.GetSceneTreeChunk(); std::vector &AnimTreeChunk=GinFile.GetAnimTreeChunk(); std::vector &KeyAnimTreeChunk=GinFile.GetKeyAnimTreeChunk(); std::vector &SkinTreeChunk=GinFile.GetSkinTreeChunk(); std::vector &UserPropChunk=GinFile.GetUserPropChunk(); std::vector &CameraChunk=GinFile.GetCameraChunk(); int Node,NodeCount; // Build Scene Tree CGinTree *GT = (CGinTree*)SceneTreeChunk[0]; std::vector const &GinTree=GT->GetTree(); NodeCount=GinTree.size(); for (Node=0;NodeParentIdx; ThisNode->Mtx=Identity; // Build Node Mtx's if (ParentIdx!=-1) { // LocalMtx TMATRIX ThisMtx,ParentMtx; CNode *ParentNode=&SceneTree[ParentIdx]; ParentMtx=ParentNode->Mtx; TQUAT ThisQ(ThisNode->XAng,ThisNode->YAng,ThisNode->ZAng,ThisNode->WAng); ThisQ.QuatToMat(&ThisMtx); ThisMtx.SetPosition(ThisNode->XPos,ThisNode->YPos,ThisNode->ZPos); ThisNode->Mtx=ParentMtx*ThisMtx; // WorldMtx ThisNode->WorldMtx=GetWorldMatrix(SceneTree,ParentIdx); } } /* for (Node=0;NodeMtx; TQUAT ThisQ(ThisNode.XAng,ThisNode.YAng,ThisNode.ZAng,ThisNode.WAng); ThisQ.QuatToMat(&ThisMtx); ThisMtx.t[0]=ThisNode.XPos; ThisMtx.t[1]=ThisNode.YPos; ThisMtx.t[2]=ThisNode.ZPos; SceneTree[Node].Mtx=ParentMtx*ThisMtx; } } */ //----------------------------------------------------------------------------- // Load Materials int MatN = MatChunk.size(); if (MatN) { CMat4 * Materials = (CMat4*)MatChunk[0]; AllMaterials = Materials->GetMaterials(); if (TexNamesChunk.size()) { CTexName * T=(CTexName *)(TexNamesChunk[0]); vector const & Strs=T->GetTexNames(); TextureList = Strs; int NumOfMeshes=MshChunk.size(); for (int j=0; j const & Mat4Id = M->GetChunk(); for (int i=0; i=0) { int tid = Materials->GetTexId(Mat4Id[i].MatId); if (tid >= Strs.size() || tid < 0) { GObject::Error(ERR_WARNING,"Texture index odd (aksed for %d, max is %d) adjusting to 0\n",tid,Strs.size()); tid=0; } // else { GString const & TexFile=Strs[tid]; /* Only add texture to list if it hasn't been on it before */ if (find(AllTexNames.begin(),AllTexNames.end(),TexFile) == AllTexNames.end()) AllTexNames.push_back(TexFile); } } } } } } else { GObject::Error(ERR_WARNING,"No Materials\n"); } //----------------------------------------------------------------------------- // Load Models and Meshes for (int m=0; mgetObj(); CNode *ThisNode=GetNodePtr(GinFile.GetModelName(CurMod)); if (loadPoints( CurMod, PointsChunk,ThisNode) != -1) { vector const &MeshChunks = M->GetChunk(); for (int mn=0; mnTriMaterial.push_back(MatIdx); loadVCol( CurMod, MeshChunks[mn].MeshNum, VColTrisChunk,ThisNode); loadUV( CurMod, MeshChunks[mn].MeshNum, UVtrisChunk,ThisNode); int Size=ThisNode->Tris.size(); ThisNode->UVTris.resize(Size); ThisNode->VColTris.resize(Size); ThisNode->TriMaterial.resize(Size); } } } } //----------------------------------------------------------------------------- // Load Anims // Sort KeyFrame Anims CKeyAnimTree *KATC= (CKeyAnimTree*)KeyAnimTreeChunk[0]; CAnimTree *NATC = (CAnimTree*)AnimTreeChunk[0]; std::vectorconst &KeyAnimTree=KATC->GetTree(); std::vectorconst &AnimTree=NATC->GetTree(); NodeCount=KeyAnimTree.size(); for (Node=0;NodeGetCam()); } } //----------------------------------------------------------------------------- // Load Skin Weight if (SkinTreeChunk.size()) { CSkinTree *ST = (CSkinTree*)SkinTreeChunk[0]; std::vector const &SkinTree=ST->GetTree(); NodeCount=SkinTree.size(); for (Node=0;NodeGetModNum()+1); // Skip SceneRoot); if (ThisNode) { std::vector const & Prop=UP->GetUserProp(); int Size=Prop.size()-1; if (Size>0) { // ThisNode->UserProp.resize(Size); // for (int c=0;cUserProp[c]=Prop[c]; char *PropPtr=(char*)&Prop[0]; ThisNode->UserProp.Import(PropPtr); } } } } //----------------------------------------------------------------------------- // Build Pruned Tree ResetPruneTree(); SetPruneNodes(0); BuildPruneTree(0,-1); //----------------------------------------------------------------------------- // Print Trees // PrintSceneTree(); // PrintPruneTree(); } /*****************************************************************************/ /*****************************************************************************/ /*****************************************************************************/ void CScene::PrintTreeNode(int Idx,const int Tree) { /* CNode &Node=SceneTree[Idx]; int NodeIdx,NodeParentIdx; std::vector ChildList; if (Tree==0) { ChildList=Node.ChildList; NodeIdx=Node.Idx; NodeParentIdx=Node.ParentIdx; } else { ChildList=Node.PruneChildList; NodeIdx=Node.PruneIdx; NodeParentIdx=Node.PruneParentIdx; } int ChildCount=ChildList.size(); for (int Sp=0;Sp &Points ,CNode *ThisNode) { for (int f=0; fGetModNum() == CurMod) { std::vector const & ThesePts=T->GetPts(); int Size= ThesePts.size(); ThisNode->Pts.resize(Size); ThisNode->RelPts.resize(Size); TMATRIX IMtx=ThisNode->Mtx; IMtx.inverse(ThisNode->Mtx); for (int g=0;gPts[g] = ThesePts[g]; /*Rel Pnt*/ //TVECTOR InVtx(ThesePts[g].x,ThesePts[g].y,ThesePts[g].z); TVECTOR InVtx=ThesePts[g];//(ThesePts[g].x,ThesePts[g].y,ThesePts[g].z); TVECTOR OutVtx=IMtx*InVtx; // ThisNode->RelPts[g].x = OutVtx.GetX(); // ThisNode->RelPts[g].y = OutVtx.GetY(); // ThisNode->RelPts[g].z = OutVtx.GetZ(); ThisNode->RelPts[g]=OutVtx; } return (Size); } } return -1; } /*****************************************************************************/ int CScene::loadTris( int CurMod, int CurMesh, vector &Tris,CNode *ThisNode) { for (int i=0; iGetModNum() == CurMod && T->GetMeshNum() == CurMesh) { std::vector const & TheseTris=T->GetTris(); int Size = TheseTris.size(); ThisNode->TriBase=ThisNode->Tris.size(); for (int j=0; jTris.push_back(TheseTris[j]); return (Size); } } return -1; } /*****************************************************************************/ int CScene::loadUV( int CurMod, int CurMesh, vector &UVTris,CNode *ThisNode) { for (int i=0; iGetModNum() == CurMod && T->GetMeshNum() == CurMesh) { std::vector const & TheseTris=T->GetUVTris(); int Size = TheseTris.size(); for (int j=0; jUVTris.push_back(TheseTris[j]); return (Size); } } return -1; } /*****************************************************************************/ int CScene::loadVCol( int CurMod, int CurMesh, vector &VColTris,CNode *ThisNode) { for (int i=0; iGetModNum() == CurMod && T->GetMeshNum() == CurMesh) { std::vector const & TheseTris=T->GetVcolTris(); int Size = TheseTris.size(); for (int j=0; jVColTris.push_back(TheseTris[j]); return (Size); } } return -1; } /*****************************************************************************/ int CScene::addMaterialIdx( int idx ) { int c = UsedMaterials.size(); for (int i=0; i const & SharedTextures,vector & Dest) { for (int f=0;f const &Tree,int Idx) { CNode ThisNode=Tree[Idx]; int ParentIdx=ThisNode.ParentIdx; TMATRIX ParentMtx=Identity; if (ParentIdx!=-1) ParentMtx=GetWorldMatrix(Tree,ParentIdx); TMATRIX ThisMtx=Identity; TMATRIX PosMtx=Identity; TMATRIX RotMtx=Identity; TMATRIX StrMtx=Identity; TMATRIX SclMtx=Identity; TMATRIX IStrMtx=Identity; // Pos PosMtx=Identity; PosMtx.SetPosition(ThisNode.XPos,ThisNode.YPos,ThisNode.ZPos); // Rot TQUAT RotQ(ThisNode.XAng,ThisNode.YAng,ThisNode.ZAng,ThisNode.WAng); RotQ.QuatToMat(&RotMtx); // Stretch TQUAT StrQ(ThisNode.Xapu,ThisNode.Yapu,ThisNode.Zapu,ThisNode.Wapu); StrQ.QuatToMat(&StrMtx); IStrMtx=StrMtx.inverse(); // Scale SclMtx=Identity; SclMtx.ApplyScaleXYZ(ThisNode.Xapk,ThisNode.Yapk,ThisNode.Zapk); ThisMtx= PosMtx*RotMtx*StrMtx*SclMtx*IStrMtx; return(ParentMtx*ThisMtx); } //---------------------------------------------------------------------------- TVECTOR GetWorldPos(std::vector const &Tree,int Idx) { CNode ThisNode=Tree[Idx]; TVECTOR ThisPos(ThisNode.XPos,ThisNode.YPos,ThisNode.ZPos); TMATRIX WorldMtx=GetWorldMatrix(Tree,ThisNode.ParentIdx); // if (WorldMtx!=ThisNode.WorldMtx) printf("!!!"); return(WorldMtx*ThisPos); } //---------------------------------------------------------------------------- TVECTOR GetWorldPos(TMATRIX &WorldMtx,TVECTOR &ThisPos) { return(WorldMtx*ThisPos); } TVECTOR CNode::GetWorldPos(TVECTOR &Pos) { return(::GetWorldPos(WorldMtx,Pos)); } TQUAT CNode::GetWorldAng(TQUAT &Q) { return(TQUAT(0,0,0,0)); }