void Transform::Scale(float sx, float sy)
{
    Transform scale;
    scale._row0[0] = sx;
    scale._row1[1] = sy;

    _Multiply(scale);
}
void Transform::Translate(float x, float y)
{
    Transform translation;
    translation._row0[3] = x;
    translation._row1[3] = y;

    _Multiply(translation);
}
void Transform::Rotate(float angle)
{
    // "cosf" and "sinf" take radians as input.
    // So, convert from degrees to radians.
    float angle_radians = vt_utils::UTILS_PI * angle / 180.0f;

    float cosa = cosf(angle_radians);
    float sina = sinf(angle_radians);

    Transform rotation;
    rotation._row0[0] = cosa;
    rotation._row0[1] = -sina;
    rotation._row1[0] = sina;
    rotation._row1[1] = cosa;

    _Multiply(rotation);
}
Beispiel #4
0
HRESULT CBoundingBox::PutData(enum BOUND_FORMAT nFormat, FWULONG nSize, /*[in, size_is(nSize)]*/ BYTE *pBuf)
{
#define BUFAABB		((struct BOUND_AABB*)pBuf)
#define BUFOBB		((struct BOUND_OBB*)pBuf)
#define BUFOBB_8	((struct BOUND_OBB_8*)pBuf)
#define BUFSPHERE	((struct BOUND_SPHERE*)pBuf)
#define BUFCYLINDER	((struct BOUND_CYLINDER*)pBuf)

	switch (nFormat)
	{
		case BOUND_FORMAT_AABB:
			if (nSize != sizeof(BOUND_AABB)) return ERROR(FW_E_FORMAT);
			m_obb.vecSize.x = fabs(BUFAABB->vecMax.x - BUFAABB->vecMin.x) * 0.5f;
			m_obb.vecSize.y = fabs(BUFAABB->vecMax.y - BUFAABB->vecMin.y) * 0.5f;
			m_obb.vecSize.z = fabs(BUFAABB->vecMax.z - BUFAABB->vecMin.z) * 0.5f;
			memset(m_obb.M, 0, sizeof(m_obb.M));
			m_obb.M[3][0] = (BUFAABB->vecMin.x + BUFAABB->vecMax.x) * 0.5f;
			m_obb.M[3][1] = (BUFAABB->vecMin.y + BUFAABB->vecMax.y) * 0.5f;
			m_obb.M[3][2] = (BUFAABB->vecMin.z + BUFAABB->vecMax.z) * 0.5f;
			m_obb.M[0][0] = m_obb.M[1][1] = m_obb.M[2][2] = m_obb.M[3][3] = 1.0f;
			break;

		case BOUND_FORMAT_OBB:
			if (nSize != sizeof(BOUND_OBB)) return ERROR(FW_E_FORMAT);
			memcpy(&m_obb, pBuf, sizeof(m_obb));
			break;

		case BOUND_FORMAT_OBB_8:
			if (nSize != sizeof(BOUND_OBB)) return ERROR(FW_E_FORMAT);
			return ERROR(FW_E_FORMAT);

		case BOUND_FORMAT_SPHERE:
			if (nSize != sizeof(BOUND_SPHERE)) return ERROR(FW_E_FORMAT);
			m_obb.vecSize.x = m_obb.vecSize.y = m_obb.vecSize.z = BUFSPHERE->fRadius;
			memset(m_obb.M, 0, sizeof(m_obb.M));
			m_obb.M[3][0] = BUFSPHERE->vecCenter.x;
			m_obb.M[3][1] = BUFSPHERE->vecCenter.y;
			m_obb.M[3][2] = BUFSPHERE->vecCenter.z;
			m_obb.M[0][0] = m_obb.M[1][1] = m_obb.M[2][2] = m_obb.M[3][3] = 1.0f;
			break;

		case BOUND_FORMAT_CYLINDER:
			if (nSize != sizeof(BOUND_CYLINDER)) return ERROR(FW_E_FORMAT);
			return ERROR(FW_E_FORMAT);

		default:
			return ERROR(FW_E_FORMAT);
	}

	ITransform *pT = NULL;
	CreateCompatibleTransform(&pT);
	HRESULT h = GetGlobalTransform(pT);
	if (FAILED(h)) return ERROR(h);
	pT->Inverse();
	FWMATRIX  M, M1;
	pT->AsMatrix(M1);
	pT->Release();
	_Multiply(M, m_obb.M, M1);
	memcpy(m_obb.M, M, sizeof(M));
	return S_OK;
}
Beispiel #5
0
HRESULT CBoundingBox::GetData(enum BOUND_FORMAT nFormat, FWULONG nSize, /*[out, size_is(nSize)]*/ BYTE *pBuf)
{
#define BUFAABB		((struct BOUND_AABB*)pBuf)
#define BUFOBB		((struct BOUND_OBB*)pBuf)
#define BUFOBB_8	((struct BOUND_OBB_8*)pBuf)
#define BUFSPHERE	((struct BOUND_SPHERE*)pBuf)
#define BUFCYLINDER	((struct BOUND_CYLINDER*)pBuf)

	FWMATRIX M, M1;
	ITransform *pT = NULL;
	CreateCompatibleTransform(&pT);
	HRESULT h = GetGlobalTransform(pT);
	if (FAILED(h)) return ERROR(h);
	pT->AsMatrix(M1);
	pT->Release();
	_Multiply(M, m_obb.M, M1);

	switch (nFormat)
	{
		case BOUND_FORMAT_AABB:
			if (nSize != sizeof(BOUND_AABB)) return ERROR(FW_E_FORMAT);
			BUFAABB->vecMin.x = -m_obb.vecSize.x;
			BUFAABB->vecMin.y = -m_obb.vecSize.y;
			BUFAABB->vecMin.z = -m_obb.vecSize.z;
			BUFAABB->vecMax.x =  m_obb.vecSize.x;
			BUFAABB->vecMax.y =  m_obb.vecSize.y;
			BUFAABB->vecMax.z =  m_obb.vecSize.z;
			_Transform(&BUFAABB->vecMin, M);
			_Transform(&BUFAABB->vecMax, M);
			break;

		case BOUND_FORMAT_OBB:
			if (nSize != sizeof(BOUND_OBB)) return ERROR(FW_E_FORMAT);
			memcpy(BUFOBB->M, M, sizeof(M));
			memcpy(&BUFOBB->vecSize, &m_obb.vecSize, sizeof(m_obb.vecSize));
			break;

		case BOUND_FORMAT_OBB_8:
			BUFOBB_8->OBB[0].x = -m_obb.vecSize.x;	BUFOBB_8->OBB[0].y = -m_obb.vecSize.y;	BUFOBB_8->OBB[0].z = -m_obb.vecSize.z;
			BUFOBB_8->OBB[1].x =  m_obb.vecSize.x;	BUFOBB_8->OBB[1].y = -m_obb.vecSize.y;	BUFOBB_8->OBB[1].z = -m_obb.vecSize.z;
			BUFOBB_8->OBB[2].x = -m_obb.vecSize.x;	BUFOBB_8->OBB[2].y = -m_obb.vecSize.y;	BUFOBB_8->OBB[2].z =  m_obb.vecSize.z;
			BUFOBB_8->OBB[3].x =  m_obb.vecSize.x;	BUFOBB_8->OBB[3].y = -m_obb.vecSize.y;	BUFOBB_8->OBB[3].z =  m_obb.vecSize.z;
			BUFOBB_8->OBB[4].x = -m_obb.vecSize.x;	BUFOBB_8->OBB[4].y =  m_obb.vecSize.y;	BUFOBB_8->OBB[4].z = -m_obb.vecSize.z;
			BUFOBB_8->OBB[5].x =  m_obb.vecSize.x;	BUFOBB_8->OBB[5].y =  m_obb.vecSize.y;	BUFOBB_8->OBB[5].z = -m_obb.vecSize.z;
			BUFOBB_8->OBB[6].x = -m_obb.vecSize.x;	BUFOBB_8->OBB[6].y =  m_obb.vecSize.y;	BUFOBB_8->OBB[6].z =  m_obb.vecSize.z;
			BUFOBB_8->OBB[7].x =  m_obb.vecSize.x;	BUFOBB_8->OBB[7].y =  m_obb.vecSize.y;	BUFOBB_8->OBB[7].z =  m_obb.vecSize.z;
			for (int i = 0; i < 8; i++)
				_Transform(BUFOBB_8->OBB + i, M);
			break;

		case BOUND_FORMAT_SPHERE:
			if (nSize != sizeof(BOUND_SPHERE)) return ERROR(FW_E_FORMAT);
			BUFSPHERE->vecCenter.x = (FWFLOAT)M[3][0];
			BUFSPHERE->vecCenter.y = (FWFLOAT)M[3][1];
			BUFSPHERE->vecCenter.z = (FWFLOAT)M[3][2];
			// _Transform not needed here (no rotation)
			BUFSPHERE->fRadius = sqrt(m_obb.vecSize.x * m_obb.vecSize.x + m_obb.vecSize.y * m_obb.vecSize.y + m_obb.vecSize.z * m_obb.vecSize.z);
			break;

		case BOUND_FORMAT_CYLINDER:
			if (nSize != sizeof(BOUND_CYLINDER)) return ERROR(FW_E_FORMAT);
			BUFCYLINDER->vecPivot1.x = BUFCYLINDER->vecPivot1.z = BUFCYLINDER->vecPivot2.x = BUFCYLINDER->vecPivot2.z = 0.0f;
			BUFCYLINDER->vecPivot1.y = -m_obb.vecSize.y;
			BUFCYLINDER->vecPivot2.y =  m_obb.vecSize.y;
			_Transform(&BUFCYLINDER->vecPivot1, M);
			_Transform(&BUFCYLINDER->vecPivot2, M);
			BUFCYLINDER->fRadius = sqrt(m_obb.vecSize.x * m_obb.vecSize.x + m_obb.vecSize.z * m_obb.vecSize.z);
			break;

		default:
			return ERROR(FW_E_FORMAT);
	}

	return S_OK;
}