www.pudn.com > 3D_Tank.rar > Arithmetic.cpp


#include "Arithmetic.h" 
 
//方便函数 
DWORD FtoDw(float f) 
{ 
	return *((DWORD *)&f); 
} 
 
float GetRandomFloat(float min, float max) 
{ 
	int f = rand() % 10001; 
	f /= 10000.0f; 
	return min + f * (max - min); 
} 
//几何体碰撞 
BOOL IsPointInBox(const D3DXVECTOR3 &point, const Box &box) 
{ 
	if ( point.x > box.m_vMin.x && point.x < box.m_vMax.x && 
		 point.y > box.m_vMin.y && point.y < box.m_vMax.y && 
		 point.z > box.m_vMin.z && point.z < box.m_vMax.z) 
		 return TRUE; 
	else 
		return FALSE; 
} 
 
BOOL BoxTest(const Box &box1, const Box &box2) 
{ 
	BOOL ReturnValue = FALSE; 
 
	if (IsPointInBox(box1.m_vMin, box2)) 
	{ 
		ReturnValue = TRUE; 
	} 
	else if (IsPointInBox(D3DXVECTOR3(box1.m_vMin.x, box1.m_vMax.y, box1.m_vMin.z), box2)) 
	{ 
		ReturnValue = TRUE; 
	} 
	else if (IsPointInBox(D3DXVECTOR3(box1.m_vMax.x, box1.m_vMax.y, box1.m_vMin.z), box2)) 
	{ 
		ReturnValue = TRUE; 
	} 
	else if (IsPointInBox(D3DXVECTOR3(box1.m_vMax.x, box1.m_vMin.y, box1.m_vMin.z), box2)) 
	{ 
		ReturnValue = TRUE; 
	} 
	else if (IsPointInBox(box1.m_vMax, box2)) 
	{ 
		ReturnValue = TRUE; 
	} 
	else if (IsPointInBox(D3DXVECTOR3(box1.m_vMax.x, box1.m_vMin.y, box1.m_vMax.z), box2)) 
	{ 
		ReturnValue = TRUE; 
	} 
	else if (IsPointInBox(D3DXVECTOR3(box1.m_vMin.x, box1.m_vMin.y, box1.m_vMax.z), box2)) 
	{ 
		ReturnValue = TRUE; 
	} 
	else if (IsPointInBox(D3DXVECTOR3(box1.m_vMin.x, box1.m_vMax.y, box1.m_vMax.z), box2)) 
	{ 
		ReturnValue = TRUE; 
	} 
		return ReturnValue; 
}//特殊情况还没有考虑到,比如点都不在另一个Box中,但线在另一个物体中 
 
D3DXMATRIX* GenerateTranslationMatrix(D3DXMATRIX *mat, const D3DXVECTOR3 &pos, const float yaw ,  
									  const float pitch, const float roll) 
{ 
	D3DXVECTOR3 look(0, 0, 1); 
	D3DXVECTOR3 up(0, 1, 0); 
	D3DXVECTOR3 right(1, 0, 0); 
 
	if (pitch != 0) 
	{ 
		D3DXMATRIX matPitch; 
		D3DXMatrixRotationAxis(&matPitch, &right, D3DXToRadian(pitch)); 
		D3DXVec3TransformNormal(&up, &up, &matPitch);		 
		D3DXVec3TransformNormal(&look, &look, &matPitch); 
	} 
 
	if (roll != 0) 
	{ 
		D3DXMATRIX matRoll; 
		D3DXMatrixRotationAxis(&matRoll, &look, D3DXToRadian(roll)); 
		D3DXVec3TransformNormal(&up, &up, &matRoll); 
		D3DXVec3TransformNormal(&right, &right, &matRoll); 
	} 
 
	if (yaw != 0) 
	{ 
		D3DXMATRIX matYaw; 
		D3DXMatrixRotationAxis(&matYaw, &up, D3DXToRadian(yaw)); 
		D3DXVec3TransformNormal(&look, &look, &matYaw); 
		D3DXVec3TransformNormal(&right, &right, &matYaw); 
	} 
 
	GenerateMatrix(mat, right, up, look, pos); 
 
	return mat; 
} 
 
VOID GetThreeDirFromMatrix(D3DXMATRIX *mat, D3DXVECTOR3 *right, D3DXVECTOR3 *up, D3DXVECTOR3 *look) 
{ 
	(*right).x = (*mat)._11; 
	(*right).y = (*mat)._12; 
	(*right).z = (*mat)._13; 
 
	(*up).x = (*mat)._21; 
	(*up).y = (*mat)._22; 
	(*up).z = (*mat)._23; 
 
	(*look).x = (*mat)._31; 
	(*look).y = (*mat)._32; 
	(*look).z = (*mat)._33; 
} 
 
D3DXMATRIX* GenerateMatrix(D3DXMATRIX *mat, const D3DXVECTOR3 &right, const D3DXVECTOR3 &up,  
						   const D3DXVECTOR3 &look, const D3DXVECTOR3 &pos) 
{ 
	(*mat)._11 = right.x; 
	(*mat)._12 = right.y; 
	(*mat)._13 = right.z; 
	(*mat)._14 = 0; 
 
	(*mat)._21 = up.x; 
	(*mat)._22 = up.y; 
	(*mat)._23 = up.z; 
	(*mat)._24 = 0; 
 
	(*mat)._31 = look.x; 
	(*mat)._32 = look.y; 
	(*mat)._33 = look.z; 
	(*mat)._34 = 0; 
 
	(*mat)._41 = pos.x; 
	(*mat)._42 = pos.y; 
	(*mat)._43 = pos.z; 
	(*mat)._44 = 1; 
 
	return mat; 
} 
 
//游戏相关 
//输入法线方向,输出俯仰和翻滚角度  !!!!!!!!注意判断角度不够严谨 
VOID GetRotationAngle(const D3DXVECTOR3 &vTarget, float *fPitch, float *fRoll) 
{ 
	float x = vTarget.x; 
	float y = vTarget.y; 
	float z = vTarget.z; 
 
	if ( fabs(x) < 0.01) 
		x = 0; 
 
	if ( fabs(y) < 0.01) 
		y = 0; 
 
	if ( fabs(z) < 0.01) 
		z = 0;				//数值太小就近似等于0 
 
	float fAngle1 = 90;		//初始物体的Up方向为Y轴方向,在从X轴正方向看过来就是90度 
 
    float fAngle2;			//目标法线的俯仰角度,以Z正方向为0度 
 
    if (y == 0) 
		fAngle2 = 0; 
	else  
	{ 
		if (z == 0) 
			fAngle2 = 90; 
		else 
            fAngle2 = D3DXToDegree(atan(y / z)); 
	} 
 
	if (fAngle2 < 0) 
		fAngle2 += 180; 
 
	*fPitch = fAngle2 - fAngle1;	//两个法线的俯仰角度差 
 
	float fAngle3 = 90;				//标准的Up方向为Y轴方向,在从Z轴负方向看过来就是90度 
 
	float fAngle4;					//目标法线的翻滚角度,以X正方向为0度 
 
    if (x == 0) 
		fAngle4 = 90; 
	else  
	{ 
		if (y == 0) 
			fAngle4 = 0; 
		else 
            fAngle4 = D3DXToDegree(atan(y / x)); 
	} 
 
	if (fAngle4 < 0) 
		fAngle4 += 180; 
 
	*fRoll = fAngle4 - fAngle3; //两个法线的翻滚角度差 
}