private static void CleanCache() { if (NextCleanTime > DateTime.UtcNow) { return; } List <uint> removeMids = new List <uint>(); lock (FaceCacheDict) { foreach (uint mid in FaceCacheDict.Keys) { FaceCache faceCache = FaceCacheDict[mid]; if (faceCache.Expire < DateTime.UtcNow) { removeMids.Add(mid); } } foreach (uint mid in removeMids) { FaceCacheDict.Remove(mid); } } NextCleanTime = DateTime.UtcNow.AddSeconds(5); Console.WriteLine("Cache cleaned {0}/{1}", removeMids.Count, FaceCacheDict.Count + removeMids.Count); }
public static void LoadFaceWithKnownUri(ILoadFace loadFace, string backupUri) { if (LoadFormCache(loadFace)) { return; } Uri uri = new Uri(backupUri); Task.Factory.StartNew(() => { FaceCache newFaceCache = new FaceCache(uri, loadFace); //newFaceCache.ApplyTo(loadFace); lock (FaceCacheDict) { if (!FaceCacheDict.ContainsKey(loadFace.UserId)) { FaceCacheDict.Add(loadFace.UserId, newFaceCache); } } CleanCache(); CachedCountChanged?.Invoke(FaceCacheDict.Count); }); }
public static bool LoadFormCache(ILoadFace loadFace) { if (FaceCacheDict.ContainsKey(loadFace.UserId)) { FaceCache faceCache = FaceCacheDict[loadFace.UserId]; faceCache.Expire = DateTime.UtcNow.AddMinutes(30); faceCache.ApplyTo(loadFace); return(true); } return(false); }
private Dictionary <string, FaceCache> ProcessModel(BlockStateModel raw, out Vector3 min, out Vector3 max) { float facesMinX = float.MaxValue, facesMinY = float.MaxValue, facesMinZ = float.MaxValue; float facesMaxX = float.MinValue, facesMaxY = float.MinValue, facesMaxZ = float.MinValue; Dictionary <string, FaceCache> faceCaches = new Dictionary <string, FaceCache>(); var model = raw.Model; for (var index = 0; index < model.Elements.Length; index++) { var element = model.Elements[index]; element.To *= Scale; element.From *= Scale; FaceCache cache = new FaceCache(); foreach (var face in element.Faces) { var uv = face.Value.UV; float x1 = 0, x2 = 0, y1 = 0, y2 = 0; if (uv == null) { switch (face.Key) { case BlockFace.North: case BlockFace.South: x1 = element.From.X; x2 = element.To.X; y1 = 16f - element.To.Y; y2 = 16f - element.From.Y; break; case BlockFace.West: case BlockFace.East: x1 = element.From.Z; x2 = element.To.Z; y1 = 16f - element.To.Y; y2 = 16f - element.From.Y; break; case BlockFace.Down: case BlockFace.Up: x1 = element.From.X; x2 = element.To.X; y1 = 16f - element.To.Z; y2 = 16f - element.From.Z; break; } } else { x1 = uv.X1; x2 = uv.X2; y1 = uv.Y1; y2 = uv.Y2; } var verts = GetFaceVertices(face.Key, element.From, element.To, GetTextureUVMap(Resources, ResolveTexture(raw, face.Value.Texture), x1, x2, y1, y2, face.Value.Rotation), out int[] indexes); float minX = float.MaxValue, minY = float.MaxValue, minZ = float.MaxValue; float maxX = float.MinValue, maxY = float.MinValue, maxZ = float.MinValue; for (int i = 0; i < verts.Length; i++) { var v = verts[i]; if (element.Rotation.Axis != Axis.Undefined) { var r = element.Rotation; var angle = (float)(r.Angle * (Math.PI / 180f)); //angle = r.Axis == Axis.Z ? angle : -angle; //angle = r.Axis == Axis.Y ? -angle : angle; var origin = r.Origin; var c = MathF.Cos(angle); var s = MathF.Sin(angle); switch (r.Axis) { case Axis.Y: { var x = v.Position.X - origin.X; var z = v.Position.Z - origin.Z; v.Position.X = origin.X + (x * c - z * s); v.Position.Z = origin.Z + (z * c + x * s); } break; case Axis.X: { var x = v.Position.Z - origin.Z; var z = v.Position.Y - origin.Y; v.Position.Z = origin.Z + (x * c - z * s); v.Position.Y = origin.Y + (z * c + x * s); } break; case Axis.Z: { var x = v.Position.X - origin.X; var z = v.Position.Y - origin.Y; v.Position.X = origin.X + (x * c - z * s); v.Position.Y = origin.Y + (z * c + x * s); } break; } } if (raw.X > 0) { var rotX = (float)(raw.X * (Math.PI / 180f)); var c = MathF.Cos(rotX); var s = MathF.Sin(rotX); var z = v.Position.Z - 8f; var y = v.Position.Y - 8f; v.Position.Z = 8f + (z * c - y * s); v.Position.Y = 8f + (y * c + z * s); } if (raw.Y > 0) { var rotX = (float)(raw.Y * (Math.PI / 180f)); var c = MathF.Cos(rotX); var s = MathF.Sin(rotX); var z = v.Position.X - 8f; var y = v.Position.Z - 8f; v.Position.X = 8f + (z * c - y * s); v.Position.Z = 8f + (y * c + z * s); } v.Position /= 16f; if (v.Position.X < minX) { minX = v.Position.X; } else if (v.Position.X > maxX) { maxX = v.Position.X; } if (v.Position.Y < minY) { minY = v.Position.Y; } else if (v.Position.Y > maxY) { maxY = v.Position.Y; } if (v.Position.Z < minZ) { minZ = v.Position.Z; } else if (v.Position.Z > maxZ) { maxZ = v.Position.Z; } verts[i] = v; } if (element.Rotation.Axis != Axis.Undefined && element.Rotation.Rescale) { var diffX = maxX - minX; var diffY = maxY - minY; var diffZ = maxZ - minZ; for (var i = 0; i < verts.Length; i++) { var v = verts[i]; v.Position.X = (v.Position.X - minX) / diffX; v.Position.Y = (v.Position.Y - minY) / diffY; v.Position.Z = (v.Position.Z - minZ) / diffZ; verts[i] = v; if (v.Position.X < facesMinX) { facesMinX = v.Position.X; } else if (v.Position.X > facesMaxX) { facesMaxX = v.Position.X; } if (v.Position.Y < facesMinY) { facesMinY = v.Position.Y; } else if (v.Position.Y > facesMaxY) { facesMaxY = v.Position.Y; } if (v.Position.Z < facesMinZ) { facesMinZ = v.Position.Z; } else if (v.Position.Z > facesMaxZ) { facesMaxZ = v.Position.Z; } } } if (minX < facesMinX) { facesMinX = minX; } else if (maxX > facesMaxX) { facesMaxX = maxX; } if (minY < facesMinY) { facesMinY = minY; } else if (maxY > facesMaxY) { facesMaxY = maxY; } if (minZ < facesMinZ) { facesMinZ = minZ; } else if (maxZ > facesMaxZ) { facesMaxZ = maxZ; } cache.Set(face.Key, new FaceData(verts, indexes, face.Value.Rotation, null)); } faceCaches.Add(index.ToString(), cache); } min = new Vector3(facesMinX, facesMinY, facesMinZ); max = new Vector3(facesMaxX, facesMaxY, facesMaxZ); return(faceCaches); }
private static void LoadFaceAndWait(ILoadFace loadFace) { if (FaceCacheDict.ContainsKey(loadFace.UserId)) { FaceCache faceCache = FaceCacheDict[loadFace.UserId]; faceCache.Expire = DateTime.UtcNow.AddMinutes(30); faceCache.ApplyTo(loadFace); } else { if (DateTime.Now < bolckUntil) { return; } //DateTime startTime = DateTime.UtcNow; Uri uri; while (true) { try { uri = LoadFaceUriFromApi(loadFace.UserId); break; } catch (WebException ex) { if (ex.Status == WebExceptionStatus.Timeout) { Console.WriteLine(ex); Thread.Sleep(1000); } else if (ex.Response != null && ((HttpWebResponse)ex.Response).StatusCode == HttpStatusCode.PreconditionFailed) { bolckUntil = DateTime.Now.AddMinutes(blockMinutes); Console.WriteLine($"Face API has been blocked, expected until {bolckUntil}"); return; } else { Console.WriteLine(ex); return; } } } if (uri != null) { FaceCache faceCache = new FaceCache(uri, loadFace); //faceCache.ApplyTo(loadFace); lock (FaceCacheDict) { if (!FaceCacheDict.ContainsKey(loadFace.UserId)) { FaceCacheDict.Add(loadFace.UserId, faceCache); } } } //DateTime endTime = DateTime.UtcNow; //TimeSpan timeSpan = endTime - startTime; //int waitTime = requestInterval - (int)timeSpan.TotalMilliseconds; //if (waitTime < 0) // waitTime = 0; //Thread.Sleep(waitTime); Thread.Sleep(requestInterval); } }