PtrIntersectResult Plane::intersect(PtrRay ray){ double dotA = ray->getDirection()->dot(*m_normal); if (dotA >= 0) return IntersectResult::NoHit; double dotB = m_normal->dot(*(ray->getOrigin()) - *m_position); double distance = -dotB / dotA; return std::make_shared<IntersectResult>(IntersectResult(shared_from_this(), distance, ray->getPoint(distance), m_normal)); }
int Plane::Intersect(Ray& ray, IntersectResult* result) { Normal3dF normal(0, 1, 0); float dotA = ray.d.Dot(normal); if (dotA >= 0) { result = &IntersectResult::NoHit; return 0; } float dotB = normal.Dot(ray.o - position); float distance = -dotB / dotA; *result = IntersectResult(this, distance, ray.GetPoint(distance), normal); return 0; }
//http://www.qiujiawei.com/triangle-intersect/ int Triangle::Intersect(Ray& ray, IntersectResult* result) { const VectorArray& vertices = mesh->vertices; const Vector3dF& p0 = vertices[indexes[0]]; const Vector3dF& p1 = vertices[indexes[1]]; const Vector3dF& p2 = vertices[indexes[2]]; const Vector3dF&& e1 = p1 - p0; const Vector3dF&& e2 = p2 - p0; if (mesh->normals[tri_idx].isEmpty()) { mesh->normals[tri_idx] = (e1.Cross(e2)).Normalize(); if (mesh->reverse) { mesh->normals[tri_idx] = -mesh->normals[tri_idx]; } } const Normal3dF& normal = mesh->normals[tri_idx]; float nDotRay = normal.Dot(ray.d); if (mesh->face == 0) { //only front face if (nDotRay >= 0) { return 0; } } else if (mesh->face == 1) { //only back face if (nDotRay <= 0) { return 0; } } //printf("nDotRay %.1f ray.d: %.2f,%.2f,%.2f len:%.1f n: %.1f,%.1f,%.1f\n", nDotRay, ray.d.x, ray.d.y, ray.d.z, ray.d.Length(), normal.x, normal.y, normal.z); const Vector3dF& s = ray.o - p0; const Vector3dF& s1 = ray.d.Cross(e2); Real d = s1.Dot(e1); if (almost_equal(d, Real(0), 2)) return 0; d = 1. / d; const Vector3dF& s2 = s.Cross(e1); const Real& r1 = s2.Dot(e2); const Real& r2 = s1.Dot(s); const Real& r3 = s2.Dot(ray.d); const Real& t = r1 * d; const Real& b1 = r2 * d; if (b1 < 0. || b1 > 1.) return 0; const Real& b2 = r3 * d; if (b2 < 0. || b1 + b2 > 1.) return 0; const Vector3dF&& position = ray.GetPoint(t); *result = IntersectResult(mesh, t, std::forward<const Vector3dF>(position), normal); return 0; }
void OgreMesh::intersect(Ogre::Node *node, const Ogre::Ray &ray, IntersectResult &rtn) { rtn = IntersectResult(); const Ogre::Vector3 &position = node->_getDerivedPosition(); const Ogre::Quaternion &orient = node->_getDerivedOrientation(); const Ogre::Vector3 &scale = node->_getDerivedScale(); std::vector<Triangle>::iterator itr,itere=mTriangles.end(); int i = 0; for (itr = mTriangles.begin(); itr != itere; itr++) { Triangle newt = *itr; newt.v1.coord = (orient * (newt.v1.coord * scale)) + position; newt.v2.coord = (orient * (newt.v2.coord * scale)) + position; newt.v3.coord = (orient * (newt.v3.coord * scale)) + position; intersectTri(ray, rtn, &newt, false); if (rtn.intersected) { rtn.tri = *itr; } //intersectTri(ray, rtn, &*itr); /* if (i < 10) { std::cout << "c1:"<<newt.v1.coord << " c2:"<<newt.v2.coord << " c3:"<<newt.v3.coord << " u:"<<newt.v2.u<<" v:"<<newt.v2.v<<std::endl }*/ } }
// нч╫╩╣Ц IntersectResult IntersectResult::NoHit() { return IntersectResult(); }