AR/VR投影:Leap Magic是下阶段令人期待的产品
mrvrar吧
全部回复
仅看楼主
level 8
目前为止,无论是虚拟现实(VR)应用还是增强现实(AR)应用,图像本身的路径基本上都经历这样的过程:光 - 镜头 - 传感器 - 数字化 CV 算法 - LCD/LED 显示器,最终我们看到的 AR/VR 内容都是通过 LCD/LED 显示器传入人眼。而 LCD/LED 本身在耗电、重量、体积等方面存在缺陷,是 AR/VR 用户体验发展的主要瓶颈之一。
而 Magic Leap 拥有一种名为 Fiber Optic Projector 的核心技术,这种“投影仪”与传统意义上的投影相比,尺寸更小,功耗更低,可以通过一根直径 1 毫米长 9 毫米的光纤投出几英寸彩色图像。
2020年03月16日 05点03分 1
level 8
谈及 Fiber Optic Projector 的原理,我们就要从已经加盟了 Magic Leap 的华盛顿大学 Eric Seibel 教授说起。Prof. Eric Seibel 致力于研究内窥镜已有数十载,他的研究团队曾在 2013 年公开展示一种直径 1 毫米、基于光纤扫描的内窥镜。相比原来动辄几厘米直径的内窥镜而言,这是一种变革性的进步。它的原理简单来说就如下图 —— 内窥镜由基于 MEMS 的驱动器 Actuator、单光纤、镜头组、直径 1 毫米的套管组成。当内窥镜工作时,微电脑通过控制多个驱动器,精确控制光纤末端的扫描路径,通过画直径由小变大的同心圆来完成整个画面的图像扫描,再将数据回传给电脑合成图像。
2020年03月16日 05点03分 2
level 8
Magic Leap 的 Fiber Optic Projector 和这个内窥镜工作原理类似,只是光纤末端并不是用来采集图像,而是发出显示图像的光线,通过驱动器足够快速的扫描,让镜头末端得以逐个投出图像。这个原理听起来简单,要在工程上实现是非常了不起的。
2020年03月16日 05点03分 3
level 8
上面我们提到过,这种基于光纤扫描的显示设备有功耗低、重量轻、体积小等优点,而且可以通过多个光纤末端阵列堆叠的方式来实现 FOV (Field of View) 显示
2020年03月16日 05点03分 4
level 8
而对于这种光纤扫描投影仪的画质现在已经达到4K,虚拟现实技术还有很多问题:像素过低;加载速度跟不上人行为与视线的变化;戴头盔或眼罩不方便;戴久了头会眩晕……如果这些问题能够解决,未来将会超越我们的想像。
2020年03月16日 05点03分 5
level 8
[code]csharpcode:using UnityEngine;using System;using System.Data;using System.Collections;using MySql.Data.MySqlClient;using MySql.Data;using System.IO;public class SqlAccess{ public static MySqlConnection dbConnection; //如果只是在本地的话,写localhost就可以。 static string host = "localhost"; //如果是局域网,那么写上本机的局域网IP //static string host = "192.168.1.106"; static string id = "root"; static string pwd = "root"; //数据库名 static string database = ""; public SqlAccess() { OpenSql(); } public static void OpenSql() { try { string connectionString = string.Format("Server = {0};port={4};Database = {1}; User ID = {2}; Password = {3};", host, database, id, pwd, "3306"); dbConnection = new MySqlConnection(connectionString); dbConnection.Open(); } catch (Exception e) { throw new Exception("服务器连接失败,请重新检查是否打开MySql服务。" + e.Message.ToString()); } }
2020年03月16日 06点03分 6
level 8
/// <summary> /// 代码新建数据表 /// </summary> /// <param name="name">新建表名</param> /// <param name="col">字段数组及具体字段</param> /// <param name="colType">字段类型参数对应</param> /// <returns></returns> public DataSet CreateTableAutoID(string name, string[] col, string[] colType) { if (col.Length != colType.Length) { throw new Exception("columns.Length != colType.Length"); } string query = "CREATE TABLE " + name + " (" + col[0] + " " + colType[0] + " NOT NULL AUTO_INCREMENT"; for (int i = 1; i < col.Length; ++i) { query += ", " + col[i] + " " + colType[i]; } query += ", PRIMARY KEY (" + col[0] + ")" + ")"; Debug.Log(query); return ExecuteQuery(query); } //插入一条数据,包括所有,不适用自动累加ID。 /// <summary> /// 插入数据 /// </summary> /// <param name="tableName">表单名称、</param> /// <param name="values"></param> /// <returns></returns> public DataSet InsertInto(string tableName, string[] values) { string query = "INSERT INTO " + tableName + " VALUES (" + "'" + values[0] + "'"; for (int i = 1; i < values.Length; ++i) { query += ", " + "'" + values[i] + "'"; } query += ")"; Debug.Log(query); return ExecuteQuery(query); } //插入部分ID /// <summary> /// 插入数据 /// </summary> /// <param name="tableName">数据表名称</param> /// <param name="col">字段名称</param> /// <param name="values">数据值</param> /// <returns></returns> public DataSet InsertInto(string tableName, string[] col, string[] values) { if (col.Length != values.Length) { throw new Exception("columns.Length != colType.Length"); } string query = "INSERT INTO " + tableName + " (" + col[0]; for (int i = 1; i < col.Length; ++i) { query += ", " + col[i]; } query += ") VALUES (" + "'" + values[0] + "'"; for (int i = 1; i < values.Length; ++i) { query += ", " + "'" + values[i] + "'"; } query += ")"; Debug.Log(query); return ExecuteQuery(query); }
2020年03月16日 06点03分 7
level 8
/// <summary> /// 查找数据 /// </summary> /// <param name="tableName">数据表名称</param> /// <param name="items">需要查找字段名称</param> /// <param name="col">查找数据字段使用属性字段</param> /// <param name="operation">判断字符</param> /// <param name="values">查找数据字段使用属性字段对应的值</param> /// <returns></returns> public DataSet SelectWhere(string tableName, string[] items, string[] col, string[] operation, string[] values) { if (col.Length != operation.Length || operation.Length != values.Length) { throw new Exception("col.Length != operation.Length != values.Length"); } string query = "SELECT " + items[0]; for (int i = 1; i < items.Length; ++i) { query += ", " + items[i]; } query += " FROM " + tableName + " WHERE " + col[0] + operation[0] + "'" + values[0] + "' "; for (int i = 1; i < col.Length; ++i) { query += " AND " + col[i] + operation[i] + "'" + values[0] + "' "; } return ExecuteQuery(query); } /// <summary> /// /// </summary> /// <param name="tableName">数据表名</param> /// <param name="cols">需要更新的字段</param> /// <param name="colsvalues">需要更新的字段对应的值</param> /// <param name="selectkey">定位关系数据字段</param> /// <param name="selectvalue">定位关系数据对应的值</param> /// <returns></returns> public DataSet UpdateInto(string tableName, string[] cols, string[] colsvalues, string selectkey, string selectvalue) { //更新字段值 string query = "UPDATE " + tableName + " SET " + cols[0] + " = " + colsvalues[0]; for (int i = 1; i < colsvalues.Length; ++i) { query += ", " + cols[i] + " =" + colsvalues[i]; } query += " WHERE " + selectkey + " = " + selectvalue + " "; return ExecuteQuery(query); } /// <summary> /// 删除数据 /// </summary> /// <param name="tableName">数据表名</param> /// <param name="cols">字段</param> /// <param name="colsvalues">字段对应的值</param> /// <returns></returns> public DataSet Delete(string tableName, string[] cols, string[] colsvalues) { string query = "DELETE FROM " + tableName + " WHERE " + cols[0] + " = " + colsvalues[0]; for (int i = 1; i < colsvalues.Length; ++i) { query += " or " + cols[i] + " = " + colsvalues[i]; } Debug.Log(query); return ExecuteQuery(query); } public void Close() { if (dbConnection != null) { dbConnection.Close(); dbConnection.Dispose(); dbConnection = null; } } /// <summary> /// 执行Sq语句 /// </summary> /// <param name="sqlString"></param> /// <returns></returns> public static DataSet ExecuteQuery(string sqlString) { if (dbConnection.State == ConnectionState.Open) { DataSet ds = new DataSet(); try { MySqlDataAdapter da = new MySqlDataAdapter(sqlString, dbConnection); da.Fill(ds); } catch (Exception ee) { throw new Exception("SQL:" + sqlString + "/n" + ee.Message.ToString()); } finally { } return ds; } return null; }}[code]csharpcode:using UnityEngine;using System;using System.Data;using System.Collections;using MySql.Data.MySqlClient;using MySql.Data;using System.IO;public class SqlControll : MonoBehaviour{string Error = null;SqlAccess sql;void Start(){}/// <summary>/// 新建表单/// </summary>/// <param name="_tableName">表单名称</param>/// <param name="_field">表单中字段</param>/// <param name="_fieldType">表单中字段的类型</param>private void CreateTable(string _tableName,string[] _field,string[] _fieldType){//sql.CreateTableAutoID("momo", new string[] { "id", "name", "qq", "email", "blog" }, new string[] { "int", "text", "text", "text", "text" });try{sql = new SqlAccess();sql.CreateTableAutoID(_tableName, _field, _fieldType);sql.Close();}catch (Exception e){Error = e.Message;}}/// <summary>/// 添加数据/// </summary>/// <param name="_tableName">表单名称</param>/// <param name="_field">表单中字段</param>/// <param name="_fieldType">表单中字段赋值</param>private void InsertIntoData(string _tableName, string[] _field, string[] _fieldValue){//sql.InsertInto("momo", new string[] { "name", "qq", "email", "blog" }, new string[] { "ruoruo", "34546546", "[email protected]", "xuanyusong.com" });try {sql.InsertInto(_tableName, _field, _fieldValue);sql.Close();}catch(Exception e){Error = e.Message;}}
2020年03月16日 06点03分 8
level 8
/// <summary>/// 删除数据/// </summary>/// <param name="_tableName">表单名称</param>/// <param name="_field">表单中字段</param>/// <param name="_fieldValue">表单中字段赋值</param>private void DeleteData(string _tableName, string[] _field, string[] _fieldValue){//sql.Delete("momo", new string[] { "qq", "email" }, new string[] { "34546546", "'[email protected]'" });try{sql.Delete(_tableName, _field, _fieldValue);sql.Close();}catch (Exception e){Error = e.Message;}}/// <summary>/// 更新数据(通过关系字段及值确定在表中的数据组,并更新在数据组中需要更新的数据)/// </summary>/// <param name="tableName">数据表名</param>/// <param name="_field">需要更新的字段</param>/// <param name="_fieldValue">需要更新的字段对应的值</param>/// <param name="_verifyField">关系字段</param>/// <param name="_verifyFieldValue">关系字段值</param>private void UpdateData(string _tableName, string[] _field, string[] _fieldValue,string _verifyField,string _verifyFieldValue){//sql.UpdateInto("momo", new string[] { "name", "qq" }, new string[] { "'ruoruo'", "'11111111'" }, "email", "'[email protected]'");try{sql.UpdateInto(_tableName, _field, _fieldValue, _verifyField, _verifyFieldValue);sql.Close();}catch (Exception e){Error = e.Message;}}/// <summary>/// 查找数据(通过关系字段及值确定在表中的数据组,并查找在数据组中需要查找的数据)/// </summary>/// <param name="_tableName"></param>/// <param name="_field">查找的数据字段</param>/// <param name="_verifyField">关系字段</param>/// <param name="_verifyFieldValue">关系字段值</param>private void SelectData(string _tableName, string[] _field, string[] _verifyField, string[] _verifyFieldValue){//DataSet ds = sql.SelectWhere("momo", new string[] { "name", "email" }, new string[] { "qq" }, new string[] { "=" }, new string[] { "34546546" });try{DataSet ds = sql.SelectWhere(_tableName, _field, _verifyField, new string[] { "=" }, _verifyFieldValue);sql.Close();if (ds != null){DataTable table = ds.Tables[0];foreach (DataRow row in table.Rows){foreach (DataColumn column in table.Columns){Debug.Log(row[column]);}}}}catch (Exception e){Error = e.Message;}}// Update is called once per framevoid OnGUI(){if (Error != null){GUILayout.Label(Error);}}}
2020年03月16日 06点03分 9
level 8
代码为 U3D调用MySQL的增删改查基本功能
2020年03月16日 07点03分 10
1