|
|
|
@ -7,7 +7,9 @@ using namespace olc; |
|
|
|
|
|
|
|
|
|
struct vec2d |
|
|
|
|
{ |
|
|
|
|
float u,v; |
|
|
|
|
float u=0; |
|
|
|
|
float v=0; |
|
|
|
|
float w=1; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -87,9 +89,8 @@ struct mesh |
|
|
|
|
|
|
|
|
|
tokens[nTokenCount].pop_back(); |
|
|
|
|
|
|
|
|
|
tris.push_back({ verts[stoi(tokens[0]) - 1], verts[stoi(tokens[3]) - 1], verts[stoi(tokens[6]) - 1], |
|
|
|
|
0,0,0 |
|
|
|
|
/*uvs[stoi(tokens[1]) - 1], uvs[stoi(tokens[4]) - 1], uvs[stoi(tokens[7]) - 1]*/}); |
|
|
|
|
tris.push_back({ verts[stoi(tokens[0]) - 1], verts[stoi(tokens[2]) - 1], verts[stoi(tokens[4]) - 1], |
|
|
|
|
uvs[stoi(tokens[1]) - 1], uvs[stoi(tokens[3]) - 1], uvs[stoi(tokens[5]) - 1]}); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -127,7 +128,8 @@ private: |
|
|
|
|
float fTheta=0; |
|
|
|
|
float fYaw=0; |
|
|
|
|
|
|
|
|
|
vec3d Matrix_MultiplyVector(mat4x4 &m, vec3d &i) |
|
|
|
|
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]; |
|
|
|
@ -300,18 +302,19 @@ private: |
|
|
|
|
return v; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
vec3d Vector_IntersectPlane(vec3d &plane_p, vec3d &plane_n, vec3d &lineStart, vec3d &lineEnd) |
|
|
|
|
vec3d 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); |
|
|
|
|
float t = (-plane_d - ad) / (bd - ad); |
|
|
|
|
t = (-plane_d - ad) / (bd - ad); |
|
|
|
|
vec3d lineStartToEnd = Vector_Sub(lineEnd, lineStart); |
|
|
|
|
vec3d lineToIntersect = Vector_Mul(lineStartToEnd, t); |
|
|
|
|
return Vector_Add(lineStart, lineToIntersect); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int Triangle_ClipAgainstPlane(vec3d plane_p, vec3d plane_n, triangle &in_tri, triangle &out_tri1, triangle &out_tri2) |
|
|
|
|
{ |
|
|
|
|
// Make sure plane normal is indeed normal
|
|
|
|
@ -328,18 +331,31 @@ private: |
|
|
|
|
// 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]; } |
|
|
|
|
else { outside_points[nOutsidePointCount++] = &in_tri.p[0]; } |
|
|
|
|
if (d1 >= 0) { inside_points[nInsidePointCount++] = &in_tri.p[1]; } |
|
|
|
|
else { outside_points[nOutsidePointCount++] = &in_tri.p[1]; } |
|
|
|
|
if (d2 >= 0) { inside_points[nInsidePointCount++] = &in_tri.p[2]; } |
|
|
|
|
else { outside_points[nOutsidePointCount++] = &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
|
|
|
|
@ -368,15 +384,24 @@ private: |
|
|
|
|
// the plane, the triangle simply becomes a smaller triangle
|
|
|
|
|
|
|
|
|
|
// Copy appearance info to new triangle
|
|
|
|
|
out_tri1.col = {in_tri.col.r,in_tri.col.g,255}; //in_tri.col;
|
|
|
|
|
out_tri1.col = in_tri.col; |
|
|
|
|
|
|
|
|
|
// 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
|
|
|
|
|
out_tri1.p[1] = Vector_IntersectPlane(plane_p, plane_n, *inside_points[0], *outside_points[0]); |
|
|
|
|
out_tri1.p[2] = Vector_IntersectPlane(plane_p, plane_n, *inside_points[0], *outside_points[1]); |
|
|
|
|
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
|
|
|
|
|
} |
|
|
|
@ -388,32 +413,44 @@ private: |
|
|
|
|
// represent a quad with two new triangles
|
|
|
|
|
|
|
|
|
|
// Copy appearance info to new triangles
|
|
|
|
|
out_tri1.col = {in_tri.col.r,255,in_tri.col.b}; //in_tri.col;
|
|
|
|
|
out_tri2.col = {255,in_tri.col.g,in_tri.col.b};//in_tri.col;
|
|
|
|
|
out_tri1.col = in_tri.col; |
|
|
|
|
out_tri2.col = in_tri.col; |
|
|
|
|
|
|
|
|
|
// 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.p[2] = Vector_IntersectPlane(plane_p, plane_n, *inside_points[0], *outside_points[0]); |
|
|
|
|
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.p[2] = Vector_IntersectPlane(plane_p, plane_n, *inside_points[1], *outside_points[0]); |
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
bool OnUserCreate() override |
|
|
|
|
{ |
|
|
|
|
texture = new Decal(new Sprite("Body.png")); |
|
|
|
|
meshCube.LoadFromObjectFile("Nia.obj"); |
|
|
|
|
texture = new Decal(new Sprite("dirtblock.png")); |
|
|
|
|
meshCube.LoadFromObjectFile("cube.obj"); |
|
|
|
|
|
|
|
|
|
matProj=Matrix_MakeProjection(90.0f,(float)ScreenHeight() / (float)ScreenWidth(),0.1f,1000.0f); |
|
|
|
|
|
|
|
|
@ -477,6 +514,9 @@ public: |
|
|
|
|
triTransformed.p[0]=Matrix_MultiplyVector(matWorld,tri.p[0]); |
|
|
|
|
triTransformed.p[1]=Matrix_MultiplyVector(matWorld,tri.p[1]); |
|
|
|
|
triTransformed.p[2]=Matrix_MultiplyVector(matWorld,tri.p[2]); |
|
|
|
|
triTransformed.uv[0]=tri.uv[0]; |
|
|
|
|
triTransformed.uv[1]=tri.uv[1]; |
|
|
|
|
triTransformed.uv[2]=tri.uv[2]; |
|
|
|
|
|
|
|
|
|
vec3d normal,line1,line2; |
|
|
|
|
line1=Vector_Sub(triTransformed.p[1],triTransformed.p[0]); |
|
|
|
@ -496,7 +536,9 @@ public: |
|
|
|
|
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(255*dp*dp,255*dp*dp,255*dp*dp); |
|
|
|
|
|
|
|
|
|
int nClippedTriangles = 0; |
|
|
|
@ -509,6 +551,21 @@ public: |
|
|
|
|
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); |
|
|
|
@ -584,7 +641,7 @@ public: |
|
|
|
|
// Rasterize triangle
|
|
|
|
|
SetDecalStructure(DecalStructure::LIST); |
|
|
|
|
SetDecalMode(DecalMode::NORMAL); |
|
|
|
|
DrawPolygonDecal(nullptr,{ |
|
|
|
|
DrawPolygonDecal(texture,{ |
|
|
|
|
{t.p[0].x, t.p[0].y}, |
|
|
|
|
{t.p[1].x, t.p[1].y}, |
|
|
|
|
{t.p[2].x, t.p[2].y} |
|
|
|
@ -592,7 +649,7 @@ public: |
|
|
|
|
{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.col); |
|
|
|
|
},{{t.uv[0].w,t.uv[1].w,t.uv[2].w}},{{t.col,t.col,t.col}}); |
|
|
|
|
/*SetDecalMode(DecalMode::WIREFRAME);
|
|
|
|
|
DrawPolygonDecal(nullptr,{ |
|
|
|
|
{t.p[0].x, t.p[0].y}, |
|
|
|
@ -602,7 +659,7 @@ public: |
|
|
|
|
{0,0}, |
|
|
|
|
{0,0}, |
|
|
|
|
{0,0}, |
|
|
|
|
},BLACK);*/ |
|
|
|
|
},WHITE);*/ |
|
|
|
|
SetDecalStructure(DecalStructure::FAN); |
|
|
|
|
triRenderCount++; |
|
|
|
|
} |
|
|
|
|