mirror of
https://github.com/AxioDL/PrimeWorldEditor.git
synced 2025-12-16 16:37:02 +00:00
Implemented frustum culling
This commit is contained in:
@@ -18,6 +18,7 @@ CCamera::CCamera()
|
||||
mLookSpeed = 1.f; // Old: 0.003f
|
||||
mViewOutdated = true;
|
||||
mProjectionOutdated = true;
|
||||
mFrustumPlanesOutdated = true;
|
||||
}
|
||||
|
||||
CCamera::CCamera(CVector3f Position, CVector3f)
|
||||
@@ -50,6 +51,7 @@ void CCamera::Pan(float XAmount, float YAmount)
|
||||
mPosition += Right * (XAmount * mMoveSpeed);
|
||||
mPosition += Up * (YAmount * mMoveSpeed);
|
||||
mViewOutdated = true;
|
||||
mFrustumPlanesOutdated = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -77,6 +79,7 @@ void CCamera::Rotate(float XAmount, float YAmount)
|
||||
mYaw -= (XAmount * mLookSpeed * 0.3f);
|
||||
mPitch -= (YAmount * mLookSpeed * 0.3f);
|
||||
mViewOutdated = true;
|
||||
mFrustumPlanesOutdated = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -85,6 +88,7 @@ void CCamera::Zoom(float Amount)
|
||||
{
|
||||
mPosition += (mDirection * Amount) * (mMoveSpeed * 25.f);
|
||||
mViewOutdated = true;
|
||||
mFrustumPlanesOutdated = true;
|
||||
}
|
||||
|
||||
void CCamera::Snap(CVector3f Position)
|
||||
@@ -93,6 +97,8 @@ void CCamera::Snap(CVector3f Position)
|
||||
mYaw = -Math::skHalfPi;
|
||||
mPitch = 0.0f;
|
||||
mViewOutdated = true;
|
||||
mFrustumPlanesOutdated = true;
|
||||
CalculateDirection();
|
||||
}
|
||||
|
||||
void CCamera::ProcessKeyInput(EKeyInputs KeyFlags, double DeltaTime)
|
||||
@@ -132,6 +138,8 @@ void CCamera::ProcessMouseInput(EKeyInputs KeyFlags, EMouseInputs MouseFlags, fl
|
||||
else if ((MouseFlags & eMiddleButton) || (MouseFlags & eRightButton))
|
||||
Pan(XMovement, YMovement);
|
||||
}
|
||||
|
||||
CalculateDirection();
|
||||
}
|
||||
|
||||
CRay CCamera::CastRay(CVector2f DeviceCoords)
|
||||
@@ -215,17 +223,27 @@ const CMatrix4f& CCamera::ProjectionMatrix()
|
||||
return mCachedProjectionMatrix;
|
||||
}
|
||||
|
||||
const CFrustumPlanes& CCamera::FrustumPlanes()
|
||||
{
|
||||
if (mFrustumPlanesOutdated)
|
||||
CalculateFrustumPlanes();
|
||||
|
||||
return mCachedFrustumPlanes;
|
||||
}
|
||||
|
||||
// ************ SETTERS ************
|
||||
void CCamera::SetPosition(CVector3f Position)
|
||||
{
|
||||
mPosition = Position;
|
||||
mViewOutdated = true;
|
||||
mFrustumPlanesOutdated = true;
|
||||
}
|
||||
|
||||
void CCamera::SetDirection(CVector3f Direction)
|
||||
{
|
||||
mDirection = Direction;
|
||||
mViewOutdated = true;
|
||||
mFrustumPlanesOutdated = true;
|
||||
}
|
||||
|
||||
void CCamera::SetYaw(float Yaw)
|
||||
@@ -263,6 +281,7 @@ void CCamera::SetAspectRatio(float AspectRatio)
|
||||
{
|
||||
mAspectRatio = AspectRatio;
|
||||
mProjectionOutdated = true;
|
||||
mFrustumPlanesOutdated = true;
|
||||
}
|
||||
|
||||
// ************ PRIVATE ************
|
||||
@@ -303,3 +322,9 @@ void CCamera::CalculateProjection()
|
||||
mCachedProjectionMatrix = Math::PerspectiveMatrix(55.f, mAspectRatio, 0.1f, 4096.f);
|
||||
mProjectionOutdated = false;
|
||||
}
|
||||
|
||||
void CCamera::CalculateFrustumPlanes()
|
||||
{
|
||||
mCachedFrustumPlanes.SetPlanes(mPosition, mDirection, 55.f, mAspectRatio, 0.1f, 4096.f);
|
||||
mFrustumPlanesOutdated = false;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef CCAMERA_H
|
||||
#define CCAMERA_H
|
||||
|
||||
#include "CFrustumPlanes.h"
|
||||
#include <Common/CAABox.h>
|
||||
#include <Common/CMatrix4f.h>
|
||||
#include <Common/CRay.h>
|
||||
@@ -30,8 +31,10 @@ class CCamera
|
||||
|
||||
CMatrix4f mCachedViewMatrix;
|
||||
CMatrix4f mCachedProjectionMatrix;
|
||||
CFrustumPlanes mCachedFrustumPlanes;
|
||||
bool mViewOutdated;
|
||||
bool mProjectionOutdated;
|
||||
bool mFrustumPlanesOutdated;
|
||||
|
||||
public:
|
||||
CCamera();
|
||||
@@ -56,6 +59,7 @@ public:
|
||||
const CMatrix4f& ViewMatrix();
|
||||
CMatrix4f RotationOnlyViewMatrix();
|
||||
const CMatrix4f& ProjectionMatrix();
|
||||
const CFrustumPlanes& FrustumPlanes();
|
||||
|
||||
// Setters
|
||||
void SetPosition(CVector3f Position);
|
||||
@@ -74,6 +78,7 @@ private:
|
||||
void CalculateDirection();
|
||||
void CalculateView();
|
||||
void CalculateProjection();
|
||||
void CalculateFrustumPlanes();
|
||||
};
|
||||
|
||||
#endif // CCAMERA_H
|
||||
|
||||
98
Core/CFrustumPlanes.cpp
Normal file
98
Core/CFrustumPlanes.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
#include "CFrustumPlanes.h"
|
||||
#include <Common/Math.h>
|
||||
#include <Common/types.h>
|
||||
|
||||
CFrustumPlanes::CFrustumPlanes()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CFrustumPlanes::~CFrustumPlanes()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const CPlane& CFrustumPlanes::GetPlane(EFrustumSide side) const
|
||||
{
|
||||
return mPlanes[side];
|
||||
}
|
||||
|
||||
void CFrustumPlanes::SetPlanes(const CVector3f& position, const CVector3f& direction, float fieldOfView, float aspectRatio, float near, float far)
|
||||
{
|
||||
// Calculate up/right vectors
|
||||
CVector3f right = direction.Cross(CVector3f::skUp).Normalized();
|
||||
CVector3f up = right.Cross(direction).Normalized();
|
||||
|
||||
// Calculate dimensions of near plane
|
||||
float nearHeight = 2 * tanf(Math::DegreesToRadians(fieldOfView) / 2.f) * near;
|
||||
float nearWidth = nearHeight * aspectRatio;
|
||||
|
||||
// Define the planes
|
||||
CVector3f nearCenter = position + (direction * near);
|
||||
mPlanes[eNearPlane].Redefine(direction, nearCenter);
|
||||
|
||||
CVector3f farCenter = position + (direction * far);
|
||||
mPlanes[eFarPlane].Redefine(-direction, farCenter);
|
||||
|
||||
CVector3f midRight = nearCenter + (right * (nearWidth / 2.f));
|
||||
CVector3f rightNormal = up.Cross((midRight - position).Normalized());
|
||||
mPlanes[eRightPlane].Redefine(rightNormal, position);
|
||||
|
||||
CVector3f midLeft = nearCenter - (right * (nearWidth / 2.f));
|
||||
CVector3f leftNormal = (midLeft - position).Normalized().Cross(up);
|
||||
mPlanes[eLeftPlane].Redefine(leftNormal, position);
|
||||
|
||||
CVector3f midTop = nearCenter + (up * (nearHeight / 2.f));
|
||||
CVector3f topNormal = (midTop - position).Normalized().Cross(right);
|
||||
mPlanes[eTopPlane].Redefine(topNormal, position);
|
||||
|
||||
CVector3f midBottom = nearCenter - (up * (nearHeight / 2.f));
|
||||
CVector3f bottomNormal = right.Cross((midBottom - position).Normalized());
|
||||
mPlanes[eBottomPlane].Redefine(bottomNormal, position);
|
||||
}
|
||||
|
||||
bool CFrustumPlanes::PointInFrustum(const CVector3f& point) const
|
||||
{
|
||||
for (u32 iPlane = 0; iPlane < 6; iPlane++)
|
||||
{
|
||||
const CPlane& plane = mPlanes[iPlane];
|
||||
|
||||
if (plane.Normal().Dot(point) + plane.Dist() < 0.f)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CFrustumPlanes::BoxInFrustum(const CAABox& box) const
|
||||
{
|
||||
CVector3f min = box.Min();
|
||||
CVector3f max = box.Max();
|
||||
|
||||
CVector3f points[8];
|
||||
points[0] = min;
|
||||
points[1] = max;
|
||||
points[2] = CVector3f(min.x, min.y, max.z);
|
||||
points[3] = CVector3f(min.x, max.y, min.z);
|
||||
points[4] = CVector3f(min.x, max.y, max.z);
|
||||
points[5] = CVector3f(max.x, min.y, max.z);
|
||||
points[6] = CVector3f(max.x, max.y, min.z);
|
||||
points[7] = CVector3f(max.x, min.y, min.z);
|
||||
|
||||
for (u32 iPlane = 0; iPlane < 6; iPlane++)
|
||||
{
|
||||
const CPlane& plane = mPlanes[iPlane];
|
||||
int numPoints = 0;
|
||||
|
||||
for (u32 iPoint = 0; iPoint < 8; iPoint++)
|
||||
{
|
||||
if (plane.Normal().Dot(points[iPoint]) + plane.Dist() < 0.f)
|
||||
numPoints++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (numPoints == 8) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
30
Core/CFrustumPlanes.h
Normal file
30
Core/CFrustumPlanes.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef CFRUSTUMPLANES_H
|
||||
#define CFRUSTUMPLANES_H
|
||||
|
||||
#include <Common/CAABox.h>
|
||||
#include <Common/CPlane.h>
|
||||
#include <Common/CVector3f.h>
|
||||
|
||||
class CFrustumPlanes
|
||||
{
|
||||
public:
|
||||
enum EFrustumSide
|
||||
{
|
||||
eNearPlane = 0, eFarPlane = 1,
|
||||
eTopPlane = 2, eBottomPlane = 3,
|
||||
eLeftPlane = 4, eRightPlane = 5
|
||||
};
|
||||
|
||||
private:
|
||||
CPlane mPlanes[6];
|
||||
|
||||
public:
|
||||
CFrustumPlanes();
|
||||
~CFrustumPlanes();
|
||||
const CPlane& GetPlane(EFrustumSide side) const;
|
||||
void SetPlanes(const CVector3f& position, const CVector3f& direction, float fieldOfView, float aspectRatio, float near, float far);
|
||||
bool PointInFrustum(const CVector3f& point) const;
|
||||
bool BoxInFrustum(const CAABox& box) const;
|
||||
};
|
||||
|
||||
#endif // CFRUSTUMPLANES_H
|
||||
@@ -215,7 +215,7 @@ void CSceneManager::ClearScene()
|
||||
mNodeCount = 0;
|
||||
}
|
||||
|
||||
void CSceneManager::AddSceneToRenderer(CRenderer *pRenderer)
|
||||
void CSceneManager::AddSceneToRenderer(CRenderer *pRenderer, CCamera& camera)
|
||||
{
|
||||
ERenderOptions options = pRenderer->RenderOptions();
|
||||
|
||||
@@ -223,32 +223,32 @@ void CSceneManager::AddSceneToRenderer(CRenderer *pRenderer)
|
||||
{
|
||||
for (u32 n = 0; n < mModelNodes.size(); n++)
|
||||
if (mModelNodes[n]->IsVisible())
|
||||
mModelNodes[n]->AddToRenderer(pRenderer);
|
||||
mModelNodes[n]->AddToRenderer(pRenderer, camera.FrustumPlanes());
|
||||
|
||||
for (u32 n = 0; n < mStaticNodes.size(); n++)
|
||||
if (mStaticNodes[n]->IsVisible())
|
||||
mStaticNodes[n]->AddToRenderer(pRenderer);
|
||||
mStaticNodes[n]->AddToRenderer(pRenderer, camera.FrustumPlanes());
|
||||
}
|
||||
|
||||
if (options & eDrawWorldCollision)
|
||||
{
|
||||
for (u32 n = 0; n < mCollisionNodes.size(); n++)
|
||||
if (mCollisionNodes[n]->IsVisible())
|
||||
mCollisionNodes[n]->AddToRenderer(pRenderer);
|
||||
mCollisionNodes[n]->AddToRenderer(pRenderer, camera.FrustumPlanes());
|
||||
}
|
||||
|
||||
if (options & eDrawLights)
|
||||
{
|
||||
for (u32 n = 0; n < mLightNodes.size(); n++)
|
||||
if (mLightNodes[n]->IsVisible())
|
||||
mLightNodes[n]->AddToRenderer(pRenderer);
|
||||
mLightNodes[n]->AddToRenderer(pRenderer, camera.FrustumPlanes());
|
||||
}
|
||||
|
||||
if ((options & eDrawObjects) || (options & eDrawObjectCollision))
|
||||
{
|
||||
for (u32 n = 0; n < mScriptNodes.size(); n++)
|
||||
if (mScriptNodes[n]->IsVisible())
|
||||
mScriptNodes[n]->AddToRenderer(pRenderer);
|
||||
mScriptNodes[n]->AddToRenderer(pRenderer, camera.FrustumPlanes());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ public:
|
||||
void SetActiveArea(CGameArea *_area);
|
||||
void SetActiveWorld(CWorld *_world);
|
||||
void ClearScene();
|
||||
void AddSceneToRenderer(CRenderer *pRenderer);
|
||||
void AddSceneToRenderer(CRenderer *pRenderer, CCamera& camera);
|
||||
SRayIntersection SceneRayCast(const CRay& Ray, ERenderOptions renderOptions);
|
||||
void PickEnvironmentObjects();
|
||||
CScriptNode* ScriptNodeByID(u32 InstanceID);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "ERenderOptions.h"
|
||||
#include <Common/CAABox.h>
|
||||
#include <Common/types.h>
|
||||
#include <Core/CFrustumPlanes.h>
|
||||
|
||||
class CRenderer;
|
||||
|
||||
@@ -12,7 +13,7 @@ class IRenderable
|
||||
public:
|
||||
IRenderable() {}
|
||||
virtual ~IRenderable() {}
|
||||
virtual void AddToRenderer(CRenderer *pRenderer) = 0;
|
||||
virtual void AddToRenderer(CRenderer *pRenderer, const CFrustumPlanes& frustum) = 0;
|
||||
virtual void Draw(ERenderOptions options) {}
|
||||
virtual void DrawAsset(ERenderOptions options, u32 asset) {}
|
||||
virtual void DrawSelection() {}
|
||||
|
||||
Reference in New Issue
Block a user