public override void Scatter_VeryLate(ref OctaveRay Ray, ref Random rand, Hare.Geometry.Vector Normal, double Cos_Theta)
            {
                if (rand.NextDouble() < Scattering_Coefficient[Ray.Octave, 1])
                {
                    Hare.Geometry.Vector diffx;
                    Hare.Geometry.Vector diffy;
                    Hare.Geometry.Vector diffz;
                    double proj;
                    //Check that the ray and the normal are both on the same side...
                    if (Cos_Theta > 0)
                    {
                        Normal *= -1;
                    }
                    diffz = Normal;
                    diffx = new Hare.Geometry.Vector(0, 0, 1);
                    proj  = Math.Abs(Hare.Geometry.Hare_math.Dot(diffz, diffx));

                    if (0.99 < proj && 1.01 > proj)
                    {
                        diffx = new Hare.Geometry.Vector(1, 0, 0);
                    }
                    diffy = Hare.Geometry.Hare_math.Cross(diffz, diffx);
                    diffx = Hare.Geometry.Hare_math.Cross(diffy, diffz);
                    diffx.Normalize();
                    diffy.Normalize();
                    diffz.Normalize();

                    double u1;
                    double u2;
                    double x;
                    double y;
                    double z;
                    Hare.Geometry.Vector vect;
                    u1 = 2.0 * Math.PI * rand.NextDouble();
                    // random azimuth
                    double Scat_Mod = rand.NextDouble();
                    u2 = Math.Acos(Scat_Mod);
                    // random zenith (elevation)
                    x = Math.Cos(u1) * Math.Sin(u2);
                    y = Math.Sin(u1) * Math.Sin(u2);
                    z = Math.Cos(u2);

                    vect = (diffx * x) + (diffy * y) + (diffz * z);
                    vect.Normalize();

                    //Return the new direction
                    Ray.direction = vect;
                }
                else
                {
                    //Specular Reflection
                    Ray.direction -= Normal * Cos_Theta * 2;
                }
            }
