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