rt: compute tangents for studio models
Enables applying normal maps to studio models. Fixes #220, fixes #241
This commit is contained in:
parent
bd2bda9a41
commit
8a457a17c2
|
@ -267,17 +267,21 @@ void Matrix4x4_ConcatScale3( matrix4x4 out, float x, float y, float z )
|
|||
Matrix4x4_Concat( out, base, temp );
|
||||
}
|
||||
|
||||
void computeTangent(vec3_t out_tangent, vec3_t v0, vec3_t v1, vec3_t v2, vec2_t uv0, vec2_t uv1, vec2_t uv2) {
|
||||
void computeTangent(vec3_t out_tangent, const vec3_t v0, const vec3_t v1, const vec3_t v2, const vec2_t uv0, const vec2_t uv1, const vec2_t uv2) {
|
||||
vec3_t e1, e2;
|
||||
vec2_t duv1, duv2;
|
||||
float f;
|
||||
|
||||
VectorSubtract(v1, v0, e1);
|
||||
VectorSubtract(v2, v0, e2);
|
||||
Vector2Subtract(uv1, uv0, duv1);
|
||||
Vector2Subtract(uv2, uv0, duv2);
|
||||
|
||||
f = 1.f / (duv1[0] * duv2[1] - duv1[1] * duv2[0]);
|
||||
const float div = duv1[0] * duv2[1] - duv1[1] * duv2[0];
|
||||
if (fabs(div) < 1e-5f) {
|
||||
VectorClear(out_tangent);
|
||||
return;
|
||||
}
|
||||
const float f = 1.f / div;
|
||||
out_tangent[0] = f * (duv2[1] * e1[0] - duv1[1] * e2[0]);
|
||||
out_tangent[1] = f * (duv2[1] * e1[1] - duv1[1] * e2[1]);
|
||||
out_tangent[2] = f * (duv2[1] * e1[2] - duv1[1] * e2[2]);
|
||||
|
|
|
@ -21,4 +21,4 @@ void Matrix4x4_CreateProjection(matrix4x4 out, float xMax, float xMin, float yMa
|
|||
void Matrix4x4_CreateOrtho(matrix4x4 m, float xLeft, float xRight, float yBottom, float yTop, float zNear, float zFar);
|
||||
void Matrix4x4_CreateModelview( matrix4x4 out );
|
||||
|
||||
void computeTangent(vec3_t out_tangent, vec3_t v0, vec3_t v1, vec3_t v2, vec2_t uv0, vec2_t uv1, vec2_t uv2);
|
||||
void computeTangent(vec3_t out_tangent, const vec3_t v0, const vec3_t v1, const vec3_t v2, const vec2_t uv0, const vec2_t uv1, const vec2_t uv2);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "vk_geometry.h"
|
||||
#include "vk_previous_frame.h"
|
||||
#include "vk_renderstate.h"
|
||||
#include "vk_math.h"
|
||||
#include "camera.h"
|
||||
|
||||
#include "xash3d_mathlib.h"
|
||||
|
@ -74,6 +75,7 @@ typedef struct
|
|||
sortedmesh_t meshes[MAXSTUDIOMESHES]; // sorted meshes
|
||||
vec3_t verts[MAXSTUDIOVERTS];
|
||||
vec3_t norms[MAXSTUDIOVERTS];
|
||||
vec3_t tangents[MAXSTUDIOVERTS];
|
||||
|
||||
vec3_t prev_verts[MAXSTUDIOVERTS]; // last frame state for motion vectors
|
||||
|
||||
|
@ -1127,14 +1129,16 @@ g_studio.verts must be computed
|
|||
void R_StudioGenerateNormals( void )
|
||||
{
|
||||
int v0, v1, v2;
|
||||
vec3_t e0, e1, norm;
|
||||
vec3_t e0, e1, norm, tangent;
|
||||
mstudiomesh_t *pmesh;
|
||||
int i, j;
|
||||
|
||||
ASSERT( m_pSubModel != NULL );
|
||||
|
||||
for( i = 0; i < m_pSubModel->numverts; i++ )
|
||||
for( i = 0; i < m_pSubModel->numverts; i++ ) {
|
||||
VectorClear( g_studio.norms[i] );
|
||||
VectorClear( g_studio.tangents[i] );
|
||||
}
|
||||
|
||||
for( j = 0; j < m_pSubModel->nummesh; j++ )
|
||||
{
|
||||
|
@ -1151,11 +1155,16 @@ void R_StudioGenerateNormals( void )
|
|||
|
||||
if( i > 2 )
|
||||
{
|
||||
// TODO should we get uv (for tangents) for STUDIO_NF_CHROME differently?
|
||||
const vec2_t uv0 = {ptricmds[2], ptricmds[3]};
|
||||
v0 = ptricmds[0]; ptricmds += 4;
|
||||
|
||||
vec2_t uv1 = {ptricmds[2], ptricmds[3]};
|
||||
v1 = ptricmds[0]; ptricmds += 4;
|
||||
|
||||
for( i -= 2; i > 0; i--, ptricmds += 4 )
|
||||
{
|
||||
const vec2_t uv2 = {ptricmds[2], ptricmds[3]};
|
||||
v2 = ptricmds[0];
|
||||
|
||||
VectorSubtract( g_studio.verts[v1], g_studio.verts[v0], e0 );
|
||||
|
@ -1166,7 +1175,14 @@ void R_StudioGenerateNormals( void )
|
|||
VectorAdd( g_studio.norms[v1], norm, g_studio.norms[v1] );
|
||||
VectorAdd( g_studio.norms[v2], norm, g_studio.norms[v2] );
|
||||
|
||||
computeTangent(tangent, g_studio.verts[v0], g_studio.verts[v1], g_studio.verts[v2], uv0, uv1, uv2);
|
||||
|
||||
VectorAdd( g_studio.tangents[v0], tangent, g_studio.tangents[v0] );
|
||||
VectorAdd( g_studio.tangents[v1], tangent, g_studio.tangents[v1] );
|
||||
VectorAdd( g_studio.tangents[v2], tangent, g_studio.tangents[v2] );
|
||||
|
||||
v1 = v2;
|
||||
Vector2Copy(uv2, uv1);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1180,11 +1196,16 @@ void R_StudioGenerateNormals( void )
|
|||
{
|
||||
qboolean odd = false;
|
||||
|
||||
// TODO should we get uv (for tangents) for STUDIO_NF_CHROME differently?
|
||||
vec2_t uv0 = {ptricmds[2], ptricmds[3]};
|
||||
v0 = ptricmds[0]; ptricmds += 4;
|
||||
|
||||
vec2_t uv1 = {ptricmds[2], ptricmds[3]};
|
||||
v1 = ptricmds[0]; ptricmds += 4;
|
||||
|
||||
for( i -= 2; i > 0; i--, ptricmds += 4 )
|
||||
{
|
||||
const vec2_t uv2 = {ptricmds[2], ptricmds[3]};
|
||||
v2 = ptricmds[0];
|
||||
|
||||
VectorSubtract( g_studio.verts[v1], g_studio.verts[v0], e0 );
|
||||
|
@ -1195,8 +1216,19 @@ void R_StudioGenerateNormals( void )
|
|||
VectorAdd( g_studio.norms[v1], norm, g_studio.norms[v1] );
|
||||
VectorAdd( g_studio.norms[v2], norm, g_studio.norms[v2] );
|
||||
|
||||
if( odd ) v1 = v2;
|
||||
else v0 = v2;
|
||||
computeTangent(tangent, g_studio.verts[v0], g_studio.verts[v1], g_studio.verts[v2], uv0, uv1, uv2);
|
||||
|
||||
VectorAdd( g_studio.tangents[v0], tangent, g_studio.tangents[v0] );
|
||||
VectorAdd( g_studio.tangents[v1], tangent, g_studio.tangents[v1] );
|
||||
VectorAdd( g_studio.tangents[v2], tangent, g_studio.tangents[v2] );
|
||||
|
||||
if( odd ) {
|
||||
v1 = v2;
|
||||
Vector2Copy(uv2, uv1);
|
||||
} else {
|
||||
v0 = v2;
|
||||
Vector2Copy(uv2, uv0);
|
||||
}
|
||||
|
||||
odd = !odd;
|
||||
}
|
||||
|
@ -1209,8 +1241,10 @@ void R_StudioGenerateNormals( void )
|
|||
}
|
||||
}
|
||||
|
||||
for( i = 0; i < m_pSubModel->numverts; i++ )
|
||||
for( i = 0; i < m_pSubModel->numverts; i++ ) {
|
||||
VectorNormalize( g_studio.norms[i] );
|
||||
VectorNormalize( g_studio.tangents[i] );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1919,6 +1953,7 @@ static void R_StudioDrawNormalMesh( short *ptricmds, vec3_t *pstudionorms, float
|
|||
VectorCopy(g_studio.verts[ptricmds[0]], dst_vtx->pos);
|
||||
VectorCopy(g_studio.prev_verts[ptricmds[0]], dst_vtx->prev_pos);
|
||||
VectorCopy(g_studio.norms[ptricmds[0]], dst_vtx->normal);
|
||||
VectorCopy(g_studio.tangents[ptricmds[0]], dst_vtx->tangent);
|
||||
dst_vtx->lm_tc[0] = dst_vtx->lm_tc[1] = 0.f;
|
||||
|
||||
if (FBitSet( g_nFaceFlags, STUDIO_NF_CHROME ))
|
||||
|
|
Loading…
Reference in New Issue