Exemplo n.º 1
0
        /// <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);
        }