Skip to content

Commit 5ff9894

Browse files
committed
MeshCamera now supports orbit and pan modes
1 parent d40f99c commit 5ff9894

1 file changed

Lines changed: 158 additions & 17 deletions

File tree

src/gameobjects/mesh/MeshCamera.js

Lines changed: 158 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ var Class = require('../../utils/Class');
88
var DegToRad = require('../../math/DegToRad');
99
var Matrix4 = require('../../math/Matrix4');
1010
var Vector3 = require('../../math/Vector3');
11+
var Vector4 = require('../../math/Vector4');
1112

1213
/**
1314
* @classdesc
@@ -31,24 +32,116 @@ var MeshCamera = new Class({
3132
this._near = near;
3233
this._far = far;
3334

34-
this._position = new Vector3(x, y, z);
35-
this._target = new Vector3();
35+
this.position = new Vector3();
36+
this.rotation = new Vector3();
3637

37-
this.orientation = Vector3.DOWN;
38+
this.forward = new Vector4();
39+
this.up = new Vector4(); // What the up direction is, invert to get bottom
40+
this.right = new Vector4(); // What the right direction is, invert to get left
3841

42+
this.matView = new Matrix4();
3943
this.viewMatrix = new Matrix4();
4044
this.projectionMatrix = new Matrix4();
45+
46+
this.mode = MeshCamera.MODE_ORBIT;
47+
},
48+
49+
panX: function (v)
50+
{
51+
this.updateViewMatrix();
52+
53+
this.position.addScale(this.right, v);
54+
},
55+
56+
panY: function (v)
57+
{
58+
this.updateViewMatrix();
59+
60+
this.position.y += this.up.y * v;
61+
62+
if (this.mode === MeshCamera.MODE_ORBIT)
63+
{
64+
// Can only move up and down the y axix in orbit mode
65+
return;
66+
}
67+
68+
this.position.x += this.up.x * v;
69+
this.position.z += this.up.z * v;
70+
},
71+
72+
panZ: function (v)
73+
{
74+
this.updateViewMatrix();
75+
76+
if (this.mode === MeshCamera.MODE_ORBIT)
77+
{
78+
// orbit mode does translate after rotate, so only need to set Z, the rotate will handle the rest.
79+
this.position.z += v;
80+
}
81+
else
82+
{
83+
// In freemode to move forward, we need to move based on our forward which is relative to our current rotation
84+
this.position.addScale(this.forward, v);
85+
}
86+
},
87+
88+
// To have different modes of movements, this function handles the view matrix update for the transform object.
89+
updateViewMatrix: function ()
90+
{
91+
var d = Math.PI / 180;
92+
var matView = this.matView;
93+
var rotation = this.rotation;
94+
95+
matView.identity();
96+
97+
// Optimize camera transform update, no need for scale nor rotateZ
98+
if (this.mode === MeshCamera.MODE_FREE)
99+
{
100+
matView.translate(this.position);
101+
matView.rotateX(rotation.x * d);
102+
matView.rotateY(rotation.y * d);
103+
}
104+
else
105+
{
106+
matView.rotateX(rotation.x * d);
107+
matView.rotateY(rotation.y * d);
108+
matView.translate(this.position);
109+
}
110+
111+
this.updateDirection();
112+
113+
this.viewMatrix.copy(matView);
114+
this.viewMatrix.invert();
115+
116+
this.dirty = true;
41117
},
42118

43119
update: function (width, height)
44120
{
45121
this.aspectRatio = width / height;
46122

47-
this.viewMatrix.lookAt(this._position, this._target, this.orientation);
123+
this.updateViewMatrix();
48124

49125
this.projectionMatrix.perspective(DegToRad(this._fov), this.aspectRatio, this._near, this._far);
50126
},
51127

128+
updateDirection: function ()
129+
{
130+
var matView = this.matView;
131+
132+
this.forward.set(0, 0, 1, 0).transformMat4(matView);
133+
this.up.set(0, 1, 0, 0).transformMat4(matView);
134+
this.right.set(1, 0, 0, 0).transformMat4(matView);
135+
},
136+
137+
reset: function ()
138+
{
139+
this.position.set();
140+
this.rotation.set();
141+
142+
this.updateViewMatrix();
143+
},
144+
52145
fov: {
53146

54147
get: function ()
@@ -107,13 +200,13 @@ var MeshCamera = new Class({
107200

108201
get: function ()
109202
{
110-
return this._position.x;
203+
return this.position.x;
111204
},
112205

113206
set: function (value)
114207
{
115-
this._position.x = value;
116-
this.dirty = true;
208+
this.position.x = value;
209+
this.updateViewMatrix();
117210
}
118211

119212
},
@@ -122,13 +215,13 @@ var MeshCamera = new Class({
122215

123216
get: function ()
124217
{
125-
return this._position.y;
218+
return this.position.y;
126219
},
127220

128221
set: function (value)
129222
{
130-
this._position.y = value;
131-
this.dirty = true;
223+
this.position.y = value;
224+
this.updateViewMatrix();
132225
}
133226

134227
},
@@ -137,25 +230,73 @@ var MeshCamera = new Class({
137230

138231
get: function ()
139232
{
140-
return this._position.z;
233+
return this.position.z;
234+
},
235+
236+
set: function (value)
237+
{
238+
this.position.z = value;
239+
this.updateViewMatrix();
240+
}
241+
242+
},
243+
244+
rotationX: {
245+
246+
get: function ()
247+
{
248+
return this.rotation.x;
249+
},
250+
251+
set: function (value)
252+
{
253+
this.rotation.x = value;
254+
this.updateViewMatrix();
255+
}
256+
257+
},
258+
259+
rotationY: {
260+
261+
get: function ()
262+
{
263+
return this.rotation.y;
141264
},
142265

143266
set: function (value)
144267
{
145-
this._position.z = value;
146-
this.dirty = true;
268+
this.rotation.y = value;
269+
this.updateViewMatrix();
270+
}
271+
272+
},
273+
274+
rotationZ: {
275+
276+
get: function ()
277+
{
278+
return this.rotation.z;
279+
},
280+
281+
set: function (value)
282+
{
283+
this.rotation.z = value;
284+
this.updateViewMatrix();
147285
}
148286

149287
},
150288

151289
destroy: function ()
152290
{
153-
this._position = null;
154-
this._target = null;
155-
this.viewMatrix = null;
156-
this.projectionMatrix = null;
291+
// TODO - Needed?
157292
}
158293

159294
});
160295

296+
// Allows free movement of position and rotation
297+
MeshCamera.MODE_FREE = 0;
298+
299+
// Movement is locked to rotate around the origin
300+
MeshCamera.MODE_ORBIT = 1;
301+
161302
module.exports = MeshCamera;

0 commit comments

Comments
 (0)