/* * $Logfile: /DescentIII/Main/editor/RoomUVs.cpp $ * $Revision: 1.1.1.1 $ * $Date: 2003-08-26 03:57:38 $ * $Author: kevinb $ * * Code to deal with texturing rooms * * $Log: not supported by cvs2svn $ * * 9 9/30/99 6:35p Matt * Added code to scale the UVs of a texture based on the size of the * texture when the texture is applied to a face. This will cause the * applied texture to have the make 3D texel size at the old texture. * * 8 4/25/99 2:38p Gwar * brought in HRoom.cpp and RoomUVs.cpp, and several misc game functions * were added to globals.cpp to make it possible * * 7 10/21/98 1:27p Jason * fixed texture u2,v2 sliding problems * * 6 10/07/98 3:19p Matt * Cleaned up and fixed Mike's old texture UV calculation code. Who ever * told that boy he could do 3D? * * 5 4/02/98 12:23p Jason * trimmed some fat from our structures * * 4 12/23/97 1:33p Samir * Added pserror.h * * 3 9/17/97 11:57a Matt * Ripped out segment code * * 2 7/18/97 7:38p Jason * finished room/terrain texture modifications * * $NoKeywords: $ */ #include "RoomUVs.h" #ifndef NEWEDITOR #include "d3edit.h" #else #include "..\neweditor\globals.h" #endif #include "pserror.h" //returns the magnatude of the 2d vector static float zhypot(float a,float b) { return sqrt(a*a + b*b); } // Given u,v coordinates at two vertices, assign u,v coordinates to the other vertices on a face. // va, vb = face-relative vertex indices corresponding to uva, uvb. Ie, they are always in 0..num_verts_in_face void AssignUVsToFace(room *rp, int facenum, roomUVL *uva, roomUVL *uvb, int va, int vb) { face *fp = &rp->faces[facenum]; int nv = fp->num_verts; int vlo,vhi; vector fvec,rvec,tvec; roomUVL ruvmag,fuvmag,uvlo,uvhi; float fmag,mag01; int i; float saveu2[MAX_VERTS_PER_FACE],savev2[MAX_VERTS_PER_FACE]; for (i=0;inum_verts;i++) { saveu2[i]=fp->face_uvls[i].u2; savev2[i]=fp->face_uvls[i].v2; } ASSERT( (vaface_uvls[vlo] = uvlo; fp->face_uvls[vhi] = uvhi; // Now we have vlo precedes vhi, compute vertices ((vhi+1) % nv) and ((vhi+2) % nv) // Assign u,v scale to a unit length right vector. fmag = zhypot(uvhi.v - uvlo.v,uvhi.u - uvlo.u); if (fmag < 0.001) { //mprintf((0,"Warning: fmag = %7.3f, using approximate u,v values\n",f2fl(fmag))); ruvmag.u = 256.0; ruvmag.v = 256.0; fuvmag.u = 256.0; fuvmag.v = 256.0; } else { ruvmag.u = uvhi.v - uvlo.v; ruvmag.v = uvlo.u - uvhi.u; fuvmag.u = uvhi.u - uvlo.u; fuvmag.v = uvhi.v - uvlo.v; } //Get pointers to our verts vector *vv0 = &rp->verts[fp->face_verts[vlo]], *vv1 = &rp->verts[fp->face_verts[vhi]]; //Get forward vector from our edge fvec = *vv1 - *vv0; mag01 = vm_NormalizeVector(&fvec); //Check for bad vector if (mag01 < 0.001 ) { OutrageMessageBox("U, V bogosity in room #%i, probably on face #%i. CLEAN UP YOUR MESS!", ROOMNUM(rp), facenum); return; } //Get right vector from the cross product of the forward vec with the surface normal rvec = fvec ^ fp->normal; //Normalize uv values ruvmag.u /= mag01; ruvmag.v /= mag01; fuvmag.u /= mag01; fuvmag.v /= mag01; //Compute UVs for each point for (i=1;iface_verts[fv]; //vert index in room //Get the vector for this edge tvec = rp->verts[rv] - *vv0; //Project the current edge onto our forward & right vectors float rproj = tvec * rvec, fproj = tvec * fvec; //Compute and assign UV values fp->face_uvls[fv].u = uvlo.u + (ruvmag.u * rproj) + (fuvmag.u * fproj); fp->face_uvls[fv].v = uvlo.v + (ruvmag.v * rproj) + (fuvmag.v * fproj); } } // Stretches the UVS of a face void StretchRoomUVs(room *rp, int facenum, int edge) { roomUVL uv0,uv1; int v0, v1; face *fp=&rp->faces[facenum]; int i; float saveu2[MAX_VERTS_PER_FACE],savev2[MAX_VERTS_PER_FACE]; for (i=0;inum_verts;i++) { saveu2[i]=fp->face_uvls[i].u2; savev2[i]=fp->face_uvls[i].v2; } v0 = edge; v1 = (v0 + 1) % rp->faces[facenum].num_verts; uv0 = rp->faces[facenum].face_uvls[v0]; //copy uv AND l uv1 = rp->faces[facenum].face_uvls[v1]; AssignUVsToFace(rp, facenum, &uv0, &uv1, v0, v1); for (i=0;inum_verts;i++) { fp->face_uvls[i].u2=saveu2[i]; fp->face_uvls[i].v2=savev2[i]; } } //Scale all the UV values in a face from the center point (as defined by averaging the u & v values) void ScaleFaceUVs(room *rp,int facenum,float scale) { face *fp=&rp->faces[facenum]; int i; float midu=0,midv=0; for (i=0;inum_verts;i++) { midu += fp->face_uvls[i].u; midv += fp->face_uvls[i].v; } midu /= fp->num_verts; midv /= fp->num_verts; for (i=0;inum_verts;i++) { fp->face_uvls[i].u = midu + (fp->face_uvls[i].u - midu) * scale; fp->face_uvls[i].v = midv + (fp->face_uvls[i].v - midv) * scale; } World_changed=1; }