/* NIGHTFALL OpenGL Interface                                              */
/* Copyright (C) 2001 Rainer Wichmann & Markus Kuster                      */
/*                                                                         */
/*  This program is free software; you can redistribute it                 */
/*  and/or modify                                                          */
/*  it under the terms of the GNU General Public License as                */
/*  published by                                                           */
/*  the Free Software Foundation; either version 2 of the License, or      */
/*  (at your option) any later version.                                    */
/*         
                                                                */
/*  This program is distributed in the hope that it will be useful,        */
/*  but WITHOUT ANY WARRANTY; without even the implied warranty of         */
/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
/*  GNU General Public License for more details.                           */
/*                                                                         */
/*  You should have received a copy of the GNU General Public License      */
/*  along with this program; if not, write to the Free Software            */
/*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */

/* ANSI C forbids an empty source file, so put this outside                */
/* do nothing here if we don't have OpenGL                                 */

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Light.h"

#ifdef  _WITH_OPENGL
#include "LightGLPrefs.h"

double RtoL2,RtoL3;

/******************************************************************
 @package   nightfall
 @author    Markus Kuster (kuster@astro.uni-tuebingen.de)
 @version   1.2
 @short     Make a vertex list for the roche lobes using eclipse 
            test information
 @param     (int)  comp   the binary component (primary/secondary)
 @return    (void)   
 @heading   Open GL Animation
*******************************************************************/
void GLMakeVolumeEclipsed( int Comp )
{
  register int i,j;
  float        com;                   /* center of mass          */
#ifdef HAVE_DISK
  long n_rings,n_ringsi,n_ringso;
#endif 
  long n_phi;                         /* # of steps in phi       */
  long n_eta;                         /* # of steps in eta       */
  double RX,C2,C;
 
  GLdouble s, t, ds, dt; /* t corresponds to eta and s to phi */

  SurfaceElement  *FirstVertPtr=NULL, *FirstVertPtr2=NULL;
  SurfaceElement  *SurfPtr,*NextRingPtr; /* pointer to surface   */
  BinaryComponent *BinPtr;            /* pointer to binary       */

  /* pointer to first surface element                            */
  SurfPtr      = Surface[Comp];

  /* the x coordinate of the center of mass                      */
  com = (((float)(Binary[Primary].Mq))/( 1.0 + (float)(Binary[Primary].Mq)));
  
  /* pointer to first surface element in the next ring           */
  NextRingPtr  = Surface[Comp];

  /* pointer to the binary parameters                            */
  BinPtr       = &Binary[Comp];

  n_eta = StepsPerPi; /* number of steps in eta */
      
  if (Flags.asynchron2 == ON) {
    F        = BinPtr->Fratio;
  } else {
    F        = 1.0;
  }

  /* find root of  (potential(x) - surfacePotential)                  */
  /*  if ( Comp == Primary ) {*/
    /* lambda, nu global; potential on x-axis                           */
/*      RochePot   = Binary[Primary].RochePot; */
/*      Mq         = Binary[Primary].Mq; */
/*      lambda     = 1.0; nu = 0.0;    */
/*      RtoL3 = RootFind(RocheSurface, BinPtr->RLag3, 0.001, 1.0e-8,  */
/*    		     "GLMakeVolume", &error);  */
/*      printf("Radius to L3 %f\n",RtoL2);  */
/*      printf("Position  L3 %f\n",BinPtr->RLag3); */
/*    } else if ( Comp == Secondary ) { */
    /* lambda, nu global; potential on x-axis                           */
/*      lambda     = 1.0;  */
/*      nu         = 0.0;   */

/*      RtoL2 = RootFind(RocheSurface,  0.0001, BinPtr->RLag2, 1.0e-8, */
/*  		     "GLMakeVolume", &error); */
/*      printf("Radius to L2 %f\n",RtoL2); */
/*      printf("Position  L2 %f\n",BinPtr->RLag2); */
/*    } */
/*    if (error == 1) { */
/*      printf("Root finding failed"); */
/*      exit(0); */
/*    } */

#ifdef HAVE_DISK
  if ( Comp != Disk ) 
    {
#endif 
      /* use a fixed n_phi in animation mode (see DivideSurface)     */
      n_phi = BinPtr->N_PhiStep[0];
  
      /* increment for texture coordinates                           */
      ds = 1.0/(GLdouble) (n_phi);
      dt = 1.0/(GLdouble) (n_eta+1);

      /* star radius on x-axis towards L1                            */ 
      RX = BinPtr->Xp; 
      
      /* mirror x -> -x for secondary                                */
      /* mirror y -> -y for left handed coordinates of roche lobes   */
      if (Comp == Secondary) {
	C       = -1;
	C2      = -1;
      } else {
	C       =  1;
	C2      = -1;
      }
      
      /* make vertex list for the roche lobe */
      if (Flags.points == TRUE) {
 	glBegin(GL_POINTS);
      } else {
 	glBegin(GL_POLYGON);
      }

      t=0.0;
      s=0.0;

      /* polygon opposite of L1 on the x-axis */
      for (j=0; j < n_phi; j++) {
	if (Comp == Primary) {
	  if ( (SurfPtr->EclipseFlag == FALSE) ) {
	    if (j == 0) {
	      glNormal3f(C*SurfPtr->l, C2*SurfPtr->m, SurfPtr->n); 
	    }
	    /* glTexCoord2d(s, t);*/
	    glVertex3f(C*SurfPtr->lambda,C2*SurfPtr->mu,SurfPtr->nu);
	  }
	} else {
	  if ( (SurfPtr->EclipseFlag == FALSE) ) {
	    /* mirror x -> -x for secondary             */
	    if (j == 0) { 
	      glNormal3f(C*SurfPtr->l, C2*SurfPtr->m, SurfPtr->n);
	    }
	    /*glTexCoord2d(s, t);*/
	    glVertex3f(C*SurfPtr->lambda,C2*SurfPtr->mu,SurfPtr->nu);
	  }
	}      
	++SurfPtr;
	s += ds;
      }
      glEnd();
      t += dt;    
      
      SurfPtr      = Surface[Comp];
      /* first point of the next ring */
      NextRingPtr += n_phi;
      
      /* begin vertex list                              */
      if (Flags.points == TRUE) {
 	glBegin(GL_POINTS);
	glPointSize(1);
      } else {
	glBegin(GL_QUAD_STRIP);
      }
      for (i=0; i < n_eta-1; i++) {
	s=0.0;
	for (j = 0; j < n_phi; j++) {
	  /* store first vertices of the actual and next ring */
	  if (j == 0) {
	    FirstVertPtr=SurfPtr;
	    FirstVertPtr2=NextRingPtr;
	  }
	  if ( (Flags.points == FALSE) || ((SurfPtr->EclipseFlag == FALSE) && (NextRingPtr->EclipseFlag == FALSE)) ) {
	    /* we are not in the last ring             */
	    /* and not in the last segment             */
	    /* assign normal vectors                   */
	    glNormal3f(C*SurfPtr->l, C2*SurfPtr->m, SurfPtr->n);
	    glTexCoord2d(s, t);
	    glVertex3f(C*SurfPtr->lambda,C2*SurfPtr->mu,SurfPtr->nu);
	    glTexCoord2d(s, t+dt);
	    glVertex3f(C*NextRingPtr->lambda,C2*NextRingPtr->mu,NextRingPtr->nu);
	  }
	  /* go to next vertex                       */
	  ++SurfPtr;
	  ++NextRingPtr;

	  s += ds;

	  /* we are in the last ring or segment      */
	  if (j == n_phi-1) {       
	    /* last point of the ring                */
	    /* close the loop with the first point   */
	    if ( (Flags.points == FALSE) || ((FirstVertPtr->EclipseFlag == FALSE) && (FirstVertPtr2->EclipseFlag == FALSE)) ) {
	      glNormal3f(C*FirstVertPtr->l, C2*FirstVertPtr->m, FirstVertPtr->n);
	      glTexCoord2d(s, t);
	      glVertex3f(C*FirstVertPtr->lambda,C2*FirstVertPtr->mu,FirstVertPtr->nu);
	      glTexCoord2d(s, t+dt);
	      glVertex3f(C*FirstVertPtr2->lambda,C2*FirstVertPtr2->mu,FirstVertPtr2->nu);
	    }
	  }
	} /* end of phi loop */
	t += dt;    
      }   /* end of eta loop */
      
      t -= dt;
      s=0.0;

      for (j = 0; j < n_phi; j++) {
	if (j == 0) {
	  FirstVertPtr=SurfPtr;
	}
	if ( Flags.points == FALSE || (SurfPtr->EclipseFlag == FALSE) ) {
	  /* this is the last ring in direction to L1 */
	  glNormal3f(C*SurfPtr->l, C2*SurfPtr->m, SurfPtr->n);
	  glTexCoord2d(s, t);
	  glVertex3f(C*SurfPtr->lambda,C2*SurfPtr->mu,SurfPtr->nu);
	  glTexCoord2d(s, t+dt);
	  glVertex3f((float) C*RX,0,0);
	}
	++SurfPtr;
	++NextRingPtr;

	s += ds;    
	if (j == n_phi-1) {       
	  /* are at the last point of the ring     */
	  /* close the loop with the first point   */
	  if ( Flags.points == FALSE || (FirstVertPtr->EclipseFlag == FALSE) ) {
	    glNormal3f(C*FirstVertPtr->l, C2*FirstVertPtr->m, FirstVertPtr->n);
	    glTexCoord2d(s, t);
	    glVertex3f(C*FirstVertPtr->lambda,C2*FirstVertPtr->mu,FirstVertPtr->nu);
	    glTexCoord2d(s, t+dt);
	    glVertex3f(C*RX, 0, 0);
	  }
	}
      }
      
      glEnd();

      /* add spots                                     */
      if ( Comp == Primary) {
	GLMakeSpots(Comp, com-1.0);
      }
      else if (Comp == Secondary) {
	/* translate to the position of the secondary                */
	GLMakeSpots(Comp, com-1.0);
      }
#ifdef HAVE_DISK
    } else {
      /* mirror x -> -x for disk                                  */
      C       =  -1;
      C2      =  -1;

      /* Disk stuff */
      n_phi    = 32;
      n_rings  = 42;
      n_ringso = BinPtr->RingsOut;
      n_ringsi = BinPtr->RingsIn;

      /* increment for texture coordinates                           */
      ds=1.0/(GLdouble) (n_phi);
      dt=1.0/(GLdouble) (n_rings);

      /* increase pointer to the first vertex of the next ring */
      NextRingPtr += n_phi;

      /* begin vertex list                             */
      if (Flags.points == TRUE) {
 	glBegin(GL_POINTS);
      } else {
	glBegin(GL_QUAD_STRIP);
      }

      t=0.0;

      /* start with top layer of the disk              */
      for (j = 0; j < n_rings; j++) {
	s=0.0;
	for (i=0; i < n_phi; i++) {
	  if (i == 0) {
	    FirstVertPtr  = SurfPtr;
	    FirstVertPtr2 = NextRingPtr;
	  }
	  if ( Flags.points == FALSE || (SurfPtr->EclipseFlag == FALSE) ) {
	    /* assign normal vectors                     */
	    glNormal3f(C*SurfPtr->l         , C2*SurfPtr->m     , SurfPtr->n);
	    glTexCoord2d(s, t);
	    glVertex3f(C*SurfPtr->lambda    , C2*SurfPtr->mu    , SurfPtr->nu);
	    glTexCoord2d(s, t+dt);
	    glVertex3f(C*NextRingPtr->lambda, C2*NextRingPtr->mu, NextRingPtr->nu);
	  }
	  /* go to next vertex                         */
	  ++SurfPtr;
	  ++NextRingPtr;

	  s += ds;

	  if ( i == n_phi-1) {
	    if ( Flags.points == FALSE || (FirstVertPtr->EclipseFlag == FALSE) ) {
	      /* last point of the ring                */
	      /* close the loop with the first point   */
	      glNormal3f(C*FirstVertPtr->l      , C2*FirstVertPtr->m  , FirstVertPtr->n  );
	      glTexCoord2d(s, t);
	      glVertex3f(C*FirstVertPtr->lambda , C2*FirstVertPtr->mu , FirstVertPtr->nu );
	      glTexCoord2d(s, t+dt);
	      glVertex3f(C*FirstVertPtr2->lambda, C2*FirstVertPtr2->mu, FirstVertPtr2->nu);
	    }
	  }
	} /* end of phi loop */
	t+=dt;    
      }   /* end of rings loop */

      /* increment for texture coordinates                           */
      ds=1.0/(GLdouble) (n_ringso);

      t = 0.0;

      /* outer disk rim */
      for (j = 0; j < n_ringso; j++) {
	s = 0.0;
	for (i=0; i < n_phi; i++) {
	  if (i == 0) {
	    FirstVertPtr  = SurfPtr;
	    FirstVertPtr2 = NextRingPtr;
	  }

	  if ( Flags.points == FALSE || (SurfPtr->EclipseFlag == FALSE) ) {
	    /* assign normal vectors                     */
	    glNormal3f(C*SurfPtr->l         , C2*SurfPtr->m     , SurfPtr->n);
	    glTexCoord2d(s, t);
	    glVertex3f(C*SurfPtr->lambda    , C2*SurfPtr->mu    , SurfPtr->nu);
	    glTexCoord2d(s, t+dt);
	    glVertex3f(C*NextRingPtr->lambda, C2*NextRingPtr->mu, NextRingPtr->nu);
	  }

	  /* go to next vertex                         */
	  ++SurfPtr;
	  ++NextRingPtr;

	  s += ds;

	  if ( Flags.points == FALSE || (FirstVertPtr->EclipseFlag == FALSE) ) {
	    if ( i == n_phi-1) {
	      /* last point of the ring                */
	      /* close the loop with the first point   */
	      glNormal3f(C*FirstVertPtr->l      , C2*FirstVertPtr->m  , FirstVertPtr->n);
	      glTexCoord2d(s, t);
	      glVertex3f(C*FirstVertPtr->lambda , C2*FirstVertPtr->mu , FirstVertPtr->nu);
	      glTexCoord2d(s, t+dt);
	      glVertex3f(C*FirstVertPtr2->lambda, C2*FirstVertPtr2->mu, FirstVertPtr2->nu);
	    }
	  }
	}
	t+=dt;    
      }

      /* increment for texture coordinates                           */
      ds=1.0/(GLdouble) (n_phi);

      t=1.0;

      /* bottom layer of the disk              */
      for (j = 0; j < n_rings; j++) {
	s=0.0;
	for (i=0; i < n_phi; i++) {
	  if (i == 0) {
	    FirstVertPtr  = SurfPtr;
	    FirstVertPtr2 = NextRingPtr;
	  }
	  if ( Flags.points == FALSE || (SurfPtr->EclipseFlag == FALSE) ) {
	    /* assign normal vectors                     */
	    glNormal3f(C*SurfPtr->l         , C2*SurfPtr->m     , SurfPtr->n);
	    glTexCoord2d(s, t);
	    glVertex3f(C*SurfPtr->lambda    , C2*SurfPtr->mu    , SurfPtr->nu);
	    glTexCoord2d(s, t-dt);
	    glVertex3f(C*NextRingPtr->lambda, C2*NextRingPtr->mu, NextRingPtr->nu);
	  }
	  /* go to next vertex                         */
	  ++SurfPtr;
	  ++NextRingPtr;

	  s += ds;

	  if ( i == n_phi-1) {
	    if ( Flags.points == FALSE || (FirstVertPtr->EclipseFlag == FALSE) ) {
	      /* last point of the ring                */
	      /* close the loop with the first point   */
	      glNormal3f(C*FirstVertPtr->l      , C2*FirstVertPtr->m  , FirstVertPtr->n);
	      glTexCoord2d(s, t);
	      glVertex3f(C*FirstVertPtr->lambda , C2*FirstVertPtr->mu , FirstVertPtr->nu);
	      glTexCoord2d(s, t-dt);
	      glVertex3f(C*FirstVertPtr2->lambda, C2*FirstVertPtr2->mu, FirstVertPtr2->nu);
	    }
	  }
	} /* end of phi loop */
	t-=dt;    
      }   /* end of rings loop */

      /* increment for texture coordinates                           */
      ds=1.0/(GLdouble) (n_ringsi);

      t=0.0;

      /* inner disk rim */
      for (j = 0; j < n_ringsi-1; j++) {
	s=0.0;
	for (i=0; i < n_phi; i++) {
	  if (i == 0) {
	    FirstVertPtr  = SurfPtr;
	    FirstVertPtr2 = NextRingPtr;
	  }
	  if ( Flags.points == FALSE || (SurfPtr->EclipseFlag == FALSE) ) {
	    /* assign normal vectors                     */
	    glNormal3f(C*SurfPtr->l         , C2*SurfPtr->m     , SurfPtr->n);
	    glTexCoord2d(s, t);
	    glVertex3f(C*SurfPtr->lambda    , C2*SurfPtr->mu    , SurfPtr->nu);
	    glTexCoord2d(s, t+dt);
	    glVertex3f(C*NextRingPtr->lambda, C2*NextRingPtr->mu, NextRingPtr->nu);
	  }

	  /* go to next vertex                         */
	  ++SurfPtr;
	  ++NextRingPtr;

	  s += ds; 

	  if ( i == n_phi-1) {
	    if ( Flags.points == FALSE || (FirstVertPtr->EclipseFlag == FALSE) ) {
	      /* last point of the ring                */
	      /* close the loop with the first point   */
	      glNormal3f(C*FirstVertPtr->l      , C2*FirstVertPtr->m  , FirstVertPtr->n);
	      glTexCoord2d(s, t);
	      glVertex3f(C*FirstVertPtr->lambda , C2*FirstVertPtr->mu , FirstVertPtr->nu);
	      glTexCoord2d(s, t+dt);
	      glVertex3f(C*FirstVertPtr2->lambda, C2*FirstVertPtr2->mu, FirstVertPtr2->nu);
	    }
	  }
	}
	t+=dt;    
      }
      
      NextRingPtr = Surface[Comp];

      s = 0;

      /* close the pot to the first vertex */
      for (i=0; i < n_phi; i++) {
	if (i == 0) {
	  FirstVertPtr  = SurfPtr;
	  FirstVertPtr2 = NextRingPtr;
	}
	
	if ( Flags.points == FALSE || (SurfPtr->EclipseFlag == FALSE) ) {
	  /* assign normal vectors                     */
	  glNormal3f(C*SurfPtr->l         , C2*SurfPtr->m     , SurfPtr->n);
	  glTexCoord2d(s, t);
	  glVertex3f(C*SurfPtr->lambda    , C2*SurfPtr->mu    , SurfPtr->nu);
	  glTexCoord2d(s, t+dt);
	  glVertex3f(C*NextRingPtr->lambda, C2*NextRingPtr->mu, NextRingPtr->nu);
	}

	/* go to next vertex                         */
	++SurfPtr;
	++NextRingPtr;

	s += ds; 

	if ( i == n_phi-1) {
	  if ( Flags.points == FALSE || (FirstVertPtr->EclipseFlag == FALSE) ) {
	    /* last point of the ring                */
	    /* close the loop with the first point   */
	    glNormal3f(C*FirstVertPtr->l      , C2*FirstVertPtr->m  , FirstVertPtr->n);
	    glTexCoord2d(s, t);
	    glVertex3f(C*FirstVertPtr->lambda , C2*FirstVertPtr->mu , FirstVertPtr->nu);
	    glTexCoord2d(s, t+dt);
	    glVertex3f(C*FirstVertPtr2->lambda, C2*FirstVertPtr2->mu, FirstVertPtr2->nu);
	  }
	}
      }
      glEnd();
    }
#endif 
}

#endif /* OpenGL end */






syntax highlighted by Code2HTML, v. 0.9.1