Example #1
0
 /// <summary>
 /// Modeled after quarter-cycle of sine wave
 /// </summary>
 public static float EaseInSine(this float This)
 {
     return(Math.Sin((This - 1) * HalfPi) + 1);
 }
Example #2
0
        /// <summary>
        ///     Fill a texture with a signed distance field generated from the alpha channel of a source texture.
        /// </summary>
        /// <param name="source">
        ///     Source texture. Alpha values of 1 are considered inside, values of 0 are considered outside, and any other values
        ///     are considered
        ///     to be on the edge. Must be readable.
        /// </param>
        /// <param name="destination">
        ///     Destination texture. Must be the same size as the source texture. Must be readable.
        ///     The texture change does not get applied automatically, you need to do that yourself.
        /// </param>
        /// <param name="maxInside">
        ///     Maximum pixel distance measured inside the edge, resulting in an alpha value of 1.
        ///     If set to or below 0, everything inside will have an alpha value of 1.
        /// </param>
        /// <param name="maxOutside">
        ///     Maximum pixel distance measured outside the edge, resulting in an alpha value of 0.
        ///     If set to or below 0, everything outside will have an alpha value of 0.
        /// </param>
        /// <param name="postProcessDistance">
        ///     Pixel distance from the edge within which pixels will be post-processed using the edge gradient.
        /// </param>
        /// <param name="rgbMode">
        ///     How to fill the destination texture's RGB channels.
        /// </param>
        public static void Generate(
            Image <Rgba32> source,
            Image <Rgba32> destination,
            float maxInside,
            float maxOutside,
            float postProcessDistance,
            RGBFillMode rgbMode)
        {
            if (source.Height != destination.Height || source.Width != destination.Width)
            {
                Logger.WriteErrorLine("Source and destination textures must be the same size.");
                return;
            }

            width  = source.Width;
            height = source.Height;
            pixels = new Pixel[width, height];
            int    x, y;
            float  scale;
            Rgba32 c = rgbMode == RGBFillMode.White ? Color.White : Color.Black;

            for (y = 0; y < height; y++)
            {
                for (x = 0; x < width; x++)
                {
                    pixels[x, y] = new Pixel();
                }
            }
            if (maxInside > 0f)
            {
                for (y = 0; y < height; y++)
                {
                    for (x = 0; x < width; x++)
                    {
                        pixels[x, y].alpha = source.GetPixel(x, y).R / 255f;
                    }
                }
                ComputeEdgeGradients();
                GenerateDistanceTransform();
                if (postProcessDistance > 0f)
                {
                    PostProcess(postProcessDistance);
                }
                scale = 1f / maxInside;
                for (y = 0; y < height; y++)
                {
                    for (x = 0; x < width; x++)
                    {
                        c.A = (byte)(255f * Math.Clamp(pixels[x, y].distance * scale, 0, 1));
                        destination.SetPixel(x, y, c);
                    }
                }
            }

            if (maxOutside > 0f)
            {
                for (y = 0; y < height; y++)
                {
                    for (x = 0; x < width; x++)
                    {
                        pixels[x, y].alpha = 1f - source.GetPixel(x, y).R / 255f;
                    }
                }
                ComputeEdgeGradients();
                GenerateDistanceTransform();
                if (postProcessDistance > 0f)
                {
                    PostProcess(postProcessDistance);
                }
                scale = 1f / maxOutside;
                if (maxInside > 0f)
                {
                    for (y = 0; y < height; y++)
                    {
                        for (x = 0; x < width; x++)
                        {
                            c.A = (byte)(255f * (0.5f + (destination.GetPixel(x, y).A / 255f -
                                                         Math.Clamp(pixels[x, y].distance * scale, 0, 1)) * 0.5f));
                            destination.SetPixel(x, y, c);
                        }
                    }
                }
                else
                {
                    for (y = 0; y < height; y++)
                    {
                        for (x = 0; x < width; x++)
                        {
                            c.A = (byte)(255f * Math.Clamp(1f - pixels[x, y].distance * scale, 0, 1));
                            destination.SetPixel(x, y, c);
                        }
                    }
                }
            }

            if (rgbMode == RGBFillMode.Distance)
            {
                for (y = 0; y < height; y++)
                {
                    for (x = 0; x < width; x++)
                    {
                        c   = destination.GetPixel(x, y);
                        c.R = c.A;
                        c.G = c.A;
                        c.B = c.A;
                        destination.SetPixel(x, y, c);
                    }
                }
            }
            else if (rgbMode == RGBFillMode.Source)
            {
                for (y = 0; y < height; y++)
                {
                    for (x = 0; x < width; x++)
                    {
                        c   = source.GetPixel(x, y);
                        c.A = destination.GetPixel(x, y).A;
                        destination.SetPixel(x, y, c);
                    }
                }
            }

            pixels = null;
        }
