2171 lines
94 KiB
JavaScript
2171 lines
94 KiB
JavaScript
/*:
|
||
* @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);
|
||
}
|
||
}();
|