private void OptimizeAtlas() { for (int atlasIndex = 0; atlasIndex < atlassedMaterials.Count; atlasIndex++) { var material = atlassedMaterials[atlasIndex]; Vector2 usedArea = new Vector2(0, 0); for (int atlasElementIndex = 0; atlasElementIndex < material.materialFragments.Count; atlasElementIndex++) { if (material.materialFragments[atlasElementIndex].atlasRegion.xMax > usedArea.x) { usedArea.x = material.materialFragments[atlasElementIndex].atlasRegion.xMax; } if (material.materialFragments[atlasElementIndex].atlasRegion.yMax > usedArea.y) { usedArea.y = material.materialFragments[atlasElementIndex].atlasRegion.yMax; } } //Headless mode ends up with zero usedArea if (Mathf.Approximately(usedArea.x, 0f) || Mathf.Approximately(usedArea.y, 0f)) { material.cropResolution = new Vector2(0.0f, 0.0f); return; } Vector2 tempResolution = new Vector2(umaGenerator.atlasResolution, umaGenerator.atlasResolution); bool done = false; while (!done && Mathf.Abs(usedArea.x) > 0.0001) { if (tempResolution.x * 0.5f >= usedArea.x) { tempResolution = new Vector2(tempResolution.x * 0.5f, tempResolution.y); } else { done = true; } } done = false; while (!done && Mathf.Abs(usedArea.y) > 0.0001) { if (tempResolution.y * 0.5f >= usedArea.y) { tempResolution = new Vector2(tempResolution.x, tempResolution.y * 0.5f); } else { done = true; } } material.cropResolution = tempResolution; } }
void Tick() { if (Event.current.type == EventType.Repaint) { float deltaTime = Time.realtimeSinceStartup - lastUpdate; // Right at the start of a transition the deltaTime will // not be reliable, so use a very small value instead // until the next repaint if (value == 0f || value == 1f) { deltaTime = 0.001f; } deltaTime = Mathf.Clamp(deltaTime, 0.00001F, 0.1F); // Larger regions fade slightly slower deltaTime /= Mathf.Sqrt(Mathf.Max(lastRect.height, 100)); lastUpdate = Time.realtimeSinceStartup; float targetValue = open ? 1F : 0F; if (!Mathf.Approximately(targetValue, value)) { value += deltaTime * animationSpeed * Mathf.Sign(targetValue - value); value = Mathf.Clamp01(value); editor.Repaint(); if (!fancyEffects) { value = targetValue; } } else { value = targetValue; } } }
RasterizationMesh RasterizeCapsuleCollider(float radius, float height, Bounds bounds, Matrix4x4 localToWorldMatrix) { // Calculate the number of rows to use // grows as sqrt(x) to the radius of the sphere/capsule which I have found works quite well int rows = Mathf.Max(4, Mathf.RoundToInt(colliderRasterizeDetail * Mathf.Sqrt(localToWorldMatrix.MultiplyVector(Vector3.one).magnitude))); if (rows > 100) { Debug.LogWarning("Very large detail for some collider meshes. Consider decreasing Collider Rasterize Detail (RecastGraph)"); } int cols = rows; Vector3[] verts; int[] trisArr; // Check if we have already calculated a similar capsule CapsuleCache cached = null; for (int i = 0; i < capsuleCache.Count; i++) { CapsuleCache c = capsuleCache[i]; if (c.rows == rows && Mathf.Approximately(c.height, height)) { cached = c; } } if (cached == null) { // Generate a sphere/capsule mesh verts = new Vector3[(rows) * cols + 2]; var tris = new List <int>(); verts[verts.Length - 1] = Vector3.up; for (int r = 0; r < rows; r++) { for (int c = 0; c < cols; c++) { verts[c + r * cols] = new Vector3(Mathf.Cos(c * Mathf.PI * 2 / cols) * Mathf.Sin((r * Mathf.PI / (rows - 1))), Mathf.Cos((r * Mathf.PI / (rows - 1))) + (r < rows / 2 ? height : -height), Mathf.Sin(c * Mathf.PI * 2 / cols) * Mathf.Sin((r * Mathf.PI / (rows - 1)))); } } verts[verts.Length - 2] = Vector3.down; for (int i = 0, j = cols - 1; i < cols; j = i++) { tris.Add(verts.Length - 1); tris.Add(0 * cols + j); tris.Add(0 * cols + i); } for (int r = 1; r < rows; r++) { for (int i = 0, j = cols - 1; i < cols; j = i++) { tris.Add(r * cols + i); tris.Add(r * cols + j); tris.Add((r - 1) * cols + i); tris.Add((r - 1) * cols + j); tris.Add((r - 1) * cols + i); tris.Add(r * cols + j); } } for (int i = 0, j = cols - 1; i < cols; j = i++) { tris.Add(verts.Length - 2); tris.Add((rows - 1) * cols + j); tris.Add((rows - 1) * cols + i); } // Add calculated mesh to the cache cached = new CapsuleCache(); cached.rows = rows; cached.height = height; cached.verts = verts; cached.tris = tris.ToArray(); capsuleCache.Add(cached); } // Read from cache verts = cached.verts; trisArr = cached.tris; return(new RasterizationMesh(verts, trisArr, bounds, localToWorldMatrix)); }