int CPolyMesh3::CalcNormal( D3DXVECTOR3* newn, D3DXVECTOR3* curp, D3DXVECTOR3* aftp1, D3DXVECTOR3* aftp2 ) { D3DXVECTOR3 vec1, vec2, crossvec; vec1 = *aftp1 - *curp; vec2 = *aftp2 - *curp; if( vec1 != vec2 ){ Vec3Cross( &crossvec, &vec1, &vec2 ); }else{ crossvec = *curp; } Vec3Normalize( newn, &crossvec ); return 0; }
void PerlinNoiseNormalMapGenerator::FillTexture( LockedTexture& texture ) { int w = texture.GetWidth(); int h = texture.GetHeight(); array2d<float> buffer; buffer.resize( w, h, 0.0f ); GetPerlinTexture( m_Params, buffer ); for( int y=0; y<h; y++ ) { for( int x=0; x<w; x++ ) { Vector3 center( Vector3( 0, 0, buffer(x,y) ) ); Vector3 sum_normal( Vector3(0,0,0) ); // indices (clockwise order from the top) Vector3 tips[4] = { Vector3( 0,-1, buffer( x, get_clamped(y-1,0,h-1) ) ), Vector3( 1, 0, buffer( get_clamped(x+1,0,w-1), y ) ), Vector3( 0, 1, buffer( x, get_clamped(y+1,0,w-1) ) ), Vector3(-1, 0, buffer( get_clamped(x-1,0,w-1), y ) ) }; // int ix[4] = { x, get_clamped(x+1,0,w-1), x, get_clamped(x-1,0,w-1) }; // int iy[4] = { get_clamped(y-1,0,h-1), y, get_clamped(y+1,0,w-1), y }; for( int i=0; i<4; i++ ) { Vector3 normal = Vec3Cross( tips[i] - center, tips[(i+1)%4] - center ); sum_normal += Vec3GetNormalized( normal ); } Vector3 ave_normal = Vec3GetNormalized( sum_normal ); Vector3 offset_normal = ( ave_normal + Vector3(1,1,1) ) * 0.5f; U8 a = 255; U8 r = get_clamped( (U8)(offset_normal.x * 255), (U8)0, (U8)255 ); U8 g = get_clamped( (U8)(offset_normal.y * 255), (U8)0, (U8)255 ); U8 b = get_clamped( (U8)(offset_normal.z * 255), (U8)0, (U8)255 ); U32 argb32 = a << 24 | r << 16 | g << 8 | b; texture.SetPixelARGB32( x, y, argb32 ); } } }
void JL_CollisionDetect_Box_Box( CJL_Shape_Box& rBox0, CJL_Shape_Box& rBox1, CJL_CollisionFunctor& rColFunctor ) { // set up 15 axes to check overlaps between boxes Vector3 avAxis[15]; avAxis[0] = rBox0.GetWorldOrient().GetColumn(0); avAxis[1] = rBox0.GetWorldOrient().GetColumn(1); avAxis[2] = rBox0.GetWorldOrient().GetColumn(2); avAxis[3] = rBox1.GetWorldOrient().GetColumn(0); avAxis[4] = rBox1.GetWorldOrient().GetColumn(1); avAxis[5] = rBox1.GetWorldOrient().GetColumn(2); Vec3Cross( avAxis[6], avAxis[0], avAxis[3] ); Vec3Cross( avAxis[7], avAxis[0], avAxis[4] ); Vec3Cross( avAxis[8], avAxis[0], avAxis[5] ); Vec3Cross( avAxis[9], avAxis[1], avAxis[3] ); Vec3Cross( avAxis[10], avAxis[1], avAxis[4] ); Vec3Cross( avAxis[11], avAxis[1], avAxis[5] ); Vec3Cross( avAxis[12], avAxis[2], avAxis[3] ); Vec3Cross( avAxis[13], avAxis[2], avAxis[4] ); Vec3Cross( avAxis[14], avAxis[2], avAxis[5] ); Scalar afDepth[15], fLength; Scalar fMinDepth = 100.0f; int i, iMinAxis = -1; float fCollTolerance = rColFunctor.m_fCollTolerance; for(i=0; i<15; i++) { afDepth[i] = 101.0f; if( Vec3LengthSq(avAxis[i]) < 0.0000001f ) continue; // invalid axis // separation axis test between 'rBox0' and 'rBox1' if( !rBox0.SepAxisTest( afDepth[i], avAxis[i], rBox1, fCollTolerance ) ) return; // no overlap if( 6<=i ) { // need to normalize axis length and penetration depth fLength = Vec3Length( avAxis[i] ); if( fLength < 0.000001f ) continue; avAxis[i] /= fLength; afDepth[i] /= fLength; } if( afDepth[i] < fMinDepth ) { fMinDepth = afDepth[i]; iMinAxis = i; } } if( iMinAxis < 0 ) return; // no collision detected if( 0.3f < fMinDepth || fMinDepth < 0.0f ) int iUnexpected = 1; // make sure the contact normal is heading toward box0 Vector3 vBox1ToBox0 = rBox0.GetWorldPosition() - rBox1.GetWorldPosition(); if( Vec3Dot( vBox1ToBox0, avAxis[iMinAxis] ) < 0 ) avAxis[iMinAxis] *= -1.0f; Vector3& N = avAxis[iMinAxis]; TCFixedVector< CJL_CollPointInfo, MAX_CONTACTS_PER_BOX_PAIR > vecCollPointInfo; if( /*use_bsptree_collision_detect*/ false ) { // add contact points based on the minimum penetration depth // AddContactPoint( avAxis[iMinAxis], fMinDepth, rBox0, rBox1, rColFunctor ); AddContactPoint( vecCollPointInfo, avAxis[iMinAxis], fMinDepth, rBox0, rBox1, rColFunctor ); } else AddCollisionPoints( vecCollPointInfo, avAxis[iMinAxis], fMinDepth, rBox0, rBox1, rColFunctor ); // also get the point from SAT so that we can obtain // the penetration depth for each intersection point Vector3 vSATPoint = Vector3(0,0,0); switch(iMinAxis) { case 0: case 1: case 2: { // box0 face, box1 corner collision // get the lowest point on the box1 along box1 normal Vector3 vP1; GetSupportPoint( vP1, rBox1, -N ); vSATPoint = ( vP1 - (0.5f * fMinDepth) * N ); } break; case 3: case 4: case 5: { // box0 corner, box1 face collision // get the lowest point on the box1 along box1 normal Vector3 vP0; GetSupportPoint( vP0, rBox0, N ); vSATPoint = ( vP0 + (0.5f * fMinDepth) * N ); } break; // we have an edge/edge collision case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: { // retrieve which edges collided int i = iMinAxis - 6; int ia = i / 3; int ib = i - ia * 3; assert(0 <= ia && ia < 3); assert(0 <= ib && ib < 3); // find two vP0, vP1 oint on both edges Vector3 vP0, vP1; GetSupportPoint( vP0, rBox0, N ); GetSupportPoint( vP1, rBox1, -N ); // find edge intersection // plane along N and F, and passing through PB Vector3 vPlaneNormal = Vec3Cross( N, rBox1.GetWorldOrient().GetColumn(ib) ); Scalar plane_dist = Vec3Dot( vPlaneNormal, vP1 ); // find the intersection T, where Pintersection = vP0 + t * box edge dir Scalar div = Vec3Dot( rBox0.GetWorldOrient().GetColumn(ia), vPlaneNormal ); // plane and ray colinear, skip the intersection. if( fabsf(div) < SCALAR_TINY ) return; // false; Scalar t = (plane_dist - Vec3Dot(vP0, vPlaneNormal)) / div; // point on edge of box0 vP0 += rBox0.GetWorldOrient().GetColumn(ia) * t; vSATPoint = ( vP0 + (0.5f * fMinDepth) * N ); } break; } if( vecCollPointInfo.size() < MAX_CONTACTS_PER_BOX_PAIR ) { const Vector3& vNewActorPos0 = rBox0.GetPhysicsActor()->GetPosition(); const Vector3& vNewActorPos1 = rBox1.GetPhysicsActor()->GetPosition(); Scalar old_depth = vecCollPointInfo.back().InitialPenetration; vecCollPointInfo.push_back( CJL_CollPointInfo( vSATPoint - vNewActorPos0, vSATPoint - vNewActorPos1, old_depth ) ); vecCollPointInfo.back().vContactPosition = vSATPoint; } rColFunctor.AddTemporaryContacts( &rBox0, &rBox1, N, &vecCollPointInfo[0], vecCollPointInfo.size() ); }
//-------------------------------------------------------------------------------------------------------------- //获取该矢量与另一矢量的叉乘积 Vector3 Vector3::GetCross( const Vector3& v3 ) const { static Vector3 tmp; Vec3Cross( &tmp, this, &v3 ); return tmp; }
//-------------------------------------------------------------------------------------------------------------- //将矢量与另一矢量叉乘 void Vector3::Cross( const Vector3& v3 ) { static Vector3 tmp; Vec3Cross( &tmp, this, &v3 ); tmp = *this; }