Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assembler兼容模拟器和Native #2

Merged
merged 4 commits into from
Jul 31, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
144 changes: 58 additions & 86 deletions assets/scripts/bezier-assembler.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,19 @@
import PageEffectAssemblerBase from "./page-effect-assembler-base";

const gfx = cc.gfx

interface BookVertex {
x:number,
y:number,
u:number,
v:number
}

interface BookQuad {
lt:number,
lb:number,
rb:number,
rt:number
}

export default class BezierAssembler extends cc.Assembler {
protected vfmtPosUvColor = 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: gfx.ATTR_COLOR, type: gfx.ATTR_TYPE_UINT8, num: 4, normalize: true },
{ name: "a_isFront", type: gfx.ATTR_TYPE_FLOAT32, num: 1},
]);

protected verts:BookVertex[] = []
protected quads:BookQuad[] = []
let vfmtPosUvColorFront = 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: gfx.ATTR_COLOR, type: gfx.ATTR_TYPE_UINT8, num: 4, normalize: true },
{ name: "a_isFront", type: gfx.ATTR_TYPE_FLOAT32, num: 1},
]);

export default class BezierAssembler extends PageEffectAssemblerBase {
protected angle:number = 0
public updateRenderData (comp: any) {
if (comp) {
let pointNum: number = comp.getPointCount()
this.verts.length = 0
this.quads.length = 0
if (pointNum < 2) {
return
}
Expand All @@ -56,6 +39,11 @@ export default class BezierAssembler extends cc.Assembler {
let lastU = 0
// 下一个点的纹理坐标
let nextU = 0

let floatsPerVert = this.floatsPerVert;
let verts = this.renderData.vDatas[0];
// 写verts时的下标
let dstOffset = 0;
for (let i = 1; i < pointNum; i++) {
let isTail = i === pointNum - 1
let lastBezierPos = bezierPosList[i - 1]
Expand All @@ -72,22 +60,55 @@ export default class BezierAssembler extends cc.Assembler {
分别计算小矩形四个顶点的坐标和纹理坐标
各顶点的坐标计算方法为在左下角坐标的基础上加上顶点在贝塞尔曲线上的坐标,如果是书页顶部的顶点则还要加上书页的高度
*/
let lb = this.verts.push({x: posX + lastBezierPos.x, y: posY + lastBezierPos.y, u: lastU, v: 1 })
let rb = this.verts.push({x: posX + nextBezierPos.x, y: posY + nextBezierPos.y, u: nextU, v: 1 })
let lt = this.verts.push({x: posX + lastBezierPos.x, y: posY + height + lastBezierPos.y, u: lastU, v: 0 })
let rt = this.verts.push({x: posX + nextBezierPos.x, y: posY + height + nextBezierPos.y, u: nextU, v: 0 })
// 填入各顶点对应的索引值
this.quads.push({
lb: lb - 1,
rb: rb - 1,
lt: lt - 1,
rt : rt - 1,
})

// 将4个顶点数据写入verts
dstOffset = floatsPerVert * (i-1) * 4;
verts[dstOffset] = posX + lastBezierPos.x;
verts[dstOffset + 1] = posY + lastBezierPos.y;
verts[dstOffset + 2] = lastU;
verts[dstOffset + 3] = 1;
dstOffset += floatsPerVert;

verts[dstOffset] = posX + nextBezierPos.x;
verts[dstOffset + 1] = posY + nextBezierPos.y;
verts[dstOffset + 2] = nextU;
verts[dstOffset + 3] = 1;
dstOffset += floatsPerVert;

verts[dstOffset] = posX + lastBezierPos.x;
verts[dstOffset + 1] = posY + height + lastBezierPos.y;
verts[dstOffset + 2] = lastU;
verts[dstOffset + 3] = 0;
dstOffset += floatsPerVert;

verts[dstOffset] = posX + nextBezierPos.x;
verts[dstOffset + 1] = posY + height + nextBezierPos.y;
verts[dstOffset + 2] = nextU;
verts[dstOffset + 3] = 0;

lastU = nextU
}

this.updateColor(comp, null);
}
}

init(comp: cc.RenderComponent) {
super.init(comp);

//@ts-ignore
let segmentCount = comp.getPointCount() - 1;
this.verticesCount = 4 * segmentCount;
this.indicesCount = 6 * segmentCount;
this.floatsPerVert = 6;

this.initData();
}

getVfmt() {
return vfmtPosUvColorFront;
}

private _getCtrlPosByAngle(width: number): {startPos: cc.Vec2, endPos: cc.Vec2, ctrlPos1: cc.Vec2, ctrlPos2: cc.Vec2} {
let startPos = new cc.Vec2(0, 0)
let endPos = null
Expand Down Expand Up @@ -175,53 +196,4 @@ export default class BezierAssembler extends cc.Assembler {
endPos = endPos.mul(Math.pow(t, 3))
return startPos.add(ctrlPos1.add(ctrlPos2.add(endPos)))
}

public fillBuffers (comp:cc.RenderComponent, renderer:cc.renderer) {
if (this.verts.length == 0) {
return
}
let buffer = renderer.getBuffer('mesh', this.vfmtPosUvColor)

let vertexOffset = buffer.byteOffset >> 2
let indiceOffset = buffer.indiceOffset
let vertexId = buffer.vertexOffset

let verts = this.verts
let vertexCount = verts.length
let indiceCount = this.quads.length * 6
// 通过设定的顶点数量及顶点索引数量获取 buffer 的数据空间
buffer.request(vertexCount, indiceCount)

let vbuf = buffer._vData //positon/uv
let ibuf = buffer._iData //index
let uintbuf = buffer._uintVData // colors

let white = cc.Color.WHITE._val
// 填充顶点缓冲
for (let i = 0, len = verts.length; i < len; i++) {
let vert = verts[i]
let isFirstVert = i % 2 === 0
let firstVert = isFirstVert ? vert : verts[i - 1]
let secondVert = isFirstVert ? verts[i + 1] : vert
// 计算当前小矩形是正面还是背面
let isFront = firstVert.x < secondVert.x ? 1.0 : 0.0
vbuf[vertexOffset++] = vert.x;
vbuf[vertexOffset++] = vert.y;
vbuf[vertexOffset++] = vert.u;
vbuf[vertexOffset++] = vert.v;
uintbuf[vertexOffset++] = white;
vbuf[vertexOffset++] = isFront;
}
// 填充索引缓冲
for (let i = 0, len = this.quads.length; i < len; i++) {
let quad = this.quads[i]
ibuf[indiceOffset++] = vertexId + quad.lb
ibuf[indiceOffset++] = vertexId + quad.rb
ibuf[indiceOffset++] = vertexId + quad.lt

ibuf[indiceOffset++] = vertexId + quad.rb
ibuf[indiceOffset++] = vertexId + quad.rt
ibuf[indiceOffset++] = vertexId + quad.lt
}
}
}
83 changes: 83 additions & 0 deletions assets/scripts/page-effect-assembler-base.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@

export default class PageEffectAssemblerBase extends cc.Assembler {
// 普通四边形的属性,根据实际的顶点格式、数量调整
protected verticesCount = 4;
protected indicesCount = 6;
protected floatsPerVert = 5;

protected colorOffset = 4;
protected renderData: cc.RenderData = null;

get verticesFloats() {
return this.verticesCount * this.floatsPerVert;
}

getBuffer() {
//@ts-ignore
return cc.renderer._handle.getBuffer("mesh", this.getVfmt());
}

getVfmt() {
// to be overwrite
return null;
}

updateColor(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;
}
}

initData() {
//@ts-ignore
this.renderData = new cc.RenderData();
this.renderData.init(this);

let data = this.renderData;
// createFlexData支持创建指定格式的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;
}
}

fillBuffers(comp, renderer) {
let renderData = this.renderData;
let vData = renderData.vDatas[0];
let iData = renderData.iDatas[0];

let buffer = this.getBuffer();
let offsetInfo = buffer.request(this.verticesCount, this.indicesCount);

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);
}

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];
}
}
}
9 changes: 9 additions & 0 deletions assets/scripts/page-effect-assembler-base.ts.meta
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"ver": "1.0.8",
"uuid": "ad29885c-a051-4f8e-a7a8-f460b4b6c081",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}