/*
 * Converted from Turbo Pascal 17-Mar-1997
 *     Emory R. Stagmer
 *         Emory_Stagmer@amecom.com
 *         stagmere@erols.com
 *
 *
 *  NOTE: the pascal program generated one .CAM file per frame which
 *  had an entire camera definition.  NOW we generate one include file
 *  (this was originally written for use under POV 2.2 and we didn't
 *   have a 'switch'!).
 *
 *Output:
 *  Will generate sequence of X,Y,Z locations within a switch.
 *  Switch Variable is : HERMITE_FRAME range 0..#frames-1
 *  Output #declare is:  HERMITE_VEC
 *  Output Example:
 *
 *  #switch( HERMITE_FRAME )
 *      #case (0):
 *          #declare HERMITE_VEC=<1,3.432,0>;
 *          #break;
 *      #case (1):
 *          #declare HERMITE_VEC=<1.1,3.523,0>;
 *          #break;
 *      // one case per frame...
 *      #else
 *          #error "Invalid HERMITE_FRAME"
 *          #break;
 *  #end // switch ( HERMITE_FRAME )
 *
 *  The variable HERMITE_FRAME can, of course, be anything, though
 *  typically related to the clock variable, like anything as simple as:
 *
 *      #declare HERMITE_FRAME = clock
 *
 *  If your animation goes from 0 to 1 (a typical scenario), you will need
 *  some kind of 'total frames' variable which can then be multiplied
 *  by the clock to generate a frame number ( or some similar scheme... ).
 *
 *  Revision History:
 *
 *  Date         Remarks
 *  --------     -------------------------------------------------------------
 *  12-May-1997  Changed Output from HERMITE_X,HERMITE_Y,HERMITE_Z to HERMITE_VEC
 *               I was almost always using the whole vector anyway, so this is
 *               MUCH simpler.  If you want any seperate component, use
 *               HERMITE_VEC.X instead of HERMITE_X
 *  12-Nov-1998  (same day of the month??!)  Now putting a ; after each
 *              #declare to get rid of warnings in POV 3.1+ (POVHerm 1.2)
 *
 *               Also now note that Alan Langford  has a
 *                  Windows version with preview from:
 *                  http://www.ambitonline.com/ftp/WinHerm050.exe
 *                  (he's also the one that pointed out the ';' problem...)
 */

#include "math.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"

#ifndef TRUE
#   define TRUE 1
#   define FALSE 0
#endif

const int  MaxPoints = 1000;
const int  MaxCtrl = 100;

// This is the input record.

class EndPointRecTyp  // The resultant intermediate computed points
    {
    public:
    float x, y, z;
    EndPointRecTyp(float vx=0.0, float vy=0.0, float vz=0.0)
            :x(vx),y(vy),z(vz) {};
    };

class CtrlRecTyp    // The control points of the curves
    {
    public:
    EndPointRecTyp Vpt, DVpt;
    int Frames;
    CtrlRecTyp():Vpt(),DVpt(){};
    };

static FILE *InFile, *OutFile, *DebugFile;

char InputFileName[255],
    OutputFileName[255] ,
    tmps[255];

EndPointRecTyp VPoints[MaxPoints],
    Look_Ats[MaxPoints];// Arrays for resultant points
CtrlRecTyp CPoints[MaxCtrl];
int CtrlCnt, PointCnt, i, j;

void Read_Input()
    {
    register int i = 0;
    CtrlRecTyp tmp;

    CtrlCnt = 0;
    while (!feof(InFile))
        {
        fscanf( InFile, "%f %f %f %f %f %f %d\n",
                &tmp.Vpt.x, &tmp.Vpt.y, &tmp.Vpt.z,
                &tmp.DVpt.x, &tmp.DVpt.y, &tmp.DVpt.z, &tmp.Frames );
        CPoints[i] = tmp;
        i++;
        }
    CtrlCnt = i;
    }


void Start_Output()
    {
    register int i = 0;
    fprintf(OutFile, "// POVHerm 1.2 - now using HERMITE_VEC instead of HERMITE_X,Y,Z (adding semicolons!)\n");
    fprintf(OutFile, "// Echoing %d Control Points\n",CtrlCnt);
    for (i=0; i;\n",
            Point.x, Point.y, Point.z);
    fprintf(OutFile,"        #break;\n");
    }


