16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-22 13:59:19 +02:00

camera frustum

This commit is contained in:
tmj-fstate
2017-03-08 23:54:20 +01:00
parent 6526620364
commit b5ae395c42
11 changed files with 314 additions and 15 deletions

View File

@@ -169,3 +169,17 @@ void TCamera::Stop()
Type = tp_Follow; Type = tp_Follow;
Velocity = vector3(0, 0, 0); Velocity = vector3(0, 0, 0);
}; };
// returns true if specified object is within camera frustum, false otherwise
bool
TCamera::IsVisible( TDynamicObject const *Dynamic ) const {
// sphere test is faster than AABB, so we'll use it here
float3 diagonal(
Dynamic->MoverParameters->Dim.L,
Dynamic->MoverParameters->Dim.H,
Dynamic->MoverParameters->Dim.W );
float const radius = static_cast<float>(diagonal.Length()) * 0.5f;
return ( m_frustum.sphere_inside( Dynamic->GetPosition(), radius ) > 0.0f );
}

View File

@@ -11,6 +11,9 @@ http://mozilla.org/MPL/2.0/.
#define CameraH #define CameraH
#include "dumb3d.h" #include "dumb3d.h"
#include "frustum.h"
#include "dynobj.h"
using namespace Math3D; using namespace Math3D;
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -25,6 +28,8 @@ class TCamera
{ {
private: private:
vector3 pOffset; // nie używane (zerowe) vector3 pOffset; // nie używane (zerowe)
cFrustum m_frustum;
public: // McZapkie: potrzebuje do kiwania na boki public: // McZapkie: potrzebuje do kiwania na boki
double Pitch; double Pitch;
double Yaw; // w środku: 0=do przodu; na zewnątrz: 0=na południe double Yaw; // w środku: 0=do przodu; na zewnątrz: 0=na południe
@@ -51,6 +56,11 @@ class TCamera
void SetCabMatrix(vector3 &p); void SetCabMatrix(vector3 &p);
void RaLook(); void RaLook();
void Stop(); void Stop();
inline
void
SetFrustum() { m_frustum.calculate(); }
bool
IsVisible( TDynamicObject const *Dynamic ) const;
// bool GetMatrix(matrix4x4 &Matrix); // bool GetMatrix(matrix4x4 &Matrix);
vector3 PtNext, PtPrev; vector3 PtNext, PtPrev;
}; };

View File

