Beispiel #1
0
float QUATERNION::GetAngleBetween(QUATERNION quat2)
{
	//establish a forward vector
	VERTEX forward;
	forward.x = 0;
	forward.y = 0;
	forward.z = 1;
	
	//create vectors for quats
	VERTEX vec1, vec2;
	vec1 = RotateVec(forward);
	vec2 = quat2.RotateVec(forward);
	
	//return the angle between the vectors
	return acos(vec1.dot(vec2));
}
void RaycastRender(b2World& world, sf::RenderTarget& target, Camera& camera) 
{
	const float ray_length = 15.0f; // How far rays will travel before they will stop.
	const float view_angle = (3.14f * (0.25f * angle_modifier)); 
	const b2Vec2 view_plane(-camera.fwd.y * angle_modifier, camera.fwd.x * angle_modifier);	
	const b2Vec2 raystart = camera.pos;

	// Cast a ray for each horizontal pixel.
	for (unsigned i = 0; i < target.getSize().x; ++i) {
		// Determine the direction the ray should go in...
		// [-1, 1] How far across the screen from left to right the current ray is.
		float screenx = -1.0f + (2.0f * (i / (float)target.getSize().x)); 
		// There are 2 ways to calculate the ray's direction.
		b2Vec2 raydir = raydir_mode_toggle ?
			// 1: Scale the view plane vector by screenx and add it to the camera's forward vector.
			(camera.fwd) + (screenx * view_plane) :
			// 2: Rotate the camera's forward vector by the viewing angle scaled by screenx. 
			RotateVec(camera.fwd, view_angle * screenx);
		// Determine the end point of the ray in world space.
		b2Vec2 rayend = camera.pos + ray_length * raydir;

		RayCastCallback callback;
		world.RayCast(&callback, raystart, rayend); // Cast the ray!

		if (callback.m_fixture) { // If the ray hit something...
			b2Vec2 ray = (callback.m_point - raystart);
			// Use either the 1) actual distance or 2) perpendicular distance from the camera to the
			// ray hit point.
			float distance = distance_mode_toggle ? ray.Length() : DotProduct(ray, camera.fwd);
			// Use this distance to figure out how tall a line to draw.
			int line_height = abs(int(target.getSize().y / distance));
			// Make far-away lines darker.
			sf::Uint8 f = sf::Uint8((1.f - (distance / ray_length)) * 255.0f);
			sf::Color c(f, f, f);

			sf::Vertex line[2] =
			{
				sf::Vertex(sf::Vector2f(float(i+1), (float)(target.getSize().y / 2) - (line_height / 2)), c),
				sf::Vertex(sf::Vector2f(float(i+1), (float)(target.getSize().y / 2) + (line_height / 2)), c)
			};

			target.draw(line, 2, sf::PrimitiveType::Lines);
		}
	}

}
Beispiel #3
0
// specular reflectivity, no colors yet, all vectors assumed normalized 
float GaussHighlight( float gloss, float aniso, float orient,  
                 Point3& N, Point3& V, Point3& L, Point3& T, float* pNL )
{
   float out = 0.0f;

   float asz = (1.0f - gloss) * ALPHA_SZ;
   float ax = ALPHA_MIN + asz;
   float ay = ALPHA_MIN + asz * (1.0f-aniso);
// DbgAssert( ax >= 0.0f && ay >= 0.0f );
   LBound( ax ); LBound( ay );

   Point3 H = Normalize(L - V); // (L + -V)/2
   float NH = DotProd(N, H);   
   if (NH > 0.0f) {
      float axy = /* normalizeOn ? ax * ay : */ DEFAULT_GLOSS2;
      float norm = 1.0f / (4.0f * PI * axy );
      float NV = -DotProd(N, V );
      if ( NV <= 0.001f)
         NV = 0.001f;

      float NL = pNL ? *pNL : DotProd( N, L );
      float g = 1.0f / (float)sqrt( NL * NV );
      if ( g > 3.0f ) g = 3.0f;

      // Apply Orientation rotation here
      float or = orient * 180.0f;
      Point3 T1 = T;
      if ( or != 0.0f )
         T1 = RotateVec( T, N, DegToRdn(or));

      // get binormal
      Point3 B = CrossProd( T1, N );

      float x = Dot( H, T1 ) / ax;
      float y = Dot( H, B ) / ay;
      float e = (float)exp( -2.0 * (x*x + y*y) / (1.0+NH) );

      out = norm * g * e;
   }
   return SPEC_MAX * out;  // does not have speclev or light color or kL
}
int main() {

	sf::RenderWindow window;
	window.create(sf::VideoMode(512, 512), "SFML Window");

	b2Vec2 gravity(0.0f, -1.0f);

	b2World world(gravity);

	AddStaticBox(world, b2Vec2(2.5f, 2.5f), b2Vec2(1.0f, 1.0f));
	AddStaticBox(world, b2Vec2(7.0f, 2.5f), b2Vec2(1.0f, 1.0f));
	AddStaticBox(world, b2Vec2(7.0f, 7.0f), b2Vec2(1.0f, 1.0f));
	AddStaticBox(world, b2Vec2(2.5f, 7.0f), b2Vec2(1.0f, 1.0f));

	// Add a dynamic circle body.
	{
		b2BodyDef body_def;
		body_def.type = b2_dynamicBody;
		body_def.position.Set(2.5f, 5.5f);
		b2Body* body = world.CreateBody(&body_def);
		b2CircleShape circle;
		circle.m_radius = 0.5f;
		b2FixtureDef fixdef;
		fixdef.shape = &circle;
		fixdef.density = 1.0f;
		fixdef.friction = 0.3f;
		body->CreateFixture(&fixdef);
	}

	DebugDrawerSFML debug_drawer;
	debug_drawer.m_target = &window;
	debug_drawer.SetFlags(b2Draw::e_shapeBit | b2Draw::e_centerOfMassBit);
	world.SetDebugDraw(&debug_drawer);
	

	sf::Clock clock;
	float dt = 0.0f;

	bool render_box2d_debug = false;

	Camera camera;
	camera.pos.x = 10.0f;
	camera.pos.y = 5.0f;
	camera.fwd.x = -1.0f;
	camera.fwd.y = 0.0f;

	unsigned frame_tex_width = 512;
	unsigned frame_tex_height = frame_tex_width;

	sf::RenderTexture frame_tex;
	frame_tex.create(frame_tex_width, frame_tex_height);

	while (window.isOpen()) {

		{
			sf::Event event;
			while (window.pollEvent(event)) {
				switch (event.type) {

				case sf::Event::Closed:
					window.close();
					break;

				case sf::Event::Resized:
					//window.setSize(sf::Vector2u(event.size.height, event.size.height));
					break;

				case sf::Event::KeyPressed:
					switch (event.key.code) {
					case sf::Keyboard::Escape:
						window.close();
						break;
					case sf::Keyboard::Q:
						// Toggle the Box2D debug draw mode.
						render_box2d_debug = !render_box2d_debug;
						break;
					case sf::Keyboard::E:
						// Toggle between ways of calculating the distance to the ray
						// hit point.
						distance_mode_toggle = !distance_mode_toggle;
						std::cout << "Distance Mode: " <<
							(distance_mode_toggle ? "true distance" : "perpendicular distance") 
							<< std::endl;
						break;
					case sf::Keyboard::R:
						// Toggle between ways of calculating the direction of the ray.
						raydir_mode_toggle = !raydir_mode_toggle;
						std::cout << "Ray Direction Mode: " <<
							(raydir_mode_toggle ? "view plane" : "rotated forward vector")
							<< std::endl;
						break;
					case sf::Keyboard::F:
						if (frame_tex_width > 64) {
							frame_tex_width /= 2;
							frame_tex_height = frame_tex_width;
						}
						frame_tex.create(frame_tex_width, frame_tex_height);
						std::cout << "Frame Texture Width: " << frame_tex_width << std::endl;
						break;
					case sf::Keyboard::G:
						if (frame_tex_width < 512) {
							frame_tex_width *= 2;
							frame_tex_height = frame_tex_width;
						}
						frame_tex.create(frame_tex_width, frame_tex_height);
						std::cout << "Frame Texture Width: " << frame_tex_width << std::endl;
						break;
					}
					break;
				}

			}
		}

		{
			dt += clock.restart().asSeconds();
			float timestep = 1.0f / 60.0f;
			if (dt >= timestep) { // If 1/60th of a second has passed...
				dt = 0.0f;

				// Step the Box2D world.
				{
					int velocity_iterations = 8;
					int position_iterations = 2;
					world.Step(timestep, velocity_iterations, position_iterations);
				}
				
				// Move and rotate the camera.
				{
					const float movespeed = 0.1f;

					if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) {
						camera.pos += movespeed * b2Vec2(camera.fwd.x, camera.fwd.y);
					}
					if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) {
						camera.pos -= movespeed * b2Vec2(camera.fwd.x, camera.fwd.y);
					}
					if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) {
						b2Vec2 left(camera.fwd.y, -camera.fwd.x);
						camera.pos += movespeed * left;
					}
					if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) {
						b2Vec2 left(camera.fwd.y, -camera.fwd.x);
						camera.pos -= movespeed * left;
					}

					const float rotatespeed = 0.05f;

					if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) {
						camera.fwd = RotateVec(camera.fwd, -rotatespeed);
					}
					if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) {
						camera.fwd = RotateVec(camera.fwd, rotatespeed);
					}
				}

				// Change the size of the viewing angle / width of the viewing plane
				{
					const float angle_change_speed = 0.05f;
					if (sf::Keyboard::isKeyPressed(sf::Keyboard::Z)) {
						angle_modifier -= angle_change_speed;
						angle_modifier = std::max(angle_modifier, 0.25f);
					}
					if (sf::Keyboard::isKeyPressed(sf::Keyboard::X)) {
						angle_modifier += angle_change_speed;
						angle_modifier = std::min(angle_modifier, 2.0f);
					}
				}
			}
		}


		window.clear(sf::Color(128, 128, 255));

		if (render_box2d_debug) {
			// Use the DebugDrawerSFML we set up earlier to render the world.
			world.DrawDebugData();
			// Draw camera.
			{
				float scale = 32.0f;
				float radius = camera.fwd.Length() * scale;
				sf::CircleShape circle(radius);
				circle.setOrigin(radius, radius);
				circle.setPosition(B2VecToSFVec(camera.pos, scale));
				circle.setOutlineThickness(-1.0f);
				circle.setFillColor(sf::Color::Transparent);

				b2Vec2 endPoint = camera.pos + camera.fwd;
				sf::Vertex line[2] =
				{
					sf::Vertex(B2VecToSFVec(camera.pos, scale)), 
					sf::Vertex(B2VecToSFVec(endPoint, scale))
				};

				window.draw(circle);
				window.draw(line, 2, sf::Lines);
			}
		}
		else {
			//sf::Clock render_time_clock;

			// Render in EXPERIMENTAL RAYCAST MODE:
			frame_tex.clear(sf::Color::Transparent);
			RaycastRender(world, frame_tex, camera);
			frame_tex.display();
			sf::Sprite frame_sprite(frame_tex.getTexture());
			frame_sprite.setScale((float)window.getSize().x / (float)frame_tex.getSize().x, 
				(float)window.getSize().y / (float)frame_tex.getSize().y);
			window.draw(frame_sprite);

			//unsigned render_time_ms = render_time_clock.getElapsedTime().asMilliseconds();
			//std::cout << render_time_ms << std::endl;
		}
		
		window.display();

	}

	return 0;
}