Skip to content

Instantly share code, notes, and snippets.

@chheller
Last active May 3, 2017 07:04
Show Gist options
  • Save chheller/07db5c5d31ee7685fdf8c4adba229fc8 to your computer and use it in GitHub Desktop.
Save chheller/07db5c5d31ee7685fdf8c4adba229fc8 to your computer and use it in GitHub Desktop.
Initial draft of a tool for generating graphs in 3D space as an effect for Unity
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Voxyl : MonoBehaviour {
public GameObject Target;
public GameObject GraphLine;
public Vector3 Scale;
public Vector3 Rotation;
public int Subdivisions;
public int MajorTicks;
public GameObject testSphere;
private GameObject self;
private Graph graph;
Bounds bounds;
private static uint INSTANCES;
void Awake()
{
if (self == null)
{
self = new GameObject();
self.transform.parent = Target.transform;
self.name = string.Format("Voxyl Graph {0}", Voxyl.INSTANCES);
}
if (graph == null)
{
graph = new Graph((Subdivisions + 1), (Subdivisions + 1), (Subdivisions + 1));
}
}
private void Start()
{
if (Target.GetComponent<Renderer>() != null)
bounds = Target.GetComponent<Renderer>().bounds;
else
bounds = new Bounds();
foreach (var childRenderer in Target.GetComponentsInChildren<Renderer>())
{
Debug.Log("Enlarging Bounds");
bounds.Encapsulate(childRenderer.bounds);
}
CreateGraph();
VisualizeGraph();
CreateMeshPlane(PlaneType.XY);
CreateMeshPlane(PlaneType.XZ);
CreateMeshPlane(PlaneType.YZ);
}
public void VisualizeGraph()
{
int dimensions = (Subdivisions + 1) * (Subdivisions + 1) * (Subdivisions + 1);
GameObject go = new GameObject();
for (int i = 0; i < dimensions; i++)
{
GameObject t = Instantiate(testSphere, go.transform);
t.transform.position = graph.Points[i % (Subdivisions + 1)][(i / (Subdivisions + 1)) % (Subdivisions + 1)][(i / ((Subdivisions + 1) * (Subdivisions + 1))) % (Subdivisions + 1)];
}
}
private GameObject CreateMesh(Vector3 pointA, Vector3 pointB, Quaternion rotation, Vector3 offset, Vector3 localScale)
{
GameObject gridLine = Instantiate(GraphLine, self.transform);
gridLine.transform.position += offset;
gridLine.transform.rotation = rotation;
gridLine.transform.localScale = localScale;
return gridLine;
}
private void CreateGraph()
{
Vector3 step = bounds.size / Subdivisions;
Debug.Log(step);
Vector3 point = new Vector3();
for (int x = 0; x < (Subdivisions + 1); x++)
{
for (int y = 0; y < (Subdivisions + 1); y++)
{
for (int z = 0; z < (Subdivisions + 1); z++)
{
point.Set(bounds.min.x + step.x * x, bounds.min.y + step.y * y, bounds.min.z + step.z * z);
//Debug.Log(point);
graph.Points[x][y][z] = point;
}
}
}
}
private enum PlaneType
{
XZ, XY, YZ
}
private GameObject[] CreateMeshPlane(PlaneType planeType)
{
GameObject graph = new GameObject();
graph.name = string.Format("New {0} graph plane", planeType.ToString());
GameObject[] gridLines = new GameObject[(Subdivisions + 1) * (Subdivisions + 1)];
Vector3 start = new Vector3();
Vector3 end = new Vector3();
Vector3 step = bounds.size / Subdivisions;
Vector3 scale = new Vector3();
Color color;
Material material = GraphLine.GetComponent<Renderer>().sharedMaterial;
Color minorColor = new Color(material.color.r, material.color.g, material.color.b, material.color.a / 3f);
Color majorColor = Color.blue;
float distance;
switch (planeType)
{
case PlaneType.XZ:
for (int x = 0; x < (Subdivisions + 1); x++)
{
for (int z = 0; z < (Subdivisions + 1); z++)
{
for (int y = 0; y < (Subdivisions); y++)
{
Instantiate(testSphere, new Vector3(this.graph.Points[x][y][z].x, this.graph.Points[x][y][z].y, this.graph.Points[x][y][z].z), Quaternion.identity, Target.transform);
GameObject line = Instantiate(GraphLine, graph.transform);
start.Set(this.graph.Points[x][y][z].x, this.graph.Points[x][y][z].y, this.graph.Points[x][y][z].z);
end.Set(start.x, start.y + step.y, start.z);
material = line.GetComponent<Renderer>().material;
color = (x % (Subdivisions / MajorTicks) == 0 && z % (Subdivisions / MajorTicks) == 0) ? majorColor : minorColor;
material.SetColor("_Color", color);
distance = Vector3.Distance(start, end);
scale.Set(line.transform.localScale.x, 0.5f * distance, line.transform.localScale.z);
line.transform.position = start + 0.5f * distance * Vector3.up;
line.transform.localScale = scale;
//line.transform.LookAt(this.graph.Points[x][y][z], Vector3.up);
line.transform.localRotation = Quaternion.Euler(0, 0, 0) ;
gridLines[x * z] = line;
}
}
}
break;
case PlaneType.XY:
for (int x = 0; x < (Subdivisions ); x++)
{
for (int y = 0; y < (Subdivisions + 1); y++)
{
for (int z = 0; z < (Subdivisions + 1); z++)
{
Instantiate(testSphere, new Vector3(this.graph.Points[x][y][z].x, this.graph.Points[x][y][z].y, this.graph.Points[x][y][z].z), Quaternion.identity, Target.transform);
GameObject line = Instantiate(GraphLine, graph.transform);
start.Set(this.graph.Points[x][y][z].x, this.graph.Points[x][y][z].y, this.graph.Points[x][y][z].z);
end.Set(start.x + step.x, start.y, start.z);
material = line.GetComponent<Renderer>().material;
color = (y % (Subdivisions / MajorTicks) == 0 && z % (Subdivisions / MajorTicks) == 0) ? majorColor : minorColor;
material.SetColor("_Color", color);
distance = Vector3.Distance(start, end);
scale.Set(line.transform.localScale.x, 0.5f * distance, line.transform.localScale.z);
line.transform.position = start + 0.5f * distance * Vector3.right;
line.transform.localScale = scale;
//line.transform.LookAt(this.graph.Points[x][y][z], Vector3.up);
line.transform.localRotation = Quaternion.Euler(0, 0, 90);
gridLines[x * z] = line;
}
}
}
break;
case PlaneType.YZ:
for (int y = 0; y < (Subdivisions + 1); y++)
{
for (int z = 0; z < (Subdivisions); z++)
{
for (int x = 0; x < (Subdivisions + 1); x++)
{
Instantiate(testSphere, new Vector3(this.graph.Points[x][y][z].x, this.graph.Points[x][y][z].y, this.graph.Points[x][y][z].z), Quaternion.identity, Target.transform);
GameObject line = Instantiate(GraphLine, graph.transform);
start.Set(this.graph.Points[x][y][z].x, this.graph.Points[x][y][z].y, this.graph.Points[x][y][z].z);
end.Set(start.x, start.y, start.z + step.z);
material = line.GetComponent<Renderer>().material;
color = (y % (Subdivisions / MajorTicks) == 0 && x % (Subdivisions / MajorTicks) == 0) ? majorColor : minorColor;
material.SetColor("_Color", color);
distance = Vector3.Distance(start, end);
scale.Set(line.transform.localScale.x, 0.5f * distance, line.transform.localScale.z);
line.transform.position = start + 0.5f * distance * Vector3.forward;
line.transform.localScale = scale;
//line.transform.LookAt(this.graph.Points[x][y][z], Vector3.up);
line.transform.localRotation = Quaternion.Euler(90, 0, 0);
gridLines[x * z] = line;
}
}
}
break;
}
return gridLines;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment