File: cull.c

package info (click to toggle)
s3d 0.2.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,708 kB
  • sloc: ansic: 23,609; python: 488; perl: 98; makefile: 31; sh: 29
file content (98 lines) | stat: -rw-r--r-- 2,087 bytes parent folder | download
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
// SPDX-License-Identifier: GPL-2.0-or-later
/* SPDX-FileCopyrightText: 2004-2015  Simon Wunderlich <sw@simonwunderlich.de>
 * code originated from  http://www.racer.nl/reference/vfc.htm
 * which is (C) Ruud van Gaal
 */

#include "global.h"
#include <math.h>		/* sqrt() */
#include <GL/gl.h>		/*  glGetFloatv */
struct t_plane {
	struct t_vertex n;
	float d;
};
#define LEFT 0
#define RIGHT 1
#define TOP  2
#define BOTTOM 3
#define PNEAR 4
#define PFAR 5

static struct t_plane frustumPlane[6];

void cull_get_planes(void)
{
	t_mtrx m, mproj, mmodel;
	struct t_plane *p;
	int i;
	float d;

	/* get matrices from opengl */
	glGetFloatv(GL_MODELVIEW_MATRIX, mmodel);
	glGetFloatv(GL_PROJECTION_MATRIX, mproj);

	mySetMatrix(mproj);
	myMultMatrix(mmodel);
	myGetMatrix(m);		/* multiply and have the result in m */

	p = &frustumPlane[RIGHT];
	p->n.x = m[3] - m[0];
	p->n.y = m[7] - m[4];
	p->n.z = m[11] - m[8];
	p->d = m[15] - m[12];

	p = &frustumPlane[LEFT];
	p->n.x = m[3] + m[0];
	p->n.y = m[7] + m[4];
	p->n.z = m[11] + m[8];
	p->d = m[15] + m[12];

	p = &frustumPlane[BOTTOM];
	p->n.x = m[3] + m[1];
	p->n.y = m[7] + m[5];
	p->n.z = m[11] + m[9];
	p->d = m[15] + m[13];

	p = &frustumPlane[TOP];
	p->n.x = m[3] - m[1];
	p->n.y = m[7] - m[5];
	p->n.z = m[11] - m[9];
	p->d = m[15] - m[13];

	p = &frustumPlane[PFAR];
	p->n.x = m[3] - m[2];
	p->n.y = m[7] - m[6];
	p->n.z = m[11] - m[10];
	p->d = m[15] - m[14];

	p = &frustumPlane[PNEAR];
	p->n.x = m[3] + m[2];
	p->n.y = m[7] + m[6];
	p->n.z = m[11] + m[10];
	p->d = m[15] + m[14];

	/* Normalize all plane normals */
	for (i = 0; i < 6; i++) {
		p = &frustumPlane[i];
		d = sqrt(p->n.x * p->n.x + p->n.y * p->n.y + p->n.z * p->n.z);
		if (d != 0.0) {
			p->n.x /= d;
			p->n.y /= d;
			p->n.z /= d;
			p->d /= d;
		}
	}
}

int cull_sphere_in_frustum(struct t_vertex *center, float radius)
{
	int i;
	struct t_plane *p;
	for (i = 0; i < 6; i++) {
		p = &frustumPlane[i];
		if (p->n.x * center->x + p->n.y * center->y + p->n.z * center->z + p->d <= -radius) {
			return 0;	/* sorry, no ... */
		}
	}
	return 1;		/* it's inside */
}