Ejemplo n.º 1
0
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() );
}
Ejemplo n.º 4
0
	//--------------------------------------------------------------------------------------------------------------
	//获取该矢量与另一矢量的叉乘积
	Vector3 Vector3::GetCross( const Vector3& v3 ) const
	{
		static Vector3 tmp;
		Vec3Cross( &tmp, this, &v3 );
		return tmp;
	}
Ejemplo n.º 5
0
	//--------------------------------------------------------------------------------------------------------------
	//将矢量与另一矢量叉乘
	void Vector3::Cross( const Vector3& v3 )
	{
		static Vector3 tmp;
		Vec3Cross( &tmp, this, &v3 );
		tmp = *this;
	}