| @@ -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(); | |||