/*: * @plugindesc * @author 奏ねこま(おとぶきねこま) * @url http: * @target MZ * * @param json file * @type string[] * @default [] * @desc Live2Dファイル(*.model3.json) * * @help */ 'use strict'; let Load_TextureArr = []; class _Load_Texture { constructor(_MdlName) { this._MdlName = _MdlName; this._TextureCnt = 0; } } class _SeParam { constructor(_SeName){ this._SeName = _SeName; this._OnFlg = false; } } class _VoiceParams { constructor (_VoiceChara , _VoiceName) { this._VoiceChara = _VoiceChara; this._VoiceName = _VoiceName; this._OnFlg = false; } } class _CmnEvParam { constructor(_CmnEvNo){ this._CmnEvNo = _CmnEvNo; this._OnFlg = false; } } let Live2D_JsonKeep = (p => ({ 'json file' : eval(p['json file']), 'live2d data' : {} }))(PluginManager.parameters('JsScript63Set')); !function() { let $p = (p => ({ 'json file' : eval(p['json file']), 'live2d data' : {} }))(PluginManager.parameters('JsScript63Set')); function load() { let loader = new (PIXI.Loader || PIXI.loaders.Loader)(); //for (let file of $p['json file']) { for (let file of modelSetting) { let fileName = file._MdlName + "/" + file._MdlName; let name = fileName.replace(/\.(?:json|model3.json)$/i, ''); $p['live2d data'][name] = false; Live2D_JsonKeep['live2d data'][name] = null; loader = loader.add(name, `img/live2d/${name}.model3.json`); } loader.load((loader, resource) => { for (let name in $p['live2d data']) { $p['live2d data'][name] = resource[name].live2dData; Live2D_JsonKeep['live2d data'][name] = resource[name].live2dData; } }); } if (!window.Live2DCubismCore) { let js = null; for (let element of document.getElementsByTagName('script')) { if (element.src.match('live2dcubismcore.min.js')) { js = element; } } if (!js) { js = document.createElement('script'); js.type = 'text/javascript'; js.src = 'js/libs/live2dcubismcore.min.js'; document.body.appendChild(js); } js.addEventListener('load', load); } else { load(); } class MosaicFilter extends PIXI.Filter { constructor(size = 10 , _XZure = 0 , _YZure = 0) { let vertex = '' + 'attribute vec2 aVertexPosition;' + 'attribute vec2 aTextureCoord;' + 'uniform mat3 projectionMatrix;' + 'varying vec2 vTextureCoord;' + 'void main(void){' + 'gl_Position=vec4((projectionMatrix*vec3(aVertexPosition,1.0)).xy,0.0,1.0);' + 'vTextureCoord=aTextureCoord;' + '}'; let fragment = '' + 'precision mediump float;' + 'varying vec2 vTextureCoord;' + 'uniform vec2 size;' + 'uniform vec2 zure;' + 'uniform sampler2D uSampler;' + 'uniform vec4 filterArea;' + 'vec2 mapCoord(vec2 coord){' + 'coord*=filterArea.xy;' + 'coord+=filterArea.zw;' + 'return coord;' + '}' + 'vec2 unmapCoord(vec2 coord){' + 'coord-=filterArea.zw;' + 'coord/=filterArea.xy;' + 'return coord;' + '}' + 'vec2 pixelate(vec2 coord, vec2 size){' + 'coord+=zure;' + 'return floor(coord / size) * size;' + '}' + 'void main(void){' + 'vec2 coord=mapCoord(vTextureCoord);' + 'coord=pixelate(coord, size);' + 'coord=unmapCoord(coord);' + 'gl_FragColor=texture2D(uSampler, coord);' + '}'; super(vertex, fragment); this.uniforms.size = [size, size]; this.uniforms.zure = [_XZure , _YZure]; } } function convars(obj) { if (typeof obj == 'string') { let _obj = obj.replace(/\\v\[(\d+)\]/gi, (match, p1) => { return $gameVariables.value(Number(p1)); }); obj = _obj != obj ? convars(_obj) : _obj; } else if (obj instanceof Array) { obj = obj.map(value => convars(value)); } else if (typeof obj == 'object') { obj = {...obj}; for (let key in obj) { obj[key] = convars(obj[key]); } } return obj; } class Game_Live2D { constructor() { this.init(); } static live2dData() { return $p['live2d data']; } static fullName(name = '') { for (let key in this.live2dData()) { if (key.match(`(?:^|/)${name}$`)) { return key; } } return ''; } get model() { return this._model; } get track() { return this._track; } get timeScale() { return this._timeScale; } get weight() { return this._weight; } get mix() { return this._mix; } get color() { return this._color; } get mosaic() { return this._mosaic; } get offset() { return this._offset; } get scale() { return this._scale; } get visible() { return this._visible; } init() { this._model = ''; this._track = {}; this._timeScale = 1; this._weight = []; this._mix = {}; this._color = {}; this._mosaic = {}; this._offset = { x: 0, y: 0 }; this._scale = { x: 1, y: 1 }; this._visible = true; this._IdleMtn = ""; this._TgtAlpha = 0; this._TgtAlphaCng = 0; this._TgtAlphaFlame = 0; this._expression = []; for (let i = 0; i <= 10 - 1; i++) { this._expression.push(""); } } get expression() { return this._expression; } setModel(name = '') { name = convars(name); this.init(); this._name = name; this._model = `${name}_${Date.now()}`; return this; } setAnimation(id, animations, ...args) { [id, animations, args] = convars([id, animations, args]); this._track = {...this._track}; let list, order, continuance, interrupt; if (typeof animations == 'string') { list = [animations]; order = 'sequential'; continuance = args[0] || 'continue'; interrupt = typeof args[1] == 'boolean' ? args[1] : args[1] == 'true'; } else { list = animations; order = args[0] || 'sequential'; continuance = args[1] || 'continue'; interrupt = typeof args[2] == 'boolean' ? args[2] : args[2] == 'true'; } this._track[id] = { list: [], order: order, continuance: continuance, interrupt: interrupt }; list.forEach(animation => { let [name, options] = `${animation}/`.replace(/ +/, '').split(/\//); let times = 1; let timeScale = 1; let weight = 1; for (let option of options.replace(/ +/, '').split(/,/)) { if (option.match(/^times=(\d+)$/i)) { times = Number(RegExp.$1); } if (option.match(/^timeScale=(\d+\.?\d*)$/i)) { timeScale = Number(RegExp.$1); } if (option.match(/^weight=(\d+\.?\d*)$/i)) { weight = Number(RegExp.$1); } } this._track[id].list.push({ name: name, times: times, timeScale: timeScale, weight: weight }); }); return this; } setExpression(id , expStr) { this._expression[id] = expStr; } setTimeScale(value) { value = convars(value); this._timeScale = Number(value); return this; } setWeight(id, value) { [id, value] = convars([id, value]); this._weight = this._weight.slice(); this._weight[id] = Number(value); return this; } setMix(...args) { args = convars(args); this._mix = {...this._mix}; let from, to, duration; if (args.length == 1) { from = '/default'; to = ''; duration = Number(args[0]); } else { from = args[0]; to = args[1]; duration = args.length > 2 ? Number(args[2]) : null; } if (duration !== null) { this._mix[`${from}/${to}`] = duration; } else { delete this._mix[`${from}/${to}`]; } return this; } setColor(...args) { args = convars(args); this._color = {...this._color}; let id, r, g, b, a; if (args.length == 3) { id = '/default/'; r = Number(args[0]); g = Number(args[1]); b = Number(args[2]); if(this._color[id] == undefined) { a = 1; } else { a = this._color[id][3]; } } else if (args.length == 4) { id = '/default/'; r = Number(args[0]); g = Number(args[1]); b = Number(args[2]); a = Number(args[3]); } else { id = args[0]; r = Number(args[1]); g = Number(args[2]); b = Number(args[3]); a = Number(args[4]); } if (r != 1 || g != 1 || b != 1 || a != 1) { this._color[id] = [r, g, b, a]; } else { this._color[id] = [r, g, b, a]; } return this; } setMosaic(...args) { args = convars(args); this._mosaic = {...this._mosaic}; let id, size; if (args.length == 1) { id = '/default/'; size = Number(args[0]); } else { id = args[0]; size = Number(args[1]); } if (size > 1) { this._mosaic[id] = size; } else { delete this._mosaic[id]; } return this; } setOffset(x, y) { [x, y] = convars([x, y]); this._offset = { x: Number(x), y: Number(y) }; return this; } setScale(x, y) { [x, y] = convars([x, y]); this._scale = { x: Number(x), y: Number(y) }; return this; } setVisible(visible) { this._visible = !!convars(visible); return this; } setParams(_prmId , _value){ let _ckid = this._model; let _AddFlg = true; for (let i = 0; i <= L2D_SetParams_Arr.length - 1; i++) { if(L2D_SetParams_Arr[i]._modelId == _ckid){ _AddFlg = false; let _ckNo = L2D_SetParams_Arr[i]._ids.indexOf(_prmId); if(_ckNo != -1){ L2D_SetParams_Arr[i]._values[_ckNo] = _value; } else { L2D_SetParams_Arr[i]._ids.push(_prmId); L2D_SetParams_Arr[i]._values.push(_value); } } } if(_AddFlg){ let _SetVar = new L2D_SetParams(); _SetVar._modelId = _ckid; _SetVar._ids = [_prmId]; _SetVar._values = [_value]; L2D_SetParams_Arr.push(_SetVar); } return this; } delParams(_prmId){ let _ckid = this._model; let _AddFlg = true; for (let i = 0; i <= L2D_DelParams_Arr.length - 1; i++) { if(L2D_DelParams_Arr[i]._modelId == _ckid){ _AddFlg = false; let _ckNo = L2D_DelParams_Arr[i]._ids.indexOf(_prmId); if(_ckNo == -1){ L2D_DelParams_Arr[i]._ids.push(_prmId); } } } if(_AddFlg){ let _SetVar = new L2D_SetParams(); _SetVar._modelId = _ckid; _SetVar._ids = [_prmId]; L2D_DelParams_Arr.push(_SetVar); } return this; } } window.Game_Live2D = Game_Live2D; class Sprite_Live2D extends Sprite { constructor(...args) { super(); this._pictureId = typeof args[0] == 'number' ? args[0] : 0; this._live2d = args[0] instanceof Game_Live2D ? args[0] : null; this._isRestore = false; this.init(); } init() { this.removeChild(this._data); this._data = null; this._model = ''; this._track = {}; this._timeScale = 1; this._weight = []; this._mix = {}; this._color = {}; this._mosaic = {}; this._offset = null; this._scale = null; this._mdlAlpha = 1; this.blnk_flg = false; this.blnk_flame = 100 + Math.floor(Math.random() * 300); this.blnk_LClosePrm = 0; this.blnk_LOpenPrm = 0; this.blnk_LBaseOpenPrm = 0; this.blnk_LIdNo = -1; this.blnk_RClosePrm = 0; this.blnk_ROpenPrm = 0; this.blnk_RBaseOpenPrm = 0; this.blnk_RIdNo = -1; } live2d() { if (this._live2d) { return this._live2d; } return null; } update() { let live2d = this.live2d(); this.updateModel(live2d); if (this._data) { this.updateColor(live2d); if(this.parent._mdlAlpha == undefined) this.parent._mdlAlpha = 1; if(!this.parent._mdlAlpha < 0.00001) { this.updateMosaic(live2d); this.updateOffset(live2d); this.updateScale(live2d); this.updateVisible(live2d); if (!this._isRestore) { this.updateTimeScale(live2d); this.updateWeight(live2d); this.updateMix(live2d); this.updateAnimation(live2d); this.snapshot(live2d); } else { this.restore(live2d); } } } super.update(); } updateModel(live2d) { if (live2d) { if (live2d.model != this._model) { let _ckdata = Game_Live2D.live2dData()[Game_Live2D.fullName(live2d._name)]; if(_ckdata == null){ throw new Error("Live2D_Err:モデル「" + live2d._name + "」が存在しない"); } if(_ckdata == false){ console.log("Json 読込中:" + live2d._name); return; } if(_ckdata.Textures.indexOf(null) != -1) { console.log("Err_updateModel:TextLoad_Wait:" + live2d._name); return; } this.init(); this._name = live2d._name; //nupu:Sprite_Live2Dに_name(モデル名)追加 this._model = live2d.model; let model = this._model.replace(/_\d+$/, ''); if (model) { let data = Game_Live2D.live2dData()[Game_Live2D.fullName(model)]; data.name = live2d._name; this._data = new PIXI.Live2D(data); this._data.animation.addListener('start', this.onStart.bind(this)); if(data.Expressions != null){ for (let i = 0; i <= data.Expressions.length - 1; i++) { this._data.animation._expression.push(data.Expressions[i]) } } this.addChild(this._data); if (live2d.snapshot) { this._isRestore = true; } let _ckModel = this._data._model; let _ckids = _ckModel.parameters.ids; if (_ckids.indexOf("eyeOpenL") != -1) { this.blnk_flg = true; let _LeyeId = _ckids.indexOf("eyeOpenL"); this.blnk_LIdNo = _LeyeId; if(_ckModel.parameters.keyValues[_LeyeId].length > 0){ let _ckLength = _ckModel.parameters.keyValues[_LeyeId].length; this.blnk_LOpenPrm = _ckModel.parameters.keyValues[_LeyeId][0]; this.blnk_LClosePrm = _ckModel.parameters.keyValues[_LeyeId][_ckLength - 1]; this.blnk_LBaseOpenPrm = this.blnk_LOpenPrm; } } if (_ckids.indexOf("eyeOpenR") != -1) { this.blnk_flg = true; let _ReyeId = _ckids.indexOf("eyeOpenR"); this.blnk_RIdNo = _ReyeId; if(_ckModel.parameters.keyValues[_ReyeId].length > 0){ let _ckLength = _ckModel.parameters.keyValues[_ReyeId].length; this.blnk_ROpenPrm = _ckModel.parameters.keyValues[_ReyeId][0]; this.blnk_RClosePrm = _ckModel.parameters.keyValues[_ReyeId][_ckLength - 1]; this.blnk_RBaseOpenPrm = this.blnk_ROpenPrm; } } } } } else if (this._model) { this.init(); } } updateTimeScale(live2d) { if (live2d.timeScale == this._timeScale) return; this._timeScale = live2d.timeScale; this._data.animation.setTimeScale(this._timeScale); } updateWeight(live2d) { if (live2d.weight == this._weight) return; this._weight = live2d.weight; try { this._weight.forEach((value, index) => { this._data.animation.setWeight(index, value); }); } catch (e) { } } updateMix(live2d) { if (live2d.mix == this._mix) return; for (let key in live2d.mix) { if (live2d.mix[key] != this._mix[key]) { let time = live2d.mix[key]; if (key == '/default/') { this._data.animation.setDefaultMix(time); } else { let [from, to] = key.split('/'); this._data.animation.setMix(from, to, time); } } } for (let key in this._mix) { if (key in live2d.mix == false) { if (key == '/default/') { this._data.animation.setDefaultMix(0); } else { let [from, to] = key.split('/'); this._data.animation.setMix(from, to, 0); } } } this._mix = live2d.mix; } updateColor(live2d) { let _ckArr = live2d.color["/default/"]; if(_ckArr == undefined){ if(this._color["/default/"] != undefined) { live2d.color["/default/"] = this._color["/default/"]; _ckArr = live2d.color["/default/"]; } else{ live2d.color["/default/"] = [1, 1, 1, 1]; _ckArr = live2d.color["/default/"]; } } if(live2d._TgtAlphaFlame > 0){ try { let _baseAlpha = live2d.color["/default/"][3]; _baseAlpha += live2d._TgtAlphaCng; live2d._TgtAlphaFlame--; if(_baseAlpha < 0){ _baseAlpha = 0; live2d._TgtAlphaFlame = 0; } if(live2d._TgtAlphaFlame == 0) _baseAlpha = live2d._TgtAlpha; live2d.setColor(_ckArr[0] , _ckArr[1] , _ckArr[2] , _baseAlpha); } catch (e) { } } if (live2d.color == this._color) return; for (let id in live2d.color) { if (live2d.color[id] != this._color[id]) { let color = live2d.color[id]; let filter = new PIXI.filters.ColorMatrixFilter(); filter.matrix = [ color[0], 0, 0, 0, 0, 0, color[1], 0, 0, 0, 0, 0, color[2], 0, 0, 0, 0, 0, color[3], 0 ]; let target = (id == '/default/') ? this._data : this.getArtMesh(id); let filters = (target.filters || []).filter(filter => { return filter instanceof PIXI.filters.ColorMatrixFilter == false; }); filters.push(filter); target.filters = filters; } if(id == '/default/') { this._mdlAlpha = live2d.color[id][3]; } } for (let id in this._color) { if (id in live2d.color == false) { let target = (id == '/default/') ? this._data : this.getArtMesh(id); let filters = (target.filters || []).filter(filter => { return filter instanceof PIXI.filters.ColorMatrixFilter == false; }); target.filters = filters.length > 0 ? filters : null; } } this._color = live2d.color; } updateMosaic(live2d) { if (live2d.mosaic == this._mosaic) return; for (let id in live2d.mosaic) { if (live2d.mosaic[id] != this._mosaic[id]) { let size = live2d.mosaic[id]; let _MosData = L2D_MosaicGet(live2d._name , id); let _XZure = -_MosData._ZureX; let _YZure = -_MosData._ZureY; let filter = new MosaicFilter(size , _XZure , _YZure); let target = (id == '/default/') ? this._data : this.getArtMesh(id); let filters = (target.filters || []).filter(filter => { return filter instanceof MosaicFilter == false; }); filters.push(filter); target.filters = filters; } } for (let id in this._mosaic) { if (id in live2d.mosaic == false) { let target = (id == '/default/') ? this._data : this.getArtMesh(id); let filters = (target.filters || []).filter(filter => { return filter instanceof MosaicFilter == false; }); target.filters = filters.length > 0 ? filters : null; } } this._mosaic = live2d.mosaic; } updateOffset(live2d) { if (live2d.offset == this._offset) return; this._offset = live2d.offset; this.x = this._offset.x; this.y = this._offset.y; } updateScale(live2d) { this.children.some( _CkLive2D => { if(_CkLive2D.constructor.name === "Live2D") { if(_CkLive2D.mask != live2d._SetMask){ _CkLive2D.mask = live2d._SetMask; } } }); if (live2d.scale == this._scale) return; this._scale = live2d.scale; this.scale.x = this._scale.x; this.scale.y = this._scale.y; } updateVisible(live2d) { this.visible = live2d.visible; } updateAnimation(live2d) { for (let i = 0; i <= live2d._expression.length - 1; i++) { if(live2d._expression[i] != "") { this._data.setExpression(i , live2d._expression[i] , live2d); live2d._expression[i] = ""; } } if (live2d.TrackCkSkipFlg == undefined) live2d.TrackCkSkipFlg = false; if (!live2d.TrackCkSkipFlg) { if (live2d.track == this._track) return; } for (let id in live2d.track) { if (live2d.track[id] != this._track[id] || live2d.TrackCkSkipFlg) { let track = live2d.track[id]; let list = []; let loop = track.continuance != 'none'; for (let animation of track.list) { for (let j = 0; j < animation.times; j++) { list.push(animation); } } if (track.order == 'shuffle') { let _list = [...list]; list = []; while (_list.length > 0) { let index = Math.floor(Math.random() * _list.length); list.push(_list.splice(index, 1)[0]); } } else if (track.order == 'random') { let index = Math.floor(Math.random() * list.length); list = [list[index]]; } list.forEach((animation, index) => { let entry; if ((index == 0 && track.interrupt) || live2d.TrackCkSkipFlg) { entry = this._data.animation.setAnimation(Number(id), animation.name, loop); } else { entry = this._data.animation.addAnimation(Number(id), animation.name, loop); } entry.timeScale = animation.timeScale; entry.weight = animation.weight; }); } } this._track = live2d.track; live2d.TrackCkSkipFlg = false; } getArtMesh(id) { let index = this._data.model.drawables.ids.indexOf(id); return this._data._meshes[index]; } onStart(trackInfo) { if (trackInfo.track.entries.length == 1) { let live2d = this.live2d(); let index = trackInfo.index; if (live2d && live2d.track[index]) { if (live2d.track[index] == this._track[index]) { if (this._track[index].continuance == 'reset') { live2d.track[index].interrupt = false; this._track = {...this._track}; this._track[index] = null; } } } } } onEnd(trackInfo) { } snapshot(live2d) { live2d.snapshot = this._data.snapshot(); } restore(live2d) { this._data.restore(live2d.snapshot); this._timeScale = live2d.timeScale; this._weight = live2d.weight; this._mix = live2d.mix; this._track = live2d.track; this._isRestore = false; } } window.Sprite_Live2D = Sprite_Live2D; // Game_Screen.prototype.live2d = function(id) { // let picture = this.picture(id); // if(picture == null) return null; // if (!picture._live2d) { // picture._live2d = new Game_Live2D(); // Game_Picture.prototype.initialize = function() { // __initialize.apply(this, arguments); // })(Game_Picture.prototype.initialize); // Game_Picture.prototype.erase = function() { // __erase.apply(this, arguments); // })(Game_Picture.prototype.erase); // Sprite_Picture.prototype.initialize = function(pictureId) { // __initialize.apply(this, arguments); // this.addChild(new Sprite_Live2D(pictureId)) // })(Sprite_Picture.prototype.initialize); }(); let SetSpriteLive2D = function(_No , _MdlName , _x , _y , _mx , _my) { _x = typeof _x !== 'undefined' ? _x : 0; _y = typeof _y !== 'undefined' ? _y : 0; _mx = typeof _mx !== 'undefined' ? _mx : 100; _my = typeof _my !== 'undefined' ? _my : 100; let _N_Sprite = SelSprite(_No); DelSprite(_No); let _INNo = _GetSpriteInNo(_No); let _SetSprite = _NSprite(_No ,"" , "" , _x , _y , 255 , _mx , _my); _SetSprite._live2d = new Game_Live2D(); _SetSprite._live2d.setModel(_MdlName); let _Set_SpriteLive2D = new Sprite_Live2D(_No); _Set_SpriteLive2D._live2d = _SetSprite._live2d; _SetSprite.addChild(_Set_SpriteLive2D); for (let i = 0; i <= L2D_MosaicDataArr.length - 1; i++) { if(L2D_MosaicDataArr[i]._Model == _MdlName){ _SetSprite._live2d.setMosaic(L2D_MosaicDataArr[i]._ArtMesh, L2D_MosaicDataArr[i]._MosPx); } } _N_Sprite.addChildAt(_SetSprite , _INNo); ViewSpriteArr_Add(_No); DebugSpriteNo(_No, "SetSpriteLive2D"); } !function() { if (!PIXI.SimpleMesh) { PIXI.SimpleMesh = class extends PIXI.mesh.Mesh { constructor(texture, vertices, uvs, indices, drawMode) { super(texture, vertices, uvs, indices, drawMode); this.state = {}; this.texture.baseTexture.resource = { source: this.texture.baseTexture.source }; Object.defineProperty(this.state, 'blendMode', { set: value => this.blendMode = value }); } } } class Mesh extends PIXI.SimpleMesh { constructor(texture, vertices, uvs, indices, drawMode) { super(texture, vertices, uvs, indices, drawMode); this.uvs = this.uvs || this.uvBuffer.data; this.indices = this.indices || this.geometry.indexBuffer.data; this.orderIndex = 0; } } class CopyMesh extends Mesh { constructor(mesh) { super(mesh.texture, mesh.vertices, mesh.uvs, mesh.indices, mesh.drawMode); this._mesh = mesh; } refresh() { this.vertices = this._mesh.vertices; } } class MaskMesh extends CopyMesh { constructor(mesh) { super(mesh); this.maskTexture = null; this.orderIndex = -Infinity; this.setup(); } setup() { this.maskTexture = new PIXI.Texture(new PIXI.BaseTexture()); this.maskTexture.baseTexture.valid = true; let filter = new PIXI.Filter(null, PIXI.Filter.defaultFragmentSrc.replace(/\S+uS.+/, 'vec4(0.);')); filter.apply = this.apply.bind(this); this.filters = [filter]; } copy(gl, uid, width, height) { let _texture = gl.getParameter(gl.TEXTURE_BINDING_2D); let texture = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texture); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, width, height, 0); gl.bindTexture(gl.TEXTURE_2D, _texture); this.maskTexture.baseTexture._glTextures[uid] = { dirtyId: 0, texture: texture }; } apply(filterManager, input, output, clear, currentState) { let gl = filterManager.renderer.gl; let uid = filterManager.renderer.CONTEXT_UID; let frame = {}, size = {}; if (input.filterFrame) { frame.x = input.filterFrame.x; frame.y = input.filterFrame.y; frame.width = input.filterFrame.width; frame.height = input.filterFrame.height; size.width = input.width; size.height = input.height; } else { frame.x = input.sourceFrame.x; frame.y = input.sourceFrame.y; frame.width = input.sourceFrame.width; frame.height = input.sourceFrame.height; size.width = input.size.width; size.height = input.size.height; } this.copy(gl, uid, size.width, size.height); this.maskTexture.maskInfo = { frame: frame, size: size }; filterManager.applyFilter(this.filters[0], input, output, clear, currentState); } update() { super.update(); this.children.forEach(child => child.update()); } } class MeshMaskFilter extends PIXI.Filter { constructor(mask, invert) { let vertexSrc = 'attribute vec2 aVertexPosition;attribute vec2 aTextureCoord;uniform mat3 projectionMatrix;uniform mat3 otherMatrix;uniform vec2 offset;varying vec2 vMaskCoord;varying vec2 vTextureCoord;void main(void){gl_Position=vec4((projectionMatrix*vec3(aVertexPosition,1.)).xy,0.,1.);vTextureCoord=aTextureCoord;vMaskCoord=(otherMatrix*vec3(aTextureCoord,1.)).xy+offset;}'; let fragmentSrc = 'precision mediump float;varying vec2 vMaskCoord;varying vec2 vTextureCoord;uniform sampler2D uSampler;uniform sampler2D mask;uniform vec2 size;uniform float invert;void main(void){float clip=step(3.5,step(0.,vMaskCoord.x)+step(0.,vMaskCoord.y)+step(vMaskCoord.x,size.x)+step(vMaskCoord.y,size.y));vec4 original=texture2D(uSampler,vTextureCoord);vec4 masky=texture2D(mask,vMaskCoord);gl_FragColor=original*abs(1.*invert-masky.a*clip);}'; super(vertexSrc, fragmentSrc); this._mask = mask; this.uniforms.invert = invert ? 1 : 0; } apply(filterManager, input, output, clear, currentState) { let texture = this._mask.maskTexture; let inputRect = {}; if (input.filterFrame) { inputRect.x = input.filterFrame.x; inputRect.y = input.filterFrame.y; inputRect.width = input.width; inputRect.height = input.height; } else { inputRect.x = input.sourceFrame.x; inputRect.y = input.sourceFrame.y; inputRect.width = input.size.width; inputRect.height = input.size.height; } let maskInfo = texture.maskInfo; this.uniforms.otherMatrix = new PIXI.Matrix(inputRect.width / maskInfo.size.width, 0, 0, inputRect.height / maskInfo.size.height, 0, 0); this.uniforms.offset = [(inputRect.x - maskInfo.frame.x) / maskInfo.size.width, (inputRect.y - maskInfo.frame.y) / maskInfo.size.height]; this.uniforms.mask = texture; this.uniforms.size = [maskInfo.frame.width / maskInfo.size.width, maskInfo.frame.height / maskInfo.size.height]; filterManager.applyFilter(this, input, output, clear); } } class Vector2 { constructor(x, y) { this.x = x || 0; this.y = y || 0; } add(vector2) { return new Vector2(this.x + vector2.x, this.y + vector2.y); } substract(vector2) { return new Vector2(this.x - vector2.x, this.y - vector2.y); } multiplyScalar(scalar) { return new Vector2(this.x * scalar, this.y * scalar); } normalize() { let length = Math.pow(this.x * this.x + this.y * this.y, 0.5); this.x /= length; this.y /= length; return this; } } class Physics { constructor(physics, parameters) { this._settings = {}; this._parameters = parameters; this.init(physics); } get settings() { return this._settings; } init(physics) { let parameters = this._parameters; let dictionary = physics.Meta.PhysicsDictionary; let settings = JSON.parse(JSON.stringify(physics.PhysicsSettings).replace(/(?<=")[^"]+(?=":)/g, m => m[0].toLowerCase() + m.slice(1))); for (let setting of settings) { let id = setting.id; delete setting.id; setting.name = (dictionary.find(item => item.Id == id) || { Name: '' }).Name; for (let input of setting.input) { input.source.index = parameters.ids.indexOf(input.source.id); } for (let output of setting.output) { output.destination.index = parameters.ids.indexOf(output.destination.id); } for (let vertex of setting.vertices) { vertex.position = new Vector2(vertex.position.x, vertex.position.y); vertex.lastGravity = new Vector2(0, 1); vertex.velocity = new Vector2(); } this._settings[id] = setting; } } apply(delta) { let values = this._parameters.values; let minimumValues = this._parameters.minimumValues; let maximumValues = this._parameters.maximumValues; let defaultValues = this._parameters.defaultValues; for (let id in this._settings) { let setting = this._settings[id]; let vertices = setting.vertices; let normalization = setting.normalization; let translation = { x: 0, y: 0 }; let angle = 0; for (let input of setting.input) { let index = input.source.index; let type = input.type; let value = this.normalize( values[index], minimumValues[index], maximumValues[index], defaultValues[index], type == 'Angle' ? normalization.angle : normalization.position, input.reflect ); value *= input.weight / 100; switch (type) { case 'X': translation.x += value; break; case 'Y': translation.y += value; break; case 'Angle': angle += value; break; } } angle = -angle / 180 * Math.PI; translation = { x: translation.x * Math.cos(angle) - translation.y * Math.sin(angle), y: translation.x * Math.sin(angle) + translation.y * Math.cos(angle) }; this.updateVertices(vertices, translation, -angle, normalization.position.maximum * 0.001, delta); for (let output of setting.output) { let index = output.destination.index; let vertexIndex = output.vertexIndex; let gravity = vertexIndex > 1 ? vertices[vertexIndex - 1].position.substract(vertices[vertexIndex - 2].position) : new Vector2(0, 1); if(vertices.length > vertexIndex) { translation = { x: vertices[vertexIndex].position.x - vertices[vertexIndex - 1].position.x, y: vertices[vertexIndex].position.y - vertices[vertexIndex - 1].position.y }; } let value = this.directionToRadian(gravity, translation); let outValues = values.slice(index); this.updateValues(outValues, minimumValues[index], maximumValues[index], value * output.scale, output.weight); for (let i = index, j = 0; i < values.length; i++, j++) { values[i] = outValues[j]; } } } } normalize(value, minimumValue, maximumValue, defaultValue, normalization, reflect) { let result = 0; value = Math.min(Math.max(value, minimumValue), maximumValue) - defaultValue; if (value != 0) { let p = (value > 0 ? maximumValue : minimumValue) - defaultValue; if (p != 0) { let n = (value > 0 ? normalization.maximum : normalization.minimum) - normalization.default; result = value * n / p + normalization.default; } } else { result = normalization.default; } return reflect ? result :-result; } updateVertices(vertices, translation, angle, shreshold, delta) { let gravity = new Vector2(Math.sin(angle), Math.cos(angle)).normalize(); vertices[0].position = new Vector2(translation.x, translation.y); for (let i = 1; i < vertices.length; ++i) { let delay = vertices[i].delay * delta * 30; let velocity = vertices[i].velocity.multiplyScalar(delay); let force = gravity.multiplyScalar(vertices[i].acceleration * delay * delay); let direction = vertices[i].position.substract(vertices[i - 1].position); let radian = this.directionToRadian(vertices[i].lastGravity, gravity) / 5; direction = new Vector2( Math.cos(radian) * direction.x - direction.y * Math.sin(radian), Math.sin(radian) * direction.x + direction.y * Math.cos(radian) ); let lastPosition = new Vector2(vertices[i].position.x, vertices[i].position.y); vertices[i].position = vertices[i - 1].position.add(direction).add(velocity).add(force); direction = vertices[i].position.substract(vertices[i - 1].position).normalize(); vertices[i].position = vertices[i - 1].position.add(direction.multiplyScalar(vertices[i].radius)); if (Math.abs(vertices[i].position.x) < shreshold) { vertices[i].position.x = 0; } if (delay != 0) { vertices[i].velocity = vertices[i].position.substract(lastPosition).multiplyScalar(vertices[i].mobility / delay); } vertices[i].lastGravity = new Vector2(gravity.x, gravity.y); } } updateValues(values, minimum, maximum, value, weight) { value = Math.min(Math.max(value, minimum), maximum); weight /= 100; if (weight >= 1) { values[0] = value; } else { values[0] = values[0] * (1 - weight) + value * weight; } } directionToRadian(from, to) { let q1 = Math.atan2(to.y, to.x); let q2 = Math.atan2(from.y, from.x); let ret = q1 - q2; while (ret < -Math.PI) { ret += Math.PI * 2; } while (ret > Math.PI) { ret -= Math.PI * 2; } return ret; } } class Curve { constructor(curve, beziersRestricted = false) { this._beziersRestricted = beziersRestricted; this._target = ''; this._id = ''; this._segments = []; this._points = []; this.create(curve); } get target() { return this._target; } get id() { return this._id; } create(curve) { this._target = curve.Target; this._id = curve.Id; this._fadeInTime = curve.FadeInTime; this._fadeOutTime = curve.FadeOutTime; this._segments = []; this._points = []; let basePoint = 0; let endPoint = 0; for (let i = 0; i < curve.Segments.length; i++) { let evaluate = null; if (i > 0) { let type = curve.Segments[i]; basePoint = endPoint; this._points.push({ time: curve.Segments[i + 1], value: curve.Segments[i + 2] }); if (type == 1) { this._points.push({ time: curve.Segments[i + 3], value: curve.Segments[i + 4] }); this._points.push({ time: curve.Segments[i + 5], value: curve.Segments[i + 6] }); endPoint = basePoint + 3; evaluate = this.bezier; i += 6; } else { endPoint = basePoint + 1; evaluate = type == 0 ? this.linear : type == 2 ? this.stepped : type == 3 ? this.inverseStepped : null; i += 2; } } else { this._points.push({ time: curve.Segments[0], value: curve.Segments[1] }); i++; } this._segments.push({ basePoint: basePoint, endPoint: endPoint, evaluate: evaluate }); } } value(time) { let segments = this._segments; let points = this._points; for (let i = 0; i < segments.length; i++) { if (points[segments[i].endPoint].time > time) { let basePoint = segments[i].basePoint; let endPoint = segments[i].endPoint; let evaluate = segments[i].evaluate; if (evaluate) { return evaluate.call(this, points.slice(basePoint, endPoint + 1), time); } break; } } return points.slice(-1)[0].value; } lerp(a, b, t) { let time = a.time + (b.time - a.time) * t; let value = a.value + (b.value - a.value) * t; return { time: time, value: value }; } linear(points, time) { let t = (time - points[0].time) / (points[1].time - points[0].time); return points[0].value + (points[1].value - points[0].value) * Math.max(t, 0); } bezier(points, time) { if (!this._beziersRestricted) { return this.cardano(points, time); } let t = Math.max((time - points[0].time) / (points[3].time - points[0].time), 0); let p0 = this.lerp(points[0], points[1], t); let p1 = this.lerp(points[1], points[2], t); let p2 = this.lerp(points[2], points[3], t); let p3 = this.lerp(p0, p1, t); let p4 = this.lerp(p1, p2, t); return this.lerp(p3, p4, t).value; } cardano(points, time) { let t0 = points[0].time; let t1 = points[1].time; let t2 = points[2].time; let t3 = points[3].time; let t4 = t3 + 3.0 * (t1 - t2) - t0; let t5 = 3.0 * (t0 + t2) - 6.0 * t1; let t6 = 3.0 * (t1 - t0); let t7 = t0 - time; let t = this.cardanoAlgorithm(t4, t5, t6, t7); let p0 = this.lerp(points[0], points[1], t); let p1 = this.lerp(points[1], points[2], t); let p2 = this.lerp(points[2], points[3], t); let p3 = this.lerp(p0, p1, t); let p4 = this.lerp(p1, p2, t); return this.lerp(p3, p4, t).value; } stepped(points) { return points[0].value; } inverseStepped(points) { return points[1].value; } range(value, min, max) { return Math.min(Math.max(value, min), max); } cbrt(x) { if (x == 0) { return x; } var cx = x; var isNegativeNumber = cx < 0; if (isNegativeNumber) { cx = -cx; } var ret; if (cx == Infinity) { ret = Infinity; } else { ret = Math.exp(Math.log(cx) / 3); ret = (cx / (ret * ret) + 2 * ret) / 3; } return isNegativeNumber ? -ret : ret; } quadratic(a, b, c) { if (Math.abs(a) < 0.00001) { if (Math.abs(b) < 0.00001) { return -c; } return -c / b; } return -(b + Math.sqrt(b * b - 4 * a * c)) / (2 * a); } cardanoAlgorithm(a, b, c, d) { if (Math.sqrt(a) < 0.00001) { return this.range(this.quadratic(b, c, d), 0, 1); } let ba = b / a; let ca = c / a; let da = d / a; let p = (3 * ca - ba * ba) / 3; let p3 = p / 3; let q = (2 * ba * ba * ba - 9 * ba * ca + 27 * da) / 27; let q2 = q / 2; let discriminant = q2 * q2 + p3 * p3 * p3; if (discriminant < 0) { let mp3 = -p / 3; let mp33 = mp3 * mp3 * mp3; let r = Math.sqrt(mp33); let t = -q / (2 * r); let cosphi = this.range(t, -1, 1); let phi = Math.acos(cosphi); let crtr = this.cbrt(r); let t1 = 2 * crtr; let root1_1 = t1 * Math.cos(phi / 3) - ba / 3; if (Math.abs(root1_1 - 0.5) < 0.51) { return this.range(root1_1, 0, 1); } let root2 = t1 * Math.cos((phi + 2 * Math.PI) / 3) - ba / 3; if (Math.abs(root2 - 0.5) < 0.51) { return this.range(root2, 0, 1); } let root3 = t1 * Math.cos((phi + 4 * Math.PI) / 3) - ba / 3; return this.range(root3, 0, 1); } else if (discriminant == 0) { let u1_1; if (q2 < 0) { u1_1 = this.cbrt(-q2); } else { u1_1 = -this.cbrt(q2); } let root1_2 = 2 * u1_1 - ba / 3; if (Math.abs(root1_2 - 0.5) < 0.51) { return this.range(root1_2, 0, 1); } let root2 = -u1_1 - ba / 3; return this.range(root2, 0, 1); } let sd = Math.sqrt(discriminant); let u1 = this.cbrt(sd - q2); let v1 = this.cbrt(sd + q2); let root1 = u1 - v1 - ba / 3; return this.range(root1, 0, 1); } } class Motion { constructor(motion) { let meta = motion.Data.Meta; this._duration = meta.Duration; this._loop = meta.Loop; this._beziersRestricted = meta.AreBeziersRestricted; this._group = motion.Group; this._name = motion.Name; this._fadeInTime = motion.FadeInTime; this._fadeOutTime = motion.FadeOutTime; this._curves = []; this.createCurve(motion.Data.Curves, this._beziersRestricted); } get duration() { return this._duration; } get group() { return this._group; }; get name() { return this._name; }; createCurve(curves) { this._curves = curves.map(curve => new Curve(curve)); } values(time) { let remain = Math.max(this._duration - time, 0); let values = {}; for (let curve of this._curves) { let fadeInTime = curve._fadeInTime != null ? curve._fadeInTime : this._fadeInTime; let fadeOutTime = curve._fadeOutTime != null ? curve._fadeOutTime : this._fadeOutTime; let fadeInWeight = time < fadeInTime ? time / fadeInTime : 1; let fadeOutWeight = remain < fadeOutTime ? remain / fadeOutTime : 1; let target = curve.target; let id = curve.id; let value = curve.value(time); let weight = fadeInWeight * fadeOutWeight; values[target] = values[target] || {}; values[target][id] = { value: value, weight: weight }; } return values; } } class Entry { constructor(motion, elapsed = 0) { this._motion = motion; this._elapsed = elapsed; this.loop = false; this.timeScale = 1; this.weight = 1; this.mixTime = 0; } get name() { return this._motion.name; } get duration() { return this._motion.duration; } get elapsed() { return this._elapsed; } get remain() { return this.duration - this._elapsed; } values(delta) { this._elapsed += (delta * this.timeScale); if (this.loop) { this._elapsed %= this.duration; } let values = this._motion.values(this._elapsed); for (let target in values) { for (let id in values[target]) { values[target][id].weight *= this.weight; } } return values; } } class Track { constructor(active = false) { this._entries = []; this._active = active; this.weight = 1; } get entries() { return this._entries; } get active() { return this._active; } add(entry) { let last = this.entry(-1); if (last) { last.loop = false; } this._entries.push(entry); } entry(index) { return this._entries.slice(index)[0]; } mix(values, next_values, rate) { let r0 = 1 - rate; let r1 = rate; for (let target in next_values) { for (let id in next_values[target]) { let value, weight; if (values[target] && values[target][id]) { let p0 = values[target][id]; let p1 = next_values[target][id]; value = p0.value * r0 + p1.value * r1; weight = p0.weight * r0 + p1.weight * r1; } else { let p = next_values[target][id]; value = p.value; weight = p.weight * r1; } values[target] = values[target] || {}; values[target][id] = { value: value, weight: weight }; } } } values(delta) { try { let entry = this._entries[0]; let next_entry = this._entries[1]; if (!entry) { return null; } if (!this._active) { delta = 0; } let _remain = entry.remain; let mixTime = next_entry ? next_entry.mixTime : 0; let values = entry.values(delta); let remain = entry.remain; if (remain > 0) { if (mixTime >= remain) { delta = Math.min(mixTime - remain, _remain - remain); let next_values = next_entry.values(delta); let rate = (mixTime - remain) / mixTime; this.mix(values, next_values, rate); } } else { if (next_entry) { delta = -remain / entry.timeScale; values = next_entry.values(delta); } this._entries.shift(); } this._active = remain > 0 || !!next_entry; return values; } catch (e) { return false; } } } class Animation { constructor(motions, parameters, parts) { this._motions = []; this._parameters = parameters; this._parts = parts; this._tracks = []; this._timeScale = 1; this._mixTime = {}; this._listeners = {}; this._expression = []; this.createMotion(motions); } get motions() { return this._motions; } get tracks() { return this._tracks; } get timeScale() { return this._timeScale; } get mixTime() { return this._mixTime; } createMotion(motions) { this._motions = motions.map(motion => new Motion(motion)); } track(index) { if (!this._tracks[index]) { this._tracks[index] = new Track(); } return this._tracks[index]; } setAnimation(index, name, loop) { let track = this._tracks[index]; if (track && track.active) { this.callListener('end', { index: index, track: track, entry: track.entry(0) }); } this._tracks[index] = null; return this.addAnimation(index, name, loop); } addAnimation(index, name, loop) { let motion = this._motions.find(motion => motion.name == name); let entry = new Entry(motion); let track = this.track(index); let last = track.entry(-1); if (last) { let key = `${last.name},${name}`; entry.mixTime = this._mixTime[key] || this._mixTime.default || 0; } entry.loop = loop; track.add(entry); return entry; } setTimeScale(scale) { this._timeScale = scale; } setWeight(index, value) { this.track(index).weight = value; } setMix(from, to, time) { if (time > 0) { this._mixTime[`${from},${to}`] = time; } else { delete this._mixTime[`${from},${to}`]; } } setDefaultMix(time) { if (time > 0) { this._mixTime.default = time; } else { delete this._mixTime.default; } } addListener(event, callback) { this._listeners[event] = this._listeners[event] || []; this._listeners[event].push(callback); } removeListener(event, callback) { if (this._listeners[event]) { let index = this._listeners[event].indexOf(callback); if (index >= 0) { this._listeners[event].splice(index, 1); } } } callListener(event, trackInfo) { if (this._listeners[event]) { this._listeners[event].forEach(callback => callback(trackInfo)); } } apply(delta) { delta *= this._timeScale; let parameters = this._parameters; let parts = this._parts; for (let track of this._tracks) { if(track == null) continue; let entry = track.entry(0); let active = track.active; let values = track.values(delta); if (!values) { continue; } for (let target in values) { for (let id in values[target]) { let p = values[target][id]; let value = p.value; let weight = p.weight * track.weight; if (target == 'Parameter') { let index = parameters.ids.indexOf(id); let _value = parameters.values[index]; parameters.values[index] = _value * (1 - weight) + value * weight; } else if (target == 'PartOpacity') { let index = parts.ids.indexOf(id); let _value = parts.opacities[index]; parts.opacities[index] = _value * (1 - weight) + value * weight; } } } let index = this._tracks.indexOf(track); let _entry = track.entry(0); let _active = track.active; if (!active && _active) { this.callListener('start', { index: index, track: track, entry: entry }); } if (entry != _entry) { if (entry) { this.callListener('end', { index: index, track: track, entry: entry }); } if (_entry) { this.callListener('start', { index: index, track: track, entry: _entry }); } } } } } class Live2D extends PIXI.Container { constructor(live2dData) { super(); this._data = live2dData; this._model = new Live2DCubismCore.Model(this._data.Moc); this._meshes = []; this._masks = {}; this._physics = null; this._animation = null; this._updateTime = 0; this.createMesh(); this.createMask(); this.createAnimation(); this.createPhysics(); this._exp_tracks = []; this._exp_SetTracks = []; this._SEParams = []; this._VoiceParams = []; for (let i = 0; i <= seSetting.length - 1; i++) { if(seSetting[i]._MdlName == this._data.name){ if(seSetting[i]._VoiceChara == "") { this._SEParams.push(new _SeParam(seSetting[i]._SeName)); } else { this._VoiceParams.push( new _VoiceParams(seSetting[i]._VoiceChara , seSetting[i]._SeName) ) } } } this._CmnParams = []; for (let i = 0; i <= this._model.parameters.ids.length - 1; i++) { if(this._model.parameters.ids[i].indexOf("CmnEv_") != -1){ let _SetCmnNo = this._model.parameters.ids[i].replace("CmnEv_" , ""); this._CmnParams.push(new _CmnEvParam(Number(_SetCmnNo))); } } if($gameSystem.L2D_SetParams_Arr == undefined) $gameSystem.L2D_SetParams_Arr = []; for (let i = 0; i <= $gameSystem.L2D_SetParams_Arr.length - 1; i++) { if($gameSystem.L2D_SetParams_Arr[i]._modelId == this._data.name) { for (let j = 0; j <= $gameSystem.L2D_SetParams_Arr[i]._ids.length - 1; j++) { let _CkId = $gameSystem.L2D_SetParams_Arr[i]._ids[j]; let _nSetNo = this._model.parameters.ids.indexOf(_CkId); if(_nSetNo != -1) { this._model.parameters.values[_nSetNo] = $gameSystem.L2D_SetParams_Arr[i]._values[j]; } else { $gameSystem.L2D_SetParams_Arr[i]._ids.splice(j , 1); $gameSystem.L2D_SetParams_Arr[i]._values.splice(j , 1); j--; } } } } } get model() { return this._model; } get animation() { return this._animation; } createMesh() { let drawables = this._model.drawables; for (let i = 0; i < drawables.count; i++) { let textureIndex = drawables.textureIndices[i]; let texture = this._data.Textures[textureIndex]; let vertices = this.localVertices(drawables.vertexPositions[i]); let uvs = new Float32Array(drawables.vertexUvs[i]); let indices = new Uint16Array(drawables.indices[i]); for (let j = 0; j < drawables.vertexCounts[i]; j++) { uvs[j * 2 + 1] = 1 - uvs[j * 2 + 1]; } for (let j = 1; j < drawables.indexCounts[i]; j += 3) { [indices[j], indices[j + 1]] = [indices[j + 1], indices[j]]; } let mesh = new Mesh(texture, vertices, uvs, indices, PIXI.DRAW_MODES.TRIANGLES); mesh.alpha = drawables.opacities[i]; mesh.visible = drawables.dynamicFlags[i] & 0x1; mesh.blendMode = drawables.constantFlags[i] & 0x3; mesh.state.culling = !(drawables.constantFlags[i] & 0x4); mesh.orderIndex = drawables.renderOrders[i]; this._meshes.push(mesh); this.addChild(mesh); } this.sortMesh(); } createMask() { let drawables = this._model.drawables; for (let i = 0; i < drawables.count; i++) { let mesh = this._meshes[i]; let invert = !!(drawables.constantFlags[i] & 0x8); let masks = [...drawables.masks[i]].sort(); if (masks.length > 0) { let mask = this._masks[masks]; if (!mask) { mask = new MaskMesh(this._meshes[masks[0]]); this.addChildAt(mask, 0); this._masks[masks] = mask; for (let j = 1; j < masks.length; j++) { mask.addChild(new CopyMesh(this._meshes[masks[j]])); } } let filters = mesh.filters || []; filters.push(new MeshMaskFilter(mask, invert)); if (mesh.blendMode > 0) { let filter = new PIXI.Filter(); filter.blendMode = mesh.blendMode; mesh.blendMode = 0; filters.push(filter); } mesh.filters = filters; } } } createPhysics() { if (this._data.Physics) { this._physics = new Physics(this._data.Physics, this._model.parameters); } } createAnimation() { if (this._data.Motions) { let motions = []; let parameters = this._model.parameters; let parts = this._model.parts; for (let name in this._data.Motions) { motions.push(...this._data.Motions[name]); } this._animation = new Animation(motions, parameters, parts); this._animation.parent = this; } } sortMesh() { this.children.sort((a, b) => a.orderIndex - b.orderIndex); } localVertices(vertices) { let canvasinfo = this._model.canvasinfo; let cox = canvasinfo.CanvasOriginX; let coy = canvasinfo.CanvasOriginY; let ppu = canvasinfo.PixelsPerUnit; return vertices.map((vertex, index) => index % 2 ? coy - vertex * ppu : vertex * ppu + cox); } setExpression(index , name) { for (let i = this._exp_tracks.length; i <= index; i++) { this._exp_tracks.push(null); } for (let i = 0; i <= this._data.Expressions.length - 1; i++) { if(this._data.Expressions[i].Name == name){ this._exp_tracks[index] = this._data.Expressions[i]; let _LSetFlg = false; var _RSetFlg = false; this._data.Expressions[i].Parameters.forEach( _Prm => { if(_Prm.Id == "eyeOpenL") { this.parent.blnk_LOpenPrm = _Prm.Value; _LSetFlg = true; } if(_Prm.Id == "eyeOpenR") { this.parent.blnk_ROpenPrm = _Prm.Value; _RSetFlg = true; } }); if(!_LSetFlg) this.parent.blnk_LOpenPrm = this.parent.blnk_LBaseOpenPrm; if(!_RSetFlg) this.parent.blnk_ROpenPrm = this.parent.blnk_RBaseOpenPrm; } } } delExpression(index) { for (var i = this._exp_tracks.length; i <= index; i++) { this._exp_tracks.push(null); } this._exp_tracks[index] = null; } update() { if(this.parent._mdlAlpha == undefined) this.parent._mdlAlpha = 1; if(this.parent._mdlAlpha < 0.00001){ return; } //★Live2Dのビューワーと見え方を合わせる為、時刻制御(performance.now())では無く、フレーム制御に変更 let time = 0; switch (L2D_Mode) { case L2D_PFSMode.Nomal: time = performance.now() / 1000; break; case L2D_PFSMode.FPS30: time = this._updateTime + (1 / 60); break; case L2D_PFSMode.FPS60: time = this._updateTime + (1 / 30); break; } if (this._updateTime > 0) { let delta = time - this._updateTime; if(L2D_Mode == L2D_PFSMode.FPS30) { let ck_Var = Math.fround(time / delta) % 2; if(ck_Var != 0) delta = 0; } this.applyAnimation(delta); this.applyPhysics(delta); } this._model.update(); for (let etrack of this._exp_SetTracks) { if(etrack == null) continue; for (let i = 0; i <= etrack.Parameters.length - 1; i++) { let _EditMode = etrack.Parameters[i].Blend; let _id = etrack.Parameters[i].Id; let _Setvalue = etrack.Parameters[i].Value; switch(_EditMode){ case "Add": let index = this._model.parameters.ids.indexOf(_id); let _value = this._model.parameters.values[index]; this._model.parameters.values[index] = _value - _Setvalue; break; } } } this._exp_SetTracks = []; for (let etrack of this._exp_tracks) { if(etrack == null) continue; for (let i = 0; i <= etrack.Parameters.length - 1; i++) { let _EditMode = etrack.Parameters[i].Blend; let _id = etrack.Parameters[i].Id; let _Setvalue = etrack.Parameters[i].Value; switch(_EditMode){ case "Add": let index = this._model.parameters.ids.indexOf(_id); let _value = this._model.parameters.values[index]; this._model.parameters.values[index] = _value + _Setvalue; break; } } this._exp_SetTracks.push(etrack); } this.updateMesh(); this.refreshMask(); this._model.drawables.resetDynamicFlags(); this._updateTime = time; if(this.NSet_ids == undefined) this.NSet_ids = []; if(this.NSet_values == undefined) this.NSet_values = []; for (let i = 0; i <= L2D_DelParams_Arr.length - 1; i++) { if(L2D_DelParams_Arr[i]._modelId == this.parent._model) { for (let j = 0; j <= L2D_DelParams_Arr[i]._ids.length - 1; j++) { let _nSetNo = this.NSet_ids.indexOf(L2D_DelParams_Arr[i]._ids[j]); if(_nSetNo != -1) { this.NSet_ids.splice(_nSetNo , 1); this.NSet_values.splice(_nSetNo , 1); } } L2D_DelParams_Arr.splice(i , 1); break; } } for (let i = 0; i <= L2D_SetParams_Arr.length - 1; i++) { if(L2D_SetParams_Arr[i]._modelId == this.parent._model) { for (let j = 0; j <= L2D_SetParams_Arr[i]._ids.length - 1; j++) { let _nSetNo = this.NSet_ids.indexOf(L2D_SetParams_Arr[i]._ids[j]); if(_nSetNo != -1){ this.NSet_values[_nSetNo] = L2D_SetParams_Arr[i]._values[j]; } else { this.NSet_ids.push(L2D_SetParams_Arr[i]._ids[j]); this.NSet_values.push(L2D_SetParams_Arr[i]._values[j]); } } L2D_SetParams_Arr.splice(i , 1); break; } } for (let i = 0; i <= this.NSet_ids.length - 1; i++) { let _nSetNo = this._model.parameters.ids.indexOf(this.NSet_ids[i]); if(_nSetNo != -1){ this._model.parameters.values[_nSetNo] = this.NSet_values[i]; } else { this.NSet_ids.splice(i , 1); this.NSet_values.splice(i , 1); i--; } } if($gameSystem.L2D_SetParams_Arr == undefined) $gameSystem.L2D_SetParams_Arr = []; for (let i = 0; i <= $gameSystem.L2D_SetParams_Arr.length - 1; i++) { if($gameSystem.L2D_SetParams_Arr[i]._modelId == this.parent._name){ for (let j = 0; j <= $gameSystem.L2D_SetParams_Arr[i]._ids.length - 1; j++) { let _CkId = $gameSystem.L2D_SetParams_Arr[i]._ids[j]; let _nSetNo = this._model.parameters.ids.indexOf(_CkId); if(_nSetNo != -1) { this._model.parameters.values[_nSetNo] = $gameSystem.L2D_SetParams_Arr[i]._values[j]; } else { $gameSystem.L2D_SetParams_Arr[i]._ids.splice(j , 1); $gameSystem.L2D_SetParams_Arr[i]._values.splice(j , 1); j--; } } } } if(L2D_SetParamsOne_Arr == undefined) L2D_SetParamsOne_Arr = []; for (let i = 0; i <= L2D_SetParamsOne_Arr.length - 1; i++) { if(L2D_SetParamsOne_Arr[i]._modelId == this.parent._name){ for (let j = 0; j <= L2D_SetParamsOne_Arr[i]._ids.length - 1; j++) { let _CkId = L2D_SetParamsOne_Arr[i]._ids[j]; let _nSetNo = this._model.parameters.ids.indexOf(_CkId); if(_nSetNo != -1) { this._model.parameters.values[_nSetNo] = L2D_SetParamsOne_Arr[i]._values[j]; L2D_SetParamsOne_Arr.splice(i , 1); i--; if(i == -1) break; } else { L2D_SetParamsOne_Arr[i]._ids.splice(j , 1); L2D_SetParamsOne_Arr[i]._values.splice(j , 1); j--; } } } } const _bCloseFlame = 5; const _bOpenFlame = 10; if(this.parent.blnk_flg){ this.parent.blnk_flame--; var _CngParaL = this.parent.blnk_LOpenPrm; var _CngParaR = this.parent.blnk_LOpenPrm; if(this.parent.blnk_flame < 0){ let WariMabL = this.parent.blnk_LClosePrm - this.parent.blnk_LOpenPrm; let WariMabR = this.parent.blnk_RClosePrm - this.parent.blnk_ROpenPrm; if (this.parent.blnk_flame >= -_bCloseFlame) { let _Var = (-this.parent.blnk_flame); _CngParaL = this.parent.blnk_LOpenPrm + (WariMabL * (_Var / 5)); _CngParaR = this.parent.blnk_ROpenPrm + (WariMabR * (_Var / 5)); } else if (this.parent.blnk_flame >= -(_bCloseFlame + _bOpenFlame)) { let _Var = (-this.parent.blnk_flame) - _bCloseFlame; _CngParaL = this.parent.blnk_LClosePrm - (WariMabL * (_Var / _bOpenFlame)); _CngParaR = this.parent.blnk_LClosePrm - (WariMabR * (_Var / _bOpenFlame)); } else if (this.parent.blnk_flame >= -16) { if (Math.random() > 0.5 && !this.blink_dflg) { this.parent.blnk_flame = 0; this.blink_dflg = true; } else { this.parent.blnk_flame = Math.floor(Math.random() * 300 + 50); this.blink_dflg = false; } } } if (this.parent.blnk_LIdNo != -1) { this._model.parameters.values[this.parent.blnk_LIdNo] = _CngParaL; } if(this.parent.blnk_RIdNo != -1){ this._model.parameters.values[this.parent.blnk_RIdNo] = _CngParaR; } } for (let i = 0; i <= this._SEParams.length - 1; i++) { let _idNo = this._model.parameters.ids.indexOf(this._SEParams[i]._SeName); if(_idNo == -1) { this._SEParams.splice(i , 1); i--; continue; } let _ckVar = this._model.parameters.values[_idNo]; if(!this._SEParams[i]._OnFlg) { if(_ckVar >= 28){ this._SEParams[i]._OnFlg = true; L2D_SePlayEvArr.push(this._SEParams[i]._SeName) } } else { if(_ckVar < 28){ this._SEParams[i]._OnFlg = false; } } } for (let i = 0; i <= this._VoiceParams.length - 1; i++) { let _idNo = this._model.parameters.ids.indexOf(this._VoiceParams[i]._VoiceName); if(_idNo == -1) { this._VoiceParams.splice(i , 1); i--; continue; } let _ckVar = this._model.parameters.values[_idNo]; if(!this._VoiceParams[i]._OnFlg) { if(_ckVar >= 28){ this._VoiceParams[i]._OnFlg = true; L2D_VoicePlayEvArr.push( [this._VoiceParams[i]._VoiceChara , this._VoiceParams[i]._VoiceName] ); } } else { if(_ckVar < 28) { this._VoiceParams[i]._OnFlg = false; } } } } updateMesh() { let drawables = this._model.drawables; let vertices = drawables.vertexPositions; let opacities = drawables.opacities; let renderOrders = drawables.renderOrders; let dynamicFlags = drawables.dynamicFlags; let needsSort = false; this._meshes.forEach((mesh, index) => { mesh.visible = !!(dynamicFlags[index] & 0x1); mesh.alpha = opacities[index]; mesh.orderIndex = renderOrders[index]; if (dynamicFlags[index] & 0x10) { needsSort = true; } if (dynamicFlags[index] & 0x20) { mesh.vertices = this.localVertices(vertices[index]); } }); if (needsSort) { this.sortMesh(); } } refreshMask() { for (let key in this._masks) { this._masks[key].refresh(); } } applyPhysics(delta) { if (this._physics) { this._physics.apply(delta); } } applyAnimation(delta) { if (this._animation) { this._animation.apply(delta); } } snapshot() { if (!this._animation) { return null; } let parameters = { ids: [...this._model.parameters.ids], values: [...this._model.parameters.values] }; let parts = { ids: [...this._model.parts.ids], opacities: [...this._model.parts.opacities] }; let animation = { tracks: [], timeScale: this._animation.timeScale, mixTime: {} }; for (let key in this._animation.mixTime) { animation.mixTime[key] = this._animation.mixTime[key]; } this._animation.tracks.forEach((track, index) => { let entries = []; animation.tracks[index] = { entries: entries, active: track.active, weight: track.weight }; try { track.entries.forEach(entry => { entries.push({ name: entry.name, elapsed: entry.elapsed, loop: entry.loop, timeScale: entry.timeScale, weight: entry.weight, mixTime: entry.mixTime }); }); } catch (e) { console.log("Live2D::TrackEntryErr"); } }); let physics = {}; if(this._physics != null){ for (let key in this._physics.settings) { physics[key] = []; for (let vertex of this._physics.settings[key].vertices) { physics[key].push({ position: {...vertex.position}, lastGravity: {...vertex.lastGravity}, velocity: {...vertex.velocity} }); } } } return { parameters: parameters, parts: parts, animation: animation, physics: physics }; } restore(snapshot) { if (!snapshot) { return; } let parameters = snapshot.parameters; let parts = snapshot.parts; let animation = snapshot.animation; let physics = snapshot.physics; parameters.ids.forEach((id, index) => { let _index = this._model.parameters.ids.indexOf(id); if (_index >= 0) { this._model.parameters.values[_index] = parameters.values[index]; } }); parts.ids.forEach((id, index) => { let _index = this._model.parts.ids.indexOf(id); if (_index >= 0) { this._model.parts.opacities[_index] = parts.opacities[index]; } }); this._animation.setTimeScale(animation.timeScale); for (let key in animation.mixTime) { if (key == 'default') { this._animation.setDefaultMix(animation.mixTime[key]); } else { let [from, to] = key.split(/(?<=^[^,]+),/); this._animation.setMix(from, to, animation.mixTime[key]); } } let motions = this._animation.motions; this._animation.tracks.splice(0); animation.tracks.forEach((trackData, index) => { let track = new Track(trackData.active); track.weight = trackData.weight; for (let entryData of trackData.entries) { let motion = motions.find(motion => motion.name == entryData.name); let entry = new Entry(motion, entryData.elapsed); entry.loop = entryData.loop; entry.timeScale = entryData.timeScale; entry.weight = entryData.weight; entry.mixTime = entryData.mixTime; track.add(entry); } this._animation.tracks[index] = track; }); for (let key in physics) { if (key in this._physics.settings) { let vertices = this._physics.settings[key].vertices; physics[key].forEach((vertex, index) => { if (vertices[index]) { Object.assign(vertices[index].position, vertex.position); Object.assign(vertices[index].lastGravity, vertex.lastGravity); Object.assign(vertices[index].velocity, vertex.velocity); } }); } } } } Live2D.Mesh = Mesh; Live2D.MaskMesh = MaskMesh; Live2D.MeshMaskFilter = MeshMaskFilter; Live2D.Vector2 = Vector2; Live2D.Physics = Physics; Live2D.Curve = Curve; Live2D.Motion = Motion; Live2D.Entry = Entry; Live2D.Track = Track; Live2D.Animation = Animation; PIXI.Live2D = Live2D; let Model3Parser = (function() { let LoaderResource = PIXI.LoaderResource || PIXI.loaders.Resource; LoaderResource.setExtensionXhrType('moc3', LoaderResource.XHR_RESPONSE_TYPE.BUFFER); function isJson(resource) { return resource.type == LoaderResource.TYPE.JSON; } function Model3Parser() { return Model3Parser.use; } Model3Parser.use = function(resource, next) { if (!isJson(resource) || !resource.data.FileReferences) { return next(); } let _loadFileName = resource.data.FileReferences.Moc.replace(".moc3",""); Load_TextureArr.push(new _Load_Texture(_loadFileName)); let data = resource.data; let fileReferences = resource.data.FileReferences; let baseUrl = resource.url.replace(/[^/]+$/, ''); let loadOption = { parentResource: resource }; let live2dData = { Version: data.Version, Moc: null, Textures: [], Physics: null, Pose: null, UserData: null, Motions: null, Expressions: null, Groups: data.Groups, HitAreas: data.HitAreas }; for (let index in fileReferences) { if (index == 'Moc') { let url = baseUrl + fileReferences.Moc; this.add(`${resource.name}/Moc`, url, loadOption, function (resource) { live2dData.Moc = new Live2DCubismCore.Moc(resource.data); next(); }); } else if (index == 'Textures') { for (let i = 0; i < fileReferences.Textures.length; i++) { let url = baseUrl + fileReferences.Textures[i]; if(live2dData.Texture_url == undefined) live2dData.Texture_url = []; live2dData.Texture_url.push(url) live2dData.Textures.push(null); this.add(`${resource.name}/Texture_${i}`, url, loadOption, function (resource) { var _setIndex = live2dData.Texture_url.indexOf(resource.url); live2dData.Textures[_setIndex] = resource.texture; next(); }); Load_TextureArr[Load_TextureArr.length - 1]._TextureCnt++; } } else if (['Physics', 'Pose', 'UserData'].includes(index)) { if(fileReferences[index] != null ) { let url = baseUrl + fileReferences[index]; this.add(`${resource.name}/${index}`, url, loadOption, function (resource) { live2dData[index] = resource.data; next(); }); } } else if (index == 'Motions') { live2dData.Motions = {}; for (let group in fileReferences.Motions) { live2dData.Motions[group] = []; let motion = fileReferences.Motions[group]; for (let i = 0; i < motion.length; i++) { live2dData.Motions[group][i] = { FadeInTime: motion[i].FadeInTime, FadeOutTime: motion[i].FadeOutTime }; let url = baseUrl + motion[i].File; this.add(`${resource.name}/Motion/${group}_${i}`, url, loadOption, function (resource) { live2dData.Motions[group][i].Group = group; live2dData.Motions[group][i].Name = motion[i].File.replace("motions/" , "").replace(".motion3.json" , ""); //live2dData.Motions[group][i].Name = motion[i].Name || group + String(i + 1).padStart(2, '0'); live2dData.Motions[group][i].Data = resource.data; next(); }); } } } else if (index == "Expressions") { live2dData.Expressions = fileReferences.Expressions; for (let i = 0; i < live2dData.Expressions.length; i++) { live2dData.Expressions[i].Parameters = []; let url = baseUrl + live2dData.Expressions[i].File; let ename = live2dData.Expressions[i].Name; this.add(`${resource.name}/Expression/${ename}`, url, loadOption, function (resource) { live2dData.Expressions.forEach( _EXP => { var _ckStrArr = resource.name.split('/'); if(_EXP.Name == _ckStrArr[_ckStrArr.length - 1]) _EXP.Parameters = resource.data.Parameters; }); next(); }); } } } resource.live2dData = live2dData; next(); }; return Model3Parser; })(); if (PIXI.Loader) { PIXI.Loader.registerPlugin(Model3Parser); } else { PIXI.loaders.Loader.addPixiMiddleware(Model3Parser); } }();