/****************************************/ /*** Generic Face Compilation Storage ***/ /****************************************/ // Contains tri data with texture data #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.uvs[i] = uv.p[i]; F.vtx[i] = P[T.p[i]]; } F.TPageFlag=0; F.OtOfs=0; F.TexName=Tex; F.Mat = -1; SetTPageFlag(F,MatFlag); CFace &NF=AddFace(F,ProcessTexFlag); return(NF); } //*************************************************************************** // All AddFace's lead to here! CFace &CFaceStore::AddFace(CFace &F,bool ProcessTexFlag) { int ListSize=FaceList.size(); FaceList.resize(ListSize+1); // Process Vtx's (for Quad) for (int i=0; i<3; i++) { F.pts[i]=AddVtx(VtxList,F.vtx[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; } 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 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::Process(vector &OutTriList,vector &OutQuadList,vector &OutVtxList) { BBox.XMin=+30000; BBox.YMin=+30000; BBox.XMax=-30000; BBox.YMax=-30000; Quad(); BuildOutTriList(OutTriList,OutVtxList); BuildOutQuadList(OutQuadList,OutVtxList); } //*************************************************************************** //*************************************************************************** //*************************************************************************** void CFaceStore::SetupUV(CFace const &In, sTri &Out) { vector &TexInfo=TexGrab->GetTexInfo(); sTexOutInfo &ThisTex=TexInfo[In.Mat]; ASSERT(In.Mat &TexInfo=TexGrab->GetTexInfo(); sTexOutInfo &ThisTex=TexInfo[In.Mat]; ASSERT(In.Mat &OutVtxList,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 &OutVtxList,sVtx &ThisVtx) { int ListSize=OutVtxList.size(); for (int i=0; i+ThisVtx.vx) BBox.XMin=+ThisVtx.vx; if (BBox.XMax<+ThisVtx.vx) BBox.XMax=+ThisVtx.vx; if (BBox.YMin>+ThisVtx.vy) BBox.YMin=+ThisVtx.vy; if (BBox.YMax<+ThisVtx.vy) BBox.YMax=+ThisVtx.vy; } //*************************************************************************** void CFaceStore::BuildOutTriList(vector &OutTriList,vector &OutVtxList) { int FaceCount=TriFaceList.size(); int ListSize=OutTriList.size(); OutTriList.resize(ListSize+FaceCount); for (int i=0; i15) Z[p]=15; } OutFace.C0=Z[0]*4; OutFace.C1=Z[1]*4; OutFace.C2=Z[2]*4; } } //*************************************************************************** void CFaceStore::BuildOutQuadList(vector &OutQuadList,vector &OutVtxList) { int FaceCount=QuadFaceList.size(); int ListSize=OutQuadList.size(); OutQuadList.resize(ListSize+FaceCount); for (int i=0; i15) Z[p]=15; } OutFace.C0=Z[0]*4; OutFace.C1=Z[1]*4; OutFace.C2=Z[2]*4; OutFace.C3=Z[3]*4; } } //*************************************************************************** //*************************************************************************** //*************************************************************************** int CFaceStore::WriteTriList(FILE *File,vector &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::Quad() { if (MaxStrip==4) { bool strips = true; while (strips) { CFace f; strips = GetFace( f ); if (strips) { if (f.pts.size() == 3) TriFaceList.push_back(f); else QuadFaceList.push_back(f); } } } else { // No quadding, copy direct int FaceCount=FaceList.size(); for (int Loop=0;Loop