mirror of
https://github.com/thug1src/thug.git
synced 2025-01-22 05:43:47 +00:00
155 lines
5.3 KiB
C++
155 lines
5.3 KiB
C++
///////////////////////////////////////////////////////////////////////////////
|
|
// p_NxViewport.cpp
|
|
|
|
#include "Gfx/NxViewMan.h"
|
|
#include "Gfx/NGPS/p_NxViewport.h"
|
|
|
|
#include "Gfx/NGPS/NX/render.h"
|
|
#include "Gfx/NGPS/NX/sprite.h"
|
|
#include "Gfx/NGPS/NX/switches.h"
|
|
|
|
namespace Nx
|
|
{
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////
|
|
// Here's a machine specific implementation of CViewport
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
CPs2Viewport::CPs2Viewport()
|
|
{
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
CPs2Viewport::CPs2Viewport( const Mth::Rect* rect, Gfx::Camera* cam) :
|
|
CViewport(rect, cam)
|
|
{
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
CPs2Viewport::~CPs2Viewport()
|
|
{
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
void CPs2Viewport::update_render_vars()
|
|
{
|
|
int view_idx = CViewportManager::sGetActiveViewportNumber(this);
|
|
Dbg_MsgAssert(view_idx >= 0, ("Can't find viewport in active viewport list"));
|
|
|
|
if (!NxPs2::render::VarsUpToDate(view_idx) && mp_camera)
|
|
{
|
|
Mth::Matrix cam_matrix(mp_camera->GetMatrix());
|
|
cam_matrix[W] = mp_camera->GetPos();
|
|
|
|
NxPs2::render::SetupVars(view_idx, cam_matrix, GetRect(), mp_camera->GetAdjustedHFOV(), GetAspectRatio(),
|
|
/*-mp_camera->GetNearClipPlane(), -mp_camera->GetFarClipPlane()*/ -1.0f, -100000.0f);
|
|
}
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
float CPs2Viewport::plat_transform_to_screen_coord(const Mth::Vector & world_pos, float & screen_pos_x, float & screen_pos_y, ZBufferValue & screen_pos_z)
|
|
{
|
|
float zdistance;
|
|
float scale;
|
|
|
|
update_render_vars();
|
|
|
|
// First check frustum
|
|
Mth::Vector screen_pos(NxPs2::render::WorldToFrustum.Transform(world_pos));
|
|
|
|
//if ((Tmr::GetVblanks() % 200) == 0)
|
|
//{
|
|
// Dbg_Message("Homogenious (%g, %g, %g, %g)", screen_pos[X], screen_pos[Y], screen_pos[Z], screen_pos[W]);
|
|
//}
|
|
|
|
if ((screen_pos[X] > screen_pos[W]) || (screen_pos[X] < -screen_pos[W]) ||
|
|
(screen_pos[Y] > screen_pos[W]) || (screen_pos[Y] < -screen_pos[W]) ||
|
|
(screen_pos[Z] > screen_pos[W]) || (screen_pos[Z] < -screen_pos[W]))
|
|
{
|
|
return -1.0f;
|
|
} else {
|
|
zdistance = -screen_pos[Z]; //(screen_pos[Z] - screen_pos[W]) / (2.0f * screen_pos[W]);
|
|
}
|
|
|
|
// Now find screen coordinates
|
|
screen_pos = NxPs2::render::WorldToIntViewport.Transform(world_pos);
|
|
|
|
//if ((Tmr::GetVblanks() % 200) == 0)
|
|
//{
|
|
// Dbg_Message("Converted (%f, %f, %f, %f) to (%g, %g, %g, %g)", world_pos[X], world_pos[Y], world_pos[Z], world_pos[W],
|
|
// screen_pos[X], screen_pos[Y], screen_pos[Z], screen_pos[W]);
|
|
//}
|
|
|
|
// Get into homogenious space
|
|
float oow = 1.0f / screen_pos[W];
|
|
screen_pos *= oow;
|
|
|
|
// Convert the int back to float
|
|
screen_pos_x = (((float) ( *((int *) &(screen_pos[X])) & 0xFFFF )) - XOFFSET) / 16.0f;
|
|
screen_pos_y = (((float) ( *((int *) &(screen_pos[Y])) & 0xFFFF )) - YOFFSET) / 16.0f;
|
|
screen_pos_z = (ZBufferValue) ( *((int *) &(screen_pos[Z])) & 0xFFFFFF );
|
|
|
|
// Convert back to NTSC, if necessary
|
|
screen_pos_x /= NxPs2::SDraw2D::GetScreenScaleX();
|
|
screen_pos_y /= NxPs2::SDraw2D::GetScreenScaleY();
|
|
|
|
//if ((Tmr::GetVblanks() % 200) == 0)
|
|
//{
|
|
// Dbg_Message("Divide by W (%g, %g, %x, %g) Z distance: %g", screen_pos_x, screen_pos_y, screen_pos_z, screen_pos[W], zdistance);
|
|
//}
|
|
|
|
// Calculate scale
|
|
scale = CViewportManager::sGet2DIn3DSpaceNoscaleDistance() / zdistance;
|
|
scale = Mth::Min(scale, CViewportManager::sGet2DIn3DSpaceMaxScale());
|
|
scale = Mth::Max(scale, CViewportManager::sGet2DIn3DSpaceMinScale());
|
|
|
|
#if 0 // This scales 1 sprite or text pixel to an inch!
|
|
float hfov;
|
|
if (mp_camera)
|
|
{
|
|
hfov = mp_camera->GetAdjustedHFOV();
|
|
} else {
|
|
hfov = CViewportManager::sGetScreenAngle();
|
|
}
|
|
|
|
// Calculate scale
|
|
float h = ((float) HRES) / (tanf(Mth::DegToRad(hfov / 2.0f)));
|
|
scale = h / zdistance;
|
|
|
|
if ((Tmr::GetVblanks() % 300) == 0)
|
|
{
|
|
Dbg_Message("H %f, ZDistance %f, Scale %f, HFOC %f", h, zdistance, scale, hfov);
|
|
}
|
|
#endif
|
|
|
|
return scale;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
// Private classes
|
|
//
|
|
|
|
} // Namespace Nx
|
|
|
|
|