⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 frustum.cpp

📁 小型的3D游戏引擎
💻 CPP
字号:
#include <windows.h>
#include <gl/gl.h>
#include "math/math.h"
#include "math/matrix.h"
#include "frustum.h"
#include "math/aabb.h"

//////////////////////////////////////////////////////////////////////////////////

static GcFrustum *frust = NULL;

GcFrustum *ActiveFrustum()
{
    return frust;
}

//////////////////////////////////////////////////////////////////////////////////

GcFrustum::GcFrustum()
{
	frust = this;
}

//////////////////////////////////////////////////////////////////////////////////

GcFrustum::~GcFrustum()
{
	frust = NULL;
}

//////////////////////////////////////////////////////////////////////////////////

void GcFrustum::Extract()
{
	GcMatrix4 projection;
	GcMatrix4 model;
	GcMatrix4 clip;
	GcVector4 temp[6];


	// Get the projection and modelview matrix from OpenGL
	glGetFloatv(GL_PROJECTION_MATRIX, projection);
	glGetFloatv(GL_MODELVIEW_MATRIX, model);

	// Combine the two matrices
	clip = projection * model;

	// Extract the right plane
	temp[0].x = clip[ 3] - clip[ 0];
	temp[0].y = clip[ 7] - clip[ 4];
	temp[0].z = clip[11] - clip[ 8];
	temp[0].w = clip[15] - clip[12];

	// Normalize the vector
	temp[0].NormalizePlane();

	// Extract the left plane
	temp[1].x = clip[ 3] + clip[ 0];
	temp[1].y = clip[ 7] + clip[ 4];
	temp[1].z = clip[11] + clip[ 8];
	temp[1].w = clip[15] + clip[12];

	// Normalize the vector
	temp[1].NormalizePlane();

	// Extract the bottom plane
	temp[2].x = clip[ 3] + clip[ 1];
	temp[2].y = clip[ 7] + clip[ 5];
	temp[2].z = clip[11] + clip[ 9];
	temp[2].w = clip[15] + clip[13];

	// Normalize the vector
	temp[2].NormalizePlane();

	// Extract the top plane
	temp[3].x = clip[ 3] - clip[ 1];
	temp[3].y = clip[ 7] - clip[ 5];
	temp[3].z = clip[11] - clip[ 9];
	temp[3].w = clip[15] - clip[13];

	// Normalize the vector
	temp[3].NormalizePlane();

	// Extract the far plane
	temp[4].x = clip[ 3] - clip[ 2];
	temp[4].y = clip[ 7] - clip[ 6];
	temp[4].z = clip[11] - clip[10];
	temp[4].w = clip[15] - clip[14];

	// Normalize the vector
	temp[4].NormalizePlane();

	// Extract the near plane
	temp[5].x = clip[ 3] + clip[ 2];
	temp[5].y = clip[ 7] + clip[ 6];
	temp[5].z = clip[11] + clip[10];
	temp[5].w = clip[15] + clip[14];

	// Normalize the vector
	temp[5].NormalizePlane();

	for( int i = 0; i < 6; ++i )
	{
		m_frustum[i].SetPlane(GcVector3(temp[i].x, temp[i].y, temp[i].z), temp[i].w);
	}
}

//////////////////////////////////////////////////////////////////////////////////

/*bool GcFrustum::BoxInFrustum(float x, float y, float z, float size, float height)
{
	// Check to see if a box is in the frustum 

	// Loop through all planes looking to see if the point is infront of it
	for(int i = 0; i < 6; i++ )
	{
		// Check to see if any of the box's points is infront of the plane
		// If it is continue to the next plane, if none are then the box outside the frustum
		if(frustum[i].x * x + frustum[i].y * y + 
		   frustum[i].z * z + frustum[i].w > 0 ) {
			continue;
		}
		if(frustum[i].x * (x + size) + frustum[i].y * y + 
		   frustum[i].z * z	+ frustum[i].w > 0 ) {
			continue;
		}
		if(frustum[i].x * x + frustum[i].y * (y + height) + 
		   frustum[i].z * z + frustum[i].w > 0 ) {
			continue;
		}
		if(frustum[i].x * (x + size) + frustum[i].y * (y + height) + 
		   frustum[i].z * z + frustum[i].w > 0 ) {
			continue;
		}
		if(frustum[i].x * x + frustum[i].y * y + 
		   frustum[i].z * (z + size) + frustum[i].w > 0 ) {
			continue;
		}
		if(frustum[i].x * (x + size) + frustum[i].y * y + 
		   frustum[i].z * (z + size) + frustum[i].w > 0 ) {
			continue;
		}
		if(frustum[i].x * x + frustum[i].y * (y +height) + 
		   frustum[i].z * (z + size) + frustum[i].w > 0 ) {
			continue;
		}
		if(frustum[i].x * (x + size) + frustum[i].y * (y + height) + 
		   frustum[i].z * (z + size) + frustum[i].w > 0 ) {
			continue;
		}
		return false;
	}
	return true;
}
*/
//////////////////////////////////////////////////////////////////////////////////

bool GcFrustum::Contains(GcAABB & aabb)
{
	for(int i = 0; i < 6; ++i)
	{
		if(m_frustum[i].Distance(aabb.Point(0)) > 0) continue;
		if(m_frustum[i].Distance(aabb.Point(1)) > 0) continue;
		if(m_frustum[i].Distance(aabb.Point(2)) > 0) continue;
		if(m_frustum[i].Distance(aabb.Point(3)) > 0) continue;
		if(m_frustum[i].Distance(aabb.Point(4)) > 0) continue;
		if(m_frustum[i].Distance(aabb.Point(5)) > 0) continue;
		if(m_frustum[i].Distance(aabb.Point(6)) > 0) continue;
		if(m_frustum[i].Distance(aabb.Point(7)) > 0) continue;

		// Ok, give up. The point isn't in the frustum
		return false;
	}

	return true;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -