Lerp() public static method

faster than unity's lerp
public static Lerp ( float from, float to, float t ) : float
from float
to float
t float
return float
コード例 #1
0
ファイル: NoiseAlgos.cs プロジェクト: heyx3/TreeGen
    /// <summary>
    /// Works like GridNoise(), but allows for interpolation instead of hard jumps between values.
    /// </summary>
    public static float InterpolateNoise(Vector3 seed, Func <Vector3, Vector3> tModifier)
    {
        //Get the integer values behind and in front of the seed values.
        float minX = Mathf.Floor(seed.x),
              maxX = Mathf.Ceil(seed.x),
              minY = Mathf.Floor(seed.y),
              maxY = Mathf.Ceil(seed.y),
              minZ = Mathf.Floor(seed.z),
              maxZ = Mathf.Ceil(seed.z);

        //Get the interpolant (will be linear if nothing is done to modify it).
        Vector3 lerp = tModifier(seed - new Vector3(minX, minY, minZ));

        return(Mathf.Lerp(Mathf.Lerp(Mathf.Lerp(WhiteNoise(new Vector3(minX, minY, minZ)),
                                                WhiteNoise(new Vector3(maxX, minY, minZ)),
                                                lerp.x),
                                     Mathf.Lerp(WhiteNoise(new Vector3(minX, maxY, minZ)),
                                                WhiteNoise(new Vector3(maxX, maxY, minZ)),
                                                lerp.x),
                                     lerp.y),
                          Mathf.Lerp(Mathf.Lerp(WhiteNoise(new Vector3(minX, minY, maxZ)),
                                                WhiteNoise(new Vector3(maxX, minY, maxZ)),
                                                lerp.x),
                                     Mathf.Lerp(WhiteNoise(new Vector3(minX, maxY, maxZ)),
                                                WhiteNoise(new Vector3(maxX, maxY, maxZ)),
                                                lerp.x),
                                     lerp.y),
                          lerp.z));
    }
コード例 #2
0
ファイル: NoiseAlgos.cs プロジェクト: heyx3/EscapeTheMine
    /// <summary>
    /// Works like GridNoise(), but allows for interpolation instead of hard jumps between values.
    /// </summary>
    public static float InterpolateNoise(float seed, Func <float, float> tModifier)
    {
        //Get the integer values behind and in front of the seed values.
        float min = Mathf.Floor(seed),
              max = Mathf.Ceil(seed);

        //Get the interpolant (will be linear if nothing is done to modify it).
        float lerp = tModifier(seed - min);

        return(Mathf.Lerp(min, max, lerp));
    }
コード例 #3
0
        void GenerateObstacleVOs(VOBuffer vos)
        {
            var range = maxSpeed * obstacleTimeHorizon;

            // Iterate through all obstacles that we might need to avoid
            for (int i = 0; i < simulator.obstacles.Count; i++)
            {
                var obstacle = simulator.obstacles[i];
                var vertex   = obstacle;
                // Iterate through all edges (defined by vertex and vertex.dir) in the obstacle
                do
                {
                    // Ignore the edge if the agent should not collide with it
                    if (vertex.ignore || (vertex.layer & collidesWith) == 0)
                    {
                        vertex = vertex.next;
                        continue;
                    }

                    // Start and end points of the current segment
                    float elevation1, elevation2;
                    var   p1 = To2D(vertex.position, out elevation1);
                    var   p2 = To2D(vertex.next.position, out elevation2);

                    Vector2 dir = (p2 - p1).normalized;

                    // Signed distance from the line (not segment, lines are infinite)
                    // TODO: Can be optimized
                    float dist = VO.SignedDistanceFromLine(p1, dir, position);

                    if (dist >= -0.01f && dist < range)
                    {
                        float factorAlongSegment = Vector2.Dot(position - p1, p2 - p1) / (p2 - p1).sqrMagnitude;

                        // Calculate the elevation (y) coordinate of the point on the segment closest to the agent
                        var segmentY = Mathf.Lerp(elevation1, elevation2, factorAlongSegment);

                        // Calculate distance from the segment (not line)
                        var sqrDistToSegment = (Vector2.Lerp(p1, p2, factorAlongSegment) - position).sqrMagnitude;

                        // Ignore the segment if it is too far away
                        // or the agent is too high up (or too far down) on the elevation axis (usually y axis) to avoid it.
                        // If the XY plane is used then all elevation checks are disabled
                        if (sqrDistToSegment < range * range && (simulator.movementPlane == MovementPlane.XY || (elevationCoordinate <= segmentY + vertex.height && elevationCoordinate + height >= segmentY)))
                        {
                            vos.Add(VO.SegmentObstacle(p2 - position, p1 - position, Vector2.zero, radius * 0.01f, 1f / ObstacleTimeHorizon, 1f / simulator.DeltaTime));
                        }
                    }

                    vertex = vertex.next;
                } while (vertex != obstacle && vertex != null && vertex.next != null);
            }
        }
