public Vector3f GetCoordinates(Face face, Vector3f out) { Vector3f tmp = Stack.alloc(Vector3f.class); Vector3f tmp1 = Stack.alloc(Vector3f.class); Vector3f tmp2 = Stack.alloc(Vector3f.class); Vector3f o = Stack.alloc(Vector3f.class); o.scale(-face.d, face.n); float[] a = floatArrays.getFixed(3); tmp1.sub(face.v[0].w, o); tmp2.sub(face.v[1].w, o); tmp.cross(tmp1, tmp2); a[0] = tmp.length(); tmp1.sub(face.v[1].w, o); tmp2.sub(face.v[2].w, o); tmp.cross(tmp1, tmp2); a[1] = tmp.length(); tmp1.sub(face.v[2].w, o); tmp2.sub(face.v[0].w, o); tmp.cross(tmp1, tmp2); a[2] = tmp.length(); float sm = a[0] + a[1] + a[2]; out.set(a[1], a[2], a[0]); out.scale(1f / (sm > 0f ? sm : 1f)); floatArrays.release(a); return out; }
public boolean Set(Face f, Mkv a, Mkv b, Mkv c) { Vector3f tmp1 = Stack.alloc(Vector3f.class); Vector3f tmp2 = Stack.alloc(Vector3f.class); Vector3f tmp3 = Stack.alloc(Vector3f.class); Vector3f nrm = Stack.alloc(Vector3f.class); tmp1.sub(b.w, a.w); tmp2.sub(c.w, a.w); nrm.cross(tmp1, tmp2); float len = nrm.length(); tmp1.cross(a.w, b.w); tmp2.cross(b.w, c.w); tmp3.cross(c.w, a.w); boolean valid = (tmp1.dot(nrm) >= -EPA_inface_eps) && (tmp2.dot(nrm) >= -EPA_inface_eps) && (tmp3.dot(nrm) >= -EPA_inface_eps); f.v[0] = a; f.v[1] = b; f.v[2] = c; f.mark = 0; f.n.scale(1f / (len > 0f ? len : cstInf), nrm); f.d = Math.max(0, -f.n.dot(a.w)); return valid; }
public boolean SolveSimplex2(Vector3f ao, Vector3f ab) { if (ab.dot(ao) >= 0) { Vector3f cabo = Stack.alloc(Vector3f.class); cabo.cross(ab, ao); if (cabo.lengthSquared() > GJK_sqinsimplex_eps) { ray.cross(cabo, ab); } else { return true; } } else { order = 0; simplex[0].set(simplex[1]); ray.set(ao); } return (false); }
public boolean SolveSimplex4(Vector3f ao, Vector3f ab, Vector3f ac, Vector3f ad) { // TODO: optimize Vector3f crs = Stack.alloc(Vector3f.class); Vector3f tmp = Stack.alloc(Vector3f.class); tmp.cross(ab, ac); Vector3f tmp2 = Stack.alloc(Vector3f.class); tmp2.cross(ac, ad); Vector3f tmp3 = Stack.alloc(Vector3f.class); tmp3.cross(ad, ab); if (tmp.dot(ao) > GJK_insimplex_eps) { crs.set(tmp); order = 2; simplex[0].set(simplex[1]); simplex[1].set(simplex[2]); simplex[2].set(simplex[3]); return SolveSimplex3a(ao, ab, ac, crs); } else if (tmp2.dot(ao) > GJK_insimplex_eps) { crs.set(tmp2); order = 2; simplex[2].set(simplex[3]); return SolveSimplex3a(ao, ac, ad, crs); } else if (tmp3.dot(ao) > GJK_insimplex_eps) { crs.set(tmp3); order = 2; simplex[1].set(simplex[0]); simplex[0].set(simplex[2]); simplex[2].set(simplex[3]); return SolveSimplex3a(ao, ad, ab, crs); } else { return (true); } }
public boolean SolveSimplex3a(Vector3f ao, Vector3f ab, Vector3f ac, Vector3f cabc) { // TODO: optimize Vector3f tmp = Stack.alloc(Vector3f.class); tmp.cross(cabc, ab); Vector3f tmp2 = Stack.alloc(Vector3f.class); tmp2.cross(cabc, ac); if (tmp.dot(ao) < -GJK_insimplex_eps) { order = 1; simplex[0].set(simplex[1]); simplex[1].set(simplex[2]); return SolveSimplex2(ao, ab); } else if (tmp2.dot(ao) > +GJK_insimplex_eps) { order = 1; simplex[1].set(simplex[2]); return SolveSimplex2(ao, ac); } else { float d = cabc.dot(ao); if (Math.abs(d) > GJK_insimplex_eps) { if (d > 0) { ray.set(cabc); } else { ray.negate(cabc); Mkv swapTmp = new Mkv(); swapTmp.set(simplex[0]); simplex[0].set(simplex[1]); simplex[1].set(swapTmp); } return false; } else { return true; } } }
public boolean EncloseOrigin() { Vector3f tmp = Stack.alloc(Vector3f.class); Vector3f tmp1 = Stack.alloc(Vector3f.class); Vector3f tmp2 = Stack.alloc(Vector3f.class); switch (order) { // Point case 0: break; // Line case 1: { Vector3f ab = Stack.alloc(Vector3f.class); ab.sub(simplex[1].w, simplex[0].w); Vector3f[] b = new Vector3f[] { Stack.alloc(Vector3f.class), Stack.alloc(Vector3f.class), Stack.alloc(Vector3f.class) }; b[0].set(1f, 0f, 0f); b[1].set(0f, 1f, 0f); b[2].set(0f, 0f, 1f); b[0].cross(ab, b[0]); b[1].cross(ab, b[1]); b[2].cross(ab, b[2]); float m[] = new float[] {b[0].lengthSquared(), b[1].lengthSquared(), b[2].lengthSquared()}; Quat4f tmpQuat = Stack.alloc(Quat4f.class); tmp.normalize(ab); QuaternionUtil.setRotation(tmpQuat, tmp, cst2Pi / 3f); Matrix3f r = Stack.alloc(Matrix3f.class); MatrixUtil.setRotation(r, tmpQuat); Vector3f w = Stack.alloc(Vector3f.class); w.set(b[m[0] > m[1] ? m[0] > m[2] ? 0 : 2 : m[1] > m[2] ? 1 : 2]); tmp.normalize(w); Support(tmp, simplex[4]); r.transform(w); tmp.normalize(w); Support(tmp, simplex[2]); r.transform(w); tmp.normalize(w); Support(tmp, simplex[3]); r.transform(w); order = 4; return (true); } // Triangle case 2: { tmp1.sub(simplex[1].w, simplex[0].w); tmp2.sub(simplex[2].w, simplex[0].w); Vector3f n = Stack.alloc(Vector3f.class); n.cross(tmp1, tmp2); n.normalize(); Support(n, simplex[3]); tmp.negate(n); Support(tmp, simplex[4]); order = 4; return (true); } // Tetrahedron case 3: return (true); // Hexahedron case 4: return (true); } return (false); }
public boolean SolveSimplex3(Vector3f ao, Vector3f ab, Vector3f ac) { Vector3f tmp = Stack.alloc(Vector3f.class); tmp.cross(ab, ac); return (SolveSimplex3a(ao, ab, ac, tmp)); }