/*********************/ /*** Elem Stuph ***/ /*********************/ #include "stdafx.h" #include #include #include #include "GLEnabledView.h" #include #include #include "Core.h" #include "TexCache.h" #include "Elem.h" #include "GinTex.h" #include "utils.h" #include "MapEdit.h" #include "MapEditDoc.h" #include "MapEditView.h" #include "MainFrm.h" #include "GUITileBank.h" const Vector3 DefOfs(+0.5f,0,+4.0f); int CElem::BlankID=-1; int CElem::InvalidID=-1; bool CElem::DefTexFlag=false; /*****************************************************************************/ // All Elems MUST run from 0,0 -> /*****************************************************************************/ const float ElemBrowserGap=0.2f; const float ElemBrowserX0=0-ElemBrowserGap/2; const float ElemBrowserX1=1+ElemBrowserGap/2; const float ElemBrowserY0=0-ElemBrowserGap/2; const float ElemBrowserY1=1+ElemBrowserGap/2; /*****************************************************************************/ const float XFlipMtx[]= { -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, }; const float YFlipMtx[]= { 1, 0, 0, 0, 0,-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, }; /*****************************************************************************/ CElem::CElem(int Width,int Height) { ElemWidth=Width; ElemHeight=Height; UnitWidth=ElemWidth/UnitSize; UnitHeight=ElemHeight/UnitSize; ElemID=-1; int AW=AlignSize(ElemWidth); int AH=AlignSize(ElemHeight); ElemRGB=0; ElemRGB=(u8*)MemAlloc(AW*AH*3); memset(ElemRGB,0,AW*AH*3); Type=ElemType2d; TexXOfs=0; TexYOfs=0; BlankFlag=true; ElemName="BLANK"; } /*****************************************************************************/ // 3d Elem (From Gin File) CElem::CElem(CCore *Core,const char *Filename,CScene &ThisScene,int Node) { CNode &ThisNode=ThisScene.GetNode(Node); CTexCache &TexCache=Core->GetTexCache(); GFName Path=Filename; SetPath=Path.Drive(); SetPath+=Path.Dir(); SetPath.Append('\\'); Type=ElemType3d; TexXOfs=-1; TexYOfs=-1; ElemRGB=0; Ofs.Zero(); Build3dElem(TexCache,ThisScene,Node); Calc3dSize(); Build3dDrawList(TexCache,DrawList[ElemType3d]); Ofs.Zero(); Create2dTexture(TexCache,Path.File(),Node); Build2dDrawList(TexCache,DrawList[ElemType2d]); BlankFlag=false; // if (!ValidFlag) SetInvalid(); ElemName=ThisScene.GetNode(Node).Name; } /*****************************************************************************/ // 2d Elem (From Bmp File) // 0,0 1,0 1,1 0,1 CElem::CElem(CCore *Core,const char *Filename,int TexID,int XOfs,int YOfs,int Width,int Height,int CentreMode) { CTexCache &TexCache=Core->GetTexCache(); GFName Path=Filename; ElemWidth=Width; ElemHeight=Height; UnitWidth=ElemWidth/UnitSize; UnitHeight=ElemHeight/UnitSize; ElemRGB=0; Type=ElemType2d; TexXOfs=XOfs; TexYOfs=YOfs; Ofs.Zero(); if (CentreMode & CentreModeL) { // Nothing to do, already there } if (CentreMode & CentreModeR) { Ofs.x-=UnitWidth; } if (CentreMode & CentreModeT) { Ofs.y-=UnitHeight; } if (CentreMode & CentreModeB) { // Nothing to do, already there } if (CentreMode & CentreModeLR) { Ofs.x-=(UnitWidth-1.0f)/2; } if (CentreMode & CentreModeTB) { Ofs.y-=(UnitHeight-1.0f)/2; } Build2dElem(Core,Path.File(),TexID); Build3dDrawList(TexCache,DrawList[ElemType3d]); Create2dTexture(TexCache,Path.File(),TexID); Build2dDrawList(TexCache,DrawList[ElemType2d]); BlankFlag=false; if (!ValidFlag) SetInvalid(); } /*****************************************************************************/ void CElem::CleanUp() { if (ElemRGB) MemFree(ElemRGB); ElemRGB=0; } /*****************************************************************************/ void CElem::SetBlank() { for (int i=0; iGetTexCache(); sTex &ThisTex=TexCache.GetTex(TexID); int CountW=ThisTex.OldW/ElemWidth; int CountH=ThisTex.OldH/ElemHeight; float dU=ThisTex.ScaleU/(float)CountW; float dV=ThisTex.ScaleV/(float)CountH; dU=(1.0f/CountW); dV=(1.0f/CountH); // dU=ThisTex.ScaleU; // dV=ThisTex.ScaleV; float u0=(TexXOfs*dU); float u1=u0+dU; float v1=1.0-(TexYOfs*dV); float v0=v1-dV; Tri0.Mat=TexID; Tri0.vtx[0]=P0; Tri0.vtx[1]=P1; Tri0.vtx[2]=P2; Tri0.uvs[0].u=u0; Tri0.uvs[0].v=v0; Tri0.uvs[1].u=u1; Tri0.uvs[1].v=v0; Tri0.uvs[2].u=u0; Tri0.uvs[2].v=v1; Tri1.Mat=TexID; Tri1.vtx[0]=P1; Tri1.vtx[1]=P2; Tri1.vtx[2]=P3; Tri1.uvs[0].u=u1; Tri1.uvs[0].v=v0; Tri1.uvs[1].u=u0; Tri1.uvs[1].v=v1; Tri1.uvs[2].u=u1; Tri1.uvs[2].v=v1; } /*****************************************************************************/ void CElem::Build3dElem(CTexCache &TexCache,CScene &ThisScene,int Node) { CNode &ThisNode=ThisScene.GetNode(Node); CNode &ParentNode=ThisScene.GetNode(ThisNode.ParentIdx); int ChildCount=ThisNode.GetPruneChildCount(); std::vector const &NodeTriList=ThisNode.GetTris(); std::vectorconst &NodeVtxList=ThisNode.GetPts(); std::vector const &NodeUVList=ThisNode.GetUVTris(); std::vector const &NodeTriMat=ThisNode.GetTriMaterial(); std::vector const &SceneTexList=ThisScene.GetTexList(); std::vector const &SceneUsedMatList=ThisScene.GetUsedMaterialIdx(); std::vector const &SceneMatList=ThisScene.GetMaterials(); int TexCount=SceneTexList.size(); int TriCount=NodeTriList.size(); int ListSize=TriList.size(); TriList.resize(ListSize+TriCount); for (int T=0; T=TexCount) { CString mexstr; mexstr.Format("Invalid TexId\n Wanted %i only have %i Id's for %s\nThis is gonna hurt!\n Dont ask me about this error, ask Kev.\n This MUST be fixed.",TexID,TexCount-1,ThisNode.Name); AfxMessageBox(mexstr,MB_OK | MB_ICONEXCLAMATION); TexID=0; } // else { TexFlags=SceneMatList[TexID].Flags; GString ThisName; GString TexName=SceneTexList[TexID]; ThisName=SetPath+TexName; // TRACE2("%i !%s!\n",TexID,ThisName); TexID=TexCache.ProcessTexture(ThisName); } // Sort Rest of Tri info Matrix4x4 TransMtx; TransMtx.Identity(); if (ParentNode.GetTris().size() || !ThisNode.ParentIdx) { TransMtx=ThisNode.Mtx; TransMtx.Invert(); } for (int p=0; p<3; p++) { Tri.vtx[p]=TransMtx*NodeVtxList[ThisTri.p[p]]; Tri.uvs[p].u=ThisUV.p[p].u; Tri.uvs[p].v=ThisUV.p[p].v; Tri.Mat=TexID; Tri.Flags=TexFlags; } } for (int Child=0; ChildTri.vtx[p].x) Min.x=Tri.vtx[p].x; if (Min.y>Tri.vtx[p].y) Min.y=Tri.vtx[p].y; if (Min.z>Tri.vtx[p].z) Min.z=Tri.vtx[p].z; if (Max.x> PC_TILE_FLAG_COLLISION_SHIFT; if (ColFlags) { sColTab &ThisCol=ColTable[ColFlags]; glColor4ub(ThisCol.R,ThisCol.G,ThisCol.B,127); } glEnable(GL_TEXTURE_2D); if (Render3d) { glEnable(GL_DEPTH_TEST); glCallList(DrawList[ElemType3d]); glDisable(GL_DEPTH_TEST); } else { glCallList(DrawList[ElemType2d]); } glDisable(GL_TEXTURE_2D); glPopMatrix(); } /*****************************************************************************/ void CElem::Purge() { for (int i=0; i-1.0f && Tri.vtx[p].z<+1.0f) MidGeom=true; } } // Basic Stats fprintf(File,"%s\tT:%i",ElemName,TriList.size()); if (MidGeom) { fprintf(File,"\t*** MID GEOM ***"); } fprintf(File,"\n"); } /*****************************************************************************/ /*****************************************************************************/ /*** Elem Set ****************************************************************/ /*****************************************************************************/ /*****************************************************************************/ CElemSet::CElemSet(const char *_Filename,int Idx,int Width,int Height,bool CreateBlank,int Centre) { GFName FName=_Filename; Filename=_Filename; Name=FName.File(); MaxWidth=Width; MaxHeight=Height; CentreMode=Centre; Loaded=FALSE; SetNumber=Idx; if (CreateBlank) { ElemList.push_back(CElem(MaxWidth,MaxHeight)); // Insert Blank } } /*****************************************************************************/ CElemSet::~CElemSet() { } /*****************************************************************************/ void CElemSet::CleanUp() { int ListSize=ElemList.size(); for (int i=0; iGetTexCache(); int TexID=TexCache.ProcessTexture(Filename); sTex &ThisTex=TexCache.GetTex(TexID); int Width,Height; if (MaxWidth==-1) MaxWidth=ThisTex.OldW; if (MaxHeight==-1) MaxHeight=ThisTex.OldH; Width=ThisTex.OldW/MaxWidth; Height=ThisTex.OldH/MaxHeight; for (int Y=0; Y=ListSize) return(false); return(ElemList[No].IsValid()); } /*****************************************************************************/ void CElemSet::Report(FILE *File) { int i,ListSize=ElemList.size(); for (i=0; iGetFilePath(); GString FilePath; char FixPath[1024]; FilePath=RootPath.Drive(); FilePath+=RootPath.Dir(); FilePath.Append('\\'); FilePath.Upper(); if (Version>=5) { File->Read(&CurrentSet,sizeof(int)); } File->Read(&ListSize,sizeof(int)); // New Style rel storage for (int i=0;iRead(&c,1); FullName.Append(c); } FullName.Upper(); GFName::makeabsolute(FilePath,FullName,FixPath); FullName=FixPath; _fullpath( FixPath, FullName, 1024); for (int z=0; zGetFilePath(); GString SavePath; SavePath=RootPath.Drive(); SavePath+=RootPath.Dir(); SavePath.Append('\\'); SavePath.Upper(); File->Write(&CurrentSet,sizeof(int)); File->Write(&ListSize,sizeof(int)); for (int i=0; iWrite(Filename,strlen(Filename)+1); } } /*****************************************************************************/ int CElemBank::AddSet(const char *Filename) { int ListSize=SetList.size(); CElemSet NewSet(Filename,ListSize,MaxWidth,MaxHeight,BlankFlag,CentreMode); int Idx=SetList.Add(NewSet); if (SetList.size()!=ListSize) LoadFlag=TRUE; return(Idx); } /*****************************************************************************/ void CElemBank::LoadAllSets(CCore *Core) { int ListSize=SetList.size(); if (!LoadFlag) return; for (int i=0;i=SetList.size()) return(false); // if (Set>SetList.size()) return(false); ASSERT(SetGetView()->SetupPersMatrix(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); while(TileID!=ListSize) { CPoint Pos=GetElemPos(TileID,BrowserWidth); float XPos=(float)Pos.x*(1+ElemBrowserGap); float YPos=(float)Pos.y*(1+ElemBrowserGap); glLoadIdentity(); glScalef(Scale,Scale,Scale); glTranslatef(-CamPos.x+XPos,CamPos.y-YPos,0); glLoadName (TileID); glBegin (GL_QUADS); BuildGLQuad(ElemBrowserX0,ElemBrowserX1,ElemBrowserY0,ElemBrowserY1,0); glEnd(); TileID++; } HitCount= glRenderMode (GL_RENDER); glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); // Process hits GLuint *HitPtr=SelectBuffer; TileID=-2; if (HitCount) // Just take 1st { TileID=HitPtr[3]; } glMatrixMode(GL_MODELVIEW); // <-- Prevent arse GL assert CursorPos=TileID; } /*****************************************************************************/ void CElemBank::Report() { FILE *File=fopen("\\Report.txt","wt"); int ListSize=SetList.size(); for (int i=0; iGUIAdd(GUIElemList,IDD_ELEMLIST); } /*****************************************************************************/ void CElemBank::GUIKill(CCore *Core) { Core->GUIRemove(GUIElemList,IDD_ELEMLIST); } /*****************************************************************************/ void CElemBank::GUIUpdate(CCore *Core) { int ListSize=GetSetCount(); bool IsSubView=Core->IsSubView(); if (GUIElemList.m_List) { GUIElemList.m_List.ResetContent(); if (ListSize) { for (int i=0; i