void Hermite3D(void)
    {
    register int Current, Next, divisor;

    // C1..C4 are from Foley/VanDam eq (13.30) p.517 - the "t" equations.}
    float t, t2, t3, Delta, C1, C2, C3, C4;
    int Done, FirstTime, Completed; // booleans

    // Vxx variables are for view origin
    EndPointRecTyp VP1, VP2, VtempPnt1, VtempPnt2, VtempPoint;

    Current = 0;
    Next = 1;
    FirstTime = TRUE;
    Completed = FALSE;
    PointCnt = 0;

    while(!Completed)
        {
#ifdef DEBUG
fprintf(DebugFile,"In Main Loop in Hermite...\n");
#endif

        //
        //    First time through we want to start at the t=0 point.
        //    However if we did that each time, we"d end up with a duplicate
        //    point (where t=1 and t=0) for each end-point, so start at the
        //    Delta for each control point after the first.
        //    Which means we also need to change the number of frames for the
        //    last point so we end up where we think we will...
        //

        divisor = CPoints[Current].Frames;
        if (Next == CtrlCnt-1)
            divisor--;

        Delta = 1.0/float(divisor);

        t = 0.0;

        Done = FALSE;

        VP1.x = CPoints[Current].Vpt.x;
        VP1.y = CPoints[Current].Vpt.y;
        VP1.z = CPoints[Current].Vpt.z;
        VP2.x = CPoints[Next].Vpt.x;
        VP2.y = CPoints[Next].Vpt.y;
        VP2.z = CPoints[Next].Vpt.z;
        VtempPnt1.x = CPoints[Current].DVpt.x;
        VtempPnt1.y = CPoints[Current].DVpt.y;
        VtempPnt1.z = CPoints[Current].DVpt.z;
        VtempPnt2.x = CPoints[Next].DVpt.x;
        VtempPnt2.y = CPoints[Next].DVpt.y;
        VtempPnt2.z = CPoints[Next].DVpt.z;


#ifdef DEBUG
fprintf(DebugFile,"ctrlvec1.x.y.z=",
VtempPnt1.X:4:2,",",
VtempPnt1.Y:4:2,",",
VtempPnt1.Z:4:2);
fprintf(DebugFile,"ctrlvec2.x.y.z=",
VtempPnt2.X:4:2,",",
VtempPnt2.Y:4:2,",",
VtempPnt2.Z:4:2);
Close(DebugFile);
Append(DebugFile);
#endif


                if ( FirstTime && !Done)
                    FirstTime = FALSE;

#ifdef DEBUG
fprintf(DebugFile,"    Hermite - Delta=",Delta:10:8,
    "x1,y1,x2,y2=", VP1.X:4,",",vp1.Y:4,",",vp2.X:4,",",vp2.y:4 );
Close(DebugFile);
Append(DebugFile);
#endif

                while( !Done )
                    {
                    t2 = t*t; // squared
                    t3 = t2*t; // cubed 

                    C1 = (2*t3 - 3*t2 +     1);
                    C2 = (-2*t3 + 3*t2        );
                    C3 = (   t3 - 2*t2 + t    );
                    C4 = (   t3 -   t2        );

                    VtempPoint.x = VP1.x * C1 +
                                   VP2.x * C2 +
                                   VtempPnt1.x * C3 +
                                   VtempPnt2.x * C4;

                    VtempPoint.y = VP1.y * C1 +
                                   VP2.y * C2 +
                                   VtempPnt1.y * C3 +
                                   VtempPnt2.y * C4;

                    VtempPoint.z = VP1.z * C1 +
                                   VP2.z * C2 +
                                   VtempPnt1.z * C3 +
                                   VtempPnt2.z * C4;

#ifdef DEBUG
fprintf(debugfile,  "    V3DPoint in VMHermite X = ",VtempPoint.X:4:2, " Y = ",VtempPoint.Y:4:2, " Z = ",VtempPoint.Z:4:2 );
fprintf(debugfile,  "    L3DPoint in VMHermite X = ",LtempPoint.X:4:2, " Y = ",LtempPoint.Y:4:2, " Z = ",LtempPoint.Z:4:2 );
Close(debugfile);Append(debugfile);
#endif

                    VPoints[PointCnt++] = VtempPoint;

                    t += Delta;

                    if (Next == CtrlCnt-1) //Last curve segment include t=1
                        Done = ( t >= (0.999999+Delta));
                    else
                        Done = ( t >= 0.999999 ); // 1.0 is end of curve segment

                    } // while t

            if( Next < CtrlCnt-1 )// new control records...
                {
                Current++;
                Next++;
                }
            else
                Completed = TRUE;
            } // while more control points
    }


// ------- Main -----------


int main( int argc, char *argv[] )
    {

#ifdef DEBUG
Assign( DebugFile, "HermDBG.txt" );
ReWrite(DebugFile);
#endif

    CtrlCnt = 0;
    PointCnt = 0;

    if( argc > 1 )
        strcpy( InputFileName, argv[1] );
    else
        {
        memset( InputFileName, 0x00, sizeof(InputFileName) );
        printf("Enter Input Filename:");
        gets(InputFileName);
        printf("\n\n");
        }

    if (argc > 2 )
        strcpy( OutputFileName, argv[2] );
    else
        {
        memset( OutputFileName, 0x00, sizeof(OutputFileName) );
        printf("Enter Output filename:");
        gets(OutputFileName);
        printf("\n\n");
        }

    InFile = fopen(InputFileName, "r" );
    if (!InFile)
        {
        perror("Opening Input");
        exit(0);
        }

    OutFile = fopen(OutputFileName, "w" );
    if (!OutFile)
        {
        perror("Opening Output");
        exit(0);
        }

    Read_Input();
    fclose(InFile);

    Hermite3D();

    Start_Output();

    for (i=0; i

    Source: geocities.com/emory_stagmer/povherm

               ( geocities.com/emory_stagmer)