Skip to content

Commit 7a0b056

Browse files
committed
Trying out MeshCamera
1 parent 4b7c344 commit 7a0b056

3 files changed

Lines changed: 401 additions & 5 deletions

File tree

src/gameobjects/mesh/Mesh.js

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ var GameObjectEvents = require('../events');
1313
var GetCalcMatrix = require('../GetCalcMatrix');
1414
var GetColor = require('../../display/color/GetColor');
1515
var GetFastValue = require('../../utils/object/GetFastValue');
16+
var Matrix4 = require('../../math/Matrix4');
17+
var Vector3 = require('../../math/Vector3');
18+
var MeshCamera = require('./MeshCamera');
1619
var MeshRender = require('./MeshRender');
1720
var StableSort = require('../../utils/array/StableSort');
1821
var Vertex = require('../../geom/mesh/Vertex');
@@ -100,6 +103,18 @@ var Mesh = new Class({
100103

101104
GameObject.call(this, scene, 'Mesh');
102105

106+
/**
107+
* A Camera which can be used to control the view of the models being managed
108+
* by this Mesh. It will default to have an fov of 45 and be positioned at 0, 0, -10,
109+
* with a near of 0.01 and far of 1000. You can change all of these by using the
110+
* methods and properties available on the `MeshCamera` class.
111+
*
112+
* @name Phaser.GameObjects.Mesh#camera
113+
* @type {Phaser.GameObjects.MeshCamera}
114+
* @since 3.50.0
115+
*/
116+
this.camera = new MeshCamera(45, 0, 0, -10, 0.01, 1000);
117+
103118
/**
104119
* The Animation State of this Mesh.
105120
*
@@ -194,9 +209,15 @@ var Mesh = new Class({
194209
*/
195210
this.hideCCW = true;
196211

212+
this.transformMatrix = new Matrix4();
213+
this._position = new Vector3();
214+
this._rotation = new Vector3();
215+
this._scale = new Vector3(1, 1, 1);
216+
197217
this.setTexture(texture, frame);
198218
this.setPosition(x, y);
199-
this.setSizeToFrame();
219+
this.setSize(800, 600);
220+
// this.setSizeToFrame();
200221
this.initPipeline();
201222

202223
if (vertices)
@@ -1036,6 +1057,23 @@ var Mesh = new Class({
10361057
preUpdate: function (time, delta)
10371058
{
10381059
this.anims.update(time, delta);
1060+
1061+
var camera = this.camera;
1062+
1063+
camera.update(800, 600);
1064+
1065+
var transformMatrix = this.transformMatrix;
1066+
1067+
transformMatrix.setWorldMatrix(this._rotation, this._position, this._scale, camera.viewMatrix, camera.projectionMatrix);
1068+
1069+
var vertices = this.vertices;
1070+
1071+
for (var i = 0; i < vertices.length; i++)
1072+
{
1073+
vertices[i].transformCoordinatesLocal(transformMatrix, 800, 600);
1074+
}
1075+
1076+
this.depthSort();
10391077
},
10401078

10411079
/**

src/gameobjects/mesh/MeshCamera.js

Lines changed: 302 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,302 @@
1+
/**
2+
* @author Richard Davey <rich@photonstorm.com>
3+
* @copyright 2020 Photon Storm Ltd.
4+
* @license {@link https://opensource.org/licenses/MIT|MIT License}
5+
*/
6+
7+
var Class = require('../../utils/Class');
8+
var DegToRad = require('../../math/DegToRad');
9+
var Matrix4 = require('../../math/Matrix4');
10+
var Vector3 = require('../../math/Vector3');
11+
var Vector4 = require('../../math/Vector4');
12+
13+
/**
14+
* @classdesc
15+
* The Mesh Camera.
16+
*
17+
* @class MeshCamera
18+
* @memberof Phaser.GameObjects
19+
* @constructor
20+
* @since 3.50.0
21+
*/
22+
var MeshCamera = new Class({
23+
24+
initialize:
25+
26+
function MeshCamera (fov, x, y, z, near, far)
27+
{
28+
this.dirty = true;
29+
this.aspectRatio = 1;
30+
31+
this._fov = fov;
32+
this._near = near;
33+
this._far = far;
34+
35+
this.position = new Vector3(x, y, z);
36+
this.rotation = new Vector3();
37+
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
41+
42+
this.matView = new Matrix4();
43+
this.viewMatrix = new Matrix4();
44+
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;
117+
},
118+
119+
update: function (width, height)
120+
{
121+
this.aspectRatio = width / height;
122+
123+
this.updateViewMatrix();
124+
125+
this.projectionMatrix.perspective(DegToRad(this._fov), this.aspectRatio, this._near, this._far);
126+
},
127+
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+
145+
fov: {
146+
147+
get: function ()
148+
{
149+
return this._fov;
150+
},
151+
152+
set: function (value)
153+
{
154+
if (value > 0 && value < 180)
155+
{
156+
this._fov = value;
157+
this.dirty = true;
158+
}
159+
}
160+
161+
},
162+
163+
near: {
164+
165+
get: function ()
166+
{
167+
return this._near;
168+
},
169+
170+
set: function (value)
171+
{
172+
if (value > 0)
173+
{
174+
this._near = value;
175+
this.dirty = true;
176+
}
177+
}
178+
179+
},
180+
181+
far: {
182+
183+
get: function ()
184+
{
185+
return this._far;
186+
},
187+
188+
set: function (value)
189+
{
190+
if (value > 0)
191+
{
192+
this._far = value;
193+
this.dirty = true;
194+
}
195+
}
196+
197+
},
198+
199+
x: {
200+
201+
get: function ()
202+
{
203+
return this.position.x;
204+
},
205+
206+
set: function (value)
207+
{
208+
this.position.x = value;
209+
this.updateViewMatrix();
210+
}
211+
212+
},
213+
214+
y: {
215+
216+
get: function ()
217+
{
218+
return this.position.y;
219+
},
220+
221+
set: function (value)
222+
{
223+
this.position.y = value;
224+
this.updateViewMatrix();
225+
}
226+
227+
},
228+
229+
z: {
230+
231+
get: function ()
232+
{
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;
264+
},
265+
266+
set: function (value)
267+
{
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();
285+
}
286+
287+
},
288+
289+
destroy: function ()
290+
{
291+
// TODO - Needed?
292+
}
293+
294+
});
295+
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+
302+
module.exports = MeshCamera;

0 commit comments

Comments
 (0)