用来可视化了解各种矩阵变换的代码
用来可视化了解各种矩阵变换的代码。直接创建即可用。代码注释完整
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
publicclassCoordinateSystem : MonoBehaviour
{
publicTransform RedPoint;
publicTransform BluePoint;
publicCamera ccamera;
publicTransform transformCamera;
publicTransform transformModel;
publicTransform transformWorld;
publicColor[] cameraSystemColor;
publicColor[] worldSystemColor;
publicColor[] modelSystemColor;
publicvoidOnDrawGizmos()
{
//世界空间坐标系
DrawACoordinate(transformWorld,worldSystemColor);
//摄像机空间坐标系
DrawACoordinate(transformCamera,cameraSystemColor);
//模型空间坐标系
DrawACoordinate(transformModel,modelSystemColor);
}
privatevoid DrawACoordinate(Transform inT,Color[] DrawColor)
{
Gizmos.color = DrawColor[0];
Gizmos.DrawLine(inT.position,inT.position + inT.forward);
Gizmos.color = DrawColor[1];
Gizmos.DrawLine(inT.position,inT.position + inT.up);
Gizmos.color = DrawColor[2];
Gizmos.DrawLine(inT.position,inT.position + inT.right);
}
publicvoid CreateModelToWorldMatrix()
{
Matrix4x4 mMatrix =Matrix4x4.TRS(transformModel.position,transformModel.rotation, transformModel.lossyScale);
Debug.Log(transformModel.localToWorldMatrix.ToString()+"\n\n"+mMatrix.ToString());
//取模型空间的原点,转移到世界坐标系中
RedPoint.position = mMatrix *newVector4(0, 0, 0, 1);
}
publicvoid CreateWorldToCameraMatrix()
{
//将世界坐标的摄像机信息构建一个变换矩阵
//需要注意的是,Z方向的轴向是反的,这是因为
//camera space matches OpenGLconvention: camera's forward is the negative Z axis.
//This is different from Unity'sconvention, where forward is the positive Z axis.
//OpenGL和unity在Z轴的正方定义是相反的
Matrix4x4 cMatrix =Matrix4x4.TRS(transformCamera.position,transformCamera.rotation,newVector3(1,1,-1));
//计算这个摄像机的逆
cMatrix = Matrix4x4.Inverse(cMatrix);
Debug.Log(ccamera.worldToCameraMatrix.ToString()+ "\n\n" + cMatrix.ToString());
Vector3 cameraPosition = cMatrix *newVector4(RedPoint.position.x,RedPoint.position.y, RedPoint.position.z, 1.0f);
BluePoint.localPosition =newVector3(cameraPosition.x,cameraPosition.y,cameraPosition.z*-1);
Debug.Log("红点在摄像机空间的坐标为" +BluePoint.localPosition.ToString());
}
publicvoid CreateProjectionMatrix()
{
//Debug.Log(ccamera.projectionMatrix.ToString()+ "\n\n"
Matrix4x4 pMatrix = Matrix4x4.Perspective(ccamera.fieldOfView,ccamera.aspect, ccamera.nearClipPlane, ccamera.farClipPlane);
Vector3 bl = BluePoint.localPosition;
Vector3 screenPosition = pMatrix * newVector4(bl.x, bl.y, bl.z, 1.0f);
screenPosition.Normalize();
Vector2 v2ScreenPosition =newVector2(screenPosition.x*0.5f+0.5f,screenPosition.y*0.5f+0.5f);
Debug.Log(ccamera.projectionMatrix + "\n\n" + pMatrix.ToString());
Debug.Log("红点在投影后的坐标为" + v2ScreenPosition.ToString());
Debug.Log(ccamera.WorldToViewportPoint(BluePoint.position));
}
}
#if UNITY_EDITOR
[CustomEditor(typeof(CoordinateSystem))]
publicclassCoordinateSystemEditor : Editor
{
publicoverridevoid OnInspectorGUI()
{
DrawDefaultInspector();
CoordinateSystem myScript = (CoordinateSystem)target;
if (GUILayout.Button("重置"))
{
myScript.RedPoint.position = Vector3.zero;
myScript.BluePoint.localPosition = Vector3.zero;
}
if (GUILayout.Button("将一个顶点从本地坐标系转换到世界坐标系"))
{
myScript.CreateModelToWorldMatrix();
}
if (GUILayout.Button("将一个顶点从世界坐标系转换到视空间坐标系"))
{
myScript.CreateWorldToCameraMatrix();
}
if (GUILayout.Button("将一个视空间坐标系的内容投影到2D平面上"))
{
myScript.CreateProjectionMatrix();
}
}
}
#endif
更多资源请点击:https://bycwedu.vipwan.cn/promotion_channels/630597732