Example #3
0
 /// <summary>
 /// Modeled after quarter-cycle of sine wave
 /// </summary>
 static internal float easeInSine(float p)
 {
     return(Math.Sin((p - 1) * HALFPI) + 1);
 }
Example #4
0
 /// <summary>
 /// Modeled after the damped sine wave y = sin(13pi/2*x)*Math.Pow(2, 10 * (x - 1))
 /// </summary>
 public static float EaseInElastic(this float This)
 {
     return(Math.Sin(13 * HalfPi * This) * Math.Pow(2, 10 * (This - 1)));
 }
Example #5
0
 /// <summary>
 /// Modeled after the overshooting cubic y = x^3-x*sin(x*pi)
 /// </summary>
 public static float EaseInBack(this float This)
 {
     return(This * This * This - This * Math.Sin(This * Pi));
 }
Example #6
0
 /// <summary>
 /// Modeled after shifted quadrant IV of unit circle
 /// </summary>
 public static float EaseInCircular(this float This)
 {
     return(1 - Math.Sqrt(1 - This * This));
 }
Example #7
0
 /// <summary>
 /// Modeled after the exponential function y = 2^(10(x - 1))
 /// </summary>
 public static float EaseInExponential(this float This)
 {
     return(This.IsAlmostZero() ? This : Math.Pow(2, 10 * (This - 1)));
 }
Example #8
0
 /// <summary>
 /// Modeled after the expo function y = -2^(-10x) + 1
 /// </summary>
 static internal float easeOutExpo(float p)
 {
     return((p == 1.0f) ? p : 1 - Math.Pow(2, -10 * p));
 }
Example #9
0
 /// <summary>
 /// Modeled after the damped sine wave y = sin(13pi/2*x)*Math.Pow(2, 10 * (x - 1))
 /// </summary>
 static internal float easeInElastic(float p)
 {
     return(Math.Sin(13 * HALFPI * p) * Math.Pow(2, 10 * (p - 1)));
 }
Example #10
0
 /// <summary>
 /// Modeled after shifted quadrant II of unit circle
 /// </summary>
 static internal float easeOutCirc(float p)
 {
     return(Math.Sqrt((2 - p) * p));
 }
Example #11
0
 /// <summary>
 /// Modeled after the expo function y = 2^(10(x - 1))
 /// </summary>
 static internal float easeInExpo(float p)
 {
     return((p == 0.0f) ? p : Math.Pow(2, 10 * (p - 1)));
 }
Example #12
0
 /// <summary>
 /// Modeled after shifted quadrant IV of unit circle
 /// </summary>
 static internal float easeInCirc(float p)
 {
     return(1 - Math.Sqrt(1 - (p * p)));
 }
Example #13
0
 /// <summary>
 /// Modeled after half sine wave
 /// </summary>
 static internal float easeInOutSine(float p)
 {
     return(0.5f * (1 - Math.Cos(p * PI)));
 }
Example #14
0
 /// <summary>
 /// Modeled after quarter-cycle of sine wave (different phase)
 /// </summary>
 static internal float easeOutSine(float p)
 {
     return(Math.Sin(p * HALFPI));
 }
Example #15
0
 /// <summary>
 /// Modeled after quarter-cycle of sine wave (different phase)
 /// </summary>
 public static float EaseOutSine(this float This)
 {
     return(Math.Sin(This * HalfPi));
 }
Example #16
0
 /// <summary>
 /// Modeled after the damped sine wave y = sin(-13pi/2*(x + 1))*Math.Pow(2, -10x) + 1
 /// </summary>
 static internal float easeOutElastic(float p)
 {
     return(Math.Sin(-13 * HALFPI * (p + 1)) * Math.Pow(2, -10 * p) + 1);
 }
