From 9bd5bdc2585623938c56347f55a2dbbd92431f66 Mon Sep 17 00:00:00 2001 From: divverent Date: Mon, 23 Feb 2009 13:52:47 +0000 Subject: [PATCH] new insane -tex option to q3map2 -scale; simulates turned off "texture lock" when scaling. git-svn-id: svn://svn.icculus.org/netradiant/trunk@196 61c419a2-8eb2-4b30-bcec-8cead039b335 --- tools/quake3/q3map2/main.c | 124 ++++++++++++++++++++++++++++++++++++- 1 file changed, 121 insertions(+), 3 deletions(-) diff --git a/tools/quake3/q3map2/main.c b/tools/quake3/q3map2/main.c index 1d01245..69239b2 100644 --- a/tools/quake3/q3map2/main.c +++ b/tools/quake3/q3map2/main.c @@ -371,6 +371,74 @@ int BSPInfo( int count, char **fileNames ) } +static void ExtrapolateTexcoords(const float *axyz, const float *ast, const float *bxyz, const float *bst, const float *cxyz, const float *cst, const float *axyz_new, float *ast_out, const float *bxyz_new, float *bst_out, const float *cxyz_new, float *cst_out) +{ + vec4_t scoeffs, tcoeffs; + float md; + m4x4_t solvematrix; + + vec3_t norm; + vec3_t dab, dac; + VectorSubtract(bxyz, axyz, dab); + VectorSubtract(cxyz, axyz, dac); + CrossProduct(dab, dac, norm); + + // assume: + // s = f(x, y, z) + // s(v + norm) = s(v) when n ortho xyz + + // s(v) = DotProduct(v, scoeffs) + scoeffs[3] + + // solve: + // scoeffs * (axyz, 1) == ast[0] + // scoeffs * (bxyz, 1) == bst[0] + // scoeffs * (cxyz, 1) == cst[0] + // scoeffs * (norm, 0) == 0 + // scoeffs * [axyz, 1 | bxyz, 1 | cxyz, 1 | norm, 0] = [ast[0], bst[0], cst[0], 0] + solvematrix[0] = axyz[0]; + solvematrix[4] = axyz[1]; + solvematrix[8] = axyz[2]; + solvematrix[12] = 1; + solvematrix[1] = bxyz[0]; + solvematrix[5] = bxyz[1]; + solvematrix[9] = bxyz[2]; + solvematrix[13] = 1; + solvematrix[2] = cxyz[0]; + solvematrix[6] = cxyz[1]; + solvematrix[10] = cxyz[2]; + solvematrix[14] = 1; + solvematrix[3] = norm[0]; + solvematrix[7] = norm[1]; + solvematrix[11] = norm[2]; + solvematrix[15] = 0; + + md = m4_det(solvematrix); + if(md*md < 1e-10) + { + Sys_Printf("Cannot invert some matrix, some texcoords aren't extrapolated!"); + return; + } + + m4x4_invert(solvematrix); + + scoeffs[0] = ast[0]; + scoeffs[1] = bst[0]; + scoeffs[2] = cst[0]; + scoeffs[3] = 0; + m4x4_transform_vec4(solvematrix, scoeffs); + tcoeffs[0] = ast[1]; + tcoeffs[1] = bst[1]; + tcoeffs[2] = cst[1]; + tcoeffs[3] = 0; + m4x4_transform_vec4(solvematrix, tcoeffs); + + ast_out[0] = scoeffs[0] * axyz_new[0] + scoeffs[1] * axyz_new[1] + scoeffs[2] * axyz_new[2] + scoeffs[3]; + ast_out[1] = tcoeffs[0] * axyz_new[0] + tcoeffs[1] * axyz_new[1] + tcoeffs[2] * axyz_new[2] + tcoeffs[3]; + bst_out[0] = scoeffs[0] * bxyz_new[0] + scoeffs[1] * bxyz_new[1] + scoeffs[2] * bxyz_new[2] + scoeffs[3]; + bst_out[1] = tcoeffs[0] * bxyz_new[0] + tcoeffs[1] * bxyz_new[1] + tcoeffs[2] * bxyz_new[2] + tcoeffs[3]; + cst_out[0] = scoeffs[0] * cxyz_new[0] + scoeffs[1] * cxyz_new[1] + scoeffs[2] * cxyz_new[2] + scoeffs[3]; + cst_out[1] = tcoeffs[0] * cxyz_new[0] + tcoeffs[1] * cxyz_new[1] + tcoeffs[2] * cxyz_new[2] + tcoeffs[3]; +} /* ScaleBSPMain() @@ -379,18 +447,20 @@ amaze and confuse your enemies with wierd scaled maps! int ScaleBSPMain( int argc, char **argv ) { - int i; + int i, j; float f, a; vec3_t scale; vec3_t vec; char str[ 1024 ]; int uniform, axis; + qboolean texscale; + float *old_xyzst = NULL; /* arg checking */ if( argc < 2 ) { - Sys_Printf( "Usage: q3map -scale [-v] \n" ); + Sys_Printf( "Usage: q3map [-v] -scale [-tex] \n" ); return 0; } @@ -400,12 +470,14 @@ int ScaleBSPMain( int argc, char **argv ) scale[1] = scale[0] = atof( argv[ argc - 3 ] ); if(argc >= 4) scale[0] = atof( argv[ argc - 4 ] ); + + texscale = !strcmp(argv[1], "-tex"); uniform = ((scale[0] == scale[1]) && (scale[1] == scale[2])); if( scale[0] == 0.0f || scale[1] == 0.0f || scale[2] == 0.0f ) { - Sys_Printf( "Usage: q3map -scale \n" ); + Sys_Printf( "Usage: q3map [-v] -scale [-tex] \n" ); Sys_Printf( "Non-zero scale value required.\n" ); return 0; } @@ -500,6 +572,20 @@ int ScaleBSPMain( int argc, char **argv ) bspLeafs[ i ].maxs[2] *= scale[2]; } + if(texscale) + { + Sys_Printf("Using texture unlocking (and probably breaking texture alignment a lot)\n"); + old_xyzst = safe_malloc(sizeof(*old_xyzst) * numBSPDrawVerts * 5); + for(i = 0; i < numBSPDrawVerts; i++) + { + old_xyzst[5*i+0] = bspDrawVerts[i].xyz[0]; + old_xyzst[5*i+1] = bspDrawVerts[i].xyz[1]; + old_xyzst[5*i+2] = bspDrawVerts[i].xyz[2]; + old_xyzst[5*i+3] = bspDrawVerts[i].st[0]; + old_xyzst[5*i+4] = bspDrawVerts[i].st[1]; + } + } + /* scale drawverts */ for( i = 0; i < numBSPDrawVerts; i++ ) { @@ -511,6 +597,38 @@ int ScaleBSPMain( int argc, char **argv ) bspDrawVerts[i].normal[2] /= scale[2]; VectorNormalize(bspDrawVerts[i].normal, bspDrawVerts[i].normal); } + + if(texscale) + { + for(i = 0; i < numBSPDrawSurfaces; i++) + { + switch(bspDrawSurfaces[i].surfaceType) + { + case SURFACE_FACE: + case SURFACE_META: + if(bspDrawSurfaces[i].numIndexes % 3) + Error("Not a triangulation!"); + for(j = bspDrawSurfaces[i].firstIndex; j < bspDrawSurfaces[i].firstIndex + bspDrawSurfaces[i].numIndexes; j += 3) + { + int ia = bspDrawIndexes[j] + bspDrawSurfaces[i].firstVert, ib = bspDrawIndexes[j+1] + bspDrawSurfaces[i].firstVert, ic = bspDrawIndexes[j+2] + bspDrawSurfaces[i].firstVert; + bspDrawVert_t *a = &bspDrawVerts[ia], *b = &bspDrawVerts[ib], *c = &bspDrawVerts[ic]; + float *oa = &old_xyzst[ia*5], *ob = &old_xyzst[ib*5], *oc = &old_xyzst[ic*5]; + // extrapolate: + // a->xyz -> oa + // b->xyz -> ob + // c->xyz -> oc + ExtrapolateTexcoords( + &oa[0], &oa[3], + &ob[0], &ob[3], + &oc[0], &oc[3], + a->xyz, a->st, + b->xyz, b->st, + c->xyz, c->st); + } + break; + } + } + } /* scale planes */ if(uniform) -- 2.39.2