/// <summary>
        /// Sets up a cache with the given characteristics.
        /// </summary>
        /// <param name="rootPath">The absolute path to the root of the cache.</param>
        /// <param name="maxEntries">The maximum number of entries in the cache.</param>
        /// <param name="maxSizeBytes">The maximum combined size of all entries in the cache.</param>
        public void Setup(string rootPath, int maxEntries, long maxSizeBytes)
        {
            this.rootPath     = rootPath;
            this.maxEntries   = maxEntries;
            this.maxSizeBytes = maxSizeBytes;

            // Check that we have a reasonable config:
            PolyUtils.AssertNotNullOrEmpty(rootPath, "rootPath can't be null or empty");
            PolyUtils.AssertTrue(Directory.Exists(rootPath), "rootPath must be an existing directory: " + rootPath);
            PolyUtils.AssertTrue(maxEntries >= 256, "maxEntries must be >= 256");
            PolyUtils.AssertTrue(maxSizeBytes >= 1048576, "maxSizeBytes must be >= 1MB");

            PtDebug.LogVerboseFormat("PBC initializing, root {0}, max entries {1}, max size {2}",
                                     rootPath, maxEntries, maxSizeBytes);

            md5 = MD5.Create();
            InitializeCache();

            setupDone = true;

            Thread backgroundThread = new Thread(BackgroundThreadMain);

            backgroundThread.IsBackground = true;
            backgroundThread.Start();
        }
Ejemplo n.º 2
0
        public static ConwayPoly ElongatedBicupola(int sides, bool gyro)
        {
            ConwayPoly poly        = ElongatedCupola(sides);
            Face       bottom      = poly.Faces[sides * 2];
            int        i           = 0;
            var        middleVerts = bottom.GetVertices();

            poly.Faces.Remove(bottom);
            poly.FaceRoles.RemoveAt(poly.FaceRoles.Count - 1);
            poly.FaceTags.RemoveAt(poly.FaceRoles.Count - 1);

            float      baseOffset  = -(_CalcSideLength(sides * 2) + _CalcCupolaHeight(sides));
            float      angleOffset = gyro ? 0.75f : 0.25f;
            ConwayPoly cap2        = _MakePolygon(sides, false, angleOffset, baseOffset, _CalcCupolaCapRadius(sides));

            poly.Append(cap2);
            var edge2 = poly.Faces.Last().Halfedge.Prev;

            int edgeOffset = gyro ? 0 : 1;

            while (true)
            {
                var side1 = new List <Vertex>
                {
                    middleVerts[PolyUtils.ActualMod(i * 2 - 1 - edgeOffset, sides * 2)],
                    middleVerts[PolyUtils.ActualMod(i * 2 - edgeOffset, sides * 2)],
                    edge2.Vertex
                };
                poly.Faces.Add(side1);
                poly.FaceRoles.Add(ConwayPoly.Roles.New);
                poly.FaceTags.Add(new HashSet <Tuple <string, ConwayPoly.TagType> >());

                var side2 = new List <Vertex>
                {
                    middleVerts[PolyUtils.ActualMod(i * 2 - edgeOffset, sides * 2)],
                    middleVerts[PolyUtils.ActualMod(i * 2 + 1 - edgeOffset, sides * 2)],
                    edge2.Next.Vertex,
                    edge2.Vertex,
                };
                poly.Faces.Add(side2);
                poly.FaceRoles.Add(ConwayPoly.Roles.NewAlt);
                poly.FaceTags.Add(new HashSet <Tuple <string, ConwayPoly.TagType> >());

                i++;
                edge2 = edge2.Next;

                if (i == sides)
                {
                    break;
                }
            }
            poly.Halfedges.MatchPairs();
            return(poly);
        }
Ejemplo n.º 3
0
        public async Task Load(int segmentAttemptId)
        {
            SegmentAttempt = await Context.Services.GetSegmentAttempt(segmentAttemptId);

            MapViewModel = new MapControlViewModel(
                Context,
                SegmentAttempt.FormattedTime,
                PolyUtils.GetMapLocations(SegmentAttempt.Locations, SegmentAttempt.Jumps));

            OnPropertyChanged(nameof(MapViewModel));
        }
