mirror of
https://github.com/photonstorm/phaser
synced 2024-11-23 05:03:37 +00:00
Merge branch 'master' of https://github.com/svipal/phaser into master
This commit is contained in:
commit
7ca2f9f10b
17 changed files with 727 additions and 397 deletions
|
@ -11,7 +11,9 @@ var GameObjectEvents = require('../events');
|
|||
var GetCalcMatrix = require('../GetCalcMatrix');
|
||||
var MeshRender = require('./MeshRender');
|
||||
var MeshCamera = require('./MeshCamera');
|
||||
var MeshLight = require('./MeshLight');
|
||||
var Model = require('../../geom/mesh/Model');
|
||||
var Vector3 = require('../../math/Vector3');
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
|
@ -84,6 +86,8 @@ var Mesh = new Class({
|
|||
*/
|
||||
this.camera = new MeshCamera(45, 0, 0, -10, 0.01, 1000);
|
||||
|
||||
this.light = new MeshLight();
|
||||
|
||||
/**
|
||||
* An array of Model instances that have been created in this Mesh.
|
||||
*
|
||||
|
@ -152,7 +156,8 @@ var Mesh = new Class({
|
|||
|
||||
this.setSize(renderer.width, renderer.height);
|
||||
|
||||
this.initPipeline();
|
||||
// TODO - Change to const
|
||||
this.initPipeline('MeshPipeline');
|
||||
|
||||
if (vertices)
|
||||
{
|
||||
|
@ -324,6 +329,7 @@ var Mesh = new Class({
|
|||
|
||||
var vertices = modelData.vertices;
|
||||
var textureCoords = modelData.textureCoords;
|
||||
var normals = modelData.vertexNormals;
|
||||
var faces = modelData.faces;
|
||||
|
||||
var defaultUV1 = { u: 0, v: 1 };
|
||||
|
@ -334,14 +340,20 @@ var Mesh = new Class({
|
|||
{
|
||||
var face = faces[i];
|
||||
|
||||
// {textureCoordsIndex: 0, vertexIndex: 16, vertexNormalIndex: 16}
|
||||
var v1 = face.vertices[0];
|
||||
var v2 = face.vertices[1];
|
||||
var v3 = face.vertices[2];
|
||||
|
||||
// {x: 0.19509, y: 0.980785, z: 0}
|
||||
var m1 = vertices[v1.vertexIndex];
|
||||
var m2 = vertices[v2.vertexIndex];
|
||||
var m3 = vertices[v3.vertexIndex];
|
||||
|
||||
var n1 = normals[v1.vertexNormalIndex];
|
||||
var n2 = normals[v2.vertexNormalIndex];
|
||||
var n3 = normals[v3.vertexNormalIndex];
|
||||
|
||||
var t1 = v1.textureCoordsIndex;
|
||||
var t2 = v2.textureCoordsIndex;
|
||||
var t3 = v3.textureCoordsIndex;
|
||||
|
@ -350,9 +362,9 @@ var Mesh = new Class({
|
|||
var uv2 = (t2 === -1) ? defaultUV2 : textureCoords[t2];
|
||||
var uv3 = (t3 === -1) ? defaultUV3 : textureCoords[t3];
|
||||
|
||||
var vert1 = model.addVertex(originX + m1.x * scale, originY + m1.y * scale, originZ + m1.z * scale, uv1.u, uv1.v);
|
||||
var vert2 = model.addVertex(originX + m2.x * scale, originY + m2.y * scale, originZ + m2.z * scale, uv2.u, uv2.v);
|
||||
var vert3 = model.addVertex(originX + m3.x * scale, originY + m3.y * scale, originZ + m3.z * scale, uv3.u, uv3.v);
|
||||
var vert1 = model.addVertex(originX + m1.x * scale, originY + m1.y * scale, originZ + m1.z * scale, uv1.u, uv1.v, n1.x, n1.y, n1.z);
|
||||
var vert2 = model.addVertex(originX + m2.x * scale, originY + m2.y * scale, originZ + m2.z * scale, uv2.u, uv2.v, n2.x, n2.y, n2.z);
|
||||
var vert3 = model.addVertex(originX + m3.x * scale, originY + m3.y * scale, originZ + m3.z * scale, uv3.u, uv3.v, n3.x, n3.y, n3.z);
|
||||
|
||||
model.addFace(vert1, vert2, vert3);
|
||||
}
|
||||
|
@ -533,6 +545,7 @@ var Mesh = new Class({
|
|||
|
||||
var camera = this.camera;
|
||||
|
||||
/*
|
||||
if (camera.dirty || width !== this._prevWidth || height !== this._prevHeight)
|
||||
{
|
||||
// Mesh has resized, flow that down to the Camera
|
||||
|
@ -541,6 +554,9 @@ var Mesh = new Class({
|
|||
this._prevWidth = width;
|
||||
this._prevHeight = height;
|
||||
}
|
||||
*/
|
||||
|
||||
camera.update(width, height);
|
||||
|
||||
var models = this.models;
|
||||
|
||||
|
|
|
@ -39,9 +39,10 @@ var MeshCamera = new Class({
|
|||
this.up = new Vector4(); // What the up direction is, invert to get bottom
|
||||
this.right = new Vector4(); // What the right direction is, invert to get left
|
||||
|
||||
this.matView = new Matrix4();
|
||||
this.viewMatrix = new Matrix4();
|
||||
this.projectionMatrix = new Matrix4();
|
||||
this.matrix = new Matrix4(); // the transform matrix
|
||||
this.viewMatrix = new Matrix4(); // the inverse of the transform matrix
|
||||
this.projectionMatrix = new Matrix4(); // perspective projection matrix
|
||||
this.viewProjectionMatrix = new Matrix4(); // perspective projection matrix multiplied by the view matrix
|
||||
|
||||
this.mode = MeshCamera.MODE_ORBIT;
|
||||
},
|
||||
|
@ -88,30 +89,20 @@ var MeshCamera = new Class({
|
|||
// To have different modes of movements, this function handles the view matrix update for the transform object.
|
||||
updateViewMatrix: function ()
|
||||
{
|
||||
var d = Math.PI / 180;
|
||||
var matView = this.matView;
|
||||
var rotation = this.rotation;
|
||||
var matView = this.matrix;
|
||||
|
||||
matView.identity();
|
||||
|
||||
// Optimize camera transform update, no need for scale nor rotateZ
|
||||
if (this.mode === MeshCamera.MODE_FREE)
|
||||
{
|
||||
matView.translate(this.position);
|
||||
matView.rotateX(rotation.x * d);
|
||||
matView.rotateY(rotation.y * d);
|
||||
matView.fromRotationXYTranslation(this.rotation, this.position, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
matView.rotateX(rotation.x * d);
|
||||
matView.rotateY(rotation.y * d);
|
||||
matView.translate(this.position);
|
||||
matView.fromRotationXYTranslation(this.rotation, this.position, false);
|
||||
}
|
||||
|
||||
this.updateDirection();
|
||||
|
||||
this.viewMatrix.copy(matView);
|
||||
this.viewMatrix.invert();
|
||||
this.viewMatrix.copy(matView).invert();
|
||||
|
||||
this.dirty = true;
|
||||
},
|
||||
|
@ -120,28 +111,21 @@ var MeshCamera = new Class({
|
|||
{
|
||||
this.aspectRatio = width / height;
|
||||
|
||||
this.updateViewMatrix();
|
||||
|
||||
// TODO - Only needs changing when the fov/etc does
|
||||
this.projectionMatrix.perspective(DegToRad(this._fov), this.aspectRatio, this._near, this._far);
|
||||
|
||||
// TODO - Only needs calculating when this camera is dirty
|
||||
this.projectionMatrix.multiplyToMat4(this.viewMatrix, this.viewProjectionMatrix);
|
||||
},
|
||||
|
||||
updateDirection: function ()
|
||||
{
|
||||
var matView = this.matView;
|
||||
var matView = this.matrix;
|
||||
|
||||
this.forward.set(0, 0, 1, 0).transformMat4(matView);
|
||||
this.up.set(0, 1, 0, 0).transformMat4(matView);
|
||||
this.right.set(1, 0, 0, 0).transformMat4(matView);
|
||||
},
|
||||
|
||||
reset: function ()
|
||||
{
|
||||
this.position.set();
|
||||
this.rotation.set();
|
||||
|
||||
this.updateViewMatrix();
|
||||
},
|
||||
|
||||
fov: {
|
||||
|
||||
get: function ()
|
||||
|
|
103
src/gameobjects/mesh/MeshLight.js
Normal file
103
src/gameobjects/mesh/MeshLight.js
Normal file
|
@ -0,0 +1,103 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2020 Photon Storm Ltd.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
var Class = require('../../utils/Class');
|
||||
var Vector3 = require('../../math/Vector3');
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* The Mesh Light.
|
||||
*
|
||||
* @class MeshLight
|
||||
* @memberof Phaser.GameObjects
|
||||
* @constructor
|
||||
* @since 3.50.0
|
||||
*/
|
||||
var MeshLight = new Class({
|
||||
|
||||
initialize:
|
||||
|
||||
function MeshLight (x, y, z)
|
||||
{
|
||||
this.position = new Vector3(x, y, z);
|
||||
this.ambient = new Vector3(1, 1, 1);
|
||||
this.diffuse = new Vector3(1, 1, 1);
|
||||
this.specular = new Vector3(1, 1, 1);
|
||||
},
|
||||
|
||||
setPosition: function (x, y, z)
|
||||
{
|
||||
this.position.set(x, y, z);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
setAmbient: function (r, g, b)
|
||||
{
|
||||
this.ambient.set(r, g, b);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
setDiffuse: function (r, g, b)
|
||||
{
|
||||
this.diffuse.set(r, g, b);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
setSpecular: function (r, g, b)
|
||||
{
|
||||
this.specular.set(r, g, b);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
x: {
|
||||
|
||||
get: function ()
|
||||
{
|
||||
return this.position.x;
|
||||
},
|
||||
|
||||
set: function (value)
|
||||
{
|
||||
this.position.x = value;
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
y: {
|
||||
|
||||
get: function ()
|
||||
{
|
||||
return this.position.y;
|
||||
},
|
||||
|
||||
set: function (value)
|
||||
{
|
||||
this.position.y = value;
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
z: {
|
||||
|
||||
get: function ()
|
||||
{
|
||||
return this.position.z;
|
||||
},
|
||||
|
||||
set: function (value)
|
||||
{
|
||||
this.position.z = value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
module.exports = MeshLight;
|
|
@ -4,8 +4,6 @@
|
|||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
var GetCalcMatrix = require('../GetCalcMatrix');
|
||||
|
||||
/**
|
||||
* Renders this Game Object with the WebGL Renderer to the given Camera.
|
||||
* The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera.
|
||||
|
@ -20,7 +18,7 @@ var GetCalcMatrix = require('../GetCalcMatrix');
|
|||
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object.
|
||||
* @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - This transform matrix is defined if the game object is nested
|
||||
*/
|
||||
var MeshWebGLRenderer = function (renderer, src, camera, parentMatrix)
|
||||
var MeshWebGLRenderer = function (renderer, src)
|
||||
{
|
||||
var models = src.models;
|
||||
var totalModels = models.length;
|
||||
|
@ -30,88 +28,18 @@ var MeshWebGLRenderer = function (renderer, src, camera, parentMatrix)
|
|||
return;
|
||||
}
|
||||
|
||||
renderer.pipelines.clear();
|
||||
|
||||
var pipeline = renderer.pipelines.set(src.pipeline, src);
|
||||
|
||||
var calcMatrix = GetCalcMatrix(src, camera, parentMatrix).calc;
|
||||
|
||||
var vertexOffset = (pipeline.vertexCount * pipeline.vertexComponentCount) - 1;
|
||||
|
||||
var debugVerts;
|
||||
var debugCallback = src.debugCallback;
|
||||
|
||||
var a = calcMatrix.a;
|
||||
var b = calcMatrix.b;
|
||||
var c = calcMatrix.c;
|
||||
var d = calcMatrix.d;
|
||||
var e = calcMatrix.e;
|
||||
var f = calcMatrix.f;
|
||||
|
||||
var F32 = pipeline.vertexViewF32;
|
||||
var U32 = pipeline.vertexViewU32;
|
||||
|
||||
var globalAlpha = camera.alpha * src.alpha;
|
||||
|
||||
for (var m = 0; m < totalModels; m++)
|
||||
{
|
||||
var model = models[m];
|
||||
|
||||
var faces = model.faces;
|
||||
var totalFaces = faces.length;
|
||||
var alpha = globalAlpha * model.alpha;
|
||||
|
||||
if (totalFaces === 0 || !model.visible || alpha <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (debugCallback)
|
||||
{
|
||||
debugVerts = [];
|
||||
}
|
||||
|
||||
var tintEffect = model.tintFill;
|
||||
var textureUnit = pipeline.setGameObject(model);
|
||||
|
||||
for (var i = 0; i < totalFaces; i++)
|
||||
{
|
||||
var face = faces[i];
|
||||
|
||||
if (model.hideCCW && !face.isCounterClockwise())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pipeline.shouldFlush(3))
|
||||
{
|
||||
pipeline.flush();
|
||||
|
||||
vertexOffset = 0;
|
||||
}
|
||||
|
||||
vertexOffset = face.vertex1.load(F32, U32, vertexOffset, textureUnit, tintEffect, alpha, a, b, c, d, e, f);
|
||||
vertexOffset = face.vertex2.load(F32, U32, vertexOffset, textureUnit, tintEffect, alpha, a, b, c, d, e, f);
|
||||
vertexOffset = face.vertex3.load(F32, U32, vertexOffset, textureUnit, tintEffect, alpha, a, b, c, d, e, f);
|
||||
|
||||
pipeline.vertexCount += 3;
|
||||
|
||||
if (debugCallback && model.drawDebug)
|
||||
{
|
||||
debugVerts.push(
|
||||
F32[vertexOffset - 20],
|
||||
F32[vertexOffset - 19],
|
||||
F32[vertexOffset - 13],
|
||||
F32[vertexOffset - 12],
|
||||
F32[vertexOffset - 6],
|
||||
F32[vertexOffset - 5]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (debugCallback && model.drawDebug)
|
||||
{
|
||||
debugCallback.call(src, src, debugVerts);
|
||||
}
|
||||
pipeline.drawModel(src, model);
|
||||
}
|
||||
|
||||
renderer.pipelines.rebind();
|
||||
};
|
||||
|
||||
module.exports = MeshWebGLRenderer;
|
||||
|
|
|
@ -8,9 +8,8 @@ var AnimationState = require('../../animations/AnimationState');
|
|||
var Class = require('../../utils/Class');
|
||||
var Components = require('../../gameobjects/components');
|
||||
var Face = require('./Face');
|
||||
var GetCalcMatrix = require('../../gameobjects/GetCalcMatrix');
|
||||
var Matrix4 = require('../../math/Matrix4');
|
||||
var StableSort = require('../../utils/array/StableSort');
|
||||
var Quaternion = require('../../math/Quaternion');
|
||||
var Vector3 = require('../../math/Vector3');
|
||||
var Vertex = require('./Vertex');
|
||||
var WrapAngle = require('../../math/angle/Wrap');
|
||||
|
@ -59,7 +58,7 @@ var Model = new Class({
|
|||
*
|
||||
* A Face consists of 3 Vertex objects.
|
||||
*
|
||||
* This array is populated during the `setVertices` method.
|
||||
* This array is populated during the `addVertices` method.
|
||||
*
|
||||
* @name Phaser.Geom.Mesh.Model#faces
|
||||
* @type {Phaser.Geom.Mesh.Face[]}
|
||||
|
@ -78,39 +77,18 @@ var Model = new Class({
|
|||
*/
|
||||
this.vertices = [];
|
||||
|
||||
/**
|
||||
* The tint fill mode.
|
||||
*
|
||||
* `false` = An additive tint (the default), where vertices colors are blended with the texture.
|
||||
* `true` = A fill tint, where the vertices colors replace the texture, but respects texture alpha.
|
||||
*
|
||||
* @name Phaser.Geom.Mesh.Model#tintFill
|
||||
* @type {boolean}
|
||||
* @default false
|
||||
* @since 3.50.0
|
||||
*/
|
||||
this.tintFill = false;
|
||||
|
||||
/**
|
||||
* When rendering, skip any Face that isn't counter clockwise?
|
||||
*
|
||||
* Enable this to hide backward-facing Faces during rendering.
|
||||
* Disable it to render all Faces.
|
||||
*
|
||||
* @name Phaser.Geom.Mesh.Model#hideCCW
|
||||
* @type {boolean}
|
||||
* @since 3.50.0
|
||||
*/
|
||||
this.hideCCW = true;
|
||||
|
||||
this.drawDebug = true;
|
||||
|
||||
this.position = new Vector3(x, y, z);
|
||||
this.rotation = new Vector3();
|
||||
this.scale = new Vector3(1, 1, 1);
|
||||
this.rotation = new Quaternion();
|
||||
|
||||
this.dirtyCache = [ x, y, z, 0, 0, 0, 1, 1, 1, 0 ];
|
||||
this.dirtyCache = [ x, y, z, 0, 0, 0, 0, 1, 1, 1, 0 ];
|
||||
|
||||
this.ambient = new Vector3(1, 1, 1);
|
||||
this.diffuse = new Vector3(1, 1, 1);
|
||||
this.specular = new Vector3(1, 1, 1);
|
||||
this.shine = 0.25;
|
||||
|
||||
this.normalMatrix = new Matrix4();
|
||||
this.transformMatrix = new Matrix4();
|
||||
|
||||
if (!texture)
|
||||
|
@ -165,6 +143,7 @@ var Model = new Class({
|
|||
var rx = rotation.x;
|
||||
var ry = rotation.y;
|
||||
var rz = rotation.z;
|
||||
var rw = rotation.w;
|
||||
|
||||
var sx = scale.x;
|
||||
var sy = scale.y;
|
||||
|
@ -179,12 +158,13 @@ var Model = new Class({
|
|||
var rxCached = dirtyCache[3];
|
||||
var ryCached = dirtyCache[4];
|
||||
var rzCached = dirtyCache[5];
|
||||
var rwCached = dirtyCache[6];
|
||||
|
||||
var sxCached = dirtyCache[6];
|
||||
var syCached = dirtyCache[7];
|
||||
var szCached = dirtyCache[8];
|
||||
var sxCached = dirtyCache[7];
|
||||
var syCached = dirtyCache[8];
|
||||
var szCached = dirtyCache[9];
|
||||
|
||||
var fCached = dirtyCache[9];
|
||||
var fCached = dirtyCache[10];
|
||||
|
||||
dirtyCache[0] = px;
|
||||
dirtyCache[1] = py;
|
||||
|
@ -193,43 +173,40 @@ var Model = new Class({
|
|||
dirtyCache[3] = rx;
|
||||
dirtyCache[4] = ry;
|
||||
dirtyCache[5] = rz;
|
||||
dirtyCache[6] = rw;
|
||||
|
||||
dirtyCache[6] = sx;
|
||||
dirtyCache[7] = sy;
|
||||
dirtyCache[8] = sz;
|
||||
dirtyCache[7] = sx;
|
||||
dirtyCache[8] = sy;
|
||||
dirtyCache[9] = sz;
|
||||
|
||||
dirtyCache[9] = faces;
|
||||
dirtyCache[10] = faces;
|
||||
|
||||
return (
|
||||
pxCached !== px || pyCached !== py || pzCached !== pz ||
|
||||
rxCached !== rx || ryCached !== ry || rzCached !== rz ||
|
||||
rxCached !== rx || ryCached !== ry || rzCached !== rz || rwCached !== rw ||
|
||||
sxCached !== sx || syCached !== sy || szCached !== sz ||
|
||||
fCached !== faces
|
||||
);
|
||||
},
|
||||
|
||||
preUpdate: function (time, delta, camera, width, height)
|
||||
preUpdate: function (time, delta)
|
||||
{
|
||||
this.anims.update(time, delta);
|
||||
|
||||
if (!camera.dirty && !this.isDirty())
|
||||
// If the model isn't dirty we can bail out and save lots of math
|
||||
if (this.isDirty())
|
||||
{
|
||||
// If neither the camera or the model is dirty, we can bail out and save lots of math
|
||||
return;
|
||||
var normalMatrix = this.normalMatrix;
|
||||
var transformMatrix = this.transformMatrix;
|
||||
|
||||
// TODO - No scale
|
||||
transformMatrix.fromRotationTranslation(this.rotation, this.position);
|
||||
transformMatrix.scale(this.scale);
|
||||
|
||||
normalMatrix.copy(transformMatrix);
|
||||
normalMatrix.invert();
|
||||
normalMatrix.transpose();
|
||||
}
|
||||
|
||||
var transformMatrix = this.transformMatrix;
|
||||
|
||||
transformMatrix.setWorldMatrix(this.rotation, this.position, this.scale, camera.viewMatrix, camera.projectionMatrix);
|
||||
|
||||
var vertices = this.vertices;
|
||||
|
||||
for (var i = 0; i < vertices.length; i++)
|
||||
{
|
||||
vertices[i].transformCoordinatesLocal(transformMatrix, width, height);
|
||||
}
|
||||
|
||||
this.depthSort();
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -273,79 +250,6 @@ var Model = new Class({
|
|||
return this.faces[index];
|
||||
},
|
||||
|
||||
/**
|
||||
* Return an array of Face objects from this Mesh that intersect with the given coordinates.
|
||||
*
|
||||
* The given position is translated through the matrix of this Mesh and the given Camera,
|
||||
* before being compared against the vertices.
|
||||
*
|
||||
* If more than one Face intersects, they will all be returned in the array, but the array will
|
||||
* be depth sorted first, so the first element will always be that closest to the camera.
|
||||
*
|
||||
* @method Phaser.Geom.Mesh.Model#getFaceAt
|
||||
* @since 3.50.0
|
||||
*
|
||||
* @param {number} x - The x position to check against.
|
||||
* @param {number} y - The y position to check against.
|
||||
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The camera to pass the coordinates through. If not given, the default Scene Camera is used.
|
||||
*
|
||||
* @return {Phaser.Geom.Mesh.Face[]} An array of Face objects that intersect with the given point, ordered by depth.
|
||||
*/
|
||||
getFaceAt: function (x, y, camera, calcMatrix)
|
||||
{
|
||||
if (camera === undefined) { camera = this.scene.sys.cameras.main; }
|
||||
if (calcMatrix === undefined) { calcMatrix = GetCalcMatrix(this.mesh, camera).calc; }
|
||||
|
||||
var faces = this.faces;
|
||||
var results = [];
|
||||
|
||||
for (var i = 0; i < faces.length; i++)
|
||||
{
|
||||
var face = faces[i];
|
||||
|
||||
if (face.contains(x, y, calcMatrix))
|
||||
{
|
||||
results.push(face);
|
||||
}
|
||||
}
|
||||
|
||||
return StableSort(results, this.sortByDepth);
|
||||
},
|
||||
|
||||
/**
|
||||
* Runs a depth sort across all Faces in this Mesh, comparing their averaged depth.
|
||||
*
|
||||
* This is called automatically if you use any of the `rotate` methods, but you can
|
||||
* also invoke it to sort the Faces should you manually position them.
|
||||
*
|
||||
* @method Phaser.Geom.Mesh.Model#depthSort
|
||||
* @since 3.50.0
|
||||
*
|
||||
* @return {this} This Mesh Game Object.
|
||||
*/
|
||||
depthSort: function ()
|
||||
{
|
||||
StableSort(this.faces, this.sortByDepth);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Compare the depth of two Faces.
|
||||
*
|
||||
* @method Phaser.Geom.Mesh.Model#sortByDepth
|
||||
* @since 3.50.0
|
||||
*
|
||||
* @param {Phaser.Geom.Mesh.Face} faceA - The first Face.
|
||||
* @param {Phaser.Geom.Mesh.Face} faceB - The second Face.
|
||||
*
|
||||
* @return {integer} The difference between the depths of each Face.
|
||||
*/
|
||||
sortByDepth: function (faceA, faceB)
|
||||
{
|
||||
return faceA.depth - faceB.depth;
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a new Vertex into the vertices array of this Mesh.
|
||||
*
|
||||
|
@ -513,102 +417,6 @@ var Model = new Class({
|
|||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Rotates all vertices of this Mesh around the X axis by the amount given.
|
||||
*
|
||||
* It then runs a depth sort on the faces before returning.
|
||||
*
|
||||
* @method Phaser.Geom.Mesh.Model#rotateVerticesX
|
||||
* @since 3.50.0
|
||||
*
|
||||
* @param {number} theta - The amount to rotate by in radians.
|
||||
*
|
||||
* @return {this} This Mesh Game Object.
|
||||
*/
|
||||
rotateVerticesX: function (theta)
|
||||
{
|
||||
var ts = Math.sin(theta);
|
||||
var tc = Math.cos(theta);
|
||||
|
||||
var verts = this.vertices;
|
||||
|
||||
for (var n = 0; n < verts.length; n++)
|
||||
{
|
||||
var vert = verts[n];
|
||||
var y = vert.y;
|
||||
var z = vert.z;
|
||||
|
||||
vert.y = y * tc - z * ts;
|
||||
vert.z = z * tc + y * ts;
|
||||
}
|
||||
|
||||
return this.depthSort();
|
||||
},
|
||||
|
||||
/**
|
||||
* Rotates all vertices of this Mesh around the Y axis by the amount given.
|
||||
*
|
||||
* It then runs a depth sort on the faces before returning.
|
||||
*
|
||||
* @method Phaser.Geom.Mesh.Model#rotateVerticesY
|
||||
* @since 3.50.0
|
||||
*
|
||||
* @param {number} theta - The amount to rotate by in radians.
|
||||
*
|
||||
* @return {this} This Mesh Game Object.
|
||||
*/
|
||||
rotateVerticesY: function (theta)
|
||||
{
|
||||
var ts = Math.sin(theta);
|
||||
var tc = Math.cos(theta);
|
||||
|
||||
var verts = this.vertices;
|
||||
|
||||
for (var n = 0; n < verts.length; n++)
|
||||
{
|
||||
var vert = verts[n];
|
||||
var x = vert.x;
|
||||
var z = vert.z;
|
||||
|
||||
vert.x = x * tc - z * ts;
|
||||
vert.z = z * tc + x * ts;
|
||||
}
|
||||
|
||||
return this.depthSort();
|
||||
},
|
||||
|
||||
/**
|
||||
* Rotates all vertices of this Mesh around the Z axis by the amount given.
|
||||
*
|
||||
* It then runs a depth sort on the faces before returning.
|
||||
*
|
||||
* @method Phaser.Geom.Mesh.Model#rotateVerticesZ
|
||||
* @since 3.50.0
|
||||
*
|
||||
* @param {number} theta - The amount to rotate by in radians.
|
||||
*
|
||||
* @return {this} This Mesh Game Object.
|
||||
*/
|
||||
rotateVerticesZ: function (theta)
|
||||
{
|
||||
var ts = Math.sin(theta);
|
||||
var tc = Math.cos(theta);
|
||||
|
||||
var verts = this.vertices;
|
||||
|
||||
for (var n = 0; n < verts.length; n++)
|
||||
{
|
||||
var vert = verts[n];
|
||||
var x = vert.x;
|
||||
var y = vert.y;
|
||||
|
||||
vert.x = x * tc - y * ts;
|
||||
vert.y = y * tc + x * ts;
|
||||
}
|
||||
|
||||
return this.depthSort();
|
||||
},
|
||||
|
||||
x: {
|
||||
|
||||
get: function ()
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
*/
|
||||
|
||||
var Class = require('../../utils/Class');
|
||||
var Vector3 = require('../../math/Vector3');
|
||||
var Utils = require('../../renderer/webgl/Utils');
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
|
@ -17,7 +15,6 @@ var Utils = require('../../renderer/webgl/Utils');
|
|||
*
|
||||
* @class Vertex
|
||||
* @memberof Phaser.Geom.Mesh
|
||||
* @extends Phaser.Math.Vector3
|
||||
* @constructor
|
||||
* @since 3.50.0
|
||||
*
|
||||
|
@ -31,43 +28,69 @@ var Utils = require('../../renderer/webgl/Utils');
|
|||
*/
|
||||
var Vertex = new Class({
|
||||
|
||||
Extends: Vector3,
|
||||
|
||||
initialize:
|
||||
|
||||
function Vertex (x, y, z, u, v, color, alpha)
|
||||
function Vertex (x, y, z, u, v, normalX, normalY, normalZ, color, alpha)
|
||||
{
|
||||
if (normalX === undefined) { normalX = 0; }
|
||||
if (normalY === undefined) { normalY = 0; }
|
||||
if (normalZ === undefined) { normalZ = 0; }
|
||||
if (color === undefined) { color = 0xffffff; }
|
||||
if (alpha === undefined) { alpha = 1; }
|
||||
|
||||
Vector3.call(this, x, y, z);
|
||||
|
||||
/**
|
||||
* The projected x coordinate of this vertex.
|
||||
* The x coordinate of this vertex.
|
||||
*
|
||||
* @name Phaser.Geom.Mesh.Vertex#vx
|
||||
* @type {number}
|
||||
* @since 3.50.0
|
||||
*/
|
||||
this.vx = 0;
|
||||
this.x = x;
|
||||
|
||||
/**
|
||||
* The projected y coordinate of this vertex.
|
||||
* The y coordinate of this vertex.
|
||||
*
|
||||
* @name Phaser.Geom.Mesh.Vertex#vy
|
||||
* @type {number}
|
||||
* @since 3.50.0
|
||||
*/
|
||||
this.vy = 0;
|
||||
this.y = y;
|
||||
|
||||
/**
|
||||
* The projected z coordinate of this vertex.
|
||||
* The z coordinate of this vertex.
|
||||
*
|
||||
* @name Phaser.Geom.Mesh.Vertex#vz
|
||||
* @type {number}
|
||||
* @since 3.50.0
|
||||
*/
|
||||
this.vz = 0;
|
||||
this.z = z;
|
||||
|
||||
/**
|
||||
* The x normal of this vertex.
|
||||
*
|
||||
* @name Phaser.Geom.Mesh.Vertex#nx
|
||||
* @type {number}
|
||||
* @since 3.50.0
|
||||
*/
|
||||
this.nx = normalX;
|
||||
|
||||
/**
|
||||
* The y normal of this vertex.
|
||||
*
|
||||
* @name Phaser.Geom.Mesh.Vertex#ny
|
||||
* @type {number}
|
||||
* @since 3.50.0
|
||||
*/
|
||||
this.ny = normalY;
|
||||
|
||||
/**
|
||||
* The z normal of this vertex.
|
||||
*
|
||||
* @name Phaser.Geom.Mesh.Vertex#nz
|
||||
* @type {number}
|
||||
* @since 3.50.0
|
||||
*/
|
||||
this.nz = normalZ;
|
||||
|
||||
/**
|
||||
* UV u coordinate of this vertex.
|
||||
|
@ -115,7 +138,6 @@ var Vertex = new Class({
|
|||
* @param {Phaser.Math.Matrix4} transformMatrix - The transform matrix to apply to this vertex.
|
||||
* @param {number} width - The width of the parent Mesh.
|
||||
* @param {number} height - The height of the parent Mesh.
|
||||
*/
|
||||
transformCoordinatesLocal: function (transformMatrix, width, height)
|
||||
{
|
||||
var x = this.x;
|
||||
|
@ -133,39 +155,7 @@ var Vertex = new Class({
|
|||
this.vy = -(ty / tw) * height;
|
||||
this.vz = (tz / tw);
|
||||
},
|
||||
|
||||
/**
|
||||
* Loads this vertex into the given Typed Arrays.
|
||||
*
|
||||
* @method Phaser.Geom.Mesh.Model#load
|
||||
* @since 3.50.0
|
||||
*
|
||||
* @param {Float32Array} F32 - The Float32 Array to put the position data in.
|
||||
* @param {Uint32Array} U32 - The Uint32 Array to put the color data in.
|
||||
* @param {number} offset - The vertex offset to place the data at.
|
||||
* @param {number} textureUnit - The currently bound texture unit.
|
||||
* @param {number} alpha - The alpha value.
|
||||
* @param {number} a - The transform matrix a value.
|
||||
* @param {number} b - The transform matrix b value.
|
||||
* @param {number} c - The transform matrix c value.
|
||||
* @param {number} d - The transform matrix d value.
|
||||
* @param {number} e - The transform matrix e value.
|
||||
* @param {number} f - The transform matrix f value.
|
||||
*
|
||||
* @return {number} The new vertex offset.
|
||||
*/
|
||||
load: function (F32, U32, offset, textureUnit, tintEffect, alpha, a, b, c, d, e, f)
|
||||
{
|
||||
F32[++offset] = this.vx * a + this.vy * c + e;
|
||||
F32[++offset] = this.vx * b + this.vy * d + f;
|
||||
F32[++offset] = this.u;
|
||||
F32[++offset] = this.v;
|
||||
F32[++offset] = textureUnit;
|
||||
F32[++offset] = tintEffect;
|
||||
U32[++offset] = Utils.getTintAppendFloatAlpha(this.color, alpha * this.alpha);
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
|
|
@ -79,6 +79,90 @@ var Matrix4 = new Class({
|
|||
return this.copy(src);
|
||||
},
|
||||
|
||||
// TODO - Docs
|
||||
fromRotationXYTranslation: function (rotation, position, translateFirst)
|
||||
{
|
||||
var x = position.x;
|
||||
var y = position.y;
|
||||
var z = position.z;
|
||||
|
||||
var sx = Math.sin(rotation.x);
|
||||
var cx = Math.cos(rotation.x);
|
||||
|
||||
var sy = Math.sin(rotation.y);
|
||||
var cy = Math.cos(rotation.y);
|
||||
|
||||
var a30 = x;
|
||||
var a31 = y;
|
||||
var a32 = z;
|
||||
|
||||
// Rotate X
|
||||
|
||||
var b21 = -sx;
|
||||
|
||||
// Rotate Y
|
||||
|
||||
var c01 = 0 - b21 * sy;
|
||||
|
||||
var c02 = 0 - cx * sy;
|
||||
|
||||
var c21 = b21 * cy;
|
||||
|
||||
var c22 = cx * cy;
|
||||
|
||||
// Translate
|
||||
if (!translateFirst)
|
||||
{
|
||||
// a30 = cy * x + 0 * y + sy * z;
|
||||
a30 = cy * x + sy * z;
|
||||
a31 = c01 * x + cx * y + c21 * z;
|
||||
a32 = c02 * x + sx * y + c22 * z;
|
||||
}
|
||||
|
||||
return this.setValues(
|
||||
cy,
|
||||
c01,
|
||||
c02,
|
||||
0,
|
||||
0,
|
||||
cx,
|
||||
sx,
|
||||
0,
|
||||
sy,
|
||||
c21,
|
||||
c22,
|
||||
0,
|
||||
a30,
|
||||
a31,
|
||||
a32,
|
||||
1
|
||||
);
|
||||
},
|
||||
|
||||
setValues: function (m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33)
|
||||
{
|
||||
var out = this.val;
|
||||
|
||||
out[0] = m00;
|
||||
out[1] = m01;
|
||||
out[2] = m02;
|
||||
out[3] = m03;
|
||||
out[4] = m10;
|
||||
out[5] = m11;
|
||||
out[6] = m12;
|
||||
out[7] = m13;
|
||||
out[8] = m20;
|
||||
out[9] = m21;
|
||||
out[10] = m22;
|
||||
out[11] = m23;
|
||||
out[12] = m30;
|
||||
out[13] = m31;
|
||||
out[14] = m32;
|
||||
out[15] = m33;
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Copy the values of a given Matrix into this Matrix.
|
||||
*
|
||||
|
@ -478,6 +562,69 @@ var Matrix4 = new Class({
|
|||
return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
|
||||
},
|
||||
|
||||
// TODO - Docs
|
||||
multiplyToMat4: function (src, out)
|
||||
{
|
||||
var a = this.val;
|
||||
var b = src.val;
|
||||
|
||||
var a00 = a[0];
|
||||
var a01 = a[1];
|
||||
var a02 = a[2];
|
||||
var a03 = a[3];
|
||||
var a10 = a[4];
|
||||
var a11 = a[5];
|
||||
var a12 = a[6];
|
||||
var a13 = a[7];
|
||||
var a20 = a[8];
|
||||
var a21 = a[9];
|
||||
var a22 = a[10];
|
||||
var a23 = a[11];
|
||||
var a30 = a[12];
|
||||
var a31 = a[13];
|
||||
var a32 = a[14];
|
||||
var a33 = a[15];
|
||||
|
||||
var b00 = b[0];
|
||||
var b01 = b[1];
|
||||
var b02 = b[2];
|
||||
var b03 = b[3];
|
||||
var b10 = b[4];
|
||||
var b11 = b[5];
|
||||
var b12 = b[6];
|
||||
var b13 = b[7];
|
||||
var b20 = b[8];
|
||||
var b21 = b[9];
|
||||
var b22 = b[10];
|
||||
var b23 = b[11];
|
||||
var b30 = b[12];
|
||||
var b31 = b[13];
|
||||
var b32 = b[14];
|
||||
var b33 = b[15];
|
||||
|
||||
return out.setValues(
|
||||
b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30,
|
||||
b01 * a01 + b01 * a11 + b02 * a21 + b03 * a31,
|
||||
b02 * a02 + b01 * a12 + b02 * a22 + b03 * a32,
|
||||
b03 * a03 + b01 * a13 + b02 * a23 + b03 * a33,
|
||||
|
||||
b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30,
|
||||
b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31,
|
||||
b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32,
|
||||
b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33,
|
||||
|
||||
b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30,
|
||||
b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31,
|
||||
b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32,
|
||||
b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33,
|
||||
|
||||
b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30,
|
||||
b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31,
|
||||
b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32,
|
||||
b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Multiply this Matrix by the given Matrix.
|
||||
*
|
||||
|
|
|
@ -11,6 +11,7 @@ var CONST = require('./pipelines/const');
|
|||
// Default Phaser 3 Pipelines
|
||||
var BitmapMaskPipeline = require('./pipelines/BitmapMaskPipeline');
|
||||
var LightPipeline = require('./pipelines/LightPipeline');
|
||||
var MeshPipeline = require('./pipelines/MeshPipeline');
|
||||
var MultiPipeline = require('./pipelines/MultiPipeline');
|
||||
var RopePipeline = require('./pipelines/RopePipeline');
|
||||
var SinglePipeline = require('./pipelines/SinglePipeline');
|
||||
|
@ -131,6 +132,7 @@ var PipelineManager = new Class({
|
|||
this.add(CONST.SINGLE_PIPELINE, new SinglePipeline({ game: game }));
|
||||
this.add(CONST.ROPE_PIPELINE, new RopePipeline({ game: game }));
|
||||
this.add(CONST.LIGHT_PIPELINE, new LightPipeline({ game: game }));
|
||||
this.add(CONST.MESH_PIPELINE, new MeshPipeline({ game: game }));
|
||||
|
||||
this.set(this.MULTI_PIPELINE);
|
||||
},
|
||||
|
|
|
@ -126,13 +126,19 @@ var WebGLPipeline = new Class({
|
|||
this.vertexCapacity = GetFastValue(config, 'vertexCapacity', renderer.config.batchSize * 6);
|
||||
|
||||
/**
|
||||
* The size in bytes of a vertex.
|
||||
* The size, in bytes, of a single vertex.
|
||||
*
|
||||
* Derived by adding together all of the vertex attributes.
|
||||
* This is derived by adding together all of the vertex attributes.
|
||||
*
|
||||
* For example, the Texture Tint Pipeline has 2 + 2 + 1 + 1 + 4 for the attributes
|
||||
* `inPosition` (size 2), `inTexCoord` (size 2), `inTexId` (size 1), `inTintEffect` (size 1)
|
||||
* and `inTint` (size 4), for a total of 28, which is the default for this property.
|
||||
* For example, the Multi Pipeline has the following attributes:
|
||||
*
|
||||
* inPosition - (size 2 x gl.FLOAT) = 8
|
||||
* inTexCoord - (size 2 x gl.FLOAT) = 8
|
||||
* inTexId - (size 1 x gl.FLOAT) = 4
|
||||
* inTintEffect - (size 1 x gl.FLOAT) = 4
|
||||
* inTint - (size 4 x gl.UNSIGNED_BYTE) = 4
|
||||
*
|
||||
* The total is 8 + 8 + 4 + 4 + 4 = 28, which is the default for this property.
|
||||
*
|
||||
* @name Phaser.Renderer.WebGL.WebGLPipeline#vertexSize
|
||||
* @type {integer}
|
||||
|
@ -459,13 +465,16 @@ var WebGLPipeline = new Class({
|
|||
},
|
||||
|
||||
/**
|
||||
* Set whenever this WebGL Pipeline is bound to a WebGL Renderer.
|
||||
* This method is called every time a Game Object asks the Pipeline Manager to use this pipeline.
|
||||
*
|
||||
* This method is called every time the WebGL Pipeline is attempted to be bound, even if it already is the current pipeline.
|
||||
* Unlike the `bind` method, which is only called once per frame, this is called for every object
|
||||
* that requests it, allowing you to perform per-object GL set-up.
|
||||
*
|
||||
* @method Phaser.Renderer.WebGL.WebGLPipeline#onBind
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @param {Phaser.GameObjects.GameObject} [gameObject] - The Game Object that invoked this pipeline, if any.
|
||||
*
|
||||
* @return {this} This WebGLPipeline instance.
|
||||
*/
|
||||
onBind: function ()
|
||||
|
|
190
src/renderer/webgl/pipelines/MeshPipeline.js
Normal file
190
src/renderer/webgl/pipelines/MeshPipeline.js
Normal file
|
@ -0,0 +1,190 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2020 Photon Storm Ltd.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
var Class = require('../../../utils/Class');
|
||||
var GetFastValue = require('../../../utils/object/GetFastValue');
|
||||
var ShaderSourceFS = require('../shaders/Mesh-frag.js');
|
||||
var ShaderSourceVS = require('../shaders/Mesh-vert.js');
|
||||
var WebGLPipeline = require('../WebGLPipeline');
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* TODO
|
||||
*
|
||||
* @class MeshPipeline
|
||||
* @extends Phaser.Renderer.WebGL.WebGLPipeline
|
||||
* @memberof Phaser.Renderer.WebGL.Pipelines
|
||||
* @constructor
|
||||
* @since 3.50.0
|
||||
*
|
||||
* @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration options for this pipeline.
|
||||
*/
|
||||
var MeshPipeline = new Class({
|
||||
|
||||
Extends: WebGLPipeline,
|
||||
|
||||
initialize:
|
||||
|
||||
function MeshPipeline (config)
|
||||
{
|
||||
var gl = config.game.renderer.gl;
|
||||
|
||||
config.fragShader = GetFastValue(config, 'fragShader', ShaderSourceFS),
|
||||
config.vertShader = GetFastValue(config, 'vertShader', ShaderSourceVS),
|
||||
config.vertexCapacity = GetFastValue(config, 'vertexCapacity', 2048 * 8),
|
||||
config.vertexSize = GetFastValue(config, 'vertexSize', 32),
|
||||
config.attributes = GetFastValue(config, 'attributes', [
|
||||
{
|
||||
name: 'aVertexPosition',
|
||||
size: 3,
|
||||
type: gl.FLOAT,
|
||||
normalized: false,
|
||||
offset: 0,
|
||||
enabled: false,
|
||||
location: -1
|
||||
},
|
||||
{
|
||||
name: 'aVertexNormal',
|
||||
size: 3,
|
||||
type: gl.FLOAT,
|
||||
normalized: false,
|
||||
offset: 12,
|
||||
enabled: false,
|
||||
location: -1
|
||||
},
|
||||
{
|
||||
name: 'aTextureCoord',
|
||||
size: 2,
|
||||
type: gl.FLOAT,
|
||||
normalized: false,
|
||||
offset: 24,
|
||||
enabled: false,
|
||||
location: -1
|
||||
}
|
||||
]);
|
||||
|
||||
WebGLPipeline.call(this, config);
|
||||
|
||||
/**
|
||||
* Float32 view of the array buffer containing the pipeline's vertices.
|
||||
*
|
||||
* @name Phaser.Renderer.WebGL.Pipelines.MeshPipeline#vertexViewF32
|
||||
* @type {Float32Array}
|
||||
* @since 3.0.0
|
||||
*/
|
||||
this.vertexViewF32 = new Float32Array(this.vertexData);
|
||||
|
||||
this.forceZero = true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Called every time the pipeline is bound by the renderer.
|
||||
* Sets the shader program, vertex buffer and other resources.
|
||||
* Should only be called when changing pipeline.
|
||||
*
|
||||
* @method Phaser.Renderer.WebGL.Pipelines.MeshPipeline#bind
|
||||
* @since 3.50.0
|
||||
*
|
||||
* @param {boolean} [reset=false] - Should the pipeline be fully re-bound after a renderer pipeline clear?
|
||||
*
|
||||
* @return {this} This WebGLPipeline instance.
|
||||
*/
|
||||
bind: function (reset)
|
||||
{
|
||||
if (reset === undefined) { reset = false; }
|
||||
|
||||
WebGLPipeline.prototype.bind.call(this, reset);
|
||||
|
||||
var gl = this.gl;
|
||||
|
||||
gl.enable(gl.DEPTH_TEST);
|
||||
gl.enable(gl.CULL_FACE);
|
||||
gl.cullFace(gl.BACK);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* This method is called every time a Game Object asks the Pipeline Manager to use this pipeline.
|
||||
*
|
||||
* Unlike the `bind` method, which is only called once per frame, this is called for every object
|
||||
* that requests it, allowing you to perform per-object GL set-up.
|
||||
*
|
||||
* @method Phaser.Renderer.WebGL.Pipelines.MeshPipeline#onBind
|
||||
* @since 3.50.0
|
||||
*
|
||||
* @param {Phaser.GameObjects.Mesh} mesh - The Mesh that requested this pipeline.
|
||||
*
|
||||
* @return {this} This WebGLPipeline instance.
|
||||
*/
|
||||
onBind: function (mesh)
|
||||
{
|
||||
var program = this.program;
|
||||
var renderer = this.renderer;
|
||||
|
||||
var camera = mesh.camera;
|
||||
var light = mesh.light;
|
||||
|
||||
renderer.setMatrix4(program, 'uViewProjectionMatrix', false, camera.viewProjectionMatrix.val);
|
||||
|
||||
renderer.setFloat3(program, 'uLightPosition', light.x, light.y, light.z);
|
||||
renderer.setFloat3(program, 'uLightAmbient', light.ambient.x, light.ambient.y, light.ambient.z);
|
||||
renderer.setFloat3(program, 'uLightDiffuse', light.diffuse.x, light.diffuse.y, light.diffuse.z);
|
||||
renderer.setFloat3(program, 'uLightSpecular', light.specular.x, light.specular.y, light.specular.z);
|
||||
renderer.setFloat3(program, 'uCameraPosition', camera.x, camera.y, camera.z);
|
||||
},
|
||||
|
||||
drawModel: function (mesh, model)
|
||||
{
|
||||
var program = this.program;
|
||||
var renderer = this.renderer;
|
||||
|
||||
renderer.setMatrix4(program, 'uModelMatrix', false, model.transformMatrix.val);
|
||||
renderer.setMatrix4(program, 'uNormalMatrix', false, model.normalMatrix.val);
|
||||
|
||||
renderer.setFloat3(program, 'uMaterialAmbient', model.ambient.x, model.ambient.y, model.ambient.z);
|
||||
renderer.setFloat3(program, 'uMaterialDiffuse', model.diffuse.x, model.diffuse.y, model.diffuse.z);
|
||||
renderer.setFloat3(program, 'uMaterialSpecular', model.specular.x, model.specular.y, model.specular.z);
|
||||
renderer.setFloat1(program, 'uMaterialShine', model.shine);
|
||||
|
||||
renderer.setTextureZero(model.frame.glTexture);
|
||||
renderer.setInt1(program, 'uTexture', 0);
|
||||
|
||||
// All the uniforms are finally bound, so now lets draw our faces!
|
||||
|
||||
var vertexViewF32 = this.vertexViewF32;
|
||||
|
||||
var vertices = model.vertices;
|
||||
|
||||
for (var i = 0; i < vertices.length; i++)
|
||||
{
|
||||
if (this.shouldFlush(1))
|
||||
{
|
||||
this.flush();
|
||||
}
|
||||
|
||||
var vertexOffset = (this.vertexCount * this.vertexComponentCount) - 1;
|
||||
|
||||
var vert = vertices[i];
|
||||
|
||||
vertexViewF32[++vertexOffset] = vert.x;
|
||||
vertexViewF32[++vertexOffset] = vert.y;
|
||||
vertexViewF32[++vertexOffset] = vert.z;
|
||||
vertexViewF32[++vertexOffset] = vert.nx;
|
||||
vertexViewF32[++vertexOffset] = vert.ny;
|
||||
vertexViewF32[++vertexOffset] = vert.nz;
|
||||
vertexViewF32[++vertexOffset] = vert.u;
|
||||
vertexViewF32[++vertexOffset] = vert.v;
|
||||
|
||||
this.vertexCount++;
|
||||
}
|
||||
|
||||
this.flush();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
module.exports = MeshPipeline;
|
|
@ -156,7 +156,7 @@ var SinglePipeline = new Class({
|
|||
|
||||
var hasFlushed = false;
|
||||
|
||||
if (this.vertexCount + 6 > this.vertexCapacity)
|
||||
if (this.shouldFlush(6))
|
||||
{
|
||||
this.flush();
|
||||
|
||||
|
@ -260,7 +260,7 @@ var SinglePipeline = new Class({
|
|||
|
||||
var hasFlushed = false;
|
||||
|
||||
if (this.vertexCount + 3 > this.vertexCapacity)
|
||||
if (this.shouldFlush(3))
|
||||
{
|
||||
this.flush();
|
||||
|
||||
|
|
|
@ -54,7 +54,17 @@ var PIPELINE_CONST = {
|
|||
* @const
|
||||
* @since 3.50.0
|
||||
*/
|
||||
ROPE_PIPELINE: 'RopePipeline'
|
||||
ROPE_PIPELINE: 'RopePipeline',
|
||||
|
||||
/**
|
||||
* The Mesh Pipeline.
|
||||
*
|
||||
* @name Phaser.Renderer.WebGL.Pipelines.MESH_PIPELINE
|
||||
* @type {string}
|
||||
* @const
|
||||
* @since 3.50.0
|
||||
*/
|
||||
MESH_PIPELINE: 'MeshPipeline'
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -15,10 +15,11 @@ var Pipelines = {
|
|||
|
||||
BitmapMaskPipeline: require('./BitmapMaskPipeline'),
|
||||
LightPipeline: require('./LightPipeline'),
|
||||
SinglePipeline: require('./SinglePipeline'),
|
||||
MeshPipeline: require('./MeshPipeline'),
|
||||
ModelViewProjection: require('./components/ModelViewProjection'),
|
||||
MultiPipeline: require('./MultiPipeline'),
|
||||
RopePipeline: require('./RopePipeline'),
|
||||
ModelViewProjection: require('./components/ModelViewProjection')
|
||||
SinglePipeline: require('./SinglePipeline')
|
||||
|
||||
};
|
||||
|
||||
|
|
45
src/renderer/webgl/shaders/Mesh-frag.js
Normal file
45
src/renderer/webgl/shaders/Mesh-frag.js
Normal file
|
@ -0,0 +1,45 @@
|
|||
module.exports = [
|
||||
'#define SHADER_NAME PHASER_MESH_FS',
|
||||
'',
|
||||
'precision mediump float;',
|
||||
'',
|
||||
'uniform vec3 uLightPosition;',
|
||||
'uniform vec3 uLightAmbient;',
|
||||
'uniform vec3 uLightDiffuse;',
|
||||
'uniform vec3 uLightSpecular;',
|
||||
'',
|
||||
'uniform vec3 uMaterialAmbient;',
|
||||
'uniform vec3 uMaterialDiffuse;',
|
||||
'uniform vec3 uMaterialSpecular;',
|
||||
'uniform float uMaterialShine;',
|
||||
'',
|
||||
'uniform vec3 uCameraPosition;',
|
||||
'',
|
||||
'uniform sampler2D uTexture;',
|
||||
'',
|
||||
'varying vec2 vTextureCoord;',
|
||||
'varying vec3 vNormal;',
|
||||
'varying vec3 vPosition;',
|
||||
'',
|
||||
'void main (void)',
|
||||
'{',
|
||||
' vec4 color = texture2D(uTexture, vTextureCoord);',
|
||||
'',
|
||||
' vec3 ambient = uLightAmbient * uMaterialAmbient;',
|
||||
'',
|
||||
' vec3 norm = normalize(vNormal);',
|
||||
' vec3 lightDir = normalize(uLightPosition - vPosition);',
|
||||
' float diff = max(dot(norm, lightDir), 0.0);',
|
||||
' vec3 diffuse = uLightDiffuse * (diff * uMaterialDiffuse);',
|
||||
'',
|
||||
' vec3 viewDir = normalize(uCameraPosition - vPosition);',
|
||||
' vec3 reflectDir = reflect(-lightDir, norm);',
|
||||
' float spec = pow(max(dot(viewDir, reflectDir), 0.0), uMaterialShine);',
|
||||
' vec3 specular = uLightSpecular * (spec * uMaterialSpecular);',
|
||||
'',
|
||||
' vec3 result = (ambient + diffuse + specular) * color.rgb;',
|
||||
'',
|
||||
' gl_FragColor = vec4(result, color.a);',
|
||||
'}',
|
||||
''
|
||||
].join('\n');
|
29
src/renderer/webgl/shaders/Mesh-vert.js
Normal file
29
src/renderer/webgl/shaders/Mesh-vert.js
Normal file
|
@ -0,0 +1,29 @@
|
|||
module.exports = [
|
||||
'#define SHADER_NAME PHASER_MESH_VS',
|
||||
'',
|
||||
'precision mediump float;',
|
||||
'',
|
||||
'attribute vec3 aVertexPosition;',
|
||||
'attribute vec3 aVertexNormal;',
|
||||
'attribute vec2 aTextureCoord;',
|
||||
'',
|
||||
'uniform mat4 uViewProjectionMatrix;',
|
||||
'uniform mat4 uModelMatrix;',
|
||||
'uniform mat4 uNormalMatrix;',
|
||||
'',
|
||||
'varying vec2 vTextureCoord;',
|
||||
'varying vec3 vNormal;',
|
||||
'varying vec3 vPosition;',
|
||||
'',
|
||||
'void main ()',
|
||||
'{',
|
||||
' vTextureCoord = aTextureCoord;',
|
||||
'',
|
||||
' vPosition = vec3(uModelMatrix * vec4(aVertexPosition, 1.0));',
|
||||
'',
|
||||
' vNormal = vec3(uNormalMatrix * vec4(aVertexNormal, 1.0));',
|
||||
'',
|
||||
' gl_Position = uViewProjectionMatrix * uModelMatrix * vec4(aVertexPosition, 1.0);',
|
||||
'}',
|
||||
''
|
||||
].join('\n');
|
42
src/renderer/webgl/shaders/src/Mesh.frag
Normal file
42
src/renderer/webgl/shaders/src/Mesh.frag
Normal file
|
@ -0,0 +1,42 @@
|
|||
#define SHADER_NAME PHASER_MESH_FS
|
||||
|
||||
precision mediump float;
|
||||
|
||||
uniform vec3 uLightPosition;
|
||||
uniform vec3 uLightAmbient;
|
||||
uniform vec3 uLightDiffuse;
|
||||
uniform vec3 uLightSpecular;
|
||||
|
||||
uniform vec3 uMaterialAmbient;
|
||||
uniform vec3 uMaterialDiffuse;
|
||||
uniform vec3 uMaterialSpecular;
|
||||
uniform float uMaterialShine;
|
||||
|
||||
uniform vec3 uCameraPosition;
|
||||
|
||||
uniform sampler2D uTexture;
|
||||
|
||||
varying vec2 vTextureCoord;
|
||||
varying vec3 vNormal;
|
||||
varying vec3 vPosition;
|
||||
|
||||
void main (void)
|
||||
{
|
||||
vec4 color = texture2D(uTexture, vTextureCoord);
|
||||
|
||||
vec3 ambient = uLightAmbient * uMaterialAmbient;
|
||||
|
||||
vec3 norm = normalize(vNormal);
|
||||
vec3 lightDir = normalize(uLightPosition - vPosition);
|
||||
float diff = max(dot(norm, lightDir), 0.0);
|
||||
vec3 diffuse = uLightDiffuse * (diff * uMaterialDiffuse);
|
||||
|
||||
vec3 viewDir = normalize(uCameraPosition - vPosition);
|
||||
vec3 reflectDir = reflect(-lightDir, norm);
|
||||
float spec = pow(max(dot(viewDir, reflectDir), 0.0), uMaterialShine);
|
||||
vec3 specular = uLightSpecular * (spec * uMaterialSpecular);
|
||||
|
||||
vec3 result = (ambient + diffuse + specular) * color.rgb;
|
||||
|
||||
gl_FragColor = vec4(result, color.a);
|
||||
}
|
26
src/renderer/webgl/shaders/src/Mesh.vert
Normal file
26
src/renderer/webgl/shaders/src/Mesh.vert
Normal file
|
@ -0,0 +1,26 @@
|
|||
#define SHADER_NAME PHASER_MESH_VS
|
||||
|
||||
precision mediump float;
|
||||
|
||||
attribute vec3 aVertexPosition;
|
||||
attribute vec3 aVertexNormal;
|
||||
attribute vec2 aTextureCoord;
|
||||
|
||||
uniform mat4 uViewProjectionMatrix;
|
||||
uniform mat4 uModelMatrix;
|
||||
uniform mat4 uNormalMatrix;
|
||||
|
||||
varying vec2 vTextureCoord;
|
||||
varying vec3 vNormal;
|
||||
varying vec3 vPosition;
|
||||
|
||||
void main ()
|
||||
{
|
||||
vTextureCoord = aTextureCoord;
|
||||
|
||||
vPosition = vec3(uModelMatrix * vec4(aVertexPosition, 1.0));
|
||||
|
||||
vNormal = vec3(uNormalMatrix * vec4(aVertexNormal, 1.0));
|
||||
|
||||
gl_Position = uViewProjectionMatrix * uModelMatrix * vec4(aVertexPosition, 1.0);
|
||||
}
|
Loading…
Reference in a new issue