/* Sphere                                       */
/*                                              */
/* Auteur: Nicolas JANEY                        */
/* nicolas.janey@univ-fcomte.fr                 */
/* Mars 2014                                    */

#include <stdio.h>
#include <math.h>

#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>

#include "Sphere.h"
#include "Pos3D.h"
#include "Materiel.h"
#include "RayonLumineux.h"
#include "LumierePonctuelle.h"
#include "LumiereDirectionnelle.h"
#include "Dir3D.h"
#include "Energie.h"
#include "Scene.h"

Sphere::Sphere(void):Objet() {
  rayon = 1.0;
}

Sphere::Sphere(Pos3D *p,double r,Materiel *m):Objet(p,m) {
  rayon = r;
}

Sphere::Sphere(Sphere *s):Objet(s) {
  rayon = s->rayon;
}

Sphere::~Sphere(void) {
}

void Sphere::print(void) {
}

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

int Sphere::intersection(RayonLumineux *rl) {
  double sx = rl->origine->x - centre->x ;
  double sy = rl->origine->y - centre->y;
  double sz = rl->origine->z - centre->z;
  double a = rl->direction->x*rl->direction->x +
             rl->direction->y*rl->direction->y + 
             rl->direction->z*rl->direction->z;
  double b = 2.0F*(rl->direction->x*sx + 
                   rl->direction->y*sy + 
                   rl->direction->z*sz);
  double c = sx*sx + sy*sy + sz*sz - rayon*rayon;
  double delta = b*b-4*a*c;
  if ( delta < 0.0F )
    return(0);
  if ( delta == 0 ) {
    double t = -b/(2.0*a);
    if ( t >= 0.001) {
      return(1); }
      else
      return(0); }
  { double t = (-b-sqrt(delta))/(2.0*a);
    if ( t >= 0.001 ) {
      return(1); } }
  { double t = (-b+sqrt(delta))/(2.0*a);
    if ( t >= 0.001 ) {
      return(1); } }
  return(0);
}

int Sphere::intersection(RayonLumineux *rl,double *d) {
  double sx = rl->origine->x - centre->x ;
  double sy = rl->origine->y - centre->y;
  double sz = rl->origine->z - centre->z;
  double a = rl->direction->x*rl->direction->x +
             rl->direction->y*rl->direction->y + 
             rl->direction->z*rl->direction->z;
  double b = 2.0F*(rl->direction->x*sx + 
                   rl->direction->y*sy + 
                   rl->direction->z*sz);
  double c = sx*sx + sy*sy + sz*sz - rayon*rayon;
  double delta = b*b-4*a*c;
  if ( delta < 0.0 )
    return(0);
  if ( delta == 0 ) {
    double t = -b/(2.0*a);
    if ( t >= 0.001) {
      *d = t;
      return(1); }
      else
      return(0); }
  { double t = (-b-sqrt(delta))/(2.0*a);
    if ( t >= 0.001 ) {
      *d = t;
      return(1); } }
  { double t = (-b+sqrt(delta))/(2.0*a);
    if ( t >= 0.001 ) {
      *d = t;
      return(1); } }
  return(0);
}

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

void Sphere::calculNormale(Dir3D *d,Pos3D *p) {
  d->x = (p->x - centre->x)/rayon;
  d->y = (p->y - centre->y)/rayon;
  d->z = (p->z - centre->z)/rayon;
}

void Sphere::modeliseOpenGL(void) {
  glutSolidSphere(rayon,180,180);
}

Sphere *Sphere::clone(void) {
  return(new Sphere(this));
}
