예제 #1
0
bool DDynamicActor::Collision_IntersectCheck( int )
{
	DLogWriteSystem(" Collision_IntersectCheck : %p", this );
	
	SVector Location = m_Locus.Location;
	SVector Start = Physics::g_vStart;
	if( m_dwColFlag & CF_COLLIDEDBY_ROOT_INTERNAL )
	{
		Location = GMath.ZeroVector;
		SMatrix Matrix = (this->m_matRootMatrixForCollision * m_Locus.LocalToWorld).Inverse();
		Start = Matrix.TransformVector( Physics::g_vStart );
	}

	SVector vExtent = Physics::g_vExtent + this->m_vExtent;
	SVector Delta = Start - Location;
	if( Abs(Delta.Y) >= vExtent.Y ) return false;

	float DeltaSquared2D = Delta.SizeSquared2D();
	float RadiusSquared = Square(vExtent.X);
	if( DeltaSquared2D >= RadiusSquared ) return false;

	float Overlap = appSqrt( RadiusSquared ) - appSqrt( DeltaSquared2D );
	if( Overlap <= Physics::g_SingleResult.m_fTime ) return false;

	Physics::g_SingleResult.m_nActorIndex	= m_dwID;
	Physics::g_SingleResult.m_nMeshIndex	= -1;
	Physics::g_SingleResult.m_fTime		= Overlap;
	Delta.Y = 0.f;
	Physics::g_SingleResult.m_vNormal		= Delta.SafeNormal();
	Physics::g_SingleResult.m_vContactPoint= m_Locus.Location + this->m_vExtent.X * Physics::g_SingleResult.m_vNormal;
	Physics::g_SingleResult.m_ActorType	= this->m_ActorType;
	return true;
}
예제 #2
0
bool DDynamicActor::Collision_IncludeCheck( int )
{
	DLogWriteSystem(" Collision_IncludeCheck : %p", this );

	SVector Location = m_Locus.Location;
	SVector Start = Physics::g_vStart;
	if( m_dwColFlag & CF_COLLIDEDBY_ROOT_INTERNAL )
	{
		Location = GMath.ZeroVector;
		SMatrix Matrix = (this->m_matRootMatrixForCollision * m_Locus.LocalToWorld).Inverse();
		Start = Matrix.TransformVector( Physics::g_vStart );
	}

	// quick rejecct
	SVector MaxLocation = Location + m_vExtent;
	SVector MinLocation = Location - m_vExtent;
	if( Start.X > MaxLocation.X ) return false;
	if( Start.X < MinLocation.X ) return false;
	if( Start.Y > MaxLocation.Y ) return false;
	if( Start.Y < MinLocation.Y ) return false;
	if( Start.Z > MaxLocation.Z ) return false;
	if( Start.Z < MinLocation.Z ) return false;

	// check circle
	float RadiusSq = ( Start.X - Location.X ) * ( Start.X - Location.X ) + ( Start.Z - Location.Z ) * ( Start.Z - Location.Z );
	if( RadiusSq > m_vExtent.X * m_vExtent.X ) return false;

	// return
	SColResult *Result = new(Physics::g_aMultiResult) SColResult;
	Result->m_nActorIndex	= m_dwID;
	Result->m_nMeshIndex	= -1;
	Result->m_ActorType		= this->m_ActorType;
	return true;
}
예제 #3
0
파일: CMoon.cpp 프로젝트: RaoMiao/freestyle
void CMoon::GetRisingTransformaion( SMatrix& matResult_ )
{
	// Rising Rate         +Y (the zenith)
	//                    (0.25)
	//                   .  |  .
	//            .         |          .
	//       .              |               .
	// (0.5)                |                   .
	//  .                   |                     . (0) = (1)
	// ---------------------+-----------------------          +X (east)
	// Transform Moon (Apply Rising Rate to Translated Moon)
	SMatrix matMoonRot;
	matMoonRot.SetRotation( SRotator( 0, 0, Rad2Angle(m_fRisingRate*fPi*2.0f - fPi/2.0f )) );
	SMatrix matMoonPitch;
	matMoonPitch.SetRotation( SRotator( Rad2Angle(m_fPitch), 0, 0 ) );
	matMoonRot = matMoonRot * matMoonPitch;
	SVector vMoonPos = matMoonRot.TransformVector( m_vTranslation );

	matResult_.SetTranslation( vMoonPos );
	Transform( matResult_ );
}
예제 #4
0
bool DDynamicActor::Collision_LineCheck( int )
{
	DLogWriteSystem(" Collision_LineCheck : %p", this );

	SVector Location = m_Locus.Location;
	SVector StartTest = Physics::g_vStartTest;
	SVector End = Physics::g_vEnd;
	if( m_dwColFlag & CF_COLLIDEDBY_ROOT_INTERNAL )
	{
		Location = GMath.ZeroVector;
		SMatrix Matrix = (this->m_matRootMatrixForCollision * m_Locus.LocalToWorld).Inverse();
		StartTest = Matrix.TransformVector( StartTest );
		End = Matrix.TransformVector( End );
	}

	// quick rejecct
	SVector vExtent = Physics::g_vExtent + this->m_vExtent;
	SVector MaxLocation = Location + vExtent;
	SVector MinLocation = Location - vExtent;
	if( StartTest.X > MaxLocation.X && End.X > MaxLocation.X ) return false;
	if( StartTest.X < MinLocation.X && End.X < MinLocation.X ) return false;
	if( StartTest.Y > MaxLocation.Y && End.Y > MaxLocation.Y ) return false;
	if( StartTest.Y < MinLocation.Y && End.Y < MinLocation.Y ) return false;
	if( StartTest.Z > MaxLocation.Z && End.Z > MaxLocation.Z ) return false;
	if( StartTest.Z < MinLocation.Z && End.Z < MinLocation.Z ) return false;

	// top of cylinder
	Physics::g_fT0 = 0.f;
	Physics::g_fT1 = Physics::g_SingleResult.m_fTime;
	SVector Normal = GMath.YAxis;	// DEBUG!!
	if( StartTest.Y > MaxLocation.Y && End.Y < MaxLocation.Y )
	{
		float T = ( MaxLocation.Y - StartTest.Y ) / ( End.Y - StartTest.Y );
		if( T > Physics::g_fT0 )
		{
			Physics::g_fT0 = ::Max( Physics::g_fT0 , T );
			Normal = GMath.YAxis;
		}
	}
	else if( StartTest.Y < MaxLocation.Y && End.Y > MaxLocation.Y )
		Physics::g_fT1 = ::Min( Physics::g_fT1, ( MaxLocation.Y - StartTest.Y ) / ( End.Y - StartTest.Y ) );

	// bottom of cylinder
	if( StartTest.Y < MinLocation.Y && End.Y > MinLocation.Y )
	{
		float T = ( MinLocation.Y - StartTest.Y ) / ( End.Y - StartTest.Y );
		if( T > Physics::g_fT0 )
		{
			Physics::g_fT0 = ::Max( Physics::g_fT0, T );
			Normal = -GMath.YAxis;
		}
	}
	else if( StartTest.Y > MinLocation.Y && End.Y < MinLocation.Y )
		Physics::g_fT1 = ::Min( Physics::g_fT1, ( MinLocation.Y - StartTest.Y ) / ( End.Y - StartTest.Y ) );

	if( Physics::g_fT0 >= Physics::g_fT1 ) return false;

	// Test
	float A, B, C;
	{
		float DX = End.X - StartTest.X;
		float DZ = End.Z - StartTest.Z;
		float TX = StartTest.X - Location.X;
		float TZ = StartTest.Z - Location.Z;
		A = DX*DX + DZ*DZ;
		B = 2.f * (TX*DX + TZ*DZ);
		C = TX*TX + TZ*TZ - vExtent.X*vExtent.X;
	}

	if( C < DYNAMIC_DIST_ERROR && StartTest.Y > MinLocation.Y && StartTest.Y < MaxLocation.Y )
	{
		A = StartTest.X - Location.X;
		B = StartTest.Z - Location.Z;
		if( A * (End.X-StartTest.X) + B * (End.Z-StartTest.Z) < -0.1f )
		{
			SColResult *Result = ( Physics::g_bMultiCheck ? new(Physics::g_aMultiResult) SColResult : &Physics::g_SingleResult );
			Result->m_nActorIndex	= m_dwID;
			Result->m_nMeshIndex	= -1;
			Result->m_fTime	= 0.f;
			Result->m_vNormal	= SVector(A,0,B).SafeNormal();
			Result->m_vLocation= Physics::g_vStart;
			Result->m_vContactPoint = Location + this->m_vExtent.X * Result->m_vNormal;
			return true;
		}
		else return false;
	}

	float D	= B*B - 4.f*A*C;
	if( D < 0.f ) return false;

	if( A < DYNAMIC_DIST_ERROR*DYNAMIC_DIST_ERROR )
	{
		if( C > 0.f ) return false;
	}
	else
	{
		A  = 0.5f / A;
		D  = appSqrt(D);
		Physics::g_fT1 = ::Min( Physics::g_fT1, (D-B) * A );
		float T = -(D+B) * A;
	
		if( ::Max(T,Physics::g_fT0) >= Physics::g_fT1 ) return false;

		if( T > Physics::g_fT0 )
		{
			Physics::g_fT0 = T;
			Normal.X = StartTest.X + (End.X-StartTest.X)*Physics::g_fT0 - Location.X;
			Normal.Y = 0;
			Normal.Z = StartTest.Z + (End.Z-StartTest.Z)*Physics::g_fT0 - Location.Z;
			Normal.Normalize();
		}
	}

	SColResult *Result = ( Physics::g_bMultiCheck ? new(Physics::g_aMultiResult) SColResult : &Physics::g_SingleResult );
	Result->m_nActorIndex = m_dwID;
	Result->m_nMeshIndex  = -1;
	Result->m_fTime  = Physics::g_fT0;
	Result->m_vLocation = CalcInterpolatedValue( Result->m_fTime, Physics::g_vStart, Physics::g_vEnd );
	Result->m_vNormal = Normal;
	Result->m_vContactPoint = Location + this->m_vExtent.X * Normal;
	Result->m_ActorType = this->m_ActorType;
	return true;
}