void COceanRenderObject::RenderHeightmapAnimations( float fAnimSpeed, IEffect *pEffect ) { float fAnimTime = m_fCurrentTime*fAnimSpeed; float fTimeFloor = floor(fAnimTime); float fAnimLerp = fAnimTime - fTimeFloor; int iFrame0 = (int)fAnimTime % OCEAN_HEIGHTMAPTEXTURE_COUNT; int iFrame1 = (iFrame0+1) % OCEAN_HEIGHTMAPTEXTURE_COUNT; Matrix4x4 worldTransform; m_IRenderer->SetMatrix( WORLD_MATRIX, worldTransform.GetMatrix() ); m_IRenderer->SetMaterial( 0, NULL ); m_IRenderer->SetAlphaTest( false ); m_IRenderer->SetDepthTest( false ); m_IRenderer->SetDepthWrite( false ); m_IRenderer->SetRenderState( RENDERSTATE_ALPHABLENDENABLE, RENDERSTATEPARAM_FALSE ); m_IRenderer->SetRenderState( RENDERSTATE_CULLMODE, RENDERSTATEPARAM_CULLNONE ); pEffect->Apply( 0, NULL, NULL ); pEffect->SetPixelConstant( 21, fAnimLerp, 0.0f, 0.0f, 0.0f ); m_IRenderer->SetTexture( 0, m_pHeightmapTextures[iFrame0] ); m_IRenderer->SetTexture( 1, m_pHeightmapTextures[iFrame1] ); m_IRenderer->SetColorMask( true, true, true, true ); m_IRenderer->RenderVertexBuffer( m_TextureGenerationVBI, m_TextureGenerationVB.m_Offset, m_TextureGenerationVB.m_Size/3 ); m_IRenderer->SetDepthTest( true ); m_IRenderer->SetDepthWrite( true ); }
void CCoordinateToolPhysicsObject::GetParentTransform( NxMat34& transform ) { Matrix4x4 parentTrans; static DWORD msgHash_GetGlobalTransform = CHashString(_T("GetGlobalTransform")).GetUniqueID(); m_ToolBox->SendMessage( msgHash_GetGlobalTransform, sizeof(parentTrans), &parentTrans, GetParentName(), &m_hsParentType ); // remove scale and rotation parentTrans.SetRotation( EulerAngle() ); transform.setColumnMajor44( parentTrans.GetMatrix() ); }
void LightMapGenerator::IntersectWithWorld( Ray &vRay, POTENTIAL_INTERSECTION_SORT &sortedIntersections ) { float rayTmin, rayTMax; Vec3 LightOrigin; double t, u, v; Ray rRay; static CHashString meshType(_T("MeshParameterization") ); for( int j = 0; j < (int)m_MeshObjects.size(); j++ ) { //now check each mesh's triangles CHashString &meshName= m_MeshObjects[ j ]; Matrix4x4 meshTransform; Matrix4x4 meshInverseTransform; static DWORD msgHash_GetMeshTransform = CHashString(_T("GetMeshTransform")).GetUniqueID(); m_ToolBox->SendMessage(msgHash_GetMeshTransform, sizeof( Matrix4x4 ), &meshTransform, &meshName, &meshType ); static DWORD msgHash_GetMeshInverseTransform = CHashString(_T("GetMeshInverseTransform")).GetUniqueID(); m_ToolBox->SendMessage(msgHash_GetMeshInverseTransform, sizeof( Matrix4x4 ), &meshInverseTransform, &meshName, &meshType ); AABB meshBounds; static DWORD msgHash_GetAABB = CHashString(_T("GetAABB")).GetUniqueID(); m_ToolBox->SendMessage(msgHash_GetAABB, sizeof( AABB ), &meshBounds, &meshName, &meshType ); //transform this by inverse matrix LightOrigin = meshInverseTransform*vRay.m_Origin; Matrix3x3 matRotate; matRotate.SetFrom4x4( meshInverseTransform.GetMatrix() ); Vec3 transformedDir = matRotate*vRay.m_Direction; transformedDir.Normalize(); rRay = Ray( LightOrigin, transformedDir ); if( meshBounds.IntersectRay( rRay, rayTmin, rayTMax ) ) { //cull mesh away that need not be tested int face = 0; //test intersection MESHPARAMINTERSECTRAYTRIANGLEMSG intersectMsg; intersectMsg.inRay = &rRay; static DWORD msgHash_IntersectRayTriangle = CHashString(_T("IntersectRayTriangle")).GetUniqueID(); m_ToolBox->SendMessage(msgHash_IntersectRayTriangle, sizeof( MESHPARAMINTERSECTRAYTRIANGLEMSG ), &intersectMsg, &meshName, &meshType ); if( intersectMsg.outCollided == true) { face = intersectMsg.outFaceIndex; t = intersectMsg.outIntersectionDistance; u = intersectMsg.outULength; v = intersectMsg.outVLength; if( t < 0 ) { continue; } PotentialIntersection pIntersection; pIntersection.faceIndex = face; pIntersection.t = t; pIntersection.u = u; pIntersection.v = v; pIntersection.mesh = meshName; pIntersection.transformedRay = rRay; sortedIntersections.insert( POTENTIAL_INTERSECTION_SORT_PAIR( (float)t, pIntersection ) ); } } } }
bool LightMapGenerator::ComputeRay( Ray &vRay, ILightObject * l, int bounces, float energy, int curbounce, floatColor &color) { POTENTIAL_INTERSECTION_SORT sortedIntersections; if( curbounce < 0 )return false; if( energy <= ENERGY_CUTOFF )return false; Vec3 triVerts[3]; Vec3 Normals[ 3 ]; float meshU[ 3 ]; float meshV[ 3 ]; double t, u, v; Ray rRay; Vec3 LightOrigin; float attenuationDistance = l->GetAttenuationDistance(); //add to lightposition //check meshes IntersectWithWorld( vRay, sortedIntersections ); if( sortedIntersections.size() > 0 ) { POTENTIAL_INTERSECTION_SORT::iterator iter = sortedIntersections.begin(); PotentialIntersection &firstIntersection = iter->second; u = firstIntersection.u; v = firstIntersection.v; t = firstIntersection.t; int face = firstIntersection.faceIndex; rRay = firstIntersection.transformedRay; static CHashString meshType(_T("MeshParameterization") ); CHashString &meshName = firstIntersection.mesh; GETPARAMETERIZEDTRIANGLESMSG meshFaces; GETPARAMETERIZEDVERTICESMSG meshVertices; static DWORD msgHash_GetTriangleFaces = CHashString(_T("GetTriangleFaces")).GetUniqueID(); m_ToolBox->SendMessage(msgHash_GetTriangleFaces, sizeof( GETPARAMETERIZEDTRIANGLESMSG), &meshFaces, &meshName, &meshType ); static DWORD msgHash_GetCollapsedMesh = CHashString(_T("GetCollapsedMesh")).GetUniqueID(); m_ToolBox->SendMessage(msgHash_GetCollapsedMesh, sizeof( GETPARAMETERIZEDVERTICESMSG), &meshVertices, &meshName, &meshType ); if( meshFaces.outList == NULL || meshVertices.outList == NULL ) { return false; } TriangleFace &tri = (*meshFaces.outList)[ face ]; for( int a = 0; a < 3; a++ ) { Vec3 &v = (* meshVertices.outList)[ tri.index [ a ] ].originalPosition; triVerts[ a ].x = v.x; triVerts[ a ].y = v.y; triVerts[ a ].z = v.z; } //we intersected, find point of intersection, find texel it maps to, color for( int a = 0; a < 3; a++ ) { meshU[ a ] = (* meshVertices.outList)[ tri.index [ a ] ].generatedU; meshV[ a ] = (* meshVertices.outList)[ tri.index [ a ] ].generatedV; Normals[ a ] = (* meshVertices.outList)[ tri.index [ a ] ].normal; } Vec3 intersect; intersect.x = (float)(rRay.m_Origin.x + rRay.m_Direction.x*t); intersect.y = (float)(rRay.m_Origin.y + rRay.m_Direction.y*t); intersect.z = (float)(rRay.m_Origin.z + rRay.m_Direction.z*t); //calculate average normal Normals[ 0 ] = Normals[ 0 ]*(1 - (float)u) + Normals[ 0 ]*(1 - (float)v) + Normals[1]* (float)u + Normals[2]* (float)v; Normals[ 0 ].Normalize(); //now take the dot with light ray float value = Normals[ 0 ].Dot( -rRay.m_Direction ); //write to KD Tree //attenuate value based on distance if( curbounce < bounces ) { attenuationDistance = 4000; //hack attenuate to prevent artifacts for now } float intensity = 1.f - ((float)t / attenuationDistance); if( intensity > 1.f ) { intensity = 1.f; } else if( intensity < 0 ) { intensity = 0; } value *= intensity*energy; if( value <= 0.f ) { value = 0.f; return false; } //linearly interpolate the color based on distance floatColor OutColor; float fogFactor = ( (float)t - m_FogStart ) / ( m_FogEnd - m_FogStart ); if( fogFactor < 0 ) { fogFactor = 0.f; } else if( fogFactor > 1.f ) { fogFactor = 1.f; } OutColor.r = m_FogColor.r*fogFactor + color.r*(1.f - fogFactor ); OutColor.g = m_FogColor.g*fogFactor + color.g*(1.f - fogFactor ); OutColor.b = m_FogColor.b*fogFactor + color.b*(1.f - fogFactor ); Matrix4x4 meshTransform; static DWORD msgHash_GetMeshTransform = CHashString(_T("GetMeshTransform")).GetUniqueID(); m_ToolBox->SendMessage(msgHash_GetMeshTransform, sizeof( Matrix4x4 ), &meshTransform, &meshName, &meshType ); intersect = meshTransform*intersect; //Only need rotation component for normal Matrix3x3 matRotate; matRotate.SetFrom4x4( meshTransform.GetMatrix() ); Vec3 vWorldSpaceNormals = matRotate*Normals[ 0 ]; vWorldSpaceNormals.Normalize(); if( curbounce < bounces ) { Vec3 color( value*OutColor.r, value*OutColor.g, value*OutColor.b ); m_PhotonMap->store( intersect, vWorldSpaceNormals, vRay.m_Direction, color ); //incoming direction must be stored as well m_KDCounter++; } #if 0 //DEBUG code to output bounce rays static int num2 = 0; num2++; if( curbounce < bounces ) { static CHashString h(_T("linename")); ADDLINEPARAMS LineParam; LineParam.name = &h; LineParam.start = vRay.m_Origin; LineParam.end = vRay.m_Origin + vRay.m_Direction*50;//intersect; LineParam.green = 255; LineParam.blue = 0; LineParam.red = 0; static DWORD msgHash_AddLine = CHashString(_T("AddLine")).GetUniqueID(); m_ToolBox->SendMessage(msgHash_AddLine,sizeof(LineParam), &LineParam ); LineParam.start = intersect; LineParam.end = intersect - vRay.m_Direction*50;//intersect; LineParam.blue = 0; LineParam.green = 0; LineParam.red = 255; static DWORD msgHash_AddLine = CHashString(_T("AddLine")).GetUniqueID(); m_ToolBox->SendMessage(msgHash_AddLine,sizeof(LineParam), &LineParam ); } #endif //Get bounce color float finalU = (float)( meshU[0]*( 1 - u - v ) + meshU[1]*u + meshU[2]*v); float finalV = (float)( meshV[0]*( 1 - u - v ) + meshV[1]*u + meshV[2]*v); floatColor bounceColor; MESHPARAMGETBASECOLORATTRIANGLEINTERSECTIONMSG getColorMsg; getColorMsg.inFace = face; getColorMsg.inUBaryCentric = finalU; getColorMsg.inVBaryCentric = finalV; static DWORD msgHash_GetBaseColorAtTriangleIntersection = CHashString(_T("GetBaseColorAtTriangleIntersection")).GetUniqueID(); m_ToolBox->SendMessage(msgHash_GetBaseColorAtTriangleIntersection, sizeof( MESHPARAMGETBASECOLORATTRIANGLEINTERSECTIONMSG), &getColorMsg, &meshName, &meshType ); bounceColor = getColorMsg.outColor; bounceColor.a *= OutColor.a; bounceColor.r *= OutColor.r; bounceColor.g *= OutColor.g; bounceColor.b *= OutColor.b; //bounceColor = OutColor; //if( bounceColor.a >= 0)x { //Calculate bounces Ray rNewRay; rNewRay.m_Origin = intersect; float currentIntensity = value*energy_loss; if( value > ENERGY_CUTOFF && curbounce > 0 && rand()%SPECULAR_CHANCE == 0) { CastSpecularRay( rNewRay, vWorldSpaceNormals ); ComputeRay( rNewRay, l, bounces, currentIntensity, curbounce - 1, bounceColor); } bool diffuseFound = false; int bounceTests = 0; while( currentIntensity > ENERGY_CUTOFF && curbounce > 0 && !diffuseFound && bounceTests < MAX_BOUNCE_TEST ) { bounceTests++; CastDiffuseRay( rNewRay, vWorldSpaceNormals ); diffuseFound = ComputeRay( rNewRay, l, bounces, currentIntensity, curbounce - 1, bounceColor); } } return true; } return false; }
void LightMapGenerator::WriteTextureDataFromPhotonMap() { // Set pointers for the array of ranges static Matrix3x3 matRot; CHashString meshType(_T("MeshParameterization") ); char buf[1024]; static int num = 0; static CHashString h(_T("none")); static Vec3 last(0,0,0); int imin = 33; int imax = 36;//m_MeshObjects.size(); for( int i = imin; i < imax; i++ ) { CHashString &meshName = m_MeshObjects[ i ]; GETPARAMETERIZEDTRIANGLESMSG meshFaces; GETPARAMETERIZEDVERTICESMSG meshVertices; Matrix4x4 meshTransform; Matrix4x4 meshInverseTransform; static DWORD msgHash_GetMeshTransform = CHashString(_T("GetMeshTransform")).GetUniqueID(); m_ToolBox->SendMessage(msgHash_GetMeshTransform, sizeof( Matrix4x4 ), &meshTransform, &meshName, &meshType ); static DWORD msgHash_GetMeshInverseTransform = CHashString(_T("GetMeshInverseTransform")).GetUniqueID(); m_ToolBox->SendMessage(msgHash_GetMeshInverseTransform, sizeof( Matrix4x4 ), &meshInverseTransform, &meshName, &meshType ); matRot.SetFrom4x4( meshTransform.GetMatrix() ); DWORD meshTextureSize; static DWORD msgHash_OnGetTextureSize = CHashString(_T("OnGetTextureSize")).GetUniqueID(); m_ToolBox->SendMessage(msgHash_OnGetTextureSize, sizeof( meshTextureSize ), &meshTextureSize, &meshName, &meshType ); static DWORD msgHash_GetTriangleFaces = CHashString(_T("GetTriangleFaces")).GetUniqueID(); m_ToolBox->SendMessage(msgHash_GetTriangleFaces, sizeof( GETPARAMETERIZEDTRIANGLESMSG), &meshFaces, &meshName, &meshType ); if( meshFaces.outList == NULL || meshVertices.outList == NULL ) { continue; } int sizeTexture = meshTextureSize*meshTextureSize; for( int j = 0; j < (int)meshFaces.outList->size(); j++ ) { if( j%100 == 0 ) { sprintf( buf, "Gathering data for mesh#%d triangles %d-%d\n", i, j/100, j/100+100 ); OutputDebugString( buf ); } //TODO: /*triMapping = &((*meshFaces.outList)[ j ].m_Pixels); floatColor * buffer = m->GetTextureBuffer(); floatColor * indirectLightBuffer = m->GetIndirectLightBuffer(); for( int k = 0; k < (int)triMapping->size(); k++ ) { TriangleTextureMapping &triMap = (*triMapping)[ k ]; int index = triMap.v*m->GetTextureSize() + triMap.u; if( index >= 0 && index < sizeTexture ) { int indexOut = -1; float usedRange = PHOTON_WEIGHT_RANGE; //check if a closest point is within range, if not, we have to extend range Vec3 transformed = (*m->m_Transform)*triMap.localSpaceCoord; //Vec3 transformed = triMap.localSpaceCoord; num++; Vec3 transformedNormal = matRot*triMap.localNormal; transformedNormal.Normalize(); float accumMaxLightIntensity = 0; static int skiptest = 0; skiptest++; //Direct pass if( buffer[ index ].a < 0 // && skiptest%100==0 ) { for( int a = 0; a< (int)m_Lights.size(); a++ ) { static floatColor lightColor; static float fcolor[4]; ILightObject * light = m_Lights[ a ]; if( light ) { light->GetColorIntensity(fcolor); lightColor.a = fcolor[3]; lightColor.r = 1.f;//fcolor[0]; lightColor.g = 1.f;//fcolor[1]; lightColor.b = 1.f;//fcolor[2]; if( ComputeDirectLightAtPoint( transformed, transformedNormal, buffer[ index ], light , lightColor ) ) { accumMaxLightIntensity += lightColor.a; } } } } if( accumMaxLightIntensity <= 0 ) { accumMaxLightIntensity = 1; } ComputeIrradianceAtPoint2( transformed, transformedNormal, accumMaxLightIntensity, indirectLightBuffer[ index ] ); #if 0 if( (num % 40) == 0 ) { ADDLINEPARAMS LineParam; LineParam.name = &h; //LineParam.start = last; //LineParam.end = transformed; LineParam.start = transformed + transformedNormal*40; LineParam.end = transformed; LineParam.blue = 0; LineParam.green = 0; last = transformed; static DWORD msgHash_AddLine = CHashString(_T("AddLine")).GetUniqueID(); m_ToolBox->SendMessage(msgHash_AddLine,sizeof(LineParam), &LineParam ); } #endif } }*/ } } }