Example #1
0
bool slFileObj::ProcessFace(char* inbuf , Shader* curMaterial) {

	const int maxNumVerts = 256;

	//Phase 1 : Load vertex data into arrays
	//This array holds the vertex numbers for
	//(a) vertices, (b) texture coordinates, (c) vertex normals.
	long vertNums[3 * maxNumVerts]; //Use -1 for missing values

	bool missingNormals = false;
	bool missingTexCoords = false;

	int i;
	char*  s = inbuf;
	for (i = 0; i < maxNumVerts + 1; i++) {
		s = ScanForNonwhite(s);
		if (s == 0) {
			break;
		}

		if (i >= maxNumVerts) {
			UnsupportedTooManyVerts(maxNumVerts);
			return false;
		}

		long scannedInt;
		int scanCode = sscanf(s, "%ld", &scannedInt);
		if (scanCode == 0) {
			return false;
		}

		//Negative indices refer to counting backwards
		vertNums[3 * i] = (scannedInt > 0) ? scannedInt : Vertices.Size()
				+
			scannedInt;
		if (vertNums[3 * i] < 1 || vertNums[3 * i] > Vertices.Size()) {
			return false;
		}

		s = ScanForWhiteOrSlash(s);
		if ((*s) != '/') {
			vertNums[3 * i + 1] = vertNums[3 * i + 2] = -1; //No texture
															///coords or normal
															///
			missingTexCoords = true;
			missingNormals = true;
			continue;
		}

		if ((*(s + 1)) == '/' || (*(s + 1)) == ' ' || (*(s + 1)) == 0) {
			vertNums[3 * i + 1] = -1;
			missingTexCoords = true;
		} else {
			scanCode = sscanf(s + 1, "%ld", &scannedInt);
			if (scanCode == 0) {
				return false;
			}

			//Negative indices refer to counting backwards
			vertNums[3 * i + 1] =
					(scannedInt > 0) ? scannedInt : TextureCoords.Size() +
				scannedInt;
			if (vertNums[3 * i + 1] < 1
			 ||	 vertNums[3 * i + 1] > TextureCoords.Size()) {
				return false;
			}
		}

		s = ScanForWhiteOrSlash(s + 1);
		if ((*s) != '/') {
			vertNums[3 * i + 2] = -1;	//No normal
			missingNormals = true;
			continue;
		}

		if ((*(s + 1)) == ' ' || (*(s + 1)) == 0) {
			vertNums[3 * i + 2] = -1;
			missingNormals = true;
		} else {
			scanCode = sscanf(s + 1, "%ld", vertNums + 3 * i + 2);
			if (scanCode != 1) {
				return false;
			}

			//Negative indices refer to counting backwards
			vertNums[3 * i + 2] =
					(scannedInt > 0) ? scannedInt : VertexNormals.Size() +
				scannedInt;

			//XXX TO DO: PUT THIS BACK ONCE NORMALS ARE SCANNED IN!
			//if (vertNums[3*i+2]<1 ||
			//vertNums[3*i+2]>VertexNormals.Size()) {
			//return false;
			//}
		}

		s = ScanForWhite(s + 1);
	}

	int numVertsInFace = i;
	if (numVertsInFace < 3) {
		return false;
	}

	//Create the ViewableTriangles
	//Textures: At the moment, we do not support materials, so it does not
	//make any sense to support textures and texture coordinates.
	vec3 vA, vB, vC;

	//Check for perfect parallolgram first
// 	if (numVertsInFace == 4) {
// 		vec3 vD;
// 		vA.SetFromHg(Vertices[vertNums[0] - 1]);
// 		vB.SetFromHg(Vertices[vertNums[3] - 1]);
// 		vC.SetFromHg(Vertices[vertNums[6] - 1]);
// 		vD.SetFromHg(Vertices[vertNums[9] - 1]);
// 		if ((vD - vA) == (vC - vB) && (vB - vA) == (vC - vD)) {
// 
// 			//Add parallelogram
// 			ViewableParallelogram*	vp = new ViewableParallelogram();
// 			vp->Init(vA, vB, vC);
// 			ScenePtr->AddViewable(vp);
// 			return true;
// 		}
// 	}

	//Otherwise, add as (numVertsInFace-2) many triangles.
	int startIdx = 0;
	int stepIdx = 1;
	for (i = 0; i < numVertsInFace - 2; i++) {

		//Add i-th face of (numVertsInFace-2) total triangles.
		int idx2 = NextTriVertIdx(startIdx, &stepIdx, numVertsInFace);
		int idx3 = NextTriVertIdx(idx2, &stepIdx, numVertsInFace);
		int i1 = vertNums[3 * startIdx] - 1;
		int i2 = vertNums[3 * idx2] - 1;
		int i3 = vertNums[3 * idx3] - 1;
		if (i1 == i2 || i1 == i3 || i2 == i3) {

			//Format error: duplicated vertex in planar, convex polygon!
			return false;
		} else {
			vA.SetFromHg(Vertices[i1]);
			vB.SetFromHg(Vertices[i2]);
			vC.SetFromHg(Vertices[i3]);
			startIdx = idx3;
			assert(0 <= idx2 && idx2 < numVertsInFace);
			assert(0 <= idx3 && idx3 < numVertsInFace);

			prTriangle*  vt = new prTriangle(
				vA, vB, vC,
				vec2(0.0,0.0),
				vec2(0.0,1.0),
				vec2(1.0,1.0),
				curMaterial
			);

			ScenePtr->Primitives()->Add(vt);

		}
	}


	return true;
}
Example #2
0
bool NffFileLoader::Load( const char* filename, SceneDescription& theScene )
{
	Reset();
	ScenePtr = &theScene;

	FILE* infile = fopen( filename, "r" );
	FileLineNumber = 0;

	if ( !infile ) {
		fprintf(stderr, "LoadNffFile: Unable to open file: %s\n", filename);
		return false;
	}

	const Material* curMaterial = &Material::Default;

	// Information for view ("v") command
	int viewCmdStatus = false;		// True if currently handling a "v" command
	VectorR3 viewPos;
	VectorR3 lookAtPos;
	VectorR3 upVector;
	double fovy;		// Field of view angle (in radians)
	int screenWidth, screenHeight;
	double hither;

	char inbuffer[1026];
	while ( true ) {
		if ( !fgets( inbuffer, 1026, infile ) ) {
			if ( viewCmdStatus ) {
				SetCameraViewInfo( theScene.GetCameraView(),
						viewPos, lookAtPos, upVector, fovy, 
						screenWidth, screenHeight, hither );
			}
			fclose( infile );
			PrintCmdNotSupportedErrors(stderr);
			return true;
		}
		FileLineNumber++;

		char *findStart = PreparseNff( inbuffer );
		if ( findStart==0 ) {
			// Ignore if a comment or a blank line
			if ( viewCmdStatus ) {
				SetCameraViewInfo( theScene.GetCameraView(),
						viewPos, lookAtPos, upVector, fovy, 
						screenWidth, screenHeight, hither );
				viewCmdStatus = false;
			}
			continue;				
		}

		bool parseErrorOccurred = false;		

		char theCommand[17];
		int scanCode = sscanf( inbuffer, "%16s", theCommand );
		if ( scanCode!=1 ) {
			parseErrorOccurred = true;
		}
		int cmdNum = GetCommandNumber( theCommand );		
		if ( cmdNum==-1 ) {
			AddUnsupportedCmd( theCommand );
			continue;
		}
		if ( viewCmdStatus && cmdNum<8 ) {
			SetCameraViewInfo( theScene.GetCameraView(),
						viewPos, lookAtPos, upVector, fovy, 
						screenWidth, screenHeight, hither );
			viewCmdStatus = false;
		}


		char* args = ObjFileLoader::ScanForSecondField( findStart );
		bool ok = true;
		switch ( cmdNum ) {
		case 0:   // 'v' command
			viewCmdStatus = true;
			break;
		case 1:   // 'b' command - background color
			{
				VectorR3 bgColor;
				scanCode = sscanf( args, "%lf %lf %lf", &(bgColor.x), &(bgColor.y), &(bgColor.z) );
				if ( scanCode!=3 ) {
					ok = false;
					break;
				}
				theScene.SetBackGroundColor( bgColor );
			}
			break;
		case 2:	// 'l' command - positional light
			{
				VectorR3 lightPos, lightColor;
				scanCode = sscanf( args, "%lf %lf %lf %lf %lf %lf", 
											&(lightPos.x), &(lightPos.y), &(lightPos.z),
											&(lightColor.x), &(lightColor.y), &(lightColor.z) );
				if ( scanCode==3 || scanCode==6 ) {
					Light* aLight = new Light();
					aLight->SetPosition( lightPos );
					if ( scanCode==6 ) {
						aLight->SetColor( lightColor );
					}
					theScene.AddLight( aLight );
				}
				else {
					ok = false;
				}
			}
			break;
		case 3:		// 'f' command - material properties
			{
				VectorR3 color;			// Material color
				double Kd, Ks;			// Diffuse and specular components
				double shininess;
				double transmission;	// Transmission coefficient
				double indexOfRefraction;
				scanCode = sscanf( args, "%lf %lf %lf %lf %lf %lf %lf %lf", 
									&color.x, &color.y, &color.z, &Kd, &Ks,
									&shininess, &transmission, &indexOfRefraction );
				if ( scanCode==8 ) {
					Material* mat = new Material();
					theScene.AddMaterial( mat );				// theScene can take of deleting this material
					mat->SetColorAmbientDiffuse( Kd*color );
					mat->SetColorSpecular( Ks*color );
					mat->SetShininess( shininess );
					if ( transmission>0.0 ) {
						mat->SetColorTransmissive( transmission, transmission, transmission );
						mat->SetIndexOfRefraction( indexOfRefraction );
					}
					curMaterial = mat;
				}
				else {
					ok = false;
				}
			}
			break;
		case 4:		// 'c' command - cylinder or cone or truncated cone
			{
				VectorR3 baseCenter;
				VectorR3 topCenter;
				double baseRadius;
				double topRadius;
				scanCode = sscanf( args, "%lf %lf %lf %lf %lf %lf %lf %lf",
									&baseCenter.x, &baseCenter.y, &baseCenter.z, &baseRadius,
									&topCenter.x, &topCenter.y, &topCenter.z, &topRadius );
				if ( scanCode==8 ) {
					ProcessConeCylNFF( baseCenter, baseRadius, topCenter, topRadius );
				}
				else { 
					ok = false;
				}
			}
		case 5:		// 's' command - sphere
			{
				VectorR3 sphereCenter;
				double radius;
				scanCode = sscanf( args, "%lf %lf %lf %lf", &sphereCenter.x, &sphereCenter.y, &sphereCenter.z, &radius );
				if ( scanCode==4 && radius>0.0 ) {
					ViewableSphere* vs = new ViewableSphere( sphereCenter, radius, curMaterial );
					theScene.AddViewable( vs );
				}
				else {
					ok = false;
				}
			}
			break;
		case 7:		// 'pp' command - normals will be ignored
			UnsupportedNormals();
			// Fall thru to 'p' command.
		case 6:		// 'p' command
			{
				int numVerts;
				const int maxNumVerts = 256;
				scanCode = sscanf( args, "%d", &numVerts );
				if (scanCode!=1 || numVerts<3 ) {
					ok = false;
				}
				else if ( numVerts>maxNumVerts ) {
					UnsupportedTooManyVerts( maxNumVerts );
				}
				else {
					ProcessFaceNFF( numVerts, curMaterial, infile );
				}
			}
			break;
		case 8:		// 'from' command
			{
				scanCode = sscanf( args, "%lf %lf %lf", &(viewPos.x), &(viewPos.y), &(viewPos.z) );
				if ( scanCode!=3 || !viewCmdStatus ) {
					ok = false;
					viewCmdStatus = false;
				}
				break;
			}
		case 9:		// 'lookat' command
			{
				scanCode = sscanf( args, "%lf %lf %lf", &(lookAtPos.x), &(lookAtPos.y), &(lookAtPos.z) );
				if ( scanCode!=3 || !viewCmdStatus ) {
					ok = false;
					viewCmdStatus = false;
				}
				break;
			}
		case 10:		// 'up' command
			{
				scanCode = sscanf( args, "%lf %lf %lf", &(upVector.x), &(upVector.y), &(upVector.z) );
				if ( scanCode!=3 || !viewCmdStatus ) {
					ok = false;
					viewCmdStatus = false;
				}
				break;
			}
		case 11:		// 'angle' command
			{
				scanCode = sscanf( args, "%lf", &fovy );
				if ( scanCode!=1 || !viewCmdStatus ) {
					ok = false;
					viewCmdStatus = false;
				}
				else {
					fovy *= PI/180.0;		// Convert to radians
				}
				break;
			}
		case 12:		// 'hither' command
			{
				scanCode = sscanf( args, "%lf", &hither );
				if ( scanCode!=1 || !viewCmdStatus ) {
					ok = false;
					viewCmdStatus = false;
				}
				break;
			}
		case 13:		// 'resolution' command
			{
				scanCode = sscanf( args, "%d %d", &screenWidth, &screenHeight );
				if ( scanCode!=2 || !viewCmdStatus ) {
					ok = false;
					viewCmdStatus = false;
				}
				break;
			}
		default:
			parseErrorOccurred  = true;
			ok = false;
			break;
		}

		if ( !ok ) {
			fprintf(stderr, "Parse error in NFF file, line %ld: %40s.\n", FileLineNumber, inbuffer );
			parseErrorOccurred = true;
		}

	}
}