Esempio n. 1
0
hkDemo::Result RayTraceDemo::stepDemo()
{

	if ( m_env->m_window->getMouse().getButtonState() != 0 )
	{
		m_rotateCounter = 60;
	}
	m_rotateCounter--;


	// rotate the camera viewpoint
	if (m_rotateCounter <= 0)
	{

		hkgWindow* w = m_env->m_window;
		hkgCamera* c = w->getViewport(0)->getCamera();

		hkVector4 from; c->getFrom( &from(0) );
		hkVector4 to; c->getTo(&to(0));
		hkVector4 up; c->getUp(&up(0));
		up.set(0,1,0);


		hkVector4 d; d.setSub4(to, from);
		hkQuaternion q( up, .03f);
		d.setRotatedDir(q, d);
		from.setSub4(to, d);

		setupDefaultCameras(m_env, from, to, up );
	}


	//
	//	Do our raytrace
	//
	{
		//
		//	Get our camera information
		//
		hkVector4 from;
		hkVector4 zOffset;
		hkVector4 upOffset;
		hkVector4 rightOffset;
		{
			from.setZero4();
			zOffset.setZero4();
			upOffset.setZero4();
			rightOffset.setZero4();

			hkgWindow* w = m_env->m_window;
			hkgCamera* c = w->getViewport(0)->getCamera();

			c->getFrom( &from(0) );
			c->getDir( &zOffset(0) );
			c->getUp( &upOffset(0) );

			rightOffset.setCross( upOffset, zOffset );
		}

		//
		// global info
		//
		hkVector4 lightPos; lightPos.setAddMul4( from, upOffset, 10 );
		hkReal lightStrength = 150.0f;

		// reflect the light in the normal graphics too 
		{
			hkVector4 lightDir; 
			hkVector4 lightTo; 
			m_env->m_window->getViewport(0)->getCamera()->getDir( &lightTo(0) );
			lightTo.add4( from ); 
			lightDir.setSub4( lightTo, lightPos);
			setSoleDirectionLight(m_env, &lightDir(0), 0xffffffff);
		}


		//
		//	Prepare the data for iterations
		//
		{
			hkgWindow* w = m_env->m_window;
			hkgCamera* c = w->getViewport(0)->getCamera();
			hkReal fa = c->getFar();
			zOffset.mul4( fa );
			upOffset.mul4( fa * c->getFOV() / 45 * CANVAS_HEIGHT/ CANVAS_WIDTH);
			rightOffset.mul4( fa * c->getFOV() / 45 );
		}

		hkpShapeRayCastInput ray;
		ray.m_from = from;
		ray.m_to.setAdd4( from, zOffset );
		ray.m_to.addMul4( 0.5f, upOffset );
		ray.m_to.addMul4( 0.5f, rightOffset );
		upOffset.mul4( 1.0f / CANVAS_HEIGHT );
		rightOffset.mul4( 1.0f / CANVAS_WIDTH );

		m_numPrimaryRays = 0;
		m_numShadowRays = 0;

		hkpShapeRayCastInput lightRay;
		lightRay.m_from = lightPos;

		//
		//	Do the raytracer
		//
		HK_TIMER_BEGIN("Raytrace Frame", HK_NULL);
		m_stopwatch.start();
		{
			hkpShapeRayCastOutput output;
			hkpShapeRayCastOutput output2;
			int* data = reinterpret_cast<int*>(m_texture->getDataPointer());
			hkVector4 yStart = ray.m_to;

			for (int y = 0; y < CANVAS_HEIGHT; y++)
			{
				ray.m_to = yStart;
				for (int x = 0; x < CANVAS_WIDTH; x++ )
				{
				#if (HK_ENDIAN_BIG==1) 
					data[0] = 0x3f3f7fFF; // background (rgba in that byte order)
				#else
					data[0] = 0xFF7f3f3f; // background
				#endif
				
					output.reset();
					m_numPrimaryRays++;
					m_shape->castRay( ray, output );
					if ( output.hasHit() )
					{
						hkReal brightness = .4f;

						hkVector4 hitPos; hitPos.setInterpolate4( ray.m_from, ray.m_to, output.m_hitFraction );
						hkVector4 lightDir; lightDir.setSub4( lightPos, hitPos );

						// get the direct light info
						{
							hkReal lightDot = output.m_normal.dot3( lightDir );
							if ( lightDot > 0.0f )
							{
								//
								//	Do shadows
								//
								output2.reset();
								lightRay.m_to.setInterpolate4( lightRay.m_from,hitPos, 0.999f);

								m_numShadowRays++;
								if (!m_shape->castRay( lightRay, output2 ))
								{
									hkReal lightDirInvLen = lightDir.lengthInverse3();
									brightness += lightDot * lightDirInvLen * lightStrength;

									// add some glare
									{
										hkVector4 reflectedDir; reflectedDir.setAddMul4( lightDir, output.m_normal, -2.0f * lightDot );
										hkVector4 rayDirection; rayDirection.setSub4( ray.m_to, ray.m_from );
										hkReal dot2 = reflectedDir.dot3( rayDirection );
										if ( dot2 > 0 )
										{
											dot2 *= lightDirInvLen;
											dot2 *= dot2;
											dot2 /= rayDirection.lengthSquared3();
											dot2 *= dot2;
											dot2 *= dot2;
											dot2 *= dot2;
											dot2 *= dot2;
											brightness += dot2 * lightStrength * 2;
										}
									}

								}
							}

						}


						unsigned s = (unsigned)hkMath::hkToIntFast( brightness );
						if ( s > 255 ) s = 255;

						#if (HK_ENDIAN_BIG==1) 
							data[0] = 0x000000ff | (s<<24) | (s<<16) | (s<<8); // rgba in that byte order
						#else
							data[0] = 0xff000000 | (s<<16) | (s<<8) | s;
						#endif
					}
					data++;
					ray.m_to.sub4( rightOffset );
				}
				yStart.sub4( upOffset );
			}
		}
		m_stopwatch.stop();
		HK_TIMER_END();
	}

	//
	// Output statistics
	//
	{
		hkReal timePerRayuSecs = m_stopwatch.getSplitSeconds() * 1e6f / (m_numPrimaryRays + m_numShadowRays);
		m_stopwatch.reset();
		char buf[512];
		hkString::snprintf(buf, 512, "Primary Rays:%d\nShadow Rays:%d\nAverage time per ray:%f microsecs", m_numPrimaryRays, m_numShadowRays, timePerRayuSecs);
		m_env->m_textDisplay->outputText(buf, 20, 350);
	}

	//
	//	Draw the texture (really slow as we don't have a quicker reinit for the textures / direct write yet in the HKG)
	//
	m_env->m_window->getContext()->lock();
	if (m_textureRealized)
	{
		m_texture->free();
	}
	m_texture->realize(true);
	m_env->m_window->getContext()->unlock();

	m_textureRealized = true;
		
	return DEMO_OK;
}
Esempio n. 2
0
void hkDefaultDemo::setLightAndFixedShadow(float* lightDir, float* shadowAabbMin, float* shadowAabbMax, float extraNear, float extraFar )
{
	setSoleDirectionLight(m_env, lightDir, 0xffffffff );
	hkgAabb aabb( shadowAabbMin, shadowAabbMax );
	setupFixedShadowFrustum(m_env, *(m_env->m_displayWorld->getLightManager()->getLight(0)), aabb, extraNear, extraFar );
}
Esempio n. 3
0
BroadphaseAddRemoveDemo::BroadphaseAddRemoveDemo(hkDemoEnvironment* env)
:	hkDefaultPhysicsDemo(env),
	m_rndgen(180673),
	m_timer(0)
{
	
	m_useBatch	=	true;
	m_draw		=	true;
	m_rate		=	0.1f;
	m_count		=	64;
	m_maxbodies	=	10000;
	m_removeat	=	0;
	//
	// Create world
	//
	{
		hkpWorldCinfo worldinfo;
		worldinfo.setupSolverInfo(hkpWorldCinfo::SOLVER_TYPE_2ITERS_SOFT);
		//worldinfo.m_gravity.set( 0, 0, -9.81f );		
		worldinfo.m_gravity.set( 0, 0, 0 );		
		worldinfo.m_enableDeactivation	=	false;
		worldinfo.m_autoUpdateKdTree = false;
		worldinfo.setBroadPhaseWorldSize( 200.0f );
		m_world = new hkpWorld( worldinfo );
		m_world->lock();
		// Register ALL agents (though some may not be necessary)
		hkpAgentRegisterUtil::registerAllAgents(m_world->getCollisionDispatcher());
	}	
	
	//
	// Create shape
	//

	m_shape=new hkpSphereShape(0.1f);	

	//
	//	Create the collision filter
	//
	{
		hkpGroupFilter* filter = new hkpGroupFilter();

		// disable all collisions by default
		filter->disableCollisionsUsingBitfield( 0xfffffffe, 0xfffffffe );
		
		m_world->setCollisionFilter( filter );
		filter->removeReference();
	}
	
	//
	// Setup the camera
	//
	{
		hkVector4 from(   0.0f, -20.0f, 0.0f );
		hkVector4 to  (   0.0f,   0.0f, 0.0f );
		hkVector4 up  (   0.0f,   0.0f, 1.0f );
		setupDefaultCameras( env, from, to, up );
		
		float ldir[] = { 0, 0.5f, -1.0f };
		setSoleDirectionLight(m_env, ldir, 0xffffffff );

		setupGraphics();
	}

	m_world->unlock();
}