phaser
Version:
A fast, free and fun HTML5 Game Framework for Desktop and Mobile web browsers from the team at Phaser Studio Inc.
247 lines (204 loc) • 7.6 kB
JavaScript
/**
* @author Richard Davey <rich@phaser.io>
* @copyright 2013-2025 Phaser Studio Inc.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*/
var Face = require('./Face');
var GetFastValue = require('../../utils/object/GetFastValue');
var Matrix4 = require('../../math/Matrix4');
var Vector3 = require('../../math/Vector3');
var Vertex = require('./Vertex');
var tempPosition = new Vector3();
var tempRotation = new Vector3();
var tempMatrix = new Matrix4();
/**
* Creates a grid of vertices based on the given configuration object and optionally adds it to a Mesh.
*
* The size of the grid is given in pixels. An example configuration may be:
*
* `{ width: 256, height: 256, widthSegments: 2, heightSegments: 2, tile: true }`
*
* This will create a grid 256 x 256 pixels in size, split into 2 x 2 segments, with
* the texture tiling across the cells.
*
* You can split the grid into segments both vertically and horizontally. This will
* generate two faces per grid segment as a result.
*
* The `tile` parameter allows you to control if the tile will repeat across the grid
* segments, or be displayed in full.
*
* If adding this grid to a Mesh you can offset the grid via the `x` and `y` properties.
*
* UV coordinates are generated based on the given texture and frame in the config. For
* example, no frame is given, the UVs will be in the range 0 to 1. If a frame is given,
* such as from a texture atlas, the UVs will be generated within the range of that frame.
*
* @function Phaser.Geom.Mesh.GenerateGridVerts
* @since 3.50.0
*
* @param {Phaser.Types.Geom.Mesh.GenerateGridConfig} config - A Grid configuration object.
*
* @return {Phaser.Types.Geom.Mesh.GenerateGridVertsResult} A Grid Result object, containing the generated vertices and indicies.
*/
var GenerateGridVerts = function (config)
{
var mesh = GetFastValue(config, 'mesh');
var texture = GetFastValue(config, 'texture', null);
var frame = GetFastValue(config, 'frame');
var width = GetFastValue(config, 'width', 1);
var height = GetFastValue(config, 'height', width);
var widthSegments = GetFastValue(config, 'widthSegments', 1);
var heightSegments = GetFastValue(config, 'heightSegments', widthSegments);
var posX = GetFastValue(config, 'x', 0);
var posY = GetFastValue(config, 'y', 0);
var posZ = GetFastValue(config, 'z', 0);
var rotateX = GetFastValue(config, 'rotateX', 0);
var rotateY = GetFastValue(config, 'rotateY', 0);
var rotateZ = GetFastValue(config, 'rotateZ', 0);
var zIsUp = GetFastValue(config, 'zIsUp', true);
var isOrtho = GetFastValue(config, 'isOrtho', (mesh) ? mesh.dirtyCache[11] : false);
var colors = GetFastValue(config, 'colors', [ 0xffffff ]);
var alphas = GetFastValue(config, 'alphas', [ 1 ]);
var tile = GetFastValue(config, 'tile', false);
var flipY = GetFastValue(config, 'flipY', false);
var widthSet = GetFastValue(config, 'width', null);
var result = {
faces: [],
verts: []
};
tempPosition.set(posX, posY, posZ);
tempRotation.set(rotateX, rotateY, rotateZ);
tempMatrix.fromRotationXYTranslation(tempRotation, tempPosition, zIsUp);
var textureFrame;
if (!texture && mesh)
{
texture = mesh.texture;
if (!frame)
{
textureFrame = mesh.frame;
}
}
else if (mesh && typeof(texture) === 'string')
{
texture = mesh.scene.sys.textures.get(texture);
}
else if (!texture)
{
// There's nothing more we can do without a texture
return result;
}
if (!textureFrame)
{
textureFrame = texture.get(frame);
}
// If the Mesh is ortho and no width / height is given, we'll default to texture sizes (if set!)
if (!widthSet && isOrtho && texture && mesh)
{
width = textureFrame.width / mesh.height;
height = textureFrame.height / mesh.height;
}
var halfWidth = width / 2;
var halfHeight = height / 2;
var gridX = Math.floor(widthSegments);
var gridY = Math.floor(heightSegments);
var gridX1 = gridX + 1;
var gridY1 = gridY + 1;
var segmentWidth = width / gridX;
var segmentHeight = height / gridY;
var uvs = [];
var vertices = [];
var ix;
var iy;
var frameU0 = 0;
var frameU1 = 1;
var frameV0 = 0;
var frameV1 = 1;
if (textureFrame)
{
frameU0 = textureFrame.u0;
frameU1 = textureFrame.u1;
if (!flipY)
{
frameV0 = textureFrame.v0;
frameV1 = textureFrame.v1;
}
else
{
frameV0 = textureFrame.v1;
frameV1 = textureFrame.v0;
}
}
var frameU = frameU1 - frameU0;
var frameV = frameV1 - frameV0;
for (iy = 0; iy < gridY1; iy++)
{
var y = iy * segmentHeight - halfHeight;
for (ix = 0; ix < gridX1; ix++)
{
var x = ix * segmentWidth - halfWidth;
vertices.push(x, -y);
var tu = frameU0 + frameU * (ix / gridX);
var tv = frameV0 + frameV * (iy / gridY);
uvs.push(tu, tv);
}
}
if (!Array.isArray(colors))
{
colors = [ colors ];
}
if (!Array.isArray(alphas))
{
alphas = [ alphas ];
}
var alphaIndex = 0;
var colorIndex = 0;
for (iy = 0; iy < gridY; iy++)
{
for (ix = 0; ix < gridX; ix++)
{
var a = (ix + gridX1 * iy) * 2;
var b = (ix + gridX1 * (iy + 1)) * 2;
var c = ((ix + 1) + gridX1 * (iy + 1)) * 2;
var d = ((ix + 1) + gridX1 * iy) * 2;
var color = colors[colorIndex];
var alpha = alphas[alphaIndex];
var vert1 = new Vertex(vertices[a], vertices[a + 1], 0, uvs[a], uvs[a + 1], color, alpha).transformMat4(tempMatrix);
var vert2 = new Vertex(vertices[b], vertices[b + 1], 0, uvs[b], uvs[b + 1], color, alpha).transformMat4(tempMatrix);
var vert3 = new Vertex(vertices[d], vertices[d + 1], 0, uvs[d], uvs[d + 1], color, alpha).transformMat4(tempMatrix);
var vert4 = new Vertex(vertices[b], vertices[b + 1], 0, uvs[b], uvs[b + 1], color, alpha).transformMat4(tempMatrix);
var vert5 = new Vertex(vertices[c], vertices[c + 1], 0, uvs[c], uvs[c + 1], color, alpha).transformMat4(tempMatrix);
var vert6 = new Vertex(vertices[d], vertices[d + 1], 0, uvs[d], uvs[d + 1], color, alpha).transformMat4(tempMatrix);
if (tile)
{
vert1.setUVs(frameU0, frameV1);
vert2.setUVs(frameU0, frameV0);
vert3.setUVs(frameU1, frameV1);
vert4.setUVs(frameU0, frameV0);
vert5.setUVs(frameU1, frameV0);
vert6.setUVs(frameU1, frameV1);
}
colorIndex++;
if (colorIndex === colors.length)
{
colorIndex = 0;
}
alphaIndex++;
if (alphaIndex === alphas.length)
{
alphaIndex = 0;
}
result.verts.push(vert1, vert2, vert3, vert4, vert5, vert6);
result.faces.push(
new Face(vert1, vert2, vert3),
new Face(vert4, vert5, vert6)
);
}
}
if (mesh)
{
mesh.faces = mesh.faces.concat(result.faces);
mesh.vertices = mesh.vertices.concat(result.verts);
}
return result;
};
module.exports = GenerateGridVerts;