Ejemplo n.º 2
0
 private void Draw_Feedback()
 {
     if (Hybrid_Select.Checked)
     {
         if (Pach_Hybrid_Control.Instance != null && !Pach_Hybrid_Control.Instance.Auralisation_Ready() || Receiver_Choice.SelectedIndex < 0)
         {
             return;
         }
         Point3d[] rec = new Point3d[Recs.Length];
         for (int i = 0; i < Recs.Length; i++)
         {
             rec[i] = Utilities.PachTools.HPttoRPt(Recs[i]);
         }
         AuralisationConduit.Instance.add_Receivers(rec);
         List <Point3d> pts = new List <Point3d>();
         foreach (Direct_Sound D in Direct_Data)
         {
             pts.Add(D.Src_Origin);
         }
         AuralisationConduit.Instance.add_Sources(pts);
         List <Deterministic_Reflection> Paths = new List <Deterministic_Reflection>();
         List <Polyline> Lines = new List <Polyline>();
         foreach (ImageSourceData I in IS_Data)
         {
             if (I != null)
             {
                 Paths.AddRange(I.Paths[Receiver_Choice.SelectedIndex]);
             }
         }
         foreach (Deterministic_Reflection p in Paths)
         {
             foreach (Polyline P in p.PolyLine)
             {
                 Lines.Add(P);
             }
         }
         AuralisationConduit.Instance.add_Reflections(Lines);
         pts.Clear();
         List <Vector3d> Dirs = new List <Vector3d>();
         for (int i = 0; i < this.Channel_View.Items.Count; i++)
         {
             Hare.Geometry.Vector TempDir = Utilities.PachTools.Rotate_Vector(Utilities.PachTools.Rotate_Vector(((channel)Channel_View.Items[i]).V, 0, -(double)Alt_Choice.Value, true), -(double)Azi_Choice.Value, 0, true);//new Hare.Geometry.Vector(Speaker_Directions[i].X, Speaker_Directions[i].Y, Speaker_Directions[i].Z)
             //Hare.Geometry.Vector TempDir = Utilities.PachTools.Rotate_Vector(((channel)Channel_View.Items[i]).V, -(double)Azi_Choice.Value, -(double)Alt_Choice.Value, true);
             TempDir.Normalize();
             pts.Add(Utilities.PachTools.HPttoRPt(Recs[0]) + (Utilities.PachTools.HPttoRPt(TempDir) * -.343 * Math.Max(5, ((channel)Channel_View.Items[i]).delay)));
             Dirs.Add(new Vector3d(TempDir.x, TempDir.y, TempDir.z));
         }
         AuralisationConduit.Instance.add_Speakers(pts, Dirs);
         AuralisationConduit.Instance.set_direction(Utilities.PachTools.HPttoRPt(Recs[Receiver_Choice.SelectedIndex]), Utilities.PachTools.HPttoRPt(Utilities.PachTools.Rotate_Vector(Utilities.PachTools.Rotate_Vector(new Hare.Geometry.Vector(1, 0, 0), 0, -(double)Alt_Choice.Value, true), -(double)Azi_Choice.Value, 0, true)));
         //AuralisationConduit.Instance.set_direction(Utilities.PachTools.HPttoRPt(Recs[Receiver_Choice.SelectedIndex]), Utilities.PachTools.HPttoRPt(Utilities.PachTools.Rotate_Vector(new Hare.Geometry.Vector(1, 0, 0), -(double)Azi_Choice.Value, -(double)Alt_Choice.Value, true)));
     }
     else if (Mapping_Select.Checked)
     {
         if (Pach_Mapping_Control.Instance != null && !Pach_Mapping_Control.Instance.Auralisation_Ready() && Receiver_Choice.SelectedIndex < 0)
         {
             return;
         }
         if (Maps == null || Maps[0] == null)
         {
             return;
         }
         AuralisationConduit.Instance.add_Receivers(Maps[0].Origins());
         List <Point3d> pts = new List <Point3d>();
         foreach (Mapping.PachMapReceiver m in Maps)
         {
             pts.Add(m.Src);
         }
         AuralisationConduit.Instance.add_Sources(pts);
     }
     else
     {
         AuralisationConduit.Instance.Enabled = false;
     }
     Rhino.RhinoDoc.ActiveDoc.Views.ActiveView.Redraw();
 }
            public override void Scatter_Early(ref BroadRay Ray, ref Queue <OctaveRay> Rays, ref Random rand, Hare.Geometry.Vector Normal, double Cos_Theta)
            {
                double roughness_chance = rand.NextDouble();

                if (Cos_Theta > 0)
                {
                    Normal    *= -1;
                    Cos_Theta *= -1;
                }

                foreach (int oct in Ray.Octaves)
                {
                    // 3. Apply Scattering.
                    //// a. Create new source for scattered energy (E * Scattering).
                    //// b. Modify E (E * 1 - Scattering).
                    OctaveRay R = Ray.SplitRay(oct, Scattering_Coefficient[oct, 1]);

                    Hare.Geometry.Vector diffx;
                    Hare.Geometry.Vector diffy;
                    Hare.Geometry.Vector diffz;
                    double proj;
                    //Check that the ray and the normal are both on the same side...
                    diffz = Normal;
                    diffx = new Hare.Geometry.Vector(0, 0, 1);
                    proj  = Math.Abs(Hare.Geometry.Hare_math.Dot(diffz, diffx));

                    if (0.99 < proj && 1.01 > proj)
                    {
                        diffx = new Hare.Geometry.Vector(1, 0, 0);
                    }
                    diffy = Hare.Geometry.Hare_math.Cross(diffz, diffx);
                    diffx = Hare.Geometry.Hare_math.Cross(diffy, diffz);
                    diffx.Normalize();
                    diffy.Normalize();
                    diffz.Normalize();

                    double u1;
                    double u2;
                    double x;
                    double y;
                    double z;
                    Hare.Geometry.Vector vect;
                    u1 = 2.0 * Math.PI * rand.NextDouble();
                    // random azimuth
                    double Scat_Mod = rand.NextDouble();
                    u2 = Math.Acos(Scat_Mod);
                    // random zenith (elevation)
                    x = Math.Cos(u1) * Math.Sin(u2);
                    y = Math.Sin(u1) * Math.Sin(u2);
                    z = Math.Cos(u2);

                    vect = (diffx * x) + (diffy * y) + (diffz * z);
                    vect.Normalize();

                    //Return the new direction
                    R.direction = vect;

                    if (R.t_sum == 0)
                    {
                        Rhino.RhinoApp.Write("Something's up!");
                    }

                    Rays.Enqueue(R);
                }
                Ray.direction -= Normal * Cos_Theta * 2;
            }
            public override void Scatter_Late(ref OctaveRay Ray, ref Queue <OctaveRay> Rays, ref Random rand, Hare.Geometry.Vector Normal, double Cos_Theta)
            {
                double scat_sel = rand.NextDouble();

                if (scat_sel > Scattering_Coefficient[Ray.Octave, 2])
                {
                    // Specular Reflection
                    Ray.direction -= Normal * Cos_Theta * 2;
                    return;
                }
                else if (scat_sel > Scattering_Coefficient[Ray.Octave, 0])
                {
                    //Only for a certain portion of high benefit cases--
                    //// a. Create new source for scattered energy (E * Scattering).
                    //// b. Modify E (E * 1 - Scattering).
                    //Create a new ray...
                    OctaveRay tr = Ray.SplitRay(1 - Scattering_Coefficient[Ray.Octave, 1]);
                    // this is the specular reflection. Save it for later.
                    tr.direction -= Normal * Cos_Theta * 2;

                    if (tr.t_sum == 0)
                    {
                        Rhino.RhinoApp.Write("Something's up!");
                    }

                    Rays.Enqueue(tr);
                }

                //If we are here, the original ray needs a scattered direction:
                Hare.Geometry.Vector diffx;
                Hare.Geometry.Vector diffy;
                Hare.Geometry.Vector diffz;
                double proj;

                //Check that the ray and the normal are both on the same side...
                if (Cos_Theta > 0)
                {
                    Normal *= -1;
                }
                diffz = Normal;
                diffx = new Hare.Geometry.Vector(0, 0, 1);
                proj  = Math.Abs(Hare.Geometry.Hare_math.Dot(diffz, diffx));

                if (0.99 < proj && 1.01 > proj)
                {
                    diffx = new Hare.Geometry.Vector(1, 0, 0);
                }
                diffy = Hare.Geometry.Hare_math.Cross(diffz, diffx);
                diffx = Hare.Geometry.Hare_math.Cross(diffy, diffz);
                diffx.Normalize();
                diffy.Normalize();
                diffz.Normalize();

                double u1;
                double u2;
                double x;
                double y;
                double z;

                Hare.Geometry.Vector vect;
                u1 = 2.0 * Math.PI * rand.NextDouble();
                // random azimuth
                double Scat_Mod = rand.NextDouble();

                u2 = Math.Acos(Scat_Mod);
                // random zenith (elevation)
                x = Math.Cos(u1) * Math.Sin(u2);
                y = Math.Sin(u1) * Math.Sin(u2);
                z = Math.Cos(u2);

                vect = (diffx * x) + (diffy * y) + (diffz * z);
                vect.Normalize();

                //Return the new direction
                Ray.direction = vect;
            }
            public static double[][] ETCurve_1d(Direct_Sound Direct, ImageSourceData ISData, Receiver_Bank RTData, double CO_Time_ms, int Sampling_Frequency, int Octave, int Rec_ID, bool Start_at_Zero, double alt, double azi, bool degrees)
            {
                double[][] Histogram = new double[3][];
                    Histogram[0] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency)];
                    Histogram[1] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency)];
                    Histogram[2] = new double[(int)(CO_Time_ms * 0.001 * Sampling_Frequency)];
                    if (RTData != null)
                    {
                        for (int i = 0; i < Histogram[0].Length; i++)
                        {
                            Hare.Geometry.Vector Vpos = RTData.Directions_Pos(Octave, i, Rec_ID, alt, azi, degrees);
                            Hare.Geometry.Vector Vneg = RTData.Directions_Neg(Octave, i, Rec_ID, alt, azi, degrees);

                            double E = RTData.Rec_List[Rec_ID].Energy(i, Octave);
                            Hare.Geometry.Vector VTot = new Hare.Geometry.Vector(Math.Abs(Vpos.x) - Math.Abs(Vneg.x), Math.Abs(Vpos.y) - Math.Abs(Vneg.y), Math.Abs(Vpos.z) - Math.Abs(Vneg.z));
                            VTot.Normalize();
                            VTot *= E;

                            Histogram[0][i] = VTot.x;
                            Histogram[1][i] = VTot.y;
                            Histogram[2][i] = VTot.z;
                        }
                    }

                    if (Direct != null && Direct.IsOccluded(Rec_ID))
                    {
                        int D_Start = 0;
                        if (!Start_at_Zero) D_Start = (int)Math.Ceiling(Direct.Time(Rec_ID) * Sampling_Frequency);

                        Hare.Geometry.Vector[] DirectValue;
                        switch (Octave)
                        {
                            case 8:
                                DirectValue = Direct.Dir_Energy_Sum(Rec_ID, alt, azi, degrees);
                                break;
                            default:
                                DirectValue = Direct.Dir_Energy(Octave, Rec_ID, alt, azi, degrees);
                                break;
                        }

                        for (int i = 0; i < DirectValue.Length; i++)
                        {
                            Histogram[0][D_Start + i] += Math.Abs(DirectValue[i].x);
                            Histogram[1][D_Start + i] += Math.Abs(DirectValue[i].y);
                            Histogram[2][D_Start + i] += Math.Abs(DirectValue[i].z);
                        }
                    }

                    if (ISData != null)
                    {
                        switch (Octave)
                        {
                            case 8:
                                foreach (Deterministic_Reflection value in ISData.Paths[Rec_ID])
                                {
                                    if (Math.Ceiling(Sampling_Frequency * value.TravelTime) < Histogram[0].Length - 1)
                                    {
                                        Hare.Geometry.Vector[] E_Sum = value.Dir_EnergySum(alt, azi, degrees);
                                        for (int i = 0; i < E_Sum.Length; i++)
                                        {
                                            Histogram[0][(int)Math.Ceiling(Sampling_Frequency * value.TravelTime + i / Sampling_Frequency)] += Math.Abs(E_Sum[i].x);
                                            Histogram[1][(int)Math.Ceiling(Sampling_Frequency * value.TravelTime + i / Sampling_Frequency)] += Math.Abs(E_Sum[i].y);
                                            Histogram[2][(int)Math.Ceiling(Sampling_Frequency * value.TravelTime + i / Sampling_Frequency)] += Math.Abs(E_Sum[i].z);
                                        }
                                    }
                                }
                                break;
                            default:
                                foreach (Deterministic_Reflection value in ISData.Paths[Rec_ID])
                                {
                                    if (Math.Ceiling(Sampling_Frequency * value.TravelTime) < Histogram[0].Length - 1)
                                    {
                                        Hare.Geometry.Vector[] E_Dir = value.Dir_Energy(Octave, alt, azi, degrees);
                                        for (int i = 0; i < E_Dir.Length; i++)
                                        {
                                            Histogram[0][(int)Math.Ceiling(Sampling_Frequency * value.TravelTime + i / Sampling_Frequency)] += Math.Abs(E_Dir[i].x);
                                            Histogram[1][(int)Math.Ceiling(Sampling_Frequency * value.TravelTime + i / Sampling_Frequency)] += Math.Abs(E_Dir[i].y);
                                            Histogram[2][(int)Math.Ceiling(Sampling_Frequency * value.TravelTime + i / Sampling_Frequency)] += Math.Abs(E_Dir[i].z);
                                        }
                                    }
                                }
                                break;
                        }
                    }
                    return Histogram;
            }
            public static Hare.Geometry.Vector Rotate_Vector(Hare.Geometry.Vector V, double azi, double alt, bool degrees)
            {
                double yaw, pitch;
                if (degrees)
                {
                    yaw = Math.PI * alt / 180.0;
                    pitch = Math.PI * azi / 180.0;
                }
                else
                {
                    yaw = alt;
                    pitch = azi;
                }

                ///Implicit Sparse Rotation Matrix
                double[] r1 = new double[3] { Math.Cos(pitch) * Math.Cos(yaw) , Math.Sin(pitch) * Math.Cos(yaw) , Math.Sin(yaw) };
                Hare.Geometry.Vector fwd = new Hare.Geometry.Vector(r1[0], r1[1], r1[2]);
                Hare.Geometry.Vector up = new Hare.Geometry.Vector(0, 0, 1) - Hare.Geometry.Hare_math.Dot(new Hare.Geometry.Vector(0, 0, 1), fwd) * fwd;
                up.Normalize();
                double[] r3 = new double[3] { up.x, up.y, up.z };
                Hare.Geometry.Vector right = Hare.Geometry.Hare_math.Cross(up, fwd);
                double[] r2 = new double[3] { right.x, right.y, right.z };

                return (new Hare.Geometry.Vector(r1[0] * V.x + r1[1] * V.y + r1[2] * V.z, r2[0] * V.x + r2[1] * V.y + r2[2] * V.z, r3[0] * V.x + r3[1] * V.y + r3[2] * V.z));
            }