#include "main.h"
#include "3d.h"
#include "vectors.h"
#include <math.h>

#define MAXFACES	4097

Object_Data SCN_SphereLow;
Object_Data SCN_SphereMiddle;
Object_Data SCN_SphereHigh;


unsigned char STATE_TEST_3D=0;

  void SPHERE3D_calc(Object_Data *SCN, float scale, unsigned char iter);
  void SPHERE3D_setup();
  
  long SPHERE3D_create2(int iterations);

Object_Data objet3d;


Ftrig SPHEREMESH2[MAXFACES];

void SphereMidPoint(Vect3D p1, Vect3D p2, Vect3D *p)
 {
   p->x = (p1.x + p2.x)*0.5;
   p->y = (p1.y + p2.y)*0.5;
   p->z = (p1.z + p2.z)*0.5;

 }


  void SPHERE3D_setup()
  {
	   SPHERE3D_calc(&SCN_SphereLow,  4.0, 2);
       SPHERE3D_calc(&SCN_SphereMiddle,  4.0, 4);
	   SPHERE3D_calc(&SCN_SphereHigh, 4.0, 5);
  }




  void SPHERE3D_calc(Object_Data *SCN, float scale, uchar iter)
       {
       long ns,i,nbf;
       float dist;
       Vect3D p1,p2,p3,v1,v2, normal, middle, nv;

       nbf=SPHERE3D_create2(iter);
       H3D_allocate_obj(SCN, nbf, nbf*4);

	   
       ns=0;
       for (i=0;i<nbf;i++)
           {
           SCN->v_original[ns]=SPHEREMESH2[i].pt1;
           SCN->v_original[ns+1]=SPHEREMESH2[i].pt2;
           SCN->v_original[ns+2]=SPHEREMESH2[i].pt3;

           p1=SCN->v_original[ns];
           p2=SCN->v_original[ns+1];
           p3=SCN->v_original[ns+2];

		   v1=Vect3D_Sub(p2,p1); 
		   v2=Vect3D_Sub(p3,p2); 
		   normal=Vect3D_CrossProduct(v1, v2);
		   normal=Vect3D_Normalize(normal);
    

           /* trouve le milieu de la face */
           middle.x=(p1.x+p2.x+p3.x)/3.0;
           middle.y=(p1.y+p2.y+p3.y)/3.0;
           middle.z=(p1.z+p2.z+p3.z)/3.0;

           /* additionne la normale */
           nv=Vect3D_Add(middle, normal);

           /* methode pour ordonner les triangles selon du clockwise/anti-clockwise */
           dist=sqrt(nv.x*nv.x+nv.y*nv.y+nv.z*nv.z);
		   
		   SCN->f[i].idx[0]=ns;
           SCN->f[i].idx[1]=ns+1;
           SCN->f[i].idx[2]=ns+2;
		   
           if (dist<1.0)     //on doit inverser
              {
              SCN->f[i].idx[0]=ns;
              SCN->f[i].idx[1]=ns+1;
              SCN->f[i].idx[2]=ns+2;
			  SCN->f[i].nrm=normal;
              }
              else
              {
              SCN->f[i].idx[0]=ns+2;
              SCN->f[i].idx[1]=ns+1;
              SCN->f[i].idx[2]=ns;

			  SCN->f[i].nrm=Vect3D_Invert(normal);
              }

			

			SCN->v_original[ns]=SCN->uvw[ns]=Vect3D_MulScalar(SCN->v_original[ns], scale);
			SCN->v_original[ns+1]=SCN->uvw[ns+1]=Vect3D_MulScalar(SCN->v_original[ns+1], scale);
			SCN->v_original[ns+2]=SCN->uvw[ns+2]=Vect3D_MulScalar(SCN->v_original[ns+2], scale);
   

           ns+=3;
           }
       SCN->nbfaces=nbf;
       SCN->nbvtx=ns;
       }      

  long SPHERE3D_create2(int iterations)
       {
       long i,j,n,nstart;
       Vect3D p1,p2,p3,p4;

       p1.x= 1.1;  p1.y= 1.03; p1.z= 1.1;
       p2.x=-1.0;  p2.y=-1.0; p2.z= 1.0; 
       p3.x= 1.1;  p3.y=-1.1; p3.z=-1.1;
       p4.x=-1.2;  p4.y= 1.3; p4.z=-1.0;


       SPHEREMESH2[0].pt1 = p2; SPHEREMESH2[0].pt2 = p3; SPHEREMESH2[0].pt3 = p1;
       SPHEREMESH2[1].pt1 = p4; SPHEREMESH2[1].pt2 = p2; SPHEREMESH2[1].pt3 = p1;
       SPHEREMESH2[2].pt1 = p2; SPHEREMESH2[2].pt2 = p4; SPHEREMESH2[2].pt3 = p3;
       SPHEREMESH2[3].pt1 = p4; SPHEREMESH2[3].pt2 = p3; SPHEREMESH2[3].pt3 = p1;
       n = 4;

       for (i=1;i<iterations;i++) {
            nstart = n;

           for (j=0;j<nstart;j++) {

                /* Create initially copies for the new facets */


                SPHEREMESH2[n] = SPHEREMESH2[j];
                SPHEREMESH2[n+1] = SPHEREMESH2[j];
                SPHEREMESH2[n+2] = SPHEREMESH2[j];

               /* Calculate the midpoints and normalize */
               SphereMidPoint(SPHEREMESH2[j].pt1,SPHEREMESH2[j].pt2, &p1);
               SphereMidPoint(SPHEREMESH2[j].pt2,SPHEREMESH2[j].pt3, &p2);
               SphereMidPoint(SPHEREMESH2[j].pt3,SPHEREMESH2[j].pt1, &p3);

               /* Replace the current facet */
               SPHEREMESH2[j].pt2 = p1;
               SPHEREMESH2[j].pt3 = p3;

               /* Create the changed vertices in the new facets */
               SPHEREMESH2[n  ].pt1 = p1;
               SPHEREMESH2[n  ].pt3 = p2;
               SPHEREMESH2[n+1].pt1 = p3;
               SPHEREMESH2[n+1].pt2 = p2;
               SPHEREMESH2[n+2].pt1 = p1;
               SPHEREMESH2[n+2].pt2 = p2;
               SPHEREMESH2[n+2].pt3 = p3;
               n += 3;
           }
   }

      for (j=0;j<n;j++)
          {
		  SPHEREMESH2[j].pt1=Vect3D_Normalize(SPHEREMESH2[j].pt1);

		    SPHEREMESH2[j].pt2=Vect3D_Normalize(SPHEREMESH2[j].pt2);
			  SPHEREMESH2[j].pt3=Vect3D_Normalize(SPHEREMESH2[j].pt3);
          }

   return(n);     //retourne le nb de faces (n*3 = nb de vtx)
}



