-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathDragControlsByPlane.js
More file actions
155 lines (107 loc) · 4.18 KB
/
DragControlsByPlane.js
File metadata and controls
155 lines (107 loc) · 4.18 KB
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*
* Running this will allow you to drag three.js objects around the screen.
*
* feature requests:
* 1. add rotation?
* 2. axis lock
* 3. inertia dragging
* 4. activate/deactivate? prevent propagation?
*
* @author zz85 from https://github.com/zz85
* follow on http://twitter.com/blurspline
*/
THREE.DragControlsByPlane = function(_camera, _objects, _domElement) {
var _projector = new THREE.Projector();
var _mouse = new THREE.Vector3(),
_offset = new THREE.Vector3();
var _selected;
var p3subp1 = new THREE.Vector3();
var targetposition = new THREE.Vector3();
var zerovector = new THREE.Vector3();
this.setObjects = function(objects) {
if (objects instanceof THREE.Scene) {
_objects = objects.children;
} else {
_objects = objects;
}
};
this.setObjects(_objects);
this.activate = function() {
_domElement.addEventListener('mousemove', onDocumentMouseMove, false);
_domElement.addEventListener('mousedown', onDocumentMouseDown, false);
_domElement.addEventListener('mouseup', onDocumentMouseUp, false);
};
this.deactivate = function() {
_domElement.removeEventListener('mousemove', onDocumentMouseMove, false);
_domElement.removeEventListener('mousedown', onDocumentMouseDown, false);
_domElement.removeEventListener('mouseup', onDocumentMouseUp, false);
};
this.activate();
function onDocumentMouseMove(event) {
event.preventDefault();
_mouse.x = (event.clientX / _domElement.width) * 2 - 1;
_mouse.y = -(event.clientY / _domElement.height) * 2 + 1;
var ray = _projector.pickingRay(_mouse, _camera);
if (_selected) {
var normal = _selected.normal;
// I found this article useful about plane-line intersections
// http://paulbourke.net/geometry/planeline/
var denom = normal.dot(ray.direction);
if (denom == 0) {
// bail
console.log('no or infinite solutions');
return;
}
var num = normal.dot(p3subp1.copy(_selected.point).subSelf(ray.origin));
var u = num / denom;
targetposition.copy(ray.direction).multiplyScalar(u).addSelf(ray.origin).subSelf(_offset);
// _selected.object.position.copy(targetposition);
var xLock, yLock, zLock = false;
var moveX, moveY, moveZ;
if (xLock) {
moveX = true;
moveY = false;
moveZ = false;
} else if (yLock) {
moveX = false;
moveY = true;
moveZ = false;
} else {
moveX = moveY = moveZ = false;
}
// Reverse Matrix?
if (moveX) _selected.object.position.x = targetposition.x;
if (moveY) _selected.object.position.y = targetposition.y;
if (moveZ) _selected.object.position.z = targetposition.z;
return;
}
var intersects = ray.intersectObjects(_objects);
if (intersects.length > 0) {
_domElement.style.cursor = 'pointer';
} else {
_domElement.style.cursor = 'auto';
}
}
function onDocumentMouseDown(event) {
event.preventDefault();
_mouse.x = (event.clientX / _domElement.width) * 2 - 1;
_mouse.y = -(event.clientY / _domElement.height) * 2 + 1;
var ray = _projector.pickingRay(_mouse, _camera);
var intersects = ray.intersectObjects(_objects);
var normal = _projector.pickingRay(zerovector, _camera).direction; // normal ray to the camera position
if (intersects.length > 0) {
_selected = intersects[0];
_selected.ray = ray;
_selected.normal = normal ;
_offset.copy(_selected.point).subSelf(_selected.object.position);
_domElement.style.cursor = 'move';
}
}
function onDocumentMouseUp(event) {
event.preventDefault();
if (_selected) {
_selected = null;
}
_domElement.style.cursor = 'auto';
}
}