示例#1
0
void b2LineJoint::SetMaxMotorForce(float32 force)
{
	m_body1->WakeUp();
	m_body2->WakeUp();
	m_maxMotorForce = B2FORCE_SCALE(float32(1.0))*force;
}
示例#2
0
文件: Timer.cpp 项目: rbmkp4800/Games
void Timer::Initialize()
{
	uint64 frequencyU64 = 0;
	QueryPerformanceFrequency(PLARGE_INTEGER(&frequencyU64));
	frequency = float32(frequencyU64);
}
示例#3
0
bool Main::loop()
{
	WindowDesc mainWindowDesc = WindowDesc::getDefault(); 
	mainWindowDesc.title = cfgWindowTitle;
	mainWindowDesc.width = cfgWindowWidth;
	mainWindowDesc.height = cfgWindowHeight;
	mainWindowDesc.posX = cfgWindowPosX;
	mainWindowDesc.posY = cfgWindowPosY;
	mainWindowDesc.debug_context = cfgDebugContext ? 1 : 0;
	mainWindowDesc.forward_compat = cfgFwdCompatContext ? 1 : 0;
	mainWindowDesc.major_version = cfgOpenglMajorVersion;
	mainWindowDesc.minor_version = cfgOpenglMinorVersion; 
	mainWindowDesc.red_bits = cfgOpenglBackbufferRedBits;
	mainWindowDesc.green_bits = cfgOpenglBackbufferGreenBits;
	mainWindowDesc.blue_bits = cfgOpenglBackbufferBlueBits;
	mainWindowDesc.alpha_bits = cfgOpenglBackbufferAlphaBits;
	mainWindowDesc.depth_bits = cfgOpenglBackbufferDepthBits;
	mainWindowDesc.stencil_bits = cfgOpenglBackbufferStencilBits;
	mainWindowDesc.accum_bits = 0;
	mainWindowDesc.aux_buffers = 0;
	mainWindowDesc.samples = 1;
	mainWindowDesc.refresh_rate = 0;

	//create a window
	Window * mainWindow = m_WindowSystem->openWindow(mainWindowDesc);
	if (!mainWindow) return false;
	//read back values
	m_RenderSystem->attachWindow(mainWindow);
	
	//
	/// INPUT EXAMPLE
	int32 inputIndex = m_InputSystem->attachWindow(mainWindow);
	if (inputIndex == -1) return false;

    InputDevice inputDevice;
    inputDevice.connectDevice(m_InputSystem->getKeyboard());
    inputDevice.connectDevice(m_InputSystem->getMouse());
    //device.connectDevice(m_InputSystem->getJoystick());

    /*
	Trigger::ID trggrReturn = device.addTrigger(&Key::WentUp<Keyboard::Code::key_RETURN>);
	Trigger::ID trggrLeftClick = device.addTrigger(&MouseButton::WentUp<Mouse::Button::Left>);
    //Trigger::ID trggrXPressed = device.addTrigger(&JoystickButton::WentDown<Joystick::Button::Button1>);
	Trigger::ID trggrConfigKey = device.addTrigger(&ConfigKey::WentDown<&cfgActionKey>);

	Trigger::ID trggrChoord = device.addTrigger(
	&And<
		&Or<
			&Key::IsPressed<Keyboard::Code::key_LSHIFT>,
			&Key::IsPressed<Keyboard::Code::key_RSHIFT>
		>,
		&And<
			&Key::IsReleased<Keyboard::Code::key_LCONTROL>,
			&Key::IsReleased<Keyboard::Code::key_RCONTROL>
		>,
		&Key::WentDown<Keyboard::Code::key_A>
	>);
    */
	/*
	trggrChoord = device.addTrigger(
		&Map<
		&Key::IsPressed<Keyboard::Code::key_LSHIFT>,
		&Key::IsPressed<Keyboard::Code::key_RSHIFT>
		>
	);
	//*/
	///END INPUT EXAMPLE
	//

    /// build a simple game object

    GameObject* obj = m_ObjectSystem->createObject();
    obj->addComponent<InputWASDComponent>(inputDevice);
    obj->setPosition(glm::vec3());
    obj->lookInDirection(GameObject::FORWARD_DIRECTION, GameObject::UP_DIRECTION);

    //create a camera and attach it to the object
    Camera cam;
    cam.attachToObject(obj);
    cam.setViewportSize(glm::uvec2(cfgWindowWidth, cfgWindowHeight));
    m_RenderSystem->getScene()->setCamera(&cam);

    cam.update();

    glm::mat4 viewMatrix = cam.getViewMatrix();

#	if DEBUG_BUILD || SHOW_DEBUG_TITLE
	const ansichar* dbg_WindowTitleTemplate = "DEBUG: CurrentFPS (%.3f)";
	ansichar dbg_WindowTitle[128];
	float32 accumDt = 0.0, lastTitleUpdate = 0.0;
#	endif
	typedef std::chrono::high_resolution_clock clock;
	typedef clock::time_point time_point;
	typedef clock::duration time_duration;
	time_point start = clock::now(), current = start, last = start;

	while (m_Running) {
		current = clock::now();
		float32 dt = float32(std::chrono::duration_cast<std::chrono::microseconds>(current - last).count());
		float32 fps = CalcFPS(dt); //get the fps estimation

#	if DEBUG_BUILD || SHOW_DEBUG_TITLE
		accumDt += dt;
		if (accumDt - lastTitleUpdate > oneSecond / 2) {
		std::sprintf(dbg_WindowTitle, dbg_WindowTitleTemplate, fps);
			lastTitleUpdate = accumDt;
			mainWindow->setTitle(dbg_WindowTitle);
		}
#	endif
		m_PackageSystem->tick(dt); //tick the package system (may reimport new packages)

		if (!m_WindowSystem->tick(dt)) {
			m_Running = false;
		}

		if (!m_InputSystem->tick(dt)) {
			m_Running = false;
		}

        if(!m_ObjectSystem->tick(dt)){
            m_Running = false;
        }

        if(!m_PhysicsSystem->tick(dt)){
            m_Running = false;
        }

		if (!m_RenderSystem->tick(dt)) {
			//Rendering failed -> shutdown
			m_Running = false;
        }

		mainWindow->swapBuffers();
		m_Running = m_Running && !mainWindow->isClosed();
		last = current;
	}

	return false;
}
b2Vec2 b2MouseJoint::GetReactionForce() const
{
	return B2FORCE_SCALE(float32(1.0))*m_impulse;
}
示例#5
0
void Test::Step(Settings* settings)
{
	float32 timeStep = settings->hz > 0.0f ? 1.0f / settings->hz : float32(0.0f);
	
	if (settings->pause)
	{
		if (settings->singleStep)
		{
			settings->singleStep = 0;
		}
		else
		{
			timeStep = 0.0f;
		}
		
		m_debugDraw.DrawString(5, m_textLine, "****PAUSED****");
		m_textLine += 15;
	}

	unsigned int flags = 0;
	flags += settings->drawShapes			* b2DebugDraw::e_shapeBit;
	flags += settings->drawJoints			* b2DebugDraw::e_jointBit;
	flags += settings->drawAABBs			* b2DebugDraw::e_aabbBit;
	flags += settings->drawPairs			* b2DebugDraw::e_pairBit;
	flags += settings->drawCOMs				* b2DebugDraw::e_centerOfMassBit;
	m_debugDraw.SetFlags(flags);

		
	m_world->SetWarmStarting(settings->enableWarmStarting > 0);
	m_world->SetContinuousPhysics(settings->enableContinuous > 0);
	
	m_pointCount = 0;
	
	m_world->Step(timeStep, settings->velocityIterations, settings->positionIterations);
		
	if (timeStep > 0.0f)
	{
		++m_stepCount;
	}
	
	if (settings->drawStats)
	{
		m_debugDraw.DrawString(5, m_textLine, "bodies/contacts/joints/proxies = %d/%d/%d",
							   m_world->GetBodyCount(), m_world->GetContactCount(), m_world->GetJointCount(), m_world->GetProxyCount());
		m_textLine += 15;
	}
	
	if (m_mouseJoint)
	{
		//b2Body* body = m_mouseJoint->GetBody2();
		//b2Vec2 p1 = body->GetWorldPoint(m_mouseJoint->m_localAnchor);
		//b2Vec2 p2 = m_mouseJoint->m_target;
		
//		glPointSize(4.0f);
//		glColor3f(0.0f, 1.0f, 0.0f);
//		glBegin(GL_POINTS);
//		glVertex2f(p1.x, p1.y);
//		glVertex2f(p2.x, p2.y);
//		glEnd();
//		glPointSize(1.0f);
//		
//		glColor3f(0.8f, 0.8f, 0.8f);
//		glBegin(GL_LINES);
//		glVertex2f(p1.x, p1.y);
//		glVertex2f(p2.x, p2.y);
//		glEnd();
	}
	
	if (m_bombSpawning)
	{
//		glPointSize(4.0f);
//		glColor3f(0.0f, 0.0f, 1.0f);
//		glBegin(GL_POINTS);
//		glColor3f(0.0f, 0.0f, 1.0f);
//		glVertex2f(m_bombSpawnPoint.x, m_bombSpawnPoint.y);
//		glEnd();
//		
//		glColor3f(0.8f, 0.8f, 0.8f);
//		glBegin(GL_LINES);
//		glVertex2f(m_mouseWorld.x, m_mouseWorld.y);
//		glVertex2f(m_bombSpawnPoint.x, m_bombSpawnPoint.y);
//		glEnd();
	}
	
	if (settings->drawContactPoints)
	{
		//const float32 k_impulseScale = 0.1f;
		const float32 k_axisScale = 0.3f;
		
		for (int i = 0; i < m_pointCount; ++i)
		{
			ContactPoint* point = m_points + i;
			
			if (point->state == b2_addState)
			{
				// Add
				m_debugDraw.DrawPoint(point->position, 10.0f, b2Color(0.3f, 0.95f, 0.3f));
			}
			else if (point->state == b2_persistState)
			{
				// Persist
				m_debugDraw.DrawPoint(point->position, 5.0f, b2Color(0.3f, 0.3f, 0.95f));
			}
			
			if (settings->drawContactNormals == 1)
			{
				b2Vec2 p1 = point->position;
				b2Vec2 p2 = p1 + k_axisScale * point->normal;
				m_debugDraw.DrawSegment(p1, p2, b2Color(0.4f, 0.9f, 0.4f));
			}
			else if (settings->drawContactForces == 1)
			{
				//b2Vec2 p1 = point->position;
				//b2Vec2 p2 = p1 + k_forceScale * point->normalForce * point->normal;
				//DrawSegment(p1, p2, b2Color(0.9f, 0.9f, 0.3f));
			}
			
			if (settings->drawFrictionForces == 1)
			{
				//b2Vec2 tangent = b2Cross(point->normal, 1.0f);
				//b2Vec2 p1 = point->position;
				//b2Vec2 p2 = p1 + k_forceScale * point->tangentForce * tangent;
				//DrawSegment(p1, p2, b2Color(0.9f, 0.9f, 0.3f));
			}
		}
	}
}
示例#6
0
void b3HullShape::ComputeMass(b3MassData* massData, float32 density) const
{
	// M. Kallay - "Computing the Moment of Inertia of a Solid Defined by a Triangle Mesh"
	// https://github.com/erich666/jgt-code/blob/master/Volume_11/Number_2/Kallay2006/Moment_of_Inertia.cpp
	
	// Polyhedron mass, center of mass, and inertia.
	// Let rho be the polyhedron density per unit volume

	// mass = rho * int(1 * dV) 

	// centroid.x = (1 / mass) * rho * int(x * dV)
	// centroid.y = (1 / mass) * rho * int(y * dV)
	// centroid.z = (1 / mass) * rho * int(z * dV)

	// Ixx = rho * int((y^2 + z^2) * dV) 
	// Iyy = rho * int((x^2 + z^2) * dV)
	// Izz = rho * int((x^2 + y^2) * dV)
	
	// Ixy = -rho * int((x * y) * dV)
	// Ixz = -rho * int((x * z) * dV)
	// Iyz = -rho * int((y * z) * dV)

	// Iyx = Ixy
	// Izx = Ixz
	// Izy = Iyz
	B3_ASSERT(m_hull->vertexCount >= 4);

	// Put the hull relative to a point that is inside the hull 
	// to help reducing round-off errors.
	b3Vec3 s; s.SetZero();
	for (u32 i = 0; i < m_hull->vertexCount; ++i)
	{
		s += m_hull->vertices[i];
	}
	s /= float32(m_hull->vertexCount);

	float32 volume = 0.0f;

	b3Vec3 center; center.SetZero();
	
	float32 xx = 0.0f;
	float32 xy = 0.0f;
	float32 yy = 0.0f;
	float32 xz = 0.0f;
	float32 zz = 0.0f;
	float32 yz = 0.0f;

	for (u32 i = 0; i < m_hull->faceCount; ++i)
	{
		const b3Face* face = m_hull->GetFace(i);
		const b3HalfEdge* begin = m_hull->GetEdge(face->edge);

		const b3HalfEdge* edge = m_hull->GetEdge(begin->next);
		do
		{
			const b3HalfEdge* next = m_hull->GetEdge(edge->next);
			
			u32 i1 = begin->origin;
			u32 i2 = edge->origin;
			u32 i3 = next->origin;

			b3Vec3 v1 = m_hull->GetVertex(i1) - s;
			b3Vec3 v2 = m_hull->GetVertex(i2) - s;
			b3Vec3 v3 = m_hull->GetVertex(i3) - s;

			// Signed tetrahedron volume
			float32 D = b3Det(v1, v2, v3);

			// Contribution to the mass
			volume += D;

			// Contribution to the centroid
			b3Vec3 v4 = v1 + v2 + v3;
			
			center += D * v4;

			// Contribution to moment of inertia monomials
			xx += D * (v1.x * v1.x + v2.x * v2.x + v3.x * v3.x + v4.x * v4.x);
			yy += D * (v1.y * v1.y + v2.y * v2.y + v3.y * v3.y + v4.y * v4.y);
			zz += D * (v1.z * v1.z + v2.z * v2.z + v3.z * v3.z + v4.z * v4.z);
			xy += D * (v1.x * v1.y + v2.x * v2.y + v3.x * v3.y + v4.x * v4.y);
			xz += D * (v1.x * v1.z + v2.x * v2.z + v3.x * v3.z + v4.x * v4.z);
			yz += D * (v1.y * v1.z + v2.y * v2.z + v3.y * v3.z + v4.y * v4.z);

			edge = next;
		} while (m_hull->GetEdge(edge->next) != begin);
	}

	b3Mat33 I;

	I.x.x = yy + zz;
	I.x.y = -xy;
	I.x.z = -xz;

	I.y.x = -xy;
	I.y.y = xx + zz;
	I.y.z = -yz;

	I.z.x = -xz;
	I.z.y = -yz;
	I.z.z = xx + yy;
	
	// Total mass
	massData->mass = density * volume / 6.0f;
	
	// Center of mass
	B3_ASSERT(volume > B3_EPSILON);
	center /= 4.0f * volume;
	massData->center = center + s;

	// Inertia relative to the local origin (s).
	massData->I = (density / 120.0f) * I;
	
	// Shift the inertia to center of mass then to the body origin.
	// Ib = Ic - m * c^2 + m * m.c^2
	// Simplification:
	// Ib = Ic + m * (m.c^2 - c^2)
	massData->I += massData->mass * (b3Steiner(massData->center) - b3Steiner(center));
}
示例#7
0
文件: Test.cpp 项目: mridul0810/box2d
void Test::Step(Settings* settings)
{
	float32 timeStep = settings->hz > 0.0f ? 1.0f / settings->hz : float32(0.0f);

	if (settings->pause)
	{
		if (settings->singleStep)
		{
			settings->singleStep = 0;
		}
		else
		{
			timeStep = 0.0f;
		}

		m_debugDraw.DrawString(5, m_textLine, "****PAUSED****");
		m_textLine += DRAW_STRING_NEW_LINE;
	}

	uint32 flags = 0;
	flags += settings->drawShapes			* b2Draw::e_shapeBit;
	flags += settings->drawParticles		* b2Draw::e_particleBit;
	flags += settings->drawJoints			* b2Draw::e_jointBit;
	flags += settings->drawAABBs			* b2Draw::e_aabbBit;
	flags += settings->drawCOMs				* b2Draw::e_centerOfMassBit;
	m_debugDraw.SetFlags(flags);

	m_world->SetAllowSleeping(settings->enableSleep > 0);
	m_world->SetWarmStarting(settings->enableWarmStarting > 0);
	m_world->SetContinuousPhysics(settings->enableContinuous > 0);
	m_world->SetSubStepping(settings->enableSubStepping > 0);
	m_particleSystem->SetStrictContactCheck(settings->strictContacts > 0);

	m_pointCount = 0;

	b2Timer timer;
	m_world->Step(timeStep,
		settings->velocityIterations,
		settings->positionIterations,
		settings->particleIterations);
	settings->stepTimeOut = timer.GetMilliseconds();

	m_world->DrawDebugData();

	if (timeStep > 0.0f)
	{
		++m_stepCount;
	}

	if (settings->drawStats)
	{
		int32 bodyCount = m_world->GetBodyCount();
		int32 contactCount = m_world->GetContactCount();
		int32 jointCount = m_world->GetJointCount();
		m_debugDraw.DrawString(5, m_textLine, "bodies/contacts/joints = %d/%d/%d", bodyCount, contactCount, jointCount);
		m_textLine += DRAW_STRING_NEW_LINE;

		int32 particleCount = m_particleSystem->GetParticleCount();
		int32 groupCount = m_particleSystem->GetParticleGroupCount();
		int32 pairCount = m_particleSystem->GetPairCount();
		int32 triadCount = m_particleSystem->GetTriadCount();
		m_debugDraw.DrawString(5, m_textLine, "particles/groups/pairs/triads = %d/%d/%d/%d", particleCount, groupCount, pairCount, triadCount);
		m_textLine += DRAW_STRING_NEW_LINE;

		int32 proxyCount = m_world->GetProxyCount();
		int32 height = m_world->GetTreeHeight();
		int32 balance = m_world->GetTreeBalance();
		float32 quality = m_world->GetTreeQuality();
		m_debugDraw.DrawString(5, m_textLine, "proxies/height/balance/quality = %d/%d/%d/%g", proxyCount, height, balance, quality);
		m_textLine += DRAW_STRING_NEW_LINE;
	}

	// Track maximum profile times
	{
		const b2Profile& p = m_world->GetProfile();
		m_maxProfile.step = b2Max(m_maxProfile.step, p.step);
		m_maxProfile.collide = b2Max(m_maxProfile.collide, p.collide);
		m_maxProfile.solve = b2Max(m_maxProfile.solve, p.solve);
		m_maxProfile.solveInit = b2Max(m_maxProfile.solveInit, p.solveInit);
		m_maxProfile.solveVelocity = b2Max(m_maxProfile.solveVelocity, p.solveVelocity);
		m_maxProfile.solvePosition = b2Max(m_maxProfile.solvePosition, p.solvePosition);
		m_maxProfile.solveTOI = b2Max(m_maxProfile.solveTOI, p.solveTOI);
		m_maxProfile.broadphase = b2Max(m_maxProfile.broadphase, p.broadphase);

		m_totalProfile.step += p.step;
		m_totalProfile.collide += p.collide;
		m_totalProfile.solve += p.solve;
		m_totalProfile.solveInit += p.solveInit;
		m_totalProfile.solveVelocity += p.solveVelocity;
		m_totalProfile.solvePosition += p.solvePosition;
		m_totalProfile.solveTOI += p.solveTOI;
		m_totalProfile.broadphase += p.broadphase;
	}

	if (settings->drawProfile)
	{
		const b2Profile& p = m_world->GetProfile();

		b2Profile aveProfile;
		memset(&aveProfile, 0, sizeof(b2Profile));
		if (m_stepCount > 0)
		{
			float32 scale = 1.0f / m_stepCount;
			aveProfile.step = scale * m_totalProfile.step;
			aveProfile.collide = scale * m_totalProfile.collide;
			aveProfile.solve = scale * m_totalProfile.solve;
			aveProfile.solveInit = scale * m_totalProfile.solveInit;
			aveProfile.solveVelocity = scale * m_totalProfile.solveVelocity;
			aveProfile.solvePosition = scale * m_totalProfile.solvePosition;
			aveProfile.solveTOI = scale * m_totalProfile.solveTOI;
			aveProfile.broadphase = scale * m_totalProfile.broadphase;
		}

		m_debugDraw.DrawString(5, m_textLine, "step [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.step, aveProfile.step, m_maxProfile.step);
		m_textLine += DRAW_STRING_NEW_LINE;
		m_debugDraw.DrawString(5, m_textLine, "collide [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.collide, aveProfile.collide, m_maxProfile.collide);
		m_textLine += DRAW_STRING_NEW_LINE;
		m_debugDraw.DrawString(5, m_textLine, "solve [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.solve, aveProfile.solve, m_maxProfile.solve);
		m_textLine += DRAW_STRING_NEW_LINE;
		m_debugDraw.DrawString(5, m_textLine, "solve init [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.solveInit, aveProfile.solveInit, m_maxProfile.solveInit);
		m_textLine += DRAW_STRING_NEW_LINE;
		m_debugDraw.DrawString(5, m_textLine, "solve velocity [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.solveVelocity, aveProfile.solveVelocity, m_maxProfile.solveVelocity);
		m_textLine += DRAW_STRING_NEW_LINE;
		m_debugDraw.DrawString(5, m_textLine, "solve position [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.solvePosition, aveProfile.solvePosition, m_maxProfile.solvePosition);
		m_textLine += DRAW_STRING_NEW_LINE;
		m_debugDraw.DrawString(5, m_textLine, "solveTOI [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.solveTOI, aveProfile.solveTOI, m_maxProfile.solveTOI);
		m_textLine += DRAW_STRING_NEW_LINE;
		m_debugDraw.DrawString(5, m_textLine, "broad-phase [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.broadphase, aveProfile.broadphase, m_maxProfile.broadphase);
		m_textLine += DRAW_STRING_NEW_LINE;
	}

	if (m_mouseTracing && !m_mouseJoint)
	{
		float32 delay = 0.1f;
		b2Vec2 acceleration = 2 / delay * (1 / delay * (m_mouseWorld - m_mouseTracerPosition) - m_mouseTracerVelocity);
		m_mouseTracerVelocity += timeStep * acceleration;
		m_mouseTracerPosition += timeStep * m_mouseTracerVelocity;
		b2CircleShape shape;
		shape.m_p = m_mouseTracerPosition;
		shape.m_radius = 2 * GetDefaultViewZoom();
		QueryCallback2 callback(m_particleSystem, &shape, m_mouseTracerVelocity);
		b2AABB aabb;
		b2Transform xf;
		xf.SetIdentity();
		shape.ComputeAABB(&aabb, xf, 0);
		m_world->QueryAABB(&callback, aabb);
	}

	if (m_mouseJoint)
	{
		b2Vec2 p1 = m_mouseJoint->GetAnchorB();
		b2Vec2 p2 = m_mouseJoint->GetTarget();

		b2Color c;
		c.Set(0.0f, 1.0f, 0.0f);
		m_debugDraw.DrawPoint(p1, 4.0f, c);
		m_debugDraw.DrawPoint(p2, 4.0f, c);

		c.Set(0.8f, 0.8f, 0.8f);
		m_debugDraw.DrawSegment(p1, p2, c);
	}

	if (m_bombSpawning)
	{
		b2Color c;
		c.Set(0.0f, 0.0f, 1.0f);
		m_debugDraw.DrawPoint(m_bombSpawnPoint, 4.0f, c);

		c.Set(0.8f, 0.8f, 0.8f);
		m_debugDraw.DrawSegment(m_mouseWorld, m_bombSpawnPoint, c);
	}

	if (settings->drawContactPoints)
	{
		const float32 k_impulseScale = 0.1f;
		const float32 k_axisScale = 0.3f;

		for (int32 i = 0; i < m_pointCount; ++i)
		{
			ContactPoint* point = m_points + i;

			if (point->state == b2_addState)
			{
				// Add
				m_debugDraw.DrawPoint(point->position, 10.0f, b2Color(0.3f, 0.95f, 0.3f));
			}
			else if (point->state == b2_persistState)
			{
				// Persist
				m_debugDraw.DrawPoint(point->position, 5.0f, b2Color(0.3f, 0.3f, 0.95f));
			}

			if (settings->drawContactNormals)
			{
				b2Vec2 p1 = point->position;
				b2Vec2 p2 = p1 + k_axisScale * point->normal;
				m_debugDraw.DrawSegment(p1, p2, b2Color(0.9f, 0.9f, 0.9f));
			}
			else if (settings->drawContactImpulse)
			{
				b2Vec2 p1 = point->position;
				b2Vec2 p2 = p1 + k_impulseScale * point->normalImpulse * point->normal;
				m_debugDraw.DrawSegment(p1, p2, b2Color(0.9f, 0.9f, 0.3f));
			}

			if (settings->drawFrictionImpulse)
			{
				b2Vec2 tangent = b2Cross(point->normal, 1.0f);
				b2Vec2 p1 = point->position;
				b2Vec2 p2 = p1 + k_impulseScale * point->tangentImpulse * tangent;
				m_debugDraw.DrawSegment(p1, p2, b2Color(0.9f, 0.9f, 0.3f));
			}
		}
	}
}