WaterControl/packages/TiledMapOptimizer/resource/Script/TmoAssembler.js
2024-07-10 18:35:07 +08:00

296 lines
9.8 KiB
JavaScript

let gfx = cc.gfx;
// 颜色去除 + 物件图集合批
var vfmtPosUvIndex = new gfx.VertexFormat([
{ name: gfx.ATTR_POSITION, type: gfx.ATTR_TYPE_FLOAT32, num: 2 },
{ name: gfx.ATTR_UV0, type: gfx.ATTR_TYPE_FLOAT32, num: 2 },
{ name: "a_texture_idx", type: gfx.ATTR_TYPE_FLOAT32, num: 1 },
]);
// 仅物件图集合批
var vfmtPosUvColorIndex = new gfx.VertexFormat([
{ name: gfx.ATTR_POSITION, type: gfx.ATTR_TYPE_FLOAT32, num: 2 },
{ name: gfx.ATTR_UV0, type: gfx.ATTR_TYPE_FLOAT32, num: 2 },
{ name: "a_texture_idx", type: gfx.ATTR_TYPE_FLOAT32, num: 1 },
{ name: gfx.ATTR_COLOR, type: gfx.ATTR_TYPE_UINT8, num: 4, normalize: true },
]);
export class TmoAssembler extends cc.Assembler {
init(comp) {
super.init(comp);
this._noColor = comp.isNoColor();
this.updateColor = this._noColor ? undefined : this.updateColorFunc;
this.uvOffset = 2;
this.colorOffset = 5;
this.textureIndexOffset = 4;
this.floatsPerVert = this._noColor ? 5 : 6;
this.indicesCount = 6;
this.verticesCount = 4;
this._renderData = new cc.RenderData();
this._renderData.init(this);
this.initLocal();
this.initData();
}
initLocal() {
this._local = [];
this._local.length = 4;
}
initData() {
let data = this._renderData;
data.createFlexData(0, this.verticesCount, this.indicesCount, this.getVfmt());
// 填充顶点索引信息
let indices = data.iDatas[0];
let count = indices.length / 6;
for (let i = 0, idx = 0; i < count; i++) {
let vertextID = i * 4;
indices[idx++] = vertextID;
indices[idx++] = vertextID + 1;
indices[idx++] = vertextID + 2;
indices[idx++] = vertextID + 1;
indices[idx++] = vertextID + 3;
indices[idx++] = vertextID + 2;
}
}
getBuffer() {
return cc.renderer._handle.getBuffer("mesh", this.getVfmt());
}
getVfmt() {
return this._noColor ? vfmtPosUvIndex : vfmtPosUvColorIndex;
}
updateRenderData(sprite) {
this.packToDynamicAtlas(sprite, sprite._spriteFrame);
if (sprite._vertsDirty) {
this.updateUVs(sprite);
this.updateVerts(sprite);
this.updateTextureIdx(sprite);
sprite._vertsDirty = false;
}
}
/**
* 填充textureIndex数据
* @param {cc.Sprite} sprite
*/
updateTextureIdx(sprite) {
let textureIdx = sprite._textureIdx;
let verts = this._renderData.vDatas[0];
let verticesCount = this.verticesCount;
let floatsPerVert = this.floatsPerVert;
let textureIndexOffset = this.textureIndexOffset;
for (let i = 0; i < verticesCount; i++) {
let index = i * floatsPerVert + textureIndexOffset;
verts[index] = textureIdx;
}
}
updateUVs(sprite) {
let uv = sprite._spriteFrame.uv;
let uvOffset = this.uvOffset;
let floatsPerVert = this.floatsPerVert;
let verts = this._renderData.vDatas[0];
for (let i = 0; i < 4; i++) {
let srcOffset = i * 2;
let dstOffset = floatsPerVert * i + uvOffset;
verts[dstOffset] = uv[srcOffset];
verts[dstOffset + 1] = uv[srcOffset + 1];
}
}
updateVerts(sprite) {
let node = sprite.node,
cw = node.width, ch = node.height,
appx = node.anchorX * cw, appy = node.anchorY * ch,
l, b, r, t;
if (sprite.trim) {
l = -appx;
b = -appy;
r = cw - appx;
t = ch - appy;
}
else {
let frame = sprite.spriteFrame,
ow = frame._originalSize.width, oh = frame._originalSize.height,
rw = frame._rect.width, rh = frame._rect.height,
offset = frame._offset,
scaleX = cw / ow, scaleY = ch / oh;
let trimLeft = offset.x + (ow - rw) / 2;
let trimRight = offset.x - (ow - rw) / 2;
let trimBottom = offset.y + (oh - rh) / 2;
let trimTop = offset.y - (oh - rh) / 2;
l = trimLeft * scaleX - appx;
b = trimBottom * scaleY - appy;
r = cw + trimRight * scaleX - appx;
t = ch + trimTop * scaleY - appy;
}
let local = this._local;
local[0] = l;
local[1] = b;
local[2] = r;
local[3] = t;
this.updateWorldVerts(sprite);
}
get verticesFloats() {
return this.verticesCount * this.floatsPerVert;
}
updateColorFunc(comp, color) {
let uintVerts = this._renderData.uintVDatas[0];
if (!uintVerts) return;
color = color != null ? color : comp.node.color._val;
let floatsPerVert = this.floatsPerVert;
let colorOffset = this.colorOffset;
for (let i = colorOffset, l = uintVerts.length; i < l; i += floatsPerVert) {
uintVerts[i] = color;
}
}
updateWorldVerts(comp) {
if (CC_NATIVERENDERER) {
// 原生平台兼容代码 复制于jsb-engine.js中的cc.Assembler2D.prototype.updateWorldVerts
var local = this._local;
var verts = this._renderData.vDatas[0];
var vl = local[0],
vr = local[2],
vb = local[1],
vt = local[3];
var floatsPerVert = this.floatsPerVert;
var vertexOffset = 0; // left bottom
verts[vertexOffset] = vl;
verts[vertexOffset + 1] = vb;
vertexOffset += floatsPerVert; // right bottom
verts[vertexOffset] = vr;
verts[vertexOffset + 1] = vb;
vertexOffset += floatsPerVert; // left top
verts[vertexOffset] = vl;
verts[vertexOffset + 1] = vt;
vertexOffset += floatsPerVert; // right top
verts[vertexOffset] = vr;
verts[vertexOffset + 1] = vt;
} else {
let local = this._local;
let verts = this._renderData.vDatas[0];
let matrix = comp.node._worldMatrix;
let matrixm = matrix.m,
a = matrixm[0], b = matrixm[1], c = matrixm[4], d = matrixm[5],
tx = matrixm[12], ty = matrixm[13];
let vl = local[0], vr = local[2],
vb = local[1], vt = local[3];
let floatsPerVert = this.floatsPerVert;
let vertexOffset = 0;
let justTranslate = a === 1 && b === 0 && c === 0 && d === 1;
if (justTranslate) {
// left bottom
verts[vertexOffset] = vl + tx;
verts[vertexOffset + 1] = vb + ty;
vertexOffset += floatsPerVert;
// right bottom
verts[vertexOffset] = vr + tx;
verts[vertexOffset + 1] = vb + ty;
vertexOffset += floatsPerVert;
// left top
verts[vertexOffset] = vl + tx;
verts[vertexOffset + 1] = vt + ty;
vertexOffset += floatsPerVert;
// right top
verts[vertexOffset] = vr + tx;
verts[vertexOffset + 1] = vt + ty;
} else {
let al = a * vl, ar = a * vr,
bl = b * vl, br = b * vr,
cb = c * vb, ct = c * vt,
db = d * vb, dt = d * vt;
// left bottom
verts[vertexOffset] = al + cb + tx;
verts[vertexOffset + 1] = bl + db + ty;
vertexOffset += floatsPerVert;
// right bottom
verts[vertexOffset] = ar + cb + tx;
verts[vertexOffset + 1] = br + db + ty;
vertexOffset += floatsPerVert;
// left top
verts[vertexOffset] = al + ct + tx;
verts[vertexOffset + 1] = bl + dt + ty;
vertexOffset += floatsPerVert;
// right top
verts[vertexOffset] = ar + ct + tx;
verts[vertexOffset + 1] = br + dt + ty;
}
}
}
fillBuffers(comp, renderer) {
if (renderer.worldMatDirty) {
this.updateWorldVerts(comp);
}
let renderData = this._renderData;
let vData = renderData.vDatas[0];
let iData = renderData.iDatas[0];
let buffer = this.getBuffer(renderer);
let offsetInfo = buffer.request(this.verticesCount, this.indicesCount);
// buffer data may be realloc, need get reference after request.
// fill vertices
let vertexOffset = offsetInfo.byteOffset >> 2,
vbuf = buffer._vData;
if (vData.length + vertexOffset > vbuf.length) {
vbuf.set(vData.subarray(0, vbuf.length - vertexOffset), vertexOffset);
} else {
vbuf.set(vData, vertexOffset);
}
// fill indices
let ibuf = buffer._iData,
indiceOffset = offsetInfo.indiceOffset,
vertexId = offsetInfo.vertexOffset;
for (let i = 0, l = iData.length; i < l; i++) {
ibuf[indiceOffset++] = vertexId + iData[i];
}
}
packToDynamicAtlas(comp, frame) {
if (CC_TEST) return;
if (!frame._original && cc.dynamicAtlasManager && frame._texture.packable) {
let packedFrame = cc.dynamicAtlasManager.insertSpriteFrame(frame);
if (packedFrame) {
frame._setDynamicAtlasFrame(packedFrame);
}
}
let material = comp._materials[0];
if (!material) return;
if (material.getProperty('texture') !== frame._texture) {
// texture was packed to dynamic atlas, should update uvs
comp._vertsDirty = true;
comp._updateMaterial();
}
}
}