public float Calculate(float lifetime, float time)
                    {
                        switch (Type)
                        {
                        case Component_ParticleSpeedMultiplierByTime.TypeEnum.Constant:
                            return(Constant);

                        case Component_ParticleSpeedMultiplierByTime.TypeEnum.Range:
                            return(MathEx.Lerp(Range.Minimum, Range.Maximum, MathEx.Saturate(time / lifetime)));

                        case Component_ParticleSpeedMultiplierByTime.TypeEnum.Curve:
                            return(Curve != null?Curve.CalculateValueByTime(time) : 1);
                        }

                        return(1);
                    }
예제 #2
0
        public double GetValueFactor()
        {
            var range = ValueRange.Value;
            var value = Value.Value;

            double factor;

            if (range[1] - range[0] > 0)
            {
                factor = MathEx.Saturate((value - range[0]) / (range[1] - range[0]));
            }
            else
            {
                factor = range[0];
            }

            return(factor);
        }
예제 #3
0
        //!!!!по сути времнно пока нет корректной толщины

        public static void AddLineSegmented(Simple3DRenderer renderer, Vector3 start, Vector3 end, int steps = -1)
        {
            //draw line segments so that there is no problem with the thickness of the lines
            var ray = new Ray(start, end - start);

            int steps2 = steps;

            if (steps2 < 0)
            {
                steps2 = (int)MathEx.Lerp(2, 10, MathEx.Saturate(Math.Pow(ray.Direction.Length() / 100, 1.3)));
            }

            for (int n = 0; n < steps2; n++)
            {
                var p0 = ray.GetPointOnRay((double)n / steps2);
                var p1 = ray.GetPointOnRay((double)(n + 1) / steps2);
                renderer.AddLine(p0, p1);
            }
        }
예제 #4
0
        void RenderLine(RenderingContext context, Vector2 start2, Vector2 end2, bool thick, ref Vector3 position, ref Quaternion rotation,
                        bool rotationIdentity)
        {
            Vector3 start, end;

            if (!rotationIdentity)
            {
                start = position + rotation * new Vector3(start2.X, start2.Y, 0);
                end   = position + rotation * new Vector3(end2.X, end2.Y, 0);
            }
            else
            {
                start = position + new Vector3(start2.X, start2.Y, 0);
                end   = position + new Vector3(end2.X, end2.Y, 0);
            }

            //clip visibility by distance
            var cameraPosition = context.viewport.CameraSettings.Position;
            var sphere         = new Sphere(cameraPosition, VisibilityDistance);

            if (!sphere.Contains(start) || !sphere.Contains(end))
            {
                var ray = new Ray(start, end - start);
                if (!sphere.Intersects(ray, out var scale1, out var scale2))
                {
                    return;
                }
                start = ray.GetPointOnRay(MathEx.Saturate(scale1));
                end   = ray.GetPointOnRay(MathEx.Saturate(scale2));
            }

            var renderer = context.viewport.Simple3DRenderer;

            if (thick)
            {
                renderer.AddLine(start, end, 0.04);
            }
            else
            {
                renderer.AddLineThin(start, end);
            }
        }
예제 #5
0
        public double[] GetTickFactors()
        {
            var result = new List <double>();

            var tickFrequency = TickFrequency.Value;

            if (tickFrequency > 0)
            {
                var    range   = ValueRange.Value;
                double current = range.Minimum;
                while (current < range.Maximum + tickFrequency / 1000)
                {
                    var factor = MathEx.Saturate((current - range[0]) / (range[1] - range[0]));
                    result.Add(factor);
                    current += tickFrequency;
                }
            }

            return(result.ToArray());
        }
예제 #6
0
 public int GetTrackBarValue(bool isInteger, double value)
 {
     if (ConvenientDistribution == ConvenientDistributionEnum.Exponential)
     {
         double v = MathEx.Saturate((value - Minimum) / (Maximum - Minimum));
         v = Math.Pow(v, 1.0 / ExponentialPower);
         return(MathEx.Clamp((int)(v * 1000), 0, 1000));
     }
     else
     {
         GetTrackBarMinMax(isInteger, out int min, out int max);
         if (isInteger)
         {
             return(MathEx.Clamp((int)(value), min, max));
         }
         else
         {
             return(MathEx.Clamp((int)(value * 1000), min, max));
         }
     }
 }
예제 #7
0
        public void SetLogarithmicRolloff(double minDistance, double maxDistance, double rolloffFactor)
        {
            //!!!!slowly

            if (maxDistance < minDistance)
            {
                maxDistance = minDistance;
            }

            int count = 10;

            if (rolloffGraph == null || rolloffGraph.Length != count)
            {
                rolloffGraph = new RolloffGraphItem[count];
            }
            rolloffGraph[0]         = new RolloffGraphItem(minDistance, 1);
            rolloffGraph[count - 1] = new RolloffGraphItem(maxDistance, 0);

            double distanceOffset = (maxDistance - minDistance) * .5f;

            for (int index = count - 2; index >= 1; index--)
            {
                double distance = minDistance + distanceOffset;
                double divisor  = minDistance + rolloffFactor * distanceOffset;
                double gain;
                if (divisor != 0)
                {
                    gain = minDistance / divisor;
                }
                else
                {
                    gain = 1;
                }
                MathEx.Saturate(ref gain);
                rolloffGraph[index] = new RolloffGraphItem(distance, gain);

                distanceOffset *= .5f;
            }
        }
