File: Sphere.cpp

package info (click to toggle)
structure-synth 1.5.0-2
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 2,268 kB
  • ctags: 1,966
  • sloc: cpp: 10,209; python: 164; makefile: 71; sh: 15
file content (105 lines) | stat: -rw-r--r-- 2,604 bytes parent folder | download | duplicates (9)
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
#include "Sphere.h"

using namespace SyntopiaCore::Math;


namespace SyntopiaCore {
	namespace GLEngine {


		//GLUquadric* Sphere::myQuad = 0; 
		int Sphere::displayListIndex = 0;

		Sphere::Sphere(SyntopiaCore::Math::Vector3f center, float radius) : center(center), radius(radius) {
			myQuad = gluNewQuadric();    
			gluQuadricDrawStyle(myQuad, GLU_FILL);

			/// Bounding box
			Vector3f v = Vector3f(radius,radius,radius);
			from = center-v;
			to = center+v;

			if (displayListIndex == 0) {
				displayListIndex = glGenLists(1);
				glNewList(displayListIndex, GL_COMPILE);
				gluSphere(myQuad, 1, 7,7);	
				glEndList();
			}
			

		};

		Sphere::~Sphere() {
			gluDeleteQuadric(myQuad);
		};

		void Sphere::draw() const {
			glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, primaryColor );
			if (primaryColor[3] < 1) {
				glEnable( GL_BLEND );
			}

			glPushMatrix();
			glTranslatef( center.x(), center.y(), center.z() );
			if (displayListIndex!=0) {
				glScalef(radius,radius,radius);
				glCallList(displayListIndex);
			} else {
				gluSphere(myQuad, radius, 7, 7);	
			}
			glPopMatrix();			
		};


			

		bool Sphere::intersectsRay(RayInfo* ri) {
			// Following: http://local.wasp.uwa.edu.au/~pbourke/geometry/sphereline/

			double a = ri->lineDirection.sqrLength();
			double b = 2*(Vector3f::dot(ri->lineDirection, (ri->startPoint - center)));
			double c = (center-ri->startPoint).sqrLength() - radius*radius;

			double d = b*b-4*a*c;

			if (d<0) {
				ri->intersection = -1;
				return false;
			} else {
				// We always choose the negative solution, since it will be closest to the startPoint. (If intersection is positive)
				ri->intersection = (b - sqrt(d))/(-2*a);
				double intersection2 = (b + sqrt(d))/(-2*a);
				if (intersection2<ri->intersection) ri->intersection = intersection2;

				ri->normal = (ri->startPoint + ri->lineDirection*ri->intersection)-center;
				ri->normal.normalize();
				for (int i = 0; i < 4; i++) ri->color[i] = primaryColor[i];
				return true;
			}
		};

		bool Sphere::intersectsAABB(Vector3f from, Vector3f to) {
			// Based on http://www.gamasutra.com/features/19991018/Gomez_4.htm
			float s, d = 0; 

			//find the square of the distance
			//from the sphere to the box
			for( long i=0 ; i<3 ; i++ )
			{
				if( center[i] < from[i] )
				{
					s = center[i] - from[i];
					d += s*s; 
				} else if( center[i] > to[i] ) {
					s = center[i] - to[i];
					d += s*s; 
				}
			}
			return d <= radius*radius;
		};



	}
}