/* Copyright (c) 2012 Advanced Micro Devices, Inc. This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ //Originally written by Takahiro Harada #include "ConvexHeightFieldShape.h" #include "Stubs/AdlCollideUtils.h" #include "CubeMapUtils.h" //#include //#include //#include "GlutStuff.h" //#define USE_OLD ConvexHeightField::ConvexHeightField(const float4* vtxBuffer, const int4* idxBuffer, int nTriangles) : CollisionShape( SHAPE_CONVEX_HEIGHT_FIELD ) { create( vtxBuffer, idxBuffer, nTriangles ); } void ConvexHeightField::create( const float4* vtxBuffer, const int4* idxBuffer, int nTriangles ) { { float maxDx2 = -1.f; int maxIdx = -1; for(int i=0; i maxDx2 ) { maxDx2 = dx2; maxIdx = idx.s[j]; } } } ADLASSERT( maxIdx != -1 ); m_scale = sqrtf( maxDx2 ); } // cast ray to find intersectPlaneLineions { for(u32 faceIdx=0; faceIdx<6; faceIdx++) { for(int i=0; i 0.f ) { minFraction = min2( minFraction, fraction ); // todo. have to check if this is the min to replace normal? float4 ab = vtxBuffer[idxBuffer[itri].y]-vtxBuffer[idxBuffer[itri].x]; float4 ac = vtxBuffer[idxBuffer[itri].z]-vtxBuffer[idxBuffer[itri].x]; minNormal = cross3( ab, ac ); minBCrd = bCrd; } } if( minFraction == FLT_MAX ) minFraction = 0.f; { u8 quantizedHeight = (u8)(minFraction*255.f); sample( (Face)faceIdx, i,j ) = quantizedHeight; sampleNormal( (Face)faceIdx, i,j ) = normalize3(minNormal); float minValue = 3.f*(1.f/3.f)*(1.f/3.f); sampleNormal( (Face)faceIdx, i,j ).w = (dot3F4( minBCrd, minBCrd ) - minValue )/(1.f-minValue); } } } } calcSamplePoints( m_samplePoints ); // calc support height using m_samplePoints { for(u32 faceIdx=0; faceIdx<6; faceIdx++) for(int i=0; i maxHeight ) maxHeight = h; } { u8 quantizedHeight = min2((u8)(maxHeight*255.f)+1, 255); sampleSupport( (Face)faceIdx, i, j ) = quantizedHeight; } } } m_aabb.setEmpty(); for(int i=0; i 0.f ) { if( fraction < minFraction ) { minFraction = fraction; minNormal = iEqn; } } } ADLASSERT( minFraction != FLT_MAX ); minNormal.w = minFraction; sampleNormal( (Face)faceIdx, i, j ) = minNormal; } } } { m_scale = -FLT_MAX; for(u32 faceIdx=0; faceIdx<6; faceIdx++) { for(int i=0; i1.f) h=1.f; // ADLASSERT( h <= 1.f ); if( h > maxHeight ) maxHeight = h; } { u8 quantizedHeight = min2((u8)(maxHeight*255.f)+1, 255); sampleSupport( (Face)faceIdx, i, j ) = quantizedHeight; } } } for(int i=0; i<6; i++) { m_faceAabbs[i].setEmpty(); for(int j=0; jm_type == ADL_SHAPE_SPHERE ) { SphereShape* sphere = (SphereShape*)shape; m_scale = sphere->m_radius; for(u32 faceIdx=0; faceIdx<6; faceIdx++) { for(int i=0; im_radius ); m_aabb.m_min = make_float4( -sphere->m_radius ); m_aabb.expandBy( make_float4( m_collisionMargin ) ); for(int i=0; i<6; i++) { m_faceAabbs[i].setEmpty(); for(int j=0; jgetVertexBuffer(), s->getTriangleBuffer(), s->getNumTris() ); } } #endif ConvexHeightField::~ConvexHeightField() { } float ConvexHeightField::queryDistance(const float4& p ) const { const float4 majorAxes[] = {make_float4(1,0,0,0), make_float4(0,1,0,0), make_float4(0,0,1,0)}; if( dot3F4( p, p ) >= m_scale*m_scale ) return FLT_MAX; int faceIdx; float x, y; CubeMapUtils::calcCrd( p, faceIdx, x, y ); x = (x*HEIGHT_RES) - 0.5f; y = (y*HEIGHT_RES) - 0.5f; float height; { int xi = (int)(x); int yi = (int)(y); float dx = x-xi; float dy = y-yi; { int xip = min2((int)(HEIGHT_RES-1), xi+1); int yip = min2((int)(HEIGHT_RES-1), yi+1); u8 xy = sample( (Face)faceIdx, xi, yi ); u8 xpy = sample( (Face)faceIdx, xip, yi ); u8 xpyp = sample( (Face)faceIdx, xip, yip ); u8 xyp = sample( (Face)faceIdx, xi, yip ); height = (xy*(1.f-dx)+xpy*dx)*(1.f-dy) + (xyp*(1.f-dx)+xpyp*dx)*dy; height = height/255.f*m_scale; height = length3( p ) - height; } } return height; } float ConvexHeightField::querySupportHeight(const float4& p ) const { const float4 majorAxes[] = {make_float4(1,0,0,0), make_float4(0,1,0,0), make_float4(0,0,1,0)}; // if( dot3F4( p, p ) >= m_scale*m_scale ) return FLT_MAX; int faceIdx; float x, y; CubeMapUtils::calcCrd( p, faceIdx, x, y ); x = (x*HEIGHT_RES) - 0.5f; y = (y*HEIGHT_RES) - 0.5f; float height; { int xi = (int)(x); int yi = (int)(y); float dx = x-xi; float dy = y-yi; { int xip = min2((int)(HEIGHT_RES-1), xi+1); int yip = min2((int)(HEIGHT_RES-1), yi+1); u8 xy = sampleSupport( (Face)faceIdx, xi, yi ); u8 xpy = sampleSupport( (Face)faceIdx, xip, yi ); u8 xpyp = sampleSupport( (Face)faceIdx, xip, yip ); u8 xyp = sampleSupport( (Face)faceIdx, xi, yip ); height = max2( xy, max2( xpy, max2( xpyp, xyp ) ) ); height = height/255.f*m_scale; } } return height; } float ConvexHeightField::queryW(const float4& p ) const { const float4 majorAxes[] = {make_float4(1,0,0,0), make_float4(0,1,0,0), make_float4(0,0,1,0)}; float value; if( dot3F4( p, p ) >= m_scale*m_scale ) return 0; int faceIdx; float x, y; CubeMapUtils::calcCrd( p, faceIdx, x, y ); x = (x*HEIGHT_RES) - 0.5f; y = (y*HEIGHT_RES) - 0.5f; { int xi = (int)(x); int yi = (int)(y); value = sampleNormal( (Face)faceIdx, xi, yi ).w; } return value; } bool ConvexHeightField::queryDistanceWithNormal( const float4& p, float4& normalOut ) const { int faceIdx; float x, y; CubeMapUtils::calcCrd( p, faceIdx, x, y ); x = (x*HEIGHT_RES) - 0.5f; y = (y*HEIGHT_RES) - 0.5f; { int xi = (int)(x); int yi = (int)(y); normalOut = sampleNormal( (Face)faceIdx, xi, yi ); } return true; } void ConvexHeightField::calcSamplePoints(float4* points) const { for(u32 faceIdx=0; faceIdx<6; faceIdx++) { for(int i=0; i