예제 #8
0
        public static float GetLodValue(RangeF lodRange, float cameraDistance)
        {
            var lodRangeMin = lodRange.Minimum;
            var lodRangeMax = lodRange.Maximum;

            float min2 = lodRangeMin * 0.9f;
            float max2 = lodRangeMax * 0.9f;

            if (cameraDistance > max2)
            {
                //if(cameraDistance < lodRangeMax)
                if (lodRangeMax != max2)
                {
                    return(MathEx.Saturate((cameraDistance - max2) / (lodRangeMax - max2)));
                }
                else
                {
                    return(0.0f);
                }
                //else
                //	return 1.0;
            }
            else if (cameraDistance < lodRangeMin)
            {
                if (cameraDistance > min2 && lodRangeMin != min2)
                {
                    return(-MathEx.Saturate((cameraDistance - min2) / (lodRangeMin - min2)));
                }
                else
                {
                    return(1.0f);
                }
            }
            else
            {
                return(0.0f);
            }
        }
예제 #9
0
        public double GetRolloffFactor()
        {
            if ((sound.Mode & SoundModes.Mode3D) != 0)
            {
                var graph = rolloffGraph;
                if (graph != null && graph.Length > 0)
                {
                    double distance = (position - SoundWorld.ListenerPosition).Length();

                    if (distance <= graph[0].Distance)
                    {
                        return(graph[0].Gain);
                    }
                    if (distance >= graph[graph.Length - 1].Distance)
                    {
                        return(graph[graph.Length - 1].Gain);
                    }

                    if (graph.Length == 1)
                    {
                        return(graph[0].Gain);
                    }
                    else if (graph.Length == 2)
                    {
                        //linear rolloff
                        if (graph[0].Distance >= graph[1].Distance)
                        {
                            return(graph[0].Gain);
                        }
                        double factor = (distance - graph[0].Distance) / (graph[1].Distance - graph[0].Distance);
                        double gain   = graph[0].Gain * (1.0f - factor) + graph[1].Gain * factor;
                        return(MathEx.Saturate(gain));
                    }
                    else
                    {
                        //spline rolloff

                        //!!!!!slowly

                        CubicSpline spline = new CubicSpline();

                        //!!!!double

                        float[] distances = new float[graph.Length];
                        float[] gains     = new float[graph.Length];
                        for (int n = 0; n < graph.Length; n++)
                        {
                            distances[n] = (float)graph[n].Distance;
                            gains[n]     = (float)graph[n].Gain;
                        }

                        double gain = spline.FitAndEval(distances, gains, (float)distance);

                        //Log.Info( "GET: {0} - {1}", distance, gain );

                        return(MathEx.Saturate(gain));
                    }
                }
            }
            return(1);
        }
예제 #10
0
 /// <summary>
 /// Clamps the components of the current instance of <see cref="Vector2"/> between 0 and 1.
 /// </summary>
 public void Saturate()
 {
     MathEx.Saturate(ref X);
     MathEx.Saturate(ref Y);
 }
