mirror of
https://github.com/kevinbentley/Descent3.git
synced 2025-01-22 19:55:23 +00:00
a4ab78192c
Join the license header with historical comments using a separator so IDEs can correctly parse the initial header. Also use .gitattributes to ensure all files are LF.
230 lines
6.0 KiB
C++
230 lines
6.0 KiB
C++
/*
|
|
* Descent 3
|
|
* Copyright (C) 2024 Parallax Software
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
--- HISTORICAL COMMENTS FOLLOW ---
|
|
|
|
* $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 <a,b>
|
|
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;i<fp->num_verts;i++)
|
|
{
|
|
saveu2[i]=fp->face_uvls[i].u2;
|
|
savev2[i]=fp->face_uvls[i].v2;
|
|
}
|
|
|
|
ASSERT( (va<nv) && (vb<nv) );
|
|
ASSERT((abs(va - vb) == 1) || (abs(va - vb) == nv-1)); // make sure the verticies specify an edge
|
|
|
|
// We want vlo precedes vhi, ie vlo < vhi, or vlo = num_verts, vhi = 0
|
|
if (va == ((vb + 1) % nv)) { // va = vb + 1
|
|
vlo = vb;
|
|
vhi = va;
|
|
uvlo = *uvb;
|
|
uvhi = *uva;
|
|
} else {
|
|
vlo = va;
|
|
vhi = vb;
|
|
uvlo = *uva;
|
|
uvhi = *uvb;
|
|
}
|
|
|
|
ASSERT(((vlo+1) % nv) == vhi); // If we are on an edge, then uvhi is one more than uvlo (mod num_verts)
|
|
fp->face_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;i<nv-1;i++) {
|
|
int fv = (vhi+i)%nv; //vert index in face
|
|
int rv = fp->face_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;i<fp->num_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;i<fp->num_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;i<fp->num_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;i<fp->num_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;
|
|
}
|