当前位置:网站首页>unity用代码生成LightProbeGroup
unity用代码生成LightProbeGroup
2022-08-03 15:35:00 【比格菲斯】
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(LightProbeGroup))]
public class LightProbeGroupRectangle : MonoBehaviour
{
public float X = 1;
public float Y = 1;
public float Z = 1;
public float unit = 0.1f;
private void OnValidate()
{
LightProbeGroup LPG = GetComponent<LightProbeGroup>();
LPG.probePositions = Creat_X_Y_Z_Cube().ToArray();
}
List<Vector3> Creat_X_Y_Z_Cube()
{
List<Vector3> pos = new List<Vector3>();
int L = (int)(Z / unit);
for (int i = 0; i <= L; i++)
{
pos.AddRange(Creat_X_Y_Area(unit * i));
}
return pos;
}
List<Vector3> Creat_X_Y_Area(float z)
{
List<Vector3> pos = new List<Vector3>();
int L = (int)(Y / unit);
for (int i = 0; i <= L; i++)
{
pos.AddRange(Creat_X_Line(unit * i, z));
}
return pos;
}
List<Vector3> Creat_X_Line(float y, float z)
{
List<Vector3> pos = new List<Vector3>();
int L = (int)(X / unit);
for (int i = 0; i <= L; i++)
{
pos.Add(new Vector3(unit * i, y, z));
}
return pos;
}
}
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(LightProbeGroup))]
public class LightProbesTetrahedralGrid : MonoBehaviour
{
// Common
[Tooltip("边长 : 同层探针间连线长度")]
public float m_Side = 1.0f;
[Tooltip("半径 : 圆形探针组大圆半径")]
public float m_Radius = 5.0f;
[Tooltip("内半径 : 圆形探针组内部小圆半径")]
public float m_InnerRadius = 0.1f;
[Tooltip("高度 : 圆形探针组高度")]
public float m_Height = 2.0f;
[Tooltip("层数 : 圆形探针组层数")]
public uint m_Levels = 3;
//最小半径
const float kMinSide = 0.05f;
//最低高度
const float kMinHeight = 0.05f;
//最小内圆半径
const float kMinInnerRadius = 0.1f;
//最小迭代数
const uint kMinIterations = 4;
// 游戏运行时,先调用 Generate 方法,添加光照探针到场景中
private void FixedUpdate()
{
Generate();
}
// OnValidate可以用来验证一些数据,脚本加载或Inspector中的任何值被修改时会调用
// 可以作为数据的保护,避免一些字段(或属性)被设置为不可用(不合理)的数据值
public void OnValidate()
{
//保证 m_Side 不小于 kMinSide
m_Side = Mathf.Max(kMinSide, m_Side);
//保证 m_Height 不小于 kMinHeight
m_Height = Mathf.Max(kMinHeight, m_Height);
// 对 m_Radius 和 m_InnerRadius 进行限制
if (m_InnerRadius < kMinInnerRadius)
{
TriangleProps props = new TriangleProps(m_Side);
m_Radius = Mathf.Max(props.circumscribedCircleRadius + 0.01f, m_Radius);
}
else
{
m_Radius = Mathf.Max(0.1f, m_Radius);
m_InnerRadius = Mathf.Min(m_Radius, m_InnerRadius);
}
}
// 结构体 三角形探针
struct TriangleProps
{
public TriangleProps(float triangleSide)
{
side = triangleSide;
halfSide = side / 2.0f;
height = Mathf.Sqrt(3.0f) * side / 2.0f;
//内切圆半径
inscribedCircleRadius = Mathf.Sqrt(3.0f) * side / 6.0f;
//外切圆半径
circumscribedCircleRadius = 2.0f * height / 3.0f;
}
public float side;
public float halfSide;
public float height;
public float inscribedCircleRadius;
public float circumscribedCircleRadius;
};
//三角形探针位,用来辅助生成探针的位置
private TriangleProps m_TriangleProps;
//生成探针主方法
public void Generate()
{
//获取光照探针组件
LightProbeGroup lightProbeGroup = GetComponent<LightProbeGroup>();
//建立要插入探针位置的列表
List<Vector3> positions = new List<Vector3>();
//三角形探针位,用来辅助生成探针的位置
m_TriangleProps = new TriangleProps(m_Side);
if (m_InnerRadius < kMinInnerRadius)
//生成圆柱
GenerateCylinder(m_TriangleProps, m_Radius, m_Height, m_Levels, positions);
else
//生成环
GenerateRing(m_TriangleProps, m_Radius, m_InnerRadius, m_Height, m_Levels, positions);
//向光照探针组中,添加探针
lightProbeGroup.probePositions = positions.ToArray();
}
//尝试添加
static void AttemptAdding(Vector3 position, Vector3 center, float distanceCutoffSquared, List<Vector3> outPositions)
{
if ((position - center).sqrMagnitude < distanceCutoffSquared)
outPositions.Add(position);
}
//计算圆柱体迭代
uint CalculateCylinderIterations(TriangleProps props, float radius)
{
int iterations = Mathf.CeilToInt((radius + props.height - props.inscribedCircleRadius) / props.height);
if (iterations > 0)
return (uint)iterations;
return 0;
}
//生成圆柱体
void GenerateCylinder(TriangleProps props, float radius, float height, uint levels, List<Vector3> outPositions)
{
uint iterations = CalculateCylinderIterations(props, radius);
float distanceCutoff = radius;
float distanceCutoffSquared = distanceCutoff * distanceCutoff;
Vector3 up = new Vector3(props.circumscribedCircleRadius, 0.0f, 0.0f);
Vector3 leftDown = new Vector3(-props.inscribedCircleRadius, 0.0f, -props.halfSide);
Vector3 rightDown = new Vector3(-props.inscribedCircleRadius, 0.0f, props.halfSide);
for (uint l = 0; l < levels; l++)
{
float tLevel = levels == 1 ? 0 : (float)l / (float)(levels - 1);
Vector3 center = new Vector3(0.0f, tLevel * height, 0.0f);
if (l % 2 == 0)
{
for (uint i = 0; i < iterations; i++)
{
Vector3 upCorner = center + up + (float)i * up * 2.0f * 3.0f / 2.0f;
Vector3 leftDownCorner = center + leftDown + (float)i * leftDown * 2.0f * 3.0f / 2.0f;
Vector3 rightDownCorner = center + rightDown + (float)i * rightDown * 2.0f * 3.0f / 2.0f;
AttemptAdding(upCorner, center, distanceCutoffSquared, outPositions);
AttemptAdding(leftDownCorner, center, distanceCutoffSquared, outPositions);
AttemptAdding(rightDownCorner, center, distanceCutoffSquared, outPositions);
Vector3 leftDownUp = upCorner - leftDownCorner;
Vector3 upRightDown = rightDownCorner - upCorner;
Vector3 rightDownLeftDown = leftDownCorner - rightDownCorner;
uint subdiv = 3 * i + 1;
for (uint s = 1; s < subdiv; s++)
{
Vector3 leftDownUpSubdiv = leftDownCorner + leftDownUp * (float)s / (float)subdiv;
AttemptAdding(leftDownUpSubdiv, center, distanceCutoffSquared, outPositions);
Vector3 upRightDownSubdiv = upCorner + upRightDown * (float)s / (float)subdiv;
AttemptAdding(upRightDownSubdiv, center, distanceCutoffSquared, outPositions);
Vector3 rightDownLeftDownSubdiv = rightDownCorner + rightDownLeftDown * (float)s / (float)subdiv;
AttemptAdding(rightDownLeftDownSubdiv, center, distanceCutoffSquared, outPositions);
}
}
}
else
{
for (uint i = 0; i < iterations; i++)
{
Vector3 upCorner = center + (float)i * (2.0f * up * 3.0f / 2.0f);
Vector3 leftDownCorner = center + (float)i * (2.0f * leftDown * 3.0f / 2.0f);
Vector3 rightDownCorner = center + (float)i * (2.0f * rightDown * 3.0f / 2.0f);
AttemptAdding(upCorner, center, distanceCutoffSquared, outPositions);
AttemptAdding(leftDownCorner, center, distanceCutoffSquared, outPositions);
AttemptAdding(rightDownCorner, center, distanceCutoffSquared, outPositions);
Vector3 leftDownUp = upCorner - leftDownCorner;
Vector3 upRightDown = rightDownCorner - upCorner;
Vector3 rightDownLeftDown = leftDownCorner - rightDownCorner;
uint subdiv = 3 * i;
for (uint s = 1; s < subdiv; s++)
{
Vector3 leftDownUpSubdiv = leftDownCorner + leftDownUp * (float)s / (float)subdiv;
AttemptAdding(leftDownUpSubdiv, center, distanceCutoffSquared, outPositions);
Vector3 upRightDownSubdiv = upCorner + upRightDown * (float)s / (float)subdiv;
AttemptAdding(upRightDownSubdiv, center, distanceCutoffSquared, outPositions);
Vector3 rightDownLeftDownSubdiv = rightDownCorner + rightDownLeftDown * (float)s / (float)subdiv;
AttemptAdding(rightDownLeftDownSubdiv, center, distanceCutoffSquared, outPositions);
}
}
}
}
}
//生成环
void GenerateRing(TriangleProps props, float radius, float innerRadius, float height, uint levels, List<Vector3> outPositions)
{
float chordLength = props.side;
float angle = Mathf.Clamp(2.0f * Mathf.Asin(chordLength / (2.0f * radius)), 0.01f, 2.0f * Mathf.PI);
uint slicesAtRadius = (uint)Mathf.FloorToInt(2.0f * Mathf.PI / angle);
uint layers = (uint)Mathf.Max(Mathf.Ceil((radius - innerRadius) / props.height), 0.0f);
for (uint level = 0; level < levels; level++)
{
float tLevel = levels == 1 ? 0 : (float)level / (float)(levels - 1);
float y = height * tLevel;
float iterationOffset0 = level % 2 == 0 ? 0.0f : 0.5f;
for (uint layer = 0; layer < layers; layer++)
{
float tLayer = layers == 1 ? 1.0f : (float)layer / (float)(layers - 1);
float tIterations = (tLayer * (radius - innerRadius) + innerRadius - kMinInnerRadius) / (radius - kMinInnerRadius);
uint slices = (uint)Mathf.CeilToInt(Mathf.Lerp(kMinIterations, slicesAtRadius, tIterations));
float x = innerRadius + (radius - innerRadius) * tLayer;
Vector3 position = new Vector3(x, y, 0.0f);
float layerSliceOffset = layer % 2 == 0 ? 0.0f : 0.5f;
for (uint slice = 0; slice < slices; slice++)
{
Quaternion rotation = Quaternion.Euler(0.0f, (slice + iterationOffset0 + layerSliceOffset) * 360.0f / (float)slices, 0.0f);
outPositions.Add(rotation * position);
}
}
}
}
}
边栏推荐
- 问题8:对朋友圈进行用例设计
- 动态链接库.dll、.so和静态库.a,cmake指令
- 【周报】2022年7月24日
- 问题10:注册页面的易用性测试?
- 新版本的 MaxCompute 中,SQL支持的 LIMIT OFFSET 的语法是什么功能?
- How to use binary search and find whether the rotation in the array contains a (target) value?Rotate the sorted array leetcode 81. Search
- 问题5:发现缺陷怎么办?缺陷的类型有哪些?
- 生物统计师与临床医生协同研究使用的低代码洞察平台丨数据科学 x 临床医学
- NodeJs - cross domain
- devops-3:Jenkins增加静态节点
猜你喜欢
劲爆!协程终于来了!线程即将是过去式
深度学习GPU最全对比,到底谁才是性价比之王?
How to prevent hacking Windows server security Settings
深入浅出Flask PIN
Ark server open tool, server tutorial win
The general trend, another key industry related to Sino-US competition, has reached a critical moment
实习路途:记录给我的第一个实习项目中的困惑
上亿数据怎么玩深度分页?兼容MySQL + ES + MongoDB
开源一夏 | 阿里云物联网平台之极速体验
16 【过渡 动画】
随机推荐
自定SvgIcon公用组件
16 【过渡 动画】
一次做数据报表的踩坑经历,让我领略了数据同步增量和全量的区别
【899. Ordered Queue】
【周报】2022年7月31日
王守创:多组学整合分析揭示植物代谢多样性的分子机制(8月2号晚)
分布式系统与微服务的区别
A new round of competition for speech recognition has started. Will natural dialogue be the next commanding height?
测试基础整合-测试分类、软件质量模型、测试流程、测试用例、测试点划分方法、缺陷、例子
How much does Ark Survival Evolved cost?
简单理解try catch和try finally
Neural networks, cool?
并发编程的核心问题
语音识别新一轮竞争打响,自然对话会是下一个制高点吗?
深度学习GPU最全对比,到底谁才是性价比之王?
JS手写call apply bind (详细)(面试)
方舟开服工具、服务器教程win
分享一款免费OPC UA服务器
No inner demons, to dry!SQL optimization and diagnosis
LyScript 验证PE程序开启的保护