123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- /**
- * 重写引擎方法,进行一些功能扩展
- */
- const { ccclass } = cc._decorator;
- @ccclass
- export default class LevelExtend extends cc.Component{
- protected onLoad(): void {
- CCCExtend.init();
- }
- }
- class CCCExtend {
- /** 初始化扩展 */
- static init() {
- this._extendRenderFlow();
- }
- /** 扩展渲染流,新增层级渲染 */
- private static _extendRenderFlow() {
- let FlagOfset = 0;
- const DONOTHING = 1 << FlagOfset++;
- const BREAK_FLOW = 1 << FlagOfset++;
- const LOCAL_TRANSFORM = 1 << FlagOfset++;
- const WORLD_TRANSFORM = 1 << FlagOfset++;
- const TRANSFORM = LOCAL_TRANSFORM | WORLD_TRANSFORM;
- const UPDATE_RENDER_DATA = 1 << FlagOfset++;
- const OPACITY = 1 << FlagOfset++;
- const COLOR = 1 << FlagOfset++;
- const OPACITY_COLOR = OPACITY | COLOR;
- const RENDER = 1 << FlagOfset++;
- const CHILDREN = 1 << FlagOfset++;
- const POST_RENDER = 1 << FlagOfset++;
- const FINAL = 1 << FlagOfset++;
- const renderFlow = cc["RenderFlow"];
- const _batcher = renderFlow.getBachther();
- let __levelBatcher: { worldMatDirty: number, parentOpacityDirty }[] = [];
- let __renderQueue: cc.Node[][] = [];
- Object.defineProperty(renderFlow.prototype, "_opacity", {
- value: function (node) {
- _batcher.parentOpacityDirty++;
- if (node["__levelRender"] && __levelBatcher[node["__itemIndex"]]) {
- __levelBatcher[node["__itemIndex"]].parentOpacityDirty = 1;
- }
- this._next._func(node);
- node._renderFlag &= ~OPACITY;
- if (node["__levelRender"] && __levelBatcher[node["__itemIndex"]] && node["__lastChildren"]) {
- __levelBatcher[node.__itemIndex].parentOpacityDirty = 0;
- }
- _batcher.parentOpacityDirty--;
- }
- })
- Object.defineProperty(renderFlow.prototype, "_worldTransform", {
- value: function (node) {
- _batcher.worldMatDirty++;
- if (node["__levelRender"] && __levelBatcher[node["__itemIndex"]]) {
- __levelBatcher[node["__itemIndex"]].worldMatDirty = 1;
- }
- let t = node._matrix;
- let trs = node._trs;
- let tm = t.m;
- tm[12] = trs[0];
- tm[13] = trs[1];
- tm[14] = trs[2];
- node._mulMat(node._worldMatrix, node._parent._worldMatrix, t);
- node._renderFlag &= ~WORLD_TRANSFORM;
- this._next._func(node);
- if (node["__levelRender"] && __levelBatcher[node["__itemIndex"]] && node["__lastChildren"]) {
- __levelBatcher[node.__itemIndex].worldMatDirty = 0;
- }
- _batcher.worldMatDirty--;
- }
- });
- const levelSplit = (node: cc.Node, lv: number, itemIndex) => {
- if (!__renderQueue[lv]) {
- __renderQueue[lv] = [];
- }
- __renderQueue[lv].push(node);
- lv++;
- node["__renderLv"] = lv;
- node["__levelRender"] = true;
- node["__itemIndex"] = itemIndex;
- const cs = node.children;
- for (let i = 0; i < cs.length; ++i) {
- const c = cs[i];
- if (!__renderQueue[lv]) {
- __renderQueue[lv] = [];
- }
- lv = levelSplit(c, lv, itemIndex);
- }
- return lv;
- }
- const checkLevelRender = (levelRenderNode: cc.Node) => {
- const cs = levelRenderNode.children;
- let rootOpacityInHierarchy = levelRenderNode["opacity"] / 255;
- __levelBatcher = [];
- for (let i = 0; i < cs.length; ++i) {
- __levelBatcher.push({ worldMatDirty: 0, parentOpacityDirty: 0 });
- levelSplit(cs[i], 0, i);
- }
- while (__renderQueue.length > 0) {
- const list = __renderQueue.shift();
- if (list.length > 0) {
- while (list.length > 0) {
- const n = list.shift();
- n["__lastChildren"] = __renderQueue.length == 0;
- n["__levelRender"] = true;
- let opacityInHierarchy = n.parent["__opacityInHierarchy"];
- if (opacityInHierarchy === undefined) {
- opacityInHierarchy = rootOpacityInHierarchy;
- }
- let opacity = (opacityInHierarchy * (n["_opacity"] / 255));
- n["__opacityInHierarchy"] = opacity;
- let cullingMask = n["_cullingMask"];
- let worldMatDirty = 0;
- if (__levelBatcher[n["__itemIndex"]]) {
- worldMatDirty = __levelBatcher[n["__itemIndex"]].worldMatDirty || 0;
- }
- let parentOpacityDirty = 0;
- if (__levelBatcher[n["__itemIndex"]]) {
- parentOpacityDirty = __levelBatcher[n["__itemIndex"]].parentOpacityDirty || 0;
- }
- let worldTransformFlag = (worldMatDirty || _batcher.worldMatDirty) ? WORLD_TRANSFORM : 0;
- let worldOpacityFlag = (parentOpacityDirty || _batcher.parentOpacityDirty) ? OPACITY_COLOR : 0;
- let worldDirtyFlag = worldTransformFlag | worldOpacityFlag;
- n["_renderFlag"] |= worldDirtyFlag;
- if (!n["_activeInHierarchy"]) continue;
- n["_cullingMask"] = n.groupIndex === 0 ? cullingMask : 1 << n.groupIndex;
- // TODO: Maybe has better way to implement cascade opacity
- let colorVal = n["_color"]._val;
- n["_color"]._fastSetA(n["_opacity"] * opacity);
- renderFlow.flows[n["_renderFlag"]]._func(n);
- n["_color"]._val = colorVal;
- }
- }
- }
- }
- Object.defineProperty(renderFlow.prototype, "_children", {
- value: function (node) {
- if (node.__levelRender) return;
- let cullingMask = node._cullingMask;
- let enableLevelRender = node["__enableLevelRender"];
- const parentOpacityInHierarchy = node.parent ? node.parent["__opacityInHierarchy"] : undefined;
- let parentOpacity = parentOpacityInHierarchy !== undefined ? parentOpacityInHierarchy : _batcher.parentOpacity;
- if (!enableLevelRender && !node.__levelRender) {
- let opacity = (parentOpacity *= (node._opacity / 255));
- node["__opacityInHierarchy"] = opacity;
- let worldTransformFlag = _batcher.worldMatDirty ? WORLD_TRANSFORM : 0;
- let worldOpacityFlag = _batcher.parentOpacityDirty ? OPACITY_COLOR : 0;
- let worldDirtyFlag = worldTransformFlag | worldOpacityFlag;
- let children = node._children;
- for (let i = 0, l = children.length; i < l; i++) {
- let c = children[i];
- // Advance the modification of the flag to avoid node attribute modification is invalid when opacity === 0.
- c._renderFlag |= worldDirtyFlag;
- c["__opacityInHierarchy"] = c._opacity * opacity / 255;
- if (!c._activeInHierarchy || c._opacity === 0) continue;
- c._cullingMask = c.groupIndex === 0 ? cullingMask : 1 << c.groupIndex;
- // TODO: Maybe has better way to implement cascade opacity
- let colorVal = c._color._val;
- c._color._fastSetA(c._opacity * opacity);
- renderFlow.flows[c._renderFlag]._func(c)
- c._color._val = colorVal;
- }
- } else {
- checkLevelRender(node);
- }
- _batcher.parentOpacity = parentOpacity;
- this._next._func(node);
- }
- })
- }
- }
|