bool BuildingCollsionImpl::collsionRay(const ResultPoint3& org, const ResultPoint3& dir, ResultPoint3& hit) { IceMaths::Ray ray(Point(org.x, org.y, org.z), Point(dir.x, dir.y, dir.z)); // 每次查询前初始化射线于交点的距离为最大值 m_hitDistance = std::numeric_limits<float>::infinity(); Opcode::RayCollider rayCollider; Opcode::CollisionFaces result; rayCollider.SetUserData(this); rayCollider.SetHitCallback(hitCallback); // flag为false时,执行完整的查询,hitCallback会被回调多次(次数等同于射线在这次查询中碰到的点的个数) rayCollider.SetFirstContact(false); rayCollider.SetCulling(false); // rayCollider.SetClosestHit(true); // rayCollider.SetMaxDist(); rayCollider.Collide(ray, *m_modelScene); if(rayCollider.GetContactStatus()) { hit.x = m_hitPoint.x; hit.y = m_hitPoint.y; hit.z = m_hitPoint.z; return true; } return false; }
double ColdetModel::computeDistanceWithRay(const double *point, const double *dir) { Opcode::RayCollider RC; Ray world_ray(Point(point[0], point[1], point[2]), Point(dir[0], dir[1], dir[2])); Opcode::CollisionFace CF; Opcode::SetupClosestHit(RC, CF); udword Cache; RC.Collide(world_ray, dataSet->model, transform, &Cache); if (CF.mDistance == FLT_MAX){ return 0; }else{ return CF.mDistance; } }