@@ -23,205 +23,6 @@ | |||
namespace lol | |||
{ | |||
//-- Face stuff | |||
void PrimitiveFace::AddPolygon(vec3 v0, vec3 v1, vec3 v2) | |||
{ | |||
vec3 vp[3] = { v0, v1, v2 }; | |||
int vi[3]; | |||
//Add vertices, if needed | |||
for (int i = 0; i < 3; ++i) | |||
{ | |||
vi[i] = FindVert(vp[i]); | |||
if (vi[i] == -1) | |||
vi[i] = AddVert(vp[i]); | |||
} | |||
//Add edges, if needed | |||
for (int j = 0; j < 3; ++j) | |||
{ | |||
bool found = false; | |||
for (int i = 0; !found && i < m_edges.Count(); ++i) | |||
{ | |||
if ((vi[j] == m_edges[i].m1 && vi[(j + 1) % 3] == m_edges[i].m2) || | |||
(vi[j] == m_edges[i].m2 && vi[(j + 1) % 3] == m_edges[i].m1)) | |||
{ | |||
found = true; | |||
m_edges[i].m3 = PrimitiveEdge::OriginalFull; | |||
} | |||
} | |||
if (!found) | |||
m_edges.Push(vi[j], vi[(j + 1) % 3], PrimitiveEdge::OriginalHalf); | |||
} | |||
} | |||
//-- | |||
void PrimitiveFace::CleanEdges() | |||
{ | |||
Array<int> vert_num; | |||
vert_num.Resize(m_vertices.Count()); | |||
//Check the vertices useage first | |||
for (int i = 0; i < m_edges.Count(); ++i) | |||
{ | |||
vert_num[EI0(i)]++; | |||
vert_num[EI1(i)]++; | |||
} | |||
//Remove the full edges | |||
for (int i = 0; i < m_edges.Count(); ++i) | |||
{ | |||
if (m_edges[i].m3 == PrimitiveEdge::OriginalFull) | |||
{ | |||
vert_num[EI0(i)] -= 1; | |||
vert_num[EI1(i)] -= 1; | |||
m_edges.Remove(i--); | |||
} | |||
} | |||
//Reorder edges | |||
for (int i = 0; i < m_edges.Count() - 1; ++i) | |||
{ | |||
int starter_i; | |||
//Find the starters | |||
for (int j = i + 1; j < m_edges.Count(); ++j) | |||
{ | |||
if (EI1(i) == EI1(j)) | |||
Swap(m_edges[j].m1, m_edges[j].m2); | |||
if (EI1(i) == EI0(j)) | |||
{ | |||
if (i + 1 != j) | |||
m_edges.Swap(i + 1, j); | |||
starter_i = i; | |||
break; | |||
} | |||
} | |||
//Change order to be ok with normal | |||
if (dot(cross(EV0(i) - EV1(i), EV1(i + 1) - EV0(i + 1)), m_normal) < 0.f) | |||
{ | |||
m_edges.Swap(i, i + 1); | |||
Swap(m_edges[i].m1, m_edges[i].m2); | |||
Swap(m_edges[i + 1].m1, m_edges[i + 1].m2); | |||
} | |||
//Go on with the sorting | |||
if (++i < m_edges.Count() - 1) | |||
{ | |||
for (int j = i + 1; j < m_edges.Count(); ++j) | |||
{ | |||
if (EI1(i) == EI1(j)) | |||
Swap(m_edges[j].m1, m_edges[j].m2); | |||
if (EI1(i) == EI0(j)) | |||
{ | |||
if (i + 1 != j) | |||
m_edges.Swap(i + 1, j); | |||
//We encountered a loop, push i toward the next potential edge | |||
if (EI1(i + 1) == EI0(starter_i)) | |||
{ | |||
i += 2; | |||
break; | |||
} | |||
//Or, we're at the end | |||
else if (++i >= m_edges.Count() - 1) | |||
break; | |||
} | |||
} | |||
} | |||
} | |||
//Remove same direction edges | |||
int starter_i = 0; | |||
for (int i = 0; i < m_edges.Count() - 1; ++i) | |||
{ | |||
int ia = i; | |||
int ib = i + 1; | |||
if (EI1(ia) == EI0(starter_i)) | |||
ib = starter_i; | |||
if (EI1(ia) == EI0(ib) && | |||
dot(normalize(EV1(ia) - EV0(ia)), normalize(EV1(ib) - EV0(ib))) == 1.f) | |||
{ | |||
vert_num[EI1(ia)] -= 2; | |||
m_edges[ib].m1 = m_edges[ia].m1; | |||
m_edges.Remove(ia); | |||
i--; | |||
if (EI1(ia) == EI0(starter_i)) | |||
{ | |||
i += 2; | |||
starter_i = i; | |||
} | |||
} | |||
} | |||
//Build the new indices | |||
int rem = 0; | |||
for (int i = 0; i < vert_num.Count(); ++i) | |||
{ | |||
if (vert_num[i] != 2) | |||
{ | |||
rem++; | |||
vert_num[i] = -1; | |||
} | |||
else | |||
vert_num[i] = i - rem; | |||
} | |||
//Apply the new indices | |||
for (int i = 0; rem > 0 && i < m_edges.Count(); ++i) | |||
{ | |||
m_edges[i].m1 = vert_num[EI0(i)]; | |||
m_edges[i].m2 = vert_num[EI1(i)]; | |||
} | |||
//Remove the surnumeral vertices | |||
for (int i = m_vertices.Count() - 1; i >= 0; --i) | |||
if (vert_num[i] == -1) | |||
m_vertices.Remove(i); | |||
} | |||
//Edge functions | |||
int PrimitiveFace::FindVert(vec3 vertex) | |||
{ | |||
for (int i = 0; i < m_vertices.Count(); ++i) | |||
if (length(m_vertices[i] - vertex) < .00001f) | |||
return i; | |||
return -1; | |||
} | |||
//-- | |||
int PrimitiveFace::AddVert(vec3 vertex) | |||
{ | |||
m_vertices.Push(vertex); | |||
return m_vertices.Count() - 1; | |||
} | |||
//-- | |||
void PrimitiveMesh::AddPolygon(vec3 v0, vec3 v1, vec3 v2, vec3 normal) | |||
{ | |||
for (int i = 0; i < m_faces.Count(); ++i) | |||
{ | |||
vec3 proj_point = ProjectPointOnPlane(v0, m_faces[i].GetCenter(), m_faces[i].GetNormal()); | |||
//Found the same face | |||
if (dot(normal, m_faces[i].GetNormal()) == 1.f && length(proj_point - v0) == .0f) | |||
{ | |||
m_faces[i].AddPolygon(v0, v1, v2); | |||
return; | |||
} | |||
} | |||
//Didn't find a thing, so add ..... | |||
m_faces.Resize(m_faces.Count() + 1); | |||
m_faces.Last().SetCenter(v0); | |||
m_faces.Last().SetNormal(normal); | |||
m_faces.Last().AddPolygon(v0, v1, v2); | |||
} | |||
//-- | |||
void PrimitiveMesh::CleanFaces() | |||
{ | |||
for (int i = 0; i < m_faces.Count(); ++i) | |||
m_faces[i].CleanEdges(); | |||
} | |||
//-- | |||
int CsgBsp::AddLeaf(int leaf_type, vec3 origin, vec3 normal, int above_idx) | |||
{ | |||
@@ -250,14 +51,14 @@ int CsgBsp::TestPoint(int leaf_idx, vec3 point) | |||
{ | |||
vec3 p2o = point - m_tree[leaf_idx].m_origin; | |||
if (length(p2o) < CSG_EPSILON) | |||
if (length(p2o) < TestEpsilon::Get()) | |||
return LEAF_CURRENT; | |||
float p2o_dot = dot(normalize(p2o), m_tree[leaf_idx].m_normal); | |||
if (p2o_dot > CSG_EPSILON) | |||
if (p2o_dot > TestEpsilon::Get()) | |||
return LEAF_FRONT; | |||
else if (p2o_dot < -CSG_EPSILON) | |||
else if (p2o_dot < -TestEpsilon::Get()) | |||
return LEAF_BACK; | |||
} | |||
return LEAF_CURRENT; | |||
@@ -313,7 +114,7 @@ void CsgBsp::AddTriangleToTree(int const &tri_idx, vec3 const &tri_p0, vec3 cons | |||
{ | |||
vec3 ray = v[(i + 1) % 3] - v[i]; | |||
if (RayIsectPlane(v[i], v[(i + 1) % 3], | |||
if (TestRayVsPlane(v[i], v[(i + 1) % 3], | |||
m_tree[leaf_idx].m_origin, m_tree[leaf_idx].m_normal, | |||
isec_v[isec_idx])) | |||
isec_i[isec_idx++] = i; | |||
@@ -356,7 +157,7 @@ void CsgBsp::AddTriangleToTree(int const &tri_idx, vec3 const &tri_p0, vec3 cons | |||
bool skip_tri = false; | |||
for(int l = 0; l < 3; l++) | |||
{ | |||
if (length(new_v[k + l] - new_v[k + (l + 1) % 3]) < CSG_EPSILON) | |||
if (length(new_v[k + l] - new_v[k + (l + 1) % 3]) < TestEpsilon::Get()) | |||
{ | |||
skip_tri = true; | |||
break; | |||
@@ -521,7 +322,7 @@ int CsgBsp::TestTriangleToTree(vec3 const &tri_p0, vec3 const &tri_p1, vec3 cons | |||
else | |||
{ | |||
//Get intersection on actual triangle sides. | |||
if (RayIsectTriangleSide(v[0], v[1], v[2], | |||
if (TestRayVsTriangleSide(v[0], v[1], v[2], | |||
isec_v[0], isec_v[1], | |||
isec_v[0], isec_i[0], isec_v[1], isec_i[1])) | |||
{ | |||
@@ -536,7 +337,7 @@ int CsgBsp::TestTriangleToTree(vec3 const &tri_p0, vec3 const &tri_p1, vec3 cons | |||
int l = 0; | |||
for(; l < 3; l++) | |||
{ | |||
if (length(v[l] - isec_v[k]) < CSG_EPSILON) | |||
if (length(v[l] - isec_v[k]) < TestEpsilon::Get()) | |||
{ | |||
skip_point = true; | |||
new_v_idx[k] = t[l]; | |||
@@ -604,7 +405,7 @@ int CsgBsp::TestTriangleToTree(vec3 const &tri_p0, vec3 const &tri_p1, vec3 cons | |||
bool skip_tri = false; | |||
for(int l = 0; l < 3; l++) | |||
{ | |||
if (length(vert_list[new_t[k + l]].m1 - vert_list[new_t[k + (l + 1) % 3]].m1) < CSG_EPSILON) | |||
if (length(vert_list[new_t[k + l]].m1 - vert_list[new_t[k + (l + 1) % 3]].m1) < TestEpsilon::Get()) | |||
{ | |||
skip_tri = true; | |||
break; | |||
@@ -25,61 +25,6 @@ namespace lol | |||
#define LEAF_BACK 0 | |||
#define LEAF_CURRENT -1 | |||
/* A safe enum for Primitive edge face. */ | |||
struct PrimitiveEdge | |||
{ | |||
enum Value | |||
{ | |||
OriginalHalf = 0, | |||
OriginalFull, | |||
MAX | |||
} | |||
m_value; | |||
inline PrimitiveEdge() : m_value(OriginalHalf) {} | |||
inline PrimitiveEdge(Value v) : m_value(v) {} | |||
inline PrimitiveEdge(int v) : m_value((Value)v) {} | |||
inline operator Value() { return m_value; } | |||
}; | |||
//-- Primitive stuff | |||
class PrimitiveFace | |||
{ | |||
public: | |||
void SetNormal(vec3 normal) { m_normal = normal; } | |||
vec3 GetNormal() { return m_normal; } | |||
void SetCenter(vec3 center) { m_center = center; } | |||
vec3 GetCenter() { return m_center; } | |||
void AddPolygon(vec3 v0, vec3 v1, vec3 v2); | |||
void CleanEdges(); | |||
vec3 EV0(int edge) { return m_vertices[m_edges[edge].m1]; } | |||
vec3 EV1(int edge) { return m_vertices[m_edges[edge].m2]; } | |||
int EI0(int edge) { return m_edges[edge].m1; } | |||
int EI1(int edge) { return m_edges[edge].m2; } | |||
int FindVert(vec3 vertex); | |||
int AddVert(vec3 vertex); | |||
//private: | |||
vec3 m_normal; //Face Normal | |||
vec3 m_center; //Face Center | |||
Array<int, int, PrimitiveEdge> m_edges; //Edges: <V0, V1, Full edge> | |||
Array<vec3> m_vertices; //Vectex list | |||
}; | |||
//-- Primitive | |||
class PrimitiveMesh | |||
{ | |||
public: | |||
void AddPolygon(vec3 v0, vec3 v1, vec3 v2, vec3 normal); | |||
void CleanFaces(); | |||
//private: | |||
Array<PrimitiveFace> m_faces; | |||
}; | |||
//Naïve bsp for the poor people | |||
class CsgBspLeaf | |||
{ | |||
@@ -166,7 +166,7 @@ void VertexDictionnary::AddVertex(const int vert_id, const vec3 vert_coord) | |||
if (cur_id == vert_id) | |||
return; | |||
if (sqlength(cur_loc - vert_coord) < CSG_EPSILON) | |||
if (sqlength(cur_loc - vert_coord) < TestEpsilon::Get()) | |||
{ | |||
if (cur_type == VDictType::Alone) | |||
cur_type = VDictType::Master; | |||
@@ -23,8 +23,6 @@ | |||
#include <stdint.h> | |||
#define CSG_EPSILON 0.0001 | |||
namespace lol | |||
{ | |||
@@ -152,6 +150,15 @@ template <typename T> struct Box3 | |||
/* | |||
* Helper geometry functions | |||
*/ | |||
class TestEpsilon | |||
{ | |||
private: | |||
static float g_test_epsilon; | |||
public: | |||
static inline float Get(); | |||
static inline void Set(float epsilon=.0001f); | |||
}; | |||
static inline bool TestAABBVsAABB(box2 const &b1, box2 const &b2) | |||
{ | |||
vec2 dist = 0.5f * (b1.A - b2.A + b1.B - b2.B); | |||
@@ -184,21 +191,41 @@ static inline bool TestAABBVsPoint(box3 const &b1, vec3 const &p) | |||
bool TestTriangleVsTriangle(vec3 const &v00, vec3 const &v01, vec3 const &v02, | |||
vec3 const &v10, vec3 const &v11, vec3 const &v12, | |||
vec3 &ip00, vec3 &ip10); | |||
bool RayIsectTriangleSide(vec3 const &v0, vec3 const &v1, vec3 const &v2, | |||
vec3 const &iP0, vec3 const &iP1, | |||
bool TestRayVsTriangleSide(vec3 const &v0, vec3 const &v1, vec3 const &v2, | |||
vec3 const &ip0, vec3 const &ip1, | |||
vec3 &iV0, int &iIdx0, vec3 &iV1, int &iIdx1); | |||
bool TestRayVsTriangle(vec3 const &ray_point, vec3 const &ray_dir, | |||
vec3 const &tri_p0, vec3 const &tri_p1, vec3 const &tri_p2, | |||
vec3 &vi); | |||
struct RayIntersect | |||
{ | |||
enum Value | |||
{ | |||
Nothing = 0, | |||
All, | |||
None, | |||
P0, | |||
P1, | |||
MAX | |||
} | |||
m_value; | |||
inline RayIntersect() : m_value(Nothing) {} | |||
inline RayIntersect(Value v) : m_value(v) {} | |||
inline RayIntersect(int v) : m_value((Value)v) {} | |||
inline operator Value() { return m_value; } | |||
}; | |||
#define RAY_ISECT_NOTHING 0 | |||
#define RAY_ISECT_ALL 1 | |||
#define RAY_ISECT_NONE 2 | |||
#define RAY_ISECT_P0 3 | |||
#define RAY_ISECT_P1 4 | |||
int RayIsectRay(vec3 const &rayP00, vec3 const &rayP01, | |||
vec3 const &rayP10, vec3 const &rayP11, | |||
vec3 &isec_point); | |||
bool RayIsectPlane(vec3 const &rayP0, vec3 const &rayP1, | |||
int TestRayVsRay(vec3 const &ray_p00, vec3 const &ray_p01, | |||
vec3 const &ray_p10, vec3 const &ray_p11, | |||
vec3 &isec_point); | |||
bool TestRayVsPlane(vec3 const &ray_p0, vec3 const &ray_p1, | |||
vec3 const &plane_point, vec3 const &plane_normal, | |||
vec3 &isec_point, bool test_line_only = false); | |||
bool TestPointVsFrustum(const vec3& point, const mat4& frustum, vec3* result_point=nullptr); | |||
@@ -24,6 +24,11 @@ using namespace std; | |||
namespace lol | |||
{ | |||
//Test epsilon stuff | |||
float TestEpsilon::g_test_epsilon = .0001f; | |||
float TestEpsilon::Get() { return g_test_epsilon; } | |||
void TestEpsilon::Set(float epsilon) { g_test_epsilon = epsilon; } | |||
//Projects Point on Plane : Normal must be given normalized. returns point on plane. | |||
vec3 ProjectPointOnPlane(vec3 const &proj_point, vec3 const &plane_point, vec3 const &plane_normal) | |||
{ | |||
@@ -59,7 +64,7 @@ namespace lol | |||
a = dot(v01, h); | |||
//rayDir is coplanar to the triangle, exit. | |||
if (a > -CSG_EPSILON && a < CSG_EPSILON) | |||
if (a > -TestEpsilon::Get() && a < TestEpsilon::Get()) | |||
return false; | |||
f = 1 / a; | |||
@@ -67,21 +72,21 @@ namespace lol | |||
triU = f * (dot(v0P, h)); | |||
//point is supposed to have an U on the segment v01 | |||
if (triU < -CSG_EPSILON || triU > 1.0) | |||
if (triU < -TestEpsilon::Get() || triU > 1.0) | |||
return false; | |||
q = cross(v0P, v01); | |||
triV = f * dot(ray_dir, q); | |||
//point is not in the triangle | |||
if (triV < -CSG_EPSILON || triU + triV > 1.0) | |||
if (triV < -TestEpsilon::Get() || triU + triV > 1.0) | |||
return false; | |||
// at this stage we can compute t to find out where | |||
// the intersection point is on the line | |||
float t = f * dot(v02, q); | |||
if (t > CSG_EPSILON) // ray intersection | |||
if (t > TestEpsilon::Get()) // ray intersection | |||
{ | |||
isec_point = tri_p0 + v01 * triU + v02 * triV; | |||
return true; | |||
@@ -115,9 +120,9 @@ namespace lol | |||
int zero_dist[2] = { 0, 0 }; | |||
for (int i = 0; i < 3; i++) | |||
{ | |||
if (PointDistToPlane(triV[i], triV[3], plane_norm[1]) < CSG_EPSILON) | |||
if (PointDistToPlane(triV[i], triV[3], plane_norm[1]) < TestEpsilon::Get()) | |||
zero_dist[0]++; | |||
if (PointDistToPlane(triV[i + 3], triV[0], plane_norm[0]) < CSG_EPSILON) | |||
if (PointDistToPlane(triV[i + 3], triV[0], plane_norm[0]) < TestEpsilon::Get()) | |||
zero_dist[1]++; | |||
} | |||
@@ -140,7 +145,7 @@ namespace lol | |||
#if 1 //if the point is near one the given entry, consider it as being the same point. | |||
for (int k = 0; k < 6; k++) | |||
{ | |||
if (length(isec[isecIdx] - triV[k]) < CSG_EPSILON) | |||
if (length(isec[isecIdx] - triV[k]) < TestEpsilon::Get()) | |||
{ | |||
isec[isecIdx] = triV[k]; | |||
break; | |||
@@ -153,7 +158,7 @@ namespace lol | |||
//If we have already found an intersection, pass if it's on this triangle. | |||
/*found_isec == i ||*/ | |||
//if it's the second intersection, we need it to be different from the first one. | |||
(isecIdx == 1 && length(isec[0] - isec[1]) > CSG_EPSILON)) | |||
(isecIdx == 1 && length(isec[0] - isec[1]) > TestEpsilon::Get())) | |||
{ | |||
found_isec = i; | |||
isecIdx++; | |||
@@ -172,42 +177,42 @@ namespace lol | |||
} | |||
//Ray/Line : returns one of the RAY_ISECT_* defines. | |||
int RayIsectRay(vec3 const &rayP00, vec3 const &rayP01, | |||
vec3 const &rayP10, vec3 const &rayP11, | |||
int TestRayVsRay(vec3 const &ray_p00, vec3 const &ray_p01, | |||
vec3 const &ray_p10, vec3 const &ray_p11, | |||
vec3 &isec_point) | |||
{ | |||
vec3 rayD0 = rayP01 - rayP00; | |||
vec3 rayD0 = ray_p01 - ray_p00; | |||
float rayS0 = length(rayD0); | |||
vec3 rayD0N = normalize(rayD0); | |||
vec3 rayD1 = rayP11 - rayP10; | |||
vec3 rayD1 = ray_p11 - ray_p10; | |||
float rayS1 = length(rayD1); | |||
vec3 rayD1N = normalize(rayD1); | |||
vec3 rayP0P1 = rayP10 - rayP00; | |||
vec3 rayP0P1 = ray_p10 - ray_p00; | |||
vec3 c01 = cross(rayD0N, rayD1N); | |||
float crs01S = length(c01); | |||
if (crs01S > -CSG_EPSILON && crs01S < CSG_EPSILON) | |||
if (crs01S > -TestEpsilon::Get() && crs01S < TestEpsilon::Get()) | |||
return 0; | |||
mat3 m0 = mat3(rayP0P1, rayD1N, c01); | |||
float t0 = determinant(m0) / (crs01S * crs01S); | |||
vec3 isec0 = rayP00 + rayD0N * t0; | |||
vec3 isec0 = ray_p00 + rayD0N * t0; | |||
mat3 m1 = mat3(rayP0P1, rayD0N, c01); | |||
float t1 = determinant(m1) / (crs01S * crs01S); | |||
vec3 isec1 = rayP10 + rayD1N * t1; | |||
vec3 isec1 = ray_p10 + rayD1N * t1; | |||
if (sqlength(isec0 - isec1) < CSG_EPSILON) //ray intersection | |||
if (sqlength(isec0 - isec1) < TestEpsilon::Get()) //ray intersection | |||
{ | |||
isec_point = (isec0 + isec0) * .5f; | |||
float d0 = (length(rayP01 - isec_point) < CSG_EPSILON || length(rayP00 - isec_point) < CSG_EPSILON)? | |||
float d0 = (length(ray_p01 - isec_point) < TestEpsilon::Get() || length(ray_p00 - isec_point) < TestEpsilon::Get())? | |||
(-1.0f): | |||
(dot(rayP00 - isec_point, rayP01 - isec_point)); | |||
float d1 = (length(rayP10 - isec_point) < CSG_EPSILON || length(rayP11 - isec_point) < CSG_EPSILON)? | |||
(dot(ray_p00 - isec_point, ray_p01 - isec_point)); | |||
float d1 = (length(ray_p10 - isec_point) < TestEpsilon::Get() || length(ray_p11 - isec_point) < TestEpsilon::Get())? | |||
(-1.0f): | |||
(dot(rayP10 - isec_point, rayP11 - isec_point)); | |||
(dot(ray_p10 - isec_point, ray_p11 - isec_point)); | |||
//if the dot is negative, your point is in each ray, so say OK. | |||
if (d0 < .0f && d1 < .0f) | |||
@@ -224,18 +229,18 @@ namespace lol | |||
} | |||
//Ray/Plane : Normal must be given normalized. returns 1 if succeeded. | |||
bool RayIsectPlane(vec3 const &rayP0, vec3 const &rayP1, | |||
bool TestRayVsPlane(vec3 const &ray_p0, vec3 const &ray_p1, | |||
vec3 const &plane_point, vec3 const &plane_normal, | |||
vec3 &isec_point, bool test_line_only) | |||
{ | |||
vec3 ray_dir = rayP1 - rayP0; | |||
vec3 ray_dir = ray_p1 - ray_p0; | |||
float d = dot(ray_dir, plane_normal); | |||
if (d > -CSG_EPSILON && d < CSG_EPSILON) | |||
if (d > -TestEpsilon::Get() && d < TestEpsilon::Get()) | |||
return false; | |||
vec3 o2p1 = rayP1 - plane_point; | |||
vec3 o2p0 = rayP0 - plane_point; | |||
vec3 o2p1 = ray_p1 - plane_point; | |||
vec3 o2p0 = ray_p0 - plane_point; | |||
if (!test_line_only) | |||
{ | |||
@@ -247,18 +252,18 @@ namespace lol | |||
return false; | |||
} | |||
float t = (dot(ProjectPointOnPlane(rayP0, plane_point, plane_normal) - rayP0, plane_normal)) / dot(ray_dir, plane_normal); | |||
float t = (dot(ProjectPointOnPlane(ray_p0, plane_point, plane_normal) - ray_p0, plane_normal)) / dot(ray_dir, plane_normal); | |||
if (!test_line_only && (t < -CSG_EPSILON || t > 1.0f)) | |||
if (!test_line_only && (t < -TestEpsilon::Get() || t > 1.0f)) | |||
return false; | |||
isec_point = rayP0 + t * ray_dir; | |||
isec_point = ray_p0 + t * ray_dir; | |||
return true; | |||
} | |||
//used to find the intersecting points between a triangle side and a coplanar line. | |||
bool RayIsectTriangleSide(vec3 const &v0, vec3 const &v1, vec3 const &v2, | |||
vec3 const &iP0, vec3 const &iP1, | |||
bool TestRayVsTriangleSide(vec3 const &v0, vec3 const &v1, vec3 const &v2, | |||
vec3 const &ip0, vec3 const &ip1, | |||
vec3 &iV0, int &iIdx0, vec3 &iV1, int &iIdx1) | |||
{ | |||
vec3 isecV[2] = { vec3(.0f), vec3(.0f) }; | |||
@@ -272,7 +277,7 @@ namespace lol | |||
isecIdx = 0; | |||
for (int j = 0; j < 3 && isecIdx < 2; j++) | |||
{ | |||
int Result = RayIsectRay(triV[j], triV[(j + 1) % 3], iP0, iP1, isec_point); | |||
int Result = TestRayVsRay(triV[j], triV[(j + 1) % 3], ip0, ip1, isec_point); | |||
if (Result == RAY_ISECT_P0 || Result == RAY_ISECT_ALL) | |||
{ | |||
isecV[isecIdx] = isec_point; | |||
@@ -782,66 +782,7 @@ public: | |||
} | |||
#define NORMAL_USAGE 1 | |||
#if 0 | |||
PrimitiveFace NewFace; | |||
NewFace.SetNormal(vec3::axis_z); | |||
NewFace.SetCenter(vec3::zero); | |||
int imax = 4, jmax = 4; | |||
int sz = 2; | |||
for (int i = 0; i < imax; ++i) | |||
{ | |||
for (int j = 0; j < jmax; ++j) | |||
{ | |||
NewFace.AddPolygon(vec3(ivec3(i, j, 0) * sz), | |||
vec3(ivec3(i, j, 0) * sz + ivec3(sz, 0, 0)), | |||
vec3(ivec3(i, j, 0) * sz + ivec3(sz, sz, 0))); | |||
NewFace.AddPolygon(vec3(ivec3(i, j, 0) * sz), | |||
vec3(ivec3(i, j, 0) * sz + ivec3(sz, sz, 0)), | |||
vec3(ivec3(i, j, 0) * sz + ivec3( 0, sz, 0))); | |||
} | |||
} | |||
for (int i = 0; i < NewFace.m_edges.Count(); ++i) | |||
{ | |||
Debug::DrawLine(NewFace.EV0(i) + vec3(.0f, .0f, 2.f), NewFace.EV1(i) + vec3(.0f, .0f, 2.f), | |||
NewFace.m_edges[i].m3 ? vec4(.0f, .7f, .0f, 1.f) : vec4(.7f, .0f, .0f, 1.f)); | |||
Debug::DrawBox(NewFace.EV0(i) + vec3(.0f, .0f, 2.f) + vec3(-.1f), | |||
NewFace.EV0(i) + vec3(.0f, .0f, 2.f) + vec3(+.1f), | |||
NewFace.m_edges[i].m3 ? vec4(.0f, .7f, .0f, 1.f) : vec4(.7f, .0f, .0f, 1.f)); | |||
} | |||
NewFace.CleanEdges(); | |||
for (int i = 0; i < NewFace.m_edges.Count(); ++i) | |||
{ | |||
Debug::DrawLine(NewFace.EV0(i), NewFace.EV1(i), vec4(vec3::zero, 1.f)); | |||
Debug::DrawBox(NewFace.EV0(i) + vec3(-.1f), | |||
NewFace.EV0(i) + vec3(+.1f), | |||
vec4(vec3::zero, 1.f)); | |||
} | |||
//Try with mesh | |||
PrimitiveMesh NewMesh; | |||
for (int i = m_meshes.Count() - 1; 0 <= i && i < m_meshes.Count(); i++) | |||
{ | |||
for (int j = 0; j < m_meshes[i].m1->m_indices.Count(); j += 3) | |||
{ | |||
VertexData v[3] = { m_meshes[i].m1->m_vert[m_meshes[i].m1->m_indices[j ]], | |||
m_meshes[i].m1->m_vert[m_meshes[i].m1->m_indices[j+1]], | |||
m_meshes[i].m1->m_vert[m_meshes[i].m1->m_indices[j+2]] }; | |||
NewMesh.AddPolygon(v[0].m_coord, v[1].m_coord, v[2].m_coord, v[0].m_normal); | |||
} | |||
NewMesh.CleanFaces(); | |||
break; | |||
} | |||
for (int j = 0; j < NewMesh.m_faces.Count(); ++j) | |||
{ | |||
for (int i = 0; i < NewMesh.m_faces[j].m_edges.Count(); ++i) | |||
{ | |||
vec3 v0 = NewMesh.m_faces[j].EV0(i) + NewMesh.m_faces[j].GetNormal() * .4f; | |||
vec3 v1 = NewMesh.m_faces[j].EV1(i) + NewMesh.m_faces[j].GetNormal() * .4f; | |||
Debug::DrawLine(v0, v1, vec4(vec3::zero, 1.f)); | |||
Debug::DrawBox(v0 + vec3(-.1f), v0 + vec3(+.1f), vec4(vec3::zero, 1.f)); | |||
} | |||
} | |||
#elif NORMAL_USAGE | |||
#if NORMAL_USAGE | |||
vec3 x = vec3(1.f,0.f,0.f); | |||
vec3 y = vec3(0.f,1.f,0.f); | |||
mat4 save_proj = m_camera->GetProjection(); | |||