UNPKG

dragonbones-runtime

Version:

the tools to build dragonbones file for diffrent framework

307 lines (281 loc) 12.2 kB
////////////////////////////////////////////////////////////////////////////////////// // // Copyright (c) 2014-present, Egret Technology. // All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // * Neither the name of the Egret nor the // names of its contributors may be used to endorse or promote products // derived from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY EGRET AND CONTRIBUTORS "AS IS" AND ANY EXPRESS // OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. // IN NO EVENT SHALL EGRET AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF USE, DATA, // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // ////////////////////////////////////////////////////////////////////////////////////// namespace egret.web { /** * @private * 顶点数组管理对象 * 用来维护顶点数组 */ export class WebGLVertexArrayObject { private size: number = 2000; private vertexMaxSize: number = this.size * 4; private indicesMaxSize: number = this.size * 6; private vertSize: number = 5; private vertices: Float32Array = null; private indices: Uint16Array = null; private indicesForMesh: Uint16Array = null; private vertexIndex: number = 0; private indexIndex: number = 0; private hasMesh: boolean = false; public constructor() { let numVerts = this.vertexMaxSize * this.vertSize; let numIndices = this.indicesMaxSize; this.vertices = new Float32Array(numVerts); this.indices = new Uint16Array(numIndices); this.indicesForMesh = new Uint16Array(numIndices); for (let i = 0, j = 0; i < numIndices; i += 6, j += 4) { this.indices[i + 0] = j + 0; this.indices[i + 1] = j + 1; this.indices[i + 2] = j + 2; this.indices[i + 3] = j + 0; this.indices[i + 4] = j + 2; this.indices[i + 5] = j + 3; } } /** * 是否达到最大缓存数量 */ public reachMaxSize(vertexCount: number = 4, indexCount: number = 6): boolean { return this.vertexIndex > this.vertexMaxSize - vertexCount || this.indexIndex > this.indicesMaxSize - indexCount; } /** * 获取缓存完成的顶点数组 */ public getVertices(): any { let view = this.vertices.subarray(0, this.vertexIndex * this.vertSize); return view; } /** * 获取缓存完成的索引数组 */ public getIndices(): any { return this.indices; } /** * 获取缓存完成的mesh索引数组 */ public getMeshIndices(): any { return this.indicesForMesh; } /** * 切换成mesh索引缓存方式 */ public changeToMeshIndices(): void { if (!this.hasMesh) { // 拷贝默认index信息到for mesh中 for (let i = 0, l = this.indexIndex; i < l; ++i) { this.indicesForMesh[i] = this.indices[i]; } this.hasMesh = true; } } public isMesh(): boolean { return this.hasMesh; } /** * 默认构成矩形 */ // private defaultMeshVertices = [0, 0, 1, 0, 1, 1, 0, 1]; // private defaultMeshUvs = [ // 0, 0, // 1, 0, // 1, 1, // 0, 1 // ]; // private defaultMeshIndices = [0, 1, 2, 0, 2, 3]; /** * 缓存一组顶点 */ public cacheArrays(buffer: WebGLRenderBuffer, sourceX: number, sourceY: number, sourceWidth: number, sourceHeight: number, destX: number, destY: number, destWidth: number, destHeight: number, textureSourceWidth: number, textureSourceHeight: number, meshUVs?: number[], meshVertices?: number[], meshIndices?: number[], rotated?: boolean): void { let alpha = buffer.globalAlpha; //计算出绘制矩阵,之后把矩阵还原回之前的 let locWorldTransform = buffer.globalMatrix; let a = locWorldTransform.a; let b = locWorldTransform.b; let c = locWorldTransform.c; let d = locWorldTransform.d; let tx = locWorldTransform.tx; let ty = locWorldTransform.ty; let offsetX = buffer.$offsetX; let offsetY = buffer.$offsetY; if (offsetX != 0 || offsetY != 0) { tx = offsetX * a + offsetY * c + tx; ty = offsetX * b + offsetY * d + ty; } if (!meshVertices) { if (destX != 0 || destY != 0) { tx = destX * a + destY * c + tx; ty = destX * b + destY * d + ty; } let a1 = destWidth / sourceWidth; if (a1 != 1) { a = a1 * a; b = a1 * b; } let d1 = destHeight / sourceHeight; if (d1 != 1) { c = d1 * c; d = d1 * d; } } if (meshVertices) { // 计算索引位置与赋值 let vertices = this.vertices; let index = this.vertexIndex * this.vertSize; // 缓存顶点数组 let i = 0, iD = 0, l = 0; let u = 0, v = 0, x = 0, y = 0; for (i = 0, l = meshUVs.length; i < l; i += 2) { iD = i * 5 / 2; x = meshVertices[i]; y = meshVertices[i + 1]; u = meshUVs[i]; v = meshUVs[i + 1]; // xy vertices[index + iD + 0] = a * x + c * y + tx; vertices[index + iD + 1] = b * x + d * y + ty; // uv vertices[index + iD + 2] = (sourceX + u * sourceWidth) / textureSourceWidth; vertices[index + iD + 3] = (sourceY + v * sourceHeight) / textureSourceHeight; // alpha vertices[index + iD + 4] = alpha; } // 缓存索引数组 if (this.hasMesh) { for (let i = 0, l = meshIndices.length; i < l; ++i) { this.indicesForMesh[this.indexIndex + i] = meshIndices[i] + this.vertexIndex; } } this.vertexIndex += meshUVs.length / 2; this.indexIndex += meshIndices.length; } else { let width = textureSourceWidth; let height = textureSourceHeight; let w = sourceWidth; let h = sourceHeight; sourceX = sourceX / width; sourceY = sourceY / height; let vertices = this.vertices; let index = this.vertexIndex * this.vertSize; if (rotated) { let temp = sourceWidth; sourceWidth = sourceHeight / width; sourceHeight = temp / height; // xy vertices[index++] = tx; vertices[index++] = ty; // uv vertices[index++] = sourceWidth + sourceX; vertices[index++] = sourceY; // alpha vertices[index++] = alpha; // xy vertices[index++] = a * w + tx; vertices[index++] = b * w + ty; // uv vertices[index++] = sourceWidth + sourceX; vertices[index++] = sourceHeight + sourceY; // alpha vertices[index++] = alpha; // xy vertices[index++] = a * w + c * h + tx; vertices[index++] = d * h + b * w + ty; // uv vertices[index++] = sourceX; vertices[index++] = sourceHeight + sourceY; // alpha vertices[index++] = alpha; // xy vertices[index++] = c * h + tx; vertices[index++] = d * h + ty; // uv vertices[index++] = sourceX; vertices[index++] = sourceY; // alpha vertices[index++] = alpha; } else { sourceWidth = sourceWidth / width; sourceHeight = sourceHeight / height; // xy vertices[index++] = tx; vertices[index++] = ty; // uv vertices[index++] = sourceX; vertices[index++] = sourceY; // alpha vertices[index++] = alpha; // xy vertices[index++] = a * w + tx; vertices[index++] = b * w + ty; // uv vertices[index++] = sourceWidth + sourceX; vertices[index++] = sourceY; // alpha vertices[index++] = alpha; // xy vertices[index++] = a * w + c * h + tx; vertices[index++] = d * h + b * w + ty; // uv vertices[index++] = sourceWidth + sourceX; vertices[index++] = sourceHeight + sourceY; // alpha vertices[index++] = alpha; // xy vertices[index++] = c * h + tx; vertices[index++] = d * h + ty; // uv vertices[index++] = sourceX; vertices[index++] = sourceHeight + sourceY; // alpha vertices[index++] = alpha; } // 缓存索引数组 if (this.hasMesh) { let indicesForMesh = this.indicesForMesh; indicesForMesh[this.indexIndex + 0] = 0 + this.vertexIndex; indicesForMesh[this.indexIndex + 1] = 1 + this.vertexIndex; indicesForMesh[this.indexIndex + 2] = 2 + this.vertexIndex; indicesForMesh[this.indexIndex + 3] = 0 + this.vertexIndex; indicesForMesh[this.indexIndex + 4] = 2 + this.vertexIndex; indicesForMesh[this.indexIndex + 5] = 3 + this.vertexIndex; } this.vertexIndex += 4; this.indexIndex += 6; } } public clear(): void { this.hasMesh = false; this.vertexIndex = 0; this.indexIndex = 0; } } }