Last active
May 3, 2017 07:04
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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