You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

279 lines
11 KiB

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace UltraCombos.Frozen
{
[ExecuteInEditMode]
public class SpaceMeshGenerator : MonoBehaviour
{
[SerializeField]
bool update = false;
[SerializeField]
int width = 8;
[SerializeField]
int length = 5;
[SerializeField]
int height = 3;
[SerializeField]
bool isAnimated = false;
Vector3 size = Vector3.zero;
private void Start()
{
update = true;
if (Application.isPlaying)
{
var renderers = GetComponentsInChildren<MeshRenderer>();
if (renderers.Length > 1)
{
renderers[1].material.SetFloat("_isGamma", isAnimated ? 1.0f : 0.0f);
}
SceneController.Instance.spaceMaterials.Clear();
foreach (var rdr in renderers)
{
SceneController.Instance.spaceMaterials.Add(rdr.material);
}
if (isAnimated)
{
var players = GetComponentsInChildren<DShowMoviePlayer>(true);
foreach (var mp in players)
{
mp.gameObject.SetActive(true);
}
var texture_applys = GetComponentsInChildren<MovieTextureApply>(true);
foreach (var ta in texture_applys)
{
ta.materials.Clear();
ta.materials.Add(renderers[1].material);
}
}
}
}
private void Update()
{
size.Set(width, height, length);
if (update)
{
update = false;
ClearFilterMesh();
}
var mesh_filters = GetComponentsInChildren<MeshFilter>();
for (int i = 0; i < mesh_filters.Length; i++)
{
var filter = mesh_filters[i];
if (filter.sharedMesh == null)
{
if (Application.isPlaying)
{
filter.sharedMesh = (i == 0) ? CreateGroundMesh() : CreateWallMesh();
}
else if (i == 0)
{
filter.sharedMesh = CreateGroundMesh();
}
}
}
}
private void OnDrawGizmosSelected()
{
var center = transform.position;
center.y += size.y * 0.5f;
var c = Gizmos.color;
Gizmos.color = Color.cyan;
Gizmos.DrawWireCube(center, size);
Gizmos.color = c;
}
private void ClearFilterMesh()
{
var mesh_filters = GetComponentsInChildren<MeshFilter>();
foreach (var filter in mesh_filters)
{
if (Application.isPlaying)
Destroy(filter.sharedMesh);
else
DestroyImmediate(filter.sharedMesh);
filter.sharedMesh = null;
}
}
private Mesh CreateWallMesh()
{
var half_size = size * 0.5f;
var tex_size = new Vector2(width, height * 3.0f);
var points = new List<Vector3>();
points.Add(new Vector3(-half_size.x, 0.0f, -half_size.z));
points.Add(new Vector3(-half_size.x, 0.0f, +half_size.z));
points.Add(new Vector3(+half_size.x, 0.0f, -half_size.z));
points.Add(new Vector3(+half_size.x, 0.0f, +half_size.z));
points.Add(new Vector3(-half_size.x, size.y, -half_size.z));
points.Add(new Vector3(-half_size.x, size.y, +half_size.z));
points.Add(new Vector3(+half_size.x, size.y, -half_size.z));
points.Add(new Vector3(+half_size.x, size.y, +half_size.z));
var vertices = new List<Vector3>();
var uvs = new List<Vector2>();
var indices = new List<int>();
var normals = new List<Vector3>();
// Front
AddIndexAndNormal(indices, vertices.Count, normals, new Vector3(0, 0, -1));
vertices.Add(points[1]);
vertices.Add(points[5]);
vertices.Add(points[3]);
vertices.Add(points[7]);
uvs.Add(new Vector2(0.0f, height * 1.0f / tex_size.y));
uvs.Add(new Vector2(0.0f, height * 0.0f / tex_size.y));
uvs.Add(new Vector2(width / tex_size.x, height * 1.0f / tex_size.y));
uvs.Add(new Vector2(width / tex_size.x, height * 0.0f / tex_size.y));
// Left
AddIndexAndNormal(indices, vertices.Count, normals, new Vector3(1, 0, 0));
vertices.Add(points[0]);
vertices.Add(points[4]);
vertices.Add(points[1]);
vertices.Add(points[5]);
uvs.Add(new Vector2(0.0f, height * 2.0f / tex_size.y));
uvs.Add(new Vector2(0.0f, height * 1.0f / tex_size.y));
uvs.Add(new Vector2(length / tex_size.x, height * 2.0f / tex_size.y));
uvs.Add(new Vector2(length / tex_size.x, height * 1.0f / tex_size.y));
// Right
AddIndexAndNormal(indices, vertices.Count, normals, new Vector3(-1, 0, 0));
vertices.Add(points[3]);
vertices.Add(points[7]);
vertices.Add(points[2]);
vertices.Add(points[6]);
uvs.Add(new Vector2(0.0f, height * 3.0f / tex_size.y));
uvs.Add(new Vector2(0.0f, height * 2.0f / tex_size.y));
uvs.Add(new Vector2(length / tex_size.x, height * 3.0f / tex_size.y));
uvs.Add(new Vector2(length / tex_size.x, height * 2.0f / tex_size.y));
if (isAnimated == false)
{
for (int i = 0; i < uvs.Count; i++)
uvs[i] = new Vector2(uvs[i].x, 1.0f - uvs[i].y);
}
var mesh = new Mesh();
mesh.name = string.Format("Space Wall Mesh: ({0}x{1}x{2})", width, length, height);
mesh.SetVertices(vertices);
mesh.SetUVs(0, uvs);
mesh.SetNormals(normals);
mesh.SetIndices(indices.ToArray(), MeshTopology.Triangles, 0);
mesh.UploadMeshData(true);
return mesh;
}
private Mesh CreateGroundMesh()
{
var half_size = size * 0.5f;
var tex_size = new Vector2(this.length * 2.0f + width, this.length + height);
var points = new List<Vector3>();
points.Add(new Vector3(-half_size.x, 0.0f, -half_size.z));
points.Add(new Vector3(-half_size.x, 0.0f, +half_size.z));
points.Add(new Vector3(+half_size.x, 0.0f, -half_size.z));
points.Add(new Vector3(+half_size.x, 0.0f, +half_size.z));
points.Add(new Vector3(-half_size.x, size.y, -half_size.z));
points.Add(new Vector3(-half_size.x, size.y, +half_size.z));
points.Add(new Vector3(+half_size.x, size.y, -half_size.z));
points.Add(new Vector3(+half_size.x, size.y, +half_size.z));
var vertices = new List<Vector3>();
var uvs = new List<Vector2>();
var indices = new List<int>();
var normals = new List<Vector3>();
// Ground
AddIndexAndNormal(indices, vertices.Count, normals, new Vector3(0, 1, 0));
vertices.Add(points[0]);
vertices.Add(points[1]);
vertices.Add(points[2]);
vertices.Add(points[3]);
uvs.Add(new Vector2(this.length / tex_size.x, 0.0f));
uvs.Add(new Vector2(this.length / tex_size.x, this.length / tex_size.y));
uvs.Add(new Vector2((this.length + width) / tex_size.x, 0.0f));
uvs.Add(new Vector2((this.length + width) / tex_size.x, this.length / tex_size.y));
if (Application.isPlaying == false)
{
// Front
AddIndexAndNormal(indices, vertices.Count, normals, new Vector3(0, 0, -1));
vertices.Add(points[1]);
vertices.Add(points[5]);
vertices.Add(points[3]);
vertices.Add(points[7]);
uvs.Add(new Vector2(length / tex_size.x, length / tex_size.y));
uvs.Add(new Vector2(length / tex_size.x, (length + height) / tex_size.y));
uvs.Add(new Vector2((length + width) / tex_size.x, length / tex_size.y));
uvs.Add(new Vector2((length + width) / tex_size.x, (length + height) / tex_size.y));
// Left
AddIndexAndNormal(indices, vertices.Count, normals, new Vector3(1, 0, 0));
vertices.Add(points[0]);
vertices.Add(points[4]);
vertices.Add(points[1]);
vertices.Add(points[5]);
uvs.Add(new Vector2(0.0f, length / tex_size.y));
uvs.Add(new Vector2(0.0f, (length + height) / tex_size.y));
uvs.Add(new Vector2(length / tex_size.x, length / tex_size.y));
uvs.Add(new Vector2(length / tex_size.x, (length + height) / tex_size.y));
// Right
AddIndexAndNormal(indices, vertices.Count, normals, new Vector3(-1, 0, 0));
vertices.Add(points[3]);
vertices.Add(points[7]);
vertices.Add(points[2]);
vertices.Add(points[6]);
uvs.Add(new Vector2((length + width) / tex_size.x, length / tex_size.y));
uvs.Add(new Vector2((length + width) / tex_size.x, (length + height) / tex_size.y));
uvs.Add(new Vector2((length * 2.0f + width) / tex_size.x, length / tex_size.y));
uvs.Add(new Vector2((length * 2.0f + width) / tex_size.x, (length + height) / tex_size.y));
}
var mesh = new Mesh();
mesh.name = string.Format("Space Ground Mesh: ({0}x{1}x{2})", width, this.length, height);
mesh.SetVertices(vertices);
mesh.SetUVs(0, uvs);
mesh.SetNormals(normals);
mesh.SetIndices(indices.ToArray(), MeshTopology.Triangles, 0);
mesh.UploadMeshData(true);
return mesh;
}
private void AddIndexAndNormal(List<int> indices, int index, List<Vector3> normals, Vector3 normal)
{
indices.Add(index + 0);
indices.Add(index + 1);
indices.Add(index + 2);
indices.Add(index + 1);
indices.Add(index + 3);
indices.Add(index + 2);
normals.Add(normal);
normals.Add(normal);
normals.Add(normal);
normals.Add(normal);
}
}
}