コード例 #4
0
ファイル: Draw.cs プロジェクト: isoundy000/ETGame
        public void CircleXZ(Vector3 center, float radius, Color color, float startAngle = 0f, float endAngle = 2 *Mathf.PI)
        {
            int steps = 40;

#if UNITY_EDITOR
            if (gizmos)
            {
                steps = (int)Mathf.Clamp(Mathf.Sqrt(radius / UnityEditor.HandleUtility.GetHandleSize((UnityEngine.Gizmos.matrix * matrix).MultiplyPoint3x4(center))) * 25, 4, 40);
            }
#endif
            while (startAngle > endAngle)
            {
                startAngle -= 2 * Mathf.PI;
            }

            Vector3 prev = new Vector3(Mathf.Cos(startAngle) * radius, 0, Mathf.Sin(startAngle) * radius);
            for (int i = 0; i <= steps; i++)
            {
                Vector3 c = new Vector3(Mathf.Cos(Mathf.Lerp(startAngle, endAngle, i / (float)steps)) * radius, 0, Mathf.Sin(Mathf.Lerp(startAngle, endAngle, i / (float)steps)) * radius);
                Line(center + prev, center + c, color);
                prev = c;
            }
        }
コード例 #5
0
 /** Hermite spline interpolation */
 static float Hermite(float start, float end, float value)
 {
     return(Mathf.Lerp(start, end, value * value * (3.0f - 2.0f * value)));
 }
コード例 #6
0
        public static IEnumerable <Progress> ScanAllTiles(this RecastGraph self)
        {
            self.transform = self.CalculateTransform();
            self.InitializeTileInfo();

            // If this is true, just fill the graph with empty tiles
            if (self.scanEmptyGraph)
            {
                self.FillWithEmptyTiles();
                yield break;
            }

            // A walkableClimb higher than walkableHeight can cause issues when generating the navmesh since then it can in some cases
            // Both be valid for a character to walk under an obstacle and climb up on top of it (and that cannot be handled with navmesh without links)
            // The editor scripts also enforce this but we enforce it here too just to be sure
            self.walkableClimb = Mathf.Min(self.walkableClimb, self.walkableHeight);

            yield return(new Progress(0, "Finding Meshes"));

            var bounds  = self.transform.Transform(new Bounds(self.forcedBoundsSize * 0.5f, self.forcedBoundsSize));
            var meshes  = self.CollectMeshes(bounds);
            var buckets = self.PutMeshesIntoTileBuckets(meshes);

            Queue <Int2> tileQueue = new Queue <Int2>();

            // Put all tiles in the queue
            for (int z = 0; z < self.tileZCount; z++)
            {
                for (int x = 0; x < self.tileXCount; x++)
                {
                    tileQueue.Enqueue(new Int2(x, z));
                }
            }

            var workQueue = new ParallelWorkQueue <Int2>(tileQueue);
            // Create the voxelizers and set all settings (one for each thread)
            var voxelizers = new Voxelize[workQueue.threadCount];

            for (int i = 0; i < voxelizers.Length; i++)
            {
                voxelizers[i] = new Voxelize(self.CellHeight, self.cellSize, self.walkableClimb, self.walkableHeight, self.maxSlope, self.maxEdgeLength);
            }
            workQueue.action = (tile, threadIndex) => {
                voxelizers[threadIndex].inputMeshes           = buckets[tile.x + tile.y * self.tileXCount];
                self.tiles[tile.x + tile.y * self.tileXCount] = self.BuildTileMesh(voxelizers[threadIndex], tile.x, tile.y, threadIndex);
            };

            // Prioritize responsiveness while playing
            // but when not playing prioritize throughput
            // (the Unity progress bar is also pretty slow to update)
            int timeoutMillis = Application.isPlaying ? 1 : 200;

            // Scan all tiles in parallel
            foreach (var done in workQueue.Run(timeoutMillis))
            {
                yield return(new Progress(Mathf.Lerp(0.1f, 0.9f, done / (float)self.tiles.Length), "Calculated Tiles: " + done + "/" + self.tiles.Length));
            }

            yield return(new Progress(0.9f, "Assigning Graph Indices"));

            // Assign graph index to nodes
            uint graphIndex = (uint)AstarPath.active.data.GetGraphIndex(self);

            self.GetNodes(node => node.GraphIndex = graphIndex);

            // First connect all tiles with an EVEN coordinate sum
            // This would be the white squares on a chess board.
            // Then connect all tiles with an ODD coordinate sum (which would be all black squares on a chess board).
            // This will prevent the different threads that do all
            // this in parallel from conflicting with each other.
            // The directions are also done separately
            // first they are connected along the X direction and then along the Z direction.
            // Looping over 0 and then 1
            for (int coordinateSum = 0; coordinateSum <= 1; coordinateSum++)
            {
                for (int direction = 0; direction <= 1; direction++)
                {
                    for (int i = 0; i < self.tiles.Length; i++)
                    {
                        if ((self.tiles[i].x + self.tiles[i].z) % 2 == coordinateSum)
                        {
                            tileQueue.Enqueue(new Int2(self.tiles[i].x, self.tiles[i].z));
                        }
                    }

                    workQueue        = new ParallelWorkQueue <Int2>(tileQueue);
                    workQueue.action = (tile, threadIndex) => {
                        // Connect with tile at (x+1,z) and (x,z+1)
                        if (direction == 0 && tile.x < self.tileXCount - 1)
                        {
                            self.ConnectTiles(self.tiles[tile.x + tile.y * self.tileXCount], self.tiles[tile.x + 1 + tile.y * self.tileXCount]);
                        }
                        if (direction == 1 && tile.y < self.tileZCount - 1)
                        {
                            self.ConnectTiles(self.tiles[tile.x + tile.y * self.tileXCount], self.tiles[tile.x + (tile.y + 1) * self.tileXCount]);
                        }
                    };

                    var numTilesInQueue = tileQueue.Count;
                    // Connect all tiles in parallel
                    foreach (var done in workQueue.Run(timeoutMillis))
                    {
                        yield return(new Progress(0.95f, "Connected Tiles " + (numTilesInQueue - done) + "/" + numTilesInQueue + " (Phase " + (direction + 1 + 2 * coordinateSum) + " of 4)"));
                    }
                }
            }

            for (int i = 0; i < meshes.Count; i++)
            {
                meshes[i].Pool();
            }
            ListPool <RasterizationMesh> .Release(ref meshes);

            // This may be used by the TileHandlerHelper script to update the tiles
            // while taking NavmeshCuts into account after the graph has been completely recalculated.
            if (self.OnRecalculatedTiles != null)
            {
                self.OnRecalculatedTiles(self.tiles.Clone() as NavmeshTile[]);
            }
        }
コード例 #7
0
        /** Will calculate a number of points around \a center which are on the graph and are separated by \a clearance from each other.
         * The maximum distance from \a center to any point will be \a radius.
         * Points will first be tried to be laid out as \a previousPoints and if that fails, random points will be selected.
         * This is great if you want to pick a number of target points for group movement. If you pass all current agent points from e.g the group's average position
         * this method will return target points so that the units move very little within the group, this is often aesthetically pleasing and reduces jitter if using
         * some kind of local avoidance.
         *
         * \param center The point to generate points around
         * \param g The graph to use for linecasting. If you are only using one graph, you can get this by AstarPath.active.graphs[0] as IRaycastableGraph.
         * Note that not all graphs are raycastable, recast, navmesh and grid graphs are raycastable. On recast and navmesh it works the best.
         * \param previousPoints The points to use for reference. Note that these should not be in world space. They are treated as relative to \a center.
         *      The new points will overwrite the existing points in the list. The result will be in world space, not relative to \a center.
         * \param radius The final points will be at most this distance from \a center.
         * \param clearanceRadius The points will if possible be at least this distance from each other.
         *
         * \todo Write unit tests
         */
        public static void GetPointsAroundPoint(Vector3 center, IRaycastableGraph g, List <Vector3> previousPoints, float radius, float clearanceRadius)
        {
            if (g == null)
            {
                throw new System.ArgumentNullException("g");
            }

            var graph = g as NavGraph;

            if (graph == null)
            {
                throw new System.ArgumentException("g is not a NavGraph");
            }

            NNInfoInternal nn = graph.GetNearestForce(center, NNConstraint.Default);

            center = nn.clampedPosition;

            if (nn.node == null)
            {
                // No valid point to start from
                return;
            }


            // Make sure the enclosing circle has a radius which can pack circles with packing density 0.5
            radius           = Mathf.Max(radius, 1.4142f * clearanceRadius * Mathf.Sqrt(previousPoints.Count)); //Mathf.Sqrt(previousPoints.Count*clearanceRadius*2));
            clearanceRadius *= clearanceRadius;

            for (int i = 0; i < previousPoints.Count; i++)
            {
                Vector3 dir  = previousPoints[i];
                float   magn = dir.magnitude;

                if (magn > 0)
                {
                    dir /= magn;
                }

                float newMagn = radius;                //magn > radius ? radius : magn;
                dir *= newMagn;

                GraphHitInfo hit;

                int tests = 0;
                while (true)
                {
                    Vector3 pt = center + dir;

                    if (g.Linecast(center, pt, nn.node, out hit))
                    {
                        if (hit.point == PF.Vector3.zero)
                        {
                            // Oops, linecast actually failed completely
                            // try again unless we have tried lots of times
                            // then we just continue anyway
                            tests++;
                            if (tests > 8)
                            {
                                previousPoints[i] = pt;
                                break;
                            }
                        }
                        else
                        {
                            pt = hit.point;
                        }
                    }

                    bool worked = false;

                    for (float q = 0.1f; q <= 1.0f; q += 0.05f)
                    {
                        Vector3 qt = Vector3.Lerp(center, pt, q);
                        worked = true;
                        for (int j = 0; j < i; j++)
                        {
                            if ((previousPoints[j] - qt).sqrMagnitude < clearanceRadius)
                            {
                                worked = false;
                                break;
                            }
                        }

                        // Abort after 8 tests or when we have found a valid point
                        if (worked || tests > 8)
                        {
                            worked            = true;
                            previousPoints[i] = qt;
                            break;
                        }
                    }

                    // Break out of nested loop
                    if (worked)
                    {
                        break;
                    }

                    // If we could not find a valid point, reduce the clearance radius slightly to improve
                    // the chances next time
                    clearanceRadius *= 0.9f;
                    // This will pick points in 2D closer to the edge of the circle with a higher probability
                    dir   = Random.onUnitSphere * Mathf.Lerp(newMagn, radius, tests / 5);
                    dir.y = 0;
                    tests++;
                }
            }
        }
コード例 #8
0
ファイル: AutoPupil.cs プロジェクト: lfe999/VamAutoPupil
 private float BrightnessToMorphValue(float brightness)
 {
     return(-1 * Math.Clamp(PupilNeutralValue + Math.Lerp(-1.0f, 1.5f, brightness), -1.0f, 1.5f));
 }
コード例 #9
0
 public Progress MapTo(float min, float max, string prefix = null)
 {
     return(new Progress(Mathf.Lerp(min, max, progress), prefix + description));
 }
コード例 #10
0
 /// <summary>
 /// Rescale parameter `v` which is in range (minA, maxA) to be in range (minB, maxB)
 /// </summary>
 /// <param name="v">Value to rescale</param>
 /// <param name="minA">Min value of original interval</param>
 /// <param name="maxA">Max value of original interval</param>
 /// <param name="minB">Min value of new interval</param>
 /// <param name="maxB">Max value of new interval</param>
 /// <returns></returns>
 private static float Rescale(float v, float minA, float maxA, float minB, float maxB)
 {
     return(Mathf.Lerp(minB, maxB, Mathf.InverseLerp(minA, maxA, v)));
 }