374 lines
7.5 KiB
C++
374 lines
7.5 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);
|
|
}
|
|
|
|
void Model::CalculateUVPerspective()
|
|
{
|
|
for (Polygon3D& currentPolygon : _polygons)
|
|
{
|
|
|
|
for (int cpi = 0; cpi < currentPolygon.GetPolygonVertexCount(); cpi++)
|
|
{
|
|
_transformedVertices[currentPolygon.GetIndex(cpi)].UVCorrect(_uvCoords[currentPolygon.GetUVIndex(cpi)].GetU(), _uvCoords[currentPolygon.GetUVIndex(cpi)].GetV());
|
|
}
|
|
|
|
}
|
|
} |