168 lines
4.7 KiB
C
168 lines
4.7 KiB
C
|
// Copyright (C) 2007 Id Software, Inc.
|
||
|
//
|
||
|
|
||
|
|
||
|
#include "../../renderer/DeviceContext.h"
|
||
|
|
||
|
#ifndef __GAME_MISC_WORLDTOSCREEN_H__
|
||
|
#define __GAME_MISC_WORLDTOSCREEN_H__
|
||
|
|
||
|
/*
|
||
|
============
|
||
|
sdWorldToScreenConverter
|
||
|
============
|
||
|
*/
|
||
|
class sdWorldToScreenConverter {
|
||
|
public:
|
||
|
sdWorldToScreenConverter( const renderView_t& view );
|
||
|
sdWorldToScreenConverter( float* projectionMatrix, float* modelViewMatrix );
|
||
|
|
||
|
void Transform( const idVec3& src, idVec2& dst ) const;
|
||
|
void Transform( const idBounds& src, const idMat3& axes, const idVec3& origin, sdBounds2D& dst ) const;
|
||
|
|
||
|
void Setup( const renderView_t& view );
|
||
|
void Setup( float* projectionMatrix, float* modelViewMatrix );
|
||
|
|
||
|
void SetExtents( const idVec2& _extents ) { extents = _extents; }
|
||
|
|
||
|
static bool TransformClipped( const idBounds &bounds, const idMat3& axes, const idVec3& origin, sdBounds2D& dst, const idFrustum& frustum, const idVec2& extents );
|
||
|
|
||
|
protected:
|
||
|
float projectionMatrixArray[ 16 ];
|
||
|
float modelViewMatrixArray[ 16 ];
|
||
|
|
||
|
float* projectionMatrix;
|
||
|
float* modelViewMatrix;
|
||
|
|
||
|
idVec2 extents;
|
||
|
};
|
||
|
|
||
|
|
||
|
/*
|
||
|
======================
|
||
|
sdWorldToScreenConverter::TransformClipped
|
||
|
======================
|
||
|
*/
|
||
|
ID_INLINE bool sdWorldToScreenConverter::TransformClipped( const idBounds &bounds, const idMat3& axes, const idVec3& origin, sdBounds2D& dst, const idFrustum& frustum, const idVec2& extents ) {
|
||
|
idBounds temp;
|
||
|
if ( !frustum.ProjectionBounds( idBox( bounds, origin, axes ), temp ) ) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
dst.GetMins().x = 0.5f * ( 1.0f - temp[ 1 ].y ) * extents.x;
|
||
|
dst.GetMaxs().x = 0.5f * ( 1.0f - temp[ 0 ].y ) * extents.x;
|
||
|
|
||
|
dst.GetMins().y = 0.5f * ( 1.0f - temp[ 1 ].z ) * extents.y;
|
||
|
dst.GetMaxs().y = 0.5f * ( 1.0f - temp[ 0 ].z ) * extents.y;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
==========================
|
||
|
sdWorldToScreenConverter::sdWorldToScreenConverter
|
||
|
==========================
|
||
|
*/
|
||
|
ID_INLINE sdWorldToScreenConverter::sdWorldToScreenConverter( const renderView_t& view ) {
|
||
|
const float width = SCREEN_WIDTH * 1.0f / deviceContext->GetAspectRatioCorrection();
|
||
|
extents.Set( width, SCREEN_HEIGHT );
|
||
|
Setup( view );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
==========================
|
||
|
sdWorldToScreenConverter::sdWorldToScreenConverter
|
||
|
==========================
|
||
|
*/
|
||
|
ID_INLINE sdWorldToScreenConverter::sdWorldToScreenConverter( float* projectionMatrix, float* modelViewMatrix ) {
|
||
|
const float width = SCREEN_WIDTH * 1.0f / deviceContext->GetAspectRatioCorrection();
|
||
|
extents.Set( width, SCREEN_HEIGHT );
|
||
|
Setup( projectionMatrix, modelViewMatrix );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
==========================
|
||
|
sdWorldToScreenConverter::Transform
|
||
|
==========================
|
||
|
*/
|
||
|
ID_INLINE void sdWorldToScreenConverter::Transform( const idVec3& src, idVec2& dst ) const {
|
||
|
int i;
|
||
|
idPlane eye, clip;
|
||
|
|
||
|
for ( i = 0 ; i < 4 ; i++ ) {
|
||
|
eye[i] =
|
||
|
src[0] * modelViewMatrix[ i + 0 * 4 ] +
|
||
|
src[1] * modelViewMatrix[ i + 1 * 4 ] +
|
||
|
src[2] * modelViewMatrix[ i + 2 * 4 ] +
|
||
|
modelViewMatrix[ i + 3 * 4 ];
|
||
|
}
|
||
|
|
||
|
for ( i = 0 ; i < 4 ; i++ ) {
|
||
|
clip[i] =
|
||
|
eye[0] * projectionMatrix[ i + 0 * 4 ] +
|
||
|
eye[1] * projectionMatrix[ i + 1 * 4 ] +
|
||
|
eye[2] * projectionMatrix[ i + 2 * 4 ] +
|
||
|
eye[3] * projectionMatrix[ i + 3 * 4 ];
|
||
|
}
|
||
|
|
||
|
if( clip[ 3 ] <= 0.01f ) {
|
||
|
clip[ 3 ] = 0.01f;
|
||
|
}
|
||
|
|
||
|
dst[ 0 ] = clip[ 0 ] / clip[ 3 ];
|
||
|
dst[ 1 ] = clip[ 1 ] / clip[ 3 ];
|
||
|
|
||
|
dst[ 0 ] = ( 0.5f * ( 1.0f + dst[ 0 ] ) * extents[ 0 ] );
|
||
|
dst[ 1 ] = ( 0.5f * ( 1.0f - dst[ 1 ] ) * extents[ 1 ] );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
==========================
|
||
|
sdWorldToScreenConverter::Transform
|
||
|
==========================
|
||
|
*/
|
||
|
ID_INLINE void sdWorldToScreenConverter::Transform( const idBounds& src, const idMat3& axes, const idVec3& origin, sdBounds2D& dst ) const {
|
||
|
idVec3 point;
|
||
|
idVec2 screenPoint;
|
||
|
|
||
|
dst.Clear();
|
||
|
|
||
|
int i;
|
||
|
for ( i = 0; i < 8; i++ ) {
|
||
|
point[ 0 ] = src[ ( i & 1 ) >> 0 ][ 0 ];
|
||
|
point[ 1 ] = src[ ( i & 2 ) >> 1 ][ 1 ];
|
||
|
point[ 2 ] = src[ ( i & 4 ) >> 2 ][ 2 ];
|
||
|
|
||
|
point *= axes;
|
||
|
point += origin;
|
||
|
|
||
|
Transform( point, screenPoint );
|
||
|
|
||
|
dst.AddPoint( screenPoint );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
==========================
|
||
|
sdWorldToScreenConverter::Setup
|
||
|
==========================
|
||
|
*/
|
||
|
ID_INLINE void sdWorldToScreenConverter::Setup( const renderView_t& view ) {
|
||
|
projectionMatrix = projectionMatrixArray;
|
||
|
modelViewMatrix = modelViewMatrixArray;
|
||
|
gameRenderWorld->SetupMatrices( &view, projectionMatrix, modelViewMatrix, false );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
==========================
|
||
|
sdWorldToScreenConverter::Setup
|
||
|
==========================
|
||
|
*/
|
||
|
ID_INLINE void sdWorldToScreenConverter::Setup( float* projectionMatrix, float* modelViewMatrix ) {
|
||
|
this->projectionMatrix = projectionMatrix;
|
||
|
this->modelViewMatrix = modelViewMatrix;
|
||
|
}
|
||
|
|
||
|
#endif // __GAME_MISC_WORLDTOSCREEN_H__
|