Unity中的矩陣(Matrix4x4)
最近在研究幀同步定點數(shù)物理系統(tǒng)中需要自定義定點數(shù)矩陣,所以在這里分享下基礎(chǔ)的矩陣案例旋轉(zhuǎn)、平移、縮放。(注意這里本文中的transform組件式基于unity浮點數(shù)的教程并非幀同步定點數(shù))參考原文
創(chuàng)建自定義模型
參數(shù)可以參考我上圖的參數(shù),這里注意三個頂點是一個面,這里我上述的模型是一個三角形的面。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Triangle : MonoBehaviour
{
/// <summary>
/// 網(wǎng)格
/// </summary>
Mesh mesh;
/// <summary>
/// 三角形頂點
/// </summary>
public Vector3[] vertices;
/// <summary>
/// 分配三角形頂點索引
/// </summary>
public int[] triangle;
/// <summary>
/// 材質(zhì)球
/// </summary>
public Material mat;
private void Start()
{
//實例化網(wǎng)格
mesh = new Mesh();
//分配頂點
mesh.vertices = vertices;
//分配三角形頂點索引
mesh.triangles = triangle;
//添加網(wǎng)格過濾器
MeshFilter mf = gameObject.AddComponent<MeshFilter>();
//網(wǎng)格賦值
mf.mesh = mesh;
//添加網(wǎng)格渲染器
MeshRenderer mr = gameObject.AddComponent<MeshRenderer>();
//材質(zhì)賦值
mr.materials[0] = mat;
}
}
創(chuàng)建模型很簡單我就不細講了,看不懂的可以看上述的注釋即可,直接黏貼也可。
平移矩陣
要做位移先搞明白矩陣中的哪幾個索引值代表的坐標位置,如下圖所示4x4矩陣
上圖Tx,Ty,Tz為平邑的方向向量
這里可以自己做個測試,將transform的初始位置修改如下所示
代碼如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MyTransform : MonoBehaviour
{
public Matrix4x4 matrix;
// Start is called before the first frame update
void Start()
{
matrix.SetTRS(transform.position,transform.rotation,transform.localScale);
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Q))
{
MyTranslate(new Vector3 (Random.Range(-5,5),Random.Range(-5,5), Random.Range(-5, 5)));
}
}
public Vector4 v;
/// <summary>
/// 平移矩陣對象
/// </summary>
/// <param name="pos"></param>
public void MyTranslate(Vector3 pos)
{
//按照當前位置進行位移
//v = new Vector4(transform.position.x,transform.position.y,transform.position.z,1);
//按照原點進行位移
v = new Vector4(0, 0, 0, 1);
matrix = Matrix4x4.identity;
//X、Y、Z移動因子
matrix.m03 = pos.x;
matrix.m13 = pos.y;
matrix.m23 = pos.z;
//矩陣位移操作
v = matrix * v;
transform.position = new Vector3(v.x, v.y, v.z);
}
}
縮放矩陣
這個就是縮放矩陣,其中“Sx”、“Sy”、“Sz”就是各個軸上的縮放因子??s放矩陣是矩陣表現(xiàn)物體大小變換的矩陣。如果縮放因子小于1,表現(xiàn)為物體縮?。蝗绻笥?,則表現(xiàn)為物體擴大,如果等于1則不發(fā)生變化。
測試的話可以根據(jù)平移矩陣的測試方式修改scale來查看矩陣點對應(yīng)值得變化
修改代碼如下文章來源:http://www.zghlxwxcb.cn/news/detail-796722.html
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MyTransform : MonoBehaviour
{
public Matrix4x4 matrix;
// Start is called before the first frame update
void Start()
{
matrix.SetTRS(transform.position,transform.rotation,transform.localScale);
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Q))
{
MyTranslate(new Vector3 (Random.Range(-5,5),Random.Range(-5,5), Random.Range(-5, 5)));
}
if (Input.GetKeyDown(KeyCode.W))
{
int scale = Random.Range(-5,5);
MyScale(new Vector3 (scale, scale, scale));
}
}
public Vector4 v;
/// <summary>
/// 平移矩陣對象
/// </summary>
/// <param name="pos"></param>
public void MyTranslate(Vector3 pos)
{
//按照當前位置進行位移
//v = new Vector4(transform.position.x,transform.position.y,transform.position.z,1);
//按照原點進行位移
v = new Vector4(0, 0, 0, 1);
matrix = Matrix4x4.identity;
//X、Y、Z移動因子
matrix.m03 = pos.x;
matrix.m13 = pos.y;
matrix.m23 = pos.z;
//矩陣位移操作
v = matrix * v;
transform.position = new Vector3(v.x, v.y, v.z);
}
/// <summary>
/// 縮放矩陣對象
/// </summary>
/// <param name="scale"></param>
public void MyScale(Vector3 scale)
{
//設(shè)置當前對象大小
//v = new Vector4(transform.localScale.x, transform.localScale.y, transform.localScale.z, 1);
//按照原點進行位移
v = new Vector4(1, 1, 1, 1);
matrix = Matrix4x4.identity;
//X、Y、Z縮放因子
matrix.m00 = scale.x;
matrix.m11 = scale.y;
matrix.m22 = scale.z;
//矩陣縮放操作
v = matrix * v;
transform.localScale = new Vector3(v.x, v.y, v.z);
}
}
旋轉(zhuǎn)矩陣
測試的話可以根據(jù)平移矩陣的測試方式修改Rotation來查看矩陣點對應(yīng)值得變化
修改代碼如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MyTransform : MonoBehaviour
{
public Matrix4x4 matrix;
// Start is called before the first frame update
void Start()
{
matrix.SetTRS(transform.position,transform.rotation,transform.localScale);
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Q))
{
MyTranslate(new Vector3 (Random.Range(-5,5),Random.Range(-5,5), Random.Range(-5, 5)));
}
if (Input.GetKeyDown(KeyCode.W))
{
int scale = Random.Range(-5,5);
MyScale(new Vector3 (scale, scale, scale));
}
if (Input.GetKeyDown(KeyCode.A))
{
MyRotation( Axle.X,10f);
}
if (Input.GetKeyDown(KeyCode.S))
{
MyRotation(Axle.Y, 10f);
}
if (Input.GetKeyDown(KeyCode.D))
{
MyRotation(Axle.Z, 10f);
}
}
public Vector4 v;
/// <summary>
/// 平移矩陣對象
/// </summary>
/// <param name="pos"></param>
public void MyTranslate(Vector3 pos)
{
//按照當前位置進行位移
//v = new Vector4(transform.position.x,transform.position.y,transform.position.z,1);
//按照原點進行位移
v = new Vector4(0, 0, 0, 1);
matrix = Matrix4x4.identity;
//X、Y、Z移動因子
matrix.m03 = pos.x;
matrix.m13 = pos.y;
matrix.m23 = pos.z;
//矩陣位移操作
v = matrix * v;
transform.position = new Vector3(v.x, v.y, v.z);
}
/// <summary>
/// 縮放矩陣對象
/// </summary>
/// <param name="scale"></param>
public void MyScale(Vector3 scale)
{
//設(shè)置當前對象大小
//v = new Vector4(transform.localScale.x, transform.localScale.y, transform.localScale.z, 1);
//按照原點進行位移
v = new Vector4(1, 1, 1, 1);
matrix = Matrix4x4.identity;
//X、Y、Z縮放因子
matrix.m00 = scale.x;
matrix.m11 = scale.y;
matrix.m22 = scale.z;
//矩陣縮放操作
v = matrix * v;
transform.localScale = new Vector3(v.x, v.y, v.z);
}
public enum Axle { X, Y, Z}
public void MyRotation(Axle axle,float angle)
{
matrix = Matrix4x4.identity;
//對應(yīng) X、Y、Z的旋轉(zhuǎn)
switch (axle)
{
case Axle.X:
matrix.m11 = Mathf.Cos(angle * Mathf.Deg2Rad);
matrix.m12 = -Mathf.Sin(angle * Mathf.Deg2Rad);
matrix.m21 = Mathf.Sin(angle * Mathf.Deg2Rad);
matrix.m22 = Mathf.Cos(angle * Mathf.Deg2Rad);
break;
case Axle.Y:
matrix.m00 = Mathf.Cos(angle * Mathf.Deg2Rad);
matrix.m02 = Mathf.Sin(angle * Mathf.Deg2Rad);
matrix.m20 = -Mathf.Sin(angle * Mathf.Deg2Rad);
matrix.m22 = Mathf.Cos(angle * Mathf.Deg2Rad);
break;
case Axle.Z:
matrix.m00 = Mathf.Cos(angle * Mathf.Deg2Rad);
matrix.m01 = -Mathf.Sin(angle * Mathf.Deg2Rad);
matrix.m10 = Mathf.Sin(angle * Mathf.Deg2Rad);
matrix.m11 = Mathf.Cos(angle * Mathf.Deg2Rad);
break;
default:
break;
}
float qw = Mathf.Sqrt(1f + matrix.m00 + matrix.m11 + matrix.m22) / 2;
float w = 4 * qw;
float qx = (matrix.m21 - matrix.m12) / w;
float qy = (matrix.m02 - matrix.m20) / w;
float qz = (matrix.m10 - matrix.m01) / w;
transform.rotation = new Quaternion(qx, qy, qz, qw);
}
}
原文中有對應(yīng)的小工具可以參考文章來源地址http://www.zghlxwxcb.cn/news/detail-796722.html
到了這里,關(guān)于Unity矩陣平移旋轉(zhuǎn)縮放Matrix4x4的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!