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; }
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 ); }
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(); }