Example #17
0
 /// <summary>
 /// Modeled after half sine wave
 /// </summary>
 public static float EaseInOutSine(this float This)
 {
     return(0.5f * (1 - Math.Cos(This * Pi)));
 }
Example #18
0
 /// <summary>
 /// Modeled after the overshooting cubic y = x^3-x*sin(x*pi)
 /// </summary>
 static internal float easeInBack(float p)
 {
     return(p * p * p - p * Math.Sin(p * PI));
 }
Example #19
0
 /// <summary>
 /// Modeled after shifted quadrant II of unit circle
 /// </summary>
 public static float EaseOutCircular(this float This)
 {
     return(Math.Sqrt((2 - This) * This));
 }
Example #20
0
        /// <summary>
        /// Modeled after overshooting cubic y = 1-((1-x)^3-(1-x)*sin((1-x)*pi))
        /// </summary>
        static internal float easeOutBack(float p)
        {
            float f = (1 - p);

            return(1 - (f * f * f - f * Math.Sin(f * PI)));
        }
Example #21
0
 /// <summary>
 /// Modeled after the exponential function y = -2^(-10x) + 1
 /// </summary>
 public static float EaseOutExponential(this float This)
 {
     return(This.IsAlmostEqualTo(1f) ? This : 1 - Math.Pow(2, -10 * This));
 }
        public static float CalcInnerDiameter(float outerDiameter, float tubeWidth)
        {
            var innerDiameter = outerDiameter - (tubeWidth * 2);

            return(Mathf.Max(0, innerDiameter));
        }
Example #23
0
 /// <summary>
 /// Modeled after the damped sine wave y = sin(-13pi/2*(x + 1))*Math.Pow(2, -10x) + 1
 /// </summary>
 public static float EaseOutElastic(this float This)
 {
     return(Math.Sin(-13 * HalfPi * (This + 1)) * Math.Pow(2, -10 * This) + 1);
 }
        public static float CalcTubeWidth(float outerDiameter, float innerDiameter)
        {
            var tubeWidth = (outerDiameter - innerDiameter) * 0.5f;

            return(Mathf.Max(kMinTubeDiameter, tubeWidth));
        }
Example #25
0
        /// <summary>
        /// Modeled after overshooting cubic y = 1-((1-x)^3-(1-x)*sin((1-x)*pi))
        /// </summary>
        public static float EaseOutBack(this float This)
        {
            var f = 1 - This;

            return(1 - (f * f * f - f * Math.Sin(f * Pi)));
        }
        internal static void Interpolate(JToken a, JToken b, float linearT, ref JToken mix, CubicBezier easing)
        {
            var easedT = easing.Sample(linearT);

            // compound types
            if (a.Type == JTokenType.Object)
            {
                JObject A   = (JObject)a;
                JObject B   = (JObject)b;
                JObject Mix = (JObject)mix;

                if (A.ContainsKey("x") && A.ContainsKey("y"))
                {
                    if (A.ContainsKey("z"))
                    {
                        // quaternion
                        if (A.ContainsKey("w"))
                        {
                            tempA.Set(A.ForceFloat("x"), A.ForceFloat("y"), A.ForceFloat("z"), A.ForceFloat("w"));
                            tempB.Set(B.ForceFloat("x"), B.ForceFloat("y"), B.ForceFloat("z"), B.ForceFloat("w"));
                            tempMix = Quaternion.Slerp(tempA, tempB, easedT);
                            Mix.SetOrAdd("x", tempMix.x);
                            Mix.SetOrAdd("y", tempMix.y);
                            Mix.SetOrAdd("z", tempMix.z);
                            Mix.SetOrAdd("w", tempMix.w);
                        }
                        // Vector3
                        else
                        {
                            Mix.SetOrAdd("x", UnityMath.Lerp(A.ForceFloat("x"), B.ForceFloat("x"), easedT));
                            Mix.SetOrAdd("y", UnityMath.Lerp(A.ForceFloat("y"), B.ForceFloat("y"), easedT));
                            Mix.SetOrAdd("z", UnityMath.Lerp(A.ForceFloat("z"), B.ForceFloat("z"), easedT));
                        }
                    }
                    // Vector2
                    else
                    {
                        Mix.SetOrAdd("x", UnityMath.Lerp(A.ForceFloat("x"), B.ForceFloat("x"), easedT));
                        Mix.SetOrAdd("y", UnityMath.Lerp(A.ForceFloat("y"), B.ForceFloat("y"), easedT));
                    }
                }
                // TODO: other compound types (color3, color4)
            }
            // simple types
            else
            {
                JValue A   = (JValue)a;
                JValue B   = (JValue)b;
                JValue Mix = (JValue)mix;

                // numeric types
                if (a.Type == JTokenType.Float || a.Type == JTokenType.Integer)
                {
                    Mix.Value = UnityMath.Lerp(A.ForceFloat(), B.ForceFloat(), easedT);
                }
                // no interpolation available, just use A
                else
                {
                    Mix.Value = A.Value;
                }
            }
        }
