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;
};
}
}
|