diff --git a/Faceball2030/Editor.cpp b/Faceball2030/Editor.cpp
new file mode 100644
index 0000000..e69de29
diff --git a/Faceball2030/Editor.h b/Faceball2030/Editor.h
new file mode 100644
index 0000000..fdb07d5
--- /dev/null
+++ b/Faceball2030/Editor.h
@@ -0,0 +1,11 @@
+#pragma once
+#include "pixelGameEngine.h"
+using namespace olc;
+
+class Editor {
+ std::string filename;
+ vi2d MAP_SIZE;
+ void Update(float fElapsedTime) {
+
+ }
+};
\ No newline at end of file
diff --git a/Faceball2030/Faceball2030.vcxproj b/Faceball2030/Faceball2030.vcxproj
index ce74af2..88cc5d0 100644
--- a/Faceball2030/Faceball2030.vcxproj
+++ b/Faceball2030/Faceball2030.vcxproj
@@ -127,9 +127,12 @@
+
+
+
diff --git a/Faceball2030/Faceball2030.vcxproj.filters b/Faceball2030/Faceball2030.vcxproj.filters
index e77fe10..65b2820 100644
--- a/Faceball2030/Faceball2030.vcxproj.filters
+++ b/Faceball2030/Faceball2030.vcxproj.filters
@@ -18,10 +18,19 @@
Source Files
+
+ Source Files
+
Header Files
+
+ Header Files
+
+
+ Header Files
+
\ No newline at end of file
diff --git a/Faceball2030/MapFormat.txt b/Faceball2030/MapFormat.txt
new file mode 100644
index 0000000..fc4bb7a
--- /dev/null
+++ b/Faceball2030/MapFormat.txt
@@ -0,0 +1,23 @@
+
+Map Format:
+Width
+Height
+
+Width*Height 16-bit values
+
+16 bits
+ Dir
+ vv
+0000 0000 0000 0000
+^ ^ En ID^ ^^^^
+| ^^^ NESW
+| Wave 321
+Blink
+
+Armor
+Speed
+Shot
+Camo
+Stop
+Shield
+Map
\ No newline at end of file
diff --git a/Faceball2030/assets/map/map1.map b/Faceball2030/assets/map/map1.map
new file mode 100644
index 0000000..e69de29
diff --git a/Faceball2030/main.cpp b/Faceball2030/main.cpp
index 75034d9..48cefa8 100644
--- a/Faceball2030/main.cpp
+++ b/Faceball2030/main.cpp
@@ -2,857 +2,714 @@
#include "pixelGameEngine.h"
#include
#include
+#include "main.h"
using namespace olc;
-const float PI = 3.14159f;
-enum Direction {
- NORTH=1,
- EAST=2,
- SOUTH=4,
- WEST=8
-};
-
-struct vec2d
+vec3d
+FaceBall::Matrix_MultiplyVector(mat4x4& m, vec3d& i)
{
- float u = 0;
- float v = 0;
- float w = 1;
+ vec3d v;
+ v.x = i.x * m.m[0][0] + i.y * m.m[1][0] + i.z * m.m[2][0] + i.w * m.m[3][0];
+ v.y = i.x * m.m[0][1] + i.y * m.m[1][1] + i.z * m.m[2][1] + i.w * m.m[3][1];
+ v.z = i.x * m.m[0][2] + i.y * m.m[1][2] + i.z * m.m[2][2] + i.w * m.m[3][2];
+ v.w = i.x * m.m[0][3] + i.y * m.m[1][3] + i.z * m.m[2][3] + i.w * m.m[3][3];
+ return v;
};
-
-struct vec3d
+mat4x4 FaceBall::Matrix_MakeIdentity()
{
- float x = 0;
- float y = 0;
- float z = 0;
- float w = 1;
+ mat4x4 matrix;
+ matrix.m[0][0] = 1.0f;
+ matrix.m[1][1] = 1.0f;
+ matrix.m[2][2] = 1.0f;
+ matrix.m[3][3] = 1.0f;
+ return matrix;
};
-struct Triangle
+mat4x4 FaceBall::Matrix_MakeRotationX(float fAngleRad)
{
- vec3d p[3];
- vec2d uv[3];
- Pixel col;
- Decal* tex;
-};
-
-struct MapSquare {
- Decal*wallN=NULL;
- Decal* wallE=NULL;
- Decal* wallS=NULL;
- Decal* wallW=NULL;
-};
+ mat4x4 matrix;
+ matrix.m[0][0] = 1.0f;
+ matrix.m[1][1] = cosf(fAngleRad);
+ matrix.m[1][2] = sinf(fAngleRad);
+ matrix.m[2][1] = -sinf(fAngleRad);
+ matrix.m[2][2] = cosf(fAngleRad);
+ matrix.m[3][3] = 1.0f;
+ return matrix;
+}
-struct Mesh
+mat4x4 FaceBall::Matrix_MakeRotationY(float fAngleRad)
{
- std::vector tris;
- Decal* texture=NULL;
-
- Mesh() {}
-
- Mesh(std::string filename,Decal*tex)
- :texture(tex){
- LoadFromObjectFile(filename);
- }
-
- private:
- void Parse(std::string str, int& v, int& uv) {
- std::cout << str << "\n";
- std::stringstream s(str.substr(0, str.find("/") + 1));
- s >> v;
- str.erase(0, str.find("/") + 1);
- std::stringstream s2(str.substr(0, str.find("/") + 1));
- s2 >> uv;
- //std::cout<<" "< verts;
- std::vector uvs;
-
- std::string data;
- while (f.good()) {
- f >> data;
- if (data == "v") {
- float x, y, z;
- f >> x >> y >> z;
- verts.push_back({ x,y,z });
- std::cout<> u >> v;
- uvs.push_back({ u,1-v });
- std::cout<> t1 >> t2 >> t3;
- int v1, v2, v3, uv1, uv2, uv3;
- Parse(t1, v1, uv1);
- Parse(t2, v2, uv2);
- Parse(t3, v3, uv3);
- tris.push_back({ verts[v1 - 1],verts[v2 - 1],verts[v3 - 1],
- uvs[uv1 - 1],uvs[uv2 - 1],uvs[uv3 - 1],WHITE });
- }
-
- }
-
- return true;
- }
-
-};
+ mat4x4 matrix;
+ matrix.m[0][0] = cosf(fAngleRad);
+ matrix.m[0][2] = sinf(fAngleRad);
+ matrix.m[2][0] = -sinf(fAngleRad);
+ matrix.m[1][1] = 1.0f;
+ matrix.m[2][2] = cosf(fAngleRad);
+ matrix.m[3][3] = 1.0f;
+ return matrix;
+}
-struct Object {
- Mesh mesh;
- vf2d pos = { 0,0 };
- float rot = 0;
-};
+mat4x4 FaceBall::Matrix_MakeRotationZ(float fAngleRad)
+{
+ mat4x4 matrix;
+ matrix.m[0][0] = cosf(fAngleRad);
+ matrix.m[0][1] = sinf(fAngleRad);
+ matrix.m[1][0] = -sinf(fAngleRad);
+ matrix.m[1][1] = cosf(fAngleRad);
+ matrix.m[2][2] = 1.0f;
+ matrix.m[3][3] = 1.0f;
+ return matrix;
+}
-struct mat4x4
+mat4x4 FaceBall::Matrix_MakeTranslation(float x, float y, float z)
{
- float m[4][4] = { 0 };
-};
+ mat4x4 matrix;
+ matrix.m[0][0] = 1.0f;
+ matrix.m[1][1] = 1.0f;
+ matrix.m[2][2] = 1.0f;
+ matrix.m[3][3] = 1.0f;
+ matrix.m[3][0] = x;
+ matrix.m[3][1] = y;
+ matrix.m[3][2] = z;
+ return matrix;
+}
-class FaceBall : public PixelGameEngine
+mat4x4 FaceBall::Matrix_MakeProjection(float fFovDegrees, float fAspectRatio, float fNear, float fFar)
{
+ float fFovRad = 1.0f / tanf(fFovDegrees * 0.5f / 180.0f * 3.14159f);
+ mat4x4 matrix;
+ matrix.m[0][0] = fAspectRatio * fFovRad;
+ matrix.m[1][1] = fFovRad;
+ matrix.m[2][2] = fFar / (fFar - fNear);
+ matrix.m[3][2] = (-fFar * fNear) / (fFar - fNear);
+ matrix.m[2][3] = 1.0f;
+ matrix.m[3][3] = 0.0f;
+ return matrix;
+}
-public:
+mat4x4 FaceBall::Matrix_MultiplyMatrix(mat4x4& m1, mat4x4& m2)
+{
+ mat4x4 matrix;
+ for (int c = 0; c < 4; c++)
+ for (int r = 0; r < 4; r++)
+ matrix.m[r][c] = m1.m[r][0] * m2.m[0][c] + m1.m[r][1] * m2.m[1][c] + m1.m[r][2] * m2.m[2][c] + m1.m[r][3] * m2.m[3][c];
+ return matrix;
+}
- bool freeRoam=false;
- FaceBall()
- {
- sAppName = "3D Demo";
- }
+mat4x4 FaceBall::Matrix_PointAt(vec3d& pos, vec3d& target, vec3d& up)
+{
+ // Calculate new forward direction
+ vec3d newForward = Vector_Sub(target, pos);
+ newForward = Vector_Normalise(newForward);
+
+ // Calculate new Up direction
+ vec3d a = Vector_Mul(newForward, Vector_DotProduct(up, newForward));
+ vec3d newUp = Vector_Sub(up, a);
+ newUp = Vector_Normalise(newUp);
+
+ // New Right direction is easy, its just cross product
+ vec3d newRight = Vector_CrossProduct(newUp, newForward);
+
+ // Construct Dimensioning and Translation Matrix
+ mat4x4 matrix;
+ matrix.m[0][0] = newRight.x; matrix.m[0][1] = newRight.y; matrix.m[0][2] = newRight.z; matrix.m[0][3] = 0.0f;
+ matrix.m[1][0] = newUp.x; matrix.m[1][1] = newUp.y; matrix.m[1][2] = newUp.z; matrix.m[1][3] = 0.0f;
+ matrix.m[2][0] = newForward.x; matrix.m[2][1] = newForward.y; matrix.m[2][2] = newForward.z; matrix.m[2][3] = 0.0f;
+ matrix.m[3][0] = pos.x; matrix.m[3][1] = pos.y; matrix.m[3][2] = pos.z; matrix.m[3][3] = 1.0f;
+ return matrix;
+}
-private:
- Mesh mapMesh;
- mat4x4 matProj;
+mat4x4 FaceBall::Matrix_QuickInverse(mat4x4& m) // Only for Rotation/Translation Matrices
+{
+ mat4x4 matrix;
+ matrix.m[0][0] = m.m[0][0]; matrix.m[0][1] = m.m[1][0]; matrix.m[0][2] = m.m[2][0]; matrix.m[0][3] = 0.0f;
+ matrix.m[1][0] = m.m[0][1]; matrix.m[1][1] = m.m[1][1]; matrix.m[1][2] = m.m[2][1]; matrix.m[1][3] = 0.0f;
+ matrix.m[2][0] = m.m[0][2]; matrix.m[2][1] = m.m[1][2]; matrix.m[2][2] = m.m[2][2]; matrix.m[2][3] = 0.0f;
+ matrix.m[3][0] = -(m.m[3][0] * matrix.m[0][0] + m.m[3][1] * matrix.m[1][0] + m.m[3][2] * matrix.m[2][0]);
+ matrix.m[3][1] = -(m.m[3][0] * matrix.m[0][1] + m.m[3][1] * matrix.m[1][1] + m.m[3][2] * matrix.m[2][1]);
+ matrix.m[3][2] = -(m.m[3][0] * matrix.m[0][2] + m.m[3][1] * matrix.m[1][2] + m.m[3][2] * matrix.m[2][2]);
+ matrix.m[3][3] = 1.0f;
+ return matrix;
+}
- vec3d vCamera = { 5,0.5,5 };
- vec3d vLookDir;
+vec3d FaceBall::Vector_Add(vec3d& v1, vec3d& v2)
+{
+ return { v1.x + v2.x, v1.y + v2.y, v1.z + v2.z };
+}
- float zOffset = 2;
+vec3d FaceBall::Vector_Sub(vec3d& v1, vec3d& v2)
+{
+ return { v1.x - v2.x, v1.y - v2.y, v1.z - v2.z };
+}
- float fTheta = 0;
- float fYaw = 0;
- float pitch = -PI / 6;
+vec3d FaceBall::Vector_Mul(vec3d& v1, float k)
+{
+ return { v1.x * k, v1.y * k, v1.z * k };
+}
- vec3d
- Matrix_MultiplyVector(mat4x4& m, vec3d& i)
- {
- vec3d v;
- v.x = i.x * m.m[0][0] + i.y * m.m[1][0] + i.z * m.m[2][0] + i.w * m.m[3][0];
- v.y = i.x * m.m[0][1] + i.y * m.m[1][1] + i.z * m.m[2][1] + i.w * m.m[3][1];
- v.z = i.x * m.m[0][2] + i.y * m.m[1][2] + i.z * m.m[2][2] + i.w * m.m[3][2];
- v.w = i.x * m.m[0][3] + i.y * m.m[1][3] + i.z * m.m[2][3] + i.w * m.m[3][3];
- return v;
- }
+vec3d FaceBall::Vector_Div(vec3d& v1, float k)
+{
+ return { v1.x / k, v1.y / k, v1.z / k };
+}
- mat4x4 Matrix_MakeIdentity()
- {
- mat4x4 matrix;
- matrix.m[0][0] = 1.0f;
- matrix.m[1][1] = 1.0f;
- matrix.m[2][2] = 1.0f;
- matrix.m[3][3] = 1.0f;
- return matrix;
- }
+float FaceBall::Vector_DotProduct(vec3d& v1, vec3d& v2)
+{
+ return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
+}
- mat4x4 Matrix_MakeRotationX(float fAngleRad)
- {
- mat4x4 matrix;
- matrix.m[0][0] = 1.0f;
- matrix.m[1][1] = cosf(fAngleRad);
- matrix.m[1][2] = sinf(fAngleRad);
- matrix.m[2][1] = -sinf(fAngleRad);
- matrix.m[2][2] = cosf(fAngleRad);
- matrix.m[3][3] = 1.0f;
- return matrix;
- }
+float FaceBall::Vector_Length(vec3d& v)
+{
+ return sqrtf(Vector_DotProduct(v, v));
+}
- mat4x4 Matrix_MakeRotationY(float fAngleRad)
- {
- mat4x4 matrix;
- matrix.m[0][0] = cosf(fAngleRad);
- matrix.m[0][2] = sinf(fAngleRad);
- matrix.m[2][0] = -sinf(fAngleRad);
- matrix.m[1][1] = 1.0f;
- matrix.m[2][2] = cosf(fAngleRad);
- matrix.m[3][3] = 1.0f;
- return matrix;
- }
+vec3d FaceBall::Vector_Normalise(vec3d& v)
+{
+ float l = Vector_Length(v);
+ return { v.x / l, v.y / l, v.z / l };
+}
- mat4x4 Matrix_MakeRotationZ(float fAngleRad)
- {
- mat4x4 matrix;
- matrix.m[0][0] = cosf(fAngleRad);
- matrix.m[0][1] = sinf(fAngleRad);
- matrix.m[1][0] = -sinf(fAngleRad);
- matrix.m[1][1] = cosf(fAngleRad);
- matrix.m[2][2] = 1.0f;
- matrix.m[3][3] = 1.0f;
- return matrix;
- }
+vec3d FaceBall::Vector_CrossProduct(vec3d& v1, vec3d& v2)
+{
+ vec3d v;
+ v.x = v1.y * v2.z - v1.z * v2.y;
+ v.y = v1.z * v2.x - v1.x * v2.z;
+ v.z = v1.x * v2.y - v1.y * v2.x;
+ return v;
+}
- mat4x4 Matrix_MakeTranslation(float x, float y, float z)
- {
- mat4x4 matrix;
- matrix.m[0][0] = 1.0f;
- matrix.m[1][1] = 1.0f;
- matrix.m[2][2] = 1.0f;
- matrix.m[3][3] = 1.0f;
- matrix.m[3][0] = x;
- matrix.m[3][1] = y;
- matrix.m[3][2] = z;
- return matrix;
- }
+vec3d FaceBall::Vector_IntersectPlane(vec3d& plane_p, vec3d& plane_n, vec3d& lineStart, vec3d& lineEnd, float& t)
+{
+ plane_n = Vector_Normalise(plane_n);
+ float plane_d = -Vector_DotProduct(plane_n, plane_p);
+ float ad = Vector_DotProduct(lineStart, plane_n);
+ float bd = Vector_DotProduct(lineEnd, plane_n);
+ t = (-plane_d - ad) / (bd - ad);
+ vec3d lineStartToEnd = Vector_Sub(lineEnd, lineStart);
+ vec3d lineToIntersect = Vector_Mul(lineStartToEnd, t);
+ return Vector_Add(lineStart, lineToIntersect);
+}
- mat4x4 Matrix_MakeProjection(float fFovDegrees, float fAspectRatio, float fNear, float fFar)
- {
- float fFovRad = 1.0f / tanf(fFovDegrees * 0.5f / 180.0f * 3.14159f);
- mat4x4 matrix;
- matrix.m[0][0] = fAspectRatio * fFovRad;
- matrix.m[1][1] = fFovRad;
- matrix.m[2][2] = fFar / (fFar - fNear);
- matrix.m[3][2] = (-fFar * fNear) / (fFar - fNear);
- matrix.m[2][3] = 1.0f;
- matrix.m[3][3] = 0.0f;
- return matrix;
- }
- mat4x4 Matrix_MultiplyMatrix(mat4x4& m1, mat4x4& m2)
- {
- mat4x4 matrix;
- for (int c = 0; c < 4; c++)
- for (int r = 0; r < 4; r++)
- matrix.m[r][c] = m1.m[r][0] * m2.m[0][c] + m1.m[r][1] * m2.m[1][c] + m1.m[r][2] * m2.m[2][c] + m1.m[r][3] * m2.m[3][c];
- return matrix;
- }
+int FaceBall::Triangle_ClipAgainstPlane(vec3d plane_p, vec3d plane_n, Triangle& in_tri, Triangle& out_tri1, Triangle& out_tri2)
+{
+ // Make sure plane normal is indeed normal
+ plane_n = Vector_Normalise(plane_n);
- mat4x4 Matrix_PointAt(vec3d& pos, vec3d& target, vec3d& up)
+ // Return signed shortest distance from point to plane, plane normal must be normalised
+ auto dist = [&](vec3d& p)
{
- // Calculate new forward direction
- vec3d newForward = Vector_Sub(target, pos);
- newForward = Vector_Normalise(newForward);
-
- // Calculate new Up direction
- vec3d a = Vector_Mul(newForward, Vector_DotProduct(up, newForward));
- vec3d newUp = Vector_Sub(up, a);
- newUp = Vector_Normalise(newUp);
-
- // New Right direction is easy, its just cross product
- vec3d newRight = Vector_CrossProduct(newUp, newForward);
-
- // Construct Dimensioning and Translation Matrix
- mat4x4 matrix;
- matrix.m[0][0] = newRight.x; matrix.m[0][1] = newRight.y; matrix.m[0][2] = newRight.z; matrix.m[0][3] = 0.0f;
- matrix.m[1][0] = newUp.x; matrix.m[1][1] = newUp.y; matrix.m[1][2] = newUp.z; matrix.m[1][3] = 0.0f;
- matrix.m[2][0] = newForward.x; matrix.m[2][1] = newForward.y; matrix.m[2][2] = newForward.z; matrix.m[2][3] = 0.0f;
- matrix.m[3][0] = pos.x; matrix.m[3][1] = pos.y; matrix.m[3][2] = pos.z; matrix.m[3][3] = 1.0f;
- return matrix;
-
+ vec3d n = Vector_Normalise(p);
+ return (plane_n.x * p.x + plane_n.y * p.y + plane_n.z * p.z - Vector_DotProduct(plane_n, plane_p));
+ };
+
+ // Create two temporary storage arrays to classify points either side of plane
+ // If distance sign is positive, point lies on "inside" of plane
+ vec3d* inside_points[3]; int nInsidePointCount = 0;
+ vec3d* outside_points[3]; int nOutsidePointCount = 0;
+ vec2d* inside_tex[3]; int nInsideTexCount = 0;
+ vec2d* outside_tex[3]; int nOutsideTexCount = 0;
+
+
+ // Get signed distance of each point in triangle to plane
+ float d0 = dist(in_tri.p[0]);
+ float d1 = dist(in_tri.p[1]);
+ float d2 = dist(in_tri.p[2]);
+
+ if (d0 >= 0) { inside_points[nInsidePointCount++] = &in_tri.p[0]; inside_tex[nInsideTexCount++] = &in_tri.uv[0]; }
+ else {
+ outside_points[nOutsidePointCount++] = &in_tri.p[0]; outside_tex[nOutsideTexCount++] = &in_tri.uv[0];
}
-
- mat4x4 Matrix_QuickInverse(mat4x4& m) // Only for Rotation/Translation Matrices
- {
- mat4x4 matrix;
- matrix.m[0][0] = m.m[0][0]; matrix.m[0][1] = m.m[1][0]; matrix.m[0][2] = m.m[2][0]; matrix.m[0][3] = 0.0f;
- matrix.m[1][0] = m.m[0][1]; matrix.m[1][1] = m.m[1][1]; matrix.m[1][2] = m.m[2][1]; matrix.m[1][3] = 0.0f;
- matrix.m[2][0] = m.m[0][2]; matrix.m[2][1] = m.m[1][2]; matrix.m[2][2] = m.m[2][2]; matrix.m[2][3] = 0.0f;
- matrix.m[3][0] = -(m.m[3][0] * matrix.m[0][0] + m.m[3][1] * matrix.m[1][0] + m.m[3][2] * matrix.m[2][0]);
- matrix.m[3][1] = -(m.m[3][0] * matrix.m[0][1] + m.m[3][1] * matrix.m[1][1] + m.m[3][2] * matrix.m[2][1]);
- matrix.m[3][2] = -(m.m[3][0] * matrix.m[0][2] + m.m[3][1] * matrix.m[1][2] + m.m[3][2] * matrix.m[2][2]);
- matrix.m[3][3] = 1.0f;
- return matrix;
+ if (d1 >= 0) {
+ inside_points[nInsidePointCount++] = &in_tri.p[1]; inside_tex[nInsideTexCount++] = &in_tri.uv[1];
}
-
- vec3d Vector_Add(vec3d& v1, vec3d& v2)
- {
- return { v1.x + v2.x, v1.y + v2.y, v1.z + v2.z };
+ else {
+ outside_points[nOutsidePointCount++] = &in_tri.p[1]; outside_tex[nOutsideTexCount++] = &in_tri.uv[1];
}
-
- vec3d Vector_Sub(vec3d& v1, vec3d& v2)
- {
- return { v1.x - v2.x, v1.y - v2.y, v1.z - v2.z };
+ if (d2 >= 0) {
+ inside_points[nInsidePointCount++] = &in_tri.p[2]; inside_tex[nInsideTexCount++] = &in_tri.uv[2];
}
-
- vec3d Vector_Mul(vec3d& v1, float k)
- {
- return { v1.x * k, v1.y * k, v1.z * k };
+ else {
+ outside_points[nOutsidePointCount++] = &in_tri.p[2]; outside_tex[nOutsideTexCount++] = &in_tri.uv[2];
}
- vec3d Vector_Div(vec3d& v1, float k)
- {
- return { v1.x / k, v1.y / k, v1.z / k };
- }
+ // Now classify triangle points, and break the input triangle into
+ // smaller output triangles if required. There are four possible
+ // outcomes...
- float Vector_DotProduct(vec3d& v1, vec3d& v2)
+ if (nInsidePointCount == 0)
{
- return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
- }
+ // All points lie on the outside of plane, so clip whole triangle
+ // It ceases to exist
- float Vector_Length(vec3d& v)
- {
- return sqrtf(Vector_DotProduct(v, v));
+ return 0; // No returned triangles are valid
}
- vec3d Vector_Normalise(vec3d& v)
+ if (nInsidePointCount == 3)
{
- float l = Vector_Length(v);
- return { v.x / l, v.y / l, v.z / l };
- }
+ // All points lie on the inside of plane, so do nothing
+ // and allow the triangle to simply pass through
+ out_tri1 = in_tri;
- vec3d Vector_CrossProduct(vec3d& v1, vec3d& v2)
- {
- vec3d v;
- v.x = v1.y * v2.z - v1.z * v2.y;
- v.y = v1.z * v2.x - v1.x * v2.z;
- v.z = v1.x * v2.y - v1.y * v2.x;
- return v;
+ return 1; // Just the one returned original triangle is valid
}
- vec3d Vector_IntersectPlane(vec3d& plane_p, vec3d& plane_n, vec3d& lineStart, vec3d& lineEnd, float& t)
+ if (nInsidePointCount == 1 && nOutsidePointCount == 2)
{
- plane_n = Vector_Normalise(plane_n);
- float plane_d = -Vector_DotProduct(plane_n, plane_p);
- float ad = Vector_DotProduct(lineStart, plane_n);
- float bd = Vector_DotProduct(lineEnd, plane_n);
- t = (-plane_d - ad) / (bd - ad);
- vec3d lineStartToEnd = Vector_Sub(lineEnd, lineStart);
- vec3d lineToIntersect = Vector_Mul(lineStartToEnd, t);
- return Vector_Add(lineStart, lineToIntersect);
+ // Triangle should be clipped. As two points lie outside
+ // the plane, the triangle simply becomes a smaller triangle
+
+ // Copy appearance info to new triangle
+ out_tri1.col = in_tri.col;
+ out_tri1.tex = in_tri.tex;
+
+ // The inside point is valid, so keep that...
+ out_tri1.p[0] = *inside_points[0];
+ out_tri1.uv[0] = *inside_tex[0];
+
+ // but the two new points are at the locations where the
+ // original sides of the triangle (lines) intersect with the plane
+ float t;
+ out_tri1.p[1] = Vector_IntersectPlane(plane_p, plane_n, *inside_points[0], *outside_points[0], t);
+ out_tri1.uv[1].u = t * (outside_tex[0]->u - inside_tex[0]->u) + inside_tex[0]->u;
+ out_tri1.uv[1].v = t * (outside_tex[0]->v - inside_tex[0]->v) + inside_tex[0]->v;
+ out_tri1.uv[1].w = t * (outside_tex[0]->w - inside_tex[0]->w) + inside_tex[0]->w;
+
+ out_tri1.p[2] = Vector_IntersectPlane(plane_p, plane_n, *inside_points[0], *outside_points[1], t);
+ out_tri1.uv[2].u = t * (outside_tex[1]->u - inside_tex[0]->u) + inside_tex[0]->u;
+ out_tri1.uv[2].v = t * (outside_tex[1]->v - inside_tex[0]->v) + inside_tex[0]->v;
+ out_tri1.uv[2].w = t * (outside_tex[1]->w - inside_tex[0]->w) + inside_tex[0]->w;
+
+ return 1; // Return the newly formed single triangle
}
-
- int Triangle_ClipAgainstPlane(vec3d plane_p, vec3d plane_n, Triangle& in_tri, Triangle& out_tri1, Triangle& out_tri2)
+ if (nInsidePointCount == 2 && nOutsidePointCount == 1)
{
- // Make sure plane normal is indeed normal
- plane_n = Vector_Normalise(plane_n);
-
- // Return signed shortest distance from point to plane, plane normal must be normalised
- auto dist = [&](vec3d& p)
- {
- vec3d n = Vector_Normalise(p);
- return (plane_n.x * p.x + plane_n.y * p.y + plane_n.z * p.z - Vector_DotProduct(plane_n, plane_p));
- };
-
- // Create two temporary storage arrays to classify points either side of plane
- // If distance sign is positive, point lies on "inside" of plane
- vec3d* inside_points[3]; int nInsidePointCount = 0;
- vec3d* outside_points[3]; int nOutsidePointCount = 0;
- vec2d* inside_tex[3]; int nInsideTexCount = 0;
- vec2d* outside_tex[3]; int nOutsideTexCount = 0;
-
-
- // Get signed distance of each point in triangle to plane
- float d0 = dist(in_tri.p[0]);
- float d1 = dist(in_tri.p[1]);
- float d2 = dist(in_tri.p[2]);
-
- if (d0 >= 0) { inside_points[nInsidePointCount++] = &in_tri.p[0]; inside_tex[nInsideTexCount++] = &in_tri.uv[0]; }
- else {
- outside_points[nOutsidePointCount++] = &in_tri.p[0]; outside_tex[nOutsideTexCount++] = &in_tri.uv[0];
- }
- if (d1 >= 0) {
- inside_points[nInsidePointCount++] = &in_tri.p[1]; inside_tex[nInsideTexCount++] = &in_tri.uv[1];
- }
- else {
- outside_points[nOutsidePointCount++] = &in_tri.p[1]; outside_tex[nOutsideTexCount++] = &in_tri.uv[1];
- }
- if (d2 >= 0) {
- inside_points[nInsidePointCount++] = &in_tri.p[2]; inside_tex[nInsideTexCount++] = &in_tri.uv[2];
- }
- else {
- outside_points[nOutsidePointCount++] = &in_tri.p[2]; outside_tex[nOutsideTexCount++] = &in_tri.uv[2];
- }
-
- // Now classify triangle points, and break the input triangle into
- // smaller output triangles if required. There are four possible
- // outcomes...
-
- if (nInsidePointCount == 0)
- {
- // All points lie on the outside of plane, so clip whole triangle
- // It ceases to exist
-
- return 0; // No returned triangles are valid
- }
-
- if (nInsidePointCount == 3)
- {
- // All points lie on the inside of plane, so do nothing
- // and allow the triangle to simply pass through
- out_tri1 = in_tri;
-
- return 1; // Just the one returned original triangle is valid
- }
-
- if (nInsidePointCount == 1 && nOutsidePointCount == 2)
- {
- // Triangle should be clipped. As two points lie outside
- // the plane, the triangle simply becomes a smaller triangle
-
- // Copy appearance info to new triangle
- out_tri1.col = in_tri.col;
- out_tri1.tex = in_tri.tex;
-
- // The inside point is valid, so keep that...
- out_tri1.p[0] = *inside_points[0];
- out_tri1.uv[0] = *inside_tex[0];
-
- // but the two new points are at the locations where the
- // original sides of the triangle (lines) intersect with the plane
- float t;
- out_tri1.p[1] = Vector_IntersectPlane(plane_p, plane_n, *inside_points[0], *outside_points[0], t);
- out_tri1.uv[1].u = t * (outside_tex[0]->u - inside_tex[0]->u) + inside_tex[0]->u;
- out_tri1.uv[1].v = t * (outside_tex[0]->v - inside_tex[0]->v) + inside_tex[0]->v;
- out_tri1.uv[1].w = t * (outside_tex[0]->w - inside_tex[0]->w) + inside_tex[0]->w;
-
- out_tri1.p[2] = Vector_IntersectPlane(plane_p, plane_n, *inside_points[0], *outside_points[1], t);
- out_tri1.uv[2].u = t * (outside_tex[1]->u - inside_tex[0]->u) + inside_tex[0]->u;
- out_tri1.uv[2].v = t * (outside_tex[1]->v - inside_tex[0]->v) + inside_tex[0]->v;
- out_tri1.uv[2].w = t * (outside_tex[1]->w - inside_tex[0]->w) + inside_tex[0]->w;
-
- return 1; // Return the newly formed single triangle
- }
-
- if (nInsidePointCount == 2 && nOutsidePointCount == 1)
- {
- // Triangle should be clipped. As two points lie inside the plane,
- // the clipped triangle becomes a "quad". Fortunately, we can
- // represent a quad with two new triangles
-
- // Copy appearance info to new triangles
- out_tri1.col = in_tri.col;
- out_tri2.col = in_tri.col;
- out_tri1.tex = in_tri.tex;
- out_tri2.tex = in_tri.tex;
-
- // The first triangle consists of the two inside points and a new
- // point determined by the location where one side of the triangle
- // intersects with the plane
- out_tri1.p[0] = *inside_points[0];
- out_tri1.p[1] = *inside_points[1];
- out_tri1.uv[0] = *inside_tex[0];
- out_tri1.uv[1] = *inside_tex[1];
-
- float t;
- out_tri1.p[2] = Vector_IntersectPlane(plane_p, plane_n, *inside_points[0], *outside_points[0], t);
- out_tri1.uv[2].u = t * (outside_tex[0]->u - inside_tex[0]->u) + inside_tex[0]->u;
- out_tri1.uv[2].v = t * (outside_tex[0]->v - inside_tex[0]->v) + inside_tex[0]->v;
- out_tri1.uv[2].w = t * (outside_tex[0]->w - inside_tex[0]->w) + inside_tex[0]->w;
-
- // The second triangle is composed of one of he inside points, a
- // new point determined by the intersection of the other side of the
- // triangle and the plane, and the newly created point above
- out_tri2.p[0] = *inside_points[1];
- out_tri2.uv[0] = *inside_tex[1];
- out_tri2.p[1] = out_tri1.p[2];
- out_tri2.uv[1] = out_tri1.uv[2];
- out_tri2.p[2] = Vector_IntersectPlane(plane_p, plane_n, *inside_points[1], *outside_points[0], t);
- out_tri2.uv[2].u = t * (outside_tex[0]->u - inside_tex[1]->u) + inside_tex[1]->u;
- out_tri2.uv[2].v = t * (outside_tex[0]->v - inside_tex[1]->v) + inside_tex[1]->v;
- out_tri2.uv[2].w = t * (outside_tex[0]->w - inside_tex[1]->w) + inside_tex[1]->w;
- return 2; // Return two newly formed triangles which form a quad
- }
+ // Triangle should be clipped. As two points lie inside the plane,
+ // the clipped triangle becomes a "quad". Fortunately, we can
+ // represent a quad with two new triangles
+
+ // Copy appearance info to new triangles
+ out_tri1.col = in_tri.col;
+ out_tri2.col = in_tri.col;
+ out_tri1.tex = in_tri.tex;
+ out_tri2.tex = in_tri.tex;
+
+ // The first triangle consists of the two inside points and a new
+ // point determined by the location where one side of the triangle
+ // intersects with the plane
+ out_tri1.p[0] = *inside_points[0];
+ out_tri1.p[1] = *inside_points[1];
+ out_tri1.uv[0] = *inside_tex[0];
+ out_tri1.uv[1] = *inside_tex[1];
+
+ float t;
+ out_tri1.p[2] = Vector_IntersectPlane(plane_p, plane_n, *inside_points[0], *outside_points[0], t);
+ out_tri1.uv[2].u = t * (outside_tex[0]->u - inside_tex[0]->u) + inside_tex[0]->u;
+ out_tri1.uv[2].v = t * (outside_tex[0]->v - inside_tex[0]->v) + inside_tex[0]->v;
+ out_tri1.uv[2].w = t * (outside_tex[0]->w - inside_tex[0]->w) + inside_tex[0]->w;
+
+ // The second triangle is composed of one of he inside points, a
+ // new point determined by the intersection of the other side of the
+ // triangle and the plane, and the newly created point above
+ out_tri2.p[0] = *inside_points[1];
+ out_tri2.uv[0] = *inside_tex[1];
+ out_tri2.p[1] = out_tri1.p[2];
+ out_tri2.uv[1] = out_tri1.uv[2];
+ out_tri2.p[2] = Vector_IntersectPlane(plane_p, plane_n, *inside_points[1], *outside_points[0], t);
+ out_tri2.uv[2].u = t * (outside_tex[0]->u - inside_tex[1]->u) + inside_tex[1]->u;
+ out_tri2.uv[2].v = t * (outside_tex[0]->v - inside_tex[1]->v) + inside_tex[1]->v;
+ out_tri2.uv[2].w = t * (outside_tex[0]->w - inside_tex[1]->w) + inside_tex[1]->w;
+ return 2; // Return two newly formed triangles which form a quad
}
+}
- void RenderWorld() {
- // Set up rotation matrices
- mat4x4 matRotZ, matRotX, matWorld;
-
- matRotZ = Matrix_MakeRotationZ(fTheta * 0.5f);
- matRotX = Matrix_MakeRotationX(fTheta);
-
- //matTrans = Matrix_MakeTranslation(0.0f, 0.0f, 0.0f);
- matWorld = Matrix_MakeIdentity();
- matWorld = Matrix_MultiplyMatrix(matRotZ, matRotX);
- //matWorld = Matrix_MultiplyMatrix(matWorld, matTrans);
-
- vec3d vUp = { 0,1,0 };
- vec3d vTarget = { 0,sinf(pitch),cosf(pitch) };
- mat4x4 matCameraRot = Matrix_MakeRotationY(fYaw);
- vLookDir = Matrix_MultiplyVector(matCameraRot, vTarget);
- vTarget = Vector_Add(vCamera, vLookDir);
- mat4x4 matCamera = Matrix_PointAt(vCamera, vTarget, vUp);
- mat4x4 matView = Matrix_QuickInverse(matCamera);
-
- std::vectorvecTrianglesToRaster;
-
- // Draw Triangles
- for (auto& obj : objects) {
- for (auto& tri : obj.mesh.tris){
- Triangle triProjected, triTransformed, triViewed;
- //mat4x4 matTrans = Matrix_MakeTranslation(-mesh.size.x/2, 0, -mesh.size.x/2);
- mat4x4 localMat = Matrix_MakeIdentity();
- //localMat = Matrix_MultiplyMatrix(localMat, matTrans);
- mat4x4 rotMat = Matrix_MakeRotationY(obj.rot);
- localMat = Matrix_MultiplyMatrix(localMat, rotMat);
- mat4x4 matTrans = Matrix_MakeTranslation(obj.pos.x, 0, obj.pos.y);
- localMat = Matrix_MultiplyMatrix(localMat, matTrans);
-
- triTransformed.p[0] = Matrix_MultiplyVector(localMat, tri.p[0]);
- triTransformed.p[1] = Matrix_MultiplyVector(localMat, tri.p[1]);
- triTransformed.p[2] = Matrix_MultiplyVector(localMat, tri.p[2]);
- triTransformed.uv[0] = tri.uv[0];
- triTransformed.uv[1] = tri.uv[1];
- triTransformed.uv[2] = tri.uv[2];
- triTransformed.col = tri.col;
-
- vec3d normal, line1, line2;
- line1 = Vector_Sub(triTransformed.p[1], triTransformed.p[0]);
- line2 = Vector_Sub(triTransformed.p[2], triTransformed.p[0]);
-
- normal = Vector_CrossProduct(line1, line2);
- normal = Vector_Normalise(normal);
-
- vec3d vCameraRay = Vector_Sub(triTransformed.p[0], vCamera);
-
- if (Vector_DotProduct(normal, vCameraRay) < 0) {
- vec3d light_dir = Vector_Mul(vLookDir, -1);
- light_dir = Vector_Normalise(light_dir);
-
- float dp = std::max(0.7f, Vector_DotProduct(light_dir, normal));
-
- triViewed.p[0] = Matrix_MultiplyVector(matView, triTransformed.p[0]);
- triViewed.p[1] = Matrix_MultiplyVector(matView, triTransformed.p[1]);
- triViewed.p[2] = Matrix_MultiplyVector(matView, triTransformed.p[2]);
- triViewed.uv[0] = triTransformed.uv[0];
- triViewed.uv[1] = triTransformed.uv[1];
- triViewed.uv[2] = triTransformed.uv[2];
- triViewed.col = Pixel(triTransformed.col.r * dp * dp, triTransformed.col.g * dp * dp, triTransformed.col.b * dp * dp);
-
- int nClippedTriangles = 0;
- Triangle clipped[2];
- nClippedTriangles = Triangle_ClipAgainstPlane({ 0.0f, 0.0f, 0.1f }, { 0.0f, 0.0f, 1.0f }, triViewed, clipped[0], clipped[1]);
-
- for (int n = 0; n < nClippedTriangles; n++) {
- // Project triangles from 3D --> 2D
- triProjected.p[0] = Matrix_MultiplyVector(matProj, clipped[n].p[0]);
- triProjected.p[1] = Matrix_MultiplyVector(matProj, clipped[n].p[1]);
- triProjected.p[2] = Matrix_MultiplyVector(matProj, clipped[n].p[2]);
- triProjected.col = clipped[n].col;
- triProjected.uv[0] = clipped[n].uv[0];
- triProjected.uv[1] = clipped[n].uv[1];
- triProjected.uv[2] = clipped[n].uv[2];
- triProjected.uv[0].u = triProjected.uv[0].u / triProjected.p[0].w;
- triProjected.uv[1].u = triProjected.uv[1].u / triProjected.p[1].w;
- triProjected.uv[2].u = triProjected.uv[2].u / triProjected.p[2].w;
-
- triProjected.uv[0].v = triProjected.uv[0].v / triProjected.p[0].w;
- triProjected.uv[1].v = triProjected.uv[1].v / triProjected.p[1].w;
- triProjected.uv[2].v = triProjected.uv[2].v / triProjected.p[2].w;
-
- triProjected.uv[0].w = 1.0f / triProjected.p[0].w;
- triProjected.uv[1].w = 1.0f / triProjected.p[1].w;
- triProjected.uv[2].w = 1.0f / triProjected.p[2].w;
-
-
- triProjected.p[0] = Vector_Div(triProjected.p[0], triProjected.p[0].w);
- triProjected.p[1] = Vector_Div(triProjected.p[1], triProjected.p[1].w);
- triProjected.p[2] = Vector_Div(triProjected.p[2], triProjected.p[2].w);
-
- triProjected.p[0].x *= -1.0f;
- triProjected.p[1].x *= -1.0f;
- triProjected.p[2].x *= -1.0f;
- triProjected.p[0].y *= -1.0f;
- triProjected.p[1].y *= -1.0f;
- triProjected.p[2].y *= -1.0f;
-
- // Scale into view
- vec3d vOffsetView = { 1,1,0 };
- triProjected.p[0] = Vector_Add(triProjected.p[0], vOffsetView);
- triProjected.p[1] = Vector_Add(triProjected.p[1], vOffsetView);
- triProjected.p[2] = Vector_Add(triProjected.p[2], vOffsetView);
- triProjected.p[0].x *= 0.5f * (float)ScreenWidth();
- triProjected.p[0].y *= 0.5f * (float)ScreenHeight();
- triProjected.p[1].x *= 0.5f * (float)ScreenWidth();
- triProjected.p[1].y *= 0.5f * (float)ScreenHeight();
- triProjected.p[2].x *= 0.5f * (float)ScreenWidth();
- triProjected.p[2].y *= 0.5f * (float)ScreenHeight();
- triProjected.tex = obj.mesh.texture;
-
- vecTrianglesToRaster.push_back(triProjected);
- }
+void FaceBall::RenderWorld() {
+ // Set up rotation matrices
+ mat4x4 matRotZ, matRotX, matWorld;
+
+ matRotZ = Matrix_MakeRotationZ(fTheta * 0.5f);
+ matRotX = Matrix_MakeRotationX(fTheta);
+
+ //matTrans = Matrix_MakeTranslation(0.0f, 0.0f, 0.0f);
+ matWorld = Matrix_MakeIdentity();
+ matWorld = Matrix_MultiplyMatrix(matRotZ, matRotX);
+ //matWorld = Matrix_MultiplyMatrix(matWorld, matTrans);
+
+ vec3d vUp = { 0,1,0 };
+ vec3d vTarget = { 0,sinf(pitch),cosf(pitch) };
+ mat4x4 matCameraRot = Matrix_MakeRotationY(fYaw);
+ vLookDir = Matrix_MultiplyVector(matCameraRot, vTarget);
+ vTarget = Vector_Add(vCamera, vLookDir);
+ mat4x4 matCamera = Matrix_PointAt(vCamera, vTarget, vUp);
+ mat4x4 matView = Matrix_QuickInverse(matCamera);
+
+ std::vectorvecTrianglesToRaster;
+
+ // Draw Triangles
+ for (auto& obj : objects) {
+ for (auto& tri : obj.mesh.tris) {
+ Triangle triProjected, triTransformed, triViewed;
+ //mat4x4 matTrans = Matrix_MakeTranslation(-mesh.size.x/2, 0, -mesh.size.x/2);
+ mat4x4 localMat = Matrix_MakeIdentity();
+ //localMat = Matrix_MultiplyMatrix(localMat, matTrans);
+ mat4x4 rotMat = Matrix_MakeRotationY(obj.rot);
+ localMat = Matrix_MultiplyMatrix(localMat, rotMat);
+ mat4x4 matTrans = Matrix_MakeTranslation(obj.pos.x, 0, obj.pos.y);
+ localMat = Matrix_MultiplyMatrix(localMat, matTrans);
+
+ triTransformed.p[0] = Matrix_MultiplyVector(localMat, tri.p[0]);
+ triTransformed.p[1] = Matrix_MultiplyVector(localMat, tri.p[1]);
+ triTransformed.p[2] = Matrix_MultiplyVector(localMat, tri.p[2]);
+ triTransformed.uv[0] = tri.uv[0];
+ triTransformed.uv[1] = tri.uv[1];
+ triTransformed.uv[2] = tri.uv[2];
+ triTransformed.col = tri.col;
+
+ vec3d normal, line1, line2;
+ line1 = Vector_Sub(triTransformed.p[1], triTransformed.p[0]);
+ line2 = Vector_Sub(triTransformed.p[2], triTransformed.p[0]);
+
+ normal = Vector_CrossProduct(line1, line2);
+ normal = Vector_Normalise(normal);
+
+ vec3d vCameraRay = Vector_Sub(triTransformed.p[0], vCamera);
+
+ if (Vector_DotProduct(normal, vCameraRay) < 0) {
+ vec3d light_dir = Vector_Mul(vLookDir, -1);
+ light_dir = Vector_Normalise(light_dir);
+
+ float dp = std::max(0.7f, Vector_DotProduct(light_dir, normal));
+
+ triViewed.p[0] = Matrix_MultiplyVector(matView, triTransformed.p[0]);
+ triViewed.p[1] = Matrix_MultiplyVector(matView, triTransformed.p[1]);
+ triViewed.p[2] = Matrix_MultiplyVector(matView, triTransformed.p[2]);
+ triViewed.uv[0] = triTransformed.uv[0];
+ triViewed.uv[1] = triTransformed.uv[1];
+ triViewed.uv[2] = triTransformed.uv[2];
+ triViewed.col = Pixel(triTransformed.col.r * dp * dp, triTransformed.col.g * dp * dp, triTransformed.col.b * dp * dp);
+
+ int nClippedTriangles = 0;
+ Triangle clipped[2];
+ nClippedTriangles = Triangle_ClipAgainstPlane({ 0.0f, 0.0f, 0.1f }, { 0.0f, 0.0f, 1.0f }, triViewed, clipped[0], clipped[1]);
+
+ for (int n = 0; n < nClippedTriangles; n++) {
+ // Project triangles from 3D --> 2D
+ triProjected.p[0] = Matrix_MultiplyVector(matProj, clipped[n].p[0]);
+ triProjected.p[1] = Matrix_MultiplyVector(matProj, clipped[n].p[1]);
+ triProjected.p[2] = Matrix_MultiplyVector(matProj, clipped[n].p[2]);
+ triProjected.col = clipped[n].col;
+ triProjected.uv[0] = clipped[n].uv[0];
+ triProjected.uv[1] = clipped[n].uv[1];
+ triProjected.uv[2] = clipped[n].uv[2];
+ triProjected.uv[0].u = triProjected.uv[0].u / triProjected.p[0].w;
+ triProjected.uv[1].u = triProjected.uv[1].u / triProjected.p[1].w;
+ triProjected.uv[2].u = triProjected.uv[2].u / triProjected.p[2].w;
+
+ triProjected.uv[0].v = triProjected.uv[0].v / triProjected.p[0].w;
+ triProjected.uv[1].v = triProjected.uv[1].v / triProjected.p[1].w;
+ triProjected.uv[2].v = triProjected.uv[2].v / triProjected.p[2].w;
+
+ triProjected.uv[0].w = 1.0f / triProjected.p[0].w;
+ triProjected.uv[1].w = 1.0f / triProjected.p[1].w;
+ triProjected.uv[2].w = 1.0f / triProjected.p[2].w;
+
+
+ triProjected.p[0] = Vector_Div(triProjected.p[0], triProjected.p[0].w);
+ triProjected.p[1] = Vector_Div(triProjected.p[1], triProjected.p[1].w);
+ triProjected.p[2] = Vector_Div(triProjected.p[2], triProjected.p[2].w);
+
+ triProjected.p[0].x *= -1.0f;
+ triProjected.p[1].x *= -1.0f;
+ triProjected.p[2].x *= -1.0f;
+ triProjected.p[0].y *= -1.0f;
+ triProjected.p[1].y *= -1.0f;
+ triProjected.p[2].y *= -1.0f;
+
+ // Scale into view
+ vec3d vOffsetView = { 1,1,0 };
+ triProjected.p[0] = Vector_Add(triProjected.p[0], vOffsetView);
+ triProjected.p[1] = Vector_Add(triProjected.p[1], vOffsetView);
+ triProjected.p[2] = Vector_Add(triProjected.p[2], vOffsetView);
+ triProjected.p[0].x *= 0.5f * (float)ScreenWidth();
+ triProjected.p[0].y *= 0.5f * (float)ScreenHeight();
+ triProjected.p[1].x *= 0.5f * (float)ScreenWidth();
+ triProjected.p[1].y *= 0.5f * (float)ScreenHeight();
+ triProjected.p[2].x *= 0.5f * (float)ScreenWidth();
+ triProjected.p[2].y *= 0.5f * (float)ScreenHeight();
+ triProjected.tex = obj.mesh.texture;
+
+ vecTrianglesToRaster.push_back(triProjected);
}
}
}
+ }
- //std::sort(vecTrianglesToRaster.begin(),vecTrianglesToRaster.end(),[](triangle&t1,triangle&t2){return (t1.p[0].z+t1.p[1].z+t1.p[2].z)/3.0f>(t2.p[0].z+t2.p[1].z+t2.p[2].z)/3.0f;});
- ClearBuffer(BLACK, true);
- int triRenderCount = 0;
- for (auto& triToRaster : vecTrianglesToRaster) {
+ //std::sort(vecTrianglesToRaster.begin(),vecTrianglesToRaster.end(),[](triangle&t1,triangle&t2){return (t1.p[0].z+t1.p[1].z+t1.p[2].z)/3.0f>(t2.p[0].z+t2.p[1].z+t2.p[2].z)/3.0f;});
+ ClearBuffer(BLACK, true);
+ int triRenderCount = 0;
+ for (auto& triToRaster : vecTrianglesToRaster) {
- Triangle clipped[2];
- std::listlistTriangles;
- listTriangles.push_back(triToRaster);
- int nNewTriangles = 1;
+ Triangle clipped[2];
+ std::listlistTriangles;
+ listTriangles.push_back(triToRaster);
+ int nNewTriangles = 1;
- for (int p = 0; p < 4; p++)
+ for (int p = 0; p < 4; p++)
+ {
+ int nTrisToAdd = 0;
+ while (nNewTriangles > 0)
{
- int nTrisToAdd = 0;
- while (nNewTriangles > 0)
+ // Take triangle from front of queue
+ Triangle test = listTriangles.front();
+ listTriangles.pop_front();
+ nNewTriangles--;
+
+ // Clip it against a plane. We only need to test each
+ // subsequent plane, against subsequent new triangles
+ // as all triangles after a plane clip are guaranteed
+ // to lie on the inside of the plane. I like how this
+ // comment is almost completely and utterly justified
+ switch (p)
{
- // Take triangle from front of queue
- Triangle test = listTriangles.front();
- listTriangles.pop_front();
- nNewTriangles--;
-
- // Clip it against a plane. We only need to test each
- // subsequent plane, against subsequent new triangles
- // as all triangles after a plane clip are guaranteed
- // to lie on the inside of the plane. I like how this
- // comment is almost completely and utterly justified
- switch (p)
- {
- case 0: nTrisToAdd = Triangle_ClipAgainstPlane({ 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, test, clipped[0], clipped[1]); break;
- case 1: nTrisToAdd = Triangle_ClipAgainstPlane({ 0.0f, (float)ScreenHeight() - 1, 0.0f }, { 0.0f, -1.0f, 0.0f }, test, clipped[0], clipped[1]); break;
- case 2: nTrisToAdd = Triangle_ClipAgainstPlane({ 0.0f, 0.0f, 0.0f }, { 1.0f, 0.0f, 0.0f }, test, clipped[0], clipped[1]); break;
- case 3: nTrisToAdd = Triangle_ClipAgainstPlane({ (float)ScreenWidth() - 1, 0.0f, 0.0f }, { -1.0f, 0.0f, 0.0f }, test, clipped[0], clipped[1]); break;
- }
-
- // Clipping may yield a variable number of triangles, so
- // add these new ones to the back of the queue for subsequent
- // clipping against next planes
- for (int w = 0; w < nTrisToAdd; w++)
- listTriangles.push_back(clipped[w]);
+ case 0: nTrisToAdd = Triangle_ClipAgainstPlane({ 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, test, clipped[0], clipped[1]); break;
+ case 1: nTrisToAdd = Triangle_ClipAgainstPlane({ 0.0f, (float)ScreenHeight() - 1, 0.0f }, { 0.0f, -1.0f, 0.0f }, test, clipped[0], clipped[1]); break;
+ case 2: nTrisToAdd = Triangle_ClipAgainstPlane({ 0.0f, 0.0f, 0.0f }, { 1.0f, 0.0f, 0.0f }, test, clipped[0], clipped[1]); break;
+ case 3: nTrisToAdd = Triangle_ClipAgainstPlane({ (float)ScreenWidth() - 1, 0.0f, 0.0f }, { -1.0f, 0.0f, 0.0f }, test, clipped[0], clipped[1]); break;
}
- nNewTriangles = listTriangles.size();
- }
- std::mapcoords;
-
- for (auto& t : listTriangles) {
- // Rasterize triangle
- SetDecalStructure(DecalStructure::LIST);
- SetDecalMode(DecalMode::NORMAL);
- DrawPolygonDecal(t.tex, {
- {t.p[0].x, t.p[0].y},
- {t.p[1].x, t.p[1].y},
- {t.p[2].x, t.p[2].y}
- }, {
- {t.uv[0].u,t.uv[0].v},
- {t.uv[1].u,t.uv[1].v},
- {t.uv[2].u,t.uv[2].v},
- }, { t.uv[0].w,t.uv[1].w,t.uv[2].w }, { t.p[0].z,t.p[1].z,t.p[2].z }, { t.col,t.col,t.col });
- /*SetDecalMode(DecalMode::WIREFRAME);
- DrawPolygonDecal(nullptr,{
- {t.p[0].x, t.p[0].y},
- {t.p[1].x, t.p[1].y},
- {t.p[2].x, t.p[2].y}
- },{
- {0,0},
- {0,0},
- {0,0},
- }, { t.uv[0].w,t.uv[1].w,t.uv[2].w }, { t.p[0].z,t.p[1].z,t.p[2].z }, { BLACK,BLACK,BLACK });*/
- SetDecalStructure(DecalStructure::FAN);
- triRenderCount++;
+ // Clipping may yield a variable number of triangles, so
+ // add these new ones to the back of the queue for subsequent
+ // clipping against next planes
+ for (int w = 0; w < nTrisToAdd; w++)
+ listTriangles.push_back(clipped[w]);
}
+ nNewTriangles = listTriangles.size();
+ }
- for (const auto&key:coords){
- vf2d coord = key.first;
- vf2d val = key.second;
- DrawStringDecal({ coord.x,coord.y }, val.str());
- }
+ std::mapcoords;
+
+ for (auto& t : listTriangles) {
+ // Rasterize triangle
+ SetDecalStructure(DecalStructure::LIST);
+ SetDecalMode(DecalMode::NORMAL);
+ DrawPolygonDecal(t.tex, {
+ {t.p[0].x, t.p[0].y},
+ {t.p[1].x, t.p[1].y},
+ {t.p[2].x, t.p[2].y}
+ }, {
+ {t.uv[0].u,t.uv[0].v},
+ {t.uv[1].u,t.uv[1].v},
+ {t.uv[2].u,t.uv[2].v},
+ }, { t.uv[0].w,t.uv[1].w,t.uv[2].w }, { t.p[0].z,t.p[1].z,t.p[2].z }, { t.col,t.col,t.col });
+ /*SetDecalMode(DecalMode::WIREFRAME);
+ DrawPolygonDecal(nullptr,{
+ {t.p[0].x, t.p[0].y},
+ {t.p[1].x, t.p[1].y},
+ {t.p[2].x, t.p[2].y}
+ },{
+ {0,0},
+ {0,0},
+ {0,0},
+ }, { t.uv[0].w,t.uv[1].w,t.uv[2].w }, { t.p[0].z,t.p[1].z,t.p[2].z }, { BLACK,BLACK,BLACK });*/
+ SetDecalStructure(DecalStructure::FAN);
+ triRenderCount++;
}
- SetDecalMode(DecalMode::NORMAL);
- DrawStringDecal({ 0,0 }, "Triangles: " + std::to_string(triRenderCount), WHITE, { 2,2 });
+ for (const auto& key : coords) {
+ vf2d coord = key.first;
+ vf2d val = key.second;
+ DrawStringDecal({ coord.x,coord.y }, val.str());
+ }
}
- void HandleKeys(float fElapsedTime) {
- vec3d vForward = Vector_Mul(vLookDir, 2 * fElapsedTime);
- if (freeRoam) {
- if (GetKey(olc::DOWN).bHeld) {
- pitch -= 1 * fElapsedTime;
- }
- if (GetKey(olc::UP).bHeld) {
- pitch += 1 * fElapsedTime;
- }
- }
- else {
- pitch = 0;
- }
- if (GetKey(olc::W).bHeld) {
- vCamera = Vector_Add(vCamera, vForward);
- }
- if (GetKey(olc::S).bHeld) {
- vCamera = Vector_Sub(vCamera, vForward);
- }
- if (GetKey(olc::A).bHeld) {
- fYaw -= 2 * fElapsedTime;
- }
- if (GetKey(olc::D).bHeld) {
- fYaw += 2 * fElapsedTime;
+ SetDecalMode(DecalMode::NORMAL);
+ DrawStringDecal({ 0,0 }, "Triangles: " + std::to_string(triRenderCount), WHITE, { 2,2 });
+}
+
+void FaceBall::HandleKeys(float fElapsedTime) {
+ vec3d vForward = Vector_Mul(vLookDir, 2 * fElapsedTime);
+ if (freeRoam) {
+ if (GetKey(olc::DOWN).bHeld) {
+ pitch -= 1 * fElapsedTime;
}
- if (GetKey(olc::F1).bPressed) {
- freeRoam = !freeRoam;
+ if (GetKey(olc::UP).bHeld) {
+ pitch += 1 * fElapsedTime;
}
}
+ else {
+ pitch = 0;
+ }
+ if (GetKey(olc::W).bHeld) {
+ vCamera = Vector_Add(vCamera, vForward);
+ }
+ if (GetKey(olc::S).bHeld) {
+ vCamera = Vector_Sub(vCamera, vForward);
+ }
+ if (GetKey(olc::A).bHeld) {
+ fYaw -= 2 * fElapsedTime;
+ }
+ if (GetKey(olc::D).bHeld) {
+ fYaw += 2 * fElapsedTime;
+ }
+ if (GetKey(olc::F1).bPressed) {
+ freeRoam = !freeRoam;
+ }
+}
- void AddWall(Direction dir,vi2d gridSquare) {
- if (dir & NORTH) {
- map[gridSquare.y][gridSquare.x].wallN = dot;
- if (gridSquare.y > 0) {
- map[gridSquare.y - 1][gridSquare.x].wallS = dot;
- }
+void FaceBall::AddWall(Direction dir, vi2d gridSquare) {
+ if (dir & NORTH) {
+ map[gridSquare.y][gridSquare.x].wallN = dot;
+ if (gridSquare.y > 0) {
+ map[gridSquare.y - 1][gridSquare.x].wallS = dot;
}
- if (dir & WEST) {
- map[gridSquare.y][gridSquare.x].wallW = dot;
- if (gridSquare.x > 0) {
- map[gridSquare.y][gridSquare.x-1].wallE = dot;
- }
+ }
+ if (dir & WEST) {
+ map[gridSquare.y][gridSquare.x].wallW = dot;
+ if (gridSquare.x > 0) {
+ map[gridSquare.y][gridSquare.x - 1].wallE = dot;
}
- if (dir & SOUTH) {
- map[gridSquare.y][gridSquare.x].wallS = dot;
- if (gridSquare.y>map;
- std::vector