原文链接:http://www.arvrschool.com/read.php?tid=22
ARVR技术交流群:129340649
模型交互主要还是以下这些交互方式:
主要的交互方式包括:1、模型的旋转、平移和缩放
这些需要配合触屏来操作。
2、模型的选定-射线法
模型选定之后显示高亮边框
3、模型动画的操作
使用代码,控制模型坐标等
使用Unity3d动画系统来完成
4、音频、文字等
使用Unity3D自带的组件完成
NGUI
5、其他
填色板等
这里先介绍最基本的交互方式:模型的旋转、平移和缩放
如果在PC上,使用鼠标操作。
如果在移动终端上,需要结合触屏来操作。
先来分析下旋转平移的原理,主要涉及到模型和摄像头的投影矩阵。
因此,一个模型的旋转、平移和缩放主要受这两者的投影矩阵对应关系影响。改变其中一个,都会使模型发生变化。
在一般的场景中,可以改变两者,而且改变摄像头的位置是比较常用的方式,因为对于缩放比较容易,网上一大推教程,可以去看看。
但是对AR场景,由于ARCamera是不能移动的,所以只能通过改变模型本身的坐标系。
请看下面的代码:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
using
UnityEngine;
using
System.Collections;
public
class
Move : MonoBehaviour
{
public
Transform target;
float
distance = 30f;
float
xSpeed = 150f;
float
ySpeed = 150f;
float
yMinLimit = -180f;
float
yMaxLimit = 180f;
float
x = 0f;
float
y = 0f;
Vector2 oldPosition1;
Vector2 oldPosition2;
private
bool
flag_Roable =
true
;
//自动旋转标志
private
System.DateTime oldTime;
private
System.DateTime nowTime;
// Use this for initialization
void
Start()
{
transform.eulerAngles =
new
Vector3 (0,-90,0);
Vector3 angles = transform.eulerAngles;
x = angles.y;
y = angles.x;
if
(rigidbody)
{
rigidbody.freezeRotation =
true
;
}
oldTime = System.DateTime.Now;
}
// Update is called once per frame
void
Update()
{
nowTime = System.DateTime.Now;
System.TimeSpan ts1 =
new
System.TimeSpan(oldTime.Ticks);
System.TimeSpan ts2 =
new
System.TimeSpan(nowTime.Ticks);
System.TimeSpan ts = ts2.Subtract(ts1).Duration();
if
(ts.Seconds > 8 && !Input.anyKey)
{
flag_Roable =
true
;
oldTime = System.DateTime.Now;
}
if
(Input.anyKey)
{
/*
if (Input.touchCount == 1)
{
if (Input.GetTouch(0).phase == TouchPhase.Moved)
{
//x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
//y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
x = Input.GetAxis("Mouse X") * xSpeed ;
y = Input.GetAxis("Mouse Y") * ySpeed ;
transform.Rotate(Vector3.up * -x * Time.deltaTime, Space.World);
transform.Rotate(Vector3.right * y * Time.deltaTime, Space.World);
}
}*/
if
(Input.touchCount > 1)
{
if
(Input.GetTouch(0).phase == TouchPhase.Moved || Input.GetTouch(1).phase == TouchPhase.Moved)
{
Vector2 tempPosition1 = Input.GetTouch(0).position;
Vector2 tempPosition2 = Input.GetTouch(1).position;
if
(isEnlarge(oldPosition1, oldPosition2, tempPosition1, tempPosition2))
{
float
oldScale = transform.localScale.x;
float
newScale = oldScale * 1.025f;
transform.localScale =
new
Vector3(newScale, newScale, newScale);
}
else
{
float
oldScale = transform.localScale.x;
float
newScale = oldScale / 1.025f;
transform.localScale =
new
Vector3(newScale, newScale, newScale);
}
//备份上一次触摸点的位置,用于对比
oldPosition1 = tempPosition1;
oldPosition2 = tempPosition2;
}
}
}
}
bool
isEnlarge(Vector2 oP1, Vector2 oP2, Vector2 nP1, Vector2 nP2)
{
//函数传入上一次触摸两点的位置与本次触摸两点的位置计算出用户的手势
var leng1 = Mathf.Sqrt((oP1.x - oP2.x) * (oP1.x - oP2.x) + (oP1.y - oP2.y) * (oP1.y - oP2.y));
var leng2 = Mathf.Sqrt((nP1.x - nP2.x) * (nP1.x - nP2.x) + (nP1.y - nP2.y) * (nP1.y - nP2.y));
if
(leng1 < leng2)
{
//放大手势
return
true
;
}
else
{
//缩小手势
return
false
;
}
}
}
|