(八)正二十面体

1.概述

本片转自如下

2.代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CreateIcosahedron : MonoBehaviour
{
    public float size = 1;

    private Vector3[] vertices;
    private Vector2[] uvs;
    private Vector3[] normals;
    private Vector4[] tangents;
    private int[] triangles;

    private Mesh CreateRegular()
    {
        Mesh mesh = new Mesh();

        // 先按12个顶点开辟顶点数组
        vertices = new Vector3[12];

        // 正二十面体顶点公式(度娘可查)
        float m = Mathf.Sqrt(50 - 10 * Mathf.Sqrt(5)) / 10 * size;
        float n = Mathf.Sqrt(50 + 10 * Mathf.Sqrt(5)) / 10 * size;

        // 按公式顺序对顶点坐标赋值
        vertices[0] = new Vector3(m, 0, n);
        vertices[1] = new Vector3(m, 0, -n);
        vertices[2] = new Vector3(-m, 0, n);
        vertices[3] = new Vector3(-m, 0, -n);
        vertices[4] = new Vector3(0, n, m);
        vertices[5] = new Vector3(0, -n, m);
        vertices[6] = new Vector3(0, n, -m);
        vertices[7] = new Vector3(0, -n, -m);
        vertices[8] = new Vector3(n, m, 0);
        vertices[9] = new Vector3(-n, m, 0);
        vertices[10] = new Vector3(n, -m, 0);
        vertices[11] = new Vector3(-n, -m, 0);

        // 正二十面体三角形的点序列
        triangles = new int[] {6,4,8, 9,4,6, 6,3,9, 6,1,3, 6,8,1,
            8,10,1, 8,0,10, 8,4,0, 4,2,0, 4,9,2,
            9,11,2, 9,3,11, 3,1,7, 1,10,7, 10,0,5,
            0,2,5, 2,11,5, 3,7,11, 5,11,7, 10,5,7};

        // 根据面的顺序,重新创建新的顶点数组,用于计算顶点法线
        Vector3[] newVs = new Vector3[triangles.Length];
        for (int i = 0; i < newVs.Length; i++)
        {
            Debug.Log(vertices[triangles[i]]);
            newVs[i] = vertices[triangles[i]];
        }

        vertices = newVs;
        uvs = new Vector2[vertices.Length];
        normals = new Vector3[vertices.Length];
        tangents = new Vector4[vertices.Length];

        // 根据新的点,设置三角面的顶点ID并计算点法线
        for (int i = 0; i < triangles.Length - 2; i += 3)
        {
            Vector3 normal = Vector3.Cross(vertices[i + 1] - vertices[i], vertices[i + 2] - vertices[i]);  // 计算点的法线
            for (int j = 0; j < 3; j++)
            {
                triangles[i + j] = i + j;        // 重新设置面的顶点ID
                normals[i + j] = normal;  // 点的法线赋值
            }
        }

        // 设置每个点的切线和UV
        for (int i = 0; i < vertices.Length; i++)
        {
            tangents[i] = new Vector4(-1, 0, 0, -1);    // 切线
            uvs[i] = new Vector2(vertices[i].x, vertices[i].y);     // UV坐标
        }

        mesh.vertices = vertices;
        mesh.triangles = triangles;
        mesh.normals = normals;
        mesh.tangents = tangents;
        mesh.uv = uvs;

        return mesh;
    }

    private void Start()
    {
        MeshFilter mf = GetComponent<MeshFilter>();
        mf.mesh = CreateRegular();
    }

    private void OnValidate()
    {
        MeshFilter mf = GetComponent<MeshFilter>();
        mf.mesh = CreateRegular();
    }
}

posted @ 2020-02-03 13:11  81192  阅读(609)  评论(0编辑  收藏  举报