mirror of
https://github.com/smallmain/cocos-enhance-kit.git
synced 2025-10-09 19:15:24 +00:00
初始化
This commit is contained in:
336
engine/cocos2d/particle/CCPNGReader.js
Normal file
336
engine/cocos2d/particle/CCPNGReader.js
Normal file
@@ -0,0 +1,336 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2011 Devon Govett
|
||||
Copyright (c) 2008-2010 Ricardo Quesada
|
||||
Copyright (c) 2011-2012 cocos2d-x.org
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-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.
|
||||
****************************************************************************/
|
||||
|
||||
const zlib = require('../compression/zlib.min');
|
||||
const debug = require('../core/CCDebug');
|
||||
|
||||
/**
|
||||
* A png file reader
|
||||
* @name PNGReader
|
||||
*/
|
||||
var PNGReader = function(data){
|
||||
var chunkSize, colors, delayDen, delayNum, frame, i, index, key, section, ccshort, text, _i, _j, _ref;
|
||||
this.data = data;
|
||||
this.pos = 8;
|
||||
this.palette = [];
|
||||
this.imgData = [];
|
||||
this.transparency = {};
|
||||
this.animation = null;
|
||||
this.text = {};
|
||||
frame = null;
|
||||
while (true) {
|
||||
chunkSize = this.readUInt32();
|
||||
section = ((function() {
|
||||
var _i, _results;
|
||||
_results = [];
|
||||
for (i = _i = 0; _i < 4; i = ++_i) {
|
||||
_results.push(String.fromCharCode(this.data[this.pos++]));
|
||||
}
|
||||
return _results;
|
||||
}).call(this)).join('');
|
||||
switch (section) {
|
||||
case 'IHDR':
|
||||
this.width = this.readUInt32();
|
||||
this.height = this.readUInt32();
|
||||
this.bits = this.data[this.pos++];
|
||||
this.colorType = this.data[this.pos++];
|
||||
this.compressionMethod = this.data[this.pos++];
|
||||
this.filterMethod = this.data[this.pos++];
|
||||
this.interlaceMethod = this.data[this.pos++];
|
||||
break;
|
||||
case 'acTL':
|
||||
this.animation = {
|
||||
numFrames: this.readUInt32(),
|
||||
numPlays: this.readUInt32() || Infinity,
|
||||
frames: []
|
||||
};
|
||||
break;
|
||||
case 'PLTE':
|
||||
this.palette = this.read(chunkSize);
|
||||
break;
|
||||
case 'fcTL':
|
||||
if (frame) {
|
||||
this.animation.frames.push(frame);
|
||||
}
|
||||
this.pos += 4;
|
||||
frame = {
|
||||
width: this.readUInt32(),
|
||||
height: this.readUInt32(),
|
||||
xOffset: this.readUInt32(),
|
||||
yOffset: this.readUInt32()
|
||||
};
|
||||
delayNum = this.readUInt16();
|
||||
delayDen = this.readUInt16() || 100;
|
||||
frame.delay = 1000 * delayNum / delayDen;
|
||||
frame.disposeOp = this.data[this.pos++];
|
||||
frame.blendOp = this.data[this.pos++];
|
||||
frame.data = [];
|
||||
break;
|
||||
case 'IDAT':
|
||||
case 'fdAT':
|
||||
if (section === 'fdAT') {
|
||||
this.pos += 4;
|
||||
chunkSize -= 4;
|
||||
}
|
||||
data = (frame != null ? frame.data : void 0) || this.imgData;
|
||||
for (i = _i = 0; 0 <= chunkSize ? _i < chunkSize : _i > chunkSize; i = 0 <= chunkSize ? ++_i : --_i) {
|
||||
data.push(this.data[this.pos++]);
|
||||
}
|
||||
break;
|
||||
case 'tRNS':
|
||||
this.transparency = {};
|
||||
switch (this.colorType) {
|
||||
case 3:
|
||||
this.transparency.indexed = this.read(chunkSize);
|
||||
ccshort = 255 - this.transparency.indexed.length;
|
||||
if (ccshort > 0) {
|
||||
for (i = _j = 0; 0 <= ccshort ? _j < ccshort : _j > ccshort; i = 0 <= ccshort ? ++_j : --_j) {
|
||||
this.transparency.indexed.push(255);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
this.transparency.grayscale = this.read(chunkSize)[0];
|
||||
break;
|
||||
case 2:
|
||||
this.transparency.rgb = this.read(chunkSize);
|
||||
}
|
||||
break;
|
||||
case 'tEXt':
|
||||
text = this.read(chunkSize);
|
||||
index = text.indexOf(0);
|
||||
key = String.fromCharCode.apply(String, text.slice(0, index));
|
||||
this.text[key] = String.fromCharCode.apply(String, text.slice(index + 1));
|
||||
break;
|
||||
case 'IEND':
|
||||
if (frame) {
|
||||
this.animation.frames.push(frame);
|
||||
}
|
||||
this.colors = (function() {
|
||||
switch (this.colorType) {
|
||||
case 0:
|
||||
case 3:
|
||||
case 4:
|
||||
return 1;
|
||||
case 2:
|
||||
case 6:
|
||||
return 3;
|
||||
}
|
||||
}).call(this);
|
||||
this.hasAlphaChannel = (_ref = this.colorType) === 4 || _ref === 6;
|
||||
colors = this.colors + (this.hasAlphaChannel ? 1 : 0);
|
||||
this.pixelBitlength = this.bits * colors;
|
||||
this.colorSpace = (function() {
|
||||
switch (this.colors) {
|
||||
case 1:
|
||||
return 'DeviceGray';
|
||||
case 3:
|
||||
return 'DeviceRGB';
|
||||
}
|
||||
}).call(this);
|
||||
if(Uint8Array != Array)
|
||||
this.imgData = new Uint8Array(this.imgData);
|
||||
return;
|
||||
default:
|
||||
this.pos += chunkSize;
|
||||
}
|
||||
this.pos += 4;
|
||||
if (this.pos > this.data.length) {
|
||||
throw new Error(debug.getError(6017));
|
||||
}
|
||||
}
|
||||
};
|
||||
PNGReader.prototype = {
|
||||
constructor: PNGReader,
|
||||
read:function(bytes){
|
||||
var i, _i, _results;
|
||||
_results = [];
|
||||
for (i = _i = 0; 0 <= bytes ? _i < bytes : _i > bytes; i = 0 <= bytes ? ++_i : --_i) {
|
||||
_results.push(this.data[this.pos++]);
|
||||
}
|
||||
return _results;
|
||||
},
|
||||
readUInt32:function(){
|
||||
var b1, b2, b3, b4;
|
||||
b1 = this.data[this.pos++] << 24;
|
||||
b2 = this.data[this.pos++] << 16;
|
||||
b3 = this.data[this.pos++] << 8;
|
||||
b4 = this.data[this.pos++];
|
||||
return b1 | b2 | b3 | b4;
|
||||
},
|
||||
readUInt16:function(){
|
||||
var b1, b2;
|
||||
b1 = this.data[this.pos++] << 8;
|
||||
b2 = this.data[this.pos++];
|
||||
return b1 | b2;
|
||||
},
|
||||
decodePixels:function(data){
|
||||
var ccbyte, c, col, i, left, length, p, pa, paeth, pb, pc, pixelBytes, pixels, pos, row, scanlineLength, upper, upperLeft, _i, _j, _k, _l, _m;
|
||||
if (data == null) {
|
||||
data = this.imgData;
|
||||
}
|
||||
if (data.length === 0) {
|
||||
return new Uint8Array(0);
|
||||
}
|
||||
var inflate = new zlib.Inflate(data,{index:0, verify:false});
|
||||
data = inflate.decompress();
|
||||
|
||||
pixelBytes = this.pixelBitlength / 8;
|
||||
scanlineLength = pixelBytes * this.width;
|
||||
pixels = new Uint8Array(scanlineLength * this.height);
|
||||
length = data.length;
|
||||
row = 0;
|
||||
pos = 0;
|
||||
c = 0;
|
||||
while (pos < length) {
|
||||
switch (data[pos++]) {
|
||||
case 0:
|
||||
for (i = _i = 0; _i < scanlineLength; i = _i += 1) {
|
||||
pixels[c++] = data[pos++];
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
for (i = _j = 0; _j < scanlineLength; i = _j += 1) {
|
||||
ccbyte = data[pos++];
|
||||
left = i < pixelBytes ? 0 : pixels[c - pixelBytes];
|
||||
pixels[c++] = (ccbyte + left) % 256;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
for (i = _k = 0; _k < scanlineLength; i = _k += 1) {
|
||||
ccbyte = data[pos++];
|
||||
col = (i - (i % pixelBytes)) / pixelBytes;
|
||||
upper = row && pixels[(row - 1) * scanlineLength + col * pixelBytes + (i % pixelBytes)];
|
||||
pixels[c++] = (upper + ccbyte) % 256;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
for (i = _l = 0; _l < scanlineLength; i = _l += 1) {
|
||||
ccbyte = data[pos++];
|
||||
col = (i - (i % pixelBytes)) / pixelBytes;
|
||||
left = i < pixelBytes ? 0 : pixels[c - pixelBytes];
|
||||
upper = row && pixels[(row - 1) * scanlineLength + col * pixelBytes + (i % pixelBytes)];
|
||||
pixels[c++] = (ccbyte + Math.floor((left + upper) / 2)) % 256;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
for (i = _m = 0; _m < scanlineLength; i = _m += 1) {
|
||||
ccbyte = data[pos++];
|
||||
col = (i - (i % pixelBytes)) / pixelBytes;
|
||||
left = i < pixelBytes ? 0 : pixels[c - pixelBytes];
|
||||
if (row === 0) {
|
||||
upper = upperLeft = 0;
|
||||
} else {
|
||||
upper = pixels[(row - 1) * scanlineLength + col * pixelBytes + (i % pixelBytes)];
|
||||
upperLeft = col && pixels[(row - 1) * scanlineLength + (col - 1) * pixelBytes + (i % pixelBytes)];
|
||||
}
|
||||
p = left + upper - upperLeft;
|
||||
pa = Math.abs(p - left);
|
||||
pb = Math.abs(p - upper);
|
||||
pc = Math.abs(p - upperLeft);
|
||||
if (pa <= pb && pa <= pc) {
|
||||
paeth = left;
|
||||
} else if (pb <= pc) {
|
||||
paeth = upper;
|
||||
} else {
|
||||
paeth = upperLeft;
|
||||
}
|
||||
pixels[c++] = (ccbyte + paeth) % 256;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new Error(debug.getError(6018, data[pos - 1]));
|
||||
}
|
||||
row++;
|
||||
}
|
||||
return pixels;
|
||||
},
|
||||
copyToImageData:function(imageData,pixels){
|
||||
var alpha, colors, data, i, input, j, k, length, palette, v, _ref;
|
||||
colors = this.colors;
|
||||
palette = null;
|
||||
alpha = this.hasAlphaChannel;
|
||||
if (this.palette.length) {
|
||||
palette = (_ref = this._decodedPalette) != null ? _ref : this._decodedPalette = this.decodePalette();
|
||||
colors = 4;
|
||||
alpha = true;
|
||||
}
|
||||
data = imageData.data || imageData;
|
||||
length = data.length;
|
||||
input = palette || pixels;
|
||||
i = j = 0;
|
||||
if (colors === 1) {
|
||||
while (i < length) {
|
||||
k = palette ? pixels[i / 4] * 4 : j;
|
||||
v = input[k++];
|
||||
data[i++] = v;
|
||||
data[i++] = v;
|
||||
data[i++] = v;
|
||||
data[i++] = alpha ? input[k++] : 255;
|
||||
j = k;
|
||||
}
|
||||
} else {
|
||||
while (i < length) {
|
||||
k = palette ? pixels[i / 4] * 4 : j;
|
||||
data[i++] = input[k++];
|
||||
data[i++] = input[k++];
|
||||
data[i++] = input[k++];
|
||||
data[i++] = alpha ? input[k++] : 255;
|
||||
j = k;
|
||||
}
|
||||
}
|
||||
},
|
||||
decodePalette:function(){
|
||||
var c, i, palette, pos, ret, transparency, _i, _ref, _ref1;
|
||||
palette = this.palette;
|
||||
transparency = this.transparency.indexed || [];
|
||||
ret = new Uint8Array((transparency.length || 0) + palette.length);
|
||||
pos = 0;
|
||||
c = 0;
|
||||
for (i = _i = 0, _ref = palette.length; _i < _ref; i = _i += 3) {
|
||||
ret[pos++] = palette[i];
|
||||
ret[pos++] = palette[i + 1];
|
||||
ret[pos++] = palette[i + 2];
|
||||
ret[pos++] = (_ref1 = transparency[c++]) != null ? _ref1 : 255;
|
||||
}
|
||||
return ret;
|
||||
},
|
||||
render: function (canvas) {
|
||||
var ctx, data;
|
||||
canvas.width = this.width;
|
||||
canvas.height = this.height;
|
||||
ctx = canvas.getContext("2d");
|
||||
data = ctx.createImageData(this.width, this.height);
|
||||
this.copyToImageData(data, this.decodePixels());
|
||||
return ctx.putImageData(data, 0, 0);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = PNGReader;
|
47
engine/cocos2d/particle/CCParticleAsset.js
Normal file
47
engine/cocos2d/particle/CCParticleAsset.js
Normal file
@@ -0,0 +1,47 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 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 Asset = require('../core/assets/CCAsset');
|
||||
const CCSpriteFrame = require('../core/assets/CCSpriteFrame');
|
||||
|
||||
/**
|
||||
* Class for particle asset handling.
|
||||
* @class ParticleAsset
|
||||
* @extends Asset
|
||||
*/
|
||||
var ParticleAsset = cc.Class({
|
||||
name: 'cc.ParticleAsset',
|
||||
extends: Asset,
|
||||
|
||||
properties: {
|
||||
spriteFrame: {
|
||||
default: null,
|
||||
type: CCSpriteFrame
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
cc.ParticleAsset = module.exports = ParticleAsset;
|
1272
engine/cocos2d/particle/CCParticleSystem.js
Normal file
1272
engine/cocos2d/particle/CCParticleSystem.js
Normal file
File diff suppressed because it is too large
Load Diff
698
engine/cocos2d/particle/CCTIFFReader.js
Normal file
698
engine/cocos2d/particle/CCTIFFReader.js
Normal file
@@ -0,0 +1,698 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2011 Gordon P. Hemsley
|
||||
http://gphemsley.org/
|
||||
|
||||
Copyright (c) 2008-2010 Ricardo Quesada
|
||||
Copyright (c) 2011-2012 cocos2d-x.org
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 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 debug = require('../core/CCDebug');
|
||||
|
||||
/**
|
||||
* cc.tiffReader is a singleton object, it's a tiff file reader, it can parse byte array to draw into a canvas
|
||||
* @class
|
||||
* @name tiffReader
|
||||
*/
|
||||
var tiffReader = /** @lends tiffReader# */{
|
||||
_littleEndian: false,
|
||||
_tiffData: null,
|
||||
_fileDirectories: [],
|
||||
|
||||
getUint8: function (offset) {
|
||||
return this._tiffData[offset];
|
||||
},
|
||||
|
||||
getUint16: function (offset) {
|
||||
if (this._littleEndian)
|
||||
return (this._tiffData[offset + 1] << 8) | (this._tiffData[offset]);
|
||||
else
|
||||
return (this._tiffData[offset] << 8) | (this._tiffData[offset + 1]);
|
||||
},
|
||||
|
||||
getUint32: function (offset) {
|
||||
var a = this._tiffData;
|
||||
if (this._littleEndian)
|
||||
return (a[offset + 3] << 24) | (a[offset + 2] << 16) | (a[offset + 1] << 8) | (a[offset]);
|
||||
else
|
||||
return (a[offset] << 24) | (a[offset + 1] << 16) | (a[offset + 2] << 8) | (a[offset + 3]);
|
||||
},
|
||||
|
||||
checkLittleEndian: function () {
|
||||
var BOM = this.getUint16(0);
|
||||
|
||||
if (BOM === 0x4949) {
|
||||
this.littleEndian = true;
|
||||
} else if (BOM === 0x4D4D) {
|
||||
this.littleEndian = false;
|
||||
} else {
|
||||
console.log(BOM);
|
||||
throw TypeError(debug.getError(6019));
|
||||
}
|
||||
|
||||
return this.littleEndian;
|
||||
},
|
||||
|
||||
hasTowel: function () {
|
||||
// Check for towel.
|
||||
if (this.getUint16(2) !== 42) {
|
||||
throw RangeError(debug.getError(6020));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
getFieldTypeName: function (fieldType) {
|
||||
var typeNames = this.fieldTypeNames;
|
||||
if (fieldType in typeNames) {
|
||||
return typeNames[fieldType];
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
getFieldTagName: function (fieldTag) {
|
||||
var tagNames = this.fieldTagNames;
|
||||
|
||||
if (fieldTag in tagNames) {
|
||||
return tagNames[fieldTag];
|
||||
} else {
|
||||
cc.logID(6021, fieldTag);
|
||||
return "Tag" + fieldTag;
|
||||
}
|
||||
},
|
||||
|
||||
getFieldTypeLength: function (fieldTypeName) {
|
||||
if (['BYTE', 'ASCII', 'SBYTE', 'UNDEFINED'].indexOf(fieldTypeName) !== -1) {
|
||||
return 1;
|
||||
} else if (['SHORT', 'SSHORT'].indexOf(fieldTypeName) !== -1) {
|
||||
return 2;
|
||||
} else if (['LONG', 'SLONG', 'FLOAT'].indexOf(fieldTypeName) !== -1) {
|
||||
return 4;
|
||||
} else if (['RATIONAL', 'SRATIONAL', 'DOUBLE'].indexOf(fieldTypeName) !== -1) {
|
||||
return 8;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
getFieldValues: function (fieldTagName, fieldTypeName, typeCount, valueOffset) {
|
||||
var fieldValues = [];
|
||||
var fieldTypeLength = this.getFieldTypeLength(fieldTypeName);
|
||||
var fieldValueSize = fieldTypeLength * typeCount;
|
||||
|
||||
if (fieldValueSize <= 4) {
|
||||
// The value is stored at the big end of the valueOffset.
|
||||
if (this.littleEndian === false)
|
||||
fieldValues.push(valueOffset >>> ((4 - fieldTypeLength) * 8));
|
||||
else
|
||||
fieldValues.push(valueOffset);
|
||||
} else {
|
||||
for (var i = 0; i < typeCount; i++) {
|
||||
var indexOffset = fieldTypeLength * i;
|
||||
if (fieldTypeLength >= 8) {
|
||||
if (['RATIONAL', 'SRATIONAL'].indexOf(fieldTypeName) !== -1) {
|
||||
// Numerator
|
||||
fieldValues.push(this.getUint32(valueOffset + indexOffset));
|
||||
// Denominator
|
||||
fieldValues.push(this.getUint32(valueOffset + indexOffset + 4));
|
||||
} else {
|
||||
cc.logID(8000);
|
||||
}
|
||||
} else {
|
||||
fieldValues.push(this.getBytes(fieldTypeLength, valueOffset + indexOffset));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fieldTypeName === 'ASCII') {
|
||||
fieldValues.forEach(function (e, i, a) {
|
||||
a[i] = String.fromCharCode(e);
|
||||
});
|
||||
}
|
||||
return fieldValues;
|
||||
},
|
||||
|
||||
getBytes: function (numBytes, offset) {
|
||||
if (numBytes <= 0) {
|
||||
cc.logID(8001);
|
||||
} else if (numBytes <= 1) {
|
||||
return this.getUint8(offset);
|
||||
} else if (numBytes <= 2) {
|
||||
return this.getUint16(offset);
|
||||
} else if (numBytes <= 3) {
|
||||
return this.getUint32(offset) >>> 8;
|
||||
} else if (numBytes <= 4) {
|
||||
return this.getUint32(offset);
|
||||
} else {
|
||||
cc.logID(8002);
|
||||
}
|
||||
},
|
||||
|
||||
getBits: function (numBits, byteOffset, bitOffset) {
|
||||
bitOffset = bitOffset || 0;
|
||||
var extraBytes = Math.floor(bitOffset / 8);
|
||||
var newByteOffset = byteOffset + extraBytes;
|
||||
var totalBits = bitOffset + numBits;
|
||||
var shiftRight = 32 - numBits;
|
||||
var shiftLeft,rawBits;
|
||||
|
||||
if (totalBits <= 0) {
|
||||
cc.logID(6023);
|
||||
} else if (totalBits <= 8) {
|
||||
shiftLeft = 24 + bitOffset;
|
||||
rawBits = this.getUint8(newByteOffset);
|
||||
} else if (totalBits <= 16) {
|
||||
shiftLeft = 16 + bitOffset;
|
||||
rawBits = this.getUint16(newByteOffset);
|
||||
} else if (totalBits <= 32) {
|
||||
shiftLeft = bitOffset;
|
||||
rawBits = this.getUint32(newByteOffset);
|
||||
} else {
|
||||
cc.logID(6022);
|
||||
}
|
||||
|
||||
return {
|
||||
'bits': ((rawBits << shiftLeft) >>> shiftRight),
|
||||
'byteOffset': newByteOffset + Math.floor(totalBits / 8),
|
||||
'bitOffset': totalBits % 8
|
||||
};
|
||||
},
|
||||
|
||||
parseFileDirectory: function (byteOffset) {
|
||||
var numDirEntries = this.getUint16(byteOffset);
|
||||
var tiffFields = [];
|
||||
|
||||
for (var i = byteOffset + 2, entryCount = 0; entryCount < numDirEntries; i += 12, entryCount++) {
|
||||
var fieldTag = this.getUint16(i);
|
||||
var fieldType = this.getUint16(i + 2);
|
||||
var typeCount = this.getUint32(i + 4);
|
||||
var valueOffset = this.getUint32(i + 8);
|
||||
|
||||
var fieldTagName = this.getFieldTagName(fieldTag);
|
||||
var fieldTypeName = this.getFieldTypeName(fieldType);
|
||||
var fieldValues = this.getFieldValues(fieldTagName, fieldTypeName, typeCount, valueOffset);
|
||||
|
||||
tiffFields[fieldTagName] = { type: fieldTypeName, values: fieldValues };
|
||||
}
|
||||
|
||||
this._fileDirectories.push(tiffFields);
|
||||
|
||||
var nextIFDByteOffset = this.getUint32(i);
|
||||
if (nextIFDByteOffset !== 0x00000000) {
|
||||
this.parseFileDirectory(nextIFDByteOffset);
|
||||
}
|
||||
},
|
||||
|
||||
clampColorSample: function(colorSample, bitsPerSample) {
|
||||
var multiplier = Math.pow(2, 8 - bitsPerSample);
|
||||
|
||||
return Math.floor((colorSample * multiplier) + (multiplier - 1));
|
||||
},
|
||||
|
||||
/**
|
||||
* @function
|
||||
* @param {Array} tiffData
|
||||
* @param {HTMLCanvasElement} canvas
|
||||
* @returns {*}
|
||||
*/
|
||||
parseTIFF: function (tiffData, canvas) {
|
||||
canvas = canvas || document.createElement('canvas');
|
||||
|
||||
this._tiffData = tiffData;
|
||||
this.canvas = canvas;
|
||||
|
||||
this.checkLittleEndian();
|
||||
|
||||
if (!this.hasTowel()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var firstIFDByteOffset = this.getUint32(4);
|
||||
|
||||
this._fileDirectories.length = 0;
|
||||
this.parseFileDirectory(firstIFDByteOffset);
|
||||
|
||||
var fileDirectory = this._fileDirectories[0];
|
||||
|
||||
var imageWidth = fileDirectory['ImageWidth'].values[0];
|
||||
var imageLength = fileDirectory['ImageLength'].values[0];
|
||||
|
||||
this.canvas.width = imageWidth;
|
||||
this.canvas.height = imageLength;
|
||||
|
||||
var strips = [];
|
||||
|
||||
var compression = (fileDirectory['Compression']) ? fileDirectory['Compression'].values[0] : 1;
|
||||
|
||||
var samplesPerPixel = fileDirectory['SamplesPerPixel'].values[0];
|
||||
|
||||
var sampleProperties = [];
|
||||
|
||||
var bitsPerPixel = 0;
|
||||
var hasBytesPerPixel = false;
|
||||
|
||||
fileDirectory['BitsPerSample'].values.forEach(function (bitsPerSample, i, bitsPerSampleValues) {
|
||||
sampleProperties[i] = {
|
||||
bitsPerSample: bitsPerSample,
|
||||
hasBytesPerSample: false,
|
||||
bytesPerSample: undefined
|
||||
};
|
||||
|
||||
if ((bitsPerSample % 8) === 0) {
|
||||
sampleProperties[i].hasBytesPerSample = true;
|
||||
sampleProperties[i].bytesPerSample = bitsPerSample / 8;
|
||||
}
|
||||
|
||||
bitsPerPixel += bitsPerSample;
|
||||
}, this);
|
||||
|
||||
if ((bitsPerPixel % 8) === 0) {
|
||||
hasBytesPerPixel = true;
|
||||
var bytesPerPixel = bitsPerPixel / 8;
|
||||
}
|
||||
|
||||
var stripOffsetValues = fileDirectory['StripOffsets'].values;
|
||||
var numStripOffsetValues = stripOffsetValues.length;
|
||||
|
||||
// StripByteCounts is supposed to be required, but see if we can recover anyway.
|
||||
if (fileDirectory['StripByteCounts']) {
|
||||
var stripByteCountValues = fileDirectory['StripByteCounts'].values;
|
||||
} else {
|
||||
cc.logID(8003);
|
||||
|
||||
// Infer StripByteCounts, if possible.
|
||||
if (numStripOffsetValues === 1) {
|
||||
var stripByteCountValues = [Math.ceil((imageWidth * imageLength * bitsPerPixel) / 8)];
|
||||
} else {
|
||||
throw Error(debug.getError(6024));
|
||||
}
|
||||
}
|
||||
|
||||
// Loop through strips and decompress as necessary.
|
||||
for (var i = 0; i < numStripOffsetValues; i++) {
|
||||
var stripOffset = stripOffsetValues[i];
|
||||
strips[i] = [];
|
||||
|
||||
var stripByteCount = stripByteCountValues[i];
|
||||
|
||||
// Loop through pixels.
|
||||
for (var byteOffset = 0, bitOffset = 0, jIncrement = 1, getHeader = true, pixel = [], numBytes = 0, sample = 0, currentSample = 0;
|
||||
byteOffset < stripByteCount; byteOffset += jIncrement) {
|
||||
// Decompress strip.
|
||||
switch (compression) {
|
||||
// Uncompressed
|
||||
case 1:
|
||||
// Loop through samples (sub-pixels).
|
||||
for (var m = 0, pixel = []; m < samplesPerPixel; m++) {
|
||||
if (sampleProperties[m].hasBytesPerSample) {
|
||||
// XXX: This is wrong!
|
||||
var sampleOffset = sampleProperties[m].bytesPerSample * m;
|
||||
pixel.push(this.getBytes(sampleProperties[m].bytesPerSample, stripOffset + byteOffset + sampleOffset));
|
||||
} else {
|
||||
var sampleInfo = this.getBits(sampleProperties[m].bitsPerSample, stripOffset + byteOffset, bitOffset);
|
||||
pixel.push(sampleInfo.bits);
|
||||
byteOffset = sampleInfo.byteOffset - stripOffset;
|
||||
bitOffset = sampleInfo.bitOffset;
|
||||
|
||||
throw RangeError(debug.getError(6025));
|
||||
}
|
||||
}
|
||||
|
||||
strips[i].push(pixel);
|
||||
|
||||
if (hasBytesPerPixel) {
|
||||
jIncrement = bytesPerPixel;
|
||||
} else {
|
||||
jIncrement = 0;
|
||||
throw RangeError(debug.getError(6026));
|
||||
}
|
||||
break;
|
||||
|
||||
// CITT Group 3 1-Dimensional Modified Huffman run-length encoding
|
||||
case 2:
|
||||
// XXX: Use PDF.js code?
|
||||
break;
|
||||
|
||||
// Group 3 Fax
|
||||
case 3:
|
||||
// XXX: Use PDF.js code?
|
||||
break;
|
||||
|
||||
// Group 4 Fax
|
||||
case 4:
|
||||
// XXX: Use PDF.js code?
|
||||
break;
|
||||
|
||||
// LZW
|
||||
case 5:
|
||||
// XXX: Use PDF.js code?
|
||||
break;
|
||||
|
||||
// Old-style JPEG (TIFF 6.0)
|
||||
case 6:
|
||||
// XXX: Use PDF.js code?
|
||||
break;
|
||||
|
||||
// New-style JPEG (TIFF Specification Supplement 2)
|
||||
case 7:
|
||||
// XXX: Use PDF.js code?
|
||||
break;
|
||||
|
||||
// PackBits
|
||||
case 32773:
|
||||
// Are we ready for a new block?
|
||||
if (getHeader) {
|
||||
getHeader = false;
|
||||
|
||||
var blockLength = 1;
|
||||
var iterations = 1;
|
||||
|
||||
// The header byte is signed.
|
||||
var header = this.getInt8(stripOffset + byteOffset);
|
||||
|
||||
if ((header >= 0) && (header <= 127)) { // Normal pixels.
|
||||
blockLength = header + 1;
|
||||
} else if ((header >= -127) && (header <= -1)) { // Collapsed pixels.
|
||||
iterations = -header + 1;
|
||||
} else /*if (header === -128)*/ { // Placeholder byte?
|
||||
getHeader = true;
|
||||
}
|
||||
} else {
|
||||
var currentByte = this.getUint8(stripOffset + byteOffset);
|
||||
|
||||
// Duplicate bytes, if necessary.
|
||||
for (var m = 0; m < iterations; m++) {
|
||||
if (sampleProperties[sample].hasBytesPerSample) {
|
||||
// We're reading one byte at a time, so we need to handle multi-byte samples.
|
||||
currentSample = (currentSample << (8 * numBytes)) | currentByte;
|
||||
numBytes++;
|
||||
|
||||
// Is our sample complete?
|
||||
if (numBytes === sampleProperties[sample].bytesPerSample) {
|
||||
pixel.push(currentSample);
|
||||
currentSample = numBytes = 0;
|
||||
sample++;
|
||||
}
|
||||
} else {
|
||||
throw RangeError(debug.getError(6025));
|
||||
}
|
||||
|
||||
// Is our pixel complete?
|
||||
if (sample === samplesPerPixel) {
|
||||
strips[i].push(pixel);
|
||||
pixel = [];
|
||||
sample = 0;
|
||||
}
|
||||
}
|
||||
|
||||
blockLength--;
|
||||
|
||||
// Is our block complete?
|
||||
if (blockLength === 0) {
|
||||
getHeader = true;
|
||||
}
|
||||
}
|
||||
|
||||
jIncrement = 1;
|
||||
break;
|
||||
|
||||
// Unknown compression algorithm
|
||||
default:
|
||||
// Do not attempt to parse the image data.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (canvas.getContext) {
|
||||
var ctx = this.canvas.getContext("2d");
|
||||
|
||||
// Set a default fill style.
|
||||
ctx.fillStyle = "rgba(255, 255, 255, 0)";
|
||||
|
||||
// If RowsPerStrip is missing, the whole image is in one strip.
|
||||
var rowsPerStrip = fileDirectory['RowsPerStrip'] ? fileDirectory['RowsPerStrip'].values[0] : imageLength;
|
||||
|
||||
var numStrips = strips.length;
|
||||
|
||||
var imageLengthModRowsPerStrip = imageLength % rowsPerStrip;
|
||||
var rowsInLastStrip = (imageLengthModRowsPerStrip === 0) ? rowsPerStrip : imageLengthModRowsPerStrip;
|
||||
|
||||
var numRowsInStrip = rowsPerStrip;
|
||||
var numRowsInPreviousStrip = 0;
|
||||
|
||||
var photometricInterpretation = fileDirectory['PhotometricInterpretation'].values[0];
|
||||
|
||||
var extraSamplesValues = [];
|
||||
var numExtraSamples = 0;
|
||||
|
||||
if (fileDirectory['ExtraSamples']) {
|
||||
extraSamplesValues = fileDirectory['ExtraSamples'].values;
|
||||
numExtraSamples = extraSamplesValues.length;
|
||||
}
|
||||
|
||||
if (fileDirectory['ColorMap']) {
|
||||
var colorMapValues = fileDirectory['ColorMap'].values;
|
||||
var colorMapSampleSize = Math.pow(2, sampleProperties[0].bitsPerSample);
|
||||
}
|
||||
|
||||
// Loop through the strips in the image.
|
||||
for (var i = 0; i < numStrips; i++) {
|
||||
// The last strip may be short.
|
||||
if ((i + 1) === numStrips) {
|
||||
numRowsInStrip = rowsInLastStrip;
|
||||
}
|
||||
|
||||
var numPixels = strips[i].length;
|
||||
var yPadding = numRowsInPreviousStrip * i;
|
||||
|
||||
// Loop through the rows in the strip.
|
||||
for (var y = 0, j = 0; y < numRowsInStrip, j < numPixels; y++) {
|
||||
// Loop through the pixels in the row.
|
||||
for (var x = 0; x < imageWidth; x++, j++) {
|
||||
var pixelSamples = strips[i][j];
|
||||
|
||||
var red = 0;
|
||||
var green = 0;
|
||||
var blue = 0;
|
||||
var opacity = 1.0;
|
||||
|
||||
if (numExtraSamples > 0) {
|
||||
for (var k = 0; k < numExtraSamples; k++) {
|
||||
if (extraSamplesValues[k] === 1 || extraSamplesValues[k] === 2) {
|
||||
// Clamp opacity to the range [0,1].
|
||||
opacity = pixelSamples[3 + k] / 256;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (photometricInterpretation) {
|
||||
// Bilevel or Grayscale
|
||||
// WhiteIsZero
|
||||
case 0:
|
||||
if (sampleProperties[0].hasBytesPerSample) {
|
||||
var invertValue = Math.pow(0x10, sampleProperties[0].bytesPerSample * 2);
|
||||
}
|
||||
|
||||
// Invert samples.
|
||||
pixelSamples.forEach(function (sample, index, samples) {
|
||||
samples[index] = invertValue - sample;
|
||||
});
|
||||
|
||||
// Bilevel or Grayscale
|
||||
// BlackIsZero
|
||||
case 1:
|
||||
red = green = blue = this.clampColorSample(pixelSamples[0], sampleProperties[0].bitsPerSample);
|
||||
break;
|
||||
|
||||
// RGB Full Color
|
||||
case 2:
|
||||
red = this.clampColorSample(pixelSamples[0], sampleProperties[0].bitsPerSample);
|
||||
green = this.clampColorSample(pixelSamples[1], sampleProperties[1].bitsPerSample);
|
||||
blue = this.clampColorSample(pixelSamples[2], sampleProperties[2].bitsPerSample);
|
||||
break;
|
||||
|
||||
// RGB Color Palette
|
||||
case 3:
|
||||
if (colorMapValues === undefined) {
|
||||
throw Error(debug.getError(6027));
|
||||
}
|
||||
|
||||
var colorMapIndex = pixelSamples[0];
|
||||
|
||||
red = this.clampColorSample(colorMapValues[colorMapIndex], 16);
|
||||
green = this.clampColorSample(colorMapValues[colorMapSampleSize + colorMapIndex], 16);
|
||||
blue = this.clampColorSample(colorMapValues[(2 * colorMapSampleSize) + colorMapIndex], 16);
|
||||
break;
|
||||
|
||||
// Unknown Photometric Interpretation
|
||||
default:
|
||||
throw RangeError(debug.getError(6028, photometricInterpretation));
|
||||
break;
|
||||
}
|
||||
|
||||
ctx.fillStyle = "rgba(" + red + ", " + green + ", " + blue + ", " + opacity + ")";
|
||||
ctx.fillRect(x, yPadding + y, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
numRowsInPreviousStrip = numRowsInStrip;
|
||||
}
|
||||
}
|
||||
|
||||
return this.canvas;
|
||||
},
|
||||
|
||||
// See: http://www.digitizationguidelines.gov/guidelines/TIFF_Metadata_Final.pdf
|
||||
// See: http://www.digitalpreservation.gov/formats/content/tiff_tags.shtml
|
||||
fieldTagNames: {
|
||||
// TIFF Baseline
|
||||
0x013B: 'Artist',
|
||||
0x0102: 'BitsPerSample',
|
||||
0x0109: 'CellLength',
|
||||
0x0108: 'CellWidth',
|
||||
0x0140: 'ColorMap',
|
||||
0x0103: 'Compression',
|
||||
0x8298: 'Copyright',
|
||||
0x0132: 'DateTime',
|
||||
0x0152: 'ExtraSamples',
|
||||
0x010A: 'FillOrder',
|
||||
0x0121: 'FreeByteCounts',
|
||||
0x0120: 'FreeOffsets',
|
||||
0x0123: 'GrayResponseCurve',
|
||||
0x0122: 'GrayResponseUnit',
|
||||
0x013C: 'HostComputer',
|
||||
0x010E: 'ImageDescription',
|
||||
0x0101: 'ImageLength',
|
||||
0x0100: 'ImageWidth',
|
||||
0x010F: 'Make',
|
||||
0x0119: 'MaxSampleValue',
|
||||
0x0118: 'MinSampleValue',
|
||||
0x0110: 'Model',
|
||||
0x00FE: 'NewSubfileType',
|
||||
0x0112: 'Orientation',
|
||||
0x0106: 'PhotometricInterpretation',
|
||||
0x011C: 'PlanarConfiguration',
|
||||
0x0128: 'ResolutionUnit',
|
||||
0x0116: 'RowsPerStrip',
|
||||
0x0115: 'SamplesPerPixel',
|
||||
0x0131: 'Software',
|
||||
0x0117: 'StripByteCounts',
|
||||
0x0111: 'StripOffsets',
|
||||
0x00FF: 'SubfileType',
|
||||
0x0107: 'Threshholding',
|
||||
0x011A: 'XResolution',
|
||||
0x011B: 'YResolution',
|
||||
|
||||
// TIFF Extended
|
||||
0x0146: 'BadFaxLines',
|
||||
0x0147: 'CleanFaxData',
|
||||
0x0157: 'ClipPath',
|
||||
0x0148: 'ConsecutiveBadFaxLines',
|
||||
0x01B1: 'Decode',
|
||||
0x01B2: 'DefaultImageColor',
|
||||
0x010D: 'DocumentName',
|
||||
0x0150: 'DotRange',
|
||||
0x0141: 'HalftoneHints',
|
||||
0x015A: 'Indexed',
|
||||
0x015B: 'JPEGTables',
|
||||
0x011D: 'PageName',
|
||||
0x0129: 'PageNumber',
|
||||
0x013D: 'Predictor',
|
||||
0x013F: 'PrimaryChromaticities',
|
||||
0x0214: 'ReferenceBlackWhite',
|
||||
0x0153: 'SampleFormat',
|
||||
0x022F: 'StripRowCounts',
|
||||
0x014A: 'SubIFDs',
|
||||
0x0124: 'T4Options',
|
||||
0x0125: 'T6Options',
|
||||
0x0145: 'TileByteCounts',
|
||||
0x0143: 'TileLength',
|
||||
0x0144: 'TileOffsets',
|
||||
0x0142: 'TileWidth',
|
||||
0x012D: 'TransferFunction',
|
||||
0x013E: 'WhitePoint',
|
||||
0x0158: 'XClipPathUnits',
|
||||
0x011E: 'XPosition',
|
||||
0x0211: 'YCbCrCoefficients',
|
||||
0x0213: 'YCbCrPositioning',
|
||||
0x0212: 'YCbCrSubSampling',
|
||||
0x0159: 'YClipPathUnits',
|
||||
0x011F: 'YPosition',
|
||||
|
||||
// EXIF
|
||||
0x9202: 'ApertureValue',
|
||||
0xA001: 'ColorSpace',
|
||||
0x9004: 'DateTimeDigitized',
|
||||
0x9003: 'DateTimeOriginal',
|
||||
0x8769: 'Exif IFD',
|
||||
0x9000: 'ExifVersion',
|
||||
0x829A: 'ExposureTime',
|
||||
0xA300: 'FileSource',
|
||||
0x9209: 'Flash',
|
||||
0xA000: 'FlashpixVersion',
|
||||
0x829D: 'FNumber',
|
||||
0xA420: 'ImageUniqueID',
|
||||
0x9208: 'LightSource',
|
||||
0x927C: 'MakerNote',
|
||||
0x9201: 'ShutterSpeedValue',
|
||||
0x9286: 'UserComment',
|
||||
|
||||
// IPTC
|
||||
0x83BB: 'IPTC',
|
||||
|
||||
// ICC
|
||||
0x8773: 'ICC Profile',
|
||||
|
||||
// XMP
|
||||
0x02BC: 'XMP',
|
||||
|
||||
// GDAL
|
||||
0xA480: 'GDAL_METADATA',
|
||||
0xA481: 'GDAL_NODATA',
|
||||
|
||||
// Photoshop
|
||||
0x8649: 'Photoshop'
|
||||
},
|
||||
|
||||
fieldTypeNames: {
|
||||
0x0001: 'BYTE',
|
||||
0x0002: 'ASCII',
|
||||
0x0003: 'SHORT',
|
||||
0x0004: 'LONG',
|
||||
0x0005: 'RATIONAL',
|
||||
0x0006: 'SBYTE',
|
||||
0x0007: 'UNDEFINED',
|
||||
0x0008: 'SSHORT',
|
||||
0x0009: 'SLONG',
|
||||
0x000A: 'SRATIONAL',
|
||||
0x000B: 'FLOAT',
|
||||
0x000C: 'DOUBLE'
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = tiffReader;
|
29
engine/cocos2d/particle/index.js
Normal file
29
engine/cocos2d/particle/index.js
Normal file
@@ -0,0 +1,29 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 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.
|
||||
****************************************************************************/
|
||||
|
||||
require('./CCParticleAsset');
|
||||
require('./CCParticleSystem');
|
||||
require('./particle-simulator');
|
||||
require('./particle-system-assembler');
|
460
engine/cocos2d/particle/particle-simulator.js
Normal file
460
engine/cocos2d/particle/particle-simulator.js
Normal file
@@ -0,0 +1,460 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 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 js = require('../core/platform/js');
|
||||
const misc = require('../core/utils/misc');
|
||||
|
||||
const ZERO_VEC2 = cc.v2(0, 0);
|
||||
let _pos = cc.v2();
|
||||
let _tpa = cc.v2();
|
||||
let _tpb = cc.v2();
|
||||
let _tpc = cc.v2();
|
||||
|
||||
let Particle = function () {
|
||||
this.pos = cc.v2(0, 0);
|
||||
this.startPos = cc.v2(0, 0);
|
||||
this.color = cc.color(0, 0, 0, 255);
|
||||
this.deltaColor = {r: 0, g: 0, b: 0, a: 255};
|
||||
this.preciseColor = {r: 0, g: 0, b: 0, a: 255};
|
||||
this.size = 0;
|
||||
this.deltaSize = 0;
|
||||
this.rotation = 0;
|
||||
this.deltaRotation = 0;
|
||||
this.timeToLive = 0;
|
||||
this.drawPos = cc.v2(0, 0);
|
||||
this.aspectRatio = 1;
|
||||
// Mode A
|
||||
this.dir = cc.v2(0, 0);
|
||||
this.radialAccel = 0;
|
||||
this.tangentialAccel = 0;
|
||||
// Mode B
|
||||
this.angle = 0;
|
||||
this.degreesPerSecond = 0;
|
||||
this.radius = 0;
|
||||
this.deltaRadius = 0;
|
||||
}
|
||||
|
||||
let pool = new js.Pool(function (par) {
|
||||
par.pos.set(ZERO_VEC2);
|
||||
par.startPos.set(ZERO_VEC2);
|
||||
par.color._val = 0xFF000000;
|
||||
par.deltaColor.r = par.deltaColor.g = par.deltaColor.b = 0;
|
||||
par.deltaColor.a = 255;
|
||||
par.size = 0;
|
||||
par.deltaSize = 0;
|
||||
par.rotation = 0;
|
||||
par.deltaRotation = 0;
|
||||
par.timeToLive = 0;
|
||||
par.drawPos.set(ZERO_VEC2);
|
||||
par.aspectRatio = 1;
|
||||
// Mode A
|
||||
par.dir.set(ZERO_VEC2);
|
||||
par.radialAccel = 0;
|
||||
par.tangentialAccel = 0;
|
||||
// Mode B
|
||||
par.angle = 0;
|
||||
par.degreesPerSecond = 0;
|
||||
par.radius = 0;
|
||||
par.deltaRadius = 0;
|
||||
}, 1024);
|
||||
pool.get = function () {
|
||||
return this._get() || new Particle();
|
||||
}
|
||||
|
||||
let Simulator = function (system) {
|
||||
this.sys = system;
|
||||
this.particles = [];
|
||||
this.active = false;
|
||||
this.readyToPlay = true;
|
||||
this.finished = false;
|
||||
this.elapsed = 0;
|
||||
this.emitCounter = 0;
|
||||
this._uvFilled = 0;
|
||||
this._worldRotation = 0;
|
||||
}
|
||||
|
||||
Simulator.prototype.stop = function () {
|
||||
this.active = false;
|
||||
this.readyToPlay = false;
|
||||
this.elapsed = this.sys.duration;
|
||||
this.emitCounter = 0;
|
||||
}
|
||||
|
||||
Simulator.prototype.reset = function () {
|
||||
this.active = true;
|
||||
this.readyToPlay = true;
|
||||
this.elapsed = 0;
|
||||
this.emitCounter = 0;
|
||||
this.finished = false;
|
||||
let particles = this.particles;
|
||||
for (let id = 0; id < particles.length; ++id)
|
||||
pool.put(particles[id]);
|
||||
particles.length = 0;
|
||||
let assembler = this.sys._assembler;
|
||||
if (assembler && assembler._ia)
|
||||
assembler._ia._count = 0;
|
||||
}
|
||||
|
||||
Simulator.prototype.emitParticle = function (pos) {
|
||||
let psys = this.sys;
|
||||
let clampf = misc.clampf;
|
||||
let particle = pool.get();
|
||||
this.particles.push(particle);
|
||||
|
||||
// Init particle
|
||||
// timeToLive
|
||||
// no negative life. prevent division by 0
|
||||
particle.timeToLive = psys.life + psys.lifeVar * (Math.random() - 0.5) * 2;
|
||||
let timeToLive = particle.timeToLive = Math.max(0, particle.timeToLive);
|
||||
|
||||
// position
|
||||
particle.pos.x = psys.sourcePos.x + psys.posVar.x * (Math.random() - 0.5) * 2;
|
||||
particle.pos.y = psys.sourcePos.y + psys.posVar.y * (Math.random() - 0.5) * 2;
|
||||
|
||||
// Color
|
||||
let sr, sg, sb, sa;
|
||||
let startColor = psys._startColor, startColorVar = psys._startColorVar;
|
||||
let endColor = psys._endColor, endColorVar = psys._endColorVar;
|
||||
particle.color.r = sr = clampf(startColor.r + startColorVar.r * (Math.random() - 0.5) * 2, 0, 255);
|
||||
particle.color.g = sg = clampf(startColor.g + startColorVar.g * (Math.random() - 0.5) * 2, 0, 255);
|
||||
particle.color.b = sb = clampf(startColor.b + startColorVar.b * (Math.random() - 0.5) * 2, 0, 255);
|
||||
particle.color.a = sa = clampf(startColor.a + startColorVar.a * (Math.random() - 0.5) * 2, 0, 255);
|
||||
|
||||
let color = particle.color;
|
||||
let preciseColor = particle.preciseColor;
|
||||
preciseColor.r = color.r;
|
||||
preciseColor.g = color.g;
|
||||
preciseColor.b = color.b;
|
||||
preciseColor.a = color.a;
|
||||
|
||||
particle.deltaColor.r = (clampf(endColor.r + endColorVar.r * (Math.random() - 0.5) * 2, 0, 255) - sr) / timeToLive;
|
||||
particle.deltaColor.g = (clampf(endColor.g + endColorVar.g * (Math.random() - 0.5) * 2, 0, 255) - sg) / timeToLive;
|
||||
particle.deltaColor.b = (clampf(endColor.b + endColorVar.b * (Math.random() - 0.5) * 2, 0, 255) - sb) / timeToLive;
|
||||
particle.deltaColor.a = (clampf(endColor.a + endColorVar.a * (Math.random() - 0.5) * 2, 0, 255) - sa) / timeToLive;
|
||||
|
||||
// size
|
||||
let startS = psys.startSize + psys.startSizeVar * (Math.random() - 0.5) * 2;
|
||||
startS = Math.max(0, startS); // No negative value
|
||||
particle.size = startS;
|
||||
if (psys.endSize === cc.ParticleSystem.START_SIZE_EQUAL_TO_END_SIZE) {
|
||||
particle.deltaSize = 0;
|
||||
} else {
|
||||
var endS = psys.endSize + psys.endSizeVar * (Math.random() - 0.5) * 2;
|
||||
endS = Math.max(0, endS); // No negative values
|
||||
particle.deltaSize = (endS - startS) / timeToLive;
|
||||
}
|
||||
|
||||
// rotation
|
||||
var startA = psys.startSpin + psys.startSpinVar * (Math.random() - 0.5) * 2;
|
||||
var endA = psys.endSpin + psys.endSpinVar * (Math.random() - 0.5) * 2;
|
||||
particle.rotation = startA;
|
||||
particle.deltaRotation = (endA - startA) / timeToLive;
|
||||
|
||||
// position
|
||||
particle.startPos.x = pos.x;
|
||||
particle.startPos.y = pos.y;
|
||||
|
||||
// aspect ratio
|
||||
particle.aspectRatio = psys._aspectRatio || 1;
|
||||
|
||||
// direction
|
||||
let a = misc.degreesToRadians( psys.angle + this._worldRotation + psys.angleVar * (Math.random() - 0.5) * 2);
|
||||
// Mode Gravity: A
|
||||
if (psys.emitterMode === cc.ParticleSystem.EmitterMode.GRAVITY) {
|
||||
let s = psys.speed + psys.speedVar * (Math.random() - 0.5) * 2;
|
||||
// direction
|
||||
particle.dir.x = Math.cos(a);
|
||||
particle.dir.y = Math.sin(a);
|
||||
particle.dir.mulSelf(s);
|
||||
// radial accel
|
||||
particle.radialAccel = psys.radialAccel + psys.radialAccelVar * (Math.random() - 0.5) * 2;
|
||||
// tangential accel
|
||||
particle.tangentialAccel = psys.tangentialAccel + psys.tangentialAccelVar * (Math.random() - 0.5) * 2;
|
||||
// rotation is dir
|
||||
if (psys.rotationIsDir) {
|
||||
particle.rotation = -misc.radiansToDegrees(Math.atan2(particle.dir.y, particle.dir.x));
|
||||
}
|
||||
}
|
||||
// Mode Radius: B
|
||||
else {
|
||||
// Set the default diameter of the particle from the source position
|
||||
var startRadius = psys.startRadius + psys.startRadiusVar * (Math.random() - 0.5) * 2;
|
||||
var endRadius = psys.endRadius + psys.endRadiusVar * (Math.random() - 0.5) * 2;
|
||||
particle.radius = startRadius;
|
||||
particle.deltaRadius = (psys.endRadius === cc.ParticleSystem.START_RADIUS_EQUAL_TO_END_RADIUS) ? 0 : (endRadius - startRadius) / timeToLive;
|
||||
particle.angle = a;
|
||||
particle.degreesPerSecond = misc.degreesToRadians(psys.rotatePerS + psys.rotatePerSVar * (Math.random() - 0.5) * 2);
|
||||
}
|
||||
};
|
||||
|
||||
// In the Free mode to get emit real rotation in the world coordinate.
|
||||
function getWorldRotation (node) {
|
||||
let rotation = 0;
|
||||
let tempNode = node;
|
||||
while (tempNode) {
|
||||
rotation += tempNode.angle;
|
||||
tempNode = tempNode.parent;
|
||||
}
|
||||
return rotation;
|
||||
}
|
||||
|
||||
Simulator.prototype.updateUVs = function (force) {
|
||||
let assembler = this.sys._assembler;
|
||||
if (!assembler) {
|
||||
return;
|
||||
}
|
||||
let buffer = assembler.getBuffer();
|
||||
if (buffer && this.sys._renderSpriteFrame) {
|
||||
const FLOAT_PER_PARTICLE = 4 * assembler._vfmt._bytes / 4;
|
||||
let vbuf = buffer._vData;
|
||||
let uv = this.sys._renderSpriteFrame.uv;
|
||||
|
||||
let start = force ? 0 : this._uvFilled;
|
||||
let particleCount = this.particles.length;
|
||||
for (let i = start; i < particleCount; i++) {
|
||||
let offset = i * FLOAT_PER_PARTICLE;
|
||||
vbuf[offset+2] = uv[0];
|
||||
vbuf[offset+3] = uv[1];
|
||||
vbuf[offset+7] = uv[2];
|
||||
vbuf[offset+8] = uv[3];
|
||||
vbuf[offset+12] = uv[4];
|
||||
vbuf[offset+13] = uv[5];
|
||||
vbuf[offset+17] = uv[6];
|
||||
vbuf[offset+18] = uv[7];
|
||||
}
|
||||
this._uvFilled = particleCount;
|
||||
}
|
||||
}
|
||||
|
||||
Simulator.prototype.updateParticleBuffer = function (particle, pos, buffer, offset) {
|
||||
let vbuf = buffer._vData;
|
||||
let uintbuf = buffer._uintVData;
|
||||
|
||||
let x = pos.x, y = pos.y;
|
||||
let width = particle.size;
|
||||
let height = width;
|
||||
let aspectRatio = particle.aspectRatio;
|
||||
aspectRatio > 1 ? (height = width / aspectRatio) : (width = height * aspectRatio);
|
||||
let halfWidth = width / 2;
|
||||
let halfHeight = height / 2;
|
||||
// pos
|
||||
if (particle.rotation) {
|
||||
let x1 = -halfWidth, y1 = -halfHeight;
|
||||
let x2 = halfWidth, y2 = halfHeight;
|
||||
let rad = -misc.degreesToRadians(particle.rotation);
|
||||
let cr = Math.cos(rad), sr = Math.sin(rad);
|
||||
// bl
|
||||
vbuf[offset] = x1 * cr - y1 * sr + x;
|
||||
vbuf[offset+1] = x1 * sr + y1 * cr + y;
|
||||
// br
|
||||
vbuf[offset+5] = x2 * cr - y1 * sr + x;
|
||||
vbuf[offset+6] = x2 * sr + y1 * cr + y;
|
||||
// tl
|
||||
vbuf[offset+10] = x1 * cr - y2 * sr + x;
|
||||
vbuf[offset+11] = x1 * sr + y2 * cr + y;
|
||||
// tr
|
||||
vbuf[offset+15] = x2 * cr - y2 * sr + x;
|
||||
vbuf[offset+16] = x2 * sr + y2 * cr + y;
|
||||
}
|
||||
else {
|
||||
// bl
|
||||
vbuf[offset] = x - halfWidth;
|
||||
vbuf[offset+1] = y - halfHeight;
|
||||
// br
|
||||
vbuf[offset+5] = x + halfWidth;
|
||||
vbuf[offset+6] = y - halfHeight;
|
||||
// tl
|
||||
vbuf[offset+10] = x - halfWidth;
|
||||
vbuf[offset+11] = y + halfHeight;
|
||||
// tr
|
||||
vbuf[offset+15] = x + halfWidth;
|
||||
vbuf[offset+16] = y + halfHeight;
|
||||
}
|
||||
// color
|
||||
uintbuf[offset+4] = particle.color._val;
|
||||
uintbuf[offset+9] = particle.color._val;
|
||||
uintbuf[offset+14] = particle.color._val;
|
||||
uintbuf[offset+19] = particle.color._val;
|
||||
};
|
||||
|
||||
Simulator.prototype.step = function (dt) {
|
||||
dt = dt > cc.director._maxParticleDeltaTime ? cc.director._maxParticleDeltaTime : dt;
|
||||
let psys = this.sys;
|
||||
let node = psys.node;
|
||||
let particles = this.particles;
|
||||
const FLOAT_PER_PARTICLE = 4 * this.sys._assembler._vfmt._bytes / 4;
|
||||
const PositionType = cc.ParticleSystem.PositionType;
|
||||
|
||||
// Calculate pos
|
||||
node._updateWorldMatrix();
|
||||
if (psys.positionType === PositionType.FREE) {
|
||||
this._worldRotation = getWorldRotation(node);
|
||||
let m = node._worldMatrix.m;
|
||||
_pos.x = m[12];
|
||||
_pos.y = m[13];
|
||||
} else if (psys.positionType === PositionType.RELATIVE) {
|
||||
this._worldRotation = node.angle;
|
||||
_pos.x = node.x;
|
||||
_pos.y = node.y;
|
||||
} else {
|
||||
this._worldRotation = 0;
|
||||
}
|
||||
|
||||
// Emission
|
||||
if (this.active && psys.emissionRate) {
|
||||
var rate = 1.0 / psys.emissionRate;
|
||||
//issue #1201, prevent bursts of particles, due to too high emitCounter
|
||||
if (particles.length < psys.totalParticles)
|
||||
this.emitCounter += dt;
|
||||
|
||||
while ((particles.length < psys.totalParticles) && (this.emitCounter > rate)) {
|
||||
this.emitParticle(_pos);
|
||||
this.emitCounter -= rate;
|
||||
}
|
||||
|
||||
this.elapsed += dt;
|
||||
if (psys.duration !== -1 && psys.duration < this.elapsed) {
|
||||
psys.stopSystem();
|
||||
}
|
||||
}
|
||||
|
||||
// Request buffer for particles
|
||||
let buffer = psys._assembler.getBuffer();
|
||||
let particleCount = particles.length;
|
||||
buffer.reset();
|
||||
buffer.request(particleCount * 4, particleCount * 6);
|
||||
|
||||
// Fill up uvs
|
||||
if (particleCount > this._uvFilled) {
|
||||
this.updateUVs();
|
||||
}
|
||||
|
||||
// Used to reduce memory allocation / creation within the loop
|
||||
let particleIdx = 0;
|
||||
while (particleIdx < particles.length) {
|
||||
// Reset temporary vectors
|
||||
_tpa.x = _tpa.y = _tpb.x = _tpb.y = _tpc.x = _tpc.y = 0;
|
||||
|
||||
let particle = particles[particleIdx];
|
||||
|
||||
// life
|
||||
particle.timeToLive -= dt;
|
||||
if (particle.timeToLive > 0) {
|
||||
// Mode A: gravity, direction, tangential accel & radial accel
|
||||
if (psys.emitterMode === cc.ParticleSystem.EmitterMode.GRAVITY) {
|
||||
let tmp = _tpc, radial = _tpa, tangential = _tpb;
|
||||
|
||||
// radial acceleration
|
||||
if (particle.pos.x || particle.pos.y) {
|
||||
radial.set(particle.pos);
|
||||
radial.normalizeSelf();
|
||||
}
|
||||
tangential.set(radial);
|
||||
radial.mulSelf(particle.radialAccel);
|
||||
|
||||
// tangential acceleration
|
||||
let newy = tangential.x;
|
||||
tangential.x = -tangential.y;
|
||||
tangential.y = newy;
|
||||
|
||||
tangential.mulSelf(particle.tangentialAccel);
|
||||
|
||||
tmp.set(radial);
|
||||
tmp.addSelf(tangential);
|
||||
tmp.addSelf(psys.gravity);
|
||||
tmp.mulSelf(dt);
|
||||
particle.dir.addSelf(tmp);
|
||||
|
||||
tmp.set(particle.dir);
|
||||
tmp.mulSelf(dt);
|
||||
particle.pos.addSelf(tmp);
|
||||
}
|
||||
// Mode B: radius movement
|
||||
else {
|
||||
// Update the angle and radius of the particle.
|
||||
particle.angle += particle.degreesPerSecond * dt;
|
||||
particle.radius += particle.deltaRadius * dt;
|
||||
|
||||
particle.pos.x = -Math.cos(particle.angle) * particle.radius;
|
||||
particle.pos.y = -Math.sin(particle.angle) * particle.radius;
|
||||
}
|
||||
|
||||
// color
|
||||
let preciseColor = particle.preciseColor;
|
||||
let deltaColor = particle.deltaColor;
|
||||
preciseColor.r += deltaColor.r * dt;
|
||||
preciseColor.g += deltaColor.g * dt;
|
||||
preciseColor.b += deltaColor.b * dt;
|
||||
preciseColor.a += deltaColor.a * dt;
|
||||
|
||||
let color = particle.color;
|
||||
color.r = preciseColor.r;
|
||||
color.g = preciseColor.g;
|
||||
color.b = preciseColor.b;
|
||||
color.a = preciseColor.a;
|
||||
|
||||
// size
|
||||
particle.size += particle.deltaSize * dt;
|
||||
if (particle.size < 0) {
|
||||
particle.size = 0;
|
||||
}
|
||||
|
||||
// angle
|
||||
particle.rotation += particle.deltaRotation * dt;
|
||||
|
||||
// update values in quad buffer
|
||||
let newPos = _tpa;
|
||||
newPos.set(particle.pos);
|
||||
if (psys.positionType !== PositionType.GROUPED) {
|
||||
newPos.addSelf(particle.startPos);
|
||||
}
|
||||
|
||||
let offset = FLOAT_PER_PARTICLE * particleIdx;
|
||||
this.updateParticleBuffer(particle, newPos, buffer, offset);
|
||||
|
||||
// update particle counter
|
||||
++particleIdx;
|
||||
} else {
|
||||
// life < 0
|
||||
let deadParticle = particles[particleIdx];
|
||||
if (particleIdx !== particles.length - 1) {
|
||||
particles[particleIdx] = particles[particles.length - 1];
|
||||
}
|
||||
pool.put(deadParticle);
|
||||
particles.length--;
|
||||
}
|
||||
}
|
||||
|
||||
psys._assembler._ia._count = particles.length * 6;
|
||||
if (particles.length > 0) {
|
||||
buffer.uploadData();
|
||||
}
|
||||
else if (!this.active && !this.readyToPlay) {
|
||||
this.finished = true;
|
||||
psys._finishedSimulation();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Simulator;
|
75
engine/cocos2d/particle/particle-system-assembler.js
Normal file
75
engine/cocos2d/particle/particle-system-assembler.js
Normal file
@@ -0,0 +1,75 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2017-2018 Chukong Technologies Inc.
|
||||
|
||||
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.
|
||||
Chukong Aipu 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.
|
||||
****************************************************************************/
|
||||
|
||||
import Assembler from '../core/renderer/assembler';
|
||||
|
||||
const ParticleSystem = require('./CCParticleSystem');
|
||||
const renderer = require('../core/renderer/');
|
||||
const QuadBuffer = require('../core/renderer/webgl/quad-buffer');
|
||||
const vfmtPosUvColor = require('../core/renderer/webgl/vertex-format').vfmtPosUvColor;
|
||||
|
||||
import InputAssembler from '../renderer/core/input-assembler';
|
||||
|
||||
class ParticleAssembler extends Assembler {
|
||||
constructor (comp) {
|
||||
super(comp);
|
||||
|
||||
this._buffer = null;
|
||||
this._ia = null;
|
||||
|
||||
this._vfmt = vfmtPosUvColor;
|
||||
}
|
||||
|
||||
getBuffer () {
|
||||
if (!this._buffer) {
|
||||
// Create quad buffer for vertex and index
|
||||
this._buffer = new QuadBuffer(renderer._handle, vfmtPosUvColor);
|
||||
|
||||
this._ia = new InputAssembler();
|
||||
this._ia._vertexBuffer = this._buffer._vb;
|
||||
this._ia._indexBuffer = this._buffer._ib;
|
||||
this._ia._start = 0;
|
||||
this._ia._count = 0;
|
||||
}
|
||||
return this._buffer;
|
||||
}
|
||||
|
||||
fillBuffers (comp, renderer) {
|
||||
if (!this._ia) return;
|
||||
|
||||
const PositionType = cc.ParticleSystem.PositionType;
|
||||
if (comp.positionType === PositionType.RELATIVE) {
|
||||
renderer.node = comp.node.parent;
|
||||
} else {
|
||||
renderer.node = comp.node;
|
||||
}
|
||||
renderer.material = comp._materials[0];
|
||||
renderer._flushIA(this._ia);
|
||||
}
|
||||
}
|
||||
|
||||
Assembler.register(ParticleSystem, ParticleAssembler);
|
||||
|
||||
module.exports = ParticleAssembler;
|
Reference in New Issue
Block a user