162 lines
3.7 KiB
C++
162 lines
3.7 KiB
C++
// Copyright (C) 2007 Id Software, Inc.
|
|
//
|
|
|
|
#include "../precompiled.h"
|
|
#pragma hdrstop
|
|
|
|
// Gordon: FIXME: This isn't initialised, so wont actually be zero?
|
|
idBoundsShort bounds_short_zero;
|
|
|
|
/*
|
|
================
|
|
idBoundsShort::PlaneDistance
|
|
================
|
|
*/
|
|
float idBoundsShort::PlaneDistance( const idPlane &plane ) const {
|
|
// Gordon: FIXME: Don't convert to float?
|
|
const idVec3 center( ( b[ 0 ][ 0 ] + b[ 1 ][ 0 ] ) * 0.5f,
|
|
( b[ 0 ][ 1 ] + b[ 1 ][ 1 ] ) * 0.5f,
|
|
( b[ 0 ][ 2 ] + b[ 1 ][ 2 ] ) * 0.5f );
|
|
|
|
const idVec3 planeNormal = plane.Normal();
|
|
const float planeD = plane[ 3 ];
|
|
|
|
const float d2 = idMath::Fabs( ( b[1][0] - center[0] ) * planeNormal[0] ) +
|
|
idMath::Fabs( ( b[1][1] - center[1] ) * planeNormal[1] ) +
|
|
idMath::Fabs( ( b[1][2] - center[2] ) * planeNormal[2] );
|
|
const float d1 = center*planeNormal + planeD;
|
|
|
|
if ( d1 - d2 > 0.0f ) {
|
|
return d1 - d2;
|
|
}
|
|
if ( d1 + d2 < 0.0f ) {
|
|
return d1 + d2;
|
|
}
|
|
return 0.0f;
|
|
}
|
|
|
|
/*
|
|
================
|
|
idBoundsShort::PlaneSide
|
|
================
|
|
*/
|
|
#if defined( ID_WIN_X86_SSE )
|
|
#include "../math/Simd_InstructionMacros.h"
|
|
ALIGN4_INIT1( float SIMD_SP_half, 0.5f );
|
|
ALIGN4_INIT1( unsigned int SIMD_SP_absMask, ~(1<<31) );
|
|
#endif
|
|
|
|
int idBoundsShort::PlaneSide( const idPlane &plane, const float epsilon ) const {
|
|
#if defined( ID_WIN_X86_SSE )
|
|
__asm {
|
|
mov edi, this
|
|
mov esi, plane
|
|
|
|
movss xmm1, [esi+ 0]
|
|
movhps xmm1, [esi+ 4]
|
|
movss xmm0, [esi+ 12]
|
|
|
|
movsx eax, word ptr [edi + 0]
|
|
movsx ebx, word ptr [edi + 2]
|
|
movsx ecx, word ptr [edi + 4]
|
|
cvtsi2ss xmm2, eax
|
|
cvtsi2ss xmm3, ebx
|
|
cvtsi2ss xmm4, ecx
|
|
|
|
movsx eax, word ptr [edi + 6]
|
|
movsx ebx, word ptr [edi + 8]
|
|
movsx ecx, word ptr [edi + 10]
|
|
cvtsi2ss xmm5, eax
|
|
cvtsi2ss xmm6, ebx
|
|
cvtsi2ss xmm7, ecx
|
|
|
|
unpcklps xmm3, xmm4
|
|
movlhps xmm2, xmm3
|
|
|
|
unpcklps xmm6, xmm7
|
|
movlhps xmm5, xmm6
|
|
|
|
movaps xmm7, xmm2
|
|
addps xmm7, xmm5
|
|
mulps xmm7, SIMD_SP_half
|
|
|
|
//float d1 = plane.Distance( center );
|
|
movaps xmm2, xmm7
|
|
mulps xmm2, xmm1
|
|
movhlps xmm3, xmm2
|
|
movaps xmm4, xmm3
|
|
shufps xmm4, xmm4, SHUFFLE_PS( 1, 1, 1, 1 )
|
|
|
|
addss xmm2, xmm3
|
|
addss xmm2, xmm4
|
|
addss xmm2, xmm0
|
|
|
|
// idMath::Fabs( ( b[1] - center ) * plane.Normal() )
|
|
subps xmm5, xmm7
|
|
mulps xmm5, xmm1
|
|
andps xmm5, SIMD_SP_absMask
|
|
|
|
// add
|
|
movhlps xmm4, xmm5
|
|
movaps xmm3, xmm4
|
|
shufps xmm3, xmm3, SHUFFLE_PS( 1, 1, 1, 1 )
|
|
|
|
addss xmm5, xmm4
|
|
addss xmm5, xmm3
|
|
|
|
// xmm5 contains final idMath::Fabs( ( b[1] - center ) * plane.Normal() )
|
|
|
|
movss xmm0, xmm2
|
|
subss xmm0, xmm5
|
|
|
|
movss xmm1, xmm2
|
|
addss xmm1, xmm5
|
|
|
|
movss xmm2, epsilon
|
|
xorps xmm3, xmm3
|
|
subps xmm3, xmm2
|
|
|
|
cmpltps xmm2, xmm0
|
|
cmpltps xmm1, xmm3
|
|
|
|
movmskps eax, xmm2
|
|
movmskps ecx, xmm1
|
|
|
|
and eax, 1
|
|
jz nexttest1
|
|
mov eax, PLANESIDE_FRONT
|
|
jmp exity
|
|
|
|
nexttest1:
|
|
and ecx, 1
|
|
jz nexttest2
|
|
mov eax, PLANESIDE_BACK
|
|
jmp exity
|
|
|
|
nexttest2:
|
|
mov eax, PLANESIDE_CROSS
|
|
|
|
exity:
|
|
}
|
|
//float d1 = plane.Distance( center );
|
|
#else
|
|
// Gordon: FIXME: Don't convert to float?
|
|
idVec3 center;
|
|
center[ 0 ] = ( b[ 0 ][ 0 ] + b[ 1 ][ 0 ] ) * 0.5f;
|
|
center[ 1 ] = ( b[ 0 ][ 1 ] + b[ 1 ][ 1 ] ) * 0.5f;
|
|
center[ 2 ] = ( b[ 0 ][ 2 ] + b[ 1 ][ 2 ] ) * 0.5f;
|
|
|
|
float d1 = plane.Distance( center );
|
|
float d2 = idMath::Fabs( ( b[1][0] - center[0] ) * plane.Normal()[0] ) +
|
|
idMath::Fabs( ( b[1][1] - center[1] ) * plane.Normal()[1] ) +
|
|
idMath::Fabs( ( b[1][2] - center[2] ) * plane.Normal()[2] );
|
|
|
|
if ( d1 - d2 > epsilon ) {
|
|
return PLANESIDE_FRONT;
|
|
}
|
|
if ( d1 + d2 < -epsilon ) {
|
|
return PLANESIDE_BACK;
|
|
}
|
|
return PLANESIDE_CROSS;
|
|
#endif
|
|
}
|