/** * * You can modify and use this source freely * only for the development of application related Live2D. * * (c) Live2D Inc. All rights reserved. */ //============================================================ //============================================================ // class L2DBaseModel //============================================================ //============================================================ function L2DBaseModel() { this.live2DModel = null; // ALive2DModel this.modelMatrix = null; // L2DModelMatrix this.eyeBlink = null; // L2DEyeBlink this.physics = null; // L2DPhysics this.pose = null; // L2DPose this.debugMode = false; this.initialized = false; this.updating = false; this.alpha = 1; this.accAlpha = 0; this.lipSync = false; // リップシンクが有効かどうか this.lipSyncValue = 0; // 基本は0~1 this.accelX = 0; this.accelY = 0; this.accelZ = 0; this.dragX = 0; this.dragY = 0; this.startTimeMSec = null; this.mainMotionManager = new L2DMotionManager(); //L2DMotionManager this.expressionManager = new L2DMotionManager(); //L2DMotionManager this.motions = {}; this.expressions = {}; this.isTexLoaded = false; } var texCounter = 0; //============================================================ // L2DBaseModel # getModelMatrix() //============================================================ L2DBaseModel.prototype.getModelMatrix = function() { return this.modelMatrix; } //============================================================ // L2DBaseModel # setAlpha() //============================================================ L2DBaseModel.prototype.setAlpha = function(a/*float*/) { if( a > 0.999 ) a = 1; if( a < 0.001 ) a = 0; this.alpha = a; } //============================================================ // L2DBaseModel # getAlpha() //============================================================ L2DBaseModel.prototype.getAlpha = function() { return this.alpha; } //============================================================ // L2DBaseModel # isInitialized() //============================================================ L2DBaseModel.prototype.isInitialized = function() { return this.initialized; } //============================================================ // L2DBaseModel # setInitialized() //============================================================ L2DBaseModel.prototype.setInitialized = function( v/*boolean*/) { this.initialized = v; } //============================================================ // L2DBaseModel # isUpdating() //============================================================ L2DBaseModel.prototype.isUpdating = function() { return this.updating; } //============================================================ // L2DBaseModel # setUpdating() //============================================================ L2DBaseModel.prototype.setUpdating = function(v/*boolean*/) { this.updating = v; } //============================================================ // L2DBaseModel # getLive2DModel() //============================================================ L2DBaseModel.prototype.getLive2DModel = function() { return this.live2DModel; } //============================================================ // L2DBaseModel # setLipSync() //============================================================ L2DBaseModel.prototype.setLipSync = function(v/*boolean*/) { this.lipSync = v; } //============================================================ // L2DBaseModel # setLipSyncValue() //============================================================ L2DBaseModel.prototype.setLipSyncValue = function(v/*float*/) { this.lipSyncValue = v; } //============================================================ // L2DBaseModel # setAccel() //============================================================ L2DBaseModel.prototype.setAccel = function(x/*float*/, y/*float*/, z/*float*/) { this.accelX = x; this.accelY = y; this.accelZ = z; } //============================================================ // L2DBaseModel # setDrag() //============================================================ L2DBaseModel.prototype.setDrag = function(x/*float*/, y/*float*/) { this.dragX = x; this.dragY = y; } //============================================================ // L2DBaseModel # getMainMotionManager() //============================================================ L2DBaseModel.prototype.getMainMotionManager = function() { return this.mainMotionManager; } //============================================================ // L2DBaseModel # getExpressionManager() //============================================================ L2DBaseModel.prototype.getExpressionManager = function() { return this.expressionManager; } //============================================================ // L2DBaseModel # loadModelData() //============================================================ L2DBaseModel.prototype.loadModelData = function(path/*String*/, callback) { /* if( this.live2DModel != null ) { this.live2DModel.deleteTextures(); } */ var pm = Live2DFramework.getPlatformManager(); //IPlatformManager if( this.debugMode ) pm.log("Load model : " + path); var thisRef = this; pm.loadLive2DModel(path, function(l2dModel) { thisRef.live2DModel = l2dModel; thisRef.live2DModel.saveParam(); var _err = Live2D.getError(); if( _err != 0 ) { console.error("Error : Failed to loadModelData()."); return; } thisRef.modelMatrix = new L2DModelMatrix( thisRef.live2DModel.getCanvasWidth(), thisRef.live2DModel.getCanvasHeight()); //L2DModelMatrix thisRef.modelMatrix.setWidth(2); thisRef.modelMatrix.setCenterPosition(0, 0); callback(thisRef.live2DModel); }); } //============================================================ // L2DBaseModel # loadTexture() //============================================================ L2DBaseModel.prototype.loadTexture = function(no/*int*/, path/*String*/, callback) { texCounter++; var pm = Live2DFramework.getPlatformManager(); //IPlatformManager if( this.debugMode ) pm.log("Load Texture : " + path); var thisRef = this; pm.loadTexture(this.live2DModel , no , path, function(){ texCounter--; if(texCounter == 0) thisRef.isTexLoaded = true; if (typeof callback == "function") callback(); }); } //============================================================ // L2DBaseModel # loadMotion() //============================================================ L2DBaseModel.prototype.loadMotion = function(name/*String*/, path /*String*/, callback) { var pm = Live2DFramework.getPlatformManager(); //IPlatformManager if(this.debugMode) pm.log("Load Motion : " + path); var motion = null; //Live2DMotion var thisRef = this; pm.loadBytes(path, function(buf) { motion = Live2DMotion.loadMotion(buf); if( name != null ) { thisRef.motions[name] = motion; } callback(motion); }); } //============================================================ // L2DBaseModel # loadExpression() //============================================================ L2DBaseModel.prototype.loadExpression = function(name/*String*/, path /*String*/, callback) { var pm = Live2DFramework.getPlatformManager(); //IPlatformManager if( this.debugMode ) pm.log("Load Expression : " + path); var thisRef = this; pm.loadBytes(path, function(buf) { if(name != null) { thisRef.expressions[name] = L2DExpressionMotion.loadJson(buf); } if (typeof callback == "function") callback(); }); } //============================================================ // L2DBaseModel # loadPose() //============================================================ L2DBaseModel.prototype.loadPose = function( path /*String*/, callback ) { var pm = Live2DFramework.getPlatformManager(); //IPlatformManager if( this.debugMode ) pm.log("Load Pose : " + path); var thisRef = this; try { pm.loadBytes(path, function(buf) { thisRef.pose = L2DPose.load(buf); if (typeof callback == "function") callback(); }); } catch(e) { console.warn(e); } } //============================================================ // L2DBaseModel # loadPhysics() //============================================================ L2DBaseModel.prototype.loadPhysics = function(path/*String*/) { var pm = Live2DFramework.getPlatformManager(); //IPlatformManager if( this.debugMode ) pm.log("Load Physics : " + path); var thisRef = this; try { pm.loadBytes(path, function(buf) { thisRef.physics = L2DPhysics.load(buf); }); } catch(e){ console.warn(e); } } //============================================================ // L2DBaseModel # hitTestSimple() //============================================================ L2DBaseModel.prototype.hitTestSimple = function(drawID, testX, testY) { var drawIndex = this.live2DModel.getDrawDataIndex(drawID); if( drawIndex < 0 ) return false; var points = this.live2DModel.getTransformedPoints(drawIndex); var left = this.live2DModel.getCanvasWidth(); var right = 0; var top = this.live2DModel.getCanvasHeight(); var bottom = 0; for( var j = 0; j < points.length; j = j + 2 ) { var x = points[j]; var y = points[j + 1]; if( x < left ) left = x; if( x > right ) right = x; if( y < top ) top = y; if( y > bottom ) bottom = y; } var tx = this.modelMatrix.invertTransformX(testX); var ty = this.modelMatrix.invertTransformY(testY); return ( left <= tx && tx <= right && top <= ty && ty <= bottom ); } /** * * You can modify and use this source freely * only for the development of application related Live2D. * * (c) Live2D Inc. All rights reserved. */ //============================================================ //============================================================ // class L2DExpressionMotion extends AMotion //============================================================ //============================================================ function L2DExpressionMotion() { AMotion.prototype.constructor.call(this); this.paramList = new Array(); //ArrayList } L2DExpressionMotion.prototype = new AMotion(); // L2DExpressionMotion extends AMotion //============================================================ L2DExpressionMotion.EXPRESSION_DEFAULT = "DEFAULT"; L2DExpressionMotion.TYPE_SET = 0; L2DExpressionMotion.TYPE_ADD = 1; L2DExpressionMotion.TYPE_MULT = 2; //============================================================ // static L2DExpressionMotion.loadJson() //============================================================ L2DExpressionMotion.loadJson = function(buf) { var ret = new L2DExpressionMotion(); var pm = Live2DFramework.getPlatformManager(); var json = pm.jsonParseFromBytes(buf); ret.setFadeIn(parseInt(json.fade_in) > 0 ? parseInt(json.fade_in) : 1000); ret.setFadeOut(parseInt(json.fade_out) > 0 ? parseInt(json.fade_out) : 1000); if(json.params == null) { return ret; } var params = json.params; var paramNum = params.length; ret.paramList = []; //ArrayList for( var i = 0; i < paramNum; i++) { var param = params[i]; var paramID = param.id.toString(); var value = parseFloat(param.val); var calcTypeInt = L2DExpressionMotion.TYPE_ADD; var calc = param.calc != null ? param.calc.toString() : "add"; if(calc === "add") { calcTypeInt = L2DExpressionMotion.TYPE_ADD; } else if(calc === "mult") { calcTypeInt = L2DExpressionMotion.TYPE_MULT; } else if(calc === "set") { calcTypeInt = L2DExpressionMotion.TYPE_SET; } else { calcTypeInt = L2DExpressionMotion.TYPE_ADD; } if(calcTypeInt == L2DExpressionMotion.TYPE_ADD) { var defaultValue = param.def == null ? 0 : parseFloat(param.def); value = value - defaultValue; } else if(calcTypeInt == L2DExpressionMotion.TYPE_MULT) { var defaultValue = param.def == null ? 1 : parseFloat(param.def); if(defaultValue == 0 ) defaultValue = 1; value = value / defaultValue; } var item = new L2DExpressionParam( ); item.id = paramID; item.type = calcTypeInt; item.value = value; ret.paramList.push(item); } return ret; } //============================================================ // L2DExpressionMotion # updateParamExe() //============================================================ L2DExpressionMotion.prototype.updateParamExe = function(model /*ALive2DModel*/, timeMSec/*long*/ ,weight /*float*/ ,motionQueueEnt /*MotionQueueEnt*/) { for(var i = this.paramList.length - 1; i >= 0; --i) { var param = this.paramList[i]; //L2DExpressionParam // if (!param || !param.type) continue; if(param.type == L2DExpressionMotion.TYPE_ADD) { model.addToParamFloat(param.id, param.value, weight); } else if(param.type == L2DExpressionMotion.TYPE_MULT) { model.multParamFloat(param.id, param.value, weight); } else if(param.type == L2DExpressionMotion.TYPE_SET) { model.setParamFloat(param.id, param.value, weight); } } } //============================================================ //============================================================ // class L2DExpressionParam //============================================================ //============================================================ function L2DExpressionParam() { this.id = ""; this.type = -1; this.value = null; } /** * * You can modify and use this source freely * only for the development of application related Live2D. * * (c) Live2D Inc. All rights reserved. */ //============================================================ //============================================================ // class L2DEyeBlink //============================================================ //============================================================ function L2DEyeBlink() { this.nextBlinkTime = null /* TODO NOT INIT */; // this.stateStartTime = null /* TODO NOT INIT */; // this.blinkIntervalMsec = null /* TODO NOT INIT */; // this.eyeState = EYE_STATE.STATE_FIRST; this.blinkIntervalMsec = 4000; this.closingMotionMsec = 100; this.closedMotionMsec = 50; this.openingMotionMsec = 150; this.closeIfZero = true; this.eyeID_L = "PARAM_EYE_L_OPEN"; this.eyeID_R = "PARAM_EYE_R_OPEN"; } //============================================================ // L2DEyeBlink # calcNextBlink() //============================================================ L2DEyeBlink.prototype.calcNextBlink = function() { var time /*long*/ = UtSystem.getUserTimeMSec(); var r /*Number*/ = Math.random(); return /*(long)*/ (time + r * (2 * this.blinkIntervalMsec - 1)); } //============================================================ // L2DEyeBlink # setInterval() //============================================================ L2DEyeBlink.prototype.setInterval = function(blinkIntervalMsec /*int*/) { this.blinkIntervalMsec = blinkIntervalMsec; } //============================================================ // L2DEyeBlink # setEyeMotion() //============================================================ L2DEyeBlink.prototype.setEyeMotion = function(closingMotionMsec/*int*/ , closedMotionMsec/*int*/ , openingMotionMsec/*int*/) { this.closingMotionMsec = closingMotionMsec; this.closedMotionMsec = closedMotionMsec; this.openingMotionMsec = openingMotionMsec; } //============================================================ // L2DEyeBlink # updateParam() //============================================================ L2DEyeBlink.prototype.updateParam = function(model/*ALive2DModel*/) { var time /*:long*/ = UtSystem.getUserTimeMSec(); var eyeParamValue /*:Number*/; var t /*:Number*/ = 0; switch(this.eyeState){ case EYE_STATE.STATE_CLOSING: t = (time - this.stateStartTime) / this.closingMotionMsec; if(t >= 1) { t = 1; this.eyeState = EYE_STATE.STATE_CLOSED; this.stateStartTime = time; } eyeParamValue = 1 - t; break; case EYE_STATE.STATE_CLOSED: t = (time - this.stateStartTime) / this.closedMotionMsec; if(t >= 1) { this.eyeState = EYE_STATE.STATE_OPENING; this.stateStartTime = time; } eyeParamValue = 0; break; case EYE_STATE.STATE_OPENING: t = (time - this.stateStartTime) / this.openingMotionMsec; if(t >= 1) { t = 1; this.eyeState = EYE_STATE.STATE_INTERVAL; this.nextBlinkTime = this.calcNextBlink(); } eyeParamValue = t; break; case EYE_STATE.STATE_INTERVAL: if(this.nextBlinkTime < time) { this.eyeState = EYE_STATE.STATE_CLOSING; this.stateStartTime = time; } eyeParamValue = 1; break; case EYE_STATE.STATE_FIRST: default: this.eyeState = EYE_STATE.STATE_INTERVAL; this.nextBlinkTime = this.calcNextBlink(); eyeParamValue = 1; break; } if(!this.closeIfZero) eyeParamValue = -eyeParamValue; model.setParamFloat(this.eyeID_L , eyeParamValue); model.setParamFloat(this.eyeID_R , eyeParamValue); } //== enum EYE_STATE == var EYE_STATE = function(){}; EYE_STATE.STATE_FIRST = "STATE_FIRST" EYE_STATE.STATE_INTERVAL = "STATE_INTERVAL" EYE_STATE.STATE_CLOSING = "STATE_CLOSING" EYE_STATE.STATE_CLOSED = "STATE_CLOSED" EYE_STATE.STATE_OPENING = "STATE_OPENING" /** * * You can modify and use this source freely * only for the development of application related Live2D. * * (c) Live2D Inc. All rights reserved. */ //============================================================ //============================================================ // class L2DMatrix44 //============================================================ //============================================================ function L2DMatrix44() { this.tr = new Float32Array(16); // this.identity(); } //============================================================ // static L2DMatrix44.mul() //============================================================ L2DMatrix44.mul = function( a/*float[]*/, b/*float[]*/, dst/*float[]*/ ) { var c = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; var n = 4; var i, j, k; for( i = 0; i < n; i++ ) { for( j = 0; j < n; j++ ) { for( k = 0; k < n; k++ ) { c[i + j * 4] += a[i + k * 4] * b[k + j * 4]; } } } for( i = 0; i < 16; i++ ) { dst[i] = c[i]; } } //============================================================ // L2DMatrix44 # identity() //============================================================ L2DMatrix44.prototype.identity = function() { for( var i/*:int*/ = 0; i < 16; i++ ) this.tr[i] = ( ( i % 5 ) == 0 ) ? 1 : 0; } //============================================================ // L2DMatrix44 # getArray() //============================================================ L2DMatrix44.prototype.getArray = function() { return this.tr; } //============================================================ // L2DMatrix44 # getCopyMatrix() //============================================================ L2DMatrix44.prototype.getCopyMatrix = function() { return new Float32Array(this.tr); // this.tr.clone(); } //============================================================ // L2DMatrix44 # setMatrix() //============================================================ L2DMatrix44.prototype.setMatrix = function( tr/*float[]*/ ) { if( this.tr == null || this.tr.length != this.tr.length ) return ; for( var i/*:int*/ = 0; i < 16; i++ ) this.tr[i] = tr[i]; } //============================================================ // L2DMatrix44 # getScaleX() //============================================================ L2DMatrix44.prototype.getScaleX = function() { return this.tr[0]; } //============================================================ // L2DMatrix44 # getScaleY() //============================================================ L2DMatrix44.prototype.getScaleY = function() { return this.tr[5]; } //============================================================ // L2DMatrix44 # transformX() //============================================================ L2DMatrix44.prototype.transformX = function( src/*float*/ ) { return this.tr[0] * src + this.tr[12]; } //============================================================ // L2DMatrix44 # transformY() //============================================================ L2DMatrix44.prototype.transformY = function( src/*float*/ ) { return this.tr[5] * src + this.tr[13]; } //============================================================ // L2DMatrix44 # invertTransformX() //============================================================ L2DMatrix44.prototype.invertTransformX = function( src/*float*/ ) { return ( src - this.tr[12] ) / this.tr[0]; } //============================================================ // L2DMatrix44 # invertTransformY() //============================================================ L2DMatrix44.prototype.invertTransformY = function( src/*float*/ ) { return ( src - this.tr[13] ) / this.tr[5]; } //============================================================ // L2DMatrix44 # multTranslate() //============================================================ L2DMatrix44.prototype.multTranslate = function( shiftX/*float*/, shiftY/*float*/ ) { var tr1 = [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, shiftX, shiftY, 0, 1 ]; L2DMatrix44.mul(tr1, this.tr, this.tr); } //============================================================ // L2DMatrix44 # translate() //============================================================ L2DMatrix44.prototype.translate = function( x/*float*/, y/*float*/ ) { this.tr[12] = x; this.tr[13] = y; } //============================================================ // L2DMatrix44 # translateX() //============================================================ L2DMatrix44.prototype.translateX = function( x/*float*/ ) { this.tr[12] = x; } //============================================================ // L2DMatrix44 # translateY() //============================================================ L2DMatrix44.prototype.translateY = function( y/*float*/ ) { this.tr[13] = y; } //============================================================ // L2DMatrix44 # multScale() //============================================================ L2DMatrix44.prototype.multScale = function( scaleX/*float*/, scaleY/*float*/ ) { var tr1 = [scaleX, 0, 0, 0, 0, scaleY, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; L2DMatrix44.mul(tr1, this.tr, this.tr); } //============================================================ // L2DMatrix44 # scale() //============================================================ L2DMatrix44.prototype.scale = function( scaleX/*float*/, scaleY/*float*/ ) { this.tr[0] = scaleX; this.tr[5] = scaleY; } /** * * You can modify and use this source freely * only for the development of application related Live2D. * * (c) Live2D Inc. All rights reserved. */ //============================================================ //============================================================ // class L2DModelMatrix extends L2DMatrix44 //============================================================ //============================================================ function L2DModelMatrix(w/*float*/, h/*float*/){ L2DMatrix44.prototype.constructor.call(this); this.width = w; this.height = h; } //L2DModelMatrix extends L2DMatrix44 L2DModelMatrix.prototype = new L2DMatrix44(); //============================================================ // L2DModelMatrix # setPosition() //============================================================ L2DModelMatrix.prototype.setPosition = function(x/*float*/, y/*float*/) { this.translate(x, y); } //============================================================ // L2DModelMatrix # setCenterPosition() //============================================================ L2DModelMatrix.prototype.setCenterPosition = function(x/*float*/, y/*float*/) { var w = this.width * this.getScaleX(); var h = this.height * this.getScaleY(); this.translate(x - w / 2, y - h / 2); } //============================================================ // L2DModelMatrix # top() //============================================================ L2DModelMatrix.prototype.top = function(y/*float*/) { this.setY(y); } //============================================================ // L2DModelMatrix # bottom() //============================================================ L2DModelMatrix.prototype.bottom = function(y/*float*/) { var h = this.height * this.getScaleY(); this.translateY(y - h); } //============================================================ // L2DModelMatrix # left() //============================================================ L2DModelMatrix.prototype.left = function(x/*float*/) { this.setX(x); } //============================================================ // L2DModelMatrix # right() //============================================================ L2DModelMatrix.prototype.right = function(x/*float*/) { var w = this.width * this.getScaleX(); this.translateX(x - w); } //============================================================ // L2DModelMatrix # centerX() //============================================================ L2DModelMatrix.prototype.centerX = function(x/*float*/) { var w = this.width * this.getScaleX(); this.translateX(x - w / 2); } //============================================================ // L2DModelMatrix # centerY() //============================================================ L2DModelMatrix.prototype.centerY = function(y/*float*/) { var h = this.height * this.getScaleY(); this.translateY(y - h / 2); } //============================================================ // L2DModelMatrix # setX() //============================================================ L2DModelMatrix.prototype.setX = function(x/*float*/) { this.translateX(x); } //============================================================ // L2DModelMatrix # setY() //============================================================ L2DModelMatrix.prototype.setY = function(y/*float*/) { this.translateY(y); } //============================================================ // L2DModelMatrix # setHeight() //============================================================ L2DModelMatrix.prototype.setHeight = function(h/*float*/) { var scaleX = h / this.height; var scaleY = -scaleX; this.scale(scaleX, scaleY); } //============================================================ // L2DModelMatrix # setWidth() //============================================================ L2DModelMatrix.prototype.setWidth = function(w/*float*/) { var scaleX = w / this.width; var scaleY = -scaleX; this.scale(scaleX, scaleY); } /** * * You can modify and use this source freely * only for the development of application related Live2D. * * (c) Live2D Inc. All rights reserved. */ //============================================================ //============================================================ // class L2DMotionManager extends MotionQueueManager //============================================================ //============================================================ function L2DMotionManager() { MotionQueueManager.prototype.constructor.call(this); this.currentPriority = null; this.reservePriority = null; this.super = MotionQueueManager.prototype; } // MotionQueueManagerクラスを継承 L2DMotionManager.prototype = new MotionQueueManager(); //============================================================ // L2DMotionManager # getCurrentPriority() //============================================================ L2DMotionManager.prototype.getCurrentPriority = function() { return this.currentPriority; } //============================================================ // L2DMotionManager # getReservePriority() //============================================================ L2DMotionManager.prototype.getReservePriority = function() { return this.reservePriority; } //============================================================ // L2DMotionManager # reserveMotion() //============================================================ L2DMotionManager.prototype.reserveMotion = function(priority/*int*/) { if(this.reservePriority >= priority) { return false; } if(this.currentPriority >= priority) { return false; } this.reservePriority = priority; return true; } //============================================================ // L2DMotionManager # setReservePriority() //============================================================ L2DMotionManager.prototype.setReservePriority = function(val/*int*/) { this.reservePriority = val; } //============================================================ // L2DMotionManager # updateParam() //============================================================ L2DMotionManager.prototype.updateParam = function(model/*ALive2DModel*/) { var updated = MotionQueueManager.prototype.updateParam.call(this, model); if(this.isFinished()) { this.currentPriority = 0; } return updated; } //============================================================ // L2DMotionManager # startMotionPrio() //============================================================ L2DMotionManager.prototype.startMotionPrio = function(motion/*AMotion*/, priority/*int*/) { if(priority == this.reservePriority) { this.reservePriority = 0; } this.currentPriority = priority; return this.startMotion(motion, false); } /** * * You can modify and use this source freely * only for the development of application related Live2D. * * (c) Live2D Inc. All rights reserved. */ //============================================================ //============================================================ // class L2DPhysics //============================================================ //============================================================ function L2DPhysics() { this.physicsList = new Array(); //ArrayList this.startTimeMSec = UtSystem.getUserTimeMSec(); } //============================================================ // static L2DPhysics.load() //============================================================ L2DPhysics.load = function(buf /*byte[]*/ ) { var ret = new L2DPhysics(); //L2DPhysicsL2DPhysics var pm = Live2DFramework.getPlatformManager(); var json = pm.jsonParseFromBytes(buf); var params = json.physics_hair; var paramNum = params.length; for(var i = 0; i < paramNum; i++) { var param = params[i]; //Value var physics = new PhysicsHair(); //PhysicsHairPhysicsHair var setup = param.setup; //Value var length = parseFloat(setup.length); var resist = parseFloat(setup.regist); var mass = parseFloat(setup.mass); physics.setup(length, resist, mass); var srcList = param.src; //Value var srcNum = srcList.length; for(var j = 0; j < srcNum; j++) { var src = srcList[j]; //Value var id = src.id; //String var type = PhysicsHair.Src.SRC_TO_X; var typeStr = src.ptype; //String if(typeStr === "x") { type = PhysicsHair.Src.SRC_TO_X; } else if(typeStr === "y") { type = PhysicsHair.Src.SRC_TO_Y; } else if(typeStr === "angle") { type = PhysicsHair.Src.SRC_TO_G_ANGLE; } else { UtDebug.error("live2d", "Invalid parameter:PhysicsHair.Src"); } var scale = parseFloat(src.scale); var weight = parseFloat(src.weight); physics.addSrcParam(type, id, scale, weight); } var targetList = param.targets; //Value var targetNum = targetList.length; for(var j = 0; j < targetNum; j++) { var target = targetList[j]; //Value var id = target.id; //String var type = PhysicsHair.Target.TARGET_FROM_ANGLE; var typeStr = target.ptype; //String if(typeStr === "angle") { type = PhysicsHair.Target.TARGET_FROM_ANGLE; } else if(typeStr === "angle_v") { type = PhysicsHair.Target.TARGET_FROM_ANGLE_V; } else { UtDebug.error("live2d", "Invalid parameter:PhysicsHair.Target"); } var scale = parseFloat(target.scale); var weight = parseFloat(target.weight); physics.addTargetParam(type, id, scale, weight); } ret.physicsList.push(physics); } return ret; } //============================================================ // L2DPhysics # updateParam() //============================================================ L2DPhysics.prototype.updateParam = function(model/*ALive2DModel*/) { var timeMSec = UtSystem.getUserTimeMSec() - this.startTimeMSec; for(var i = 0; i < this.physicsList.length; i++) { this.physicsList[i].update(model, timeMSec); } } /** * * You can modify and use this source freely * only for the development of application related Live2D. * * (c) Live2D Inc. All rights reserved. */ //============================================================ //============================================================ // class L2DPose //============================================================ //============================================================ function L2DPose() { this.lastTime = 0; this.lastModel = null; //ALive2DModel this.partsGroups = new Array(); //ArrayList } //============================================================ // static L2DPose.load() //============================================================ L2DPose.load = function(buf/*byte[]*/) { var ret = new L2DPose(); //L2DPose var pm = Live2DFramework.getPlatformManager(); var json = pm.jsonParseFromBytes(buf); var poseListInfo = json.parts_visible; //Value var poseNum = poseListInfo.length; for(var i_pose = 0; i_pose < poseNum; i_pose++) { var poseInfo = poseListInfo[i_pose]; //Value var idListInfo = poseInfo.group; //Value var idNum = idListInfo.length; var partsGroup/*L2DPartsParam*/ = new Array(); for(var i_group = 0; i_group < idNum; i_group++) { var partsInfo = idListInfo[i_group]; //Value var parts = new L2DPartsParam(partsInfo.id); //L2DPartsParamL2DPartsParam partsGroup[i_group] = parts; if(partsInfo.link == null) continue; var linkListInfo = partsInfo.link; //Value var linkNum = linkListInfo.length; parts.link = new Array(); //ArrayList for(var i_link = 0; i_link < linkNum; i_link++) { var linkParts = new L2DPartsParam(linkListInfo[i_link]); //L2DPartsParamL2DPartsParam parts.link.push(linkParts); } } ret.partsGroups.push(partsGroup); } return ret; } //============================================================ // L2DPose # updateParam() //============================================================ L2DPose.prototype.updateParam = function(model/*ALive2DModel*/) { if(model == null) return ; if(!(model == this.lastModel)) { this.initParam(model); } this.lastModel = model; var curTime = UtSystem.getUserTimeMSec(); var deltaTimeSec = ((this.lastTime == 0) ? 0 : (curTime - this.lastTime) / 1000.0); this.lastTime = curTime; if(deltaTimeSec < 0) deltaTimeSec = 0; for(var i = 0; i < this.partsGroups.length; i++) { this.normalizePartsOpacityGroup(model, this.partsGroups[i], deltaTimeSec); this.copyOpacityOtherParts(model, this.partsGroups[i]); } } //============================================================ // L2DPose # initParam() //============================================================ L2DPose.prototype.initParam = function(model/*ALive2DModel*/) { if(model == null) return ; for(var i = 0; i < this.partsGroups.length; i++) { var partsGroup = this.partsGroups[i]; //L2DPartsParam for(var j = 0; j < partsGroup.length; j++) { partsGroup[j].initIndex(model); var partsIndex = partsGroup[j].partsIndex; var paramIndex = partsGroup[j].paramIndex; if(partsIndex < 0) continue; var v/*:Boolean*/ = (model.getParamFloat(paramIndex) != 0); model.setPartsOpacity(partsIndex, (v ? 1.0 : 0.0)); model.setParamFloat(paramIndex, (v ? 1.0 : 0.0)); if(partsGroup[j].link == null) continue; for(var k = 0; k < partsGroup[j].link.length; k++) { partsGroup[j].link[k].initIndex(model); } } } } //============================================================ // L2DPose # normalizePartsOpacityGroup() //============================================================ L2DPose.prototype.normalizePartsOpacityGroup = function(model/*ALive2DModel*/, partsGroup/*L2DPartsParam[]*/, deltaTimeSec/*float*/) { var visibleParts = -1; var visibleOpacity = 1.0; var CLEAR_TIME_SEC = 0.5; var phi = 0.5; var maxBackOpacity = 0.15; for(var i = 0; i < partsGroup.length; i++) { var partsIndex = partsGroup[i].partsIndex; var paramIndex = partsGroup[i].paramIndex; if(partsIndex < 0) continue;if(model.getParamFloat(paramIndex) != 0) { if(visibleParts >= 0) { break; } visibleParts = i; visibleOpacity = model.getPartsOpacity(partsIndex); visibleOpacity += deltaTimeSec / CLEAR_TIME_SEC; if(visibleOpacity > 1) { visibleOpacity = 1; } } } if(visibleParts < 0) { visibleParts = 0; visibleOpacity = 1; } for(var i = 0; i < partsGroup.length; i++) { var partsIndex = partsGroup[i].partsIndex; if(partsIndex < 0) continue;if(visibleParts == i) { model.setPartsOpacity(partsIndex, visibleOpacity); } else { var opacity = model.getPartsOpacity(partsIndex); var a1; if(visibleOpacity < phi) { a1 = visibleOpacity * (phi - 1) / phi + 1; } else { a1 = (1 - visibleOpacity) * phi / (1 - phi); } var backOp = (1 - a1) * (1 - visibleOpacity); if(backOp > maxBackOpacity) { a1 = 1 - maxBackOpacity / (1 - visibleOpacity); } if(opacity > a1) { opacity = a1; } model.setPartsOpacity(partsIndex, opacity); } } } //============================================================ // L2DPose # copyOpacityOtherParts() //============================================================ L2DPose.prototype.copyOpacityOtherParts = function(model/*ALive2DModel*/, partsGroup/*L2DPartsParam[]*/) { for(var i_group = 0; i_group < partsGroup.length; i_group++) { var partsParam = partsGroup[i_group]; //L2DPartsParam if(partsParam.link == null) continue; if(partsParam.partsIndex < 0) continue; var opacity = model.getPartsOpacity(partsParam.partsIndex); for(var i_link = 0; i_link < partsParam.link.length; i_link++) { var linkParts = partsParam.link[i_link]; //L2DPartsParam if(linkParts.partsIndex < 0) continue; model.setPartsOpacity(linkParts.partsIndex, opacity); } } } //============================================================ //============================================================ // class L2DPartsParam //============================================================ //============================================================ function L2DPartsParam(id/*String*/){ this.paramIndex = -1; this.partsIndex = -1; this.link = null; // ArrayList this.id = id; } //============================================================ // L2DPartsParam # initIndex() //============================================================ L2DPartsParam.prototype.initIndex = function(model/*ALive2DModel*/) { this.paramIndex = model.getParamIndex("VISIBLE:" + this.id); this.partsIndex = model.getPartsDataIndex(PartsDataID.getID(this.id)); model.setParamFloat(this.paramIndex, 1); } /** * * You can modify and use this source freely * only for the development of application related Live2D. * * (c) Live2D Inc. All rights reserved. */ //============================================================ //============================================================ // class L2DTargetPoint //============================================================ //============================================================ function L2DTargetPoint() { this.EPSILON = 0.01; // 変化の最小値(この値以下は無視される) this.faceTargetX = 0; this.faceTargetY = 0; this.faceX = 0; this.faceY = 0; this.faceVX = 0; this.faceVY = 0; this.lastTimeSec = 0; } //============================================================ L2DTargetPoint.FRAME_RATE = 30; //============================================================ // L2DTargetPoint # set() //============================================================ L2DTargetPoint.prototype.setPoint = function(x/*float*/, y/*float*/) { this.faceTargetX = x; this.faceTargetY = y; } //============================================================ // L2DTargetPoint # getX() //============================================================ L2DTargetPoint.prototype.getX = function() { return this.faceX; } //============================================================ // L2DTargetPoint # getY() //============================================================ L2DTargetPoint.prototype.getY = function() { return this.faceY; } //============================================================ // L2DTargetPoint # update() //============================================================ L2DTargetPoint.prototype.update = function() { var TIME_TO_MAX_SPEED = 0.15; var FACE_PARAM_MAX_V = 40.0 / 7.5; var MAX_V = FACE_PARAM_MAX_V / L2DTargetPoint.FRAME_RATE; if(this.lastTimeSec == 0) { this.lastTimeSec = UtSystem.getUserTimeMSec(); return; } var curTimeSec = UtSystem.getUserTimeMSec(); var deltaTimeWeight = (curTimeSec - this.lastTimeSec) * L2DTargetPoint.FRAME_RATE / 1000.0; this.lastTimeSec = curTimeSec; var FRAME_TO_MAX_SPEED = TIME_TO_MAX_SPEED * L2DTargetPoint.FRAME_RATE; var MAX_A = deltaTimeWeight * MAX_V / FRAME_TO_MAX_SPEED; var dx = (this.faceTargetX - this.faceX); var dy = (this.faceTargetY - this.faceY); // if(dx == 0 && dy == 0) return; if( Math.abs(dx) <= this.EPSILON && Math.abs(dy) <= this.EPSILON ) return; var d = Math.sqrt(dx * dx + dy * dy); var vx = MAX_V * dx / d; var vy = MAX_V * dy / d; var ax = vx - this.faceVX; var ay = vy - this.faceVY; var a = Math.sqrt(ax * ax + ay * ay); if(a < -MAX_A || a > MAX_A) { ax *= MAX_A / a; ay *= MAX_A / a; a = MAX_A; } this.faceVX += ax; this.faceVY += ay; { var max_v = 0.5 * ( Math.sqrt(MAX_A * MAX_A + 16 * MAX_A * d - 8 * MAX_A * d) - MAX_A); var cur_v = Math.sqrt(this.faceVX * this.faceVX + this.faceVY * this.faceVY); if(cur_v > max_v) { this.faceVX *= max_v / cur_v; this.faceVY *= max_v / cur_v; } } this.faceX += this.faceVX; this.faceY += this.faceVY; } /** * * You can modify and use this source freely * only for the development of application related Live2D. * * (c) Live2D Inc. All rights reserved. */ //============================================================ //============================================================ // class L2DViewMatrix extends L2DMatrix44 //============================================================ //============================================================ function L2DViewMatrix() { L2DMatrix44.prototype.constructor.call(this); this.screenLeft = null; this.screenRight = null; this.screenTop = null; this.screenBottom = null; this.maxLeft = null; this.maxRight = null; this.maxTop = null; this.maxBottom = null; this.max = Number.MAX_VALUE; this.min = 0; } L2DViewMatrix.prototype = new L2DMatrix44(); //L2DViewMatrix extends L2DMatrix44 //============================================================ // L2DViewMatrix # getMaxScale() //============================================================ L2DViewMatrix.prototype.getMaxScale = function() { return this.max; } //============================================================ // L2DViewMatrix # getMinScale() //============================================================ L2DViewMatrix.prototype.getMinScale = function() { return this.min; } //============================================================ // L2DViewMatrix # setMaxScale() //============================================================ L2DViewMatrix.prototype.setMaxScale = function(v/*float*/) { this.max = v; } //============================================================ // L2DViewMatrix # setMinScale() //============================================================ L2DViewMatrix.prototype.setMinScale = function(v/*float*/) { this.min = v; } //============================================================ // L2DViewMatrix # isMaxScale() //============================================================ L2DViewMatrix.prototype.isMaxScale = function() { return this.getScaleX() == this.max; } //============================================================ // L2DViewMatrix # isMinScale() //============================================================ L2DViewMatrix.prototype.isMinScale = function() { return this.getScaleX() == this.min; } //============================================================ // L2DViewMatrix # adjustTranslate() //============================================================ L2DViewMatrix.prototype.adjustTranslate = function(shiftX/*float*/, shiftY/*float*/) { if(this.tr[0] * this.maxLeft + (this.tr[12] + shiftX) > this.screenLeft) shiftX = this.screenLeft - this.tr[0] * this.maxLeft - this.tr[12]; if(this.tr[0] * this.maxRight + (this.tr[12] + shiftX) < this.screenRight) shiftX = this.screenRight - this.tr[0] * this.maxRight - this.tr[12]; if(this.tr[5] * this.maxTop + (this.tr[13] + shiftY) < this.screenTop) shiftY = this.screenTop - this.tr[5] * this.maxTop - this.tr[13]; if(this.tr[5] * this.maxBottom + (this.tr[13] + shiftY) > this.screenBottom) shiftY = this.screenBottom - this.tr[5] * this.maxBottom - this.tr[13]; var tr1 = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, shiftX, shiftY, 0, 1 ]; L2DMatrix44.mul(tr1, this.tr, this.tr); } //============================================================ // L2DViewMatrix # adjustScale() //============================================================ L2DViewMatrix.prototype.adjustScale = function(cx/*float*/, cy/*float*/, scale/*float*/) { var targetScale = scale * this.tr[0]; if(targetScale < this.min) { if(this.tr[0] > 0) scale = this.min / this.tr[0]; } else if(targetScale > this.max) { if(this.tr[0] > 0) scale = this.max / this.tr[0]; } var tr1 = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, cx, cy, 0, 1]; var tr2 = [scale, 0, 0, 0, 0, scale, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ]; var tr3 = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -cx, -cy, 0, 1 ]; L2DMatrix44.mul(tr3, this.tr, this.tr); L2DMatrix44.mul(tr2, this.tr, this.tr); L2DMatrix44.mul(tr1, this.tr, this.tr); } //============================================================ // L2DViewMatrix # setScreenRect() //============================================================ L2DViewMatrix.prototype.setScreenRect = function(left/*float*/, right/*float*/, bottom/*float*/, top/*float*/) { this.screenLeft = left; this.screenRight = right; this.screenTop = top; this.screenBottom = bottom; } //============================================================ // L2DViewMatrix # setMaxScreenRect() //============================================================ L2DViewMatrix.prototype.setMaxScreenRect = function(left/*float*/, right/*float*/, bottom/*float*/, top/*float*/) { this.maxLeft = left; this.maxRight = right; this.maxTop = top; this.maxBottom = bottom; } //============================================================ // L2DViewMatrix # getScreenLeft() //============================================================ L2DViewMatrix.prototype.getScreenLeft = function() { return this.screenLeft; } //============================================================ // L2DViewMatrix # getScreenRight() //============================================================ L2DViewMatrix.prototype.getScreenRight = function() { return this.screenRight; } //============================================================ // L2DViewMatrix # getScreenBottom() //============================================================ L2DViewMatrix.prototype.getScreenBottom = function() { return this.screenBottom; } //============================================================ // L2DViewMatrix # getScreenTop() //============================================================ L2DViewMatrix.prototype.getScreenTop = function() { return this.screenTop; } //============================================================ // L2DViewMatrix # getMaxLeft() //============================================================ L2DViewMatrix.prototype.getMaxLeft = function() { return this.maxLeft; } //============================================================ // L2DViewMatrix # getMaxRight() //============================================================ L2DViewMatrix.prototype.getMaxRight = function() { return this.maxRight; } //============================================================ // L2DViewMatrix # getMaxBottom() //============================================================ L2DViewMatrix.prototype.getMaxBottom = function() { return this.maxBottom; } //============================================================ // L2DViewMatrix # getMaxTop() //============================================================ L2DViewMatrix.prototype.getMaxTop = function() { return this.maxTop; } /** * * You can modify and use this source freely * only for the development of application related Live2D. * * (c) Live2D Inc. All rights reserved. */ //============================================================ //============================================================ // class Live2DFramework //============================================================ //============================================================ function Live2DFramework() { } //============================================================ Live2DFramework.platformManager = null; //============================================================ // static Live2DFramework.getPlatformManager() //============================================================ Live2DFramework.getPlatformManager = function() { return Live2DFramework.platformManager; } //============================================================ // static Live2DFramework.setPlatformManager() //============================================================ Live2DFramework.setPlatformManager = function( platformManager /*IPlatformManager*/ ) { Live2DFramework.platformManager = platformManager; }