public bool samePlane(CTri t) { const float THRESH = 0.001f; float dd = Math.Abs(t.mPlaneD - mPlaneD); if (dd > THRESH) { return(false); } dd = Math.Abs(t.mNormal.x - mNormal.x); if (dd > THRESH) { return(false); } dd = Math.Abs(t.mNormal.y - mNormal.y); if (dd > THRESH) { return(false); } dd = Math.Abs(t.mNormal.z - mNormal.z); if (dd > THRESH) { return(false); } return(true); }
public bool sharesEdge(CTri t) { bool ret = false; uint count = 0; if (t.hasIndex(mI1)) { count++; } if (t.hasIndex(mI2)) { count++; } if (t.hasIndex(mI3)) { count++; } if (count >= 2) { ret = true; } return(ret); }
public static bool featureMatch(CTri m, List <CTri> tris, List <CTri> input_mesh) { bool ret = false; float neardot = 0.707f; m.mConcavity = 0; for (int i = 0; i < tris.Count; i++) { CTri t = tris[i]; if (t.samePlane(m)) { ret = false; break; } float dot = float3.dot(t.mNormal, m.mNormal); if (dot > neardot) { float d1 = t.planeDistance(m.mP1); float d2 = t.planeDistance(m.mP2); float d3 = t.planeDistance(m.mP3); if (d1 > 0.001f || d2 > 0.001f || d3 > 0.001f) // can't be near coplaner! { neardot = dot; t.raySect(m.mP1, m.mNormal, ref m.mNear1); t.raySect(m.mP2, m.mNormal, ref m.mNear2); t.raySect(m.mP3, m.mNormal, ref m.mNear3); ret = true; } } } if (ret) { m.mC1 = m.mP1.Distance(m.mNear1); m.mC2 = m.mP2.Distance(m.mNear2); m.mC3 = m.mP3.Distance(m.mNear3); m.mConcavity = m.mC1; if (m.mC2 > m.mConcavity) { m.mConcavity = m.mC2; } if (m.mC3 > m.mConcavity) { m.mConcavity = m.mC3; } } return(ret); }
public float Facing(CTri t) { return(float3.dot(mNormal, t.mNormal)); }
public float Facing(CTri t) { return float3.dot(mNormal, t.mNormal); }
public bool sharesEdge(CTri t) { bool ret = false; uint count = 0; if (t.hasIndex(mI1)) count++; if (t.hasIndex(mI2)) count++; if (t.hasIndex(mI3)) count++; if (count >= 2) ret = true; return ret; }
public bool samePlane(CTri t) { const float THRESH = 0.001f; float dd = Math.Abs(t.mPlaneD - mPlaneD); if (dd > THRESH) return false; dd = Math.Abs(t.mNormal.x - mNormal.x); if (dd > THRESH) return false; dd = Math.Abs(t.mNormal.y - mNormal.y); if (dd > THRESH) return false; dd = Math.Abs(t.mNormal.z - mNormal.z); if (dd > THRESH) return false; return true; }
// compute's how 'concave' this object is and returns the total volume of the // convex hull as well as the volume of the 'concavity' which was found. public static float computeConcavity(List <float3> vertices, List <int> indices, ref float4 plane, ref float volume) { float cret = 0f; volume = 1f; HullResult result = new HullResult(); HullDesc desc = new HullDesc(); desc.MaxFaces = 256; desc.MaxVertices = 256; desc.SetHullFlag(HullFlag.QF_TRIANGLES); desc.Vertices = vertices; HullError ret = HullUtils.CreateConvexHull(desc, ref result); if (ret == HullError.QE_OK) { volume = computeMeshVolume2(result.OutputVertices, result.Indices); // ok..now..for each triangle on the original mesh.. // we extrude the points to the nearest point on the hull. List <CTri> tris = new List <CTri>(); for (int i = 0; i < result.Indices.Count / 3; i++) { int i1 = result.Indices[i * 3 + 0]; int i2 = result.Indices[i * 3 + 1]; int i3 = result.Indices[i * 3 + 2]; float3 p1 = result.OutputVertices[i1]; float3 p2 = result.OutputVertices[i2]; float3 p3 = result.OutputVertices[i3]; CTri t = new CTri(p1, p2, p3, i1, i2, i3); tris.Add(t); } // we have not pre-computed the plane equation for each triangle in the convex hull.. float totalVolume = 0; List <CTri> ftris = new List <CTri>(); // 'feature' triangles. List <CTri> input_mesh = new List <CTri>(); for (int i = 0; i < indices.Count / 3; i++) { int i1 = indices[i * 3 + 0]; int i2 = indices[i * 3 + 1]; int i3 = indices[i * 3 + 2]; float3 p1 = vertices[i1]; float3 p2 = vertices[i2]; float3 p3 = vertices[i3]; CTri t = new CTri(p1, p2, p3, i1, i2, i3); input_mesh.Add(t); } for (int i = 0; i < indices.Count / 3; i++) { int i1 = indices[i * 3 + 0]; int i2 = indices[i * 3 + 1]; int i3 = indices[i * 3 + 2]; float3 p1 = vertices[i1]; float3 p2 = vertices[i2]; float3 p3 = vertices[i3]; CTri t = new CTri(p1, p2, p3, i1, i2, i3); featureMatch(t, tris, input_mesh); if (t.mConcavity > 0.05f) { float v = t.getVolume(); totalVolume += v; ftris.Add(t); } } SplitPlane.computeSplitPlane(vertices, indices, ref plane); cret = totalVolume; } return(cret); }
// compute's how 'concave' this object is and returns the total volume of the // convex hull as well as the volume of the 'concavity' which was found. public static float computeConcavity(List<float3> vertices, List<int> indices, ref float4 plane, ref float volume) { float cret = 0f; volume = 1f; HullResult result = new HullResult(); HullDesc desc = new HullDesc(); desc.MaxFaces = 256; desc.MaxVertices = 256; desc.SetHullFlag(HullFlag.QF_TRIANGLES); desc.Vertices = vertices; HullError ret = HullUtils.CreateConvexHull(desc, ref result); if (ret == HullError.QE_OK) { volume = computeMeshVolume2(result.OutputVertices, result.Indices); // ok..now..for each triangle on the original mesh.. // we extrude the points to the nearest point on the hull. List<CTri> tris = new List<CTri>(); for (int i = 0; i < result.Indices.Count / 3; i++) { int i1 = result.Indices[i * 3 + 0]; int i2 = result.Indices[i * 3 + 1]; int i3 = result.Indices[i * 3 + 2]; float3 p1 = result.OutputVertices[i1]; float3 p2 = result.OutputVertices[i2]; float3 p3 = result.OutputVertices[i3]; CTri t = new CTri(p1, p2, p3, i1, i2, i3); tris.Add(t); } // we have not pre-computed the plane equation for each triangle in the convex hull.. float totalVolume = 0; List<CTri> ftris = new List<CTri>(); // 'feature' triangles. List<CTri> input_mesh = new List<CTri>(); for (int i = 0; i < indices.Count / 3; i++) { int i1 = indices[i * 3 + 0]; int i2 = indices[i * 3 + 1]; int i3 = indices[i * 3 + 2]; float3 p1 = vertices[i1]; float3 p2 = vertices[i2]; float3 p3 = vertices[i3]; CTri t = new CTri(p1, p2, p3, i1, i2, i3); input_mesh.Add(t); } for (int i = 0; i < indices.Count / 3; i++) { int i1 = indices[i * 3 + 0]; int i2 = indices[i * 3 + 1]; int i3 = indices[i * 3 + 2]; float3 p1 = vertices[i1]; float3 p2 = vertices[i2]; float3 p3 = vertices[i3]; CTri t = new CTri(p1, p2, p3, i1, i2, i3); featureMatch(t, tris, input_mesh); if (t.mConcavity > 0.05f) { float v = t.getVolume(); totalVolume += v; ftris.Add(t); } } SplitPlane.computeSplitPlane(vertices, indices, ref plane); cret = totalVolume; } return cret; }
public static bool featureMatch(CTri m, List<CTri> tris, List<CTri> input_mesh) { bool ret = false; float neardot = 0.707f; m.mConcavity = 0; for (int i = 0; i < tris.Count; i++) { CTri t = tris[i]; if (t.samePlane(m)) { ret = false; break; } float dot = float3.dot(t.mNormal, m.mNormal); if (dot > neardot) { float d1 = t.planeDistance(m.mP1); float d2 = t.planeDistance(m.mP2); float d3 = t.planeDistance(m.mP3); if (d1 > 0.001f || d2 > 0.001f || d3 > 0.001f) // can't be near coplaner! { neardot = dot; t.raySect(m.mP1, m.mNormal, ref m.mNear1); t.raySect(m.mP2, m.mNormal, ref m.mNear2); t.raySect(m.mP3, m.mNormal, ref m.mNear3); ret = true; } } } if (ret) { m.mC1 = m.mP1.Distance(m.mNear1); m.mC2 = m.mP2.Distance(m.mNear2); m.mC3 = m.mP3.Distance(m.mNear3); m.mConcavity = m.mC1; if (m.mC2 > m.mConcavity) m.mConcavity = m.mC2; if (m.mC3 > m.mConcavity) m.mConcavity = m.mC3; } return ret; }