Ejemplo n.º 4
0
        public async Task Load(int id)
        {
            Ride = await Context.Services.GetRide(id);

            MapViewModel = new MapControlViewModel(
                Context,
                Ride.DisplayName,
                PolyUtils.GetMapLocations(Ride.Locations, Ride.Jumps));

            OnPropertyChanged(nameof(MapViewModel));
        }
Ejemplo n.º 5
0
        public async Task Load(int id)
        {
            Segment = await Context.Services.GetSegment(id);

            MapViewModel = new MapControlViewModel(
                Context,
                Segment.Name,
                PolyUtils.GetMapLocations(Segment.Locations),
                showRideFeatures: false);

            OnPropertyChanged(nameof(MapViewModel));
        }
Ejemplo n.º 6
0
        public static ConwayPoly GyroelongatedCupola(int sides)
        {
            ConwayPoly poly    = Antiprism(sides * 2);
            Face       topFace = poly.Faces[1];
            ConwayPoly cap1    = _MakePolygon(sides, true, 0f, _CalcCupolaHeight(sides) + _CalcAntiprismHeight(sides * 2), _CalcCupolaCapRadius(sides));

            poly.Append(cap1);

            int i           = 0;
            var middleVerts = topFace.GetVertices();

            poly.Faces.Remove(topFace);
            poly.FaceRoles.RemoveAt(1);
            poly.FaceTags.RemoveAt(1);

            var edge2 = poly.Faces.Last().Halfedge.Prev;

            while (true)
            {
                var side1 = new List <Vertex>
                {
                    middleVerts[PolyUtils.ActualMod(i * 2 - 1, sides * 2)],
                    middleVerts[PolyUtils.ActualMod(i * 2, sides * 2)],
                    edge2.Vertex
                };
                poly.Faces.Add(side1);
                poly.FaceRoles.Add(ConwayPoly.Roles.New);
                poly.FaceTags.Add(new HashSet <Tuple <string, ConwayPoly.TagType> >());

                var side2 = new List <Vertex>
                {
                    middleVerts[PolyUtils.ActualMod(i * 2, sides * 2)],
                    middleVerts[PolyUtils.ActualMod(i * 2 + 1, sides * 2)],
                    edge2.Next.Vertex,
                    edge2.Vertex,
                };
                poly.Faces.Add(side2);
                poly.FaceRoles.Add(ConwayPoly.Roles.NewAlt);
                poly.FaceTags.Add(new HashSet <Tuple <string, ConwayPoly.TagType> >());

                i++;
                edge2 = edge2.Next;
                if (i == sides)
                {
                    break;
                }
            }

            poly.Halfedges.MatchPairs();
            return(poly);
        }
        /// <summary>
        /// (Background thread). Main function that constantly checks the queues for pending requests and executes
        /// them as they arrive.
        /// </summary>
        private void BackgroundThreadMain()
        {
            try
            {
                while (true)
                {
                    CacheRequest request;

                    // Wait until the next request comes in.
                    if (!requestsPendingWork.WaitAndDequeue(/* waitTime */ 5000, out request))
                    {
                        continue;
                    }

                    // Process it.
                    switch (request.type)
                    {
                    case RequestType.READ:
                        BackgroundHandleReadRequest(request);
                        break;

                    case RequestType.WRITE:
                        BackgroundHandleWriteRequest(request);
                        break;

                    case RequestType.CLEAR:
                        BackgroundHandleClearRequest(request);
                        break;

                    default:
                        PolyUtils.Throw("Invalid cache request type, should be READ, WRITE or CLEAR.");
                        break;
                    }
                }
            }
            //catch (ThreadAbortException)
            //{
            //    // That's ok (happens on project shutdown).
            //}
            catch (Exception ex)
            {
                Debug.LogErrorFormat("Cache background thread crashed: " + ex);
            }
        }
