////////////////////////////////////////////////////////////
//                                                        //
//  PC MAGAZIN - PC Underground                           //
//  (w)(c)2002 Carsten Dachsbacher                        //
//                                                        //
////////////////////////////////////////////////////////////
#include	<windows.h>			
#include	<gl\gl.h>			
#include	<gl\glu.h>			
#include	<math.h>
#include	<stdio.h>
#include	<assert.h>
#include	"3DObject.h"
#include	"VERTEX3DOP.h"
#include	"glh_extensions.h"

C3DObject::C3DObject( char *file, float scale )
{
	if ( file == NULL )
	{
		nVertices = nFaces = 0;
	}

	FILE *f = fopen( file, "rt" );
	assert( f );

	fscanf( f, "%d %d", &nVertices, &nFaces );

	pVertexList	= new VERTEX3D[ nVertices ];
	assert( pVertexList );
	pTexCoord	= new VERTEX3D[ nVertices ];
	assert( pTexCoord );
	pNormalList	= new VERTEX3D[ nVertices ];
	assert( pNormalList );
	pFaceList	= new FACE[ nFaces ];
	assert( pFaceList );

	for ( int i = 0; i < nVertices; i++ )
	{
		fscanf( f, "%f %f %f", &pVertexList[ i ].x, &pVertexList[ i ].y, &pVertexList[ i ].z );
		pVertexList[ i ] *= scale;
	}

	int dummy;
	for ( i = 0; i < nFaces; i++ )
		fscanf( f, "%d %d %d %d", &dummy, &pFaceList[ i ].a, &pFaceList[ i ].b, &pFaceList[ i ].c );

	fclose( f );

	// Normalen berechnen
	for ( i = 0; i < nFaces; i++ )
	{
		VERTEX3D	*a1, *a2, *a3;
		VERTEX3D	a, b;

		a1 = &pVertexList[ pFaceList[ i ].a ];
		a2 = &pVertexList[ pFaceList[ i ].b ];
		a3 = &pVertexList[ pFaceList[ i ].c ];

		a.x = a2->x - a1->x;
		a.y = a2->y - a1->y;
		a.z = a2->z - a1->z;
		b.x = a3->x - a1->x;
		b.y = a3->y - a1->y;
		b.z = a3->z - a1->z;

		pFaceList[ i ].normal.x = a.y * b.z - b.y * a.z;
		pFaceList[ i ].normal.y = a.z * b.x - b.z * a.x;
		pFaceList[ i ].normal.z = a.x * b.y - b.x * a.y;
	}

	// Vertexnormalen
	for ( i = 0; i < nVertices; i++ )
		pNormalList[ i ].x =
		pNormalList[ i ].y =
		pNormalList[ i ].z = 0.0f;

	for ( i = 0; i < nFaces; i++ )
	{
		pNormalList[ pFaceList[ i ].a ].x += pFaceList[ i ].normal.x;
		pNormalList[ pFaceList[ i ].a ].y += pFaceList[ i ].normal.y;
		pNormalList[ pFaceList[ i ].a ].z += pFaceList[ i ].normal.z;
		pNormalList[ pFaceList[ i ].b ].x += pFaceList[ i ].normal.x;
		pNormalList[ pFaceList[ i ].b ].y += pFaceList[ i ].normal.y;
		pNormalList[ pFaceList[ i ].b ].z += pFaceList[ i ].normal.z;
		pNormalList[ pFaceList[ i ].c ].x += pFaceList[ i ].normal.x;
		pNormalList[ pFaceList[ i ].c ].y += pFaceList[ i ].normal.y;
		pNormalList[ pFaceList[ i ].c ].z += pFaceList[ i ].normal.z;
	}

	for ( i = 0; i < nVertices; i++ )
		~pNormalList[ i ];

	list = glGenLists( 1 );

	glNewList( list, GL_COMPILE );

	glBegin( GL_TRIANGLES );

	for ( i = 0; i < nFaces; i++ )
	{
		glNormal3fv( (GLfloat*)&pNormalList[ pFaceList[ i ].a ] );
		glVertex3fv( (GLfloat*)&pVertexList[ pFaceList[ i ].a ] );
		
		glNormal3fv( (GLfloat*)&pNormalList[ pFaceList[ i ].b ] );
		glVertex3fv( (GLfloat*)&pVertexList[ pFaceList[ i ].b ] );

		glNormal3fv( (GLfloat*)&pNormalList[ pFaceList[ i ].c ] );
		glVertex3fv( (GLfloat*)&pVertexList[ pFaceList[ i ].c ] );
	}

	glEnd();

	glEndList();
}


C3DObject::~C3DObject()
{
	delete pVertexList;
	delete pNormalList;
	delete pFaceList;
}


void	C3DObject::drawObject()
{
	glCallList( list );
}

