/// <summary> /// Проброс луча через объект /// </summary> /// <param name="pos">Расположение луча</param> /// <param name="dir">Направление луча</param> /// <param name="hitPos">Место пересечения</param> /// <param name="hitNormal">Нормаль пересечения</param> /// <param name="hitVolume">Пересеченный объект</param> /// <returns>True если есть пересечение</returns> internal bool RayCast(Vec3 pos, Vec3 dir, float rayLength, out Vec3 hitPos, out Vec3 hitNormal, out VolumeComponent hitVolume) { // Перестроение основной сферы if (needCullRebuild) { RebuildCullSphere(); } // Пересечение с основной сферой if (Intersections.RaySphere(pos, dir, cullSphere.Position, cullSphere.Radius)) { float range = float.MaxValue; Vec3 norm = Vec3.Zero; Vec3 hitp = Vec3.Zero; VolumeComponent hvol = null; // Пересечение с волюмами Vec3 tfpos = PointToLocal(pos); Vec3 tfnrm = VectorToLocal(dir); VolumeComponent[] volumes = GetComponents <VolumeComponent>(); if (volumes != null && volumes.Length > 0) { foreach (VolumeComponent v in volumes) { if (v.Enabled) { Vec3 hp, hn; if (v.RayHit(tfpos, tfnrm, rayLength, out hp, out hn)) { float dst = (hp - tfpos).Length; if (dst < range) { range = dst; hitp = hp; norm = hn; hvol = v; } } } } } // Возврат if (hvol != null && range <= rayLength) { hitPos = PointToWorld(hitp); hitNormal = VectorToWorld(norm); hitVolume = hvol; return(true); } } // Нет пересечения hitPos = Vec3.Zero; hitNormal = Vec3.Zero; hitVolume = null; return(false); }