Unity矩阵matrix4x4的应用:世界空间与模型空间的坐标系转化

更新时间:2023-06-17 12:24:22 阅读: 评论:0

Unity矩阵matrix4x4的应⽤:世界空间与模型空间的坐标系转化
⽂章⽬录
draw怎么读
前⾔
近期由于项⽬需求,研究了⼀下通过矩阵来转换不同坐标系,接下来就简单记录⼀下。
⼀、矩阵 Matrix4x4?
UnityEngine.Matrix4x4 是 Unity 提供的⽅便矩阵计算⽽封装的⼀个结构体,提供了很多相对便于⽇常开发的函数。除了 之外,相信⽹上有很多关于这个矩阵的定义的解释了,这⾥就不介绍了,给个 吧。
补发英文
这⾥我们结合⼀个具体例⼦来看吧:我们想知道⼀只蚂蚁在⼀个很⼤的球上的可视范围(别和我纠结蚂蚁的视⼒问题啊!)。
⼆、应⽤过程
1、案例分析
苏州软件培训中心⾸先,我们能确定的是,蚂蚁在球⾯上是相对于球⾯有⼀个偏转的。所以,蚂蚁⾃⾝是有⼀个 “模型空间
坐标系”的,同时,不可避免的,蚂蚁也处于另外的⼀个“Unity世界空间坐标系”中。在Unity中,蚂蚁的位置是相对世界空间坐标系来说的。
asrt我们想知道蚂蚁的可视范围,可以想到的⽅式有,以蚂蚁为圆⼼,向四周打⼀圈射线,判断碰撞,得出可视范围,可以此绘制出Mesh。
2、函数介绍
Matrix4x4.TRS
该函数可⽤于构建旋转矩阵。三个参数分别为位置、旋转与缩放。上述案例中,世界空间坐标系为标准三维空间坐标系,⽽模型空间坐标系可以⽤蚂蚁的位置与旋转来表⽰。
Matrix4x4.MultiplyVector
上述旋转矩阵中,该函数可⽤于转换世界空间坐标系中的向量⾄模型空间坐标系。
Matrix4x4.MultiplyPoint
上述旋转矩阵中,该函数可⽤于转换世界空间坐标系中的坐标点⾄模型空间坐标系。
gateway
Matrix4X4.inver
矩阵的逆。可获取该矩阵的逆矩阵。结合上⾯两个函数,我们就可转换模型空间坐标系中的信息⾄世界空间。
⽤于获取该旋转矩阵中的旋转四元数。可以乘以另⼀个四元数以获取它在另⼀个坐标系下的表⽰。
public bool isPoint;
public bool inver;
public Transform orgCoor;// 原始坐标系
public Transform newCoor;// 新坐标系
public Transform tranOrg;// 原始位置
public Transform tranNew;// 转换后的位置
/// <summary>
/// 转点
/// </summary>
private void MultiplyPoint()
{
Matrix4x4 matrix4X4 = Matrix4x4.TRS(newCoor.position, ation, newCoor.localScale);
if(!inver)
tranNew.position = matrix4X4.MultiplyPoint(tranOrg.position);
el
tranNew.position = matrix4X4.inver.MultiplyPoint(tranOrg.position);// 这⾥的 position 依然是相对于世界空间坐标系(orgCoor)来说的
//Vector4 a = matrix4X4.inver * (tranOrg.position);
}
/// <summary>
/// 转向量
/// </summary>
private void MultiplyVector()
{
Matrix4x4 matrix4X4 = Matrix4x4.TRS(newCoor.position, ation, newCoor.localScale);
if(!inver)
{
tranNew.position = matrix4X4.MultiplyVector(tranOrg.position - orgCoor.position)+ newCoor.position;
}
el
{
tranNew.position = matrix4X4.inver.MultiplyVector(tranOrg.position - newCoor.position)+ orgCoor.position;
}
}
3、实际代码
利⽤世界空间坐标系与Mesh的绘制坐标系相同,我们可以将理想的锥形在世界空间中表⽰出来,再转换到模型空间坐标系中(此时虽然是模型空间中,但还是⽤的世界空间坐标系中的坐标点表⽰位置)利⽤碰撞计算Mesh的顶点位置,最后再转换回世界空间坐标系中。此
时,Mesh顶点的坐标表⽰是相对世界空间的,可以⽤于⽣成 sh 的赋值。
最后,附上相关代码
/// <summary>
/// 球⾯上的地⾯侦察范围Mesh创建(带碰撞)
/// </summary>
/// <param name="trans">球⾯上某点的Transform</param>
/// <param name="radius">侦察半径</param>
/// <param name="layer">层级</param>
/// <returns></returns>
style什么意思public static Mesh CreateAntDetectionRange(Transform trans,float radius,int layer,int upHeight =20)
{
// 此处涉及2个空间坐标系,分别为 unity世界空间坐标系、物体的模型空间坐标系
Matrix4x4 matrix4X4 = Matrix4x4.TRS(trans.position, ation, trans.localScale);// 构造从 unity世界空间坐标系到物体的模型空间坐标系矩阵
Vector3 orgPoint = trans.position;
mf global
Vector3 upPoint = matrix4X4.MultiplyPoint(Vector3.up * upHeight);// 中间点的 unity世界坐标点
//List<Vector3> vertices = new List<Vector3> { Vector3.up * upHeight };
List<Vector3> vertices =new List<Vector3>();
for(int i =0; i <=360; i +=3)
{
Vector3 endPosSelf = Quaternion.AngleAxis(i, Vector3.up)* Vector3.forward * radius;// 模型空间中的位置信息
Vector3 endPos = matrix4X4.MultiplyPoint(endPosSelf);// 模型空间相对位置信息转化为世界空间位置信息
if(Physics.Raycast(upPoint,(endPos - upPoint).normalized,out RaycastHit hit, radius, layer))
{
endPos = hit.point;
Debug.DrawLine(upPoint, endPos, llow);
}
el
{
{
Debug.DrawLine(upPoint, endPos, d);
}
// //Debug.DrawLine(Vector3.up * upHeight + orgPoint, Quaternion.AngleAxis(i, Vector3.up) * Vector3.forward * radius + orgPoint, );
falloff//Vector3 direction = matrix4X4.MultiplyVector(Quaternion.AngleAxis(i, Vector3.up) * Vector3.forward * radius - Vector3.up * upHeight);  // ⾃⾝射线⽅向转到世界空间射线⽅向
//Vector3 endPos = upPoint + direction;
//if (Physics.Raycast(upPoint, alized, out RaycastHit hit, radius, layer))
//{
//    endPos = hit.point;
//    Debug.DrawLine(upPoint, endPos, llow);
//}
//el
//{
//    Debug.DrawLine(upPoint, endPos, d);
//}
vertices.Add(matrix4X4.inver.MultiplyPoint(endPos));
}
return CreatePolygonMesh(matrix4X4.inver.MultiplyPoint(upPoint), vertices.ToArray());
}
/// <summary>
/// 简单多边形⽹格(单中⼼点连边)
/// </summary>
/
// <param name="center">中点</param>
/// <param name="points">边</param>
/// <returns></returns>
public static Mesh CreatePolygonMesh(Vector3 center, Vector3[] points,bool coverEnd =true)
{
List<Vector3> vertices =new List<Vector3>();
vertices.Add(center);
vertices.AddRange(points);
jedwardList<int> triangles =new List<int>();
for(int i =1; i < vertices.Count; i++)
{
if(i == vertices.Count -1)
{
if(coverEnd)
{
triangles.Add(0);
triangles.Add(i);
triangles.Add(1);
}
}
el
{
triangles.Add(0);
triangles.Add(i);
triangles.Add(i +1);
}
}
Mesh mesh =new Mesh()
神探夏洛克第三季
{
vertices = vertices.ToArray(),
triangles = triangles.ToArray()
};
//mesh.RecalculateNormals();
return mesh;
}
坐标系之间的转化需要⼀定的空间想象能⼒,这⽅⾯不是很强的同学可以试试⽤三⽀笔模拟⼀个坐标系,⽅便理解。

本文发布于:2023-06-17 12:24:22,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/90/148202.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:空间   坐标系   世界
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图