Ejemplo n.º 8
0
        public CreateSegmentScreenViewModel(MainContext context, RideDto ride) : base(context)
        {
            segment     = new SegmentDto();
            Ride        = ride;
            count       = 1;
            displayText = "Tap on the map to set a start point";

            MapViewModel = new MapControlViewModel(
                context,
                Ride?.DisplayName ?? "Map",
                ride != null ? PolyUtils.GetMapLocations(Ride.Locations, Ride.Jumps) : new List <MapLocation>(),
                isReadOnly: false,
                showRideFeatures: false,
                goToMapPageOnClick: false,
                mapType: MapType.Satellite,
                canChangeMapType: true);

            MapViewModel.MapTapped += MapViewModel_MapTapped;
        }
Ejemplo n.º 9
0
        // dot(rayDir, rayDir) * t^2 + 2*t*dot(rayDir, rayOrig-center) + dot(rayOrig-center, rayOrig-center) - R*R=0
        public bool Hit(Ray ray, float tMin, float tMax, ref HitRecord record)
        {
            float a    = ray.Direction.LengthSquared; // dot(rayDir, rayDir)
            Vec3  temp = new Vec3();

            Vec3.Subtract(ray.Origin, this.Center, temp);
            float b = 2 * ray.Direction.Dot(temp);                    //2*dot(rayDir, rayOrig-center)
            float c = temp.LengthSquared - this.Radius * this.Radius; //dot(rayOrig-center, rayOrig-center) - R*R

            if (!PolyUtils.HasRealRoot(a, b, c))
            {
                // No hit
                return(false);
            }
            // Check first root for hit
            float firstRoot = PolyUtils.FirstRoot(a, b, c);

            if (firstRoot > tMin && firstRoot < tMax)
            {
                record.T     = firstRoot;
                record.Point = ray.PointAt(firstRoot);
                Vec3.Subtract(record.Point, this.Center, temp);
                record.Normal   = temp / this.Radius;
                record.Material = this.Material;
                return(true);
            }
            // Check second root for hit
            float secondRoot = PolyUtils.SecondRoot(a, b, c);

            if (secondRoot > tMin && secondRoot < tMax)
            {
                record.T     = secondRoot;
                record.Point = ray.PointAt(secondRoot);
                Vec3.Subtract(record.Point, this.Center, temp);
                record.Normal   = temp / this.Radius;
                record.Material = this.Material;
                return(true);
            }

            return(false);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Co-routine that services one PendingRequest. This method must be called with StartCoroutine.
        /// </summary>
        /// <param name="request">The request to service.</param>
        private IEnumerator HandleWebRequest(PendingRequest request, BufferHolder bufferHolder)
        {
            // NOTE: This method runs on the main thread, but never blocks -- the blocking part of the work is
            // done by yielding the UnityWebRequest, which releases the main thread for other tasks while we
            // are waiting for the web request to complete (by the miracle of coroutines).

            // Let the caller create the UnityWebRequest, configuring it as they want. The caller can set the URL,
            // method, headers, anything they want. The only thing they can't do is call Send(), as we're in charge
            // of doing that.
            UnityWebRequest webRequest = request.creationCallback();

            PtDebug.LogVerboseFormat("Web request: {0} {1}", webRequest.method, webRequest.url);

            bool cacheAllowed = cache != null && webRequest.method == "GET" && request.maxAgeMillis != CACHE_NONE;

            // Check the cache (if it's a GET request and cache is enabled).
            if (cacheAllowed)
            {
                bool   cacheHit      = false;
                byte[] cacheData     = null;
                bool   cacheReadDone = false;
                cache.RequestRead(webRequest.url, request.maxAgeMillis, (bool success, byte[] data) =>
                {
                    cacheHit      = success;
                    cacheData     = data;
                    cacheReadDone = true;
                });
                while (!cacheReadDone)
                {
                    yield return(null);
                }
                if (cacheHit)
                {
                    PtDebug.LogVerboseFormat("Web request CACHE HIT: {0}, response: {1} bytes",
                                             webRequest.url, cacheData.Length);
                    request.completionCallback(PolyStatus.Success(), /* responseCode */ 200, cacheData);

                    // Return the buffer to the pool for reuse.
                    CleanUpAfterWebRequest(bufferHolder);

                    yield break;
                }
                else
                {
                    PtDebug.LogVerboseFormat("Web request CACHE MISS: {0}.", webRequest.url);
                }
            }

            DownloadHandlerBuffer handler = new DownloadHandlerBuffer();

            webRequest.downloadHandler = handler;

            // We need to asset that we actually succeeded in setting the download handler, because this can fail
            // if, for example, the creation callback mistakenly called Send().
            PolyUtils.AssertTrue(webRequest.downloadHandler == handler,
                                 "Couldn't set download handler. It's either disposed of, or the creation callback mistakenly called Send().");

            // Start the web request. This will suspend this coroutine until the request is done.
            PtDebug.LogVerboseFormat("Sending web request: {0}", webRequest.url);
            yield return(UnityCompat.SendWebRequest(webRequest));

            // Request is finished. Call user-supplied callback.
            PtDebug.LogVerboseFormat("Web request finished: {0}, HTTP response code {1}, response: {2}",
                                     webRequest.url, webRequest.responseCode, webRequest.downloadHandler.text);
            PolyStatus status = UnityCompat.IsNetworkError(webRequest) ? PolyStatus.Error(webRequest.error) : PolyStatus.Success();

            request.completionCallback(status, (int)webRequest.responseCode, webRequest.downloadHandler.data);

            // Cache the result, if applicable.
            if (!UnityCompat.IsNetworkError(webRequest) && cacheAllowed)
            {
                byte[] data = webRequest.downloadHandler.data;
                if (data != null && data.Length > 0)
                {
                    byte[] copy = new byte[data.Length];
                    Buffer.BlockCopy(data, 0, copy, 0, data.Length);
                    cache.RequestWrite(webRequest.url, copy);
                }
            }

            // Clean up.
            webRequest.Dispose();
            CleanUpAfterWebRequest(bufferHolder);
        }
Ejemplo n.º 11
0
    public void Generate()
    {
        var multigrid = new MultiGrid(Divisions, Dimensions, Offset, MinDistance, MaxDistance, colorRatio, colorIndex, colorIntersect);

        (poly, shapes, colors) = multigrid.Build(SharedVertices, randomize);
        if (shapes.Count == 0)
        {
            return;
        }
        if (ColorMethod == PolyHydraEnums.ColorMethods.ByTags)
        {
            float colorMin = colors.Min();
            float colorMax = colors.Max();

            for (var faceIndex = 0; faceIndex < poly.Faces.Count; faceIndex++)
            {
                var   face       = poly.Faces[faceIndex];
                var   colorIndex = colors[faceIndex];
                float colorValue;
                switch (ColorFunction)
                {
                case ColorFunctions.Mod:
                    colorValue = colorIndex % 1;
                    break;

                case ColorFunctions.ActualMod:
                    colorValue = PolyUtils.ActualMod(colorIndex, 1);
                    break;

                case ColorFunctions.Normalized:
                    colorValue = Mathf.InverseLerp(colorMin, colorMax, colorIndex);
                    break;

                case ColorFunctions.Abs:
                    colorValue = Mathf.Abs(colorIndex);
                    break;

                default:
                    colorValue = colorIndex;
                    break;
                }
                string colorString = ColorUtility.ToHtmlStringRGB(ColorGradient.Evaluate(colorValue));
                var    tag         = new Tuple <string, ConwayPoly.TagType>(
                    $"#{colorString}",
                    TagType);
                poly.FaceTags[faceIndex].Add(tag);
            }
        }

        if (ApplyOp)
        {
            var o1 = new OpParams {
                valueA = op1Amount1, valueB = op1Amount2, facesel = op1Facesel
            };
            poly = poly.ApplyOp(op1, o1);
            var o2 = new OpParams {
                valueA = op2Amount1, valueB = op2Amount2, facesel = op2Facesel
            };
            poly = poly.ApplyOp(op2, o2);
            var o3 = new OpParams {
                valueA = op3Amount1, valueB = op3Amount2, facesel = op3Facesel
            };
            poly = poly.ApplyOp(op3, o3);
        }

        var mesh = PolyMeshBuilder.BuildMeshFromConwayPoly(poly, false, null, ColorMethod);

        GetComponent <MeshFilter>().mesh = mesh;
    }
Ejemplo n.º 12
0
        private static ConwayPoly _MakeCupola(int sides, float height, bool bi = false, bool gyro = true)
        {
            sides = Mathf.Clamp(sides, 3, 64);

            ConwayPoly poly   = _MakePolygon(sides * 2);
            Face       bottom = poly.Faces[0];
            ConwayPoly cap1   = _MakePolygon(sides, true, 0.25f, height, _CalcCupolaCapRadius(sides));

            poly.Append(cap1);

            int i = 0;
            var squareSideFaces = new List <Face>();
            var edge1           = poly.Halfedges[0];
            var edge2           = poly.Halfedges[sides * 2];

            while (true)
            {
                var side1 = new List <Vertex>
                {
                    edge1.Next.Vertex,
                    edge1.Vertex,
                    edge2.Prev.Vertex
                };
                poly.Faces.Add(side1);
                poly.FaceRoles.Add(ConwayPoly.Roles.New);
                poly.FaceTags.Add(new HashSet <Tuple <string, ConwayPoly.TagType> >());

                var side2 = new List <Vertex>
                {
                    edge1.Vertex,
                    edge1.Prev.Vertex,
                    edge2.Vertex,
                    edge2.Prev.Vertex
                };
                poly.Faces.Add(side2);
                squareSideFaces.Add(poly.Faces.Last());
                poly.FaceRoles.Add(ConwayPoly.Roles.NewAlt);
                poly.FaceTags.Add(new HashSet <Tuple <string, ConwayPoly.TagType> >());

                i++;
                edge1 = edge1.Next.Next;
                edge2 = edge2.Prev;
                if (i == sides)
                {
                    break;
                }
            }

            if (bi)
            {
                float      angleOffset = gyro ? 0.75f : 0.25f;
                ConwayPoly cap2        = _MakePolygon(sides, false, angleOffset, -height, _CalcCupolaCapRadius(sides));
                poly.Append(cap2);

                i = 0;
                var middleVerts = bottom.GetVertices();

                poly.Faces.Remove(bottom);
                poly.FaceRoles.RemoveAt(0);

                edge2 = poly.Faces.Last().Halfedge.Prev;
                int indexOffset = gyro ? 0 : -1;
                while (true)
                {
                    var side1 = new List <Vertex>
                    {
                        middleVerts[PolyUtils.ActualMod(i * 2 - 1 + indexOffset, sides * 2)],
                        middleVerts[PolyUtils.ActualMod(i * 2 + indexOffset, sides * 2)],
                        edge2.Vertex
                    };
                    poly.Faces.Add(side1);
                    poly.FaceRoles.Add(ConwayPoly.Roles.New);
                    poly.FaceTags.Add(new HashSet <Tuple <string, ConwayPoly.TagType> >());

                    var side2 = new List <Vertex>
                    {
                        middleVerts[PolyUtils.ActualMod(i * 2 + indexOffset, sides * 2)],
                        middleVerts[PolyUtils.ActualMod(i * 2 + 1 + indexOffset, sides * 2)],
                        edge2.Next.Vertex,
                        edge2.Vertex,
                    };
                    poly.Faces.Add(side2);
                    poly.FaceRoles.Add(ConwayPoly.Roles.NewAlt);
                    poly.FaceTags.Add(new HashSet <Tuple <string, ConwayPoly.TagType> >());

                    i++;
                    edge2 = edge2.Next;

                    if (i == sides)
                    {
                        break;
                    }
                }
            }

            poly.Halfedges.MatchPairs();
            return(poly);
        }