예제 #11
0
        static bool GenerateFile(string sourceRealFileName, bool generateIrradiance, int destSize, string destRealFileName, List <Vector3> outIrradianceValues, out string error)
        {
            var tempDirectory = GetTemporaryDirectory();

            string arguments;

            if (generateIrradiance)
            {
                arguments = $"--format=hdr --size={destSize} --type=cubemap --ibl-irradiance=\"{tempDirectory}\" \"{sourceRealFileName}\"";
            }
            else
            {
                arguments = $"--format=hdr --size={destSize} --type=cubemap -x \"{tempDirectory}\" \"{sourceRealFileName}\"";
            }

            var process = new Process();

            process.StartInfo.FileName  = Path.Combine(VirtualFileSystem.Directories.EngineInternal, @"Tools\Filament\cmgen.exe");
            process.StartInfo.Arguments = arguments;
            process.Start();
            process.WaitForExit();

            var exitCode = process.ExitCode;

            if (exitCode != 0)
            {
                error = $"cmgen.exe exit code = {exitCode}.";
                return(false);
            }

            var folder = Path.Combine(tempDirectory, Path.GetFileNameWithoutExtension(sourceRealFileName));

            int  size;
            bool need16bit = false;
            {
                var file  = Path.Combine(folder, generateIrradiance ? "i_nx.hdr" : "m0_nx.hdr");
                var bytes = File.ReadAllBytes(file);
                if (!ImageUtility.LoadFromBuffer(bytes, "hdr", out var data, out var size2, out _, out var format, out _, out _, out error))
                {
                    return(false);
                }
                size = size2.X;
                if (format != PixelFormat.Float32RGB)
                {
                    error = "format != PixelFormat.Float32RGB";
                    return(false);
                }

                var image2D = new ImageUtility.Image2D(format, size2, data);
                for (int y = 0; y < image2D.Size.Y; y++)
                {
                    for (int x = 0; x < image2D.Size.X; x++)
                    {
                        var v = image2D.GetPixel(new Vector2I(x, y));
                        if (v.X > 1.001f || v.Y >= 1.001f || v.Z >= 1.001f)
                        {
                            need16bit = true;
                            goto end16bit;
                        }
                    }
                }
                end16bit :;
            }

            var surfaces = new List <DDSImage.Surface>();

            for (int face = 0; face < 6; face++)
            {
                int counter     = 0;
                int currentSize = size;
                while (currentSize > 0)
                {
                    var postfixes = new string[] { "px", "nx", "py", "ny", "pz", "nz" };

                    string file;
                    if (generateIrradiance)
                    {
                        file = Path.Combine(folder, $"i_{postfixes[ face ]}.hdr");
                    }
                    else
                    {
                        file = Path.Combine(folder, $"m{counter}_{postfixes[ face ]}.hdr");
                    }

                    var bytes = File.ReadAllBytes(file);
                    if (!ImageUtility.LoadFromBuffer(bytes, "hdr", out var data, out var size2, out _, out var format, out _, out _, out error))
                    {
                        return(false);
                    }
                    if (format != PixelFormat.Float32RGB)
                    {
                        error = "format != PixelFormat.Float32RGB";
                        return(false);
                    }
                    if (size2.X != currentSize)
                    {
                        error = "size2.X != currentSize";
                        return(false);
                    }

                    if (need16bit)
                    {
                        byte[] newData = new byte[currentSize * currentSize * 4 * 2];

                        unsafe
                        {
                            fixed(byte *pData = data)
                            {
                                float *pData2 = (float *)pData;

                                fixed(byte *pNewData = newData)
                                {
                                    Half *pNewData2 = (Half *)pNewData;

                                    for (int n = 0; n < currentSize * currentSize; n++)
                                    {
                                        pNewData2[n * 4 + 0] = new Half(pData2[n * 3 + 0]);
                                        pNewData2[n * 4 + 1] = new Half(pData2[n * 3 + 1]);
                                        pNewData2[n * 4 + 2] = new Half(pData2[n * 3 + 2]);
                                        pNewData2[n * 4 + 3] = new Half(1.0f);
                                    }
                                }
                            }
                        }

                        surfaces.Add(new DDSImage.Surface(new Vector2I(currentSize, currentSize), newData));
                    }
                    else
                    {
                        byte[] newData = new byte[currentSize * currentSize * 4];

                        unsafe
                        {
                            fixed(byte *pData = data)
                            {
                                float *pData2 = (float *)pData;

                                for (int n = 0; n < currentSize * currentSize; n++)
                                {
                                    newData[n * 4 + 3] = 255;
                                    newData[n * 4 + 2] = (byte)(MathEx.Saturate(pData2[n * 3 + 0]) * 255.0);
                                    newData[n * 4 + 1] = (byte)(MathEx.Saturate(pData2[n * 3 + 1]) * 255.0);
                                    newData[n * 4 + 0] = (byte)(MathEx.Saturate(pData2[n * 3 + 2]) * 255.0);
                                }
                            }
                        }

                        surfaces.Add(new DDSImage.Surface(new Vector2I(currentSize, currentSize), newData));
                    }

                    counter++;
                    currentSize /= 2;

                    if (generateIrradiance)
                    {
                        break;
                    }
                }
            }

            var image = new DDSImage(need16bit ? DDSImage.FormatEnum.R16G16B16A16 : DDSImage.FormatEnum.X8R8G8B8, surfaces.ToArray(), true);

            if (!WriteToFile(destRealFileName, image, out error))
            {
                return(false);
            }

            if (outIrradianceValues != null)
            {
                var shFile = Path.Combine(folder, "sh.txt");
                var lines  = File.ReadAllLines(shFile);
                foreach (var line in lines)
                {
                    var index1 = line.IndexOf('(');
                    var index2 = line.IndexOf(')');
                    if (index1 != -1 && index2 != -1)
                    {
                        var str = line.Substring(index1 + 1, index2 - index1 - 1).Trim();

                        var strs = str.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                        if (strs.Length != 3)
                        {
                            error = "Unable to parse \"sh.txt\".";
                            return(false);
                        }

                        var x = double.Parse(strs[0].Trim());
                        var y = double.Parse(strs[1].Trim());
                        var z = double.Parse(strs[2].Trim());

                        outIrradianceValues.Add(new Vector3(x, y, z));
                    }
                }
            }

            DeleteDirectory(tempDirectory);

            error = "";
            return(true);
        }