Skip to content

Instantly share code, notes, and snippets.

@z3nth10n
Last active October 28, 2019 20:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save z3nth10n/35a3ae22064d4ab85abb05b4e15bc854 to your computer and use it in GitHub Desktop.
Save z3nth10n/35a3ae22064d4ab85abb05b4e15bc854 to your computer and use it in GitHub Desktop.

Images:

Sapling:

#1

I need to cross the two quads, but they are parallel. I need to show this:

...

Button:

#2

I need to scale the cube correctly in order to show this:

...

using System.Collections;
using System.Collections.Generic;
using BayatGames.Frameworks.Voxel3D;
using UnityEngine;
namespace UnityCraft.Tests
{
public class CustomRenderers : MonoBehaviour
{
private MeshData saplingMeshData;
private MeshData buttonMeshData;
private MeshData levelMeshData;
private static Rect[] NullRects => new[]
{
Rect.zero,
Rect.zero,
Rect.zero,
Rect.zero,
Rect.zero,
Rect.zero
};
// Start is called before the first frame update
private void Start()
{
saplingMeshData = new MeshData();
buttonMeshData = new MeshData();
levelMeshData = new MeshData();
saplingMeshData.AddCross(Vector3.zero, 0, Rect.zero, Rect.zero);
buttonMeshData.AddScaledCube(Vector3.zero, 0, NullRects, new Vector3(.4f, .2f, .3f));
saplingMeshData.CreateGameObject("Sapling");
buttonMeshData.CreateGameObject("Button");
//levelMeshData.CreateGameObject("Level");
}
// Update is called once per frame
private void Update()
{
}
}
public static class F
{
public static GameObject CreateGameObject(this MeshData data, string name)
{
var mesh = data.BuildMesh(name);
var gameObject = new GameObject(name);
var meshFilter = gameObject.AddComponent<MeshFilter>();
meshFilter.mesh = mesh;
var meshRenderer = gameObject.AddComponent<MeshRenderer>();
return gameObject;
}
}
}
using System;
using System.Collections.Generic;
using UnityEngine;
namespace UnityCraft.Voxel3D
{
[Serializable]
public class MeshData
{
[SerializeField]
protected List<Vector3> vertices = new List<Vector3>();
[SerializeField]
protected List<List<int>> triangles = new List<List<int>>();
[SerializeField]
protected List<Vector2> uv = new List<Vector2>();
public virtual int SubMeshCount
{
get => triangles.Count;
set
{
if (value > triangles.Count)
{
int difference = value - triangles.Count;
for (int i = 0; i < difference; i++)
{
triangles.Add(new List<int>());
}
}
else if (triangles.Count > value)
{
int difference = triangles.Count - value;
for (int i = 0; i < difference; i++)
{
triangles.RemoveAt(triangles.Count - i);
}
}
}
}
public virtual List<Vector3> Vertices => vertices;
public virtual List<List<int>> Triangles => triangles;
public virtual List<Vector2> UV => uv;
public MeshData() : this(1)
{
}
public MeshData(int subMeshCount)
{
SubMeshCount = subMeshCount;
}
public virtual void AddVertex(Vector3 vertex)
{
vertices.Add(vertex);
}
public virtual void AddTriangle(int subMesh, int triangle)
{
if (subMesh >= triangles.Count)
{
return;
}
triangles[subMesh].Add(triangle);
}
public virtual void AddUV(Vector2 uv)
{
this.uv.Add(uv);
}
public virtual void AddCube(Vector3 position, Rect[] uvs)
{
AddCube(position, 0, uvs);
}
public virtual void AddCube(Vector3 position, int subMesh, Rect[] uvs)
{
AddQuad(position, subMesh, VoxelDirection.Forward, uvs[0]);
AddQuad(position, subMesh, VoxelDirection.Back, uvs[1]);
AddQuad(position, subMesh, VoxelDirection.Right, uvs[2]);
AddQuad(position, subMesh, VoxelDirection.Left, uvs[3]);
AddQuad(position, subMesh, VoxelDirection.Up, uvs[4]);
AddQuad(position, subMesh, VoxelDirection.Down, uvs[5]);
}
public virtual void AddScaledCube(Vector3 position, int subMesh, Rect[] uvs, Vector3 scale)
{
AddQuad(position, subMesh, VoxelDirection.Forward, uvs[0], scale);
AddQuad(position, subMesh, VoxelDirection.Back, uvs[1], scale);
AddQuad(position, subMesh, VoxelDirection.Right, uvs[2], scale);
AddQuad(position, subMesh, VoxelDirection.Left, uvs[3], scale);
AddQuad(position, subMesh, VoxelDirection.Up, uvs[4], scale);
AddQuad(position, subMesh, VoxelDirection.Down, uvs[5], scale);
}
public virtual void AddScaledCube(Vector3 position, int subMesh, Rect[] uvs, Vector3[] scales)
{
AddQuad(position, subMesh, VoxelDirection.Forward, uvs[0], scales[0]);
AddQuad(position, subMesh, VoxelDirection.Back, uvs[1], scales[1]);
AddQuad(position, subMesh, VoxelDirection.Right, uvs[2], scales[2]);
AddQuad(position, subMesh, VoxelDirection.Left, uvs[3], scales[3]);
AddQuad(position, subMesh, VoxelDirection.Up, uvs[4], scales[4]);
AddQuad(position, subMesh, VoxelDirection.Down, uvs[5], scales[5]);
}
public virtual void AddCross(Vector3 position, int subMesh, params Rect[] uvs)
{
AddQuad(position, VoxelDirection.Diagonal1, uvs[0]);
AddQuad(position, VoxelDirection.Diagonal2, uvs[1]);
}
public virtual void AddQuad(Vector3 position, VoxelDirection direction, Rect uv)
{
AddQuad(position, 0, direction, uv);
}
public virtual void AddQuad(Vector3 position, int subMesh, VoxelDirection direction, Rect uv, Vector3 scale = default)
{
if (scale == default)
scale = Vector3.one;
switch (direction)
{
case VoxelDirection.Forward:
vertices.Add((position + Vector3.forward + Vector3.left) * scale.z);
vertices.Add((position + Vector3.forward) * scale.z);
vertices.Add((position + Vector3.forward + Vector3.left + Vector3.up) * scale.z);
vertices.Add((position + Vector3.forward + Vector3.up) * scale.z);
break;
case VoxelDirection.Back:
vertices.Add(position * scale.z);
vertices.Add((position + Vector3.left) * scale.x);
vertices.Add((position + Vector3.up) * scale.x);
vertices.Add((position + Vector3.left + Vector3.up) * scale.x);
break;
case VoxelDirection.Right:
vertices.Add((position + Vector3.forward) * scale.x);
vertices.Add(position * scale.x);
vertices.Add((position + Vector3.forward + Vector3.up) * scale.x);
vertices.Add((position + Vector3.up) * scale.x);
break;
case VoxelDirection.Left:
vertices.Add((position + Vector3.left) * scale.x);
vertices.Add((position + Vector3.left + Vector3.forward) * scale.x);
vertices.Add((position + Vector3.left + Vector3.up) * scale.x);
vertices.Add((position + Vector3.left + Vector3.forward + Vector3.up) * scale.x);
break;
case VoxelDirection.Up:
vertices.Add((position + Vector3.up) * scale.y);
vertices.Add((position + Vector3.up + Vector3.left) * scale.y);
vertices.Add((position + Vector3.up + Vector3.forward) * scale.y);
vertices.Add((position + Vector3.up + Vector3.forward + Vector3.left) * scale.y);
break;
case VoxelDirection.Down:
vertices.Add((position + Vector3.forward) * scale.y);
vertices.Add((position + Vector3.forward + Vector3.left) * scale.y);
vertices.Add(position * scale.y);
vertices.Add((position + Vector3.left) * scale.y);
break;
case VoxelDirection.Diagonal1:
vertices.Add(position);
vertices.Add(position + Vector3.up);
vertices.Add(position + Vector3.right + Vector3.forward);
vertices.Add(position + Vector3.one);
break;
case VoxelDirection.Diagonal2:
vertices.Add(position + Vector3.forward);
vertices.Add(position + Vector3.forward + Vector3.up);
vertices.Add(position + Vector3.left);
vertices.Add(position + Vector3.left + Vector3.up);
break;
}
triangles[subMesh].Add(vertices.Count - 4);
triangles[subMesh].Add(vertices.Count - 3);
triangles[subMesh].Add(vertices.Count - 2);
triangles[subMesh].Add(vertices.Count - 3);
triangles[subMesh].Add(vertices.Count - 1);
triangles[subMesh].Add(vertices.Count - 2);
this.uv.Add(new Vector2(uv.x + uv.width, uv.y));
this.uv.Add(new Vector2(uv.x, uv.y));
this.uv.Add(new Vector2(uv.x + uv.width, uv.y + uv.height));
this.uv.Add(new Vector2(uv.x, uv.y + uv.height));
}
public virtual Mesh BuildMesh(string name = "")
{
// Debug.Log($"Creating mesh {name}! (Reviewing stacktrace)");
Mesh mesh = new Mesh
{
subMeshCount = triangles.Count,
vertices = vertices.ToArray(),
name = name
};
for (int i = 0; i < triangles.Count; i++)
{
mesh.SetTriangles(triangles[i], i, true);
}
mesh.uv = uv.ToArray();
mesh.RecalculateBounds();
mesh.RecalculateNormals();
mesh.RecalculateTangents();
return mesh;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment