unity三维地球模型生成
2024-09-05 14:34:52
准备一张贴图
创建材质球
球面坐标系转直角坐标系
x=rsinθcosφ.
y=rsinθsinφ.
z=rcosθ.
效果如下
脚本如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine; //创建球形mesh
public class BallCreater : MonoBehaviour {
public Material ballMat;//材质
void Start () {
createBall("mEarth",new Vector3(0,0,0),100.0f,181,88);
} void Update () { }
/// <summary>
/// 创建球形mesh
/// </summary>
/// <param name="meshName">名称</param>
/// <param name="center">球心</param>
/// <param name="radius">半径</param>
/// <param name="longPart">经线数</param>
/// <param name="latPart">纬线数</param>
/// <returns></returns>
private GameObject createBall(string meshName,Vector3 center, float radius, int longPart, int latPart)
{
GameObject meshObject = new GameObject(meshName); int verticeNum = longPart * latPart+2* longPart;//经线数*纬线数+极点处多个重合点 (首尾经线重合)
Vector3[] vertices = new Vector3[verticeNum];//顶点数组
Vector3[] normals = new Vector3[verticeNum];//顶点法线数组
Vector2[] uvs = new Vector2[verticeNum];//uv数组
int[] triangles = new int[(longPart-1)* latPart * 3 * 2];//三角集合数组,保存顶点索引 float degreesToRadians = Mathf.PI / 180.0f; //弧度转换
float deltaLong = 360.0f /(longPart-1);//经度每份对应度数
float deltaLat = 180.0f/ (latPart+2);//纬度每份对应度数
//极点放置多个顶点,同位置不同uv
for (int i = 0; i < longPart; i++)
{
vertices[i] = new Vector3(0, 0, 1) * radius;
normals[i] = vertices[0].normalized;
uvs[i] = new Vector2((float)i/(float)longPart,0);
}
int k = 0;
for (int i = 0; i < longPart-1; i++)
{
triangles[k++] = i;
triangles[k++] = i+ longPart;
triangles[k++] = i + longPart+1;
}
for (int tempLat = 0; tempLat < latPart; tempLat++)
{
float tempAngle1 = ((tempLat+1)* deltaLat) * degreesToRadians;
for (int tempLong = 0; tempLong < longPart; tempLong++)
{
float tempAngle2 = (tempLong*deltaLong) * degreesToRadians;
int tempIndex = tempLong+ tempLat* longPart+ longPart;
vertices[tempIndex] = new Vector3(Mathf.Sin(tempAngle1) * Mathf.Cos(tempAngle2), Mathf.Sin(tempAngle1) * Mathf.Sin(tempAngle2), Mathf.Cos(tempAngle1)) * radius;
normals[tempIndex] = vertices[tempIndex].normalized;
uvs[tempIndex] = new Vector2((float)tempLong / (float)longPart, (float)tempLat / (float)latPart);
if (tempLat!= latPart-1)
{
if (tempLong != longPart-1)
{
triangles[k++] = tempLong + tempLat * longPart + longPart;
triangles[k++] = tempLong + tempLat * longPart + 2 * longPart;
triangles[k++] = tempLong + tempLat * longPart + longPart + 1; triangles[k++] = tempLong + tempLat * longPart + 2 * longPart;
triangles[k++] = tempLong + tempLat * longPart + 1 + 2 * longPart;
triangles[k++] = tempLong + tempLat * longPart + 1 + longPart; }
}
}
}
//极点放置多个顶点,同位置不同uv
for (int i = 0; i < longPart; i++)
{
vertices[verticeNum - 1-i] = new Vector3(0, 0, -1) * radius;
normals[verticeNum - 1-i] = vertices[verticeNum - 1].normalized;
uvs[verticeNum - 1-i] = new Vector2(1.0f-(float)i / (float)longPart, 1.0f);
}
for (int i = 0; i < longPart-1; i++)
{
triangles[k++] = verticeNum - 1-i;
triangles[k++] = verticeNum - 1-i- longPart;
triangles[k++] = verticeNum - 2 - i- longPart;
} Mesh mesh = new Mesh();
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.normals = normals;
mesh.uv = uvs;
mesh.RecalculateBounds();
mesh.RecalculateNormals();
meshObject.AddComponent<MeshFilter>();
meshObject.AddComponent<MeshRenderer>();
meshObject.GetComponent<MeshFilter>().mesh = mesh;
meshObject.GetComponent<MeshRenderer>().material = ballMat;
meshObject.transform.position += center;
return meshObject;
} }
最新文章
- # Hawk:开源贡献计划,设计,反思
- Failed to create the Java Virtual Machine.问题的解决
- TO BE OPEN
- 关于页面 reflow 和 repaint
- jQuery实现jsonp源码分析(京东2015面试)
- Android(java)学习笔记196:Android中Menu的使用(静态和动态)
- Spring Mvc和Mybatis的多数据库访问配置过程
- 网站的优化----首页优化---app调取服务端数据
- JS学习笔记(三)函数
- CSS3 文字与字体相关样式
- Spring Boot 中应用Spring data mongdb
- vs2012 aps.net 4.5尚未在web服务器上注册,您需要手动将Web服务器配置为
- Redis可视化工具 Redis Desktop Manager
- Kernel数据结构移植(list和rbtree)
- laravel 关闭 csrf 验证 TokenMismatchException
- JAVA追加写入文本文件
- 课程四(Convolutional Neural Networks),第二 周(Deep convolutional models: case studies) —— 1.Practice questions
- 配置 -- php运行报Call to undefined function curl_init()的解决办法
- SeekBar的用法和自定义滑块的样式
- Spark应用程序的运行架构几种说
热门文章
- CSRF(cross-site request forgery )跨站请求攻击
- Nginx HTTP服务器配置模板
- 「数据结构与算法(Python)」(三)
- 洛谷P1169 棋盘制作【悬线法】【区间dp】
- string::at
- AtCoder Beginner Contest 116 C题 【题意:可以在任意区间【L,R】上加1,求通过最少加1次数得到题目给定的区间】】{思维好题}
- 参数类型 (@Controller层)
- cat/tac
- 51nod 1412
- Bzoj 1588: [HNOI2002]营业额统计(splay)