Example #27
0
        static void WriteBackInstance(ILRuntime.Runtime.Enviorment.AppDomain __domain, StackObject *ptr_of_this_method, IList <object> __mStack, ref UnityEngine.Mathf instance_of_this_method)
        {
            ptr_of_this_method = ILIntepreter.GetObjectAndResolveReference(ptr_of_this_method);
            switch (ptr_of_this_method->ObjectType)
            {
            case ObjectTypes.Object:
            {
                __mStack[ptr_of_this_method->Value] = instance_of_this_method;
            }
            break;

            case ObjectTypes.FieldReference:
            {
                var ___obj = __mStack[ptr_of_this_method->Value];
                if (___obj is ILTypeInstance)
                {
                    ((ILTypeInstance)___obj)[ptr_of_this_method->ValueLow] = instance_of_this_method;
                }
                else
                {
                    var t = __domain.GetType(___obj.GetType()) as CLRType;
                    t.SetFieldValue(ptr_of_this_method->ValueLow, ref ___obj, instance_of_this_method);
                }
            }
            break;

            case ObjectTypes.StaticFieldReference:
            {
                var t = __domain.GetType(ptr_of_this_method->Value);
                if (t is ILType)
                {
                    ((ILType)t).StaticInstance[ptr_of_this_method->ValueLow] = instance_of_this_method;
                }
                else
                {
                    ((CLRType)t).SetStaticFieldValue(ptr_of_this_method->ValueLow, instance_of_this_method);
                }
            }
            break;

            case ObjectTypes.ArrayReference:
            {
                var instance_of_arrayReference = __mStack[ptr_of_this_method->Value] as UnityEngine.Mathf[];
                instance_of_arrayReference[ptr_of_this_method->ValueLow] = instance_of_this_method;
            }
            break;
            }
        }
