bool isRaySphereIntersection(const MVector3 & origin, const MVector3 & direction, const MVector3 & sphereCenter, float sphereRadius, MVector3 * point) { MVector3 vec = origin - sphereCenter; float b = direction.dotProduct(vec); float c = vec.getSquaredLength() - (sphereRadius * sphereRadius); float d = (b * b) - c; if(d < 0) return false; float distance = -b - sqrtf(d); point->x = (origin.x + (distance * direction.x)); point->y = (origin.y + (distance * direction.y)); point->z = (origin.z + (distance * direction.z)); return true; }
bool getNearestRaytracedPosition(const MVector3 & origin, const MVector3 & dest, const void * indices, M_TYPES indicesType, const MVector3 * vertices, unsigned int size, MVector3 * intersection) { M_PROFILE_SCOPE(getNearestRaytracedPosition); bool isRaytraced = false; float dist; float nearDist; MVector3 I; MVector3 rayVector = dest - origin; // init near dist nearDist = rayVector.getSquaredLength(); switch(indicesType) { case M_USHORT: { unsigned int v; unsigned short * idx = (unsigned short *)indices; for (v = 0; v < size; v += 3) { const MVector3 * v1 = &vertices[idx[v]]; const MVector3 * v2 = &vertices[idx[v+1]]; const MVector3 * v3 = &vertices[idx[v+2]]; // make normal MVector3 normal = getTriangleNormal(*v1, *v2, *v3); // compute ray intersection if(isEdgeTriangleIntersection(origin, dest, *v1, *v2, *v3, normal, &I)) { rayVector = I - origin; dist = rayVector.getSquaredLength(); if(dist < nearDist) { nearDist = dist; (*intersection) = I; } isRaytraced = true; } } } break; case M_UINT: { unsigned int v; unsigned int * idx = (unsigned int *)indices; for (v = 0; v < size; v += 3) { const MVector3 * v1 = &vertices[idx[v]]; const MVector3 * v2 = &vertices[idx[v+1]]; const MVector3 * v3 = &vertices[idx[v+2]]; // make normal MVector3 normal = getTriangleNormal(*v1, *v2, *v3); // compute ray intersection if(isEdgeTriangleIntersection(origin, dest, *v1, *v2, *v3, normal, &I)) { rayVector = I - origin; dist = rayVector.getSquaredLength(); if(dist < nearDist) { nearDist = dist; (*intersection) = I; } isRaytraced = true; } } } break; default: break; } return isRaytraced; }