mirror of
https://github.com/Garux/netradiant-custom.git
synced 2026-09-28 00:00:03 +02:00
* fix AP texture alignment deduction during bsp to map decompilation
This commit is contained in:
@@ -188,6 +188,7 @@ Q3map2:
|
||||
* -onesky: fallback to old behavior: any sky emits total of all suns/skylights in the map
|
||||
* -modelclip: Decompile model autoclip brushes during bsp to map conversion (they are skipped by default)
|
||||
* -wtf: During bsp to map conversion use common/WTF on faces with failed texture alignment deduction
|
||||
* fix AP texture alignment deduction during bsp to map decompilation
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1530,8 +1530,8 @@ double Det3x3( double a00, double a01, double a02,
|
||||
}
|
||||
|
||||
void BP_from_ST( brushprimit_texdef_t& bp, const PlanePoints& points, const DoubleVector3 st[3], const DoubleVector3& normal, const bool normalize /*= true*/ ){
|
||||
double xyI[2], xyJ[2], xyK[2];
|
||||
double stI[2], stJ[2], stK[2];
|
||||
BasicVector2<double> xyI, xyJ, xyK;
|
||||
BasicVector2<double> stI, stJ, stK;
|
||||
double D, D0, D1, D2;
|
||||
DoubleVector3 texX, texY;
|
||||
ComputeAxisBase( normal, texX, texY );
|
||||
@@ -1542,9 +1542,9 @@ void BP_from_ST( brushprimit_texdef_t& bp, const PlanePoints& points, const Doub
|
||||
xyJ[1] = vector3_dot( points[1], texY );
|
||||
xyK[0] = vector3_dot( points[2], texX );
|
||||
xyK[1] = vector3_dot( points[2], texY );
|
||||
stI[0] = st[0][0]; stI[1] = st[0][1];
|
||||
stJ[0] = st[1][0]; stJ[1] = st[1][1];
|
||||
stK[0] = st[2][0]; stK[1] = st[2][1];
|
||||
stI = st[0].vec2();
|
||||
stJ = st[1].vec2();
|
||||
stK = st[2].vec2();
|
||||
|
||||
// - solve linear equations:
|
||||
// - (x, y) := xyz . (texX, texY)
|
||||
@@ -2111,10 +2111,34 @@ void Texdef_from_ST( TextureProjection& projection, const PlanePoints& points, c
|
||||
else
|
||||
projection.m_brushprimit_texdef = bp;
|
||||
if( g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_QUAKE ){
|
||||
#if 0 // generic alternative, not so practically precise
|
||||
const auto axis = projectionaxis_for_normal( plane.normal() );
|
||||
// reuse BP_from_ST(); project points to AP plane
|
||||
PlanePoints pointsAP( points );
|
||||
pointsAP[0][axis] = 0;
|
||||
pointsAP[1][axis] = 0;
|
||||
pointsAP[2][axis] = 0;
|
||||
DoubleVector3 normal( 0 );
|
||||
normal[axis] = std::copysign( 1, plane.normal()[axis] );
|
||||
BP_from_ST( bp, pointsAP, st, normal );
|
||||
projection.m_brushprimit_texdef = bp;
|
||||
|
||||
const TexdefTypeId tmp = g_bp_globals.m_texdefTypeId;
|
||||
g_bp_globals.m_texdefTypeId = TEXDEFTYPEID_BRUSHPRIMITIVES;
|
||||
Matrix4 local2tex;
|
||||
Texdef_Construct_local2tex( projection, width, height, normal, local2tex );
|
||||
g_bp_globals.m_texdefTypeId = tmp;
|
||||
|
||||
Matrix4 basis;
|
||||
Normal_GetTransform( normal, basis );
|
||||
matrix4_transpose( basis );
|
||||
Texdef_fromTransform( projection.m_texdef, width, height, matrix4_multiplied_by_matrix4( local2tex, basis ) );
|
||||
#else
|
||||
const TexdefTypeId tmp = g_bp_globals.m_texdefTypeId;
|
||||
g_bp_globals.m_texdefTypeId = TEXDEFTYPEID_BRUSHPRIMITIVES;
|
||||
AP_from_BP( projection, plane, width, height );
|
||||
g_bp_globals.m_texdefTypeId = tmp;
|
||||
#endif
|
||||
}
|
||||
else if( g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_VALVE ){
|
||||
Valve220_from_BP( projection, plane, width, height );
|
||||
|
||||
@@ -39,9 +39,9 @@
|
||||
exports a map brush
|
||||
*/
|
||||
|
||||
inline float Det3x3( float a00, float a01, float a02,
|
||||
float a10, float a11, float a12,
|
||||
float a20, float a21, float a22 ){
|
||||
inline double Det3x3( double a00, double a01, double a02,
|
||||
double a10, double a11, double a12,
|
||||
double a20, double a21, double a22 ){
|
||||
return
|
||||
a00 * ( a11 * a22 - a12 * a21 )
|
||||
- a01 * ( a10 * a22 - a12 * a20 )
|
||||
@@ -420,12 +420,10 @@ static void ConvertBrush( FILE *f, int bspBrushNum, const Vector3& origin, bool
|
||||
|
||||
if ( vert[0] != nullptr && vert[1] != nullptr && vert[2] != nullptr ) {
|
||||
if ( brushPrimitives ) {
|
||||
int i;
|
||||
Vector3 texX, texY;
|
||||
Vector2 xyI, xyJ, xyK;
|
||||
Vector2 stI, stJ, stK;
|
||||
float D, D0, D1, D2;
|
||||
|
||||
BasicVector2<double> xyI, xyJ, xyK;
|
||||
BasicVector2<double> stI, stJ, stK;
|
||||
double D, D0, D1, D2;
|
||||
DoubleVector3 texX, texY;
|
||||
ComputeAxisBase( buildPlane.normal(), texX, texY );
|
||||
|
||||
xyI[0] = vector3_dot( vert[0]->xyz, texX );
|
||||
@@ -448,7 +446,7 @@ static void ConvertBrush( FILE *f, int bspBrushNum, const Vector3& origin, bool
|
||||
xyK[0], xyK[1], 1
|
||||
);
|
||||
if ( D != 0 ) {
|
||||
for ( i = 0; i < 2; ++i )
|
||||
for ( int i = 0; i < 2; ++i )
|
||||
{
|
||||
D0 = Det3x3(
|
||||
stI[i], xyI[1], 1,
|
||||
@@ -465,7 +463,7 @@ static void ConvertBrush( FILE *f, int bspBrushNum, const Vector3& origin, bool
|
||||
xyJ[0], xyJ[1], stJ[i],
|
||||
xyK[0], xyK[1], stK[i]
|
||||
);
|
||||
buildSide.texMat[i] = { D0 / D, D1 / D, D2 / D };
|
||||
buildSide.texMat[i] = Vector3( D0 / D, D1 / D, D2 / D );
|
||||
}
|
||||
}
|
||||
else{
|
||||
@@ -494,33 +492,18 @@ static void ConvertBrush( FILE *f, int bspBrushNum, const Vector3& origin, bool
|
||||
else
|
||||
{
|
||||
// invert QuakeTextureVecs
|
||||
int i;
|
||||
int sv, tv;
|
||||
float stI[2], stJ[2], stK[2];
|
||||
Vector3 sts[2];
|
||||
BasicVector2<double> stI, stJ, stK;
|
||||
double D, D0, D1, D2;
|
||||
DoubleVector3 sts[2];
|
||||
float shift[2], scale[2];
|
||||
float rotate;
|
||||
float D, D0, D1, D2;
|
||||
|
||||
const auto vecs = TextureAxisFromPlane( buildPlane );
|
||||
if ( vecs[0][0] ) {
|
||||
sv = 0;
|
||||
}
|
||||
else if ( vecs[0][1] ) {
|
||||
sv = 1;
|
||||
}
|
||||
else{
|
||||
sv = 2;
|
||||
}
|
||||
if ( vecs[1][0] ) {
|
||||
tv = 0;
|
||||
}
|
||||
else if ( vecs[1][1] ) {
|
||||
tv = 1;
|
||||
}
|
||||
else{
|
||||
tv = 2;
|
||||
}
|
||||
sv = vecs[0][0]? 0
|
||||
: vecs[0][1]? 1: 2;
|
||||
tv = vecs[1][0]? 0
|
||||
: vecs[1][1]? 1: 2;
|
||||
|
||||
stI[0] = vert[0]->st[0] * buildSide.shaderInfo->shaderWidth;
|
||||
stI[1] = vert[0]->st[1] * buildSide.shaderInfo->shaderHeight;
|
||||
@@ -535,7 +518,7 @@ static void ConvertBrush( FILE *f, int bspBrushNum, const Vector3& origin, bool
|
||||
vert[2]->xyz[sv], vert[2]->xyz[tv], 1
|
||||
);
|
||||
if ( D != 0 ) {
|
||||
for ( i = 0; i < 2; ++i )
|
||||
for ( int i = 0; i < 2; ++i )
|
||||
{
|
||||
D0 = Det3x3(
|
||||
stI[i], vert[0]->xyz[tv], 1,
|
||||
@@ -558,8 +541,8 @@ static void ConvertBrush( FILE *f, int bspBrushNum, const Vector3& origin, bool
|
||||
}
|
||||
else{
|
||||
fprintf( stderr, "degenerate triangle found when solving texDef equations\n" ); // FIXME add stuff here
|
||||
sts[0] = { 2.f, 0.f, 0.f };
|
||||
sts[1] = { 0.f, -2.f, 0.f };
|
||||
sts[0] = { 2.0, 0.0, 0.0 };
|
||||
sts[1] = { 0.0, -2.0, 0.0 };
|
||||
}
|
||||
// now we must solve:
|
||||
// // now we must invert:
|
||||
@@ -574,12 +557,37 @@ static void ConvertBrush( FILE *f, int bspBrushNum, const Vector3& origin, bool
|
||||
// nt = cosv * vecs[1][tv];
|
||||
// vecsrotscaled[1][sv] = ns / scale[1];
|
||||
// vecsrotscaled[1][tv] = nt / scale[1];
|
||||
scale[0] = 1.0 / sqrt( sts[0][0] * sts[0][0] + sts[0][1] * sts[0][1] );
|
||||
scale[1] = 1.0 / sqrt( sts[1][0] * sts[1][0] + sts[1][1] * sts[1][1] );
|
||||
#if 0
|
||||
scale[0] = 1.0 / vector2_length( sts[0].vec2() );
|
||||
scale[1] = 1.0 / vector2_length( sts[1].vec2() );
|
||||
rotate = radians_to_degrees( atan2( sts[0][1] * vecs[0][sv] - sts[1][0] * vecs[1][tv], sts[0][0] * vecs[0][sv] + sts[1][1] * vecs[1][tv] ) );
|
||||
shift[0] = buildSide.shaderInfo->shaderWidth * FRAC( sts[0][2] / buildSide.shaderInfo->shaderWidth );
|
||||
shift[1] = buildSide.shaderInfo->shaderHeight * FRAC( sts[1][2] / buildSide.shaderInfo->shaderHeight );
|
||||
#else // Texdef_fromTransform() from brush_primit.cpp, flawless unlike upper
|
||||
scale[0] = 1.0 / vector2_length( sts[0].vec2() );
|
||||
scale[1] = 1.0 / vector2_length( sts[1].vec2() );
|
||||
|
||||
rotate = -radians_to_degrees( atan2( -sts[0][1], sts[0][0] ) );
|
||||
|
||||
if ( rotate == -180.0f ) {
|
||||
rotate = 180.0f;
|
||||
}
|
||||
|
||||
shift[0] = buildSide.shaderInfo->shaderWidth * FRAC( sts[0][2] / buildSide.shaderInfo->shaderWidth );
|
||||
shift[1] = buildSide.shaderInfo->shaderHeight * FRAC( sts[1][2] / buildSide.shaderInfo->shaderHeight );
|
||||
|
||||
// If the 2d cross-product of the x and y axes is positive, one of the axes has a negative scale.
|
||||
if ( vector2_cross( Vector2( sts[0][0], sts[0][1] ), Vector2( sts[1][0], sts[1][1] ) ) > 0 ) {
|
||||
if ( rotate >= 180.0f ) {
|
||||
rotate -= 180.0f;
|
||||
scale[0] = -scale[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
scale[1] = -scale[1];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* print brush side */
|
||||
/* ( 640 24 -224 ) ( 448 24 -224 ) ( 448 -232 -224 ) common/caulk 0 48 0 0.500000 0.500000 0 0 0 */
|
||||
fprintf( f, "\t\t( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) %s %.8f %.8f %.8f %.8f %.8f %d 0 0\n",
|
||||
|
||||
Reference in New Issue
Block a user