#include "Math.h" #include "Camera.h" Cube ::Cube(float x, float y, float z) { vertexCount = 8 ; polyCount = 12 ; position.x = x ; position.y = y ; position.z = z ; float scaler = 0.2 ; localVertices[0].x = -50 * scaler ; localVertices[0].y = 50 * scaler ; localVertices[0].z = -50 * scaler ; localVertices[0].w = 1 ; localVertices[1].x = 50 * scaler ; localVertices[1].y = 50 * scaler ; localVertices[1].z = -50 * scaler ; localVertices[1].w = 1 ; localVertices[2].x = 50 * scaler ; localVertices[2].y = -50 * scaler ; localVertices[2].z = -50 * scaler ; localVertices[2].w = 1 ; localVertices[3].x = -50 * scaler ; localVertices[3].y = -50 * scaler ; localVertices[3].z = -50 * scaler ; localVertices[3].w = 1 ; localVertices[4].x = 50 * scaler ; localVertices[4].y = 50 * scaler ; localVertices[4].z = 50 * scaler ; localVertices[4].w = 1 ; localVertices[5].x = 50 * scaler ; localVertices[5].y = -50 * scaler ; localVertices[5].z = 50 * scaler ; localVertices[5].w = 1 ; localVertices[6].x = -50 * scaler ; localVertices[6].y = -50 * scaler ; localVertices[6].z = 50 * scaler ; localVertices[6].w = 1 ; localVertices[7].x = -50 * scaler ; localVertices[7].y = 50 * scaler ; localVertices[7].z = 50 * scaler ; localVertices[7].w = 1 ; polygones[0].pVertexList = transformedVertices ; polygones[0].vertexIndexArray[0] = 0 ; polygones[0].vertexIndexArray[1] = 3 ; polygones[0].vertexIndexArray[2] = 2 ; polygones[1].pVertexList = transformedVertices ; polygones[1].vertexIndexArray[0] = 0 ; polygones[1].vertexIndexArray[1] = 2 ; polygones[1].vertexIndexArray[2] = 1 ; polygones[2].pVertexList = transformedVertices ; polygones[2].vertexIndexArray[0] = 1 ; polygones[2].vertexIndexArray[1] = 2 ; polygones[2].vertexIndexArray[2] = 5 ; polygones[3].pVertexList = transformedVertices ; polygones[3].vertexIndexArray[0] = 1 ; polygones[3].vertexIndexArray[1] = 5 ; polygones[3].vertexIndexArray[2] = 4 ; polygones[4].pVertexList = transformedVertices ; polygones[4].vertexIndexArray[0] = 4 ; polygones[4].vertexIndexArray[1] = 5 ; polygones[4].vertexIndexArray[2] = 6 ; polygones[5].pVertexList = transformedVertices ; polygones[5].vertexIndexArray[0] = 4 ; polygones[5].vertexIndexArray[1] = 6; polygones[5].vertexIndexArray[2] = 7 ; polygones[6].pVertexList = transformedVertices ; polygones[6].vertexIndexArray[0] = 7 ; polygones[6].vertexIndexArray[1] = 6 ; polygones[6].vertexIndexArray[2] = 3 ; polygones[7].pVertexList = transformedVertices ; polygones[7].vertexIndexArray[0] = 7 ; polygones[7].vertexIndexArray[1] = 3 ; polygones[7].vertexIndexArray[2] = 0 ; polygones[8].pVertexList = transformedVertices ; polygones[8].vertexIndexArray[0] = 7 ; polygones[8].vertexIndexArray[1] = 0 ; polygones[8].vertexIndexArray[2] = 1 ; polygones[9].pVertexList = transformedVertices ; polygones[9].vertexIndexArray[0] = 4 ; polygones[9].vertexIndexArray[1] = 7 ; polygones[9].vertexIndexArray[2] = 1 ; polygones[10].pVertexList = transformedVertices ; polygones[10].vertexIndexArray[0] = 3 ; polygones[10].vertexIndexArray[1] = 6 ; polygones[10].vertexIndexArray[2] = 5 ; polygones[11].pVertexList = transformedVertices ; polygones[11].vertexIndexArray[0] = 2 ; polygones[11].vertexIndexArray[1] = 3 ; polygones[11].vertexIndexArray[2] = 5 ; } void Cube ::RotateAroundX(float unit) { float sinTheta = sin(DEGREE_TO_RADIAN((unit))) ; float cosTheta = cos(DEGREE_TO_RADIAN((unit))) ; Matrix4X4 rotateAroundY = { 1, 0, 0, 0, 0, cosTheta, sinTheta, 0, 0, -sinTheta, cosTheta, 0, 0, 0, 0, 1 } ; Vector4 temp ; for (int i = 0; i < vertexCount; ++i) { VectorMultMatrix(&localVertices[i], &rotateAroundY, &temp) ; localVertices[i].x = temp.x ; localVertices[i].y = temp.y ; localVertices[i].z = temp.z ; localVertices[i].w = temp.w ; } } void Cube ::RotateAroundY(float unit) { float sinTheta = sin(DEGREE_TO_RADIAN((unit))) ; float cosTheta = cos(DEGREE_TO_RADIAN((unit))) ; Matrix4X4 rotateAroundY = { cosTheta, 0, -sinTheta, 0, 0, 1, 0, 0, sinTheta, 0, cosTheta, 0, 0, 0, 0, 1 } ; Vector4 temp ; for (int i = 0; i < vertexCount; ++i) { VectorMultMatrix(&localVertices[i], &rotateAroundY, &temp) ; localVertices[i].x = temp.x ; localVertices[i].y = temp.y ; localVertices[i].z = temp.z ; localVertices[i].w = temp.w ; } } void Cube ::RotateAroundZ(float unit) { float sinTheta = sin(DEGREE_TO_RADIAN((unit))) ; float cosTheta = cos(DEGREE_TO_RADIAN((unit))) ; Matrix4X4 rotateAroundZ = { cosTheta, sinTheta, 0, 0, -sinTheta, cosTheta, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 } ; Vector4 temp ; for (int i = 0; i < vertexCount; ++i) { VectorMultMatrix(&localVertices[i], &rotateAroundZ, &temp) ; localVertices[i].x = temp.x ; localVertices[i].y = temp.y ; localVertices[i].z = temp.z ; localVertices[i].w = temp.w ; } } void VectorPlusVector(Vector3* lhs, Vector3* rhs, Vector3* pResult) { pResult ->x = lhs ->x + rhs ->x ; pResult ->y = lhs ->y + rhs ->y ; pResult ->z = lhs ->z + rhs ->z ; } void VectorMinusVector(Vector3* endPoint, Vector3* startPoint, Vector3* pResult) { pResult ->x = endPoint ->x - startPoint ->x ; pResult ->y = endPoint ->y - startPoint ->y ; pResult ->z = endPoint ->z - startPoint ->z ; } void VectorCrossVector(Vector3* lhs, Vector3* rhs, Vector3* pResult) { pResult ->x = lhs ->y * rhs ->z - lhs ->z * rhs ->y ; pResult ->y = lhs ->z * rhs ->x - lhs ->x * rhs ->z ; pResult ->z = lhs ->x * rhs ->y - lhs ->y * rhs ->x ; } float VectorDotVector(Vector3* lhs, Vector3* rhs) { return lhs ->x * rhs ->x + lhs ->y * rhs ->y + lhs ->z * rhs ->z ; } void Vector4ToVector3(Vector4* resourcePoint, Vector3* newPoint) { newPoint ->x = resourcePoint ->x / resourcePoint ->w ; newPoint ->y = resourcePoint ->y / resourcePoint ->w ; newPoint ->z = resourcePoint ->z / resourcePoint ->w ; } void InitializeMatrix(Matrix3X3* pMatrix, float m11, float m12, float m13, float m21, float m22, float m23, float m31, float m32, float m33) { pMatrix ->m11 = m11 ; pMatrix ->m12 = m12 ; pMatrix ->m13 = m13 ; pMatrix ->m21 = m21 ; pMatrix ->m22 = m22 ; pMatrix ->m23 = m23 ; pMatrix ->m31 = m31 ; pMatrix ->m32 = m32 ; pMatrix ->m33 = m33 ; } void InitializeMatrix(Matrix4X4* pMatrix, float m11, float m12, float m13, float m14, float m21, float m22, float m23, float m24, float m31, float m32, float m33, float m34, float m41, float m42, float m43, float m44) { pMatrix ->m11 = m11 ; pMatrix ->m12 = m12 ; pMatrix ->m13 = m13 ; pMatrix ->m14 = m14 ; pMatrix ->m21 = m21 ; pMatrix ->m22 = m22 ; pMatrix ->m23 = m23 ; pMatrix ->m24 = m24 ; pMatrix ->m31 = m31 ; pMatrix ->m32 = m32 ; pMatrix ->m33 = m33 ; pMatrix ->m34 = m34 ; pMatrix ->m41 = m41 ; pMatrix ->m42 = m42 ; pMatrix ->m43 = m43 ; pMatrix ->m44 = m44 ; } void VectorMultMatrix(Vector4* point, Matrix4X4* matrix, Vector4* pResult) { for (int col = 0; col < 4; ++col) { float sum = 0 ; for (int row = 0; row < 4; ++row) sum += point ->M[row] * matrix ->M[row][col] ; pResult ->M[col] = sum ; } } void MatrixMultMatrix(Matrix4X4* lhs, Matrix4X4* rhs, Matrix4X4* pResult) { for (int row = 0; row < 4; ++row) { for (int col = 0; col < 4; ++col) { float temp = 0 ; for (int i = 0; i < 4; ++i) temp += lhs ->M[row][i] * rhs ->M[i][col] ; pResult ->M[row][col] = temp ; } } } float GetDeterminant(const Matrix4X4* pMatrix) { return pMatrix ->m11 * pMatrix ->m22 * pMatrix ->m33 * pMatrix ->m44 - pMatrix ->m11 * pMatrix ->m24 * pMatrix ->m33 * pMatrix ->m42 + pMatrix ->m12 * pMatrix ->m23 * pMatrix ->m34 * pMatrix ->m41 - pMatrix ->m12 * pMatrix ->m21 * pMatrix ->m34 * pMatrix ->m43 + pMatrix ->m13 * pMatrix ->m24 * pMatrix ->m31 * pMatrix ->m42 - pMatrix ->m13 * pMatrix ->m22 * pMatrix ->m31 * pMatrix ->m44 + pMatrix ->m14 * pMatrix ->m21 * pMatrix ->m32 * pMatrix ->m43 - pMatrix ->m14 * pMatrix ->m23 * pMatrix ->m32 * pMatrix ->m41 ; } void ScaleAccordingTo(Cube* pCube, Vector3* pAxis, float k) { Matrix4X4 matrix = { 1 + (k - 1) * pAxis ->x * pAxis ->x, (k - 1) * pAxis ->x * pAxis ->y, (k - 1) * pAxis ->x * pAxis ->z, 0, (k - 1) * pAxis ->x * pAxis ->y, 1 + (k - 1) * pAxis ->y * pAxis ->y, (k - 1) * pAxis ->y * pAxis ->z, 0, (k - 1) * pAxis ->x * pAxis ->z, (k - 1) * pAxis ->z * pAxis ->y, 1 + (k - 1) * pAxis ->z * pAxis ->z, 0, 0, 0, 0, 1 } ; for (int i = 0; i < pCube ->vertexCount; ++i) VectorMultMatrix(&pCube ->localVertices[i], &matrix, &pCube ->localVertices[i]) ; } void ModelToWorld(Cube* pCube) { for (int i = 0; i < pCube ->vertexCount; ++i) { pCube ->transformedVertices[i].x = pCube ->localVertices[i].x + pCube ->position.x ; pCube ->transformedVertices[i].y = pCube ->localVertices[i].y + pCube ->position.y ; pCube ->transformedVertices[i].z = pCube ->localVertices[i].z + pCube ->position.z ; pCube ->transformedVertices[i].w = pCube ->localVertices[i].w ; } } void RemoveBackface(PolySelfContained* polyList, int count, Vector3* pViewPortPosition) { for (int i = 0; i < count; ++i) { Vector3 point0 ; point0.x = polyList[i].vertexList[0].x ; point0.y = polyList[i].vertexList[0].y ; point0.z = polyList[i].vertexList[0].z ; Vector3 point1 ; point1.x = polyList[i].vertexList[1].x ; point1.y = polyList[i].vertexList[1].y ; point1.z = polyList[i].vertexList[1].z ; Vector3 point2 ; point2.x = polyList[i].vertexList[2].x ; point2.y = polyList[i].vertexList[2].y ; point2.z = polyList[i].vertexList[2].z ; // 1 // / // / // / // 0\ // \ // \ // \ // 2 Vector3 u ; VectorMinusVector(&point1, &point0, &u) ; Vector3 v ; VectorMinusVector(&point2, &point0, &v) ; Vector3 n ; VectorCrossVector(&v, &u, &n) ; Vector3 view ; VectorMinusVector(pViewPortPosition, &point0, &view) ; float dotValue = VectorDotVector(&n, &view) ; if (dotValue <= 0) polyList[i].removed = true ; else polyList[i].removed = false ; } } void WorldToCamera(PolySelfContained* polyList, int count, Matrix4X4* pMatrix) { Vector4 temp ; for (int i = 0; i < count; ++i) { if (polyList[i].removed) continue ; VectorMultMatrix(&polyList[i].vertexList[0], pMatrix, &temp) ; polyList[i].vertexList[0] = temp; VectorMultMatrix(&polyList[i].vertexList[1], pMatrix, &temp) ; polyList[i].vertexList[1]= temp ; VectorMultMatrix(&polyList[i].vertexList[2], pMatrix, &temp) ; polyList[i].vertexList[2] = temp ; } } void CameraToClip(PolySelfContained* polyList, int count, Matrix4X4* pMatrix) { Vector4 temp ; for (int i = 0; i < count; ++i) { if (polyList[i].removed) continue ; VectorMultMatrix(&polyList[i].vertexList[0], pMatrix, &temp) ; polyList[i].vertexList[0] = temp ; VectorMultMatrix(&polyList[i].vertexList[1], pMatrix, &temp) ; polyList[i].vertexList[1]= temp ; VectorMultMatrix(&polyList[i].vertexList[2], pMatrix, &temp) ; polyList[i].vertexList[2] = temp ; } } void ClipToPerspective(PolySelfContained* polyList, int count, float nearDistance) { for (int i = 0; i < count; ++i) { if (polyList[i].removed) continue ; float w = polyList[i].vertexList[0].w ; polyList[i].vertexList[0].x /= w ; polyList[i].vertexList[0].y /= w ; polyList[i].vertexList[0].z = nearDistance ; w = polyList[i].vertexList[1].w ; polyList[i].vertexList[1].x /= w ; polyList[i].vertexList[1].y /= w ; polyList[i].vertexList[1].z = nearDistance ; w = polyList[i].vertexList[2].w ; polyList[i].vertexList[2].x /= w ; polyList[i].vertexList[2].y /= w ; polyList[i].vertexList[2].z = nearDistance ; } } void CameraToperspective(PolySelfContained* polyList, int count, float viewPortWidth, float viewPortHeight, float fov) { float viewDistance = (viewPortWidth - 1) / 2 / tan(fov / 2) ; Matrix4X4 projectionMatrix = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1 / viewDistance, 0, 0, 0, 0 } ; Vector4 temp ; for (int i = 0; i < count; ++i) { if (polyList[i].removed) continue ; VectorMultMatrix(&polyList[i].vertexList[0], &projectionMatrix, &temp) ; polyList[i].vertexList[0] = temp ; polyList[i].vertexList[0].x /= polyList[i].vertexList[0].w ; polyList[i].vertexList[0].y /= polyList[i].vertexList[0].w ; polyList[i].vertexList[0].z /= polyList[i].vertexList[0].w ; VectorMultMatrix(&polyList[i].vertexList[1], &projectionMatrix, &temp) ; polyList[i].vertexList[1] = temp ; polyList[i].vertexList[1].x /= polyList[i].vertexList[1].w ; polyList[i].vertexList[1].y /= polyList[i].vertexList[1].w ; polyList[i].vertexList[1].z /= polyList[i].vertexList[1].w ; VectorMultMatrix(&polyList[i].vertexList[2], &projectionMatrix, &temp) ; polyList[i].vertexList[2] = temp ; polyList[i].vertexList[2].x /= polyList[i].vertexList[2].w ; polyList[i].vertexList[2].y /= polyList[i].vertexList[2].w ; polyList[i].vertexList[2].z /= polyList[i].vertexList[2].w ; } } void PerspectiveToScreen(PolySelfContained* polyList, int count, float viewPortWidth, float viewPortHeight) { Vector4 temp ; for (int i = 0; i < count; ++i) { if (polyList[i].removed) continue ; //polyList[i].vertexList[0].x = viewPortWidth * (polyList[i].vertexList[0].x + 1) / 2 ; //polyList[i].vertexList[0].y = viewPortHeight * (polyList[i].vertexList[0].y + 1) / 2 ; //polyList[i].vertexList[1].x = viewPortWidth * (polyList[i].vertexList[1].x + 1) / 2 ; //polyList[i].vertexList[1].y = viewPortHeight * (polyList[i].vertexList[1].y + 1) / 2 ; //polyList[i].vertexList[2].x = viewPortWidth * (polyList[i].vertexList[2].x + 1) / 2 ; //polyList[i].vertexList[2].y = viewPortHeight * (polyList[i].vertexList[2].y + 1) / 2 ; polyList[i].vertexList[0].x = (polyList[i].vertexList[0].x + 1) * (viewPortWidth / 2 - 0.5) ; polyList[i].vertexList[0].y = (viewPortHeight - 1) - (polyList[i].vertexList[0].y + 1) * (viewPortHeight / 2 - 0.5) ; polyList[i].vertexList[1].x = (polyList[i].vertexList[1].x + 1) * (viewPortWidth / 2 - 0.5) ; polyList[i].vertexList[1].y = (viewPortHeight - 1) - (polyList[i].vertexList[1].y + 1) * (viewPortHeight / 2 - 0.5) ; polyList[i].vertexList[2].x = (polyList[i].vertexList[2].x + 1) * (viewPortWidth / 2 - 0.5) ; polyList[i].vertexList[2].y = (viewPortHeight - 1) - (polyList[i].vertexList[2].y + 1) * (viewPortHeight / 2 - 0.5) ; //temp.x = viewPortWidth / 2 - 0.5 + polyList[i].vertexList[0].x ; //temp.y = viewPortHeight / 2 - 0.5 - polyList[i].vertexList[0].y ; //temp.z = polyList[i].vertexList[0].z ; //temp.w = polyList[i].vertexList[0].w ; //polyList[i].vertexList[0] = temp ; //temp.x = viewPortWidth / 2 - 0.5 + polyList[i].vertexList[1].x ; //temp.y = viewPortHeight / 2 - 0.5 - polyList[i].vertexList[1].y ; //temp.z = polyList[i].vertexList[1].z ; //temp.w = polyList[i].vertexList[1].w ; //polyList[i].vertexList[1] = temp ; //temp.x = viewPortWidth / 2 - 0.5 + polyList[i].vertexList[2].x ; //temp.y = viewPortHeight / 2 - 0.5 - polyList[i].vertexList[2].y ; //temp.z = polyList[i].vertexList[2].z ; //temp.w = polyList[i].vertexList[2].w ; //polyList[i].vertexList[2] = temp ; } }