brush_primit.cpp
来自「quake3工具源码。包括生成bsp文件」· C++ 代码 · 共 441 行 · 第 1/2 页
CPP
441 行
#include "stdafx.h"
#include "qe3.h"
// compute a determinant using Sarrus rule
//++timo "inline" this with a macro
// NOTE : the three vec3_t are understood as columns of the matrix
vec_t SarrusDet(vec3_t a, vec3_t b, vec3_t c)
{
return a[0]*b[1]*c[2]+b[0]*c[1]*a[2]+c[0]*a[1]*b[2]
-c[0]*b[1]*a[2]-a[1]*b[0]*c[2]-a[0]*b[2]*c[1];
}
//++timo replace everywhere texX by texS etc. ( ----> and in q3map !)
// NOTE : ComputeAxisBase here and in q3map code must always BE THE SAME !
// WARNING : special case behaviour of atan2(y,x) <-> atan(y/x) might not be the same everywhere when x == 0
// rotation by (0,RotY,RotZ) assigns X to normal
void ComputeAxisBase(vec3_t normal,vec3_t texS,vec3_t texT )
{
vec_t RotY,RotZ;
// do some cleaning
if (fabs(normal[0])<1e-6)
normal[0]=0.0f;
if (fabs(normal[1])<1e-6)
normal[1]=0.0f;
if (fabs(normal[2])<1e-6)
normal[2]=0.0f;
RotY=-atan2(normal[2],sqrt(normal[1]*normal[1]+normal[0]*normal[0]));
RotZ=atan2(normal[1],normal[0]);
// rotate (0,1,0) and (0,0,1) to compute texS and texT
texS[0]=-sin(RotZ);
texS[1]=cos(RotZ);
texS[2]=0;
// the texT vector is along -Z ( T texture coorinates axis )
texT[0]=-sin(RotY)*cos(RotZ);
texT[1]=-sin(RotY)*sin(RotZ);
texT[2]=-cos(RotY);
}
void FaceToBrushPrimitFace(face_t *f)
{
vec3_t texX,texY;
vec3_t proj;
// ST of (0,0) (1,0) (0,1)
vec_t ST[3][5]; // [ point index ] [ xyz ST ]
//++timo not used as long as brushprimit_texdef and texdef are static
/* f->brushprimit_texdef.contents=f->texdef.contents;
f->brushprimit_texdef.flags=f->texdef.flags;
f->brushprimit_texdef.value=f->texdef.value;
strcpy(f->brushprimit_texdef.name,f->texdef.name); */
#ifdef _DEBUG
if ( f->plane.normal[0]==0.0f && f->plane.normal[1]==0.0f && f->plane.normal[2]==0.0f )
{
Sys_Printf("Warning : f->plane.normal is (0,0,0) in FaceToBrushPrimitFace\n");
}
// check d_texture
if (!f->d_texture)
{
Sys_Printf("Warning : f.d_texture is NULL in FaceToBrushPrimitFace\n");
return;
}
#endif
// compute axis base
ComputeAxisBase(f->plane.normal,texX,texY);
// compute projection vector
VectorCopy(f->plane.normal,proj);
VectorScale(proj,f->plane.dist,proj);
// (0,0) in plane axis base is (0,0,0) in world coordinates + projection on the affine plane
// (1,0) in plane axis base is texX in world coordinates + projection on the affine plane
// (0,1) in plane axis base is texY in world coordinates + projection on the affine plane
// use old texture code to compute the ST coords of these points
VectorCopy(proj,ST[0]);
EmitTextureCoordinates(ST[0], f->d_texture, f);
VectorCopy(texX,ST[1]);
VectorAdd(ST[1],proj,ST[1]);
EmitTextureCoordinates(ST[1], f->d_texture, f);
VectorCopy(texY,ST[2]);
VectorAdd(ST[2],proj,ST[2]);
EmitTextureCoordinates(ST[2], f->d_texture, f);
// compute texture matrix
f->brushprimit_texdef.coords[0][2]=ST[0][3];
f->brushprimit_texdef.coords[1][2]=ST[0][4];
f->brushprimit_texdef.coords[0][0]=ST[1][3]-f->brushprimit_texdef.coords[0][2];
f->brushprimit_texdef.coords[1][0]=ST[1][4]-f->brushprimit_texdef.coords[1][2];
f->brushprimit_texdef.coords[0][1]=ST[2][3]-f->brushprimit_texdef.coords[0][2];
f->brushprimit_texdef.coords[1][1]=ST[2][4]-f->brushprimit_texdef.coords[1][2];
}
// compute texture coordinates for the winding points
void EmitBrushPrimitTextureCoordinates(face_t * f, winding_t * w)
{
vec3_t texX,texY;
vec_t x,y;
// compute axis base
ComputeAxisBase(f->plane.normal,texX,texY);
// in case the texcoords matrix is empty, build a default one
// same behaviour as if scale[0]==0 && scale[1]==0 in old code
if (f->brushprimit_texdef.coords[0][0]==0 && f->brushprimit_texdef.coords[1][0]==0 && f->brushprimit_texdef.coords[0][1]==0 && f->brushprimit_texdef.coords[1][1]==0)
{
f->brushprimit_texdef.coords[0][0] = 1.0f;
f->brushprimit_texdef.coords[1][1] = 1.0f;
ConvertTexMatWithQTexture( &f->brushprimit_texdef, NULL, &f->brushprimit_texdef, f->d_texture );
}
int i;
for (i=0 ; i<w->numpoints ; i++)
{
x=DotProduct(w->points[i],texX);
y=DotProduct(w->points[i],texY);
#ifdef _DEBUG
if (g_qeglobals.bNeedConvert)
{
// check we compute the same ST as the traditional texture computation used before
vec_t S=f->brushprimit_texdef.coords[0][0]*x+f->brushprimit_texdef.coords[0][1]*y+f->brushprimit_texdef.coords[0][2];
vec_t T=f->brushprimit_texdef.coords[1][0]*x+f->brushprimit_texdef.coords[1][1]*y+f->brushprimit_texdef.coords[1][2];
if ( fabs(S-w->points[i][3])>1e-2 || fabs(T-w->points[i][4])>1e-2 )
{
if ( fabs(S-w->points[i][3])>1e-4 || fabs(T-w->points[i][4])>1e-4 )
Sys_Printf("Warning : precision loss in brush -> brush primitive texture computation\n");
else
Sys_Printf("Warning : brush -> brush primitive texture computation bug detected\n");
}
}
#endif
w->points[i][3]=f->brushprimit_texdef.coords[0][0]*x+f->brushprimit_texdef.coords[0][1]*y+f->brushprimit_texdef.coords[0][2];
w->points[i][4]=f->brushprimit_texdef.coords[1][0]*x+f->brushprimit_texdef.coords[1][1]*y+f->brushprimit_texdef.coords[1][2];
}
}
// parse a brush in brush primitive format
void BrushPrimit_Parse(brush_t *b)
{
epair_t *ep;
face_t *f;
int i,j;
GetToken (true);
if (strcmp (token, "{"))
{
Warning ("parsing brush primitive");
return;
}
do
{
if (!GetToken (true))
break;
if (!strcmp (token, "}") )
break;
// reading of b->epairs if any
if (strcmp (token, "(") )
{
ep = ParseEpair();
ep->next = b->epairs;
b->epairs = ep;
}
else
// it's a face
{
f = Face_Alloc();
f->next = NULL;
if (!b->brush_faces)
b->brush_faces = f;
else
{
face_t *scan;
for (scan=b->brush_faces ; scan->next ; scan=scan->next)
;
scan->next = f;
}
// read the three point plane definition
for (i=0 ; i<3 ; i++)
{
if (i != 0)
GetToken (true);
if (strcmp (token, "(") )
{
Warning ("parsing brush");
return;
}
for (j=0 ; j<3 ; j++)
{
GetToken (false);
f->planepts[i][j] = atof(token);
}
GetToken (false);
if (strcmp (token, ")") )
{
Warning ("parsing brush");
return;
}
}
// texture coordinates
GetToken (false);
if (strcmp(token, "("))
{
Warning ("parsing brush primitive");
return;
}
GetToken (false);
if (strcmp(token, "("))
{
Warning ("parsing brush primitive");
return;
}
for (j=0;j<3;j++)
{
GetToken(false);
f->brushprimit_texdef.coords[0][j]=atof(token);
}
GetToken (false);
if (strcmp(token, ")"))
{
Warning ("parsing brush primitive");
return;
}
GetToken (false);
if (strcmp(token, "("))
{
Warning ("parsing brush primitive");
return;
}
for (j=0;j<3;j++)
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?