unity 坐标系转换_Unity3D之笛卡尔坐标系转换——屏幕坐标转换世界坐标,世界坐标转换相机坐标工具...
因为要做AR的标记功能,所以就要用到坐标的转换,就总结了一下屏幕坐标、世界坐标、相机坐标之间的转换。
首先说明的是Unity3D遵从Direct3D标准的左手笛卡尔坐标系变换规则。
也就是说:
世界坐标系就是左手笛卡尔坐标系(x,y,z),相机也是左手笛卡尔坐标系(u,v,w),且面向自身坐标系w坐标轴正上方,屏幕以中央为原点,右和上分别为x,y的正方向。
我将工具代码直接上:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraTransformationUtilities : MonoBehaviour
{
public static CameraTransformationUtilities Instance { get; private set; }
protected CameraTransformationUtilities() { }
private void Start()
{
Instance = this;
}
/// 投影矩阵
/// 视点矩阵
/// 列表形式的投影矩阵
/// 列表形式的视点矩阵
/// 要投影的点的引用
/// 要投影的点引用列表
/// 屏幕宽
/// 屏幕高
/// 列表是否以行优先进行矩阵元素的存储
/// 水平翻转
/// 上下翻转
public void UnprojectScreenToWorld(
Matrix4x4 projectionMatrix,
Matrix4x4 viewMatrix,
ref Vector3 p)
{
// 世界坐标->相机坐标, 相机坐标->屏幕坐标 分别需要 viewMatrix和projectionMatrix
Matrix4x4 PV = projectionMatrix * viewMatrix;
// 逆矩阵即为从屏幕到世界的坐标变换,需指定像素深度
p = PV.inverse.MultiplyPoint(p);
}
public void UnprojectScreenToWorld(
IReadOnlyList projection,
IReadOnlyList view,
ref Vector3 p,
bool rowBase = true
)
{
Matrix4x4 projectionMatrix = ConstructMatirx(projection, rowBase);
Matrix4x4 viewMatrix = ConstructMatirx(view, rowBase);
UnprojectScreenToWorld(projectionMatrix, viewMatrix, ref p);
}
public void UnprojectScreenToWorld(
IReadOnlyList projection,
IReadOnlyList view,
ref Vector3 p,
float width,
float height,
bool rowBase = true,
bool flipLeftToRight = false,
bool flipUpsideDown = false
)
{
Matrix4x4 projectionMatrix = ConstructMatirx(projection, rowBase);
Matrix4x4 viewMatrix = ConstructMatirx(view, rowBase);
ScreenSpaceTransform(ref p, width, height, flipLeftToRight, flipUpsideDown);
UnprojectScreenToWorld(projectionMatrix, viewMatrix, ref p);
}
public void UnProjectScreenToWorld(
Matrix4x4 projectionMatrix,
Matrix4x4 viewMatrix,
ref List pl
)
{
Matrix4x4 PV = projectionMatrix * viewMatrix;
for (int i = 0; i < pl.Count; i++)
{
pl[i] = PV.inverse.MultiplyPoint(pl[i]);
}
}
public void UnProjectScreenToWorld(
IReadOnlyList projection,
IReadOnlyList view,
ref List pl,
float width,
float height,
bool rowBase = true,
bool flipLeftToRight = false,
bool flipUpsideDown = false
)
{
Matrix4x4 projectionMatrix = ConstructMatirx(projection, rowBase);
Matrix4x4 viewMatrix = ConstructMatirx(view, rowBase);
Matrix4x4 PV = projectionMatrix * viewMatrix;
ScreenSpaceTransform(ref pl, width, height, flipLeftToRight, flipUpsideDown);
for(int i = 0; i < pl.Count; i++)
{
pl[i] = PV.inverse.MultiplyPoint(pl[i]);
}
}
///
/// 获得相机的世界坐标,遵从 Direct3D 标准的左手笛卡尔坐标系。
///
/// 视点矩阵
///
public Vector3 GetCameraPosition(Matrix4x4 viewMatrix)
{
Matrix4x4 invV = viewMatrix.inverse;
return new Vector3(invV.m30, invV.m31, invV.m32);
}
///
/// 获得相机的世界坐标,遵从 Direct3D 标准的左手笛卡尔坐标系。
///
/// 视点矩阵元素列表
/// 列表是否以行优先进行矩阵元素的存储
///
public Vector3 GetCameraPosition(IReadOnlyList view, bool rowBase = true)
{
Matrix4x4 viewMatrix = ConstructMatirx(view, rowBase);
Matrix4x4 invV = viewMatrix.inverse;
return new Vector3(invV.m30, invV.m31, invV.m32);
}
///
/// 获得相机的视线方向,遵从 Direct3D 标准的左手笛卡尔坐标系。
///
/// 视点矩阵
///
public Vector3 GetCameraViewDirection(Matrix4x4 viewMatrix)
{
Matrix4x4 invV = viewMatrix.inverse;
return new Vector3(invV.m20, invV.m21, invV.m22);
}
///
/// 获得相机的视线方向,遵从 Direct3D 标准的左手笛卡尔坐标系。
///
/// 视点矩阵元素列表
/// 列表是否以行优先进行矩阵元素的存储
///
public Vector3 GetCameraViewDirection(IReadOnlyList view, bool rowBase = true)
{
Matrix4x4 viewMatrix = ConstructMatirx(view, rowBase);
Matrix4x4 invV = viewMatrix.inverse;
return new Vector3(invV.m20, invV.m21, invV.m22);
}
///
/// 将屏幕点坐标转换成以屏幕中心为原点,
/// 右和上分别为x,y正方向,
/// -1到1的坐标
///
/// 屏幕宽或高
/// 像素坐标(指定宽则为横坐标,指定高则为纵坐标)
/// 是否翻转(Unity通常情况下会将纵坐标翻转)
///
public void ScreenSpaceTransform(ref Vector3 p, float width, float height, bool flipLeftToRight = false, bool flipUpSideDown = false)
{
p.Set((p.x / width * 2 - 1) * (flipLeftToRight ? -1 : 1),
(p.y / height * 2 - 1) * (flipUpSideDown ? -1 : 1),
p.z);
}
public void ScreenSpaceTransform(ref List pl, float width, float height, bool flipLeftToRight = false, bool flipUpSideDown = false)
{
for(int i = 0; i
{
pl[i].Set((pl[i].x / width * 2 - 1) * (flipLeftToRight ? -1 : 1),
(pl[i].y / height * 2 - 1) * (flipUpSideDown ? -1 : 1),
pl[i].z);
}
}
///
/// 从列表中构造Matirx4x4矩阵
///
/// 矩阵元素列表
/// 列表是否以行优先进行矩阵元素的存储
///
public Matrix4x4 ConstructMatirx(IReadOnlyList elements, bool rowBase = true)
{
if (elements.Count != 16) return Matrix4x4.identity;
Matrix4x4 mat = new Matrix4x4();
if (rowBase)
{
mat.m00 = elements[0];
mat.m01 = elements[1];
mat.m02 = elements[2];
mat.m03 = elements[3];
mat.m10 = elements[4];
mat.m11 = elements[5];
mat.m12 = elements[6];
mat.m13 = elements[7];
mat.m20 = elements[8];
mat.m21 = elements[9];
mat.m22 = elements[10];
mat.m23 = elements[11];
mat.m30 = elements[12];
mat.m31 = elements[13];
mat.m32 = elements[14];
mat.m33 = elements[15];
}
else
{
mat.m00 = elements[0];
mat.m10 = elements[1];
mat.m20 = elements[2];
mat.m30 = elements[3];
mat.m01 = elements[4];
mat.m11 = elements[5];
mat.m21 = elements[6];
mat.m31 = elements[7];
mat.m02 = elements[8];
mat.m12 = elements[9];
mat.m22 = elements[10];
mat.m32 = elements[11];
mat.m03 = elements[12];
mat.m11 = elements[13];
mat.m23 = elements[14];
mat.m33 = elements[15];
}
return mat;
}
}
坐标的转换,用的地方特别多,尤其是屏幕划线展示在世界坐标中,我把他形成了工具,直接可以用。
unity 坐标系转换_Unity3D之笛卡尔坐标系转换——屏幕坐标转换世界坐标,世界坐标转换相机坐标工具...相关推荐
- 经纬度与地心笛卡尔坐标系转换
个人随笔 (Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu) 经纬度与笛卡尔坐标系转换,转换的几何计算并不复杂,不过不推理一遍的话,始终是理解的不够透彻.所 ...
- 印章识别--笛卡尔坐标系转换成极坐标系
#代码,使用了opencv自带的函数linearPolar import cv2 import numpy as npsource = cv2.imread('images/image.jpg', 1 ...
- 笛卡尔坐标系和Frenet坐标系
笛卡尔坐标系和Frenet坐标系 Frenet坐标系,自动驾驶"混乱"的源头 [自动驾驶]运动规划丨轨迹规划丨Frenet坐标转换 [自动驾驶]笛卡尔坐标系和frenet坐标系相互 ...
- 拉普拉斯算子从笛卡尔坐标系到圆柱坐标系下的推导过程
这段时间推导圆膜振动方程的时候,需要将振动方程从笛卡尔坐标系转换到圆柱坐标系.虽然这个结果书上都有了,但是不满足于直接给出的结果,想自己推导一下.于是就有了下面的内容.总结起来:就是将笛卡尔坐标系下的 ...
- 双球坐标系_坐标系为啥有多种,笛卡尔坐标系、柱坐标系、球坐标系都有啥区别...
什么是坐标系 坐标系,是理科常用辅助方法.为了说明质点的位置.运动的快慢.方向等,必须选取其坐标系.在 参照系 中,为确定空间一点的位置,按规定方法选取的有次序的一组数据,这就叫做"坐标&q ...
- Frenet坐标系及其与笛卡尔坐标的转换(2)——原理
目录 文章目录 目录 4.1.3 推导 s ˙ \dot{s} s˙ 4.1.4 推导 l ′ ′ l'' l′′ 4.1.5 推导 s ¨ \ddot{s} s¨ 4.1.6 推导 l ¨ \ddo ...
- Frenet坐标系及其与笛卡尔坐标的转换(1)——原理
目录 文章目录 目录 1 Frenet坐标系 2 Frenet坐标系基本概念 3 位置:笛卡尔与Frenet坐标点位置的转换 3.1 位置:笛卡尔坐标 -> Frenet坐标 3.1.1 求解 ...
- unity 坐标系转换_Unity的几种坐标系及相互转换
介绍 1.WorldSpace(世界坐标系) 当我们向场景中添加物体时,他们都是以世界坐标系的方式的方式显示在场景中的 通过transform.position可以得到它在世界中的坐标位置,trans ...
- 笛卡尔坐标系_Shader学习(4)坐标系和矢量的概念
文中多有引用,如有侵权请指出. 坐标系和矢量的概念 1. 笛卡尔坐标系 (1) 在三维游戏的实现中,所有的物体和图像都在笛卡尔坐标系的基础上实现. (2) 二维坐标系和三维坐标系,这些知识在高中时期就 ...
最新文章
- JSP与Web技术概论
- SAP MM Purchasing Report中Selection Parameter WE101 WE103
- NOIp #2010
- WINDOWS 几种坐标系
- 从网络访问计算机不能添加用户名,windows7 和 XP 能互相用\\ip访问,但是不能通过计算机名访问...
- Java导入导出Excel工具类ExcelUtil
- 2952 细胞分裂 2
- PDFlib TET Crack,文本提取工具包
- 美通企业日报 | 阿迪发布星战系列球鞋;安进27亿美元收购百济神州20.5%股份
- 华硕飞行堡垒atk驱动在哪_11月8日华硕再撒大额福利 满减优惠价机不可失_第1页...
- 面试:list集合去重
- Ant Design Vue 菜单刷新后保持菜单选中/点击菜单,收起其他展开的所有菜单,保持菜单聚焦简洁
- 从社区报告看未来20年美国AI研究战略
- 微信小程序 登陆过期,请重新授权
- 分析、归纳、综合、演绎
- R费希尔精确检验(Fisher‘s exact test)
- redis 学习笔记
- nginx本地代理调试微信登录(window版本)
- 基于VUE的SVG动画处理(一)
- AI 人工智能学习路线
热门文章
- Javascript(JS) leetcode 279. 完全平方数
- 冒泡排序(Bubble Sort)的学习
- ubuntu下禁止TeamViewer开机自启分析
- iOS视频下载遇到的问题(附上AFHTTPRequestOperation下载视频方法)
- 应届毕业/临时访深码工深圳居住计划
- 3G手机Android应用开发视频教程_黎活明老师的视频下载地址(总共有八天课程)
- 秒懂!!单臂路由!网络如此简单
- 影视编导必备三项知识
- 软件研发管理经验总结-管理细分
- 程序人生:老板要求“996工作制” 你该怎么办?