/****************************************/ /*** Generic Face Compilation Storage ***/ /****************************************/ // Contains tri data with texture data // Will quad later #include #include #include #include "FaceStore.h" #include "TexGrab.h" #include "DaveLib.h" #include "PsxTypes.h" #include //*************************************************************************** Vector3 normalise(Vector3 &v) { float sqmag = v.x * v.x + v.y * v.y + v.z * v.z; if (sqmag > 0.001f) { float mag = (float)sqrt( sqmag ); Vector3 out; out.x = v.x / mag; out.y = v.y / mag; out.z = v.z / mag; return out; } else { return v; } } //*************************************************************************** Vector3 crossProduct( Vector3 &v0, Vector3 &v1, Vector3 &v2 ) { Vector3 dv1, dv2; Vector3 out; dv1.x = v1.x - v0.x; dv1.y = v1.y - v0.y; dv1.z = v1.z - v0.z; dv2.x = v2.x - v0.x; dv2.y = v2.y - v0.y; dv2.z = v2.z - v0.z; out.x = (dv1.z * dv2.y) - (dv1.y * dv2.z); out.y = (dv1.x * dv2.z) - (dv1.z * dv2.x); out.z = (dv1.y * dv2.x) - (dv1.x * dv2.y); out = normalise(out); return out; } //*************************************************************************** inline float dotProduct( Vector3 &v0, Vector3 &v1 ) { float dp = v0.x * v1.x + v0.y * v1.y + v0.z * v1.z; return dp; } //*************************************************************************** inline bool aprox( float x, float y ) { if (fabs(x-y)<0.03) { return true; } else { return false; } } //*************************************************************************** inline bool uvaprox( sUV &uv0, sUV &uv1 ) { return (aprox(uv0.u, uv1.u) && aprox(uv0.v, uv1.v)); } //*************************************************************************** void CFaceStore::SetTPageFlag(CFace &F,int MatFlag) { switch (MatFlag>>3) { // case 0: F.TPageFlag=2; break; /* Subtractive */ case 1: F.TPageFlag=1; break; /* Additive */ default: F.TPageFlag=0; break; } } //*************************************************************************** CFace &CFaceStore::AddFace(vector const &P, const sGinTri &T, const sUVTri &uv,GString const &Tex,int MatFlag,bool ProcessTexFlag ) { CFace F; for (int i=0; i<3; i++) { F.pts[i] = T.p[i]; F.vis[i] = T.vis[i]; F.uvs[i] = uv.p[i]; F.vtx[i] = P[T.p[i]]; // Limit UV's if (F.uvs[i].u < 0.f) F.uvs[i].u=0.f; if (F.uvs[i].u > 1.f) F.uvs[i].u=1.f; if (F.uvs[i].v < 0.f) F.uvs[i].v=0.f; if (F.uvs[i].v > 1.f) F.uvs[i].v=1.f; } F.TPageFlag=0; F.TexName=Tex; F.Mat = -1; SetTPageFlag(F,MatFlag); CFace &NF=AddFace(F,ProcessTexFlag); return(NF); } //*************************************************************************** CFace &CFaceStore::AddFace(CFace &F,bool ProcessTexFlag) { int ListSize=FaceList.size(); FaceList.resize(ListSize+1); // Process Vtx's for (int i=0; i<3; i++) { F.pts[i]=AddVtx(F.vtx[i]); } if (ProcessTexFlag && F.Mat==-1) { F.Mat=AddTex(F.TexName); } F.Normal = crossProduct( F.vtx[0], F.vtx[1], F.vtx[2] ); F.Avail = true; FaceList[ListSize]=F; return(F); } //*************************************************************************** void CFaceStore::AddFaces(vector &Faces,bool ProcessTexFlag) { int ListSize=Faces.size(); for (int i=0 ;i 1.f) F.uvs[i].u=1.f; if (F.uvs[i].v < 0.f) F.uvs[i].v=0.f; if (F.uvs[i].v > 1.f) F.uvs[i].v=1.f; } F.Mat = Face.Mat; F.Normal = crossProduct( F.vtx[0], F.vtx[1], F.vtx[2] ); F.Avail = true; F.ID=ID; return(F); } */ //*************************************************************************** //*** Texture Stuff ********************************************************* //*************************************************************************** int CFaceStore::AddTex(GString const &TexName) { static GString LastTex; static int LastIdx=-1; vector const &TexList=TexGrab->GetTexInfoList(); int ListSize=TexList.size(); GString Filename=TexName; Filename.Lower(); LastTex=Filename; for (LastIdx=0; LastIdxAddFile(Filename); LastIdx=ListSize; return(ListSize); } //*************************************************************************** void CFaceStore::ProcessTextures() { // Set Texgrab Defaults TexGrab->ShrinkToFit(true); TexGrab->NoSort(); TexGrab->AnimatedHeadersOnly(true); TexGrab->DontOutputBoxes(true); TexGrab->AllowRotate(true); TexGrab->Process(); } //*************************************************************************** void CFaceStore::Process() { Quad(); BuildOutTriLists(); } //*************************************************************************** //*************************************************************************** //*************************************************************************** void CFaceStore::Quad() { int FaceCount=FaceList.size(); for (int i=0; i &TexInfo=TexGrab->GetTexInfo(); sTexOutInfo &ThisTex=TexInfo[In.Mat]; ASSERT(In.Mat &TexInfo=TexGrab->GetTexInfo(); sTexOutInfo &ThisTex=TexInfo[In.Mat]; ASSERT(In.Mat &TexInfo=TexGrab->GetTexInfo(); sTexOutInfo &ThisTex=TexInfo[In.Mat]; int W = ThisTex.w - 1; int H = ThisTex.h - 1; if (ThisTex.Rotated) { Out.uv0[0] = (ThisTex.u + H) - round(In.uvs[0].v * H); Out.uv0[1] = (ThisTex.v + W) - round(In.uvs[0].u * W); Out.uv1[0] = (ThisTex.u + H) - round(In.uvs[1].v * H); Out.uv1[1] = (ThisTex.v + W) - round(In.uvs[1].u * W); Out.uv2[0] = (ThisTex.u + H) - round(In.uvs[2].v * H); Out.uv2[1] = (ThisTex.v + W) - round(In.uvs[2].u * W); Out.uv3[0] = (ThisTex.u + H) - round(In.uvs[3].v * H); Out.uv3[1] = (ThisTex.v + W) - round(In.uvs[3].u * W); } else { Out.uv0[0] = (ThisTex.u)+ round(In.uvs[0].u * W); Out.uv0[1] = (ThisTex.v + H) - round(In.uvs[0].v * H); Out.uv1[0] = (ThisTex.u)+ round(In.uvs[1].u * W); Out.uv1[1] = (ThisTex.v + H) - round(In.uvs[1].v * H); Out.uv2[0] = (ThisTex.u)+ round(In.uvs[2].u * W); Out.uv2[1] = (ThisTex.v + H) - round(In.uvs[2].v * H); Out.uv3[0] = (ThisTex.u)+ round(In.uvs[3].u * W); Out.uv3[1] = (ThisTex.v + H) - round(In.uvs[3].v * H); } Out.TPage=ThisTex.Tpage; Out.Clut=ThisTex.Clut; } //*************************************************************************** int CFaceStore::AddVtx(Vector3 &InVtx) { int ListSize=OutVtxList.size(); sVtx ThisVtx; ThisVtx.vx=round(InVtx.x*Scale); ThisVtx.vy=round(InVtx.y*Scale); ThisVtx.vz=round(InVtx.z*Scale); for (int i=0; i &List) { int ListSize=List.size(); int Pos=ftell(File); for (int i=0; i &List) { int ListSize=List.size(); int Pos=ftell(File); for (int i=0; i &List) { int ListSize=List.size(); int Pos=ftell(File); for (int i=0; i::iterator pb, pe, pm; vector::iterator ub, ue, um; vector::iterator vb, ve, vm; pb = F.pts.begin(); pe = F.pts.end(); ub = F.uvs.begin(); ue = F.uvs.end(); vb = F.vtx.begin(); ve = F.vtx.end(); pm = pb + idx; um = ub + idx; vm = vb + idx; rotate(pb, pm, pe); rotate(ub, um, ue); rotate(vb, vm, ve); } for (j=0; j::iterator pb, pe, pm; vector::iterator ub, ue, um; vector::iterator vb, ve, vm; pb = F.pts.begin(); pe = F.pts.end()-1; ub = F.uvs.begin(); ue = F.uvs.end()-1; vb = F.vtx.begin(); ve = F.vtx.end()-1; pm = pb + idx; um = ub + idx; vm = vb + idx; rotate(pb, pm, pe); rotate(ub, um, ue); rotate(vb, vm, ve); } F.pts.resize(ptc+1); F.vtx.resize(ptc+1); F.uvs.resize(ptc+1); F.pts[ptc] = nf.pts[unc]; F.vtx[ptc] = nf.vtx[unc]; F.uvs[ptc] = nf.uvs[unc]; nf.avail = false; if (minC && MaxStrip>F.pts.size()) FollowFace( minF, F ); } //*************************************************************************** bool CFaceStore::GetFace( CFace &F ) { int minF = -1; int minC = 9999; int c = FaceList.size(); for (int i=0; iF.pts.size()) FollowFace( minF, F ); return true; } /*****************************************************************************/ /*****************************************************************************/ /*****************************************************************************/ void CFaceStore::QuadGetPnts(CFace &F,int *Join0,int *Join1,int *Pnt) { if (!F.vis[0]) { *Join0= F.pts[0]; *Join1= F.pts[1]; *Pnt= 2; } else if (!F.vis[1]) { *Join0= F.pts[1]; *Join1= F.pts[2]; *Pnt= 0; } else { *Join0= F.pts[2]; *Join1= F.pts[0]; *Pnt= 1; } } //*************************************************************************** int CFaceStore::QuadGetAttached(int FaceNo) { CFace ThisFace=FaceList[FaceNo]; int Vis=ThisFace.vis[0]+ThisFace.vis[1]+ThisFace.vis[2]; if (Vis==7) return(0); // Pure Tri int FaceCount=FaceList.size(); int J00,J01,P0; int J10,J11,P1; QuadGetPnts(ThisFace,&J00,&J01,&P0); for (int Loop=FaceNo+1;Loop::iterator pb, pe, pm; vector::iterator ub, ue, um; vector::iterator vb, ve, vm; pb = F.pts.begin(); pe = F.pts.end(); ub = F.uvs.begin(); ue = F.uvs.end(); vb = F.vtx.begin(); ve = F.vtx.end(); pm = pb + idx; um = ub + idx; vm = vb + idx; rotate(pb, pm, pe); rotate(ub, um, ue); rotate(vb, vm, ve); } } //*************************************************************************** void CFaceStore::Quad(vector &TriList,vector &QuadList) { int FaceCount=FaceList.size(); if (MaxStrip==4) { //vector ThisTriList; for (int Loop=0;Loop