mirror of
https://github.com/TTimo/GtkRadiant.git
synced 2024-11-10 07:11:54 +00:00
Adding plane_aliasing regression test as promised in an email. I was able
to come up with this regression test, demonstrating the error, on my first try. git-svn-id: svn://svn.icculus.org/gtkradiant/GtkRadiant/branches/Rambetter-math-fix-experiments@410 8a3a26a2-13c4-0310-b231-cf6edde360e5
This commit is contained in:
parent
f5ebc52dca
commit
41470e6a03
6 changed files with 214 additions and 0 deletions
129
regression_tests/q3map2/plane_aliasing/README.txt
Normal file
129
regression_tests/q3map2/plane_aliasing/README.txt
Normal file
|
@ -0,0 +1,129 @@
|
|||
DESCRIPTION OF PROBLEM:
|
||||
=======================
|
||||
|
||||
This example map demonstrates what a relatively large value for plane distance
|
||||
epsilon can do as far as destroying draw surfaces. The plane distance
|
||||
epsilon was 0.01 at the time of this writing. This means that two planes
|
||||
with the same normal and a distance 0.00999 apart are considered to be the
|
||||
same plane.
|
||||
|
||||
The recommended value of plane distance epsilon is more along the lines of
|
||||
0.001; however, we can't currently change this epsilon to that value due to
|
||||
lack of resolution in 32 bit floating point integers in the 2^16 number range.
|
||||
The smallest epsilon in 32 bit float land that can be added to 2^16 that
|
||||
results in a value greater than 2^16 is approximately 0.007, which is already
|
||||
practically the current default plane distance epsilon (0.01).
|
||||
|
||||
Brush 0 in the example map is a 6-sided brush with red top face. The red top
|
||||
face is defined such in the .map file:
|
||||
|
||||
( -127 256 513 ) ( -127 384 513 ) ( 1 384 512 )
|
||||
|
||||
During the -bsp stage,
|
||||
|
||||
In ParseRawBrush() for brush 0
|
||||
Side 4:
|
||||
(-127.000000 256.000000 513.000000)
|
||||
(-127.000000 384.000000 513.000000)
|
||||
(1.000000 384.000000 512.000000)
|
||||
normal: (0.0078122616 0.0000000000 0.9999694824)
|
||||
dist: 511.9921875000
|
||||
|
||||
Now brush 1, the 4-sided brush with the red top face, has the following
|
||||
defined as the red top face:
|
||||
|
||||
( -128 0 513 ) ( -128 128 513 ) ( 0 128 512 )
|
||||
|
||||
It's almost the same plane, only off by a distance of about 0.01.
|
||||
|
||||
During compiling:
|
||||
|
||||
In ParseRawBrush() for brush 1
|
||||
Side 1:
|
||||
(-128.000000 0.000000 513.000000)
|
||||
(-128.000000 128.000000 513.000000)
|
||||
(0.000000 128.000000 512.000000)
|
||||
normal: (0.0078122616 0.0000000000 0.9999694824)
|
||||
dist: 511.9921875000
|
||||
|
||||
Note that the normal and dist are identical to the plane above, even though
|
||||
the two are different. This leads to multiplying errors later on, when this
|
||||
side is intersected with the bottom green face. In particular, the blue face
|
||||
disappears from the map. The blue face:
|
||||
|
||||
In CreateBrushWindings() for brush 1
|
||||
Handling side 2 on the brush
|
||||
Before clipping we have:
|
||||
(-262144.00000000 0.00000000 262144.00000000)
|
||||
(262144.00000000 0.00000000 262144.00000000)
|
||||
(262144.00000000 -0.00000000 -262144.00000000)
|
||||
(-262144.00000000 0.00000000 -262144.00000000)
|
||||
After clipping w/ side 0 we have:
|
||||
(-262144.00000000 0.00000000 262144.00000000)
|
||||
(262144.00000000 0.00000000 262144.00000000)
|
||||
(262144.00000000 0.00000000 -19977.00073172)
|
||||
(-262144.00000000 0.00000000 20983.00073758)
|
||||
After clipping w/ side 1 we have:
|
||||
(262144.00000000 0.00000000 -1535.99218726)
|
||||
(262144.00000000 0.00000000 -19977.00073172)
|
||||
(-128.11106773 0.00000000 513.00868046)
|
||||
After clipping w/ side 3 we have:
|
||||
(0.00000000 0.00000000 503.00000293)
|
||||
(-128.11106773 0.00000000 513.00868046)
|
||||
(-0.00000000 0.00000000 512.00781274)
|
||||
|
||||
We see the error is greater than 0.1 in the X value -128.11106773. This
|
||||
causes the draw surface to be discarded in processing later on. We must
|
||||
not allow such a great error. An error greater than or equal to 0.1 is
|
||||
considered to be very bad.
|
||||
|
||||
This disappearing blue triangle can be fixed simply by deleting brush 0,
|
||||
the 6-sided brush that causes the bad plane alias. I would suggest deleting
|
||||
this brush by editing the .map file manually (and then renumbering the brushes
|
||||
manually).
|
||||
|
||||
After deleting this brush:
|
||||
|
||||
In ParseRawBrush() for brush 0
|
||||
Side 1:
|
||||
(-128.000000 0.000000 513.000000)
|
||||
(-128.000000 128.000000 513.000000)
|
||||
(0.000000 128.000000 512.000000)
|
||||
normal: (0.0078122616 0.0000000000 0.9999694824)
|
||||
dist: 511.9843750000
|
||||
|
||||
In CreateBrushWindings() for brush 0
|
||||
Handling side 1 on the brush
|
||||
Before clipping we have:
|
||||
(262132.00000000 262136.00000000 -1535.90625143)
|
||||
(262132.00000000 -262136.00000000 -1535.90625143)
|
||||
(-262124.00048828 -262136.00000000 2559.84375238)
|
||||
(-262124.00048828 262136.00000000 2559.84375238)
|
||||
After clipping w/ side 0 we have:
|
||||
(262132.00000000 262136.00000000 -1535.90625143)
|
||||
(262132.00000000 -262136.00000000 -1535.90625143)
|
||||
(-127.99993289 -262136.00000000 512.99999805)
|
||||
(-127.99993289 262136.00000000 512.99999805)
|
||||
After clipping w/ side 2 we have:
|
||||
(262132.00000000 262136.00000000 -1535.90625143)
|
||||
(262132.00000000 -0.00000000 -1535.90625143)
|
||||
(-127.99993289 -0.00000000 512.99999805)
|
||||
(-127.99993289 262136.00000000 512.99999805)
|
||||
After clipping w/ side 3 we have:
|
||||
(0.00000000 0.00000000 511.99999857)
|
||||
(-127.99993289 -0.00000000 512.99999805)
|
||||
(-127.99993289 127.99993289 512.99999805)
|
||||
|
||||
Note that we're way more accurate now, and we're nowhere near to approaching
|
||||
the 0.1 error. All it took was the deletion of a seemintly unrelated brush.
|
||||
|
||||
|
||||
SOLUTION TO PROBLEM:
|
||||
====================
|
||||
|
||||
The suggested fix is to increase the resolution of plane distance from 32 bit
|
||||
float to 64 bit float for the relevant brush processing operations. After that
|
||||
is done, decrease the default plane distance epsilon from 0.01 to 0.001. Note
|
||||
that even though plane distance epsilon can be specified on the command-line,
|
||||
it will do no good (even if set to 0) if the plane distance is close to
|
||||
2^16.
|
|
@ -0,0 +1,85 @@
|
|||
// entity 0
|
||||
{
|
||||
"classname" "worldspawn"
|
||||
// brush 0
|
||||
{
|
||||
( -127 384 513 ) ( -127 256 513 ) ( -127 256 384 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
|
||||
( 1 384 512 ) ( -127 384 512 ) ( -127 384 384 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
|
||||
( 1 256 512 ) ( 1 384 512 ) ( 1 384 384 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
|
||||
( -127 256 512 ) ( 1 256 512 ) ( 1 256 384 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
|
||||
( -127 256 513 ) ( -127 384 513 ) ( 1 384 512 ) radiant_regression_tests/red 0 0 0 0.500000 0.500000 0 0 0
|
||||
( 1 384 384 ) ( -127 384 384 ) ( -127 256 384 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
|
||||
}
|
||||
// brush 1
|
||||
{
|
||||
( 0 128 503 ) ( -128 128 513 ) ( 0 0 503 ) radiant_regression_tests/green 0 0 0 0.500000 0.500000 0 0 0
|
||||
( -128 0 513 ) ( -128 128 513 ) ( 0 128 512 ) radiant_regression_tests/red 0 0 0 0.500000 0.500000 0 0 0
|
||||
( -128 0 512 ) ( 0 0 512 ) ( 0 0 384 ) radiant_regression_tests/blue 0 0 0 0.500000 0.500000 0 0 0
|
||||
( -128 128 503 ) ( 0 0 503 ) ( -128 128 513 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
|
||||
}
|
||||
// brush 2
|
||||
{
|
||||
( -128 472 8 ) ( -128 320 8 ) ( -128 320 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
|
||||
( -232 512 8 ) ( -416 512 8 ) ( -416 512 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
|
||||
( 512 -304 8 ) ( 512 -152 8 ) ( 512 -152 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
|
||||
( 48 -512 8 ) ( 232 -512 8 ) ( 232 -512 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
|
||||
( -432 232 0 ) ( -432 384 0 ) ( -248 384 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
|
||||
( -256 384 -8 ) ( -440 384 -8 ) ( -440 232 -8 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
|
||||
}
|
||||
// brush 3
|
||||
{
|
||||
( -136 512 1040 ) ( -136 -512 1040 ) ( -136 -512 8 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
|
||||
( -512 512 1032 ) ( -520 512 1032 ) ( -520 512 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
|
||||
( -128 -512 1032 ) ( -128 512 1032 ) ( -128 512 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
|
||||
( -520 -512 1032 ) ( -512 -512 1032 ) ( -512 -512 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
|
||||
( -520 -512 1024 ) ( -520 512 1024 ) ( -512 512 1024 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
|
||||
( -512 512 0 ) ( -520 512 0 ) ( -520 -512 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
|
||||
}
|
||||
// brush 4
|
||||
{
|
||||
( 512 512 1024 ) ( 512 -512 1024 ) ( 512 -512 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
|
||||
( 592 512 1024 ) ( 512 512 1024 ) ( 512 512 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
|
||||
( 520 -512 1000 ) ( 520 512 1000 ) ( 520 512 -24 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
|
||||
( 512 -512 1024 ) ( 592 -512 1024 ) ( 592 -512 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
|
||||
( 512 -512 1024 ) ( 512 512 1024 ) ( 592 512 1024 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
|
||||
( 592 512 0 ) ( 512 512 0 ) ( 512 -512 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
|
||||
}
|
||||
// brush 5
|
||||
{
|
||||
( -128 512 1200 ) ( -128 -512 1200 ) ( -128 -512 1024 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
|
||||
( 512 512 1200 ) ( -512 512 1200 ) ( -512 512 1024 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
|
||||
( 512 -512 1200 ) ( 512 512 1200 ) ( 512 512 1024 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
|
||||
( -512 -512 1200 ) ( 512 -512 1200 ) ( 512 -512 1024 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
|
||||
( -456 -512 1032 ) ( -456 512 1032 ) ( 568 512 1032 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
|
||||
( 512 512 1024 ) ( -512 512 1024 ) ( -512 -512 1024 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
|
||||
}
|
||||
// brush 6
|
||||
{
|
||||
( -128 712 1024 ) ( -128 512 1024 ) ( -128 512 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
|
||||
( 512 520 1040 ) ( -512 520 1040 ) ( -512 520 16 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
|
||||
( 512 512 1024 ) ( 512 712 1024 ) ( 512 712 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
|
||||
( -512 512 1024 ) ( 512 512 1024 ) ( 512 512 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
|
||||
( -512 512 1024 ) ( -512 712 1024 ) ( 512 712 1024 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
|
||||
( 512 712 0 ) ( -512 712 0 ) ( -512 512 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
|
||||
}
|
||||
// brush 7
|
||||
{
|
||||
( -128 -512 1024 ) ( -128 -624 1024 ) ( -128 -624 56 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
|
||||
( 512 -512 1024 ) ( -512 -512 1024 ) ( -512 -512 56 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
|
||||
( 512 -624 1024 ) ( 512 -512 1024 ) ( 512 -512 56 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
|
||||
( -512 -520 1048 ) ( 512 -520 1048 ) ( 512 -520 80 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
|
||||
( -512 -624 1024 ) ( -512 -512 1024 ) ( 512 -512 1024 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
|
||||
( 512 -504 0 ) ( -512 -504 0 ) ( -512 -616 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
|
||||
}
|
||||
}
|
||||
// entity 1
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "192 64 640"
|
||||
"light" "3000"
|
||||
}
|
||||
// entity 2
|
||||
{
|
||||
"classname" "info_player_deathmatch"
|
||||
"origin" "-64 64 640"
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in a new issue