@@ -3703,6 +3703,7 @@ void TDynamicObject::TurnOff()
void TDynamicObject::Render() void TDynamicObject::Render()
{ // rysowanie elementów nieprzezroczystych { // rysowanie elementów nieprzezroczystych
// youBy - sprawdzamy, czy jest sens renderowac // youBy - sprawdzamy, czy jest sens renderowac
/*
double modelrotate; double modelrotate;
vector3 tempangle; vector3 tempangle;
// zmienne // zmienne
@@ -3713,8 +3714,7 @@ void TDynamicObject::Render()
if (ObjSqrDist < 500) // jak jest blisko - do 70m if (ObjSqrDist < 500) // jak jest blisko - do 70m
modelrotate = 0.01; // mały kąt, żeby nie znikało modelrotate = 0.01; // mały kąt, żeby nie znikało
else else
{ // Global::pCameraRotation to kąt bewzględny w świecie (zero - na { // Global::pCameraRotation to kąt bewzględny w świecie (zero - na północ)
// północ)
tempangle = (vPosition - Global::pCameraPosition); // wektor od kamery tempangle = (vPosition - Global::pCameraPosition); // wektor od kamery
modelrotate = ABuAcos(tempangle); // określenie kąta modelrotate = ABuAcos(tempangle); // określenie kąta
// if (modelrotate>M_PI) modelrotate-=(2*M_PI); // if (modelrotate>M_PI) modelrotate-=(2*M_PI);
@@ -3730,8 +3730,8 @@ void TDynamicObject::Render()
if (modelrotate < maxrot) if (modelrotate < maxrot)
renderme = true; renderme = true;
*/
if (renderme) if (Global::pCamera->IsVisible(this))
{ {
TSubModel::iInstance = (size_t)this; //żeby nie robić cudzych animacji TSubModel::iInstance = (size_t)this; //żeby nie robić cudzych animacji
// AnsiString asLoadName=""; // AnsiString asLoadName="";

View File

@@ -93,7 +93,7 @@ void window_resize_callback(GLFWwindow *window, int w, int h)
{ {
Global::ScreenWidth = w; Global::ScreenWidth = w;
Global::ScreenHeight = h; Global::ScreenHeight = h;
Global::fDistanceFactor = h / 768.0f; // not sure if this is really something we want to use Global::fDistanceFactor = std::max( 0.5f, h / 768.0f ); // not sure if this is really something we want to use
glViewport(0, 0, w, h); glViewport(0, 0, w, h);
} }

View File

@@ -495,9 +495,9 @@ void Global::ConfigParse(cParser &Parser)
{ {
Parser.getTokens(); Parser.getTokens();
Parser >> token; Parser >> Global::bUseVBO;
// NOTE: temporary override until render paths are sorted out
Global::bUseVBO = (token == "yes"); Global::bUseVBO = false;
} }
else if (token == "feedbackmode") else if (token == "feedbackmode")
{ {

View File

@@ -1050,7 +1050,9 @@ void TSubModel::RaAnimation(TAnimType a)
void TSubModel::RenderDL() void TSubModel::RenderDL()
{ // główna procedura renderowania przez DL { // główna procedura renderowania przez DL
if (iVisible && (fSquareDist >= fSquareMinDist) && (fSquareDist < fSquareMaxDist)) if( ( iVisible )
&& ( fSquareDist >= (fSquareMinDist / Global::fDistanceFactor) )
&& ( fSquareDist <= (fSquareMaxDist * Global::fDistanceFactor) ) )
{ {
if (iFlags & 0xC000) if (iFlags & 0xC000)
{ {
@@ -1147,7 +1149,9 @@ void TSubModel::RenderDL()
void TSubModel::RenderAlphaDL() void TSubModel::RenderAlphaDL()
{ // renderowanie przezroczystych przez DL { // renderowanie przezroczystych przez DL
if (iVisible && (fSquareDist >= fSquareMinDist) && (fSquareDist < fSquareMaxDist)) if( ( iVisible )
&& ( fSquareDist >= (fSquareMinDist / Global::fDistanceFactor) )
&& ( fSquareDist <= (fSquareMaxDist * Global::fDistanceFactor) ) )
{ {
if (iFlags & 0xC000) if (iFlags & 0xC000)
{ {
@@ -1227,7 +1231,9 @@ void TSubModel::RenderAlphaDL()
void TSubModel::RenderVBO() void TSubModel::RenderVBO()
{ // główna procedura renderowania przez VBO { // główna procedura renderowania przez VBO
if (iVisible && (fSquareDist >= fSquareMinDist) && (fSquareDist < fSquareMaxDist)) if( ( iVisible )
&& ( fSquareDist >= (fSquareMinDist / Global::fDistanceFactor) )
&& ( fSquareDist <= (fSquareMaxDist * Global::fDistanceFactor) ) )
{ {
if (iFlags & 0xC000) if (iFlags & 0xC000)
{ {
@@ -1400,7 +1406,9 @@ void TSubModel::RenderVBO()
void TSubModel::RenderAlphaVBO() void TSubModel::RenderAlphaVBO()
{ // renderowanie przezroczystych przez VBO { // renderowanie przezroczystych przez VBO
if (iVisible && (fSquareDist >= fSquareMinDist) && (fSquareDist < fSquareMaxDist)) if( ( iVisible )
&& ( fSquareDist >= (fSquareMinDist / Global::fDistanceFactor) )
&& ( fSquareDist <= (fSquareMaxDist * Global::fDistanceFactor) ) )
{ {
if (iFlags & 0xC000) if (iFlags & 0xC000)
{ {
@@ -1475,6 +1483,8 @@ void TSubModel::RaArrayFill(CVertNormTex *Vert)
Next->RaArrayFill(Vert); Next->RaArrayFill(Vert);
}; };
// NOTE: leftover from static distance factor adjustment.
// TODO: get rid of it, once we have the dynamic adjustment code in place
void TSubModel::AdjustDist() void TSubModel::AdjustDist()
{ // aktualizacja odległości faz LoD, zależna od { // aktualizacja odległości faz LoD, zależna od
// rozdzielczości pionowej oraz multisamplingu // rozdzielczości pionowej oraz multisamplingu
@@ -2120,10 +2130,13 @@ void TModel3d::Init()
} }
if (iNumVerts) if (iNumVerts)
{ {
/* // NOTE: we will be applying distance factor dynamically during render,
// so we're leaving the defined ranges intact
if (Global::fDistanceFactor != if (Global::fDistanceFactor !=
1.0) // trochę zaoszczędzi czasu na modelach z wieloma submocelami 1.0) // trochę zaoszczędzi czasu na modelach z wieloma submocelami
Root->AdjustDist(); // aktualizacja odległości faz LoD, zależnie od Root->AdjustDist(); // aktualizacja odległości faz LoD, zależnie od
// rozdzielczości pionowej oraz multisamplingu // rozdzielczości pionowej oraz multisamplingu
*/
if (Global::bUseVBO) if (Global::bUseVBO)
{ {
if (!m_pVNT) // jeśli nie ma jeszcze tablicy (wczytano z pliku if (!m_pVNT) // jeśli nie ma jeszcze tablicy (wczytano z pliku

View File

@@ -30,8 +30,6 @@ http://mozilla.org/MPL/2.0/.
#include "Console.h" #include "Console.h"
#include "color.h" #include "color.h"
#define TEXTURE_FILTER_CONTROL_EXT 0x8500
#define TEXTURE_LOD_BIAS_EXT 0x8501
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// GLUTAPI void APIENTRY glutBitmapCharacterDLL(void *font, int character); // GLUTAPI void APIENTRY glutBitmapCharacterDLL(void *font, int character);
@@ -283,6 +281,7 @@ bool TWorld::Init( GLFWwindow *w ) {
glEnable(GL_CULL_FACE); // Cull back-facing triangles glEnable(GL_CULL_FACE); // Cull back-facing triangles
glLineWidth(1.0f); glLineWidth(1.0f);
glPointSize(3.0f); glPointSize(3.0f);
glEnable( GL_POINT_SMOOTH );
#ifdef EU07_USE_OLD_LIGHTING_MODEL #ifdef EU07_USE_OLD_LIGHTING_MODEL
// ----------- LIGHTING SETUP ----------- // ----------- LIGHTING SETUP -----------
// Light values and coordinates // Light values and coordinates
@@ -1110,13 +1109,22 @@ bool TWorld::Update()
int updatecount = 1; int updatecount = 1;
if( dt > m_primaryupdaterate ) // normalnie 0.01s if( dt > m_primaryupdaterate ) // normalnie 0.01s
{ {
/*
// NOTE: experimentally disabled physics update cap
auto const iterations = std::ceil(dt / m_primaryupdaterate); auto const iterations = std::ceil(dt / m_primaryupdaterate);
updatecount = std::min( 20, static_cast<int>( iterations ) ); updatecount = std::min( 20, static_cast<int>( iterations ) );
*/
updatecount = std::ceil( dt / m_primaryupdaterate );
/*
// NOTE: changing dt wrecks things further down the code. re-acquire proper value later or cleanup here
dt = dt / iterations; // Ra: fizykę lepiej by było przeliczać ze stałym krokiem dt = dt / iterations; // Ra: fizykę lepiej by było przeliczać ze stałym krokiem
*/
} }
// NOTE: updates are limited to 20, but dt is distributed over potentially many more iterations // NOTE: updates are limited to 20, but dt is distributed over potentially many more iterations
// this means at count > 20 simulation and render are going to desync. is that right? // this means at count > 20 simulation and render are going to desync. is that right?
Ground.Update(dt, updatecount); // tu zrobić tylko coklatkową aktualizację przesunięć // NOTE: experimentally changing this to prevent the desync.
// TODO: test what happens if we hit more than 20 * 0.01 sec slices, i.e. less than 5 fps
Ground.Update(dt / updatecount, updatecount); // tu zrobić tylko coklatkową aktualizację przesunięć
/* /*
if (DebugModeFlag) if (DebugModeFlag)
if (Global::bActive) // nie przyspieszać, gdy jedzie w tle :) if (Global::bActive) // nie przyspieszać, gdy jedzie w tle :)
@@ -1437,6 +1445,7 @@ bool TWorld::Render()
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity(); glLoadIdentity();
Camera.SetMatrix(); // ustawienie macierzy kamery względem początku scenerii Camera.SetMatrix(); // ustawienie macierzy kamery względem początku scenerii
Camera.SetFrustum(); // update camera frustum to match current data
if( !Global::bWireFrame ) { if( !Global::bWireFrame ) {
// bez nieba w trybie rysowania linii // bez nieba w trybie rysowania linii

178
frustum.cpp Normal file
View File

@@ -0,0 +1,178 @@
/*
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
*/
#include "stdafx.h"
#include "frustum.h"
void
cFrustum::calculate() {
float proj[ 16 ];
float modl[ 16 ];
float clip[ 16 ];
glGetFloatv( GL_PROJECTION_MATRIX, proj );
glGetFloatv( GL_MODELVIEW_MATRIX, modl );
// multiply the matrices to retrieve clipping planes
clip[ 0 ] = modl[ 0 ] * proj[ 0 ] + modl[ 1 ] * proj[ 4 ] + modl[ 2 ] * proj[ 8 ] + modl[ 3 ] * proj[ 12 ];
clip[ 1 ] = modl[ 0 ] * proj[ 1 ] + modl[ 1 ] * proj[ 5 ] + modl[ 2 ] * proj[ 9 ] + modl[ 3 ] * proj[ 13 ];
clip[ 2 ] = modl[ 0 ] * proj[ 2 ] + modl[ 1 ] * proj[ 6 ] + modl[ 2 ] * proj[ 10 ] + modl[ 3 ] * proj[ 14 ];
clip[ 3 ] = modl[ 0 ] * proj[ 3 ] + modl[ 1 ] * proj[ 7 ] + modl[ 2 ] * proj[ 11 ] + modl[ 3 ] * proj[ 15 ];
clip[ 4 ] = modl[ 4 ] * proj[ 0 ] + modl[ 5 ] * proj[ 4 ] + modl[ 6 ] * proj[ 8 ] + modl[ 7 ] * proj[ 12 ];
clip[ 5 ] = modl[ 4 ] * proj[ 1 ] + modl[ 5 ] * proj[ 5 ] + modl[ 6 ] * proj[ 9 ] + modl[ 7 ] * proj[ 13 ];
clip[ 6 ] = modl[ 4 ] * proj[ 2 ] + modl[ 5 ] * proj[ 6 ] + modl[ 6 ] * proj[ 10 ] + modl[ 7 ] * proj[ 14 ];
clip[ 7 ] = modl[ 4 ] * proj[ 3 ] + modl[ 5 ] * proj[ 7 ] + modl[ 6 ] * proj[ 11 ] + modl[ 7 ] * proj[ 15 ];
clip[ 8 ] = modl[ 8 ] * proj[ 0 ] + modl[ 9 ] * proj[ 4 ] + modl[ 10 ] * proj[ 8 ] + modl[ 11 ] * proj[ 12 ];
clip[ 9 ] = modl[ 8 ] * proj[ 1 ] + modl[ 9 ] * proj[ 5 ] + modl[ 10 ] * proj[ 9 ] + modl[ 11 ] * proj[ 13 ];
clip[ 10 ] = modl[ 8 ] * proj[ 2 ] + modl[ 9 ] * proj[ 6 ] + modl[ 10 ] * proj[ 10 ] + modl[ 11 ] * proj[ 14 ];
clip[ 11 ] = modl[ 8 ] * proj[ 3 ] + modl[ 9 ] * proj[ 7 ] + modl[ 10 ] * proj[ 11 ] + modl[ 11 ] * proj[ 15 ];
clip[ 12 ] = modl[ 12 ] * proj[ 0 ] + modl[ 13 ] * proj[ 4 ] + modl[ 14 ] * proj[ 8 ] + modl[ 15 ] * proj[ 12 ];
clip[ 13 ] = modl[ 12 ] * proj[ 1 ] + modl[ 13 ] * proj[ 5 ] + modl[ 14 ] * proj[ 9 ] + modl[ 15 ] * proj[ 13 ];
clip[ 14 ] = modl[ 12 ] * proj[ 2 ] + modl[ 13 ] * proj[ 6 ] + modl[ 14 ] * proj[ 10 ] + modl[ 15 ] * proj[ 14 ];
clip[ 15 ] = modl[ 12 ] * proj[ 3 ] + modl[ 13 ] * proj[ 7 ] + modl[ 14 ] * proj[ 11 ] + modl[ 15 ] * proj[ 15 ];
// get the sides of the frustum.
m_frustum[ side_RIGHT ][ plane_A ] = clip[ 3 ] - clip[ 0 ];
m_frustum[ side_RIGHT ][ plane_B ] = clip[ 7 ] - clip[ 4 ];
m_frustum[ side_RIGHT ][ plane_C ] = clip[ 11 ] - clip[ 8 ];
m_frustum[ side_RIGHT ][ plane_D ] = clip[ 15 ] - clip[ 12 ];
normalize_plane( side_RIGHT );
m_frustum[ side_LEFT ][ plane_A ] = clip[ 3 ] + clip[ 0 ];
m_frustum[ side_LEFT ][ plane_B ] = clip[ 7 ] + clip[ 4 ];
m_frustum[ side_LEFT ][ plane_C ] = clip[ 11 ] + clip[ 8 ];
m_frustum[ side_LEFT ][ plane_D ] = clip[ 15 ] + clip[ 12 ];
normalize_plane( side_LEFT );
m_frustum[ side_BOTTOM ][ plane_A ] = clip[ 3 ] + clip[ 1 ];
m_frustum[ side_BOTTOM ][ plane_B ] = clip[ 7 ] + clip[ 5 ];
m_frustum[ side_BOTTOM ][ plane_C ] = clip[ 11 ] + clip[ 9 ];
m_frustum[ side_BOTTOM ][ plane_D ] = clip[ 15 ] + clip[ 13 ];
normalize_plane( side_BOTTOM );
m_frustum[ side_TOP ][ plane_A ] = clip[ 3 ] - clip[ 1 ];
m_frustum[ side_TOP ][ plane_B ] = clip[ 7 ] - clip[ 5 ];
m_frustum[ side_TOP ][ plane_C ] = clip[ 11 ] - clip[ 9 ];
m_frustum[ side_TOP ][ plane_D ] = clip[ 15 ] - clip[ 13 ];
normalize_plane( side_TOP );
m_frustum[ side_BACK ][ plane_A ] = clip[ 3 ] - clip[ 2 ];
m_frustum[ side_BACK ][ plane_B ] = clip[ 7 ] - clip[ 6 ];
m_frustum[ side_BACK ][ plane_C ] = clip[ 11 ] - clip[ 10 ];
m_frustum[ side_BACK ][ plane_D ] = clip[ 15 ] - clip[ 14 ];
normalize_plane( side_BACK );
m_frustum[ side_FRONT ][ plane_A ] = clip[ 3 ] + clip[ 2 ];
m_frustum[ side_FRONT ][ plane_B ] = clip[ 7 ] + clip[ 6 ];
m_frustum[ side_FRONT ][ plane_C ] = clip[ 11 ] + clip[ 10 ];
m_frustum[ side_FRONT ][ plane_D ] = clip[ 15 ] + clip[ 14 ];
normalize_plane( side_FRONT );
}
bool
cFrustum::point_inside( float const X, float const Y, float const Z ) const {
// cycle through the sides of the frustum, checking if the point is behind them
for( int idx = 0; idx < 6; ++idx ) {
if( m_frustum[ idx ][ plane_A ] * X
+ m_frustum[ idx ][ plane_B ] * Y
+ m_frustum[ idx ][ plane_C ] * Z
+ m_frustum[ idx ][ plane_D ] <= 0 )
return false;
}
// the point is in front of each frustum plane, i.e. inside of the frustum
return true;
}
float
cFrustum::sphere_inside( float const X, float const Y, float const Z, float const Radius ) const {
float distance;
// go through all the sides of the frustum. bail out as soon as possible
for( int idx = 0; idx < 6; ++idx ) {
distance =
m_frustum[ idx ][ plane_A ] * X
+ m_frustum[ idx ][ plane_B ] * Y
+ m_frustum[ idx ][ plane_C ] * Z
+ m_frustum[ idx ][ plane_D ];
if( distance <= -Radius )
return 0.0f;
}
return distance + Radius;
}
bool
cFrustum::cube_inside( float const X, float const Y, float const Z, float const Size ) const {
for( int idx = 0; idx < 6; ++idx ) {
if( m_frustum[ idx ][ plane_A ] * ( X - Size )
+ m_frustum[ idx ][ plane_B ] * ( Y - Size )
+ m_frustum[ idx ][ plane_C ] * ( Z - Size )
+ m_frustum[ idx ][ plane_D ] > 0 )
continue;
if( m_frustum[ idx ][ plane_A ] * ( X + Size )
+ m_frustum[ idx ][ plane_B ] * ( Y - Size )
+ m_frustum[ idx ][ plane_C ] * ( Z - Size )
+ m_frustum[ idx ][ plane_D ] > 0 )
continue;
if( m_frustum[ idx ][ plane_A ] * ( X - Size )
+ m_frustum[ idx ][ plane_B ] * ( Y + Size )
+ m_frustum[ idx ][ plane_C ] * ( Z - Size )
+ m_frustum[ idx ][ plane_D ] > 0 )
continue;
if( m_frustum[ idx ][ plane_A ] * ( X + Size )
+ m_frustum[ idx ][ plane_B ] * ( Y + Size )
+ m_frustum[ idx ][ plane_C ] * ( Z - Size )
+ m_frustum[ idx ][ plane_D ] > 0 )
continue;
if( m_frustum[ idx ][ plane_A ] * ( X - Size )
+ m_frustum[ idx ][ plane_B ] * ( Y - Size )
+ m_frustum[ idx ][ plane_C ] * ( Z + Size )
+ m_frustum[ idx ][ plane_D ] > 0 )
continue;
if( m_frustum[ idx ][ plane_A ] * ( X + Size )
+ m_frustum[ idx ][ plane_B ] * ( Y - Size )
+ m_frustum[ idx ][ plane_C ] * ( Z + Size )
+ m_frustum[ idx ][ plane_D ] > 0 )
continue;
if( m_frustum[ idx ][ plane_A ] * ( X - Size )
+ m_frustum[ idx ][ plane_B ] * ( Y + Size )
+ m_frustum[ idx ][ plane_C ] * ( Z + Size )
+ m_frustum[ idx ][ plane_D ] > 0 )
continue;
if( m_frustum[ idx ][ plane_A ] * ( X + Size )
+ m_frustum[ idx ][ plane_B ] * ( Y + Size )
+ m_frustum[ idx ][ plane_C ] * ( Z + Size )
+ m_frustum[ idx ][ plane_D ] > 0 )
continue;
return false;
}
return true;
}
void cFrustum::normalize_plane( cFrustum::side const Side ) {
float magnitude =
std::sqrt(
m_frustum[ Side ][ plane_A ] * m_frustum[ Side ][ plane_A ]
+ m_frustum[ Side ][ plane_B ] * m_frustum[ Side ][ plane_B ]
+ m_frustum[ Side ][ plane_C ] * m_frustum[ Side ][ plane_C ] );
m_frustum[ Side ][ plane_A ] /= magnitude;
m_frustum[ Side ][ plane_B ] /= magnitude;
m_frustum[ Side ][ plane_C ] /= magnitude;
m_frustum[ Side ][ plane_D ] /= magnitude;
}

67
frustum.h Normal file
View File

@@ -0,0 +1,67 @@
/*
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
*/
#pragma once
#include "float3d.h"
#include "dumb3d.h"
// generic frustum class. used to determine if objects are inside current view area
class cFrustum {
public:
// constructors:
// methods:
// update the frustum to match current view orientation
void
calculate();
// returns true if specified point is inside of the frustum
inline
bool
point_inside( float3 const &Point ) const { return point_inside( Point.x, Point.y, Point.z ); }
inline
bool
point_inside( Math3D::vector3 const &Point ) const { return point_inside( static_cast<float>( Point.x ), static_cast<float>( Point.y ), static_cast<float>( Point.z ) ); }
bool
point_inside( float const X, float const Y, float const Z ) const;
// tests if the sphere is in frustum, returns the distance between origin and sphere centre
inline
float
sphere_inside( float3 const &Center, float const Radius ) const { return sphere_inside( Center.x, Center.y, Center.z, Radius ); }
inline
float
sphere_inside( Math3D::vector3 const &Center, float const Radius ) const { return sphere_inside( static_cast<float>( Center.x ), static_cast<float>( Center.y ), static_cast<float>( Center.z ), Radius ); }
float
sphere_inside( float const X, float const Y, float const Z, float const Radius ) const;
// returns true if specified cube is inside of the frustum. Size = half of the length
inline
bool
cube_inside( float3 const &Center, float const Size ) const { return cube_inside( Center.x, Center.y, Center.z, Size ); }
inline
bool
cube_inside( Math3D::vector3 const &Center, float const Size ) const { return cube_inside( static_cast<float>( Center.x ), static_cast<float>( Center.y ), static_cast<float>( Center.z ), Size ); }
bool
cube_inside( float const X, float const Y, float const Z, float const Size ) const;
protected:
// types:
// planes of the frustum
enum side { side_RIGHT = 0, side_LEFT = 1, side_BOTTOM = 2, side_TOP = 3, side_BACK = 4, side_FRONT = 5 };
// parameters of the frustum plane: A, B, C define plane normal, D defines distance from origin
enum plane { plane_A = 0, plane_B = 1, plane_C = 2, plane_D = 3 };
// methods:
void
normalize_plane( cFrustum::side const Side ); // normalizes a plane (A side) from the frustum
// members:
float m_frustum[6][4]; // holds the A B C and D values (normal & distance) for each side of the frustum.
};

View File

@@ -101,6 +101,7 @@
<ClCompile Include="EvLaunch.cpp" /> <ClCompile Include="EvLaunch.cpp" />
<ClCompile Include="FadeSound.cpp" /> <ClCompile Include="FadeSound.cpp" />
<ClCompile Include="Float3d.cpp" /> <ClCompile Include="Float3d.cpp" />
<ClCompile Include="frustum.cpp" />
<ClCompile Include="Gauge.cpp" /> <ClCompile Include="Gauge.cpp" />
<ClCompile Include="Globals.cpp" /> <ClCompile Include="Globals.cpp" />
<ClCompile Include="Ground.cpp" /> <ClCompile Include="Ground.cpp" />
@@ -166,6 +167,7 @@
<ClInclude Include="EvLaunch.h" /> <ClInclude Include="EvLaunch.h" />
<ClInclude Include="FadeSound.h" /> <ClInclude Include="FadeSound.h" />
<ClInclude Include="Float3d.h" /> <ClInclude Include="Float3d.h" />
<ClInclude Include="frustum.h" />
<ClInclude Include="Gauge.h" /> <ClInclude Include="Gauge.h" />
<ClInclude Include="Globals.h" /> <ClInclude Include="Globals.h" />
<ClInclude Include="Ground.h" /> <ClInclude Include="Ground.h" />

View File

@@ -201,6 +201,9 @@
<ClCompile Include="sn_utils.cpp"> <ClCompile Include="sn_utils.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="frustum.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Globals.h"> <ClInclude Include="Globals.h">
@@ -389,6 +392,9 @@
<ClInclude Include="sn_utils.h"> <ClInclude Include="sn_utils.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="frustum.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="maszyna.rc"> <ResourceCompile Include="maszyna.rc">