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); }
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; }
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; }