Ejemplo n.º 1
0
bool
getStick(const QVector3D p1, const QVector3D p2,
		const QColor c1, const QColor c2,
		const float ratio, const float radius,
		vector<QVector3D>& trigVertex, vector<QVector3D>& trigNormal,
		vector<QColor>& trigColor ){

	float stickRadius = radius;
	trigVertex.clear();
	trigNormal.clear();
	trigColor.clear();
	QVector3D mid = p1 + (p2-p1)*ratio;
	QVector3D s1,s2, sMid;

	if( p1.z() != p2.z() && p1.y() != p2.y() ){
		s1.setX(p1.x());
		double z=sqrt(stickRadius*stickRadius*(p2.y()-p1.y())*(p2.y()-p1.y())/
				( (p2.z()-p1.z())*(p2.z()-p1.z())+(p2.y()-p1.y())*(p2.y()-p1.y()) ))+p1.z() ;
		s1.setZ(z);
		s1.setY( p1.y() - (z-p1.z())*(p2.z()-p1.z())/(p2.y()-p1.y()) );
	}else if( p1.z() != p2.z() && p2.x()!=p1.x() ){
		s1.setY(p1.y());
		double z=sqrt(stickRadius*stickRadius*(p2.x()-p1.x())*(p2.x()-p1.x())/
				( (p2.z()-p1.z())*(p2.z()-p1.z())+(p2.x()-p1.x())*(p2.x()-p1.x()) ))+p1.z() ;
		s1.setZ(z);
		s1.setX( p1.x() - (z-p1.z())*(p2.z()-p1.z())/(p2.x()-p1.x()) );
	}else if( p1.y() != p2.y() && p2.x()!=p1.x() ){
		s1.setZ(p1.z());
		double y=sqrt(stickRadius*stickRadius*(p2.x()-p1.x())*(p2.x()-p1.x())/
				( (p2.y()-p1.y())*(p2.y()-p1.y())+(p2.x()-p1.x())*(p2.x()-p1.x()) ))+p1.y() ;
		s1.setY(y);
		s1.setX( p1.x() - (y-p1.y())*(p2.y()-p1.y())/(p2.x()-p1.x()) );
	}

	s2.setX( s1.x() + p2.x()-p1.x() );
	s2.setY( s1.y() + p2.y()-p1.y() );
	s2.setZ( s1.z() + p2.z()-p1.z() );

	//stick
	sMid=s1+(s2-s1)*ratio;
	QVector3D axis=p2-p1;
	QVector3D start1=s1;
	QVector3D start2=s2;

	for( double angle=0; angle<=360.0; angle+=20.0 ){
		double ang=angle*3.14159/180.0;
		QVector3D t1=rotateAroundAxis((start1-p1), axis, ang )+p1;
		QVector3D t2=rotateAroundAxis((start2-p1), axis, ang )+p1;
		QVector3D tMid=t1+(t2-t1)*ratio;

		QVector3D nt1=t1-p1;
		QVector3D nt2=t2-p2;
		QVector3D ns1=s1-p1;
		QVector3D ns2=s2-p2;
		QVector3D ntMid=tMid-mid;
		QVector3D nsMid=sMid-mid;

		trigVertex.push_back(t1);
		trigVertex.push_back(s1);
		trigVertex.push_back(sMid);
		trigNormal.push_back(-nt1);
		trigNormal.push_back(-ns1);
		trigNormal.push_back(-nsMid);
		trigColor.push_back(c1);
		trigColor.push_back(c1);
		trigColor.push_back(c1);

		trigVertex.push_back(t1);
		trigVertex.push_back(sMid);
		trigVertex.push_back(tMid);
		trigNormal.push_back(-nt1);
		trigNormal.push_back(-nsMid);
		trigNormal.push_back(-ntMid);
		trigColor.push_back(c1);
		trigColor.push_back(c1);
		trigColor.push_back(c1);

		trigVertex.push_back(tMid);
		trigVertex.push_back(sMid);
		trigVertex.push_back(s2);
		trigNormal.push_back(-ntMid);
		trigNormal.push_back(-nsMid);
		trigNormal.push_back(-ns2);
		trigColor.push_back(c2);
		trigColor.push_back(c2);
		trigColor.push_back(c2);

		trigVertex.push_back(tMid);
		trigVertex.push_back(s2);
		trigVertex.push_back(t2);
		trigNormal.push_back(-ntMid);
		trigNormal.push_back(-ns2);
		trigNormal.push_back(-nt2);
		trigColor.push_back(c2);
		trigColor.push_back(c2);
		trigColor.push_back(c2);

		s1=t1;
		s2=t2;
		sMid=tMid;
	}

	//head1
	s1=start1;
	for( double angle=0; angle<=180.0; angle+=20.0 ){
		double ang=angle*3.14159/180.0;
		QVector3D t1=rotateAroundAxis((start1-p1), axis, ang )+p1;
		QVector3D axis1=QVector3D::crossProduct(p2-p1,s1-p1);
		QVector3D axis2=QVector3D::crossProduct(p2-p1,t1-p1);

		QVector3D ss1=s1;
		QVector3D tt1=t1;

		for( double angle2=0; angle2<=180; angle2+=30 ){
			double ang2=angle2*3.14159/180.0;
			QVector3D v1=rotateAroundAxis((s1-p1),axis1,ang2)+p1;
			QVector3D v2=rotateAroundAxis((t1-p1),axis2,ang2)+p1;
			QVector3D n0=ss1-p1;
			QVector3D n1=tt1-p1;
			QVector3D n2=v1-p1;
			QVector3D n3=v2-p1;

			if( angle2<=90 ){
				trigVertex.push_back(ss1);
				trigVertex.push_back(tt1);
				trigVertex.push_back(v1);
				trigNormal.push_back(-n0);
				trigNormal.push_back(-n1);
				trigNormal.push_back(-n2);
				trigColor.push_back(c1);
				trigColor.push_back(c1);
				trigColor.push_back(c1);

				trigVertex.push_back(v1);
				trigVertex.push_back(tt1);
				trigVertex.push_back(v2);
				trigNormal.push_back(-n2);
				trigNormal.push_back(-n1);
				trigNormal.push_back(-n3);
				trigColor.push_back(c1);
				trigColor.push_back(c1);
				trigColor.push_back(c1);
			}else{
				trigVertex.push_back(ss1);
				trigVertex.push_back(v1);
				trigVertex.push_back(tt1);

				trigNormal.push_back(-n0);
				trigNormal.push_back(-n2);
				trigNormal.push_back(-n1);

				trigColor.push_back(c1);
				trigColor.push_back(c1);
				trigColor.push_back(c1);

				trigVertex.push_back(v1);
				trigVertex.push_back(v2);
				trigVertex.push_back(tt1);

				trigNormal.push_back(-n2);
				trigNormal.push_back(-n3);
				trigNormal.push_back(-n1);

				trigColor.push_back(c1);
				trigColor.push_back(c1);
				trigColor.push_back(c1);
			}
			ss1=v1;
			tt1=v2;
		}
	}

	//head2
	s1=start2;
	for( double angle=0; angle<=180.0; angle+=20.0 ){
		double ang=angle*3.14159/180.0;
		QVector3D t1=rotateAroundAxis((start2-p2), axis, ang )+p2;
		QVector3D axis1=QVector3D::crossProduct(p1-p2,s1-p2);
		QVector3D axis2=QVector3D::crossProduct(p1-p2,t1-p2);

		QVector3D ss1=s1;
		QVector3D tt1=t1;

		for( double angle2=0; angle2<=180; angle2+=30 ){
			double ang2=angle2*3.14159/180.0;
			QVector3D v1=rotateAroundAxis((s1-p2),axis1,ang2)+p2;
			QVector3D v2=rotateAroundAxis((t1-p2),axis2,ang2)+p2;
			QVector3D n0=ss1-p2;
			QVector3D n1=tt1-p2;
			QVector3D n2=v1-p2;
			QVector3D n3=v2-p2;

			if( angle2>90 ){
				trigVertex.push_back(ss1);
				trigVertex.push_back(tt1);
				trigVertex.push_back(v1);
				trigNormal.push_back(-n0);
				trigNormal.push_back(-n1);
				trigNormal.push_back(-n2);
				trigColor.push_back(c2);
				trigColor.push_back(c2);
				trigColor.push_back(c2);

				trigVertex.push_back(v1);
				trigVertex.push_back(tt1);
				trigVertex.push_back(v2);
				trigNormal.push_back(-n2);
				trigNormal.push_back(-n1);
				trigNormal.push_back(-n3);
				trigColor.push_back(c2);
				trigColor.push_back(c2);
				trigColor.push_back(c2);
			}else if(angle2<=90){
				trigVertex.push_back(ss1);
				trigVertex.push_back(v1);
				trigVertex.push_back(tt1);
				trigNormal.push_back(-n0);
				trigNormal.push_back(-n2);
				trigNormal.push_back(-n1);
				trigColor.push_back(c2);
				trigColor.push_back(c2);
				trigColor.push_back(c2);

				trigVertex.push_back(v1);
				trigVertex.push_back(v2);
				trigVertex.push_back(tt1);

				trigNormal.push_back(-n2);
				trigNormal.push_back(-n3);
				trigNormal.push_back(-n1);

				trigColor.push_back(c2);
				trigColor.push_back(c2);
				trigColor.push_back(c2);
			}
			ss1=v1;
			tt1=v2;
		}
		s1=t1;
	}

	return true;
}
Ejemplo n.º 2
0
int main(){
	
	int BOTTLE_COUNT = 7;

	// =========== LOAD IMAGES ==========

	sf::Texture odd_tile_image, even_tile_image, dice_img, bottle_label, bottle_two_label;

	bottle_label.loadFromFile("label.png");
	bottle_two_label.loadFromFile("label.png");

	sf::String dice_file = "dice.jpg";
	sf::String odd_tile_file = "odd_tile.jpg";
	sf::String even_tile_file = "even_tile.jpg";
	if (!odd_tile_image.loadFromFile(odd_tile_file)){
		std::cout << "Could not load " << odd_tile_file.getData();
	}
	if (!even_tile_image.loadFromFile(even_tile_file)){
		std::cout << "Could not load " << even_tile_file.getData();
	}
	if (!dice_img.loadFromFile(dice_file)){
		std::cout << "Could not load " << dice_file.getData();
	}
	// =========== END LOAD IMAGES ==========

	int width = 1024, height = 960;
	sf::ContextSettings Settings;
	Settings.depthBits = 24; // Request a 24 bits depth buffer
	Settings.stencilBits = 8;  // Request a 8 bits stencil buffer
	Settings.antialiasingLevel = 2;  // Request 2 levels of antialiasing
	sf::RenderWindow window(sf::VideoMode(width, height, 32), "C00170460 - Keith Byrne CA2", sf::Style::Close, Settings);
	window.setFramerateLimit(60);
	sf::Clock Clock;


	// Help message

	sf::Font font;
	font.loadFromFile("C:\\Windows\\Fonts\\arial.TTF");

	

	std::string instructions;
	instructions += "W A S D for Camera Movement\n";
	instructions += "NUMPAD 4 6 8 2 for left/right/up/down Torch Movement\n";
	instructions += "SPACEBAR for torch light switch\n";
	instructions += "LEFT CTRL for torch light colour switch\n";
	instructions += "P for global light switch.";

	sf::Text help;
	help.setFont(font);
	help.setString(instructions);
	help.setColor(sf::Color::White);
	help.setCharacterSize(20);
	help.setPosition(20, 40);

	bool global_switch = true;

	// Camera Setup
	Camera camera(1, // forward speed
		5, // rotation speed
			Vector<float>(0, 5, -15),      // position
				Vector<float>(0, 0, 20),    // forward
					Vector<float>::YAXIS);       // up

	glClearDepth(1.f);
	glClearColor(0.0f, 0.0f, 1.0f, 1.0f); //background colour
	glEnable(GL_DEPTH_TEST);
	glClear(GL_DEPTH_BUFFER_BIT);
	glDepthMask(GL_TRUE);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	// Setup a perspective projection & Camera position 
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	glEnable(GL_TEXTURE_2D);

	//set up a 3D Perspective View volume
	gluPerspective(90.f, (float)width / height, 1.f, 50.0f);//fov, aspect, zNear, zFar 

	double t = 0.0;
	double tetha;
	double fi_tetha = (2 * M_PI) / 60;

	// Dice
	Dice dice(2,						//3D Cube dimension
		Vector<float>(0, 0, -2));		//Initial positioning

	auto dice_rotation_vector = Vector<float>::YAXIS;
	{
		auto xVector = dice.getXVector();
		auto yVector = dice.getYVector();
		auto zv = dice.getZVector();
		auto xv = xVector.rotateAroundAxis(zv, 45);
		xv = xv.rotateAroundAxis(xVector, -45);
		auto yv = yVector.rotateAroundAxis(zv, 45);
		yv = yv.rotateAroundAxis(xVector, -45);
		dice.setXYVectors(xv, yv);
	}

	dice.initDiceTexture(&dice_img);
	dice.setColor({ 1, 1, 1, 0.2f});

	std::vector<Bottle> bottles;
	int modulo_factor = BOTTLE_COUNT / 3;

#pragma region Bottle Set A
	//Create six packesque bottle arrangement
	for (int i = 0; i < BOTTLE_COUNT - 1; i++){

		//Bottle instantiation as follows
		//Position (x,y,z) global construct
		//Tapering object radius array (bottom to top)
		//Object heights (liquid, etc..)
		//Thickness
		//Liquid measure
		float x_pos = -10;
		float y_pos = 0.5f;
		float z_pos = -10;

		if (i % modulo_factor == 0)
		{
			z_pos = -7.5;
			z_pos += i;
			x_pos = -7.5;
			Bottle bottle(Vector<float>(x_pos, y_pos, z_pos),
			{ 1, 1, .95f, .85f, .7f, .5f, .4f, .4f },
			{ 3.85f, .2f, .2f, .2f, .2f, 2, 1 },
			.1f, 4.2f);

			bottle.label = Label(1, 3, 200, Vector<float>(x_pos, y_pos + 1.0f, z_pos));
			bottle.label.slices = 500;

			//Set label global colour to full opacity 
			bottle.outerColour = { 1.0f, 1.0f, 1.0f, 0.3f };
			bottle.innerColour = { 1.0f, 1.0f, 1.0f, 0.3f };

			bottle.liquidColour = { 1.000f, 0.843f, 0.000f, 0.6f };
			bottle.labelColour = { 0, 0, 0, 1 };

			bottle.label.setTexture(&bottle_label, bottle.label.generateTextureVertices());
			bottle.init();
			bottles.push_back(bottle);
		}
		else
		{
			z_pos += i;
			Bottle bottle(Vector<float>(x_pos, y_pos, z_pos),
			{ 1, 1, .95f, .85f, .7f, .5f, .4f, .4f },
			{ 3.85f, .2f, .2f, .2f, .2f, 2, 1 },
			.1f, 4.2f);     // thickness of bottle, height of liquid

			bottle.label = Label(1, 3, 200, Vector<float>(x_pos, y_pos + 1.0f, z_pos));
			bottle.label.slices = 500;

			//Set label global colour to full opacity 
			bottle.outerColour = { 1.0f, 1.0f, 1.0f, 0.3f };
			bottle.innerColour = { 1.0f, 1.0f, 1.0f, 0.3f };

			bottle.liquidColour = { 1.000f, 0.843f, 0.000f, 0.6f };
			bottle.labelColour = { 0, 0, 0, 1 };

			bottle.label.setTexture(&bottle_label, bottle.label.generateTextureVertices());
			bottle.init();
			bottles.push_back(bottle);
		}

	}
#pragma endregion

	// Torch
	Torch torch(0.5f, 1,      // radius 1, radius 2, height
		Vector<float>(-5, 10, 0), // position
		GL_LIGHT1); // light
	torch.setYVector(Vector<float>(0, -1, 0));
	torch.addColor({ 1, 1, 1, 1 });
	torch.addColor({ 1, 1, 0, 1 });
	torch.addColor({ 0, 1, 1, 1 });
	torch.addColor({ 0, 1, 0, 1 });
	torch.setColor(0);

	torch.setfv(GL_DIFFUSE, { .8f, .8f, .8f, .8f });
	torch.setfv(GL_SPECULAR, { 1, 1, 1, 1 });
	torch.setf(GL_SPOT_CUTOFF, 30);
	torch.setf(GL_SPOT_EXPONENT, 5);
	torch.setf(GL_CONSTANT_ATTENUATION, .001);
	torch.setf(GL_LINEAR_ATTENUATION, .001);
	torch.setf(GL_QUADRATIC_ATTENUATION, .01);

	// Odd/Even tiled floor setup. 200x200
	Floor floor(Vector<int>(200, 200),
		Vector<float>(1, 1),          
		Vector<float>(-100, -100),    
		odd_tile_image,		//Map odd floor texture
		even_tile_image);	//Map even floor texture


	//Setup HSR
	glClearDepth(1.0f);
	glClearColor(0.00f, 0.00f, 0.1f, 1.0f); //background colour
	glEnable(GL_DEPTH_TEST);
	glDepthMask(GL_TRUE);
	glEnable(GL_TEXTURE_2D);
	glEnable(GL_AUTO_NORMAL);
	glEnable(GL_NORMALIZE);
	glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
	glShadeModel(GL_SMOOTH);

	//Lighting Config
	glEnable(GL_LIGHTING);
	GLfloat global_ambient[] = { 0.2f, 0.2f, 0.2f, 0.2f };
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient);

	Light globalLight(GL_LIGHT0);
	globalLight.setfv(GL_AMBIENT, { .0f, .0f, .0f, 0.05f });
	globalLight.setfv(GL_DIFFUSE, { .0f, .0f, .0f, 0.05f });
	globalLight.setfv(GL_SPECULAR, { .0f, .0f, .0f, 0.05f });
	globalLight.setfv(GL_POSITION, { -50, -50, 0, 1 });
	//globalLight.enable();

	Light masterLight(GL_LIGHT2);
	masterLight.setfv(GL_AMBIENT, { .5f, .5f, 1.0f, 0.4f });
	masterLight.setfv(GL_DIFFUSE, { .1f, .1f, .1f, .0f });
	masterLight.setfv(GL_SPECULAR, { 1, 1, 1, 0.1f });
	masterLight.setfv(GL_POSITION, { 0, -50, 0, 1 });
	//masterLight.enable();
	global_switch = false;

	// Material
	glEnable(GL_COLOR_MATERIAL);
	glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
	GLfloat materialSpecular[4] = { 1, 1, 1, 1 };
	GLfloat materialAmbient[4] = { .1f, .1f, .1f, .1f };
	GLfloat materialDiffuse[4] = { .8f, .8f, .8f, .8f };
	glMaterialfv(GL_FRONT, GL_SPECULAR, materialSpecular);
	glMaterialfv(GL_FRONT, GL_AMBIENT, materialAmbient);
	glMaterialfv(GL_FRONT, GL_DIFFUSE, materialDiffuse);
	glMateriali(GL_FRONT, GL_SHININESS, 100);

	// Start game loop 
	while (window.isOpen()){
		// Process events 
		sf::Event Event;
		while (window.pollEvent(Event))
		{
			// Close window : exit 
			if (Event.type == sf::Event::Closed)
				window.close();
			// Escape key : exit 
			if ((Event.type == sf::Event::KeyPressed) && (Event.key.code == sf::Keyboard::Escape))
				window.close();

			//update the camera
			if ((Event.type == sf::Event::KeyPressed) && (Event.key.code == sf::Keyboard::P)){
				if (global_switch == true)
				{
					masterLight.disable();
					global_switch = false;
				}
				else{
					masterLight.enable();
					global_switch = true;
				}
			}

			if ((Event.type == sf::Event::KeyPressed) && (Event.key.code == sf::Keyboard::PageUp)){
				for (int i = 0; i < BOTTLE_COUNT - 1; i++)
				{
					float liquid = bottles[i].liquid;
					liquid += 0.5f;
					bottles[i].incrementLiquid();
				}
			}

			if ((Event.type == sf::Event::KeyPressed) && (Event.key.code == sf::Keyboard::PageDown)){
				for (int i = 0; i < BOTTLE_COUNT - 1; i++)
				{
					float liquid = bottles[i].heights[0];
					liquid -= 0.5f;
					bottles[i].decrementLiquid();
				}
			}

			torch.update(Event);

			
		}

		camera.updateKeyboardEvent();
		torch.updateKeyboardEvent();
		
		//Prepare for drawing
		// Clear color and depth buffer
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


		// Apply some transformations
		//initialise the worldview matrix
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();

		//get the viewing transform from the camera
		camera.ViewingTransform();

		//make the world spin
		//TODO:probably should remove this in final
		static float ang = 0.0;
		//ang+=0.01f;
		//glRotatef(ang*2,0,1,0);//spin about y-axis

		auto light_position = torch.getPosition();
		auto yVector = torch.getYVector();

		//make sure light object follows absolute position and direction of torch source
		torch.setfv(GL_POSITION, { light_position.x, light_position.y, light_position.z, 1 });
		torch.setfv(GL_SPOT_DIRECTION, { yVector.x, yVector.y, yVector.z });

		
		window.draw(floor);
		dice.rotate(dice_rotation_vector, 5);
		window.draw(dice);
		

		for (int i = 0; i < BOTTLE_COUNT-1; i++){
			bottles[i].rotate(Vector<float>(1, 1, 2), 2);
			window.draw(bottles[i]);
		}

		window.draw(torch);
		

		window.pushGLStates();
		window.draw(help);
		window.popGLStates();

			//Render all objects to display
			window.display();
	}
	return EXIT_SUCCESS;
}