etqw-sdk/source/idlib/bv/BoundsShort.cpp

163 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
}