Skip to content

Instantly share code, notes, and snippets.

@jasursadikov
Created August 10, 2022 14:43
Show Gist options
  • Save jasursadikov/3b2987eaee69e1444ddee049307bd29f to your computer and use it in GitHub Desktop.
Save jasursadikov/3b2987eaee69e1444ddee049307bd29f to your computer and use it in GitHub Desktop.
360 sphere generator for VR videos
using UnityEngine;
public sealed class Dome
{
private readonly Vector2Int size;
private readonly float fill;
public Dome(Vector2Int size, float fill)
{
this.size = size;
this.fill = fill;
}
public Mesh Generate()
{
var mesh = new Mesh();
mesh.name = $"Dome [{fill}]";
var indices = new int[size.x, size.y];
var vertices = new Vector3[size.x, size.y];
var normals = new Vector3[size.x, size.y];
var uvs = new Vector2[size.x * size.y];
var triangles = new int[6 * (size.x + 1) * (size.y + 1)];
for (int i = 0, y = 0; y < size.y; y++)
for (int x = 0; x < size.x; x++, i++)
{
var radius = Mathf.Sin(Mathf.PI / 360 * fill / (size.y - 1) * y);
var px = Mathf.Cos(Mathf.PI * 2f / size.x * x) * radius;
var py = Mathf.Cos(Mathf.PI / 360 * fill / (size.y - 1) * y);
var pz = Mathf.Sin(Mathf.PI * 2f / size.x * x) * radius;
indices[x, y] = i;
vertices[x, y] = new Vector3(px, py, pz);
normals[x, y] = new Vector3(px, py, pz);
}
for (int t = 0, y = 0; y < size.y - 1; y++)
{
for (int x = 0; x < size.x - 1; x++)
{
triangles[t++] = indices[x, y];
triangles[t++] = indices[x, y + 1];
triangles[t++] = indices[x + 1, y + 1];
triangles[t++] = indices[x, y];
triangles[t++] = indices[x + 1, y + 1];
triangles[t++] = indices[x + 1, y];
}
triangles[t++] = indices[size.x - 1, y];
triangles[t++] = indices[size.x - 1, y + 1];
triangles[t++] = indices[0, y + 1];
triangles[t++] = indices[size.x - 1, y];
triangles[t++] = indices[0, y + 1];
triangles[t++] = indices[0, y];
}
for (int t = 0, y = 0; y < size.y; y++)
for (int x = 0; x < size.x; x++, t++)
{
var uvX = Mathf.Cos(Mathf.PI * 2f / size.x * x) * (-1f / size.y * y);
var uvY = Mathf.Sin(Mathf.PI * 2f / size.x * x) * (-1f / size.y * y);
uvs[t] = new Vector2(uvX, uvY) / 2f + Vector2.one / 2f;
}
mesh.vertices = MatrixToArray(vertices);
mesh.normals = MatrixToArray(normals);
mesh.uv = uvs;
mesh.triangles = triangles;
return mesh;
}
private T[] MatrixToArray<T>(T[,] matrix)
{
var result = new T[matrix.GetLength(0) * matrix.GetLength(1)];
for (int i = 0, y = 0; y < matrix.GetLength(1); y++)
for (int x = 0; x < matrix.GetLength(0); i++, x++)
result[i] = matrix[x, y];
return result;
}
}
using UnityEngine;
[RequireComponent(typeof(MeshFilter))]
[RequireComponent(typeof(MeshRenderer))]
public sealed class FisheyeGenerator : MonoBehaviour
{
[SerializeField] private MeshFilter target;
[SerializeField, Min(2)] private int rows;
[SerializeField, Min(3)] private int coloumns;
[SerializeField, Range(0, 360)] private float fill;
[ContextMenu("Generate")]
void Generate()
{
var dome = new Dome(new Vector2Int(rows, coloumns), fill);
target.mesh = dome.Generate();
}
[ContextMenu("Export")]
void Export()
{
}
#if UNITY_EDITOR
void OnValidate()
{
target = target ?? GetComponent<MeshFilter>();
fill = Mathf.Clamp(fill, 0, 360);
}
void OnDrawGizmosSelected()
{
Gizmos.matrix = transform.localToWorldMatrix;
Gizmos.color = Color.yellow;
if (target != null && target.mesh != null)
Gizmos.DrawWireMesh(target.mesh);
}
#endif
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment