File: Frustum.cpp

package info (click to toggle)
spring 103.0%2Bdfsg2-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 43,720 kB
  • ctags: 63,685
  • sloc: cpp: 368,283; ansic: 33,988; python: 12,417; java: 12,203; awk: 5,879; sh: 1,846; xml: 655; perl: 405; php: 211; objc: 194; makefile: 77; sed: 2
file content (125 lines) | stat: -rw-r--r-- 3,088 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */


#include "Frustum.h"

#include "Rendering/GL/myGL.h"
#undef far // avoid collision with windef.h

void Frustum::InversePlanes ()
{
	std::vector<Plane>::iterator p;
	for(p=planes.begin(); p!=planes.end(); ++p) {
		p->Inverse ();
	}
}

// find the box vertices to compare against the plane
static void BoxPlaneVerts (const Vector3& min, const Vector3& max, const Vector3& plane,
                           Vector3& close, Vector3& far)
{
	if(plane.x > 0) { close.x = min.x; far.x = max.x; }
	else { close.x = max.x; far.x = min.x; }
	if(plane.y > 0) { close.y = min.y; far.y = max.y; }
	else { close.y = max.y; far.y = min.y; }
	if(plane.z > 0) { close.z = min.z; far.z = max.z; }
	else { close.z = max.z; far.z = min.z; }
}

void Frustum::CalcCameraPlanes (Vector3 *cbase, Vector3 *cright, Vector3* cup, Vector3* cfront, float tanHalfFov, float aspect)
{
	planes.resize(5);
	planes[0].SetVec (*cfront);
	planes[0].CalcDist (*cbase + *cfront);

	float m = 200.0f;
	base = *cbase + *cfront * m;
	up = *cup , right = *cright;
	up *= tanHalfFov * m;
	right *= tanHalfFov * m * aspect;
	front = *cfront;

	pos [0] = base + right + up; // rightup
	pos [1] = base + right - up; // rightdown
	pos [2] = base - right - up; // leftdown
	pos [3] = base - right + up; // leftup

	base = *cbase;

	planes[1].MakePlane (base, pos[2], pos[3]); // left
	planes[2].MakePlane (base, pos[3], pos[0]); // up
	planes[3].MakePlane (base, pos[0], pos[1]); // right
	planes[4].MakePlane (base, pos[1], pos[2]); // down

	right.ANormalize();
	up.ANormalize();
	front.ANormalize();
}

void Frustum::Draw ()
{
	if (base.x==0.0f) return;

	glDisable(GL_CULL_FACE);

/*	if (keys[SDLK_t]) {
		glBegin(GL_LINES);
		glColor3ub (255,0,0);
		glVertex3fv((float*)&base);
		glVertex3fv((float*)&(base+front*100));
		glEnd();
		glBegin(GL_LINES);
		glColor3ub (0,255,0);
		glVertex3fv((float*)&base);
		glVertex3fv((float*)&(base+right*100));
		glEnd();
		glBegin(GL_LINES);
		glColor3ub (0,0,255);
		glVertex3fv((float*)&base);
		glVertex3fv((float*)&(base+up*100));
		glEnd();
	}else{*/
		glBegin (GL_LINES);
		for (int a=0;a<4;a++) {
			glVertex3f (base.x, base.y, base.z);
			glVertex3f (pos[a].x, pos[a].y, pos[a].z);
		}
		glEnd();
		glBegin (GL_LINE_LOOP);
		for (int a=0;a<4;a++) {
			glVertex3fv ((float*)&pos[a]);
		}
		glEnd();
	//}
	glColor3ub(255,255,255);
}

Frustum::VisType Frustum::IsBoxVisible (const Vector3& min, const Vector3& max)
{
	bool full = true;
	Vector3 c,f;

	std::vector<Plane>::iterator p;
	for(p=planes.begin(); p!=planes.end(); ++p)
	{
		BoxPlaneVerts (min, max, p->GetVector(), c, f);
		
		const float dc = p->Dist(&c);
		const float df = p->Dist(&f);
		if(dc < 0.0f || df < 0.0f) full=false;
		if(dc < 0.0f && df < 0.0f) return Outside;
	}

	return full ? Inside : Partial;
}

Frustum::VisType Frustum::IsPointVisible (const Vector3& pt)
{
	std::vector<Plane>::const_iterator p;
	for(p=planes.begin(); p!=planes.end(); ++p) {
		float d = p->Dist (&pt);

		if (d < 0.0f) return Outside;
	}
	return Inside;
}