Files
Graphics-Rasterizer/Model.cpp
IDunnoDev cdb940f6aa Week10 [30/11] - [06/12]
Added active Variable to the Lights Classes
Added updated MD2Loader Class
Added Model Filename and Texture File Name to the Model Class
Added Active Flag to the Model Class
Added DrawMode to the Model Class
Added Texture and UV Variables to the Model Class
Added UV Coordinates to the Polygon3D Class
Added DrawString method to the Rasterizer to write text to the screen space
Added Interpolate and Lerp Methods to the Rasterizer
Added Select statement for drawing a current models draw mode
Added DrawTextured Method to the Rasterizer Class
Added UVCoord Class
Added Texture Class
Added = operator to the Vector3D Class
Added UVCoord to the Vertex Class
Moved Models and Texture Files into a subfolder
Fixed issue with textures not loading properly because of the vector address problem
2021-12-11 20:31:39 +00:00

363 lines
7.1 KiB
C++

#include "Model.h"
Model::Model()
{
_kdRed = 1.0f;
_kdGreen = 1.0f;
_kdBlue = 1.0f;
_active = false;
_drawMethod = DrawMethod::Wireframe;
_modelMD2Filename = "";
_modelTextureFilename = "";
}
Model::Model(string MD2Filename, string textureFilename)
{
_kdRed = 1.0f;
_kdGreen = 1.0f;
_kdBlue = 1.0f;
_active = false;
_drawMethod = DrawMethod::Wireframe;
_modelMD2Filename = MD2Filename;
_modelTextureFilename = textureFilename;
}
Model::~Model()
{
_vertices.~vector();
_transformedVertices.~vector();
_polygons.~vector();
_pendingTransforms.~vector();
_uvCoords.~vector();
}
string Model::GetModelFilename() const
{
return _modelMD2Filename;
}
const char* Model::CGetModelFilename() const
{
return _modelMD2Filename.c_str();
}
string Model::GetTextureFilename() const
{
return _modelTextureFilename;
}
const char* Model::CGetTextureFilename() const
{
return _modelTextureFilename.c_str();
}
void Model::SetActive(bool value)
{
_active = value;
}
void Model::ToggleActive()
{
_active = !_active;
}
bool Model::GetActive() const
{
return _active;
}
void Model::SetDrawMethod(DrawMethod method)
{
_drawMethod = method;
}
DrawMethod Model::GetDrawMethod() const
{
return _drawMethod;
}
vector<Polygon3D>& Model::GetPolygons()
{
return _polygons;
}
vector<Vertex>& Model::GetVertices()
{
return _vertices;
}
vector<UVCoord>& Model::GetUVCoords()
{
return _uvCoords;
}
const vector<Matrix>& Model::GetPendingTransforms()
{
return _pendingTransforms;
}
size_t Model::GetPolygonCount()
{
return _polygons.size();
}
size_t Model::GetVerticesCount()
{
return _vertices.size();
}
size_t Model::GetUVCoordCount()
{
return _uvCoords.size();
}
size_t Model::GetPendingTransformCount()
{
return _pendingTransforms.size();
}
void Model::AddVertex(float x, float y, float z)
{
_vertices.push_back(Vertex(x, y, z));
_transformedVertices.push_back(Vertex(x, y, z));
}
void Model::AddPolygon(int index0, int index1, int index2, int uvIndex0, int uvIndex1, int uvIndex2)
{
_polygons.push_back(Polygon3D(index0, index1, index2, uvIndex0, uvIndex1, uvIndex2));
}
void Model::AddTextureUV(float u, float v)
{
_uvCoords.push_back(UVCoord(u, v));
}
void Model::EnqueueTransform(Matrix transform)
{
_pendingTransforms.push_back(transform);
}
void Model::ClearPendingTransforms()
{
_pendingTransforms.clear();
}
Texture& Model::GetTexture()
{
return _texture;
}
const Polygon3D& Model::GetPolygon(int index) const
{
return _polygons[index];
}
const Vertex& Model::GetVertex(int polygonIndex, int vertexPolygonIndex) const
{
return GetVertex(GetPolygon(polygonIndex).GetIndex(vertexPolygonIndex));
}
const Vertex& Model::GetVertex(int index) const
{
return _transformedVertices[index];
}
const UVCoord& Model::GetUVCoord(int index) const
{
return _uvCoords[index];
}
vector<Vertex> Model::GetPolygonVertexArray(int index) const
{
vector<Vertex> polygonVerticies = {};
for (int i = 0; i < GetPolygon(index).GetPolygonVertexCount(); i++)
{
polygonVerticies.push_back(GetVertex(index, i));
}
return polygonVerticies;
}
void Model::SetPolygonColor(int index, COLORREF color)
{
_polygons[index].SetColor(color);
}
void Model::SetVertexColor(int polyIndex, int vertIndex, COLORREF color)
{
_transformedVertices[GetPolygon(polyIndex).GetIndex(vertIndex)].SetColor(color);
}
void Model::SetReflectionCoefficient(float red, float green, float blue)
{
_kdRed = BoundsCheck(0.0f, 1.0f, red);
_kdGreen = BoundsCheck(0.0f, 1.0f, green);
_kdBlue = BoundsCheck(0.0f, 1.0f, blue);
}
void Model::SetReflectionCoefficient(ColRef color, float value)
{
float valueChecked = BoundsCheck(0.0f, 1.0f, value);
switch (color)
{
default:
case ColRef::Red:
_kdRed = valueChecked;
break;
case ColRef::Green:
_kdGreen = valueChecked;
break;
case ColRef::Blue:
_kdBlue = valueChecked;
break;
}
}
void Model::SetRedReflectionCoefficient(float value)
{
SetReflectionCoefficient(ColRef::Red, value);
}
void Model::SetGreenReflectionCoefficient(float value)
{
SetReflectionCoefficient(ColRef::Green, value);
}
void Model::SetBlueReflectionCoefficient(float value)
{
SetReflectionCoefficient(ColRef::Blue, value);
}
float Model::GetReflectionCoefficient(ColRef color) const
{
float result;
switch (color)
{
default:
case ColRef::Red:
result = _kdRed;
break;
case ColRef::Green:
result = _kdGreen;
break;
case ColRef::Blue:
result = _kdBlue;
break;
}
return result;
}
float Model::GetRedReflectionCoefficient() const
{
return GetReflectionCoefficient(ColRef::Red);
}
float Model::GetGreenReflectionCoefficient() const
{
return GetReflectionCoefficient(ColRef::Green);
}
float Model::GetBlueReflectionCoefficient() const
{
return GetReflectionCoefficient(ColRef::Blue);
}
void Model::ApplyTransformToLocalVertices(const Matrix& transform)
{
for (int i = 0; i < GetVerticesCount(); i++)
{
_transformedVertices[i] = transform * _vertices[i];
}
}
void Model::ApplyTransformToTransformedVertices(const Matrix& transform)
{
for (int i = 0; i < GetVerticesCount(); i++)
{
_transformedVertices[i] = transform * _transformedVertices[i];
}
}
void Model::DehomogenizeAllVertices()
{
for (Vertex& currentVertex : _transformedVertices)
{
currentVertex.Dehomogenize();
}
}
void Model::CalculateBackfaces(Camera& currentCamera)
{
for (Polygon3D& currentPolygon : _polygons)
{
Vector3D vectorA = _transformedVertices[currentPolygon.GetIndex(1)] - _transformedVertices[currentPolygon.GetIndex(0)];
Vector3D vectorB = _transformedVertices[currentPolygon.GetIndex(2)] - _transformedVertices[currentPolygon.GetIndex(0)];
currentPolygon.SetNormal(Vector3D::CrossProduct(vectorA, vectorB));
currentPolygon.NormalizeNormal();
Vector3D eyeVector = _transformedVertices[currentPolygon.GetIndex(0)] - currentCamera.GetCameraPosition();
eyeVector.Normalize();
float dotProduct = Vector3D::DotProduct(currentPolygon.GetNormal(), eyeVector);
if (dotProduct < 0)
{
currentPolygon.SetCulled(true);
}
else
{
currentPolygon.SetCulled(false);
}
}
}
void Model::CalculateVertexNormals()
{
for (Vertex& currentVertex : _transformedVertices)
{
currentVertex.ResetNormal(true);
}
for (int pi = 0; pi < GetPolygonCount(); pi++)
{
for (int i = 0; i < _polygons[pi].GetPolygonVertexCount(); i++)
{
_transformedVertices[_polygons[pi].GetIndex(i)].SetNormal(_transformedVertices[_polygons[pi].GetIndex(i)].GetNormal() + _polygons[pi].GetNormal());
_transformedVertices[_polygons[pi].GetIndex(i)].IncrementContributeCount();
_transformedVertices[_polygons[pi].GetIndex(i)].SetUVIndex(_polygons[pi].GetUVIndex(i));
}
}
for (Vertex& currentVertex : _transformedVertices)
{
currentVertex.SetNormal(currentVertex.GetNormal() / currentVertex.GetContributeCount());
currentVertex.NormalizeNormal();
}
}
bool DepthCompare(Polygon3D& a, Polygon3D& b)
{
return a.GetDepth() > b.GetDepth();
}
void Model::Sort()
{
for (Polygon3D& currentPolygon : _polygons)
{
float zTotal = 0.0f;
for (int i = 0; i < currentPolygon.GetPolygonVertexCount(); i++)
{
zTotal += _transformedVertices[currentPolygon.GetIndex(i)].GetZ();
}
currentPolygon.SetDepth(zTotal / currentPolygon.GetPolygonVertexCount());
}
sort(_polygons.begin(), _polygons.end(), DepthCompare);
}