实现2.4.11版本
53
2.4.11/.gitignore
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
#/////////////////////////////////////////////////////////////////////////////
|
||||
# Fireball Projects
|
||||
#/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/library/
|
||||
/temp/
|
||||
/local/
|
||||
/build/
|
||||
native
|
||||
#/////////////////////////////////////////////////////////////////////////////
|
||||
# npm files
|
||||
#/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
npm-debug.log
|
||||
node_modules/
|
||||
|
||||
#/////////////////////////////////////////////////////////////////////////////
|
||||
# Logs and databases
|
||||
#/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
*.log
|
||||
*.sql
|
||||
*.sqlite
|
||||
|
||||
#/////////////////////////////////////////////////////////////////////////////
|
||||
# files for debugger
|
||||
#/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
*.sln
|
||||
*.csproj
|
||||
*.pidb
|
||||
*.unityproj
|
||||
*.suo
|
||||
|
||||
#/////////////////////////////////////////////////////////////////////////////
|
||||
# OS generated files
|
||||
#/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
.DS_Store
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
|
||||
#/////////////////////////////////////////////////////////////////////////////
|
||||
# WebStorm files
|
||||
#/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
.idea/
|
||||
|
||||
#//////////////////////////
|
||||
# VS Code files
|
||||
#//////////////////////////
|
||||
|
||||
.vscode/
|
13
2.4.11/assets/lcc-ui-sorting-group.meta
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"ver": "1.1.3",
|
||||
"uuid": "67d51efb-7233-4c27-b96c-386cc3d5e810",
|
||||
"importer": "folder",
|
||||
"isBundle": false,
|
||||
"bundleName": "",
|
||||
"priority": 1,
|
||||
"compressionType": {},
|
||||
"optimizeHotUpdate": {},
|
||||
"inlineSpriteFrames": {},
|
||||
"isRemoteBundle": {},
|
||||
"subMetas": {}
|
||||
}
|
13
2.4.11/assets/lcc-ui-sorting-group/engine-extend.meta
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"ver": "1.1.3",
|
||||
"uuid": "0998106b-40d7-467a-aa96-9eb7bc459a51",
|
||||
"importer": "folder",
|
||||
"isBundle": false,
|
||||
"bundleName": "",
|
||||
"priority": 1,
|
||||
"compressionType": {},
|
||||
"optimizeHotUpdate": {},
|
||||
"inlineSpriteFrames": {},
|
||||
"isRemoteBundle": {},
|
||||
"subMetas": {}
|
||||
}
|
111
2.4.11/assets/lcc-ui-sorting-group/engine-extend/node.ts
Normal file
@ -0,0 +1,111 @@
|
||||
|
||||
//@ts-ignore
|
||||
const nodeMemPool = require('./trans-pool/index').NodeMemPool
|
||||
|
||||
declare module cc {
|
||||
export interface Node {
|
||||
|
||||
/**
|
||||
* 排序优先级 - private
|
||||
*/
|
||||
_sortingPriority:number;
|
||||
|
||||
/**
|
||||
* 排序优先级
|
||||
*/
|
||||
sortingPriority:number;
|
||||
|
||||
/**
|
||||
* 排序优使能 - private
|
||||
*/
|
||||
_sortingEnabled:boolean;
|
||||
|
||||
/**
|
||||
* 排序优使能
|
||||
*/
|
||||
sortingEnabled:boolean;
|
||||
}
|
||||
}
|
||||
|
||||
if(!('sortingPriority' in cc.Node.prototype)){
|
||||
Object.defineProperty(cc.Node.prototype, 'sortingPriority', {
|
||||
get: function() {
|
||||
return this._sortingPriority;
|
||||
},
|
||||
set: function(value) {
|
||||
this._sortingPriority = value;
|
||||
// console.log(`sortingPriority ${this.name} ${value}`);
|
||||
if(CC_JSB){
|
||||
this._sortingPriorityProxy[0] = value;
|
||||
}
|
||||
},
|
||||
enumerable: true
|
||||
});
|
||||
|
||||
Object.defineProperty(cc.Node.prototype, 'sortingEnabled', {
|
||||
get: function() {
|
||||
return this._sortingEnabled;
|
||||
},
|
||||
set: function(value) {
|
||||
this._sortingEnabled = value;
|
||||
// console.log(`sortingEnabled ${this.name} ${value}`);
|
||||
if(CC_JSB){
|
||||
this._sortingEnabledProxy[0] = value ? 1 : 0;
|
||||
}
|
||||
},
|
||||
enumerable: true
|
||||
});
|
||||
}
|
||||
|
||||
if(CC_JSB){
|
||||
//@ts-ignore
|
||||
cc.Node.prototype._initDataFromPool = function(){
|
||||
if (!this._spaceInfo) {
|
||||
if (CC_EDITOR || CC_TEST) {
|
||||
this._spaceInfo = {
|
||||
trs: new Float64Array(10),
|
||||
localMat: new Float64Array(16),
|
||||
worldMat: new Float64Array(16),
|
||||
};
|
||||
} else {
|
||||
this._spaceInfo = nodeMemPool.pop();
|
||||
}
|
||||
}
|
||||
|
||||
let spaceInfo = this._spaceInfo;
|
||||
this._matrix = cc.mat4(spaceInfo.localMat);
|
||||
cc.Mat4.identity(this._matrix);
|
||||
this._worldMatrix = cc.mat4(spaceInfo.worldMat);
|
||||
cc.Mat4.identity(this._worldMatrix);
|
||||
this._localMatDirty = 0xffff;
|
||||
this._worldMatDirty = true;
|
||||
this._sortingPriorityProxy = spaceInfo.sortingPriority;
|
||||
this._sortingEnabledProxy = spaceInfo.sortingEnabled;
|
||||
|
||||
let trs = this._trs = spaceInfo.trs;
|
||||
trs[0] = 0; // position.x
|
||||
trs[1] = 0; // position.y
|
||||
trs[2] = 0; // position.z
|
||||
trs[3] = 0; // rotation.x
|
||||
trs[4] = 0; // rotation.y
|
||||
trs[5] = 0; // rotation.z
|
||||
trs[6] = 1; // rotation.w
|
||||
trs[7] = 1; // scale.x
|
||||
trs[8] = 1; // scale.y
|
||||
trs[9] = 1; // scale.z
|
||||
}
|
||||
|
||||
//@ts-ignore
|
||||
cc.Node.prototype._backDataIntoPool = function() {
|
||||
if (!(CC_EDITOR || CC_TEST)) {
|
||||
// push back to pool
|
||||
nodeMemPool.push(this._spaceInfo);
|
||||
this._sortingPriorityProxy = null;
|
||||
this._sortingEnabledProxy = null;
|
||||
this._matrix = null;
|
||||
this._worldMatrix = null;
|
||||
this._trs = null;
|
||||
this._spaceInfo = null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"uuid": "f0c38288-db93-4468-ab2a-0e3bc2059d15",
|
||||
"importer": "typescript",
|
||||
"isPlugin": false,
|
||||
"loadPluginInWeb": true,
|
||||
"loadPluginInNative": true,
|
||||
"loadPluginInEditor": false,
|
||||
"subMetas": {}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
|
||||
declare module cc {
|
||||
export interface RenderComponent {
|
||||
|
||||
/**
|
||||
* 渲染优先级
|
||||
*/
|
||||
renderPriority:number;
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"uuid": "910f4c68-0289-4422-a65c-6dc64f77511e",
|
||||
"importer": "typescript",
|
||||
"isPlugin": false,
|
||||
"loadPluginInWeb": true,
|
||||
"loadPluginInNative": true,
|
||||
"loadPluginInEditor": false,
|
||||
"subMetas": {}
|
||||
}
|
153
2.4.11/assets/lcc-ui-sorting-group/engine-extend/render-flow.ts
Normal file
@ -0,0 +1,153 @@
|
||||
|
||||
let _batcher;
|
||||
let _cullingMask = 0;
|
||||
|
||||
/**
|
||||
* 当前渲染优先级
|
||||
*/
|
||||
let renderPriority = 0;
|
||||
|
||||
/**
|
||||
* 渲染器缓存
|
||||
*/
|
||||
let rendererCache:cc.RenderComponent[] = [];
|
||||
|
||||
/**
|
||||
* 渲染器排序
|
||||
*/
|
||||
let rendererOrder:boolean = false;
|
||||
|
||||
/**
|
||||
* 刷新渲染缓存
|
||||
*/
|
||||
function flushRendererCache(){
|
||||
if(rendererCache.length > 0){
|
||||
if(rendererOrder){
|
||||
rendererCache.sort((a, b)=>{ return a.renderPriority - b.renderPriority; });
|
||||
}
|
||||
for(let render of rendererCache){
|
||||
// console.log(`${render.node.name} - ${render.renderPriority}`);
|
||||
//@ts-ignore
|
||||
render._checkBacth(_batcher, render.node._cullingMask);
|
||||
//@ts-ignore
|
||||
render._assembler.fillBuffers(render, _batcher);
|
||||
}
|
||||
rendererCache.length = 0;
|
||||
}
|
||||
rendererOrder = false;
|
||||
}
|
||||
|
||||
//@ts-ignore
|
||||
cc.RenderFlow.visitRootNode = function (rootNode){
|
||||
renderPriority = 0;
|
||||
rendererCache.length = 0;
|
||||
rendererOrder = false;
|
||||
|
||||
//@ts-ignore
|
||||
_batcher = cc.RenderFlow.getBachther();
|
||||
|
||||
//@ts-ignore
|
||||
cc.RenderFlow.validateRenderers();
|
||||
|
||||
let preCullingMask = _cullingMask;
|
||||
_cullingMask = rootNode._cullingMask;
|
||||
|
||||
//@ts-ignore
|
||||
if (rootNode._renderFlag & cc.RenderFlow.FLAG_WORLD_TRANSFORM) {
|
||||
_batcher.worldMatDirty ++;
|
||||
rootNode._calculWorldMatrix();
|
||||
//@ts-ignore
|
||||
rootNode._renderFlag &= ~cc.RenderFlow.FLAG_WORLD_TRANSFORM;
|
||||
|
||||
//@ts-ignore
|
||||
cc.RenderFlow.flows[rootNode._renderFlag]._func(rootNode);
|
||||
flushRendererCache();
|
||||
|
||||
_batcher.worldMatDirty --;
|
||||
}
|
||||
else {
|
||||
//@ts-ignore
|
||||
cc.RenderFlow.flows[rootNode._renderFlag]._func(rootNode);
|
||||
flushRendererCache();
|
||||
}
|
||||
|
||||
_cullingMask = preCullingMask;
|
||||
}
|
||||
|
||||
//@ts-ignore
|
||||
cc.RenderFlow.prototype._render = function (node) {
|
||||
let comp = node._renderComponent;
|
||||
if(comp instanceof cc.Mask){
|
||||
flushRendererCache();
|
||||
|
||||
//@ts-ignore
|
||||
comp._checkBacth(_batcher, node._cullingMask);
|
||||
//@ts-ignore
|
||||
comp._assembler.fillBuffers(comp, _batcher);
|
||||
}else{
|
||||
if (_batcher.worldMatDirty && comp._assembler.updateWorldVerts) {
|
||||
comp._assembler.updateWorldVerts(comp);
|
||||
}
|
||||
rendererCache.push(comp);
|
||||
comp.renderPriority = node._sortingEnabled ? node._sortingPriority : renderPriority;
|
||||
if(renderPriority != 0){
|
||||
rendererOrder = true;
|
||||
}
|
||||
}
|
||||
this._next._func(node);
|
||||
};
|
||||
|
||||
//@ts-ignore
|
||||
cc.RenderFlow.prototype._postRender = function (node) {
|
||||
let comp = node._renderComponent;
|
||||
if(comp instanceof cc.Mask){
|
||||
flushRendererCache();
|
||||
}
|
||||
comp._checkBacth(_batcher, node._cullingMask);
|
||||
comp._assembler.postFillBuffers(comp, _batcher);
|
||||
this._next._func(node);
|
||||
};
|
||||
|
||||
//@ts-ignore
|
||||
cc.RenderFlow.prototype._children = function (node) {
|
||||
let cullingMask = _cullingMask;
|
||||
let batcher = _batcher;
|
||||
|
||||
let preRenderPriority = renderPriority;
|
||||
|
||||
let parentOpacity = batcher.parentOpacity;
|
||||
let opacity = (batcher.parentOpacity *= (node._opacity / 255));
|
||||
|
||||
renderPriority = node._sortingEnabled ? node._sortingPriority : renderPriority;
|
||||
// console.log(`${node.name} ${renderPriority}`);
|
||||
|
||||
//@ts-ignore
|
||||
let worldTransformFlag = batcher.worldMatDirty ? cc.RenderFlow.FLAG_WORLD_TRANSFORM : 0;
|
||||
//@ts-ignore
|
||||
let worldOpacityFlag = batcher.parentOpacityDirty ? cc.RenderFlow.FLAG_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;
|
||||
if (!c._activeInHierarchy || c._opacity === 0) continue;
|
||||
|
||||
_cullingMask = 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);
|
||||
// @ts-ignore
|
||||
cc.RenderFlow.flows[c._renderFlag]._func(c);
|
||||
c._color._val = colorVal;
|
||||
}
|
||||
|
||||
batcher.parentOpacity = parentOpacity;
|
||||
|
||||
renderPriority = preRenderPriority;
|
||||
|
||||
this._next._func(node);
|
||||
};
|
@ -0,0 +1,10 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"uuid": "d9ee1293-73e0-4588-a058-685d75be1912",
|
||||
"importer": "typescript",
|
||||
"isPlugin": false,
|
||||
"loadPluginInWeb": true,
|
||||
"loadPluginInNative": true,
|
||||
"loadPluginInEditor": false,
|
||||
"subMetas": {}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
{
|
||||
"ver": "1.1.3",
|
||||
"uuid": "10d7cfa4-65ae-4b25-8725-2630ae630cd3",
|
||||
"importer": "folder",
|
||||
"isBundle": false,
|
||||
"bundleName": "",
|
||||
"priority": 1,
|
||||
"compressionType": {},
|
||||
"optimizeHotUpdate": {},
|
||||
"inlineSpriteFrames": {},
|
||||
"isRemoteBundle": {},
|
||||
"subMetas": {}
|
||||
}
|
@ -1,19 +1,18 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
Copyright (c) 2019 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You
|
||||
shall not use Cocos Creator software for developing other software or tools
|
||||
that's used for developing games. You are not granted to publish, distribute,
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to
|
||||
you.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
@ -23,22 +22,10 @@
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include "cocos/cocos.h"
|
||||
let NodeUnit = require('./node-unit');
|
||||
let NodeMemPool = require('./node-mem-pool');
|
||||
|
||||
/**
|
||||
@brief The cocos2d Application.
|
||||
|
||||
The reason for implement as private inheritance is to hide some interface call
|
||||
by Director.
|
||||
*/
|
||||
class Game : public cc::BaseGame {
|
||||
public:
|
||||
Game();
|
||||
int init() override;
|
||||
// bool init() override;
|
||||
void onPause() override;
|
||||
void onResume() override;
|
||||
void onClose() override;
|
||||
};
|
||||
module.exports = {
|
||||
NodeMemPool: new NodeMemPool(NodeUnit)
|
||||
};
|
@ -0,0 +1,10 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"uuid": "eb098cc5-0be2-48ee-8103-989d20216bda",
|
||||
"importer": "javascript",
|
||||
"isPlugin": false,
|
||||
"loadPluginInWeb": true,
|
||||
"loadPluginInNative": true,
|
||||
"loadPluginInEditor": false,
|
||||
"subMetas": {}
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
let MemPool = function (unitClass) {
|
||||
this._unitClass = unitClass;
|
||||
this._pool = [];
|
||||
this._findOrder = [];
|
||||
|
||||
if (CC_JSB && CC_NATIVERENDERER) {
|
||||
this._initNative();
|
||||
}
|
||||
};
|
||||
|
||||
let proto = MemPool.prototype;
|
||||
proto._initNative = function () {
|
||||
this._nativeMemPool = new renderer.MemPool();
|
||||
};
|
||||
|
||||
proto._buildUnit = function (unitID) {
|
||||
let unit = new this._unitClass(unitID, this);
|
||||
if (CC_JSB && CC_NATIVERENDERER) {
|
||||
this._nativeMemPool.updateCommonData(unitID, unit._data, unit._signData);
|
||||
}
|
||||
return unit;
|
||||
};
|
||||
|
||||
proto._destroyUnit = function (unitID) {
|
||||
this._pool[unitID] = null;
|
||||
for (let idx = 0, n = this._findOrder.length; idx < n; idx++) {
|
||||
let unit = this._findOrder[idx];
|
||||
if (unit && unit.unitID == unitID) {
|
||||
this._findOrder.splice(idx, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (CC_JSB && CC_NATIVERENDERER) {
|
||||
this._nativeMemPool.removeCommonData(unitID);
|
||||
}
|
||||
};
|
||||
|
||||
proto._findUnitID = function () {
|
||||
let unitID = 0;
|
||||
let pool = this._pool;
|
||||
while (pool[unitID]) unitID++;
|
||||
return unitID;
|
||||
};
|
||||
|
||||
proto.pop = function () {
|
||||
let findUnit = null;
|
||||
let idx = 0;
|
||||
let findOrder = this._findOrder;
|
||||
let pool = this._pool;
|
||||
for (let n = findOrder.length; idx < n; idx++) {
|
||||
let unit = findOrder[idx];
|
||||
if (unit && unit.hasSpace()) {
|
||||
findUnit = unit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!findUnit) {
|
||||
let unitID = this._findUnitID();
|
||||
findUnit = this._buildUnit(unitID);
|
||||
pool[unitID] = findUnit;
|
||||
findOrder.push(findUnit);
|
||||
idx = findOrder.length - 1;
|
||||
}
|
||||
|
||||
// swap has space unit to first position, so next find will fast
|
||||
let firstUnit = findOrder[0];
|
||||
if (firstUnit !== findUnit) {
|
||||
findOrder[0] = findUnit;
|
||||
findOrder[idx] = firstUnit;
|
||||
}
|
||||
|
||||
return findUnit.pop();
|
||||
};
|
||||
|
||||
proto.push = function (info) {
|
||||
let unit = this._pool[info.unitID];
|
||||
unit.push(info.index);
|
||||
if (this._findOrder.length > 1 && unit.isAllFree()) {
|
||||
this._destroyUnit(info.unitID);
|
||||
}
|
||||
return unit;
|
||||
};
|
||||
module.exports = MemPool;
|
@ -0,0 +1,10 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"uuid": "13cfc2d4-b859-42dc-917a-561662386b76",
|
||||
"importer": "javascript",
|
||||
"isPlugin": false,
|
||||
"loadPluginInWeb": true,
|
||||
"loadPluginInNative": true,
|
||||
"loadPluginInEditor": false,
|
||||
"subMetas": {}
|
||||
}
|
@ -1,19 +1,18 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
Copyright (c) 2019 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You
|
||||
shall not use Cocos Creator software for developing other software or tools
|
||||
that's used for developing games. You are not granted to publish, distribute,
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to
|
||||
you.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
@ -23,43 +22,28 @@
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
#include "Game.h"
|
||||
|
||||
#ifndef GAME_NAME
|
||||
#define GAME_NAME "CocosGame";
|
||||
#endif
|
||||
let MemPool = require('./mem-pool');
|
||||
let NodeMemPool = function (unitClass) {
|
||||
MemPool.call(this, unitClass);
|
||||
};
|
||||
|
||||
#ifndef SCRIPT_XXTEAKEY
|
||||
#define SCRIPT_XXTEAKEY "";
|
||||
#endif
|
||||
(function(){
|
||||
let Super = function(){};
|
||||
Super.prototype = MemPool.prototype;
|
||||
NodeMemPool.prototype = new Super();
|
||||
})();
|
||||
|
||||
Game::Game() = default;
|
||||
let proto = NodeMemPool.prototype;
|
||||
proto._initNative = function () {
|
||||
this._nativeMemPool = new renderer.NodeMemPool();
|
||||
};
|
||||
|
||||
int Game::init() {
|
||||
_windowInfo.title = GAME_NAME;
|
||||
// configurate window size
|
||||
// _windowInfo.height = 600;
|
||||
// _windowInfo.width = 800;
|
||||
proto._destroyUnit = function (unitID) {
|
||||
MemPool.prototype._destroyUnit.call(this, unitID);
|
||||
if (CC_JSB && CC_NATIVERENDERER) {
|
||||
this._nativeMemPool.removeNodeData(unitID);
|
||||
}
|
||||
};
|
||||
|
||||
#if CC_DEBUG
|
||||
_debuggerInfo.enabled = true;
|
||||
#else
|
||||
_debuggerInfo.enabled = false;
|
||||
#endif
|
||||
_debuggerInfo.port = 6086;
|
||||
_debuggerInfo.address = "0.0.0.0";
|
||||
_debuggerInfo.pauseOnStart = false;
|
||||
|
||||
_xxteaKey = SCRIPT_XXTEAKEY;
|
||||
|
||||
BaseGame::init();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Game::onPause() { BaseGame::onPause(); }
|
||||
|
||||
void Game::onResume() { BaseGame::onResume(); }
|
||||
|
||||
void Game::onClose() { BaseGame::onClose(); }
|
||||
|
||||
CC_REGISTER_APPLICATION(Game);
|
||||
module.exports = NodeMemPool;
|
@ -0,0 +1,10 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"uuid": "caa4d37a-9df4-4a7b-9407-eafa3c27df76",
|
||||
"importer": "javascript",
|
||||
"isPlugin": false,
|
||||
"loadPluginInWeb": true,
|
||||
"loadPluginInNative": true,
|
||||
"loadPluginInEditor": false,
|
||||
"subMetas": {}
|
||||
}
|
@ -0,0 +1,158 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
const FLOAT_ARRAY_TYPE = (CC_JSB && CC_NATIVERENDERER) ? Float32Array : Float64Array;
|
||||
const FLOAT_BYTES = (CC_JSB && CC_NATIVERENDERER) ? 4 : 8;
|
||||
|
||||
const Uint32_Bytes = 4;
|
||||
const Uint8_Bytes = 1;
|
||||
|
||||
// Space : [Dirty] [Size:4 Uint32]
|
||||
const Dirty_Type = Uint32Array;
|
||||
const Dirty_Members = 1;
|
||||
const Dirty_Stride = Dirty_Members * Uint32_Bytes;
|
||||
|
||||
// Space : [TRS] [Size:4 * 10 Float32|Float64]
|
||||
const TRS_Members = 10;
|
||||
const TRS_Stride = TRS_Members * FLOAT_BYTES;
|
||||
|
||||
// Space : [LocalMatrix] [Size:4 * 16 Float32|Float64]
|
||||
const LocalMatrix_Members = 16;
|
||||
const LocalMatrix_Stride = LocalMatrix_Members * FLOAT_BYTES;
|
||||
|
||||
// Space : [WorldMatrix] [Size:4 * 16 Float32|Float64]
|
||||
const WorldMatrix_Members = 16;
|
||||
const WorldMatrix_Stride = WorldMatrix_Members * FLOAT_BYTES;
|
||||
|
||||
// Space : [sortingPriority] [Size:4 * 1 Float32|Float64]
|
||||
const SortingPriority_Members = 1;
|
||||
const SortingPriority_Stride = SortingPriority_Members * FLOAT_BYTES;
|
||||
|
||||
// Space : [Parent Unit] [Size:4 Uint32]
|
||||
// Space : [Parent Index] [Size:4 Uint32]
|
||||
const Parent_Type = Uint32Array;
|
||||
const Parent_Members = 2;
|
||||
const Parent_Stride = Parent_Members * Uint32_Bytes;
|
||||
|
||||
// Space : [ZOrder] [Size:4 Uint32]
|
||||
const ZOrder_Type = Uint32Array;
|
||||
const ZOrder_Members = 1;
|
||||
const ZOrder_Stride = ZOrder_Members * Uint32_Bytes;
|
||||
|
||||
// Space : [CullingMask] [Size:4 Int32]
|
||||
const CullingMask_Type = Int32Array;
|
||||
const CullingMask_Members = 1;
|
||||
const CullingMask_Stride = CullingMask_Members * Uint32_Bytes;
|
||||
|
||||
// Space : [Opacity] [Size:1 Uint8]
|
||||
const Opacity_Type = Uint8Array;
|
||||
const Opacity_Members = 1;
|
||||
const Opacity_Stride = Opacity_Members * Uint8_Bytes;
|
||||
|
||||
// Space : [Is3D] [Size:1 Uint8]
|
||||
const Is3D_Type = Uint8Array;
|
||||
const Is3D_Members = 1;
|
||||
const Is3D_Stride = Is3D_Members * Uint8_Bytes;
|
||||
|
||||
// Space : [sortingEnabled] [Size:1 Uint8]
|
||||
const SortingEnabled_Type = Uint8Array;
|
||||
const SortingEnabled_Members = 1;
|
||||
const SortingEnabled_Stride = SortingEnabled_Members * Uint8_Bytes;
|
||||
|
||||
// Space : [NodePtr] [Size:4 * 2 Uint32]
|
||||
const Node_Type = Uint32Array;
|
||||
const Node_Members = 2;
|
||||
|
||||
// Space : [Skew] [Size:4 * 2 Float32]
|
||||
const Skew_Members = 2;
|
||||
const Skew_Stride = Skew_Members * FLOAT_BYTES;
|
||||
|
||||
let UnitBase = require('./unit-base');
|
||||
let NodeUnit = function (unitID, memPool) {
|
||||
UnitBase.call(this, unitID, memPool);
|
||||
|
||||
let contentNum = this._contentNum;
|
||||
this.trsList = new FLOAT_ARRAY_TYPE(contentNum * TRS_Members);
|
||||
this.localMatList = new FLOAT_ARRAY_TYPE(contentNum * LocalMatrix_Members);
|
||||
this.worldMatList = new FLOAT_ARRAY_TYPE(contentNum * WorldMatrix_Members);
|
||||
|
||||
if (CC_JSB && CC_NATIVERENDERER) {
|
||||
this.dirtyList = new Dirty_Type(contentNum * Dirty_Members);
|
||||
this.parentList = new Parent_Type(contentNum * Parent_Members);
|
||||
this.zOrderList = new ZOrder_Type(contentNum * ZOrder_Members);
|
||||
this.cullingMaskList = new CullingMask_Type(contentNum * CullingMask_Members);
|
||||
this.opacityList = new Opacity_Type(contentNum * Opacity_Members);
|
||||
this.is3DList = new Is3D_Type(contentNum * Is3D_Members);
|
||||
this.nodeList = new Node_Type(contentNum * Node_Members);
|
||||
this.skewList = new FLOAT_ARRAY_TYPE(contentNum * Skew_Members);
|
||||
this.sortingPriorityList = new FLOAT_ARRAY_TYPE(contentNum * SortingPriority_Stride);
|
||||
this.sortingEnabledList = new SortingEnabled_Type(contentNum * SortingEnabled_Stride);
|
||||
|
||||
this._memPool._nativeMemPool.updateNodeData(
|
||||
unitID,
|
||||
this.dirtyList,
|
||||
this.trsList,
|
||||
this.localMatList,
|
||||
this.worldMatList,
|
||||
this.parentList,
|
||||
this.zOrderList,
|
||||
this.cullingMaskList,
|
||||
this.opacityList,
|
||||
this.is3DList,
|
||||
this.nodeList,
|
||||
this.skewList,
|
||||
this.sortingPriorityList,
|
||||
this.sortingEnabledList
|
||||
);
|
||||
}
|
||||
|
||||
for (let i = 0; i < contentNum; i ++) {
|
||||
let space = this._spacesData[i];
|
||||
|
||||
space.trs = new FLOAT_ARRAY_TYPE(this.trsList.buffer, i * TRS_Stride, TRS_Members);
|
||||
space.localMat = new FLOAT_ARRAY_TYPE(this.localMatList.buffer, i * LocalMatrix_Stride, LocalMatrix_Members);
|
||||
space.worldMat = new FLOAT_ARRAY_TYPE(this.worldMatList.buffer, i * WorldMatrix_Stride, WorldMatrix_Members);
|
||||
|
||||
if (CC_JSB && CC_NATIVERENDERER) {
|
||||
space.dirty = new Dirty_Type(this.dirtyList.buffer, i * Dirty_Stride, Dirty_Members);
|
||||
space.parent = new Parent_Type(this.parentList.buffer, i * Parent_Stride, Parent_Members);
|
||||
space.zOrder = new ZOrder_Type(this.zOrderList.buffer, i * ZOrder_Stride, ZOrder_Members);
|
||||
space.cullingMask = new CullingMask_Type(this.cullingMaskList.buffer, i * CullingMask_Stride, CullingMask_Members);
|
||||
space.opacity = new Opacity_Type(this.opacityList.buffer, i * Opacity_Stride, Opacity_Members);
|
||||
space.is3D = new Is3D_Type(this.is3DList.buffer, i * Is3D_Stride, Is3D_Members);
|
||||
space.skew = new FLOAT_ARRAY_TYPE(this.skewList.buffer, i * Skew_Stride, Skew_Members);
|
||||
space.sortingPriority = new FLOAT_ARRAY_TYPE(this.sortingPriorityList.buffer, i * SortingPriority_Stride, SortingPriority_Members);
|
||||
space.sortingEnabled = new SortingEnabled_Type(this.sortingEnabledList.buffer, i * SortingEnabled_Stride, SortingEnabled_Members);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
(function(){
|
||||
let Super = function(){};
|
||||
Super.prototype = UnitBase.prototype;
|
||||
NodeUnit.prototype = new Super();
|
||||
})();
|
||||
|
||||
module.exports = NodeUnit;
|
@ -0,0 +1,10 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"uuid": "3e3243b6-45a4-4eec-9abb-805de55e8b1f",
|
||||
"importer": "javascript",
|
||||
"isPlugin": false,
|
||||
"loadPluginInWeb": true,
|
||||
"loadPluginInNative": true,
|
||||
"loadPluginInEditor": false,
|
||||
"subMetas": {}
|
||||
}
|
@ -0,0 +1,167 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
// Unit has many segment, layout such as :
|
||||
// Head Free Pointer + Using Segment Num + Segment 1 + Segment 2 + Segment 3 ...
|
||||
|
||||
// sign data format
|
||||
// Space : [If Free Flag] [Size:1 Uint16]
|
||||
// Space : [Next Free Index] [Size:1 Uint16]
|
||||
|
||||
// invalid pointer value
|
||||
let POINTER_INVALID_FLAG = 0xffff;
|
||||
let SPACE_FREE_FLAG = 0x0;
|
||||
let SPACE_USE_FLAG = 0x1;
|
||||
let POS_NEXT_FREE = 0;
|
||||
let POS_FREE_FLAG = 1;
|
||||
|
||||
let UnitBase = function (unitID, memPool, contentNum) {
|
||||
contentNum = contentNum || 128;
|
||||
|
||||
// set unit id
|
||||
this.unitID = unitID;
|
||||
this._memPool = memPool;
|
||||
|
||||
this._data = new Uint16Array(2);
|
||||
// head of the free content index
|
||||
this._data[0] = 0;
|
||||
// using segment num
|
||||
this._data[1] = 0;
|
||||
|
||||
this._contentNum = contentNum;
|
||||
this._signData = new Uint16Array(this._contentNum * 2);
|
||||
this._spacesData = [];
|
||||
|
||||
for (let i = 0; i < contentNum; i++) {
|
||||
let signIndex = i * 2;
|
||||
// store content block index but not sign array index
|
||||
this._signData[signIndex + POS_NEXT_FREE] = i + 1;
|
||||
this._signData[signIndex + POS_FREE_FLAG] = SPACE_FREE_FLAG;
|
||||
|
||||
this._spacesData[i] = {
|
||||
index: i,
|
||||
unitID: unitID,
|
||||
};
|
||||
}
|
||||
// last one has no next space;
|
||||
this._signData[(contentNum - 1) * 2] = POINTER_INVALID_FLAG;
|
||||
};
|
||||
|
||||
let UnitBaseProto = UnitBase.prototype;
|
||||
UnitBaseProto.hasSpace = function () {
|
||||
return this._data[0] !== POINTER_INVALID_FLAG;
|
||||
};
|
||||
|
||||
UnitBaseProto.isAllFree = function () {
|
||||
return this._data[1] == 0;
|
||||
};
|
||||
|
||||
// pop space from unit
|
||||
UnitBaseProto.pop = function () {
|
||||
let headFreeIndex = this._data[0];
|
||||
if (headFreeIndex === POINTER_INVALID_FLAG) return null;
|
||||
|
||||
let index = headFreeIndex;
|
||||
let signIndex = index * 2;
|
||||
let space = this._spacesData[index];
|
||||
|
||||
// set use flag
|
||||
this._signData[signIndex + POS_FREE_FLAG] = SPACE_USE_FLAG;
|
||||
|
||||
// store new next free space index
|
||||
this._data[0] = this._signData[signIndex + POS_NEXT_FREE];
|
||||
// add using segment num
|
||||
this._data[1]++;
|
||||
return space;
|
||||
};
|
||||
|
||||
// push back to unit
|
||||
UnitBaseProto.push = function (index) {
|
||||
let signIndex = index * 2;
|
||||
|
||||
// set free flag
|
||||
this._signData[signIndex + POS_FREE_FLAG] = SPACE_FREE_FLAG;
|
||||
|
||||
// store head free index to the space
|
||||
this._signData[signIndex + POS_NEXT_FREE] = this._data[0];
|
||||
// update head free index
|
||||
this._data[0] = index;
|
||||
// sub using segment num
|
||||
this._data[1]--;
|
||||
};
|
||||
|
||||
// dump all space info
|
||||
UnitBaseProto.dump = function () {
|
||||
let spaceNum = 0;
|
||||
let index = this._data[0];
|
||||
let freeStr = "";
|
||||
|
||||
while (index != POINTER_INVALID_FLAG) {
|
||||
spaceNum ++;
|
||||
freeStr += index + "->";
|
||||
index = this._signData[index * 2 + POS_NEXT_FREE];
|
||||
}
|
||||
|
||||
let usingNum = 0;
|
||||
let usingStr = "";
|
||||
let contentNum = this._contentNum;
|
||||
for (let i = 0; i < contentNum; i++) {
|
||||
let freeFlag = this._signData[i * 2 + POS_FREE_FLAG];
|
||||
if (freeFlag == SPACE_USE_FLAG) {
|
||||
usingNum ++;
|
||||
usingStr += i + "->";
|
||||
}
|
||||
}
|
||||
|
||||
let totalNum = spaceNum + usingNum;
|
||||
console.log(
|
||||
"unitID:", this.unitID,
|
||||
"spaceNum:", spaceNum,
|
||||
"calc using num:", usingNum,
|
||||
'store using num:', this._data[1],
|
||||
'calc total num:', totalNum,
|
||||
'actually total num:', this._contentNum
|
||||
);
|
||||
console.log("free info:", freeStr);
|
||||
console.log("using info:", usingStr);
|
||||
|
||||
if (usingNum != this._data[1]) {
|
||||
cc.error(
|
||||
'using num error',
|
||||
"calc using num:", usingNum,
|
||||
'store using num:', this._data[1]
|
||||
);
|
||||
}
|
||||
|
||||
if (spaceNum + usingNum != this._contentNum) {
|
||||
cc.error(
|
||||
'total num error',
|
||||
'calc total num:', totalNum,
|
||||
'actually total num:', this._contentNum
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = UnitBase;
|
@ -0,0 +1,10 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"uuid": "b1e0a00c-ca02-49ba-9561-19c4ca3078df",
|
||||
"importer": "javascript",
|
||||
"isPlugin": false,
|
||||
"loadPluginInWeb": true,
|
||||
"loadPluginInNative": true,
|
||||
"loadPluginInEditor": false,
|
||||
"subMetas": {}
|
||||
}
|
10
2.4.11/assets/lcc-ui-sorting-group/sorting-define.ts.meta
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"uuid": "8f6e89ff-d851-45d4-bab8-d32cd5371760",
|
||||
"importer": "typescript",
|
||||
"isPlugin": false,
|
||||
"loadPluginInWeb": true,
|
||||
"loadPluginInNative": true,
|
||||
"loadPluginInEditor": false,
|
||||
"subMetas": {}
|
||||
}
|
55
2.4.11/assets/lcc-ui-sorting-group/sorting-group.ts
Normal file
@ -0,0 +1,55 @@
|
||||
|
||||
import { ORDER_IN_LAYER_MAX, SortingLayer } from './sorting-define';
|
||||
|
||||
const { ccclass, property, disallowMultiple, executeInEditMode } = cc._decorator;
|
||||
|
||||
@ccclass('lcc-ui/SortingGroup')
|
||||
@disallowMultiple()
|
||||
@executeInEditMode()
|
||||
export class SortingGroup extends cc.Component {
|
||||
/**
|
||||
* 排序层
|
||||
*/
|
||||
@property({type: cc.Enum(SortingLayer)})
|
||||
private _sortingLayer:SortingLayer = SortingLayer.DEFAULT;
|
||||
|
||||
/**
|
||||
* 排序层
|
||||
*/
|
||||
@property({type: cc.Enum(SortingLayer)})
|
||||
get sortingLayer(){
|
||||
return this._sortingLayer;
|
||||
}
|
||||
set sortingLayer(value:SortingLayer){
|
||||
this._sortingLayer = value;
|
||||
// this.node.sortingPriority = Math.sign(this._sortingLayer) * (Math.abs(this._sortingLayer) * ORDER_IN_LAYER_MAX + this._orderInLayer);
|
||||
}
|
||||
|
||||
/**
|
||||
* 排序值
|
||||
*/
|
||||
@property({ type:cc.Float, min: 0, max : ORDER_IN_LAYER_MAX })
|
||||
private _orderInLayer:number = 0;
|
||||
|
||||
/**
|
||||
* 排序值
|
||||
*/
|
||||
@property({ type:cc.Float, min: 0, max : ORDER_IN_LAYER_MAX })
|
||||
get orderInLayer(){
|
||||
return this._orderInLayer;
|
||||
}
|
||||
set orderInLayer(value:number){
|
||||
this._orderInLayer = value;
|
||||
// this.node.sortingPriority = Math.sign(this._sortingLayer) * (Math.abs(this._sortingLayer) * ORDER_IN_LAYER_MAX + this._orderInLayer);
|
||||
}
|
||||
|
||||
onEnable(){
|
||||
this.node.sortingPriority = Math.sign(this._sortingLayer) * (Math.abs(this._sortingLayer) * ORDER_IN_LAYER_MAX + this._orderInLayer);
|
||||
this.node.sortingEnabled = true;
|
||||
}
|
||||
|
||||
onDisable(){
|
||||
this.node.sortingPriority = 0;
|
||||
this.node.sortingEnabled = false;
|
||||
}
|
||||
}
|
10
2.4.11/assets/lcc-ui-sorting-group/sorting-group.ts.meta
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"uuid": "ac8d9166-422c-4cd3-a0be-0bdcddb52da2",
|
||||
"importer": "typescript",
|
||||
"isPlugin": false,
|
||||
"loadPluginInWeb": true,
|
||||
"loadPluginInNative": true,
|
||||
"loadPluginInEditor": false,
|
||||
"subMetas": {}
|
||||
}
|
13
2.4.11/assets/test.meta
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"ver": "1.1.3",
|
||||
"uuid": "d29d0f8f-d7b1-4b60-a834-224ebe63fb72",
|
||||
"importer": "folder",
|
||||
"isBundle": false,
|
||||
"bundleName": "",
|
||||
"priority": 1,
|
||||
"compressionType": {},
|
||||
"optimizeHotUpdate": {},
|
||||
"inlineSpriteFrames": {},
|
||||
"isRemoteBundle": {},
|
||||
"subMetas": {}
|
||||
}
|
13
2.4.11/assets/test/prefabs.meta
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"ver": "1.1.3",
|
||||
"uuid": "b5d585a3-e6d1-4710-aa13-dc6f42f7bbd1",
|
||||
"importer": "folder",
|
||||
"isBundle": false,
|
||||
"bundleName": "",
|
||||
"priority": 1,
|
||||
"compressionType": {},
|
||||
"optimizeHotUpdate": {},
|
||||
"inlineSpriteFrames": {},
|
||||
"isRemoteBundle": {},
|
||||
"subMetas": {}
|
||||
}
|
1322
2.4.11/assets/test/prefabs/ListTestItem-sorting.prefab
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.3.2",
|
||||
"uuid": "5319446a-3497-48fc-99a7-9806589fd3c6",
|
||||
"importer": "prefab",
|
||||
"optimizationPolicy": "AUTO",
|
||||
"asyncLoadAssets": false,
|
||||
"readonly": false,
|
||||
"subMetas": {}
|
||||
}
|
1172
2.4.11/assets/test/prefabs/ListTestItem.prefab
Normal file
9
2.4.11/assets/test/prefabs/ListTestItem.prefab.meta
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.3.2",
|
||||
"uuid": "77b9c6bb-79b1-4086-86fa-ac30b56d67cc",
|
||||
"importer": "prefab",
|
||||
"optimizationPolicy": "AUTO",
|
||||
"asyncLoadAssets": false,
|
||||
"readonly": false,
|
||||
"subMetas": {}
|
||||
}
|
13
2.4.11/assets/test/scenes.meta
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"ver": "1.1.3",
|
||||
"uuid": "e2dc59cc-2d8b-4b93-adab-48a29cdcf581",
|
||||
"importer": "folder",
|
||||
"isBundle": false,
|
||||
"bundleName": "",
|
||||
"priority": 1,
|
||||
"compressionType": {},
|
||||
"optimizeHotUpdate": {},
|
||||
"inlineSpriteFrames": {},
|
||||
"isRemoteBundle": {},
|
||||
"subMetas": {}
|
||||
}
|
1124
2.4.11/assets/test/scenes/test-scene-sorting.fire
Normal file
8
2.4.11/assets/test/scenes/test-scene-sorting.fire.meta
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"ver": "1.3.2",
|
||||
"uuid": "c6ba3258-b873-4d4f-b31a-60f4c79e523a",
|
||||
"importer": "scene",
|
||||
"asyncLoadAssets": false,
|
||||
"autoReleaseAssets": false,
|
||||
"subMetas": {}
|
||||
}
|
1124
2.4.11/assets/test/scenes/test-scene.fire
Normal file
8
2.4.11/assets/test/scenes/test-scene.fire.meta
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"ver": "1.3.2",
|
||||
"uuid": "6b1f9620-447d-4dcc-aeac-09aca68c29e7",
|
||||
"importer": "scene",
|
||||
"asyncLoadAssets": false,
|
||||
"autoReleaseAssets": false,
|
||||
"subMetas": {}
|
||||
}
|
13
2.4.11/assets/test/scripts.meta
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"ver": "1.1.3",
|
||||
"uuid": "845ea615-d321-4ea5-ab0e-4c6292a58d18",
|
||||
"importer": "folder",
|
||||
"isBundle": false,
|
||||
"bundleName": "",
|
||||
"priority": 1,
|
||||
"compressionType": {},
|
||||
"optimizeHotUpdate": {},
|
||||
"inlineSpriteFrames": {},
|
||||
"isRemoteBundle": {},
|
||||
"subMetas": {}
|
||||
}
|
43
2.4.11/assets/test/scripts/list-test-item.ts
Normal file
@ -0,0 +1,43 @@
|
||||
// Learn TypeScript:
|
||||
// - https://docs.cocos.com/creator/2.4/manual/en/scripting/typescript.html
|
||||
// Learn Attribute:
|
||||
// - https://docs.cocos.com/creator/2.4/manual/en/scripting/reference/attributes.html
|
||||
// Learn life-cycle callbacks:
|
||||
// - https://docs.cocos.com/creator/2.4/manual/en/scripting/life-cycle-callbacks.html
|
||||
|
||||
const {ccclass, property} = cc._decorator;
|
||||
|
||||
@ccclass
|
||||
export default class ListTestItem extends cc.Component {
|
||||
|
||||
@property({type: cc.Label})
|
||||
rankText:cc.Label = null;
|
||||
|
||||
@property({type: cc.Label})
|
||||
goldText:cc.Label = null;
|
||||
|
||||
@property({type: cc.Sprite})
|
||||
flagImage:cc.Sprite = null;
|
||||
|
||||
@property({type: cc.Label})
|
||||
levelText:cc.Label = null;
|
||||
|
||||
@property({type: cc.ProgressBar})
|
||||
levelBar:cc.ProgressBar = null;
|
||||
|
||||
@property({type: cc.Label})
|
||||
descText:cc.Label = null;
|
||||
|
||||
@property({type: cc.Node})
|
||||
uiOpacity:cc.Node = null;
|
||||
|
||||
randomData(index:number, flagSpriteFrame:cc.SpriteFrame){
|
||||
this.rankText.string = String(index);
|
||||
this.goldText.string = String(Math.floor(1000 + Math.random()* 1000));
|
||||
this.flagImage.spriteFrame = flagSpriteFrame;
|
||||
this.levelText.string = `lv.${Math.floor(Math.random()* 100)}`;
|
||||
this.levelBar.progress = Math.random();
|
||||
this.descText.string = `什么也没留下 - ${index}`;
|
||||
this.uiOpacity.opacity = 100 + Math.floor(Math.random() * 155);
|
||||
}
|
||||
}
|
10
2.4.11/assets/test/scripts/list-test-item.ts.meta
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"uuid": "9f5387d6-696a-4491-82ea-1a443403ed3c",
|
||||
"importer": "typescript",
|
||||
"isPlugin": false,
|
||||
"loadPluginInWeb": true,
|
||||
"loadPluginInNative": true,
|
||||
"loadPluginInEditor": false,
|
||||
"subMetas": {}
|
||||
}
|
28
2.4.11/assets/test/scripts/test-scene.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import ListTestItem from "./list-test-item";
|
||||
|
||||
const { ccclass, property } = cc._decorator;
|
||||
|
||||
@ccclass
|
||||
export class TestScene extends cc.Component {
|
||||
|
||||
@property({type:cc.Prefab})
|
||||
listTestItemPrefab:cc.Prefab = null;
|
||||
|
||||
@property({type:cc.Node})
|
||||
listContent:cc.Node = null;
|
||||
|
||||
@property({type:[cc.SpriteFrame]})
|
||||
flagSpriteFrames:cc.SpriteFrame[] = [];
|
||||
|
||||
@property
|
||||
listItemMax:number = 200;
|
||||
|
||||
start() {
|
||||
for(let i = 0; i < this.listItemMax; i++){
|
||||
let node = cc.instantiate(this.listTestItemPrefab);
|
||||
node.parent = this.listContent;
|
||||
let item = node.getComponent(ListTestItem);
|
||||
item?.randomData(i + 1, this.flagSpriteFrames[Math.floor(Math.random() * this.flagSpriteFrames.length)])
|
||||
}
|
||||
}
|
||||
}
|
10
2.4.11/assets/test/scripts/test-scene.ts.meta
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"uuid": "66495605-543c-44a7-b208-dfc48bdce8b8",
|
||||
"importer": "typescript",
|
||||
"isPlugin": false,
|
||||
"loadPluginInWeb": true,
|
||||
"loadPluginInNative": true,
|
||||
"loadPluginInEditor": false,
|
||||
"subMetas": {}
|
||||
}
|
13
2.4.11/assets/test/textures.meta
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"ver": "1.1.3",
|
||||
"uuid": "0927e59d-b693-4ac2-9e53-0eeffbd0e543",
|
||||
"importer": "folder",
|
||||
"isBundle": false,
|
||||
"bundleName": "",
|
||||
"priority": 1,
|
||||
"compressionType": {},
|
||||
"optimizeHotUpdate": {},
|
||||
"inlineSpriteFrames": {},
|
||||
"isRemoteBundle": {},
|
||||
"subMetas": {}
|
||||
}
|
3
2.4.11/assets/test/textures/AutoAtlas.pac
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"__type__": "cc.SpriteAtlas"
|
||||
}
|
23
2.4.11/assets/test/textures/AutoAtlas.pac.meta
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"ver": "1.2.5",
|
||||
"uuid": "42c27816-9000-4fb5-a99e-5aea6002d77b",
|
||||
"importer": "auto-atlas",
|
||||
"maxWidth": 1024,
|
||||
"maxHeight": 1024,
|
||||
"padding": 2,
|
||||
"compressionLevel": 6,
|
||||
"allowRotation": true,
|
||||
"forceSquared": false,
|
||||
"powerOfTwo": false,
|
||||
"algorithm": "MaxRects",
|
||||
"format": "png",
|
||||
"quality": 80,
|
||||
"contourBleed": true,
|
||||
"paddingBleed": true,
|
||||
"filterUnused": true,
|
||||
"packable": false,
|
||||
"premultiplyAlpha": false,
|
||||
"filterMode": "bilinear",
|
||||
"platformSettings": {},
|
||||
"subMetas": {}
|
||||
}
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
38
2.4.11/assets/test/textures/box-1.png.meta
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"ver": "2.3.7",
|
||||
"uuid": "a095424e-cf6f-4be2-a7b1-34a3ccc2f2ec",
|
||||
"importer": "texture",
|
||||
"type": "sprite",
|
||||
"wrapMode": "clamp",
|
||||
"filterMode": "bilinear",
|
||||
"premultiplyAlpha": false,
|
||||
"genMipmaps": false,
|
||||
"packable": true,
|
||||
"width": 105,
|
||||
"height": 100,
|
||||
"platformSettings": {},
|
||||
"subMetas": {
|
||||
"box-1": {
|
||||
"ver": "1.0.6",
|
||||
"uuid": "1e6042b1-be42-4958-aed1-1b837ad8b6ab",
|
||||
"importer": "sprite-frame",
|
||||
"rawTextureUuid": "a095424e-cf6f-4be2-a7b1-34a3ccc2f2ec",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": false,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 0,
|
||||
"trimY": 0,
|
||||
"width": 105,
|
||||
"height": 100,
|
||||
"rawWidth": 105,
|
||||
"rawHeight": 100,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"subMetas": {}
|
||||
}
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 873 B After Width: | Height: | Size: 873 B |
38
2.4.11/assets/test/textures/box-2.png.meta
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"ver": "2.3.7",
|
||||
"uuid": "3a1e47f2-e0c6-48af-8c8c-e48f9f95a7d5",
|
||||
"importer": "texture",
|
||||
"type": "sprite",
|
||||
"wrapMode": "clamp",
|
||||
"filterMode": "bilinear",
|
||||
"premultiplyAlpha": false,
|
||||
"genMipmaps": false,
|
||||
"packable": true,
|
||||
"width": 171,
|
||||
"height": 27,
|
||||
"platformSettings": {},
|
||||
"subMetas": {
|
||||
"box-2": {
|
||||
"ver": "1.0.6",
|
||||
"uuid": "48a96f63-2eeb-4165-a0ca-654da41ec4ae",
|
||||
"importer": "sprite-frame",
|
||||
"rawTextureUuid": "3a1e47f2-e0c6-48af-8c8c-e48f9f95a7d5",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": false,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 0,
|
||||
"trimY": 0,
|
||||
"width": 171,
|
||||
"height": 27,
|
||||
"rawWidth": 171,
|
||||
"rawHeight": 27,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"subMetas": {}
|
||||
}
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 451 B After Width: | Height: | Size: 451 B |
38
2.4.11/assets/test/textures/box-3.png.meta
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"ver": "2.3.7",
|
||||
"uuid": "02a30094-7497-4650-81e0-0c49c1c28a2a",
|
||||
"importer": "texture",
|
||||
"type": "sprite",
|
||||
"wrapMode": "clamp",
|
||||
"filterMode": "bilinear",
|
||||
"premultiplyAlpha": false,
|
||||
"genMipmaps": false,
|
||||
"packable": true,
|
||||
"width": 171,
|
||||
"height": 27,
|
||||
"platformSettings": {},
|
||||
"subMetas": {
|
||||
"box-3": {
|
||||
"ver": "1.0.6",
|
||||
"uuid": "6b84a7e0-d31a-42ab-90de-bb04c9ea0d2f",
|
||||
"importer": "sprite-frame",
|
||||
"rawTextureUuid": "02a30094-7497-4650-81e0-0c49c1c28a2a",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": false,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 0,
|
||||
"trimY": 0,
|
||||
"width": 171,
|
||||
"height": 27,
|
||||
"rawWidth": 171,
|
||||
"rawHeight": 27,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"subMetas": {}
|
||||
}
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
38
2.4.11/assets/test/textures/box-4.png.meta
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"ver": "2.3.7",
|
||||
"uuid": "a218f909-f8aa-4325-9d22-af05af387299",
|
||||
"importer": "texture",
|
||||
"type": "sprite",
|
||||
"wrapMode": "clamp",
|
||||
"filterMode": "bilinear",
|
||||
"premultiplyAlpha": false,
|
||||
"genMipmaps": false,
|
||||
"packable": true,
|
||||
"width": 240,
|
||||
"height": 241,
|
||||
"platformSettings": {},
|
||||
"subMetas": {
|
||||
"box-4": {
|
||||
"ver": "1.0.6",
|
||||
"uuid": "f122dcc2-a3bf-4eb3-a7a1-e93654669f51",
|
||||
"importer": "sprite-frame",
|
||||
"rawTextureUuid": "a218f909-f8aa-4325-9d22-af05af387299",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": false,
|
||||
"offsetX": 0.5,
|
||||
"offsetY": 0.5,
|
||||
"trimX": 5,
|
||||
"trimY": 5,
|
||||
"width": 231,
|
||||
"height": 230,
|
||||
"rawWidth": 240,
|
||||
"rawHeight": 241,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"subMetas": {}
|
||||
}
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 952 B After Width: | Height: | Size: 952 B |
38
2.4.11/assets/test/textures/box-5.png.meta
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"ver": "2.3.7",
|
||||
"uuid": "b77831b2-df3a-4606-9a8e-0423d0a664a5",
|
||||
"importer": "texture",
|
||||
"type": "sprite",
|
||||
"wrapMode": "clamp",
|
||||
"filterMode": "bilinear",
|
||||
"premultiplyAlpha": false,
|
||||
"genMipmaps": false,
|
||||
"packable": true,
|
||||
"width": 240,
|
||||
"height": 241,
|
||||
"platformSettings": {},
|
||||
"subMetas": {
|
||||
"box-5": {
|
||||
"ver": "1.0.6",
|
||||
"uuid": "9b9dc23d-1001-44d7-9c36-a7d960f7a49d",
|
||||
"importer": "sprite-frame",
|
||||
"rawTextureUuid": "b77831b2-df3a-4606-9a8e-0423d0a664a5",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": false,
|
||||
"offsetX": 0.5,
|
||||
"offsetY": 0.5,
|
||||
"trimX": 5,
|
||||
"trimY": 5,
|
||||
"width": 231,
|
||||
"height": 230,
|
||||
"rawWidth": 240,
|
||||
"rawHeight": 241,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"subMetas": {}
|
||||
}
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 200 B After Width: | Height: | Size: 200 B |
38
2.4.11/assets/test/textures/box-6.png.meta
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"ver": "2.3.7",
|
||||
"uuid": "2f2e41cc-a8a8-4438-9ff2-014f9282ed06",
|
||||
"importer": "texture",
|
||||
"type": "sprite",
|
||||
"wrapMode": "clamp",
|
||||
"filterMode": "bilinear",
|
||||
"premultiplyAlpha": false,
|
||||
"genMipmaps": false,
|
||||
"packable": true,
|
||||
"width": 70,
|
||||
"height": 32,
|
||||
"platformSettings": {},
|
||||
"subMetas": {
|
||||
"box-6": {
|
||||
"ver": "1.0.6",
|
||||
"uuid": "f195da9c-9b72-4765-9535-724d8383e63e",
|
||||
"importer": "sprite-frame",
|
||||
"rawTextureUuid": "2f2e41cc-a8a8-4438-9ff2-014f9282ed06",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": false,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 0,
|
||||
"trimY": 0,
|
||||
"width": 70,
|
||||
"height": 32,
|
||||
"rawWidth": 70,
|
||||
"rawHeight": 32,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"subMetas": {}
|
||||
}
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 105 B After Width: | Height: | Size: 105 B |
38
2.4.11/assets/test/textures/box-7.png.meta
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"ver": "2.3.7",
|
||||
"uuid": "1fe24969-ad78-4ca9-b410-4ba370b3a890",
|
||||
"importer": "texture",
|
||||
"type": "sprite",
|
||||
"wrapMode": "clamp",
|
||||
"filterMode": "bilinear",
|
||||
"premultiplyAlpha": false,
|
||||
"genMipmaps": false,
|
||||
"packable": true,
|
||||
"width": 63,
|
||||
"height": 43,
|
||||
"platformSettings": {},
|
||||
"subMetas": {
|
||||
"box-7": {
|
||||
"ver": "1.0.6",
|
||||
"uuid": "f625fa33-7315-4748-89a5-cf48448980c9",
|
||||
"importer": "sprite-frame",
|
||||
"rawTextureUuid": "1fe24969-ad78-4ca9-b410-4ba370b3a890",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": false,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 0,
|
||||
"trimY": 0,
|
||||
"width": 63,
|
||||
"height": 43,
|
||||
"rawWidth": 63,
|
||||
"rawHeight": 43,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"subMetas": {}
|
||||
}
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 119 B After Width: | Height: | Size: 119 B |
38
2.4.11/assets/test/textures/box-8.png.meta
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"ver": "2.3.7",
|
||||
"uuid": "5849d769-7609-4f98-9510-fb88660f795a",
|
||||
"importer": "texture",
|
||||
"type": "sprite",
|
||||
"wrapMode": "clamp",
|
||||
"filterMode": "bilinear",
|
||||
"premultiplyAlpha": false,
|
||||
"genMipmaps": false,
|
||||
"packable": true,
|
||||
"width": 64,
|
||||
"height": 41,
|
||||
"platformSettings": {},
|
||||
"subMetas": {
|
||||
"box-8": {
|
||||
"ver": "1.0.6",
|
||||
"uuid": "2e46e265-3945-4ae5-99d4-8f4eb56f391a",
|
||||
"importer": "sprite-frame",
|
||||
"rawTextureUuid": "5849d769-7609-4f98-9510-fb88660f795a",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": false,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 0,
|
||||
"trimY": 0,
|
||||
"width": 64,
|
||||
"height": 41,
|
||||
"rawWidth": 64,
|
||||
"rawHeight": 41,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"subMetas": {}
|
||||
}
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 153 B After Width: | Height: | Size: 153 B |
38
2.4.11/assets/test/textures/box-9.png.meta
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"ver": "2.3.7",
|
||||
"uuid": "240b0fb6-a282-4b50-881f-559e9d9363e4",
|
||||
"importer": "texture",
|
||||
"type": "sprite",
|
||||
"wrapMode": "clamp",
|
||||
"filterMode": "bilinear",
|
||||
"premultiplyAlpha": false,
|
||||
"genMipmaps": false,
|
||||
"packable": true,
|
||||
"width": 63,
|
||||
"height": 29,
|
||||
"platformSettings": {},
|
||||
"subMetas": {
|
||||
"box-9": {
|
||||
"ver": "1.0.6",
|
||||
"uuid": "157e8a85-da38-415f-93f2-ccda0b947415",
|
||||
"importer": "sprite-frame",
|
||||
"rawTextureUuid": "240b0fb6-a282-4b50-881f-559e9d9363e4",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": false,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 0,
|
||||
"trimY": 0,
|
||||
"width": 63,
|
||||
"height": 29,
|
||||
"rawWidth": 63,
|
||||
"rawHeight": 29,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"subMetas": {}
|
||||
}
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 569 B After Width: | Height: | Size: 569 B |
38
2.4.11/assets/test/textures/btn-black.png.meta
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"ver": "2.3.7",
|
||||
"uuid": "78813583-64ea-4df9-90dc-410129a1d07d",
|
||||
"importer": "texture",
|
||||
"type": "sprite",
|
||||
"wrapMode": "clamp",
|
||||
"filterMode": "bilinear",
|
||||
"premultiplyAlpha": false,
|
||||
"genMipmaps": false,
|
||||
"packable": true,
|
||||
"width": 210,
|
||||
"height": 80,
|
||||
"platformSettings": {},
|
||||
"subMetas": {
|
||||
"btn-black": {
|
||||
"ver": "1.0.6",
|
||||
"uuid": "ea1039ee-663b-4557-be34-c1c9adf6a822",
|
||||
"importer": "sprite-frame",
|
||||
"rawTextureUuid": "78813583-64ea-4df9-90dc-410129a1d07d",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": false,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 0,
|
||||
"trimY": 0,
|
||||
"width": 210,
|
||||
"height": 80,
|
||||
"rawWidth": 210,
|
||||
"rawHeight": 80,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"subMetas": {}
|
||||
}
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 838 B After Width: | Height: | Size: 838 B |
38
2.4.11/assets/test/textures/btn-white-2.png.meta
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"ver": "2.3.7",
|
||||
"uuid": "acd864b8-87e0-46c3-aaaa-d8585dd24570",
|
||||
"importer": "texture",
|
||||
"type": "sprite",
|
||||
"wrapMode": "clamp",
|
||||
"filterMode": "bilinear",
|
||||
"premultiplyAlpha": false,
|
||||
"genMipmaps": false,
|
||||
"packable": true,
|
||||
"width": 68,
|
||||
"height": 36,
|
||||
"platformSettings": {},
|
||||
"subMetas": {
|
||||
"btn-white-2": {
|
||||
"ver": "1.0.6",
|
||||
"uuid": "f7af8780-666e-4912-b0f4-963319c0afb4",
|
||||
"importer": "sprite-frame",
|
||||
"rawTextureUuid": "acd864b8-87e0-46c3-aaaa-d8585dd24570",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": false,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 0,
|
||||
"trimY": 0,
|
||||
"width": 68,
|
||||
"height": 36,
|
||||
"rawWidth": 68,
|
||||
"rawHeight": 36,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"subMetas": {}
|
||||
}
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 809 B After Width: | Height: | Size: 809 B |
38
2.4.11/assets/test/textures/btn-white.png.meta
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"ver": "2.3.7",
|
||||
"uuid": "954ea7ef-12bb-43aa-8077-ed7a567b460c",
|
||||
"importer": "texture",
|
||||
"type": "sprite",
|
||||
"wrapMode": "clamp",
|
||||
"filterMode": "bilinear",
|
||||
"premultiplyAlpha": false,
|
||||
"genMipmaps": false,
|
||||
"packable": true,
|
||||
"width": 214,
|
||||
"height": 84,
|
||||
"platformSettings": {},
|
||||
"subMetas": {
|
||||
"btn-white": {
|
||||
"ver": "1.0.6",
|
||||
"uuid": "b8da036a-31c8-4ea9-8332-e33929b16e38",
|
||||
"importer": "sprite-frame",
|
||||
"rawTextureUuid": "954ea7ef-12bb-43aa-8077-ed7a567b460c",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": false,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 1,
|
||||
"trimY": 1,
|
||||
"width": 212,
|
||||
"height": 82,
|
||||
"rawWidth": 214,
|
||||
"rawHeight": 84,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"subMetas": {}
|
||||
}
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
38
2.4.11/assets/test/textures/circle-countdown.png.meta
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"ver": "2.3.7",
|
||||
"uuid": "ca4624dc-b082-4c76-871d-c96cb21fc8fd",
|
||||
"importer": "texture",
|
||||
"type": "sprite",
|
||||
"wrapMode": "clamp",
|
||||
"filterMode": "bilinear",
|
||||
"premultiplyAlpha": false,
|
||||
"genMipmaps": false,
|
||||
"packable": true,
|
||||
"width": 249,
|
||||
"height": 249,
|
||||
"platformSettings": {},
|
||||
"subMetas": {
|
||||
"circle-countdown": {
|
||||
"ver": "1.0.6",
|
||||
"uuid": "097e1875-d5b0-43cc-8aad-64ae21d92aac",
|
||||
"importer": "sprite-frame",
|
||||
"rawTextureUuid": "ca4624dc-b082-4c76-871d-c96cb21fc8fd",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": false,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 2,
|
||||
"trimY": 2,
|
||||
"width": 245,
|
||||
"height": 245,
|
||||
"rawWidth": 249,
|
||||
"rawHeight": 249,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"subMetas": {}
|
||||
}
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
38
2.4.11/assets/test/textures/flag-disconnection.png.meta
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"ver": "2.3.7",
|
||||
"uuid": "0e81c7eb-0241-43a9-b503-0f91db7e0f37",
|
||||
"importer": "texture",
|
||||
"type": "sprite",
|
||||
"wrapMode": "clamp",
|
||||
"filterMode": "bilinear",
|
||||
"premultiplyAlpha": false,
|
||||
"genMipmaps": false,
|
||||
"packable": true,
|
||||
"width": 84,
|
||||
"height": 84,
|
||||
"platformSettings": {},
|
||||
"subMetas": {
|
||||
"flag-disconnection": {
|
||||
"ver": "1.0.6",
|
||||
"uuid": "9f408d81-d67e-4968-b885-0edece9785f3",
|
||||
"importer": "sprite-frame",
|
||||
"rawTextureUuid": "0e81c7eb-0241-43a9-b503-0f91db7e0f37",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": false,
|
||||
"offsetX": 0.5,
|
||||
"offsetY": 0,
|
||||
"trimX": 2,
|
||||
"trimY": 2,
|
||||
"width": 81,
|
||||
"height": 80,
|
||||
"rawWidth": 84,
|
||||
"rawHeight": 84,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"subMetas": {}
|
||||
}
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
38
2.4.11/assets/test/textures/flag-eliminated.png.meta
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"ver": "2.3.7",
|
||||
"uuid": "d3490a01-c27e-4704-950f-dcd87a95d179",
|
||||
"importer": "texture",
|
||||
"type": "sprite",
|
||||
"wrapMode": "clamp",
|
||||
"filterMode": "bilinear",
|
||||
"premultiplyAlpha": false,
|
||||
"genMipmaps": false,
|
||||
"packable": true,
|
||||
"width": 84,
|
||||
"height": 84,
|
||||
"platformSettings": {},
|
||||
"subMetas": {
|
||||
"flag-eliminated": {
|
||||
"ver": "1.0.6",
|
||||
"uuid": "4528c934-0086-44da-8923-a956a624cb75",
|
||||
"importer": "sprite-frame",
|
||||
"rawTextureUuid": "d3490a01-c27e-4704-950f-dcd87a95d179",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": false,
|
||||
"offsetX": 0.5,
|
||||
"offsetY": 0,
|
||||
"trimX": 2,
|
||||
"trimY": 2,
|
||||
"width": 81,
|
||||
"height": 80,
|
||||
"rawWidth": 84,
|
||||
"rawHeight": 84,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"subMetas": {}
|
||||
}
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
38
2.4.11/assets/test/textures/flag-escape.png.meta
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"ver": "2.3.7",
|
||||
"uuid": "eaa9875d-572c-46ea-b275-f0bd36cc6697",
|
||||
"importer": "texture",
|
||||
"type": "sprite",
|
||||
"wrapMode": "clamp",
|
||||
"filterMode": "bilinear",
|
||||
"premultiplyAlpha": false,
|
||||
"genMipmaps": false,
|
||||
"packable": true,
|
||||
"width": 84,
|
||||
"height": 84,
|
||||
"platformSettings": {},
|
||||
"subMetas": {
|
||||
"flag-escape": {
|
||||
"ver": "1.0.6",
|
||||
"uuid": "5dde49b3-365a-4e01-b7a5-a079116b7d7c",
|
||||
"importer": "sprite-frame",
|
||||
"rawTextureUuid": "eaa9875d-572c-46ea-b275-f0bd36cc6697",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": false,
|
||||
"offsetX": 0.5,
|
||||
"offsetY": 0,
|
||||
"trimX": 2,
|
||||
"trimY": 2,
|
||||
"width": 81,
|
||||
"height": 80,
|
||||
"rawWidth": 84,
|
||||
"rawHeight": 84,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"subMetas": {}
|
||||
}
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
38
2.4.11/assets/test/textures/gold.png.meta
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"ver": "2.3.7",
|
||||
"uuid": "bc529642-594d-4486-aafb-bfd2d3edf02c",
|
||||
"importer": "texture",
|
||||
"type": "sprite",
|
||||
"wrapMode": "clamp",
|
||||
"filterMode": "bilinear",
|
||||
"premultiplyAlpha": false,
|
||||
"genMipmaps": false,
|
||||
"packable": true,
|
||||
"width": 60,
|
||||
"height": 61,
|
||||
"platformSettings": {},
|
||||
"subMetas": {
|
||||
"gold": {
|
||||
"ver": "1.0.6",
|
||||
"uuid": "f74c16b3-291b-41b4-8542-9b85fbca505b",
|
||||
"importer": "sprite-frame",
|
||||
"rawTextureUuid": "bc529642-594d-4486-aafb-bfd2d3edf02c",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": false,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 0,
|
||||
"trimY": 0,
|
||||
"width": 60,
|
||||
"height": 61,
|
||||
"rawWidth": 60,
|
||||
"rawHeight": 61,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"subMetas": {}
|
||||
}
|
||||
}
|
||||
}
|
32207
2.4.11/creator.d.ts
vendored
Normal file
15
2.4.11/jsconfig.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es6",
|
||||
"module": "commonjs",
|
||||
"experimentalDecorators": true
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
".vscode",
|
||||
"library",
|
||||
"local",
|
||||
"settings",
|
||||
"temp"
|
||||
]
|
||||
}
|
@ -0,0 +1,397 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "ModelBatcher.hpp"
|
||||
#include "RenderFlow.hpp"
|
||||
#include "StencilManager.hpp"
|
||||
#include "assembler/RenderDataList.hpp"
|
||||
#include "NodeProxy.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
#define INIT_MODEL_LENGTH 16
|
||||
|
||||
ModelBatcher::ModelBatcher(RenderFlow* flow)
|
||||
: _flow(flow)
|
||||
, _modelOffset(0)
|
||||
, _cullingMask(0)
|
||||
, _walking(false)
|
||||
, _currEffect(nullptr)
|
||||
, _buffer(nullptr)
|
||||
, _useModel(false)
|
||||
, _node(nullptr)
|
||||
{
|
||||
for (int i = 0; i < INIT_MODEL_LENGTH; i++)
|
||||
{
|
||||
_modelPool.push_back(new Model());
|
||||
}
|
||||
_rendererCache.reserve(1024);
|
||||
_stencilMgr = StencilManager::getInstance();
|
||||
}
|
||||
|
||||
ModelBatcher::~ModelBatcher()
|
||||
{
|
||||
setCurrentEffect(nullptr);
|
||||
setNode(nullptr);
|
||||
|
||||
for (int i = 0; i < _modelPool.size(); i++)
|
||||
{
|
||||
auto model = _modelPool[i];
|
||||
delete model;
|
||||
}
|
||||
_modelPool.clear();
|
||||
|
||||
for (auto iter = _buffers.begin(); iter != _buffers.end(); ++iter)
|
||||
{
|
||||
MeshBuffer *buffer = iter->second;
|
||||
delete buffer;
|
||||
}
|
||||
_buffers.clear();
|
||||
}
|
||||
|
||||
void ModelBatcher::reset()
|
||||
{
|
||||
for (int i = 0; i < _modelOffset; ++i)
|
||||
{
|
||||
Model* model = _modelPool[i];
|
||||
model->reset();
|
||||
}
|
||||
_flow->getRenderScene()->removeModels();
|
||||
_modelOffset = 0;
|
||||
|
||||
for (auto iter : _buffers)
|
||||
{
|
||||
iter.second->reset();
|
||||
}
|
||||
_buffer = nullptr;
|
||||
|
||||
_commitState = CommitState::None;
|
||||
setCurrentEffect(nullptr);
|
||||
setNode(nullptr);
|
||||
_ia.clear();
|
||||
_cullingMask = 0;
|
||||
_walking = false;
|
||||
_useModel = false;
|
||||
|
||||
_modelMat.set(Mat4::IDENTITY);
|
||||
_stencilMgr->reset();
|
||||
}
|
||||
|
||||
void ModelBatcher::changeCommitState(CommitState state)
|
||||
{
|
||||
if (_commitState == state) return;
|
||||
switch(_commitState)
|
||||
{
|
||||
case CommitState::Custom:
|
||||
flushIA();
|
||||
break;
|
||||
case CommitState::Common:
|
||||
flush();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
setCurrentEffect(nullptr);
|
||||
_commitState = state;
|
||||
}
|
||||
|
||||
void ModelBatcher::commit(NodeProxy* node, Assembler* assembler, int cullingMask)
|
||||
{
|
||||
changeCommitState(CommitState::Common);
|
||||
|
||||
bool useModel = assembler->getUseModel();
|
||||
bool ignoreWorldMatrix = assembler->isIgnoreWorldMatrix();
|
||||
|
||||
auto customWorldMat = assembler->getCustomWorldMatrix();
|
||||
customWorldMat = customWorldMat ? customWorldMat : &node->getWorldMatrix();
|
||||
const Mat4& worldMat = useModel && !ignoreWorldMatrix ? *customWorldMat : Mat4::IDENTITY;
|
||||
|
||||
auto asmDirty = assembler->isDirty(AssemblerBase::VERTICES_OPACITY_CHANGED);
|
||||
auto nodeDirty = node->isDirty(RenderFlow::NODE_OPACITY_CHANGED);
|
||||
auto needUpdateOpacity = (asmDirty || nodeDirty) && !assembler->isIgnoreOpacityFlag();
|
||||
|
||||
for (std::size_t i = 0, l = assembler->getIACount(); i < l; ++i)
|
||||
{
|
||||
assembler->beforeFillBuffers(i);
|
||||
|
||||
EffectVariant* effect = assembler->getEffect(i);
|
||||
if (!effect) continue;
|
||||
|
||||
if (_currEffect == nullptr ||
|
||||
_currEffect->getHash() != effect->getHash() ||
|
||||
_cullingMask != cullingMask || useModel)
|
||||
{
|
||||
// Break auto batch
|
||||
flush();
|
||||
|
||||
setNode(_useModel ? node : nullptr);
|
||||
setCurrentEffect(effect);
|
||||
_modelMat.set(worldMat);
|
||||
_useModel = useModel;
|
||||
_cullingMask = cullingMask;
|
||||
}
|
||||
|
||||
if (needUpdateOpacity)
|
||||
{
|
||||
assembler->updateOpacity(i, node->getRealOpacity());
|
||||
}
|
||||
|
||||
assembler->fillBuffers(node, this, i);
|
||||
}
|
||||
}
|
||||
|
||||
void ModelBatcher::commitIA(NodeProxy* node, CustomAssembler* assembler, int cullingMask)
|
||||
{
|
||||
changeCommitState(CommitState::Custom);
|
||||
|
||||
EffectVariant* effect = assembler->getEffect(0);
|
||||
if (!effect) return;
|
||||
|
||||
auto customIA = assembler->getIA(0);
|
||||
if (!customIA) return;
|
||||
|
||||
std::size_t iaCount = assembler->getIACount();
|
||||
bool useModel = assembler->getUseModel();
|
||||
auto customWorldMat = assembler->getCustomWorldMatrix();
|
||||
customWorldMat = customWorldMat ? customWorldMat : &node->getWorldMatrix();
|
||||
const Mat4& worldMat = useModel ? *customWorldMat : Mat4::IDENTITY;
|
||||
|
||||
if (_currEffect == nullptr ||
|
||||
_currEffect->getHash() != effect->getHash() ||
|
||||
_cullingMask != cullingMask || useModel ||
|
||||
!_ia.isMergeable(*customIA))
|
||||
{
|
||||
flushIA();
|
||||
|
||||
setNode(_useModel ? node : nullptr);
|
||||
setCurrentEffect(effect);
|
||||
_modelMat.set(worldMat);
|
||||
_useModel = useModel;
|
||||
_cullingMask = cullingMask;
|
||||
|
||||
_ia.setVertexBuffer(customIA->getVertexBuffer());
|
||||
_ia.setIndexBuffer(customIA->getIndexBuffer());
|
||||
_ia.setStart(customIA->getStart());
|
||||
_ia.setCount(0);
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < iaCount; i++ )
|
||||
{
|
||||
customIA = assembler->getIA(i);
|
||||
effect = assembler->getEffect(i);
|
||||
if (!effect) continue;
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
flushIA();
|
||||
|
||||
setNode(_useModel ? node : nullptr);
|
||||
setCurrentEffect(effect);
|
||||
_modelMat.set(worldMat);
|
||||
_useModel = useModel;
|
||||
_cullingMask = cullingMask;
|
||||
|
||||
_ia.setVertexBuffer(customIA->getVertexBuffer());
|
||||
_ia.setIndexBuffer(customIA->getIndexBuffer());
|
||||
_ia.setStart(customIA->getStart());
|
||||
_ia.setCount(0);
|
||||
}
|
||||
|
||||
_ia.setCount(_ia.getCount() + customIA->getCount());
|
||||
}
|
||||
}
|
||||
|
||||
void ModelBatcher::flushIA()
|
||||
{
|
||||
if (_commitState != CommitState::Custom)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_walking || !_currEffect || _ia.getCount() <= 0)
|
||||
{
|
||||
_ia.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
// Stencil manager process
|
||||
_stencilMgr->handleEffect(_currEffect);
|
||||
|
||||
// Generate model
|
||||
Model* model = nullptr;
|
||||
if (_modelOffset >= _modelPool.size())
|
||||
{
|
||||
model = new Model();
|
||||
_modelPool.push_back(model);
|
||||
}
|
||||
else
|
||||
{
|
||||
model = _modelPool[_modelOffset];
|
||||
}
|
||||
_modelOffset++;
|
||||
model->setWorldMatix(_modelMat);
|
||||
model->setCullingMask(_cullingMask);
|
||||
model->setEffect(_currEffect);
|
||||
model->setNode(_node);
|
||||
model->setInputAssembler(_ia);
|
||||
|
||||
_ia.clear();
|
||||
|
||||
_flow->getRenderScene()->addModel(model);
|
||||
}
|
||||
|
||||
void ModelBatcher::flush()
|
||||
{
|
||||
if (_commitState != CommitState::Common)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_walking || !_currEffect || !_buffer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int indexStart = _buffer->getIndexStart();
|
||||
int indexOffset = _buffer->getIndexOffset();
|
||||
int indexCount = indexOffset - indexStart;
|
||||
if (indexCount <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_ia.setVertexBuffer(_buffer->getVertexBuffer());
|
||||
_ia.setIndexBuffer(_buffer->getIndexBuffer());
|
||||
_ia.setStart(indexStart);
|
||||
_ia.setCount(indexCount);
|
||||
|
||||
// Stencil manager process
|
||||
_stencilMgr->handleEffect(_currEffect);
|
||||
|
||||
// Generate model
|
||||
Model* model = nullptr;
|
||||
if (_modelOffset >= _modelPool.size())
|
||||
{
|
||||
model = new Model();
|
||||
_modelPool.push_back(model);
|
||||
}
|
||||
else
|
||||
{
|
||||
model = _modelPool[_modelOffset];
|
||||
}
|
||||
_modelOffset++;
|
||||
model->setWorldMatix(_modelMat);
|
||||
model->setCullingMask(_cullingMask);
|
||||
model->setEffect(_currEffect);
|
||||
model->setNode(_node);
|
||||
model->setInputAssembler(_ia);
|
||||
|
||||
_ia.clear();
|
||||
|
||||
_flow->getRenderScene()->addModel(model);
|
||||
|
||||
_buffer->updateOffset();
|
||||
}
|
||||
|
||||
void ModelBatcher::startBatch()
|
||||
{
|
||||
reset();
|
||||
_walking = true;
|
||||
}
|
||||
|
||||
void ModelBatcher::terminateBatch()
|
||||
{
|
||||
flush();
|
||||
flushIA();
|
||||
|
||||
for (auto iter : _buffers)
|
||||
{
|
||||
iter.second->uploadData();
|
||||
}
|
||||
|
||||
_walking = false;
|
||||
}
|
||||
|
||||
void ModelBatcher::setNode(NodeProxy* node)
|
||||
{
|
||||
if (_node == node)
|
||||
{
|
||||
return;
|
||||
}
|
||||
CC_SAFE_RELEASE(_node);
|
||||
_node = node;
|
||||
CC_SAFE_RETAIN(_node);
|
||||
}
|
||||
|
||||
void ModelBatcher::setCurrentEffect(EffectVariant* effect)
|
||||
{
|
||||
if (_currEffect == effect)
|
||||
{
|
||||
return;
|
||||
}
|
||||
CC_SAFE_RELEASE(_currEffect);
|
||||
_currEffect = effect;
|
||||
CC_SAFE_RETAIN(_currEffect);
|
||||
};
|
||||
|
||||
MeshBuffer* ModelBatcher::getBuffer(VertexFormat* fmt)
|
||||
{
|
||||
if (_buffer != nullptr && fmt == _buffer->_vertexFmt)
|
||||
{
|
||||
return _buffer;
|
||||
}
|
||||
|
||||
MeshBuffer* buffer = nullptr;
|
||||
auto iter = _buffers.find(fmt);
|
||||
if (iter == _buffers.end())
|
||||
{
|
||||
buffer = new MeshBuffer(this, fmt);
|
||||
_buffers.emplace(fmt, buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer = iter->second;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void ModelBatcher::flushRendererCache(){
|
||||
if(_rendererCache.size() > 0){
|
||||
if(_rendererOrder){
|
||||
std::stable_sort(_rendererCache.begin(), _rendererCache.end(), [](NodeProxy* a, NodeProxy* b) { return a->getRenderPriority() < b->getRenderPriority(); });
|
||||
}
|
||||
CCLOGINFO("flushRendererCache : %d", _rendererCache.size());
|
||||
for(std::vector<NodeProxy*>::iterator it = _rendererCache.begin(); it != _rendererCache.end(); it++){
|
||||
NodeProxy* node = *it;
|
||||
CCLOGINFO("%s %d", node->getName().c_str(), node->getRenderPriority());
|
||||
node->getAssembler()->handle(node, this, _flow->getRenderScene());
|
||||
}
|
||||
_rendererCache.clear();
|
||||
}
|
||||
_rendererOrder = false;
|
||||
}
|
||||
|
||||
RENDERER_END
|
@ -0,0 +1,178 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "../Macro.h"
|
||||
#include "assembler/Assembler.hpp"
|
||||
#include "assembler/CustomAssembler.hpp"
|
||||
#include "MeshBuffer.hpp"
|
||||
#include "../renderer/Renderer.h"
|
||||
#include "math/CCMath.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class RenderFlow;
|
||||
class StencilManager;
|
||||
|
||||
/**
|
||||
* @addtogroup scene
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief ModelBatcher is responsible for transforming node's render handles into final render datas.
|
||||
* It collects render data, batches different render handle together into Models and submits to render Scene.
|
||||
*/
|
||||
class ModelBatcher
|
||||
{
|
||||
public:
|
||||
|
||||
enum CommitState {
|
||||
None,
|
||||
Common,
|
||||
Custom,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The constructor.
|
||||
*/
|
||||
ModelBatcher(RenderFlow* flow);
|
||||
/**
|
||||
* @brief The destructor.
|
||||
*/
|
||||
~ModelBatcher();
|
||||
/**
|
||||
* @brief Reset all render buffer.
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/**
|
||||
* @brief Commit a render handle to the model batcher
|
||||
* @param[in] node The node which owns the render handle
|
||||
* @param[in] handle The render handle contains render datas
|
||||
*/
|
||||
void commit(NodeProxy* node, Assembler* handle, int cullingMask);
|
||||
/**
|
||||
* @brief Commit a custom render handle to the model batcher
|
||||
* @param[in] node The node which owns the render handle
|
||||
* @param[in] handle The custom render handle contains render datas
|
||||
*/
|
||||
void commitIA(NodeProxy* node, CustomAssembler* handle, int cullingMask);
|
||||
|
||||
/**
|
||||
* @brief This method should be invoked before commit any render handles each frame.
|
||||
* It notifies the model batcher to get ready for constructing Models
|
||||
*/
|
||||
void startBatch();
|
||||
/**
|
||||
* @brief Flush all cached render data into a new Model and add the Model to render Scene.
|
||||
*/
|
||||
void flush();
|
||||
/**
|
||||
* @brief Finished Custom input assmebler batch and add the Model to render Scene.
|
||||
*/
|
||||
void flushIA();
|
||||
/**
|
||||
* @brief Add new input assembler into current input assembler.
|
||||
*/
|
||||
void flushIA(InputAssembler* customIA);
|
||||
/**
|
||||
* @brief This method should be invoked after committed all render handles each frame.
|
||||
*/
|
||||
void terminateBatch();
|
||||
|
||||
/**
|
||||
* @brief Gets a suitable MeshBuffer for the given VertexFormat.
|
||||
* Render datas arranged in different VertexFormat can't share the same buffer.
|
||||
* @param[in] fmt The VertexFormat
|
||||
*/
|
||||
MeshBuffer* getBuffer(VertexFormat* fmt);
|
||||
/**
|
||||
* @brief Gets the current MeshBuffer.
|
||||
*/
|
||||
const MeshBuffer* getCurrentBuffer() const { return _buffer; };
|
||||
/**
|
||||
* @brief Sets the current MeshBuffer.
|
||||
* @param[in] buffer
|
||||
*/
|
||||
void setCurrentBuffer(MeshBuffer* buffer) { _buffer = buffer; };
|
||||
/**
|
||||
* @brief Gets the global RenderFlow pointer.
|
||||
*/
|
||||
RenderFlow* getFlow() const { return _flow; };
|
||||
|
||||
void setNode(NodeProxy* node);
|
||||
void setCullingMask(int cullingMask) { _cullingMask = cullingMask; }
|
||||
void setCurrentEffect(EffectVariant* effect);
|
||||
void setUseModel(bool useModel) { _useModel = useModel; }
|
||||
void changeCommitState(CommitState state);
|
||||
|
||||
void setSortingPriority(float_t value){
|
||||
_sortingPriority = value;
|
||||
}
|
||||
float_t getSortingPriority() const {
|
||||
return _sortingPriority;
|
||||
}
|
||||
void setRendererOrder(bool value){
|
||||
_rendererOrder = value;
|
||||
}
|
||||
bool getRendererOrder() const {
|
||||
return _rendererOrder;
|
||||
}
|
||||
void pushRendererCache(NodeProxy*value){
|
||||
_rendererCache.push_back(value);
|
||||
}
|
||||
void flushRendererCache();
|
||||
private:
|
||||
int _modelOffset = 0;
|
||||
int _cullingMask = 0;
|
||||
bool _useModel = false;
|
||||
bool _walking = false;
|
||||
cocos2d::Mat4 _modelMat;
|
||||
CommitState _commitState = CommitState::None;
|
||||
|
||||
NodeProxy* _node = nullptr;
|
||||
|
||||
MeshBuffer* _buffer = nullptr;
|
||||
EffectVariant* _currEffect = nullptr;
|
||||
RenderFlow* _flow = nullptr;
|
||||
|
||||
StencilManager* _stencilMgr = nullptr;
|
||||
|
||||
InputAssembler _ia;
|
||||
std::vector<Model*> _modelPool;
|
||||
std::unordered_map<VertexFormat*, MeshBuffer*> _buffers;
|
||||
|
||||
float_t _sortingPriority = 0;
|
||||
bool _rendererOrder = false;
|
||||
std::vector<NodeProxy*> _rendererCache;
|
||||
};
|
||||
|
||||
// end of scene group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
@ -0,0 +1,196 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "NodeMemPool.hpp"
|
||||
#include "base/ccMacros.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
UnitNode::UnitNode()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
UnitNode::~UnitNode()
|
||||
{
|
||||
unset(&dirty, (uint8_t**)&dirtyData, &dirtyLen);
|
||||
unset(&trs, (uint8_t**)&trsData, &trsLen);
|
||||
unset(&localMat, (uint8_t**)&localMatData, &localMatLen);
|
||||
unset(&worldMat, (uint8_t**)&worldMatData, &worldMatLen);
|
||||
unset(&parent, (uint8_t**)&parentData, &parentLen);
|
||||
unset(&zOrder, (uint8_t**)&zOrderData, &zOrderLen);
|
||||
unset(&cullingMask, (uint8_t**)&cullingMaskData, &cullingMaskLen);
|
||||
unset(&opacity, (uint8_t**)&opacityData, &opacityLen);
|
||||
unset(&is3D, (uint8_t**)&is3DData, &is3DLen);
|
||||
unset(&node, (uint8_t**)&nodeData, &nodeLen);
|
||||
unset(&skew, (uint8_t**)&skewData, &skewLen);
|
||||
}
|
||||
|
||||
void UnitNode::setDirty(se::Object* jsData)
|
||||
{
|
||||
set(&dirty, (uint8_t**)&dirtyData, &dirtyLen, jsData);
|
||||
}
|
||||
|
||||
void UnitNode::setTRS(se::Object* jsData)
|
||||
{
|
||||
set(&trs, (uint8_t**)&trsData, &trsLen, jsData);
|
||||
}
|
||||
|
||||
void UnitNode::setLocalMat(se::Object* jsData)
|
||||
{
|
||||
set(&localMat, (uint8_t**)&localMatData, &localMatLen, jsData);
|
||||
}
|
||||
|
||||
void UnitNode::setWorldMat(se::Object* jsData)
|
||||
{
|
||||
set(&worldMat, (uint8_t**)&worldMatData, &worldMatLen, jsData);
|
||||
}
|
||||
|
||||
void UnitNode::setParent(se::Object* jsData)
|
||||
{
|
||||
set(&parent, (uint8_t**)&parentData, &parentLen, jsData);
|
||||
}
|
||||
|
||||
void UnitNode::setZOrder(se::Object* jsData)
|
||||
{
|
||||
set(&zOrder, (uint8_t**)&zOrderData, &zOrderLen, jsData);
|
||||
}
|
||||
|
||||
void UnitNode::setCullingMask(se::Object* jsData)
|
||||
{
|
||||
set(&cullingMask, (uint8_t**)&cullingMaskData, &cullingMaskLen, jsData);
|
||||
}
|
||||
|
||||
void UnitNode::setOpacity(se::Object* jsData)
|
||||
{
|
||||
set(&opacity, (uint8_t**)&opacityData, &opacityLen, jsData);
|
||||
}
|
||||
|
||||
void UnitNode::setIs3D(se::Object* jsData)
|
||||
{
|
||||
set(&is3D, (uint8_t**)&is3DData, &is3DLen, jsData);
|
||||
}
|
||||
|
||||
void UnitNode::setNode(se::Object *jsData)
|
||||
{
|
||||
set(&node, (uint8_t**)&nodeData, &nodeLen, jsData);
|
||||
}
|
||||
|
||||
void UnitNode::setSkew(se::Object* jsData)
|
||||
{
|
||||
set(&skew, (uint8_t**)&skewData, &skewLen, jsData);
|
||||
}
|
||||
|
||||
void UnitNode::setSortingPriority(se::Object* jsData){
|
||||
set(&sortingPriority, (uint8_t**)&sortingPriorityData, &sortingPriorityLen, jsData);
|
||||
}
|
||||
|
||||
void UnitNode::setSortingEnabled(se::Object* jsData){
|
||||
set(&sortingEnabled, (uint8_t**)&sortingEnabledData, &sortingEnabledLen, jsData);
|
||||
}
|
||||
|
||||
NodeMemPool* NodeMemPool::_instance = nullptr;
|
||||
|
||||
NodeMemPool::NodeMemPool()
|
||||
{
|
||||
_instance = this;
|
||||
}
|
||||
|
||||
NodeMemPool::~NodeMemPool()
|
||||
{
|
||||
for(auto it = _nodePool.begin(); it != _nodePool.end(); it++)
|
||||
{
|
||||
if (*it)
|
||||
{
|
||||
delete (*it);
|
||||
}
|
||||
}
|
||||
_nodePool.clear();
|
||||
_instance = nullptr;
|
||||
}
|
||||
|
||||
const std::vector<UnitNode*>& NodeMemPool::getNodePool() const
|
||||
{
|
||||
return _nodePool;
|
||||
}
|
||||
|
||||
void NodeMemPool::removeNodeData(std::size_t unitID)
|
||||
{
|
||||
CCASSERT(unitID < _nodePool.size(), "NodeMemPool removeNodeData unitID can not be rather than pool size");
|
||||
auto unit = _nodePool[unitID];
|
||||
if (unit)
|
||||
{
|
||||
delete unit;
|
||||
_nodePool[unitID] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
UnitNode* NodeMemPool::getUnit(std::size_t unitID) const
|
||||
{
|
||||
CCASSERT(unitID < _nodePool.size(), "NodeMemPool getUnit unitID can not be rather than pool size");
|
||||
return _nodePool[unitID];
|
||||
}
|
||||
|
||||
void NodeMemPool::updateNodeData(std::size_t unitID, se_object_ptr dirty, se_object_ptr trs, se_object_ptr localMat, se_object_ptr worldMat, se_object_ptr parent, se_object_ptr zOrder, se_object_ptr cullingMask, se_object_ptr opacity, se_object_ptr is3D, se_object_ptr node, se_object_ptr skew, se_object_ptr sortingPriority, se_object_ptr sortingEnabled)
|
||||
{
|
||||
// UnitID may equal to node pool size, then node pool must increase size.
|
||||
CCASSERT(unitID <= _nodePool.size(), "NodeMemPool updateNodeData unitID can not be rather than pool size");
|
||||
|
||||
UnitNode* unit = nullptr;
|
||||
if (unitID == _nodePool.size())
|
||||
{
|
||||
unit = new UnitNode;
|
||||
_nodePool.push_back(unit);
|
||||
}
|
||||
else if (unitID < _nodePool.size())
|
||||
{
|
||||
unit = _nodePool[unitID];
|
||||
if(!unit)
|
||||
{
|
||||
unit = new UnitNode;
|
||||
_nodePool[unitID] = unit;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
unit->unitID = unitID;
|
||||
unit->setDirty(dirty);
|
||||
unit->setTRS(trs);
|
||||
unit->setLocalMat(localMat);
|
||||
unit->setWorldMat(worldMat);
|
||||
unit->setParent(parent);
|
||||
unit->setZOrder(zOrder);
|
||||
unit->setCullingMask(cullingMask);
|
||||
unit->setOpacity(opacity);
|
||||
unit->setIs3D(is3D);
|
||||
unit->setNode(node);
|
||||
unit->setSkew(skew);
|
||||
unit->setSortingPriority(sortingPriority);
|
||||
unit->setSortingEnabled(sortingEnabled);
|
||||
}
|
||||
|
||||
RENDERER_END
|
@ -0,0 +1,217 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "MemPool.hpp"
|
||||
#include "math/Mat4.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class NodeProxy;
|
||||
|
||||
struct TRS {
|
||||
float x = 0.0f;
|
||||
float y = 0.0f;
|
||||
float z = 0.0f;
|
||||
float qx = 0.0f;
|
||||
float qy = 0.0f;
|
||||
float qz = 0.0f;
|
||||
float qw = 0.0f;
|
||||
float sx = 0.0f;
|
||||
float sy = 0.0f;
|
||||
float sz = 0.0f;
|
||||
};
|
||||
|
||||
#define PARENT_INVALID 0xffffffff
|
||||
struct ParentInfo {
|
||||
uint32_t unitID = 0;
|
||||
uint32_t index = 0;
|
||||
};
|
||||
|
||||
struct Skew {
|
||||
float_t x = 0.0f;
|
||||
float_t y = 0.0f;
|
||||
};
|
||||
|
||||
class UnitNode: public UnitBase {
|
||||
public:
|
||||
UnitNode();
|
||||
virtual ~UnitNode();
|
||||
void setDirty(se::Object* jsData);
|
||||
void setTRS(se::Object* jsData);
|
||||
void setLocalMat(se::Object* jsData);
|
||||
void setWorldMat(se::Object* jsData);
|
||||
void setParent(se::Object* jsData);
|
||||
void setZOrder(se::Object* jsData);
|
||||
void setCullingMask(se::Object* jsData);
|
||||
void setOpacity(se::Object* jsData);
|
||||
void setIs3D(se::Object* jsData);
|
||||
void setNode(se::Object* jsData);
|
||||
void setLevel(se::Object* jsData);
|
||||
void setSkew(se::Object* jsData);
|
||||
void setSortingPriority(se::Object* jsData);
|
||||
void setSortingEnabled(se::Object* jsData);
|
||||
|
||||
uint32_t* getDirty(std::size_t index) const
|
||||
{
|
||||
return dirtyData + index;
|
||||
}
|
||||
|
||||
TRS* getTRS(std::size_t index) const
|
||||
{
|
||||
return (TRS*)trsData + index;
|
||||
}
|
||||
|
||||
cocos2d::Mat4* getLocalMat(std::size_t index) const
|
||||
{
|
||||
return (cocos2d::Mat4*)localMatData + index;
|
||||
}
|
||||
|
||||
cocos2d::Mat4* getWorldMat(std::size_t index) const
|
||||
{
|
||||
return (cocos2d::Mat4*)worldMatData + index;
|
||||
}
|
||||
|
||||
ParentInfo* getParent(std::size_t index) const
|
||||
{
|
||||
return (ParentInfo*)parentData + index;
|
||||
}
|
||||
|
||||
int32_t* getZOrder(std::size_t index) const
|
||||
{
|
||||
return zOrderData + index;
|
||||
}
|
||||
|
||||
int32_t* getCullingMask(std::size_t index) const
|
||||
{
|
||||
return cullingMaskData + index;
|
||||
}
|
||||
|
||||
uint8_t* getOpacity(std::size_t index) const
|
||||
{
|
||||
return opacityData + index;
|
||||
}
|
||||
|
||||
uint8_t* getIs3D(std::size_t index) const
|
||||
{
|
||||
return is3DData + index;
|
||||
}
|
||||
|
||||
uint64_t* getNode(std::size_t index) const
|
||||
{
|
||||
return nodeData + index;
|
||||
}
|
||||
|
||||
Skew* getSkew(std::size_t index) const
|
||||
{
|
||||
return (Skew*)skewData + index;
|
||||
}
|
||||
|
||||
float_t* getSortingPriority(std::size_t index) const
|
||||
{
|
||||
return (float_t*)sortingPriorityData + index;
|
||||
}
|
||||
|
||||
uint8_t* getSortingEnabled(std::size_t index) const
|
||||
{
|
||||
return sortingEnabledData + index;
|
||||
}
|
||||
|
||||
protected:
|
||||
se::Object* dirty = nullptr;
|
||||
uint32_t* dirtyData = nullptr;
|
||||
std::size_t dirtyLen = 0;
|
||||
|
||||
se::Object* trs = nullptr;
|
||||
float_t* trsData = nullptr;
|
||||
std::size_t trsLen = 0;
|
||||
|
||||
se::Object* localMat = nullptr;
|
||||
float_t* localMatData = nullptr;
|
||||
std::size_t localMatLen = 0;
|
||||
|
||||
se::Object* worldMat = nullptr;
|
||||
float_t* worldMatData = nullptr;
|
||||
std::size_t worldMatLen = 0;
|
||||
|
||||
se::Object* parent = nullptr;
|
||||
uint32_t* parentData = nullptr;
|
||||
std::size_t parentLen = 0;
|
||||
|
||||
se::Object* zOrder = nullptr;
|
||||
int32_t* zOrderData = nullptr;
|
||||
std::size_t zOrderLen = 0;
|
||||
|
||||
se::Object* cullingMask = nullptr;
|
||||
int32_t* cullingMaskData = nullptr;
|
||||
std::size_t cullingMaskLen = 0;
|
||||
|
||||
se::Object* opacity = nullptr;
|
||||
uint8_t* opacityData = nullptr;
|
||||
std::size_t opacityLen = 0;
|
||||
|
||||
se::Object* is3D = nullptr;
|
||||
uint8_t* is3DData = nullptr;
|
||||
std::size_t is3DLen = 0;
|
||||
|
||||
se::Object* node = nullptr;
|
||||
uint64_t* nodeData = nullptr;
|
||||
std::size_t nodeLen = 0;
|
||||
|
||||
se::Object* skew = nullptr;
|
||||
float_t* skewData = nullptr;
|
||||
std::size_t skewLen = 0;
|
||||
|
||||
se::Object* sortingPriority = nullptr;
|
||||
float_t* sortingPriorityData = nullptr;
|
||||
std::size_t sortingPriorityLen = 0;
|
||||
|
||||
se::Object* sortingEnabled = nullptr;
|
||||
uint8_t* sortingEnabledData = nullptr;
|
||||
std::size_t sortingEnabledLen = 0;
|
||||
};
|
||||
|
||||
class NodeMemPool: public MemPool {
|
||||
public:
|
||||
NodeMemPool();
|
||||
virtual ~NodeMemPool();
|
||||
|
||||
static NodeMemPool* getInstance()
|
||||
{
|
||||
return _instance;
|
||||
}
|
||||
|
||||
void removeNodeData(std::size_t unitID);
|
||||
|
||||
void updateNodeData(std::size_t unitID, se_object_ptr dirty, se_object_ptr trs, se_object_ptr localMat, se_object_ptr worldMat, se_object_ptr parent, se_object_ptr zOrder, se_object_ptr cullingMask, se_object_ptr opacity, se_object_ptr is3D, se_object_ptr node, se_object_ptr skew, se_object_ptr sortingPriority, se_object_ptr sortingEnabled);
|
||||
|
||||
UnitNode* getUnit(std::size_t unitID) const;
|
||||
const std::vector<UnitNode*>& getNodePool() const;
|
||||
private:
|
||||
static NodeMemPool* _instance;
|
||||
std::vector<UnitNode*> _nodePool;
|
||||
};
|
||||
|
||||
RENDERER_END
|
@ -0,0 +1,633 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "NodeProxy.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "ModelBatcher.hpp"
|
||||
#include "../renderer/Scene.h"
|
||||
#include "base/ccMacros.h"
|
||||
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
|
||||
#include "cocos/scripting/js-bindings/manual/jsb_conversions.hpp"
|
||||
#include "cocos/scripting/js-bindings/auto/jsb_renderer_auto.hpp"
|
||||
#include "NodeMemPool.hpp"
|
||||
#include <math.h>
|
||||
#include "RenderFlow.hpp"
|
||||
#include "assembler/AssemblerSprite.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
uint32_t NodeProxy::_globalRenderOrder = 0;
|
||||
|
||||
NodeProxy::NodeProxy(std::size_t unitID, std::size_t index, const std::string& id, const std::string& name)
|
||||
{
|
||||
traverseHandle = render;
|
||||
|
||||
_id = id;
|
||||
_unitID = unitID;
|
||||
_index = index;
|
||||
_name = name;
|
||||
|
||||
NodeMemPool* pool = NodeMemPool::getInstance();
|
||||
CCASSERT(pool, "NodeProxy constructor NodeMemPool is null");
|
||||
UnitNode* unit = pool->getUnit(unitID);
|
||||
CCASSERT(unit, "NodeProxy constructor unit is null");
|
||||
|
||||
UnitCommon* common = pool->getCommonUnit(unitID);
|
||||
_signData = common->getSignData(_index);
|
||||
|
||||
_dirty = unit->getDirty(index);
|
||||
*_dirty &= ~RenderFlow::PRE_CALCULATE_VERTICES;
|
||||
|
||||
_trs = unit->getTRS(index);
|
||||
_localMat = unit->getLocalMat(index);
|
||||
_worldMat = unit->getWorldMat(index);
|
||||
_parentInfo = unit->getParent(index);
|
||||
_parentInfo->unitID = PARENT_INVALID;
|
||||
_parentInfo->index = PARENT_INVALID;
|
||||
_localZOrder = unit->getZOrder(index);
|
||||
_cullingMask = unit->getCullingMask(index);
|
||||
_opacity = unit->getOpacity(index);
|
||||
_is3DNode = unit->getIs3D(index);
|
||||
_skew = unit->getSkew(index);
|
||||
_sortingPriority = unit->getSortingPriority(index);
|
||||
_sortingEnabled = unit->getSortingEnabled(index);
|
||||
|
||||
uint64_t* self = unit->getNode(index);
|
||||
*self = (uint64_t)this;
|
||||
}
|
||||
|
||||
NodeProxy::~NodeProxy()
|
||||
{
|
||||
for (auto& child : _children)
|
||||
{
|
||||
child->_parent = nullptr;
|
||||
}
|
||||
|
||||
CC_SAFE_RELEASE(_assembler);
|
||||
}
|
||||
|
||||
void NodeProxy::destroyImmediately()
|
||||
{
|
||||
if (_parent)
|
||||
{
|
||||
_parent->removeChild(this);
|
||||
}
|
||||
RenderFlow::getInstance()->removeNodeLevel(_level, _worldMat);
|
||||
CC_SAFE_RELEASE_NULL(_assembler);
|
||||
_level = NODE_LEVEL_INVALID;
|
||||
_dirty = nullptr;
|
||||
_trs = nullptr;
|
||||
_localMat = nullptr;
|
||||
_worldMat = nullptr;
|
||||
_parentInfo = nullptr;
|
||||
_localZOrder = nullptr;
|
||||
_cullingMask = nullptr;
|
||||
_opacity = nullptr;
|
||||
_is3DNode = nullptr;
|
||||
_skew = nullptr;
|
||||
_sortingPriority = nullptr;
|
||||
_sortingEnabled = nullptr;
|
||||
}
|
||||
|
||||
// lazy allocs
|
||||
void NodeProxy::childrenAlloc()
|
||||
{
|
||||
_children.reserve(4);
|
||||
}
|
||||
|
||||
void NodeProxy::addChild(NodeProxy* child)
|
||||
{
|
||||
if (child == nullptr)
|
||||
{
|
||||
CCLOGWARN("Argument must be non-nil");
|
||||
return;
|
||||
}
|
||||
if (child->_parent != nullptr)
|
||||
{
|
||||
CCLOGWARN("child already added. It can't be added again");
|
||||
return;
|
||||
}
|
||||
auto assertNotSelfChild
|
||||
( [ this, child ]() -> bool
|
||||
{
|
||||
for ( NodeProxy* parent( this ); parent != nullptr;
|
||||
parent = parent->getParent() )
|
||||
if ( parent == child )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
} );
|
||||
(void)assertNotSelfChild;
|
||||
|
||||
if (!assertNotSelfChild())
|
||||
{
|
||||
CCLOGWARN("A node cannot be the child of his own children" );
|
||||
return;
|
||||
}
|
||||
|
||||
if (_children.empty())
|
||||
{
|
||||
this->childrenAlloc();
|
||||
}
|
||||
_children.pushBack(child);
|
||||
child->setParent(this);
|
||||
}
|
||||
|
||||
void NodeProxy::detachChild(NodeProxy *child, ssize_t childIndex)
|
||||
{
|
||||
// set parent nil at the end
|
||||
child->setParent(nullptr);
|
||||
_children.erase(childIndex);
|
||||
}
|
||||
|
||||
void NodeProxy::removeChild(NodeProxy* child)
|
||||
{
|
||||
// explicit nil handling
|
||||
if (_children.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ssize_t index = _children.getIndex(child);
|
||||
if( index != CC_INVALID_INDEX )
|
||||
this->detachChild( child, index );
|
||||
}
|
||||
|
||||
void NodeProxy::removeAllChildren()
|
||||
{
|
||||
// not using detachChild improves speed here
|
||||
for (const auto& child : _children)
|
||||
{
|
||||
// set parent nil at the end
|
||||
child->setParent(nullptr);
|
||||
}
|
||||
|
||||
_children.clear();
|
||||
}
|
||||
|
||||
NodeProxy* NodeProxy::getChildByName(std::string childName)
|
||||
{
|
||||
for (auto child : _children)
|
||||
{
|
||||
if (child->_name == childName)
|
||||
{
|
||||
return child;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NodeProxy* NodeProxy::getChildByID(std::string id)
|
||||
{
|
||||
for (auto child : _children)
|
||||
{
|
||||
if (child->_id == id)
|
||||
{
|
||||
return child;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void NodeProxy::notifyUpdateParent()
|
||||
{
|
||||
if (_parentInfo->index == PARENT_INVALID)
|
||||
{
|
||||
if (_parent)
|
||||
{
|
||||
_parent->removeChild(this);
|
||||
}
|
||||
updateLevel();
|
||||
return;
|
||||
}
|
||||
|
||||
NodeMemPool* pool = NodeMemPool::getInstance();
|
||||
CCASSERT(pool, "NodeProxy updateParent NodeMemPool is null");
|
||||
UnitNode* unit = pool->getUnit(_parentInfo->unitID);
|
||||
CCASSERT(unit, "NodeProxy updateParent unit is null");
|
||||
uint64_t* parentAddrs = unit->getNode(_parentInfo->index);
|
||||
NodeProxy* parent = (NodeProxy*)*parentAddrs;
|
||||
CCASSERT(parent, "NodeProxy updateParent parent is null");
|
||||
|
||||
if (parent != _parent) {
|
||||
if (_parent)
|
||||
{
|
||||
_parent->removeChild(this);
|
||||
}
|
||||
parent->addChild(this);
|
||||
updateLevel();
|
||||
}
|
||||
}
|
||||
|
||||
void NodeProxy::updateLevel()
|
||||
{
|
||||
static RenderFlow::LevelInfo levelInfo;
|
||||
auto renderFlow = RenderFlow::getInstance();
|
||||
|
||||
renderFlow->removeNodeLevel(_level, _worldMat);
|
||||
|
||||
levelInfo.dirty = _dirty;
|
||||
levelInfo.localMat = _localMat;
|
||||
levelInfo.worldMat = _worldMat;
|
||||
levelInfo.opacity = _opacity;
|
||||
levelInfo.realOpacity = &_realOpacity;
|
||||
|
||||
if (_parent)
|
||||
{
|
||||
_level = _parent->_level + 1;
|
||||
levelInfo.parentWorldMat = _parent->_worldMat;
|
||||
levelInfo.parentDirty = _parent->_dirty;
|
||||
levelInfo.parentRealOpacity = &_parent->_realOpacity;
|
||||
}
|
||||
else
|
||||
{
|
||||
_level = 0;
|
||||
levelInfo.parentWorldMat = nullptr;
|
||||
levelInfo.parentDirty = nullptr;
|
||||
levelInfo.parentRealOpacity = nullptr;
|
||||
}
|
||||
renderFlow->insertNodeLevel(_level, levelInfo);
|
||||
|
||||
for (auto it = _children.begin(); it != _children.end(); it++)
|
||||
{
|
||||
(*it)->updateLevel();
|
||||
}
|
||||
}
|
||||
|
||||
void NodeProxy::setLocalZOrder(int zOrder)
|
||||
{
|
||||
if (*_localZOrder != zOrder)
|
||||
{
|
||||
*_localZOrder = zOrder;
|
||||
if (_parent != nullptr)
|
||||
{
|
||||
*_parent->_dirty |= RenderFlow::REORDER_CHILDREN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NodeProxy::reorderChildren()
|
||||
{
|
||||
if (*_dirty & RenderFlow::REORDER_CHILDREN)
|
||||
{
|
||||
#if CC_64BITS
|
||||
std::sort(std::begin(_children), std::end(_children), [](NodeProxy* n1, NodeProxy* n2) {
|
||||
return (*n1->_localZOrder < *n2->_localZOrder);
|
||||
});
|
||||
#else
|
||||
std::stable_sort(std::begin(_children), std::end(_children), [](NodeProxy* n1, NodeProxy* n2) {
|
||||
return *n1->_localZOrder < *n2->_localZOrder;
|
||||
});
|
||||
#endif
|
||||
*_dirty &= ~RenderFlow::REORDER_CHILDREN;
|
||||
}
|
||||
}
|
||||
|
||||
void NodeProxy::setAssembler(AssemblerBase* assembler)
|
||||
{
|
||||
if (assembler == _assembler) return;
|
||||
CC_SAFE_RELEASE(_assembler);
|
||||
_assembler = assembler;
|
||||
CC_SAFE_RETAIN(_assembler);
|
||||
|
||||
auto assemblerSprite = dynamic_cast<AssemblerSprite*>(_assembler);
|
||||
if (assemblerSprite)
|
||||
{
|
||||
*_dirty |= RenderFlow::PRE_CALCULATE_VERTICES;
|
||||
}
|
||||
else
|
||||
{
|
||||
*_dirty &= ~RenderFlow::PRE_CALCULATE_VERTICES;
|
||||
}
|
||||
}
|
||||
|
||||
void NodeProxy::clearAssembler()
|
||||
{
|
||||
CC_SAFE_RELEASE_NULL(_assembler);
|
||||
*_dirty &= ~RenderFlow::PRE_CALCULATE_VERTICES;
|
||||
}
|
||||
|
||||
AssemblerBase* NodeProxy::getAssembler() const
|
||||
{
|
||||
return _assembler;
|
||||
}
|
||||
|
||||
void NodeProxy::getPosition(cocos2d::Vec3* out) const
|
||||
{
|
||||
out->x = _trs->x;
|
||||
out->y = _trs->y;
|
||||
out->z = _trs->z;
|
||||
}
|
||||
|
||||
void NodeProxy::getRotation(cocos2d::Quaternion* out) const
|
||||
{
|
||||
out->x = _trs->qx;
|
||||
out->y = _trs->qy;
|
||||
out->z = _trs->qz;
|
||||
out->w = _trs->qw;
|
||||
}
|
||||
|
||||
void NodeProxy::getScale(cocos2d::Vec3* out) const
|
||||
{
|
||||
out->x = _trs->sx;
|
||||
out->y = _trs->sy;
|
||||
out->z = _trs->sz;
|
||||
}
|
||||
|
||||
void NodeProxy::getWorldRotation(cocos2d::Quaternion* out) const
|
||||
{
|
||||
getRotation(out);
|
||||
|
||||
cocos2d::Quaternion rot;
|
||||
NodeProxy* curr = _parent;
|
||||
while (curr != nullptr)
|
||||
{
|
||||
curr->getRotation(&rot);
|
||||
Quaternion::multiply(rot, *out, out);
|
||||
curr = curr->getParent();
|
||||
}
|
||||
}
|
||||
|
||||
void NodeProxy::getWorldPosition(cocos2d::Vec3* out) const
|
||||
{
|
||||
getPosition(out);
|
||||
|
||||
cocos2d::Vec3 pos;
|
||||
cocos2d::Quaternion rot;
|
||||
cocos2d::Vec3 scale;
|
||||
NodeProxy* curr = _parent;
|
||||
while (curr != nullptr)
|
||||
{
|
||||
curr->getPosition(&pos);
|
||||
curr->getRotation(&rot);
|
||||
curr->getScale(&scale);
|
||||
|
||||
out->multiply(scale);
|
||||
out->transformQuat(rot);
|
||||
out->add(pos);
|
||||
curr = curr->getParent();
|
||||
}
|
||||
}
|
||||
|
||||
void NodeProxy::getWorldRT(cocos2d::Mat4* out) const
|
||||
{
|
||||
cocos2d::Vec3 opos(_trs->x, _trs->y, _trs->z);
|
||||
cocos2d::Quaternion orot(_trs->qx, _trs->qy, _trs->qz, _trs->qw);
|
||||
|
||||
cocos2d::Vec3 pos;
|
||||
cocos2d::Quaternion rot;
|
||||
cocos2d::Vec3 scale;
|
||||
NodeProxy* curr = _parent;
|
||||
while (curr != nullptr)
|
||||
{
|
||||
curr->getPosition(&pos);
|
||||
curr->getRotation(&rot);
|
||||
curr->getScale(&scale);
|
||||
|
||||
opos.multiply(scale);
|
||||
opos.transformQuat(rot);
|
||||
opos.add(pos);
|
||||
Quaternion::multiply(rot, orot, &orot);
|
||||
curr = curr->getParent();
|
||||
}
|
||||
out->setIdentity();
|
||||
out->translate(opos);
|
||||
cocos2d::Mat4 quatMat;
|
||||
cocos2d::Mat4::createRotation(orot, &quatMat);
|
||||
out->multiply(quatMat);
|
||||
}
|
||||
|
||||
void NodeProxy::setOpacity(uint8_t opacity)
|
||||
{
|
||||
if (*_opacity != opacity)
|
||||
{
|
||||
*_opacity = opacity;
|
||||
*_dirty |= RenderFlow::OPACITY;
|
||||
}
|
||||
}
|
||||
|
||||
void NodeProxy::updateRealOpacity()
|
||||
{
|
||||
bool selfOpacityDirty = *_dirty & RenderFlow::OPACITY;
|
||||
if (_parent)
|
||||
{
|
||||
if (selfOpacityDirty || *_parent->_dirty & RenderFlow::NODE_OPACITY_CHANGED)
|
||||
{
|
||||
_realOpacity = *_opacity * _parent->getRealOpacity() / 255.0f;
|
||||
*_dirty &= ~RenderFlow::OPACITY;
|
||||
*_dirty |= RenderFlow::NODE_OPACITY_CHANGED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (selfOpacityDirty)
|
||||
{
|
||||
_realOpacity = *_opacity;
|
||||
*_dirty &= ~RenderFlow::OPACITY;
|
||||
*_dirty |= RenderFlow::NODE_OPACITY_CHANGED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NodeProxy::updateWorldMatrix()
|
||||
{
|
||||
if (!_updateWorldMatrix) return;
|
||||
|
||||
bool selfWorldDirty = *_dirty & RenderFlow::WORLD_TRANSFORM;
|
||||
if (_parent)
|
||||
{
|
||||
if (selfWorldDirty || *_parent->_dirty & RenderFlow::WORLD_TRANSFORM_CHANGED)
|
||||
{
|
||||
cocos2d::Mat4::multiply(_parent->getWorldMatrix(), *_localMat, _worldMat);
|
||||
*_dirty &= ~RenderFlow::WORLD_TRANSFORM;
|
||||
*_dirty |= RenderFlow::WORLD_TRANSFORM_CHANGED;
|
||||
}
|
||||
}
|
||||
else if (selfWorldDirty)
|
||||
{
|
||||
*_worldMat = *_localMat;
|
||||
*_dirty &= ~RenderFlow::WORLD_TRANSFORM;
|
||||
*_dirty |= RenderFlow::WORLD_TRANSFORM_CHANGED;
|
||||
}
|
||||
}
|
||||
|
||||
void NodeProxy::updateWorldMatrix(const cocos2d::Mat4& worldMatrix)
|
||||
{
|
||||
*_worldMat = worldMatrix;
|
||||
*_dirty &= ~RenderFlow::WORLD_TRANSFORM;
|
||||
*_dirty |= RenderFlow::WORLD_TRANSFORM_CHANGED;
|
||||
}
|
||||
|
||||
void NodeProxy::updateLocalMatrix()
|
||||
{
|
||||
bool skew = std::abs(_skew->x - 0.0f) > MATH_EPSILON || std::abs(_skew->y - 0.0f) > MATH_EPSILON;
|
||||
if (*_dirty & RenderFlow::LOCAL_TRANSFORM || skew)
|
||||
{
|
||||
_localMat->setIdentity();
|
||||
|
||||
// Transform = Translate * Rotation * Scale;
|
||||
cocos2d::Quaternion q(_trs->qx, _trs->qy, _trs->qz, _trs->qw);
|
||||
if (*_is3DNode)
|
||||
{
|
||||
_localMat->translate(_trs->x, _trs->y, _trs->z);
|
||||
_localMat->rotate(q);
|
||||
_localMat->scale(_trs->sx, _trs->sy, _trs->sz);
|
||||
}
|
||||
else
|
||||
{
|
||||
_localMat->translate(_trs->x, _trs->y, 0);
|
||||
_localMat->rotate(q);
|
||||
_localMat->scale(_trs->sx, _trs->sy, 1);
|
||||
}
|
||||
|
||||
if (skew)
|
||||
{
|
||||
auto& m = _localMat->m;
|
||||
auto a = m[0];
|
||||
auto b = m[1];
|
||||
auto c = m[4];
|
||||
auto d = m[5];
|
||||
auto skx = (float)tanf(CC_DEGREES_TO_RADIANS(_skew->x));
|
||||
auto sky = (float)tanf(CC_DEGREES_TO_RADIANS(_skew->y));
|
||||
m[0] = a + c * sky;
|
||||
m[1] = b + d * sky;
|
||||
m[4] = c + a * skx;
|
||||
m[5] = d + b * skx;
|
||||
}
|
||||
|
||||
*_dirty &= ~RenderFlow::LOCAL_TRANSFORM;
|
||||
*_dirty |= RenderFlow::WORLD_TRANSFORM;
|
||||
}
|
||||
}
|
||||
|
||||
void NodeProxy::render(NodeProxy* node, ModelBatcher* batcher, Scene* scene)
|
||||
{
|
||||
node->_renderOrder = _globalRenderOrder++;
|
||||
|
||||
if (!node->_needVisit || node->_realOpacity == 0) return;
|
||||
|
||||
float_t preSortingPriority = batcher->getSortingPriority();
|
||||
batcher->setSortingPriority(node->getSortingEnabled() ? node->getSortingPriority() : preSortingPriority);
|
||||
|
||||
bool needRender = *node->_dirty & RenderFlow::RENDER;
|
||||
if (node->_needRender != needRender)
|
||||
{
|
||||
if (node->_assembler) node->_assembler->enableDirty(AssemblerBase::VERTICES_OPACITY_CHANGED);
|
||||
node->_needRender = needRender;
|
||||
}
|
||||
|
||||
// pre render
|
||||
if (node->_assembler && needRender) {
|
||||
if(node->_assembler->isMaskAssembler()){
|
||||
batcher->flushRendererCache();
|
||||
node->_assembler->handle(node, batcher, scene);
|
||||
}else{
|
||||
batcher->pushRendererCache(node);
|
||||
node->setRenderPriority(batcher->getSortingPriority());
|
||||
if(batcher->getSortingPriority() != 0){
|
||||
batcher->setRendererOrder(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
node->reorderChildren();
|
||||
for (const auto& child : node->_children)
|
||||
{
|
||||
auto traverseHandle = child->traverseHandle;
|
||||
traverseHandle(child, batcher, scene);
|
||||
}
|
||||
|
||||
// post render
|
||||
bool needPostRender = *(node->_dirty) & RenderFlow::POST_RENDER;
|
||||
if (node->_assembler && needPostRender){
|
||||
if(node->_assembler->isMaskAssembler()){
|
||||
batcher->flushRendererCache();
|
||||
}
|
||||
node->_assembler->postHandle(node, batcher, scene);
|
||||
}
|
||||
|
||||
batcher->setSortingPriority(preSortingPriority);
|
||||
}
|
||||
|
||||
void NodeProxy::visit(NodeProxy* node, ModelBatcher* batcher, Scene* scene)
|
||||
{
|
||||
node->_renderOrder = _globalRenderOrder++;
|
||||
|
||||
if (!node->_needVisit) return;
|
||||
|
||||
node->updateRealOpacity();
|
||||
|
||||
if (node->_realOpacity == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
node->updateLocalMatrix();
|
||||
node->updateWorldMatrix();
|
||||
|
||||
float_t preSortingPriority = batcher->getSortingPriority();
|
||||
batcher->setSortingPriority(node->getSortingEnabled() ? node->getSortingPriority() : preSortingPriority);
|
||||
|
||||
bool needRender = *(node->_dirty) & RenderFlow::RENDER;
|
||||
if (node->_needRender != needRender)
|
||||
{
|
||||
if (node->_assembler) node->_assembler->enableDirty(AssemblerBase::VERTICES_OPACITY_CHANGED);
|
||||
node->_needRender = needRender;
|
||||
}
|
||||
|
||||
// pre render
|
||||
if (node->_assembler && needRender){
|
||||
if(node->_assembler->isMaskAssembler()){
|
||||
batcher->flushRendererCache();
|
||||
node->_assembler->handle(node, batcher, scene);
|
||||
}else{
|
||||
batcher->pushRendererCache(node);
|
||||
node->setRenderPriority(batcher->getSortingPriority());
|
||||
if(batcher->getSortingPriority() != 0){
|
||||
batcher->setRendererOrder(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
node->reorderChildren();
|
||||
for (const auto& child : node->_children)
|
||||
{
|
||||
visit(child, batcher, scene);
|
||||
}
|
||||
|
||||
// post render
|
||||
bool needPostRender = *(node->_dirty) & RenderFlow::POST_RENDER;
|
||||
if (node->_assembler && needPostRender){
|
||||
if(node->_assembler->isMaskAssembler()){
|
||||
batcher->flushRendererCache();
|
||||
}
|
||||
node->_assembler->postHandle(node, batcher, scene);
|
||||
}
|
||||
|
||||
batcher->setSortingPriority(preSortingPriority);
|
||||
}
|
||||
|
||||
RENDERER_END
|
@ -0,0 +1,379 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include "../Macro.h"
|
||||
#include "base/CCRef.h"
|
||||
#include "base/ccTypes.h"
|
||||
#include "base/CCVector.h"
|
||||
#include "base/CCMap.h"
|
||||
#include "math/CCMath.h"
|
||||
#include "assembler/AssemblerBase.hpp"
|
||||
#include "MemPool.hpp"
|
||||
#include <functional>
|
||||
|
||||
namespace se {
|
||||
class Object;
|
||||
}
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class ModelBatcher;
|
||||
class Scene;
|
||||
struct TRS;
|
||||
struct ParentInfo;
|
||||
struct Skew;
|
||||
|
||||
/**
|
||||
* @addtogroup scene
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief NodeProxy is a cpp delegator of js Node.\n
|
||||
* It synchronize the hierarchy from js node tree, update the transform each frame, and manages assembler which represent the render component.\n
|
||||
* JS API: renderer.NodeProxy
|
||||
@code
|
||||
let node = new cc.Node();
|
||||
// NodeProxy is automatically created by cc.Node
|
||||
let proxy = node._proxy;
|
||||
@endcode
|
||||
*/
|
||||
class NodeProxy : public Ref
|
||||
{
|
||||
public:
|
||||
typedef std::function<void(NodeProxy*, ModelBatcher*, Scene*)> TraverseFunc;
|
||||
|
||||
/*
|
||||
* @brief Visit the node but do not transform position.
|
||||
*/
|
||||
static void render(NodeProxy* node, ModelBatcher* batcher, Scene* scene);
|
||||
/*
|
||||
* @brief Visit the node as a ordinary node but not a root node.
|
||||
*/
|
||||
static void visit(NodeProxy* node, ModelBatcher* batcher, Scene* scene);
|
||||
/*
|
||||
* @brief Reset global render order.
|
||||
*/
|
||||
static void resetGlobalRenderOrder() { _globalRenderOrder = 0; }
|
||||
|
||||
/*
|
||||
* @brief The default constructor.
|
||||
*/
|
||||
NodeProxy(std::size_t unitID, std::size_t index, const std::string& id, const std::string& name);
|
||||
/*
|
||||
* @brief The destructor.
|
||||
*/
|
||||
~NodeProxy();
|
||||
/*
|
||||
* @brief destroy node data immediately .
|
||||
*/
|
||||
void destroyImmediately();
|
||||
|
||||
/*
|
||||
* @brief If js node has been destroy.
|
||||
*/
|
||||
bool isValid() { return _trs != nullptr; }
|
||||
|
||||
/// @{
|
||||
/// @name Hierarchy
|
||||
|
||||
/**
|
||||
* @brief Adds child node proxy to the node proxy.
|
||||
* @param[in] child A child node proxy pointer.
|
||||
*/
|
||||
void addChild(NodeProxy * child);
|
||||
/**
|
||||
* @brief Removes child node proxy from the node proxy.
|
||||
* @param[in] child A child node proxy pointer.
|
||||
*/
|
||||
void removeChild(NodeProxy* child);
|
||||
/**
|
||||
* @brief Removes all child node proxies from the current one.
|
||||
*/
|
||||
void removeAllChildren();
|
||||
/**
|
||||
* @brief Update parent by parent unitId and index.
|
||||
*/
|
||||
void notifyUpdateParent();
|
||||
|
||||
/**
|
||||
* @brief Sets the node proxy parent.
|
||||
* @param[in] parent.
|
||||
*/
|
||||
inline void setParent(NodeProxy* parent) { _parent = parent; };
|
||||
/**
|
||||
* @brief Gets the node proxy parent.
|
||||
* @return Parent.
|
||||
*/
|
||||
inline NodeProxy* getParent() const { return _parent; };
|
||||
/**
|
||||
* @brief Gets the node proxy all children.
|
||||
* @return Children container.
|
||||
*/
|
||||
inline const Vector<NodeProxy*>& getChildren() const { return _children; };
|
||||
/**
|
||||
* @brief Gets the node proxy child count.
|
||||
* @return Child count.
|
||||
*/
|
||||
inline size_t getChildrenCount() const { return _children.size(); };
|
||||
/**
|
||||
* @brief Gets a child node by name.
|
||||
* @return Child node.
|
||||
*/
|
||||
NodeProxy* getChildByName(std::string childName);
|
||||
/**
|
||||
* @brief Gets a child node by runtime id.
|
||||
* @return Child node.
|
||||
*/
|
||||
NodeProxy* getChildByID(std::string id);
|
||||
/**
|
||||
* @brief Sets the node proxy's local zorder.
|
||||
* @param[in] zOrder The value of zorder.
|
||||
*/
|
||||
void setLocalZOrder(int zOrder);
|
||||
|
||||
/// @} end of Hierarchy
|
||||
|
||||
/*
|
||||
* @brief Gets the world matrix.
|
||||
* @return World matrix.
|
||||
*/
|
||||
inline const cocos2d::Mat4& getWorldMatrix() const { return *_worldMat; };
|
||||
|
||||
/*
|
||||
* @brief Gets the local matrix.
|
||||
* @return Local matrix.
|
||||
*/
|
||||
inline const cocos2d::Mat4& getLocalMatrix() const { return *_localMat; };
|
||||
|
||||
/*
|
||||
* @brief Gets the position.
|
||||
* @param[out] out The position vector
|
||||
*/
|
||||
void getPosition(cocos2d::Vec3* out) const;
|
||||
/*
|
||||
* @brief Gets the rotation.
|
||||
* @param[out] out The rotation quaternion.
|
||||
*/
|
||||
void getRotation(cocos2d::Quaternion* out) const;
|
||||
/*
|
||||
* @brief Gets the scale.
|
||||
* @param[out] out The scale vector.
|
||||
*/
|
||||
void getScale(cocos2d::Vec3* out) const;
|
||||
/*
|
||||
* @brief Gets world rotation.
|
||||
* @param[out] out The rotation quaternion.
|
||||
*/
|
||||
void getWorldRotation(cocos2d::Quaternion* out) const;
|
||||
/*
|
||||
* @brief Gets the position in world coordinates.
|
||||
* @param[out] out The world position vector.
|
||||
*/
|
||||
void getWorldPosition(cocos2d::Vec3* out) const;
|
||||
/*
|
||||
* @brief Gets the matrix contains the world rotation and translation.
|
||||
* @param[out] out The matrix to store datas.
|
||||
*/
|
||||
void getWorldRT(cocos2d::Mat4* out) const;
|
||||
|
||||
/**
|
||||
* @brief Gets the node's opacity.
|
||||
*/
|
||||
inline uint8_t getOpacity() const { return *_opacity; };
|
||||
/**
|
||||
* @brief Sets the node's opacity.
|
||||
*/
|
||||
void setOpacity(uint8_t opacity);
|
||||
/**
|
||||
* @brief Updates opacity from parent.
|
||||
*/
|
||||
void updateRealOpacity();
|
||||
/**
|
||||
* @brief Gets the node's realOpacity.
|
||||
*/
|
||||
inline const uint8_t getRealOpacity() const {return _realOpacity;};
|
||||
/**
|
||||
* @brief Gets the node's group id, this controls which camera can see the node.
|
||||
*/
|
||||
inline int getCullingMask() const { return *_cullingMask; };
|
||||
/**
|
||||
* @brief Sets the node's group id.
|
||||
* @param[in] groupID The group id
|
||||
*/
|
||||
inline void setCullingMask(int cullingMask) { *_cullingMask = cullingMask; };
|
||||
|
||||
/**
|
||||
* @brief Gets the node's name.
|
||||
* This equals to the one in JS node, helps to debug in cpp.
|
||||
* @return name
|
||||
*/
|
||||
inline const std::string& getName() const { return _name; };
|
||||
/**
|
||||
* @brief Sets the node's name.
|
||||
* The name should be updated once JS node's name changes.
|
||||
* @param[in] name
|
||||
*/
|
||||
inline void setName(const std::string& name) { _name = name; };
|
||||
|
||||
/**
|
||||
* @brief Sets the node's 3D state.
|
||||
* @param[in] is3DNode
|
||||
*/
|
||||
inline void set3DNode(bool is3DNode) { *_is3DNode = is3DNode ? 0x1 : 0x0; };
|
||||
|
||||
/**
|
||||
* @brief Sets a system handle to the node proxy, system handle will be invoked during node's visit process.
|
||||
* @param[in] handle The system handle pointer.
|
||||
*/
|
||||
void setAssembler(AssemblerBase* assembler);
|
||||
/**
|
||||
* @brief Removes a system handle from node proxy by system id.
|
||||
* @param[in] sysid The system id.
|
||||
*/
|
||||
void clearAssembler();
|
||||
/**
|
||||
* @brief Gets the system handle by system id.
|
||||
* @param[in] sysid The system id.
|
||||
* @return The system handle object or nullptr if not exist
|
||||
*/
|
||||
AssemblerBase* getAssembler() const;
|
||||
/*
|
||||
* @brief Enables visit.
|
||||
*/
|
||||
void enableVisit(bool value) { _needVisit = value; }
|
||||
|
||||
/*
|
||||
* @brief Disables visit.
|
||||
*/
|
||||
void disableVisit() { _needVisit = false; }
|
||||
|
||||
/*
|
||||
* @brief Updates local matrix.
|
||||
*/
|
||||
void updateLocalMatrix();
|
||||
/*
|
||||
* @brief Updates world matrix.
|
||||
*/
|
||||
void updateWorldMatrix();
|
||||
/*
|
||||
* @brief Updates world matrix with provide matrix.
|
||||
*/
|
||||
void updateWorldMatrix(const cocos2d::Mat4& worldMatrix);
|
||||
/*
|
||||
* @brief Enables calc world matrix.
|
||||
*/
|
||||
void enableUpdateWorldMatrix(bool value) { _updateWorldMatrix = value; }
|
||||
|
||||
/*
|
||||
* @brief Gets node runtime id
|
||||
*/
|
||||
const std::string& getID() const { return _id; }
|
||||
|
||||
/*
|
||||
* @brief Gets node dirty
|
||||
*/
|
||||
uint32_t* getDirty() const { return _dirty; }
|
||||
|
||||
/*
|
||||
* @brief Is node flag dirty
|
||||
*/
|
||||
bool isDirty(uint32_t flag) const { return *_dirty & flag; }
|
||||
|
||||
/*
|
||||
* @brief Gets render order
|
||||
*/
|
||||
uint32_t getRenderOrder () { return _renderOrder; }
|
||||
|
||||
/*
|
||||
* @brief switch traverse interface to visit
|
||||
*/
|
||||
void switchTraverseToVisit() { traverseHandle = visit; }
|
||||
/*
|
||||
* @brief switch traverse interface to render
|
||||
*/
|
||||
void switchTraverseToRender() { traverseHandle = render; }
|
||||
|
||||
/*
|
||||
* @brief traverse handle
|
||||
*/
|
||||
TraverseFunc traverseHandle = nullptr;
|
||||
|
||||
float_t getRenderPriority() const { return _renderPriority; }
|
||||
void setRenderPriority(float_t value) { _renderPriority = value; };
|
||||
bool getSortingEnabled() { return *_sortingEnabled != 0; }
|
||||
float_t getSortingPriority() const { return *_sortingPriority ; }
|
||||
protected:
|
||||
void updateLevel();
|
||||
void childrenAlloc();
|
||||
void detachChild(NodeProxy* child, ssize_t childIndex);
|
||||
void reorderChildren();
|
||||
private:
|
||||
bool _needVisit = true;
|
||||
bool _updateWorldMatrix = true;
|
||||
bool _needRender = false;
|
||||
|
||||
uint8_t _realOpacity = 255;
|
||||
std::string _id = "";
|
||||
std::string _name = "";
|
||||
std::size_t _level = 0;
|
||||
|
||||
uint32_t* _dirty = nullptr;
|
||||
TRS* _trs = nullptr;
|
||||
cocos2d::Mat4* _localMat = nullptr;
|
||||
cocos2d::Mat4* _worldMat = nullptr;
|
||||
ParentInfo* _parentInfo = nullptr;
|
||||
int32_t* _localZOrder = nullptr;
|
||||
int32_t* _cullingMask = nullptr;
|
||||
uint8_t* _opacity = nullptr;
|
||||
uint8_t* _is3DNode = nullptr;
|
||||
Skew* _skew = nullptr;
|
||||
|
||||
float_t* _sortingPriority = nullptr;
|
||||
uint8_t* _sortingEnabled = nullptr;
|
||||
|
||||
std::size_t _unitID = 0;
|
||||
std::size_t _index = 0;
|
||||
|
||||
Sign* _signData = nullptr;
|
||||
NodeProxy* _parent = nullptr; ///< weak reference to parent node
|
||||
cocos2d::Vector<NodeProxy*> _children; ///< array of children nodes
|
||||
|
||||
AssemblerBase* _assembler = nullptr;
|
||||
|
||||
uint32_t _renderOrder = 0;
|
||||
static uint32_t _globalRenderOrder;
|
||||
|
||||
float_t _renderPriority = 0;
|
||||
};
|
||||
|
||||
// end of scene group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
@ -0,0 +1,381 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "RenderFlow.hpp"
|
||||
#include "NodeMemPool.hpp"
|
||||
#include "assembler/AssemblerSprite.hpp"
|
||||
|
||||
#if USE_MIDDLEWARE
|
||||
#include "MiddlewareManager.h"
|
||||
#endif
|
||||
|
||||
#define SUB_RENDER_THREAD_COUNT 1
|
||||
#define RENDER_THREAD_COUNT (SUB_RENDER_THREAD_COUNT + 1)
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
const uint32_t InitLevelCount = 3;
|
||||
const uint32_t InitLevelNodeCount = 100;
|
||||
|
||||
const uint32_t LocalMat_Use_Thread_Unit_Count = 5;
|
||||
const uint32_t WorldMat_Use_Thread_Node_count = 500;
|
||||
|
||||
RenderFlow* RenderFlow::_instance = nullptr;
|
||||
|
||||
RenderFlow::RenderFlow(DeviceGraphics* device, Scene* scene, ForwardRenderer* forward)
|
||||
: _device(device)
|
||||
, _scene(scene)
|
||||
, _forward(forward)
|
||||
{
|
||||
_instance = this;
|
||||
|
||||
_batcher = new ModelBatcher(this);
|
||||
|
||||
#if SUB_RENDER_THREAD_COUNT > 0
|
||||
_paralleTask = new ParallelTask();
|
||||
_paralleTask->init(SUB_RENDER_THREAD_COUNT);
|
||||
|
||||
for (uint32_t i = 0; i < SUB_RENDER_THREAD_COUNT; i++)
|
||||
{
|
||||
_paralleTask->pushTask(i, [this](int tid){
|
||||
switch(_parallelStage)
|
||||
{
|
||||
case ParallelStage::LOCAL_MAT:
|
||||
calculateLocalMatrix(tid);
|
||||
break;
|
||||
case ParallelStage::WORLD_MAT:
|
||||
calculateLevelWorldMatrix(tid, _parallelStage);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
#endif
|
||||
|
||||
_levelInfoArr.resize(InitLevelCount);
|
||||
for (auto i = 0; i < InitLevelCount; i++)
|
||||
{
|
||||
_levelInfoArr[i].reserve(InitLevelNodeCount);
|
||||
}
|
||||
}
|
||||
|
||||
RenderFlow::~RenderFlow()
|
||||
{
|
||||
CC_SAFE_DELETE(_paralleTask);
|
||||
CC_SAFE_DELETE(_batcher);
|
||||
}
|
||||
|
||||
void RenderFlow::removeNodeLevel(std::size_t level, cocos2d::Mat4* worldMat)
|
||||
{
|
||||
if (level >= _levelInfoArr.size()) return;
|
||||
auto& levelInfos = _levelInfoArr[level];
|
||||
for(auto it = levelInfos.begin(); it != levelInfos.end(); it++)
|
||||
{
|
||||
if (it->worldMat == worldMat)
|
||||
{
|
||||
levelInfos.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderFlow::insertNodeLevel(std::size_t level, const LevelInfo& levelInfo)
|
||||
{
|
||||
if (level >= _levelInfoArr.size())
|
||||
{
|
||||
_levelInfoArr.resize(level + 1);
|
||||
}
|
||||
auto& levelInfos = _levelInfoArr[level];
|
||||
levelInfos.push_back(levelInfo);
|
||||
}
|
||||
|
||||
void RenderFlow::calculateLocalMatrix(int tid)
|
||||
{
|
||||
const uint16_t SPACE_FREE_FLAG = 0x0;
|
||||
cocos2d::Mat4 matTemp;
|
||||
|
||||
NodeMemPool* instance = NodeMemPool::getInstance();
|
||||
CCASSERT(instance, "RenderFlow calculateLocalMatrix NodeMemPool is null");
|
||||
auto& commonList = instance->getCommonList();
|
||||
auto& nodePool = instance->getNodePool();
|
||||
|
||||
UnitCommon* commonUnit = nullptr;
|
||||
uint16_t usingNum = 0;
|
||||
std::size_t contentNum = 0;
|
||||
Sign* signData = nullptr;
|
||||
UnitNode* nodeUnit = nullptr;
|
||||
uint32_t* dirty = nullptr;
|
||||
cocos2d::Mat4* localMat = nullptr;
|
||||
TRS* trs = nullptr;
|
||||
uint8_t* is3D = nullptr;
|
||||
cocos2d::Quaternion* quat = nullptr;
|
||||
float trsZ = 0.0f, trsSZ = 0.0f;
|
||||
|
||||
std::size_t begin = 0, end = commonList.size();
|
||||
std::size_t fieldSize = end / RENDER_THREAD_COUNT;
|
||||
if (tid >= 0)
|
||||
{
|
||||
begin = tid * fieldSize;
|
||||
if (tid < RENDER_THREAD_COUNT - 1)
|
||||
{
|
||||
end = (tid + 1) * fieldSize;
|
||||
}
|
||||
}
|
||||
|
||||
for(auto i = begin; i < end; i++)
|
||||
{
|
||||
commonUnit = commonList[i];
|
||||
if (!commonUnit) continue;
|
||||
usingNum = commonUnit->getUsingNum();
|
||||
if (usingNum == 0) continue;
|
||||
|
||||
contentNum = commonUnit->getContentNum();
|
||||
signData = commonUnit->getSignData(0);
|
||||
|
||||
nodeUnit = nodePool[commonUnit->unitID];
|
||||
|
||||
dirty = nodeUnit->getDirty(0);
|
||||
localMat = nodeUnit->getLocalMat(0);
|
||||
trs = nodeUnit->getTRS(0);
|
||||
is3D = nodeUnit->getIs3D(0);
|
||||
|
||||
NodeProxy** nodeProxy = (NodeProxy**)nodeUnit->getNode(0);
|
||||
|
||||
for (auto j = 0; j < contentNum; j++, localMat ++, trs ++, is3D ++, signData++, dirty++, nodeProxy++)
|
||||
{
|
||||
if (signData->freeFlag == SPACE_FREE_FLAG) continue;
|
||||
|
||||
// reset world transform changed flag
|
||||
*dirty &= ~(WORLD_TRANSFORM_CHANGED | NODE_OPACITY_CHANGED);
|
||||
if (!(*dirty & LOCAL_TRANSFORM)) continue;
|
||||
|
||||
localMat->setIdentity();
|
||||
trsZ = *is3D ? trs->z : 0;
|
||||
localMat->translate(trs->x, trs->y, trsZ);
|
||||
|
||||
quat = (cocos2d::Quaternion*)&(trs->qx);
|
||||
cocos2d::Mat4::createRotation(*quat, &matTemp);
|
||||
cocos2d::Mat4::multiply(*localMat, matTemp, localMat);
|
||||
|
||||
trsSZ = *is3D ? trs->sz : 1;
|
||||
cocos2d::Mat4::createScale(trs->sx, trs->sy, trsSZ, &matTemp);
|
||||
cocos2d::Mat4::multiply(*localMat, matTemp, localMat);
|
||||
|
||||
*dirty &= ~LOCAL_TRANSFORM;
|
||||
*dirty |= WORLD_TRANSFORM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderFlow::calculateLevelWorldMatrix(int tid, int stage)
|
||||
{
|
||||
if (_curLevel >= _levelInfoArr.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto& levelInfos = _levelInfoArr[_curLevel];
|
||||
|
||||
std::size_t begin = 0, end = levelInfos.size();
|
||||
std::size_t fieldSize = end / RENDER_THREAD_COUNT;
|
||||
if (tid >= 0)
|
||||
{
|
||||
begin = tid * fieldSize;
|
||||
if (tid < RENDER_THREAD_COUNT - 1)
|
||||
{
|
||||
end = (tid + 1) * fieldSize;
|
||||
}
|
||||
}
|
||||
|
||||
for(std::size_t index = begin; index < end; index++)
|
||||
{
|
||||
auto& info = levelInfos[index];
|
||||
auto dirty = info.dirty;
|
||||
auto parentDirty = info.parentDirty;
|
||||
auto selfWorldDirty = *dirty & WORLD_TRANSFORM;
|
||||
auto selfOpacityDirty = *dirty & OPACITY;
|
||||
|
||||
if (parentDirty)
|
||||
{
|
||||
if ((*parentDirty & WORLD_TRANSFORM_CHANGED) || selfWorldDirty)
|
||||
{
|
||||
cocos2d::Mat4::multiply(*info.parentWorldMat, *info.localMat, info.worldMat);
|
||||
*dirty |= WORLD_TRANSFORM_CHANGED;
|
||||
*dirty &= ~WORLD_TRANSFORM;
|
||||
}
|
||||
|
||||
if ((*parentDirty & NODE_OPACITY_CHANGED) || selfOpacityDirty)
|
||||
{
|
||||
*info.realOpacity = *info.opacity * *info.parentRealOpacity / 255.0f;
|
||||
*dirty |= NODE_OPACITY_CHANGED;
|
||||
*dirty &= ~OPACITY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (selfWorldDirty)
|
||||
{
|
||||
*info.worldMat = *info.localMat;
|
||||
*dirty |= WORLD_TRANSFORM_CHANGED;
|
||||
*dirty &= ~WORLD_TRANSFORM;
|
||||
}
|
||||
|
||||
if (selfOpacityDirty)
|
||||
{
|
||||
*info.realOpacity = *info.opacity;
|
||||
*dirty |= NODE_OPACITY_CHANGED;
|
||||
*dirty &= ~OPACITY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderFlow::calculateWorldMatrix()
|
||||
{
|
||||
for(std::size_t level = 0, n = _levelInfoArr.size(); level < n; level++)
|
||||
{
|
||||
auto& levelInfos = _levelInfoArr[level];
|
||||
for(std::size_t index = 0, count = levelInfos.size(); index < count; index++)
|
||||
{
|
||||
auto& info = levelInfos[index];
|
||||
auto selfWorldDirty = *info.dirty & WORLD_TRANSFORM;
|
||||
auto selfOpacityDirty = *info.dirty & OPACITY;
|
||||
|
||||
if (info.parentDirty)
|
||||
{
|
||||
if ((*info.parentDirty & WORLD_TRANSFORM_CHANGED) || selfWorldDirty)
|
||||
{
|
||||
cocos2d::Mat4::multiply(*info.parentWorldMat, *info.localMat, info.worldMat);
|
||||
*info.dirty |= WORLD_TRANSFORM_CHANGED;
|
||||
*info.dirty &= ~WORLD_TRANSFORM;
|
||||
}
|
||||
|
||||
if ((*info.parentDirty & NODE_OPACITY_CHANGED) || selfOpacityDirty)
|
||||
{
|
||||
*info.realOpacity = *info.opacity * *info.parentRealOpacity / 255.0f;
|
||||
*info.dirty |= NODE_OPACITY_CHANGED;
|
||||
*info.dirty &= ~OPACITY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (selfWorldDirty)
|
||||
{
|
||||
*info.worldMat = *info.localMat;
|
||||
*info.dirty |= WORLD_TRANSFORM_CHANGED;
|
||||
*info.dirty &= ~WORLD_TRANSFORM;
|
||||
}
|
||||
|
||||
if (selfOpacityDirty)
|
||||
{
|
||||
*info.realOpacity = *info.opacity;
|
||||
*info.dirty |= NODE_OPACITY_CHANGED;
|
||||
*info.dirty &= ~OPACITY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderFlow::render(NodeProxy* scene, float deltaTime, Camera *camera)
|
||||
{
|
||||
if (scene != nullptr)
|
||||
{
|
||||
|
||||
#if USE_MIDDLEWARE
|
||||
// udpate middleware before render
|
||||
middleware::MiddlewareManager::getInstance()->update(deltaTime);
|
||||
#endif
|
||||
|
||||
#if SUB_RENDER_THREAD_COUNT > 0
|
||||
|
||||
int mainThreadTid = RENDER_THREAD_COUNT - 1;
|
||||
|
||||
NodeMemPool* instance = NodeMemPool::getInstance();
|
||||
auto& commonList = instance->getCommonList();
|
||||
if (commonList.size() < LocalMat_Use_Thread_Unit_Count)
|
||||
{
|
||||
_parallelStage = ParallelStage::NONE;
|
||||
calculateLocalMatrix();
|
||||
}
|
||||
else
|
||||
{
|
||||
_parallelStage = ParallelStage::LOCAL_MAT;
|
||||
_paralleTask->beginAllThreads();
|
||||
calculateLocalMatrix(mainThreadTid);
|
||||
_paralleTask->waitAllThreads();
|
||||
}
|
||||
|
||||
_curLevel = 0;
|
||||
for(auto count = _levelInfoArr.size(); _curLevel < count; _curLevel++)
|
||||
{
|
||||
auto& levelInfos = _levelInfoArr[_curLevel];
|
||||
if (levelInfos.size() < WorldMat_Use_Thread_Node_count)
|
||||
{
|
||||
_parallelStage = ParallelStage::NONE;
|
||||
calculateLevelWorldMatrix();
|
||||
}
|
||||
else
|
||||
{
|
||||
_parallelStage = ParallelStage::WORLD_MAT;
|
||||
_paralleTask->beginAllThreads();
|
||||
calculateLevelWorldMatrix(mainThreadTid);
|
||||
_paralleTask->waitAllThreads();
|
||||
}
|
||||
}
|
||||
#else
|
||||
calculateLocalMatrix();
|
||||
calculateWorldMatrix();
|
||||
#endif
|
||||
|
||||
_batcher->startBatch();
|
||||
_batcher->setSortingPriority(0);
|
||||
_batcher->setRendererOrder(false);
|
||||
|
||||
#if USE_MIDDLEWARE
|
||||
// render middleware
|
||||
middleware::MiddlewareManager::getInstance()->render(deltaTime);
|
||||
#endif
|
||||
scene->resetGlobalRenderOrder();
|
||||
|
||||
auto traverseHandle = scene->traverseHandle;
|
||||
traverseHandle(scene, _batcher, _scene);
|
||||
_batcher->terminateBatch();
|
||||
|
||||
if (camera) {
|
||||
_forward->renderCamera(camera, _scene);
|
||||
}
|
||||
else {
|
||||
_forward->render(_scene, deltaTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderFlow::visit(NodeProxy* rootNode)
|
||||
{
|
||||
NodeProxy::visit(rootNode, _batcher, _scene);
|
||||
}
|
||||
|
||||
RENDERER_END
|
@ -0,0 +1,180 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Macro.h"
|
||||
#include "NodeProxy.hpp"
|
||||
#include "ModelBatcher.hpp"
|
||||
#include "../renderer/Scene.h"
|
||||
#include "../renderer/ForwardRenderer.h"
|
||||
#include "../gfx/DeviceGraphics.h"
|
||||
#include "ParallelTask.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
/**
|
||||
* @addtogroup scene
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This class is responsible for the rendering process.\n
|
||||
* It visits the node tree, let nodes commit their render handles, starts the device level rendering process with ForwardRenderer.\n
|
||||
* JS API: renderer.RenderFlow
|
||||
@code
|
||||
// You actually shouldn't create RenderFlow by yourself, you can
|
||||
let renderFlow = cc.RenderFlow._nativeFlow;
|
||||
@endcode
|
||||
*/
|
||||
|
||||
#define NODE_LEVEL_INVALID 0xffffffff
|
||||
|
||||
class RenderFlow
|
||||
{
|
||||
public:
|
||||
|
||||
enum RenderFlowFlag {
|
||||
// sync js render flag
|
||||
|
||||
DONOTHING = 1 << 0,
|
||||
BREAK_FLOW = 1 << 1,
|
||||
LOCAL_TRANSFORM = 1 << 2,
|
||||
WORLD_TRANSFORM = 1 << 3,
|
||||
TRANSFORM = LOCAL_TRANSFORM | WORLD_TRANSFORM,
|
||||
UPDATE_RENDER_DATA = 1 << 4,
|
||||
OPACITY = 1 << 5,
|
||||
COLOR = 1 << 6,
|
||||
RENDER = 1 << 7,
|
||||
CHILDREN = 1 << 8,
|
||||
POST_RENDER = 1 << 9,
|
||||
FINAL = 1 << 10,
|
||||
|
||||
PRE_CALCULATE_VERTICES = 1 << 28,
|
||||
// native render flag
|
||||
REORDER_CHILDREN = 1 << 29,
|
||||
// world matrix changed
|
||||
WORLD_TRANSFORM_CHANGED = 1 << 30,
|
||||
// cascade opacity changed
|
||||
NODE_OPACITY_CHANGED = 1 << 31,
|
||||
};
|
||||
|
||||
enum ParallelStage {
|
||||
NONE = 1 << 0,
|
||||
LOCAL_MAT = 1 << 1,
|
||||
WORLD_MAT = 1 << 2,
|
||||
CALC_VERTICES = 1 << 3,
|
||||
};
|
||||
|
||||
struct LevelInfo{
|
||||
uint32_t* dirty = nullptr;
|
||||
uint32_t* parentDirty = nullptr;
|
||||
cocos2d::Mat4* parentWorldMat = nullptr;
|
||||
uint8_t* parentRealOpacity = nullptr;
|
||||
cocos2d::Mat4* localMat = nullptr;
|
||||
cocos2d::Mat4* worldMat = nullptr;
|
||||
uint8_t* opacity = nullptr;
|
||||
uint8_t* realOpacity = nullptr;
|
||||
};
|
||||
|
||||
static RenderFlow *getInstance()
|
||||
{
|
||||
return _instance;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief The constructor.
|
||||
* @param[in] device
|
||||
* @param[in] scene
|
||||
* @param[in] forward
|
||||
*/
|
||||
RenderFlow(DeviceGraphics* device, Scene* scene, ForwardRenderer* forward);
|
||||
/*
|
||||
* @brief The destructor.
|
||||
*/
|
||||
~RenderFlow();
|
||||
|
||||
/*
|
||||
* @brief Gets the ModelBatcher which is responsible for collecting render Models.
|
||||
*/
|
||||
ModelBatcher* getModelBatcher() const { return _batcher; };
|
||||
/*
|
||||
* @brief Gets the DeviceGraphics using by the current RenderFlow.
|
||||
*/
|
||||
DeviceGraphics* getDevice() const { return _device; };
|
||||
/*
|
||||
* @brief Gets the render Scene which manages all render Models.
|
||||
*/
|
||||
Scene* getRenderScene() const { return _scene; };
|
||||
/**
|
||||
* @brief Render the scene specified by its root node.
|
||||
* @param[in] scene The root node.
|
||||
*/
|
||||
void render(NodeProxy* scene, float deltaTime, Camera *camera = nullptr);
|
||||
/**
|
||||
* @brief Visit a node tree.
|
||||
*/
|
||||
void visit(NodeProxy* rootNode);
|
||||
/**
|
||||
* @brief Calculate local matrix.
|
||||
* @param[in] tid It must rather than -1 if enable multiple thread.
|
||||
*/
|
||||
void calculateLocalMatrix(int tid = -1);
|
||||
/**
|
||||
* @brief Calculate world matrix.
|
||||
*/
|
||||
void calculateWorldMatrix();
|
||||
/**
|
||||
* @brief Calculate world matrix by level.
|
||||
* @param[in] tid Thread id.
|
||||
* @param[level] level Node level.
|
||||
*/
|
||||
void calculateLevelWorldMatrix(int tid = -1, int stage = -1);
|
||||
/**
|
||||
* @brief remove node level
|
||||
*/
|
||||
void removeNodeLevel(std::size_t level, cocos2d::Mat4* worldMat);
|
||||
/**
|
||||
* @brief insert node level
|
||||
*/
|
||||
void insertNodeLevel(std::size_t level, const LevelInfo& levelInfo);
|
||||
private:
|
||||
|
||||
static RenderFlow *_instance;
|
||||
|
||||
ModelBatcher* _batcher = nullptr;
|
||||
Scene* _scene = nullptr;
|
||||
DeviceGraphics* _device = nullptr;
|
||||
ForwardRenderer* _forward = nullptr;
|
||||
std::size_t _curLevel = 0;
|
||||
std::vector<std::vector<LevelInfo>> _levelInfoArr;
|
||||
|
||||
ParallelStage _parallelStage = ParallelStage::NONE;
|
||||
ParallelTask* _paralleTask = nullptr;
|
||||
};
|
||||
|
||||
// end of scene group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
@ -0,0 +1,69 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "AssemblerBase.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
AssemblerBase::AssemblerBase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
AssemblerBase::~AssemblerBase()
|
||||
{
|
||||
if (_jsDirty)
|
||||
{
|
||||
_jsDirty->unroot();
|
||||
_jsDirty->decRef();
|
||||
_jsDirty = nullptr;
|
||||
}
|
||||
_dirty = nullptr;
|
||||
_dirtyLen = 0;
|
||||
|
||||
clearCustomWorldMatirx();
|
||||
}
|
||||
|
||||
void AssemblerBase::setDirty(se_object_ptr jsDirty)
|
||||
{
|
||||
if (_jsDirty == jsDirty) return;
|
||||
|
||||
if (_jsDirty)
|
||||
{
|
||||
_jsDirty->unroot();
|
||||
_jsDirty->decRef();
|
||||
_jsDirty = nullptr;
|
||||
}
|
||||
|
||||
if (jsDirty == nullptr) return;
|
||||
|
||||
_jsDirty = jsDirty;
|
||||
_jsDirty->root();
|
||||
_jsDirty->incRef();
|
||||
_dirty = nullptr;
|
||||
_dirtyLen = 0;
|
||||
_jsDirty->getTypedArrayData((uint8_t**)&_dirty, &_dirtyLen);
|
||||
}
|
||||
|
||||
RENDERER_END
|
@ -0,0 +1,193 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../Macro.h"
|
||||
#include <stdint.h>
|
||||
#include "base/CCVector.h"
|
||||
#include "../../renderer/Effect.h"
|
||||
#include "scripting/js-bindings/jswrapper/Object.hpp"
|
||||
#include "math/Mat4.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class NodeProxy;
|
||||
class ModelBatcher;
|
||||
class Scene;
|
||||
|
||||
/**
|
||||
* @addtogroup scene
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Base class for all assembler
|
||||
* A assembler could take actions during node visit process, before and after all children visit.
|
||||
*/
|
||||
class AssemblerBase: public cocos2d::Ref
|
||||
{
|
||||
public:
|
||||
|
||||
enum AssemblerFlag {
|
||||
VERTICES_OPACITY_CHANGED = 1 << 0,
|
||||
VERTICES_DIRTY = 1 << 1,
|
||||
};
|
||||
|
||||
AssemblerBase();
|
||||
|
||||
virtual ~AssemblerBase();
|
||||
|
||||
/**
|
||||
* @brief Callback which will be invoked before visiting child nodes.
|
||||
* @param[in] node The node being processed.
|
||||
* @param[in] batcher
|
||||
* @param[in] scene
|
||||
*/
|
||||
virtual void handle(NodeProxy *node, ModelBatcher* batcher, Scene* scene) {}
|
||||
/**
|
||||
* @brief Callback which will be invoked after visiting child nodes.
|
||||
* @param[in] node The node being processed.
|
||||
* @param[in] batcher
|
||||
* @param[in] scene
|
||||
*/
|
||||
virtual void postHandle(NodeProxy *node, ModelBatcher* batcher, Scene* scene) {}
|
||||
|
||||
/**
|
||||
* @brief Gets whether the current handle should use model matrix uniform during rendering
|
||||
*/
|
||||
bool getUseModel() const
|
||||
{
|
||||
return _useModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets whether the current handle should use model matrix uniform during rendering
|
||||
*/
|
||||
void setUseModel(bool useModel)
|
||||
{
|
||||
_useModel = useModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets custom world matrix
|
||||
*/
|
||||
const cocos2d::Mat4* getCustomWorldMatrix() const
|
||||
{
|
||||
return _worldMatrix;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets custom world matrix
|
||||
*/
|
||||
void setCustomWorldMatrix(const cocos2d::Mat4& matrix)
|
||||
{
|
||||
if (!_worldMatrix)
|
||||
{
|
||||
_worldMatrix = new cocos2d::Mat4();
|
||||
}
|
||||
*_worldMatrix = matrix;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear custom world matrix
|
||||
*/
|
||||
void clearCustomWorldMatirx()
|
||||
{
|
||||
if (_worldMatrix)
|
||||
{
|
||||
delete _worldMatrix;
|
||||
_worldMatrix = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sync script dirty flag.
|
||||
*/
|
||||
void setDirty(se_object_ptr jsDirty);
|
||||
|
||||
/**
|
||||
* @brief Changes dirty flag.
|
||||
*/
|
||||
void enableDirty(uint32_t flag)
|
||||
{
|
||||
if (_dirty)
|
||||
{
|
||||
*_dirty |= flag;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Changes dirty flag.
|
||||
*/
|
||||
void disableDirty(uint32_t flag)
|
||||
{
|
||||
if (_dirty)
|
||||
{
|
||||
*_dirty &= ~flag;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Is flag dirty.
|
||||
*/
|
||||
bool isDirty(uint32_t flag)
|
||||
{
|
||||
if (_dirty)
|
||||
{
|
||||
return *_dirty & flag;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resets data.
|
||||
*/
|
||||
virtual void reset() {}
|
||||
|
||||
bool isMaskAssembler() const
|
||||
{
|
||||
return _isMaskAssembler;
|
||||
}
|
||||
|
||||
void setMaskAssembler()
|
||||
{
|
||||
_isMaskAssembler = true;
|
||||
}
|
||||
|
||||
protected:
|
||||
se::Object* _jsDirty = nullptr;
|
||||
uint32_t* _dirty = nullptr;
|
||||
std::size_t _dirtyLen = 0;
|
||||
|
||||
bool _useModel = false;
|
||||
cocos2d::Mat4* _worldMatrix = nullptr;
|
||||
|
||||
bool _isMaskAssembler = false;
|
||||
};
|
||||
|
||||
// end of scene group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
@ -0,0 +1,92 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "MaskAssembler.hpp"
|
||||
#include "../ModelBatcher.hpp"
|
||||
#include "../StencilManager.hpp"
|
||||
#include "../../Macro.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
MaskAssembler::MaskAssembler()
|
||||
{
|
||||
setMaskAssembler();
|
||||
}
|
||||
|
||||
MaskAssembler::~MaskAssembler()
|
||||
{
|
||||
CC_SAFE_RELEASE(_renderSubHandle);
|
||||
CC_SAFE_RELEASE(_clearSubHandle);
|
||||
}
|
||||
|
||||
void MaskAssembler::setRenderSubHandle(Assembler* renderSubHandle)
|
||||
{
|
||||
if (_renderSubHandle == renderSubHandle) return;
|
||||
CC_SAFE_RELEASE(_renderSubHandle);
|
||||
_renderSubHandle = renderSubHandle;
|
||||
CC_SAFE_RETAIN(_renderSubHandle);
|
||||
}
|
||||
|
||||
void MaskAssembler::setClearSubHandle(Assembler* clearSubHandle)
|
||||
{
|
||||
if (_clearSubHandle == clearSubHandle) return;
|
||||
CC_SAFE_RELEASE(_clearSubHandle);
|
||||
_clearSubHandle = clearSubHandle;
|
||||
CC_SAFE_RETAIN(_clearSubHandle);
|
||||
}
|
||||
|
||||
void MaskAssembler::handle(NodeProxy *node, ModelBatcher* batcher, Scene* scene)
|
||||
{
|
||||
batcher->flush();
|
||||
batcher->flushIA();
|
||||
|
||||
StencilManager* instance = StencilManager::getInstance();
|
||||
instance->pushMask(_inverted);
|
||||
instance->clear();
|
||||
batcher->commit(node, _clearSubHandle, node->getCullingMask());
|
||||
batcher->flush();
|
||||
instance->enterLevel();
|
||||
|
||||
if (_imageStencil)
|
||||
{
|
||||
batcher->commit(node, this, node->getCullingMask());
|
||||
}
|
||||
else if (_renderSubHandle)
|
||||
{
|
||||
_renderSubHandle->handle(node, batcher, scene);
|
||||
}
|
||||
|
||||
batcher->flush();
|
||||
instance->enableMask();
|
||||
}
|
||||
|
||||
void MaskAssembler::postHandle(NodeProxy *node, ModelBatcher *batcher, Scene *scene)
|
||||
{
|
||||
batcher->flush();
|
||||
batcher->flushIA();
|
||||
batcher->setCurrentEffect(getEffect(0));
|
||||
StencilManager::getInstance()->exitMask();
|
||||
}
|
||||
|
||||
RENDERER_END
|
@ -0,0 +1,62 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include "Assembler.hpp"
|
||||
#include "../MeshBuffer.hpp"
|
||||
#include "math/CCMath.h"
|
||||
#include "SimpleSprite2D.hpp"
|
||||
|
||||
class ModelBatcher;
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class MaskAssembler: public SimpleSprite2D
|
||||
{
|
||||
public:
|
||||
MaskAssembler();
|
||||
virtual ~MaskAssembler();
|
||||
virtual void handle(NodeProxy *node, ModelBatcher* batcher, Scene* scene) override;
|
||||
virtual void postHandle(NodeProxy *node, ModelBatcher* batcher, Scene* scene) override;
|
||||
|
||||
void setMaskInverted(bool inverted) { _inverted = inverted; };
|
||||
bool getMaskInverted() { return _inverted; };
|
||||
|
||||
void setRenderSubHandle(Assembler* renderSubHandle);
|
||||
void setClearSubHandle(Assembler* clearSubHandle);
|
||||
|
||||
void setImageStencil(bool isImageStencil) { _imageStencil = isImageStencil; };
|
||||
|
||||
protected:
|
||||
bool _inverted = false;
|
||||
bool _imageStencil = false;
|
||||
|
||||
private:
|
||||
Assembler* _renderSubHandle = nullptr;
|
||||
Assembler* _clearSubHandle = nullptr;
|
||||
};
|
||||
|
||||
RENDERER_END
|
1
2.4.11/lcc-ui-sorting-group-native/readme.txt
Normal file
@ -0,0 +1 @@
|
||||
cocos creator 2.4.11
|
8
2.4.11/project.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"engine": "cocos-creator-js",
|
||||
"packages": "packages",
|
||||
"name": "lcc-ui-sorting-group-2.4.x-demo",
|
||||
"id": "e7de0a0e-0144-4f35-98b5-dfc103ea8611",
|
||||
"version": "2.4.11",
|
||||
"isNew": false
|
||||
}
|
55
2.4.11/settings/builder.json
Normal file
@ -0,0 +1,55 @@
|
||||
{
|
||||
"title": "lcc-ui-sorting-group-2_4_x-demo",
|
||||
"packageName": "org.cocos2d.demo",
|
||||
"startScene": "c6ba3258-b873-4d4f-b31a-60f4c79e523a",
|
||||
"excludeScenes": [],
|
||||
"orientation": {
|
||||
"landscapeRight": true,
|
||||
"landscapeLeft": true,
|
||||
"portrait": false,
|
||||
"upsideDown": false
|
||||
},
|
||||
"webOrientation": "landscape",
|
||||
"inlineSpriteFrames": true,
|
||||
"inlineSpriteFrames_native": true,
|
||||
"mainCompressionType": "default",
|
||||
"mainIsRemote": false,
|
||||
"optimizeHotUpdate": false,
|
||||
"md5Cache": true,
|
||||
"nativeMd5Cache": true,
|
||||
"encryptJs": true,
|
||||
"xxteaKey": "176efd2d-6dc3-43",
|
||||
"zipCompressJs": true,
|
||||
"fb-instant-games": {},
|
||||
"android": {
|
||||
"packageName": "com.lcc.sorting.test",
|
||||
"REMOTE_SERVER_ROOT": ""
|
||||
},
|
||||
"ios": {
|
||||
"packageName": "org.cocos2d.demo",
|
||||
"REMOTE_SERVER_ROOT": "",
|
||||
"ios_enable_jit": true
|
||||
},
|
||||
"mac": {
|
||||
"packageName": "org.cocos2d.demo",
|
||||
"REMOTE_SERVER_ROOT": "",
|
||||
"width": 1280,
|
||||
"height": 720
|
||||
},
|
||||
"win32": {
|
||||
"REMOTE_SERVER_ROOT": "",
|
||||
"width": 1280,
|
||||
"height": 720
|
||||
},
|
||||
"android-instant": {
|
||||
"packageName": "org.cocos2d.demo",
|
||||
"REMOTE_SERVER_ROOT": "",
|
||||
"pathPattern": "",
|
||||
"scheme": "https",
|
||||
"host": "",
|
||||
"skipRecord": false,
|
||||
"recordPath": ""
|
||||
},
|
||||
"appBundle": false,
|
||||
"agreements": {}
|
||||
}
|
37
2.4.11/settings/project.json
Normal file
@ -0,0 +1,37 @@
|
||||
{
|
||||
"group-list": [
|
||||
"default"
|
||||
],
|
||||
"collision-matrix": [
|
||||
[
|
||||
true
|
||||
]
|
||||
],
|
||||
"excluded-modules": [
|
||||
"3D Physics/Builtin"
|
||||
],
|
||||
"preview-port": 7456,
|
||||
"design-resolution-width": 1920,
|
||||
"design-resolution-height": 1080,
|
||||
"fit-width": false,
|
||||
"fit-height": true,
|
||||
"use-project-simulator-setting": false,
|
||||
"simulator-orientation": false,
|
||||
"use-customize-simulator": true,
|
||||
"simulator-resolution": {
|
||||
"width": 960,
|
||||
"height": 640
|
||||
},
|
||||
"clear-simulator-cache": true,
|
||||
"facebook": {
|
||||
"enable": false,
|
||||
"appID": "",
|
||||
"live": {
|
||||
"enable": false
|
||||
},
|
||||
"audience": {
|
||||
"enable": false
|
||||
}
|
||||
},
|
||||
"last-module-event-record-time": 1675838102527
|
||||
}
|
6
2.4.11/settings/services.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"game": {
|
||||
"name": "未知游戏",
|
||||
"appid": "UNKNOW"
|
||||
}
|
||||
}
|
19
2.4.11/tsconfig.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"lib": [ "es2015", "es2017", "dom" ],
|
||||
"target": "es5",
|
||||
"experimentalDecorators": true,
|
||||
"skipLibCheck": true,
|
||||
"outDir": "temp/vscode-dist",
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"library",
|
||||
"local",
|
||||
"temp",
|
||||
"build",
|
||||
"settings"
|
||||
]
|
||||
}
|
0
.gitignore → 3.6.3/.gitignore
vendored
@ -1,21 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 Nomat
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 Nomat
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|