Example #28
0
        public static bool GeneratePathedStairs(ref ChiselBrushContainer brushContainer, ref ChiselPathedStairsDefinition definition)
        {
            definition.Validate();

            var shapeVertices       = new List <Vector2>();
            var shapeSegmentIndices = new List <int>();

            GetPathVertices(definition.shape, definition.curveSegments, shapeVertices, shapeSegmentIndices);

            var totalSubMeshCount = 0;

            for (int i = 0; i < shapeVertices.Count; i++)
            {
                if (i == 0 && !definition.shape.closed)
                {
                    continue;
                }

                var leftSide  = (!definition.shape.closed && i == 1) ? definition.stairs.leftSide  : StairsSideType.None;
                var rightSide = (!definition.shape.closed && i == shapeVertices.Count - 1) ? definition.stairs.rightSide : StairsSideType.None;

                totalSubMeshCount += BrushMeshFactory.GetLinearStairsSubMeshCount(definition.stairs, leftSide, rightSide);
            }
            if (totalSubMeshCount == 0)
            {
                return(false);
            }

            //			var stairDirections = definition.shape.closed ? shapeVertices.Count : (shapeVertices.Count - 1);

            brushContainer.EnsureSize(totalSubMeshCount);

            var depth  = definition.stairs.absDepth;
            var height = definition.stairs.absHeight;

            var halfDepth  = depth * 0.5f;
            var halfHeight = height * 0.5f;

            int subMeshIndex = 0;

            for (int vi0 = shapeVertices.Count - 3, vi1 = shapeVertices.Count - 2, vi2 = shapeVertices.Count - 1, vi3 = 0; vi3 < shapeVertices.Count; vi0 = vi1, vi1 = vi2, vi2 = vi3, vi3++)
            {
                if (vi2 == 0 && !definition.shape.closed)
                {
                    continue;
                }

                // TODO: optimize this, we're probably redoing a lot of stuff for every iteration
                var v0 = shapeVertices[vi0];
                var v1 = shapeVertices[vi1];
                var v2 = shapeVertices[vi2];
                var v3 = shapeVertices[vi3];

                var m0 = (v0 + v1) * 0.5f;
                var m1 = (v1 + v2) * 0.5f;
                var m2 = (v2 + v3) * 0.5f;

                var d0 = (v1 - v0);
                var d1 = (v2 - v1);
                var d2 = (v3 - v2);

                var maxWidth0  = d0.magnitude;
                var maxWidth1  = d1.magnitude;
                var maxWidth2  = d2.magnitude;
                var halfWidth1 = d1 * 0.5f;

                d0 /= maxWidth0;
                d1 /= maxWidth1;
                d2 /= maxWidth2;

                var depthVector = new Vector3(d1.y, 0, -d1.x);
                var lineCenter  = new Vector3(m1.x, halfHeight, m1.y) - (depthVector * halfDepth);

                var depthVector0 = new Vector2(d0.y, -d0.x) * depth;
                var depthVector1 = new Vector2(d1.y, -d1.x) * depth;
                var depthVector2 = new Vector2(d2.y, -d2.x) * depth;

                m0 -= depthVector0;
                m1 -= depthVector1;
                m2 -= depthVector2;

                Vector2 output;
                var     leftShear  = Intersect(m1, d1, m0, d0, out output) ?  Vector2.Dot(d1, (output - (m1 - halfWidth1))) : 0;
                var     rightShear = Intersect(m1, d1, m2, d2, out output) ? -Vector2.Dot(d1, (output - (m1 + halfWidth1))) : 0;

                var transform = Matrix4x4.TRS(lineCenter,                                       // move to center of line
                                              Quaternion.LookRotation(depthVector, Vector3.up), // rotate to align with line
                                              Vector3.one);

                // set the width to the width of the line
                definition.stairs.width       = maxWidth1 * (definition.stairs.width < 0 ? -1 : 1);
                definition.stairs.nosingWidth = 0;

                var leftSide     = (!definition.shape.closed && vi2 == 1) ? definition.stairs.leftSide  : StairsSideType.None;
                var rightSide    = (!definition.shape.closed && vi2 == shapeVertices.Count - 1) ? definition.stairs.rightSide : StairsSideType.None;
                var subMeshCount = BrushMeshFactory.GetLinearStairsSubMeshCount(definition.stairs, leftSide, rightSide);
                if (subMeshCount == 0)
                {
                    continue;
                }

                if (!BrushMeshFactory.GenerateLinearStairsSubMeshes(ref brushContainer, definition.stairs, leftSide, rightSide, subMeshIndex))
                {
                    return(false);
                }

                var halfWidth = maxWidth1 * 0.5f;
                for (int m = 0; m < subMeshCount; m++)
                {
                    var vertices = brushContainer.brushMeshes[subMeshIndex + m].vertices;
                    for (int v = 0; v < vertices.Length; v++)
                    {
                        // TODO: is it possible to put all of this in a single matrix?
                        // lerp the stairs to go from less wide to wider depending on the depth of the vertex
                        var depthFactor = 1.0f - ((vertices[v].z / depth) + 0.5f);
                        var wideFactor  = (vertices[v].x / halfWidth) + 0.5f;
                        var scale       = (vertices[v].x / halfWidth);

                        // lerp the stairs width depending on if it's on the left or right side of the stairs
                        vertices[v].x = Mathf.Lerp(scale * (halfWidth - (rightShear * depthFactor)),
                                                   scale * (halfWidth - (leftShear * depthFactor)),
                                                   wideFactor);
                        vertices[v] = transform.MultiplyPoint(vertices[v]);
                    }
                }

                subMeshIndex += subMeshCount;
            }
            return(false);
        }