#include "Model.h" Model::Model() { _kdRed = 1.0f; _kdGreen = 1.0f; _kdBlue = 1.0f; } Model::~Model() { } vector& Model::GetPolygons() { return _polygons; } const vector& Model::GetVertices() { return _vertices; } const vector& Model::GetPendingTransforms() { return _pendingTransforms; } size_t Model::GetPolygonCount() { return _polygons.size(); } size_t Model::GetVerticesCount() { return _vertices.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) { _polygons.push_back(Polygon3D(index0, index1, index2)); } void Model::EnqueueTransform(Matrix transform) { _pendingTransforms.push_back(transform); } void Model::ClearPendingTransforms() { _pendingTransforms.clear(); } 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]; } 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 ¤tVertex : _transformedVertices) { currentVertex.Dehomogenize(); } } void Model::CalculateBackfaces(Camera& currentCamera) { for (Polygon3D ¤tPolygon : _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)); Vector3D eyeVector = _transformedVertices[currentPolygon.GetIndex(0)] - currentCamera.GetCurrentPosition(); float dotProduct = Vector3D::DotProduct(currentPolygon.GetNormal(), eyeVector); if (dotProduct < 0) { currentPolygon.SetCulled(true); } else { currentPolygon.SetCulled(false); } } } bool DepthCompare(Polygon3D& a, Polygon3D& b) { return a.GetDepth() > b.GetDepth(); } void Model::Sort() { for (Polygon3D ¤tPolygon : _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); }