Merge pull request #1 from Live2D/feature/TypeScript_AddSamples

Add TypeScript Samples for Web
translate
Takuya Ito 2018-09-20 17:08:22 +09:00 committed by GitHub
commit 019ad2b525
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
136 changed files with 94575 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
node_modules/
/Core/*
!Please copy cubism core for web

26
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,26 @@
{
"version": "0.2.0",
"configurations": [
// Web
{
//
"name": "Launch remote website with sourcemaps",
// (chrome)
"type": "chrome",
// launchattach
"request": "launch",
// WebURL
"url": "http://localhost:5500/Sample/TypeScript/Demo/index.html",
//
"webRoot": "${workspaceFolder}/",
// true/false
"sourceMaps": true,
}
]
}

32
.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,32 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "build-all",
"problemMatcher": []
},
{
"type": "npm",
"script": "watch-all",
"problemMatcher": []
},
{
"type": "npm",
"script": "build-sample",
"problemMatcher": []
},
{
"type": "npm",
"script": "watch-sample",
"problemMatcher": []
},
{
"type": "npm",
"script": "build-framework",
"problemMatcher": []
}
]
}

View File

@ -0,0 +1 @@
Please copy cubism native core

View File

@ -0,0 +1,66 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
/**
* @brief ID<br>
* <br>
* http://docs.live2d.com/cubism-editor-manual/standard-parametor-list/
*/
export namespace Live2DCubismFramework
{
// パーツID
export const HitAreaPrefix: string = "HitArea";
export const HitAreaHead: string = "Head";
export const HitAreaBody: string = "Body";
export const PartsIdCore: string = "Parts01Core";
export const PartsArmPrefix: string = "Parts01Arm_";
export const PartsArmLPrefix: string = "Parts01ArmL_";
export const PartsArmRPrefix: string = "Parts01ArmR_";
// パラメータID
export const ParamAngleX: string = "ParamAngleX";
export const ParamAngleY: string = "ParamAngleY";
export const ParamAngleZ: string = "ParamAngleZ";
export const ParamEyeLOpen: string = "ParamEyeLOpen";
export const ParamEyeLSmile: string = "ParamEyeLSmile";
export const ParamEyeROpen: string = "ParamEyeROpen";
export const ParamEyeRSmile: string = "ParamEyeRSmile";
export const ParamEyeBallX: string = "ParamEyeBallX";
export const ParamEyeBallY: string = "ParamEyeBallY";
export const ParamEyeBallForm: string = "ParamEyeBallForm";
export const ParamBrowLY: string = "ParamBrowLY";
export const ParamBrowRY: string = "ParamBrowRY";
export const ParamBrowLX: string = "ParamBrowLX";
export const ParamBrowRX: string = "ParamBrowRX";
export const ParamBrowLAngle: string = "ParamBrowLAngle";
export const ParamBrowRAngle: string = "ParamBrowRAngle";
export const ParamBrowLForm: string = "ParamBrowLForm";
export const ParamBrowRForm: string = "ParamBrowRForm";
export const ParamMouthForm: string = "ParamMouthForm";
export const ParamMouthOpenY: string = "ParamMouthOpenY";
export const ParamCheek: string = "ParamCheek";
export const ParamBodyAngleX: string = "ParamBodyAngleX";
export const ParamBodyAngleY: string = "ParamBodyAngleY";
export const ParamBodyAngleZ: string = "ParamBodyAngleZ";
export const ParamBreath: string = "ParamBreath";
export const ParamArmLA: string = "ParamArmLA";
export const ParamArmRA: string = "ParamArmRA";
export const ParamArmLB: string = "ParamArmLB";
export const ParamArmRB: string = "ParamArmRB";
export const ParamHandL: string = "ParamHandL";
export const ParamHandR: string = "ParamHandR";
export const ParamHairFront: string = "ParamHairFront";
export const ParamHairSide: string = "ParamHairSide";
export const ParamHairBack: string = "ParamHairBack";
export const ParamHairFluffy: string = "ParamHairFluffy";
export const ParamShoulderY: string = "ParamShoulderY";
export const ParamBustX: string = "ParamBustX";
export const ParamBustY: string = "ParamBustY";
export const ParamBaseX: string = "ParamBaseX";
export const ParamBaseY: string = "ParamBaseY";
export const ParamNONE: string = "NONE:";
}

View File

@ -0,0 +1,32 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
//========================================================
// ログ出力関数の設定
//========================================================
//---------- ログ出力レベル 選択項目 定義 ----------
/// 詳細ログ出力設定
export const CSM_LOG_LEVEL_VERBOSE: number = 0;
/// デバッグログ出力設定
export const CSM_LOG_LEVEL_DEBUG: number = 1;
/// Infoログ出力設定
export const CSM_LOG_LEVEL_INFO: number = 2;
/// 警告ログ出力設定
export const CSM_LOG_LEVEL_WARNING: number = 3;
/// エラーログ出力設定
export const CSM_LOG_LEVEL_ERROR: number = 4;
/// ログ出力オフ設定
export const CSM_LOG_LEVEL_OFF: number = 5;
/**
*
*
*
* CSM_LOG_LEVEL_VERBOSE CSM_LOG_LEVEL_OFF
*/
export const CSM_LOG_LEVEL: number = CSM_LOG_LEVEL_VERBOSE;

View File

@ -0,0 +1,681 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
import {Live2DCubismFramework as cubismframework} from "./live2dcubismframework";
import {Live2DCubismFramework as icubismmodelsetting} from "./icubismmodelsetting";
import {Live2DCubismFramework as cubismid} from "./id/cubismid";
import {Live2DCubismFramework as cubismjson} from "./utils/cubismjson";
import {Live2DCubismFramework as csmmap} from"./type/csmmap";
import csmMap = csmmap.csmMap;
import CubismFramework = cubismframework.CubismFramework;
import CubismIdHandle = cubismid.CubismIdHandle;
import CubismJson = cubismjson.CubismJson;
import Value = cubismjson.Value;
import ICubismModelSetting = icubismmodelsetting.ICubismModelSetting;
export namespace Live2DCubismFramework
{
/**
* Model3Json
*/
// JSON Keys
const Version: string = "Version";
const FileReferences: string = "FileReferences";
const Groups: string = "Groups";
const Layout: string = "Layout";
const HitAreas: string = "HitAreas";
const Moc: string = "Moc";
const Textures: string = "Textures";
const Physics: string = "Physics";
const Pose: string = "Pose";
const Expressions: string = "Expressions";
const Motions: string = "Motions";
const UserData: string = "UserData";
const Name: string = "Name";
const FilePath: string = "File";
const Id: string = "Id";
const Ids: string = "Ids";
const Target: string = "Target";
// Motions
const Idle: string = "Idle";
const TapBody: string = "TapBody";
const PinchIn: string = "PinchIn";
const PinchOut: string = "PinchOut";
const Shake: string = "Shake";
const FlickHead: string = "FlickHead";
const Parameter: string = "Parameter";
const SoundPath: string = "Sound";
const FadeInTime: string = "FadeInTime";
const FadeOutTime: string = "FadeOutTime";
// Layout
const CenterX: string = "CenterX";
const CenterY: string = "CenterY";
const X: string = "X";
const Y: string = "Y";
const Width: string = "Width";
const Height: string = "Height";
const LipSync: string = "LipSync";
const EyeBlink: string = "EyeBlink";
const InitParameter: string = "init_param";
const InitPartsVisible: string = "init_parts_visible";
const Val: string = "val";
/**
* Model3Json
*
* model3.json
*/
export class CubismModelSettingJson extends ICubismModelSetting
{
/**
*
*
* @param buffer Model3Json
* @param size Model3Json
*/
public constructor(buffer: ArrayBuffer, size: number)
{
super();
this._json = CubismJson.create(buffer, size);
}
/**
*
*/
public release(): void
{
CubismJson.delete(this._json);
}
/**
* CubismJson
*
* @return CubismJson
*/
public GetJson(): CubismJson
{
return this._json;
}
/**
* Moc
* @return Moc
*/
public getModelFileName(): string
{
if(!this.isExistModelFile())
{
return "";
}
return this._json.getRoot().getMap().getValue(FileReferences).getMap().getValue(Moc).getRawString();
}
/**
* 使
*
*/
public getTextureCount(): number
{
if(!this.isExistTextureFiles())
{
return 0;
}
return this._json.getRoot().getMap().getValue(FileReferences).getMap().getValue(Textures).getSize();
}
/**
*
* @return
*/
public getTextureDirectory(): string
{
return this._json.getRoot().getMap().getValue(FileReferences).getMap().getValue(Textures).getRawString();
}
/**
* 使
* @param index
* @return
*/
public getTextureFileName(index: number): string
{
return this._json.getRoot().getMap().getValue(FileReferences).getMap().getValue(Textures).getVector().at(index).getRawString();
}
/**
*
* @return
*/
public getHitAreasCount(): number
{
if(!this.isExistHitAreas())
{
return 0;
}
return this._json.getRoot().getMap().getValue(HitAreas).getSize();
}
/**
* ID
*
* @param index index
* @return ID
*/
public getHitAreaId(index: number): CubismIdHandle
{
return CubismFramework.getIdManager().getId(this._json.getRoot().getMap().getValue(HitAreas).getVector().at(index).getMap().getValue(Id).getRawString());
}
/**
*
* @param index
* @return
*/
public getHitAreaName(index: number): string
{
return this._json.getRoot().getMap().getValue(HitAreas).getVector().at(index).getMap().getValue(Name).getRawString();
}
/**
*
* @return
*/
public getPhysicsFileName(): string
{
if(!this.isExistPhysicsFile())
{
return "";
}
return this._json.getRoot().getMap().getValue(FileReferences).getMap().getValue(Physics).getRawString();
}
/**
*
* @return
*/
public getPoseFileName(): string
{
if(!this.isExistPoseFile())
{
return "";
}
return this._json.getRoot().getMap().getValue(FileReferences).getMap().getValue(Pose).getRawString();
}
/**
*
* @return
*/
public getExpressionCount(): number
{
if(!this.isExistExpressionFile())
{
return 0;
}
return this._json.getRoot().getMap().getValue(FileReferences).getMap().getValue(Expressions).getSize();
}
/**
*
* @param index
* @return
*/
public getExpressionName(index: number): string
{
return this._json.getRoot().getMap().getValue(FileReferences).getMap().getValue(Expressions).getVector().at(index).getMap().getValue(Name).getRawString();
}
/**
*
* @param index
* @return
*/
public getExpressionFileName(index: number): string
{
return this._json.getRoot().getMap().getValue(FileReferences).getMap().getValue(Expressions).getVector().at(index).getMap().getValue(FilePath).getRawString();
}
/**
*
* @return
*/
public getMotionGroupCount(): number
{
if(!this.isExistMotionGroups())
{
return 0;
}
return this._json.getRoot().getMap().getValue(FileReferences).getMap().getValue(Motions).getMap().getSize();
}
/**
*
* @param index
* @return
*/
public getMotionGroupName(index: number): string
{
if(!this.isExistMotionGroups())
{
return null;
}
return this._json.getRoot().getMap().getValue(FileReferences).getMap().getValue(Motions).getKeys().at(index);
}
/**
*
* @param groupName
* @return
*/
public getMotionCount(groupName: string): number
{
if(!this.isExistMotionGroupName(groupName))
{
return 0;
}
return this._json.getRoot().getMap().getValue(FileReferences).getMap().getValue(Motions).getMap().getValue(groupName).getSize();
}
/**
*
* @param groupName
* @param index
* @return
*/
public getMotionFileName(groupName: string, index: number): string
{
if(!this.isExistMotionGroupName(groupName))
{
return "";
}
return this._json.getRoot().getMap().getValue(FileReferences).getMap().getValue(Motions).getMap().getValue(groupName).getVector().at(index).getMap().getValue(FilePath).getRawString();
}
/**
*
* @param groupName
* @param index
* @return
*/
public getMotionSoundFileName(groupName: string, index: number): string
{
if(!this.isExistMotionSoundFile(groupName, index))
{
return "";
}
return this._json.getRoot().getMap().getValue(FileReferences).getMap().getValue(Motions).getMap().getValue(groupName).getVector().at(index).getMap().getValue(SoundPath).getRawString();
}
/**
*
* @param groupName
* @param index
* @return []
*/
public getMotionFadeInTimeValue(groupName: string, index: number): number
{
if(!this.isExistMotionFadeIn(groupName, index))
{
return -1.0;
}
return this._json.getRoot().getMap().getValue(FileReferences).getMap().getValue(Motions).getMap().getValue(groupName).getVector().at(index).getMap().getValue(FadeInTime).toFloat();
}
/**
*
* @param groupName
* @param index
* @return []
*/
public getMotionFadeOutTimeValue(groupName: string, index: number): number
{
if(!this.isExistMotionFadeOut(groupName, index))
{
return -1.0;
}
return this._json.getRoot().getMap().getValue(FileReferences).getMap().getValue(Motions).getMap().getValue(groupName).getVector().at(index).getMap().getValue(FadeOutTime).toFloat();
}
/**
*
* @return
*/
public getUserDataFile(): string
{
if(!this.isExistUserDataFile())
{
return "";
}
return this._json.getRoot().getMap().getValue(FileReferences).getMap().getValue(UserData).getRawString();
}
/**
*
* @param outLayoutMap csmMap
* @return true
* @return false
*/
public getLayoutMap(outLayoutMap: csmMap<string, number>): boolean
{
// 存在しない要素にアクセスするとエラーになるためValueがnullの場合はnullを代入する
let map: csmMap<string, Value> = (this._json.getRoot().getMap().isExist(Layout))
? this._json.getRoot().getMap().getValue(Layout).getMap()
: null;
if(map == null)
{
return false;
}
let ret: boolean = false;
for(const ite: csmMap.iterator<string, Value> = map.begin(); ite.notEqual(map.end()); ite.preIncrement())
{
outLayoutMap.setValue(ite.ptr().first, ite.ptr().second.toFloat());
ret = true;
}
return ret;
}
/**
*
* @return
*/
public getEyeBlinkParameterCount(): number
{
if (!this.isExistEyeBlinkParameters())
{
return 0;
}
let num: number = 0;
for (let i = 0; i < this._json.getRoot().getMap().getValue(Groups).getSize(); i++)
{
if (this._json.getRoot().getMap().getValue(Groups).getVector().at(i).getMap().getValue(Name).getRawString() == EyeBlink)
{
num = this._json.getRoot().getMap().getValue(Groups).getVector().at(i).getMap().getValue(Ids).getVector().getSize();
break;
}
}
return num;
}
/**
* ID
* @param index
* @return ID
*/
public getEyeBlinkParameterId(index: number): CubismIdHandle
{
if (!this.isExistEyeBlinkParameters())
{
return null;
}
for (let i = 0; i < this._json.getRoot().getMap().getValue(Groups).getSize(); i++)
{
if (this._json.getRoot().getMap().getValue(Groups).getVector().at(i).getMap().getValue(Name).getRawString() == EyeBlink)
{
return CubismFramework.getIdManager().getId(this._json.getRoot().getMap().getValue(Groups).getVector().at(i).getMap().getValue(Ids).getVector().at(index).getRawString());
}
}
return null;
}
/**
*
* @return
*/
public getLipSyncParameterCount(): number
{
if (!this.isExistLipSyncParameters())
{
return 0;
}
let num: number = 0;
for (let i: number = 0; i < this._json.getRoot().getMap().getValue(Groups).getSize(); i++)
{
if (this._json.getRoot().getMap().getValue(Groups).getVector().at(i).getMap().getValue(Name).getRawString() == LipSync)
{
num = this._json.getRoot().getMap().getValue(Groups).getVector().at(i).getMap().getValue(Ids).getVector().getSize();
break;
}
}
return num;
}
/**
*
* @param index
* @return ID
*/
public getLipSyncParameterId(index: number): CubismIdHandle
{
if (!this.isExistLipSyncParameters())
{
return null;
}
for (let i: number = 0; i < this._json.getRoot().getMap().getValue(Groups).getSize(); i++)
{
if (this._json.getRoot().getMap().getValue(Groups).getVector().at(i).getMap().getValue(Name).getRawString() == LipSync)
{
return CubismFramework.getIdManager().getId(this._json.getRoot().getMap().getValue(Groups).getVector().at(i).getMap().getValue(Ids).getVector().at(index).getRawString());
}
}
return null;
}
/**
*
* @return true
* @return false
*/
private isExistModelFile(): boolean
{
return this._json.getRoot().getMap().getValue(FileReferences).getMap().isExist(Moc);
}
/**
*
* @return true
* @return false
*/
private isExistTextureFiles(): boolean
{
return this._json.getRoot().getMap().getValue(FileReferences).getMap().isExist(Textures);
}
/**
*
* @return true
* @return false
*/
private isExistHitAreas(): boolean
{
return this._json.getRoot().getMap().isExist(HitAreas);
}
/**
*
* @return true
* @return false
*/
private isExistPhysicsFile(): boolean
{
return this._json.getRoot().getMap().getValue(FileReferences).getMap().isExist(Physics);
}
/**
*
* @return true
* @return false
*/
private isExistPoseFile(): boolean
{
return this._json.getRoot().getMap().getValue(FileReferences).getMap().isExist(Pose);
}
/**
*
* @return true
* @return false
*/
private isExistExpressionFile(): boolean
{
return this._json.getRoot().getMap().getValue(FileReferences).getMap().isExist(Expressions);
}
/**
*
* @return true
* @return false
*/
private isExistMotionGroups(): boolean
{
return this._json.getRoot().getMap().getValue(FileReferences).getMap().isExist(Motions);
}
/**
*
* @param groupName
* @return true
* @return false
*/
private isExistMotionGroupName(groupName: string): boolean
{
if(!this._json.getRoot().getMap().getValue(FileReferences).getMap().isExist(Motions))
{
return false;
}
return this._json.getRoot().getMap().getValue(FileReferences).getMap().getValue(Motions).getMap().isExist(groupName);
}
/**
*
* @param groupName
* @param index
* @return true
* @return false
*/
private isExistMotionSoundFile(groupName: string, index: number): boolean
{
return this._json.getRoot().getMap().getValue(FileReferences).getMap().getValue(Motions).getMap().getValue(groupName).getVector().at(index).getMap().isExist(SoundPath);
}
/**
*
* @param groupName
* @param index
* @return true
* @return false
*/
private isExistMotionFadeIn(groupName: string, index: number): boolean
{
return this._json.getRoot().getMap().getValue(FileReferences).getMap().getValue(Motions).getMap().getValue(groupName).getVector().at(index).getMap().isExist(FadeInTime);
}
/**
*
* @param groupName
* @param index
* @return true
* @return false
*/
private isExistMotionFadeOut(groupName: string, index: number): boolean
{
return this._json.getRoot().getMap().getValue(FileReferences).getMap().getValue(Motions).getMap().getValue(groupName).getVector().at(index).getMap().isExist(FadeOutTime);
}
/**
* UserData
* @return true
* @return false
*/
private isExistUserDataFile(): boolean
{
if(!this._json.getRoot().getMap().getValue(FileReferences).getMap().isExist(UserData))
{
return false;
}
return !this._json.getRoot().getMap().getValue(FileReferences).getMap().getValue(UserData).isNull();
}
/**
*
* @return true
* @return false
*/
private isExistEyeBlinkParameters(): boolean
{
if(!this._json.getRoot().getMap().isExist(Groups))
{
return false;
}
for (let i: number = 0; i < this._json.getRoot().getMap().getValue(Groups).getSize(); ++i)
{
if (this._json.getRoot().getMap().getValue(Groups).getVector().at(i).getMap().getValue(Name).getRawString() == EyeBlink)
{
return true;
}
}
return false;
}
/**
*
* @return true
* @return false
*/
private isExistLipSyncParameters(): boolean
{
if(!this._json.getRoot().getMap().isExist(Groups))
{
return false;
}
for (let i: number = 0; i < this._json.getRoot().getMap().getValue(Groups).getSize(); ++i)
{
if (this._json.getRoot().getMap().getValue(Groups).getVector().at(i).getMap().getValue(Name).getRawString() == LipSync)
{
return true;
}
}
return false;
}
private _json: CubismJson;
}
}

View File

@ -0,0 +1,140 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
import {Live2DCubismFramework as csmvector} from "../type/csmvector";
import {Live2DCubismFramework as cubismmodel} from "../model/cubismmodel";
import {Live2DCubismFramework as cubismid} from "../id/cubismid";
import CubismIdHandle = cubismid.CubismIdHandle;
import CubismModel = cubismmodel.CubismModel;
import csmVector = csmvector.csmVector;
export namespace Live2DCubismFramework
{
/**
*
*
*
*/
export class CubismBreath
{
/**
*
*/
public static create(): CubismBreath
{
return new CubismBreath();
}
/**
*
* @param instance CubismBreath
*/
public static delete(instance: CubismBreath): void
{
instance = void 0;
instance = null;
}
/**
*
* @param breathParameters
*/
public setParameters(breathParameters: csmVector<CubismBreath.BreathParameterData>): void
{
this._breathParameters = breathParameters;
}
/**
*
* @return
*/
public getParameters(): csmVector<CubismBreath.BreathParameterData>
{
return this._breathParameters;
}
/**
*
* @param model
* @param deltaTimeSeconds []
*/
public updateParameters(model: CubismModel, deltaTimeSeconds: number): void
{
this._currentTime += deltaTimeSeconds;
const t: number = this._currentTime * 2.0 * 3.14159;
for(let i: number = 0; i < this._breathParameters.getSize(); ++i)
{
let data: CubismBreath.BreathParameterData = this._breathParameters.at(i);
model.addParameterValueById(
data.parameterId,
data.offset + (data.peak * Math.sin(t / data.cycle)),
data.weight
);
}
}
/**
*
*/
public constructor()
{
this._currentTime = 0.0;
}
_breathParameters: csmVector<CubismBreath.BreathParameterData>; // 呼吸にひもづいているパラメータのリスト
_currentTime: number; // 積算時間[秒]
}
export namespace CubismBreath
{
/**
*
*/
export class BreathParameterData
{
/**
*
* @param parameterId ID
* @param offset
* @param peak
* @param cycle
* @param weight
*/
constructor(parameterId?: CubismIdHandle, offset?: number, peak?: number, cycle?: number, weight?: number)
{
this.parameterId = (parameterId == undefined)
? null
: parameterId;
this.offset = (offset == undefined)
? 0.0
: offset;
this.peak = (peak == undefined)
? 0.0
: peak;
this.cycle = (cycle == undefined)
? 0.0
: cycle;
this.weight = (weight == undefined)
? 0.0
: weight;
}
parameterId: CubismIdHandle; // 呼吸をひもづけるパラメータID\
offset: number; // 呼吸を正弦波としたときの、波のオフセット
peak: number; // 呼吸を正弦波としたときの、波の高さ
cycle: number; // 呼吸を正弦波としたときの、波の周期
weight: number; // パラメータへの重み
}
}
}

View File

@ -0,0 +1,238 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
import {Live2DCubismFramework as csmvector} from "../type/csmvector";
import {Live2DCubismFramework as icubismmodelsetting} from "../icubismmodelsetting";
import {Live2DCubismFramework as cubismid} from "../id/cubismid";
import {Live2DCubismFramework as cubismmodel} from "../model/cubismmodel";
import CubismModel = cubismmodel.CubismModel;
import CubismIdHandle = cubismid.CubismIdHandle;
import ICubismModelSetting = icubismmodelsetting.ICubismModelSetting;
import csmVector = csmvector.csmVector;
export namespace Live2DCubismFramework
{
/**
*
*
*
*/
export class CubismEyeBlink
{
/**
*
* @param modelSetting
* @return
* @note NULLID
*/
public static create(modelSetting: ICubismModelSetting = null): CubismEyeBlink
{
return new CubismEyeBlink(modelSetting);
}
/**
*
* @param eyeBlink CubismEyeBlink
*/
public static delete(eyeBlink: CubismEyeBlink): void
{
eyeBlink = void 0;
eyeBlink = null;
}
/**
*
* @param blinkingInterval []
*/
public setBlinkingInterval(blinkingInterval: number): void
{
this._blinkingIntervalSeconds = blinkingInterval;
}
/**
*
* @param closing []
* @param closed []
* @param opening []
*/
public setBlinkingSetting(closing: number, closed: number, opening: number): void
{
this._closingSeconds = closing;
this._closedSeconds = closed;
this._openingSeconds = opening;
}
/**
* ID
* @param parameterIds ID
*/
public setParameterIds(parameterIds: csmVector<CubismIdHandle>): void
{
this._parameterIds = parameterIds;
}
/**
* ID
* @return ID
*/
public getParameterIds(): csmVector<CubismIdHandle>
{
return this._parameterIds;
}
/**
*
* @param model
* @param deltaTimeSeconds []
*/
public updateParameters(model: CubismModel, deltaTimeSeconds: number): void
{
this._userTimeSeconds += deltaTimeSeconds;
let parameterValue: number;
let t: number = 0.0;
switch(this._blinkingState)
{
case CubismEyeBlink.EyeState.EyeState_Closing:
t = ((this._userTimeSeconds - this._stateStartTimeSeconds) / this._closingSeconds);
if(t >= 1.0)
{
t = 1.0;
this._blinkingState = CubismEyeBlink.EyeState.EyeState_Closed;
this._stateStartTimeSeconds = this._userTimeSeconds;
}
parameterValue = 1.0 - t;
break;
case CubismEyeBlink.EyeState.EyeState_Closed:
t = ((this._userTimeSeconds - this._stateStartTimeSeconds) / this._closedSeconds);
if(t >= 1.0)
{
this._blinkingState = CubismEyeBlink.EyeState.EyeState_Opening;
this._stateStartTimeSeconds = this._userTimeSeconds;
}
parameterValue = 0.0;
break;
case CubismEyeBlink.EyeState.EyeState_Opening:
t = ((this._userTimeSeconds - this._stateStartTimeSeconds) / this._openingSeconds);
if(t >= 1.0)
{
t = 1.0;
this._blinkingState = CubismEyeBlink.EyeState.EyeState_Interval;
this._nextBlinkingTime = this.determinNextBlinkingTiming();
}
parameterValue = t;
break;
case CubismEyeBlink.EyeState.EyeState_Interval:
if(this._nextBlinkingTime < this._userTimeSeconds)
{
this._blinkingState = CubismEyeBlink.EyeState.EyeState_Closing;
this._stateStartTimeSeconds = this._userTimeSeconds;
}
parameterValue = 1.0;
break;
case CubismEyeBlink.EyeState.EyeState_First:
default:
this._blinkingState = CubismEyeBlink.EyeState.EyeState_Interval;
this._nextBlinkingTime = this.determinNextBlinkingTiming();
parameterValue = 1.0;
break;
}
if(!CubismEyeBlink.CloseIfZero)
{
parameterValue = -parameterValue;
}
for(let i: number = 0; i < this._parameterIds.getSize(); ++i)
{
model.setParameterValueById(this._parameterIds.at(i), parameterValue);
}
}
/**
*
* @param modelSetting
*/
public constructor(modelSetting: ICubismModelSetting)
{
this._blinkingState = CubismEyeBlink.EyeState.EyeState_First;
this._nextBlinkingTime = 0.0;
this._stateStartTimeSeconds = 0.0;
this._blinkingIntervalSeconds = 4.0;
this._closingSeconds = 0.1;
this._closedSeconds = 0.05;
this._openingSeconds = 0.15;
this._userTimeSeconds = 0.0;
this._parameterIds = new csmVector<CubismIdHandle>();
if(modelSetting == null)
{
return;
}
for(let i: number = 0; i < modelSetting.getEyeBlinkParameterCount(); ++i)
{
this._parameterIds.pushBack(modelSetting.getEyeBlinkParameterId(i));
}
}
/**
*
*
* @return []
*/
public determinNextBlinkingTiming(): number
{
const r: number = Math.random();
return this._userTimeSeconds + (r * (2.0 * this._blinkingIntervalSeconds - 1.0));
}
_blinkingState: number; // 現在の状態
_parameterIds: csmVector<CubismIdHandle>; // 操作対象のパラメータのIDのリスト
_nextBlinkingTime: number; // 次のまばたきの時刻[秒]
_stateStartTimeSeconds: number; // 現在の状態が開始した時刻[秒]
_blinkingIntervalSeconds: number; // まばたきの間隔[秒]
_closingSeconds: number; // まぶたを閉じる動作の所要時間[秒]
_closedSeconds: number; // まぶたを閉じている動作の所要時間[秒]
_openingSeconds: number; // まぶたを開く動作の所要時間[秒]
_userTimeSeconds: number; // デルタ時間の積算値[秒]
}
export namespace CubismEyeBlink
{
/**
*
*
*
*/
export enum EyeState
{
EyeState_First = 0, // 初期状態
EyeState_Interval, // まばたきしていない状態
EyeState_Closing, // まぶたが閉じていく途中の状態
EyeState_Closed, // まぶたが閉じている状態
EyeState_Opening // まぶたが開いていく途中の状態
}
/**
* ID0 true 1 false
*/
export const CloseIfZero = true;
}
}

View File

@ -0,0 +1,416 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
import {Live2DCubismFramework as cubismid} from "../id/cubismid";
import {Live2DCubismFramework as csmvector} from "../type/csmvector";
import {Live2DCubismFramework as cubismmodel} from "../model/cubismmodel";
import {Live2DCubismFramework as cubismframework} from "../live2dcubismframework";
import {Live2DCubismFramework as cubismjson} from "../utils/cubismjson";
import CubismIdHandle = cubismid.CubismIdHandle;
import csmVector = csmvector.csmVector;
import CubismModel = cubismmodel.CubismModel;
import CubismFramework = cubismframework.CubismFramework;
import CubismJson = cubismjson.CubismJson;
import Value = cubismjson.Value;
export namespace Live2DCubismFramework
{
const Epsilon: number = 0.001;
const DefaultFadeInSeconds: number = 0.5;
// Pose.jsonのタグ
const FadeIn: string = "FadeInTime";
const Link: string = "Link";
const Groups: string = "Groups";
const Id: string = "Id";
/**
*
*
*
*/
export class CubismPose
{
/**
*
* @param pose3json pose3.json
* @param size pose3.json[byte]
* @return
*/
public static create(pose3json: ArrayBuffer, size: number): CubismPose
{
let ret: CubismPose = new CubismPose();
let json: CubismJson = CubismJson.create(pose3json, size);
let root: Value = json.getRoot();
// フェード時間の指定
if(root.getMap().isExist(FadeIn))
{
ret._fadeTimeSeconds = root.getMap().getValue(FadeIn).toFloat(DefaultFadeInSeconds);
if(ret._fadeTimeSeconds <= 0.0)
{
ret._fadeTimeSeconds = DefaultFadeInSeconds;
}
}
// パーツグループ
let poseListInfo: Value = root.getMap().getValue(Groups);
const poseCount: number = poseListInfo.getSize();
for(let poseIndex: number = 0; poseIndex < poseCount; ++poseIndex)
{
let idListInfo: Value = poseListInfo.getVector().at(poseIndex);
const idCount: number = idListInfo.getSize();
let groupCount: number = 0;
for(let groupIndex: number = 0; groupIndex < idCount; ++groupIndex)
{
let partInfo: Value = idListInfo.getVector().at(groupIndex);
let partData: CubismPose.PartData = new CubismPose.PartData();
const parameterId: CubismIdHandle = CubismFramework.getIdManager().getId(partInfo.getMap().getValue(Id).getRawString());
partData.partId = parameterId;
// リンクするパーツの設定
if(partInfo.getMap().isExist(Link))
{
let linkListInfo: Value = partInfo.getMap().getValue(Link);
const linkCount: number = linkListInfo.getSize();
for(let linkIndex: number = 0; linkIndex < linkCount; ++linkIndex)
{
let linkPart: CubismPose.PartData = new CubismPose.PartData();
const linkId: CubismIdHandle = CubismFramework.getIdManager().getId(linkListInfo.getVector().at(linkIndex).getString());
linkPart.partId = linkId;
partData.link.pushBack(linkPart);
}
}
ret._partGroups.pushBack(partData.clone());
++groupCount;
}
ret._partGroupCounts.pushBack(groupCount);
}
CubismJson.delete(json);
return ret;
}
/**
*
* @param pose CubismPose
*/
public static delete(pose: CubismPose): void
{
pose = void 0;
pose = null;
}
/**
*
* @param model
* @param deltaTimeSeconds []
*/
public updateParameters(model: CubismModel, deltaTimeSeconds: number): void
{
// 前回のモデルと同じでない場合は初期化が必要
if(model != this._lastModel)
{
// パラメータインデックスの初期化
this.reset(model);
}
this._lastModel = model;
// 設定から時間を変更すると、経過時間がマイナスになる事があるので、経過時間0として対応
if(deltaTimeSeconds < 0.0)
{
deltaTimeSeconds = 0.0;
}
let beginIndex: number = 0;
for(let i = 0; i < this._partGroupCounts.getSize(); i++)
{
const partGroupCount: number = this._partGroupCounts.at(i);
this.doFade(model, deltaTimeSeconds, beginIndex, partGroupCount);
beginIndex += partGroupCount;
}
this.copyPartOpacities(model);
}
/**
*
* @param model
* @note 0
*/
public reset(model: CubismModel): void
{
let beginIndex: number = 0;
for(let i: number = 0; i < this._partGroupCounts.getSize(); ++i)
{
const groupCount: number = this._partGroupCounts.at(i);
for(let j: number = beginIndex; j < beginIndex + groupCount; ++j)
{
this._partGroups.at(j).initialize(model);
const partsIndex: number = this._partGroups.at(j).partIndex;
const paramIndex: number = this._partGroups.at(j).parameterIndex;
if(partsIndex < 0)
{
continue;
}
model.setPartOpacityByIndex(partsIndex, (j == beginIndex ? 1.0 : 0.0));
model.setParameterValueByIndex(paramIndex, (j == beginIndex ? 1.0: 0.0));
for(let k: number = 0; k < this._partGroups.at(j).link.getSize(); ++k)
{
this._partGroups.at(j).link.at(k).initialize(model);
}
}
beginIndex += groupCount;
}
}
/**
*
*
* @param model
*/
public copyPartOpacities(model: CubismModel): void
{
for(let groupIndex: number = 0; groupIndex < this._partGroups.getSize(); ++groupIndex)
{
let partData: CubismPose.PartData = this._partGroups.at(groupIndex);
if(partData.link.getSize() == 0)
{
continue; // 連動するパラメータはない
}
const partIndex: number = this._partGroups.at(groupIndex).partIndex;
const opacity: number = model.getPartOpacityByIndex(partIndex);
for(let linkIndex: number = 0; linkIndex < partData.link.getSize(); ++linkIndex)
{
let linkPart: CubismPose.PartData = partData.link.at(linkIndex);
const linkPartIndex: number = linkPart.partIndex;
if(linkPartIndex < 0)
{
continue;
}
model.setPartOpacityByIndex(linkPartIndex, opacity);
}
}
}
/**
*
* @param model
* @param deltaTimeSeconds []
* @param beginIndex
* @param partGroupCount
*/
public doFade(model: CubismModel, deltaTimeSeconds: number, beginIndex: number, partGroupCount: number): void
{
let visiblePartIndex: number = -1;
let newOpacity: number = 1.0;
const phi: number = 0.5;
const backOpacityThreshold: number = 0.15;
// 現在、表示状態になっているパーツを取得
for(let i: number = beginIndex; i < beginIndex + partGroupCount; ++i)
{
const partIndex: number = this._partGroups.at(i).partIndex;
const paramIndex: number = this._partGroups.at(i).parameterIndex;
if(model.getParameterValueByIndex(paramIndex) > Epsilon)
{
if(visiblePartIndex >= 0)
{
break;
}
visiblePartIndex = i;
newOpacity = model.getPartOpacityByIndex(partIndex);
// 新しい不透明度を計算
newOpacity += (deltaTimeSeconds / this._fadeTimeSeconds);
if(newOpacity > 1.0)
{
newOpacity = 1.0;
}
}
}
if(visiblePartIndex < 0)
{
visiblePartIndex = 0;
newOpacity = 1.0;
}
// 表示パーツ、非表示パーツの不透明度を設定する
for(let i: number = beginIndex; i < beginIndex + partGroupCount; ++i)
{
const partsIndex: number = this._partGroups.at(i).partIndex;
// 表示パーツの設定
if(visiblePartIndex == i)
{
model.setPartOpacityByIndex(partsIndex, newOpacity); // 先に設定
}
// 非表示パーツの設定
else
{
let opacity: number = model.getPartOpacityByIndex(partsIndex);
let a1: number; // 計算によって求められる不透明度
if(newOpacity < phi)
{
a1 = newOpacity * (phi - 1) / phi + 1.0; // (0,1),(phi,phi)を通る直線式
}
else
{
a1 = (1 - newOpacity) * phi / (1.0 - phi); // (1,0),(phi,phi)を通る直線式
}
// 背景の見える割合を制限する場合
const backOpacity: number = (1.0 - a1) * (1.0 - newOpacity);
if(backOpacity > backOpacityThreshold)
{
a1 = 1.0 - backOpacityThreshold / (1.0 - newOpacity);
}
if(opacity > a1)
{
opacity = a1; // 計算の不透明度よりも大きければ(濃ければ)不透明度を上げる
}
model.setPartOpacityByIndex(partsIndex, opacity);
}
}
}
/**
*
*/
public constructor()
{
this._fadeTimeSeconds = DefaultFadeInSeconds;
this._lastModel = null;
this._partGroups = new csmVector<CubismPose.PartData>();
this._partGroupCounts = new csmVector<number>();
}
_partGroups: csmVector<CubismPose.PartData>; // パーツグループ
_partGroupCounts: csmVector<number>; // それぞれのパーツグループの個数
_fadeTimeSeconds: number; // フェード時間[秒]
_lastModel: CubismModel; // 前回操作したモデル
}
export namespace CubismPose
{
/**
*
*/
export class PartData
{
/**
*
*/
constructor(v?: PartData)
{
this.parameterIndex = 0;
this.partIndex = 0;
this.link = new csmVector<PartData>();
if(v != undefined)
{
this.partId = v.partId;
for(const ite: csmVector.iterator<PartData> = v.link.begin(); ite.notEqual(v.link.end()); ite.preIncrement())
{
this.link.pushBack(ite.ptr().clone());
}
}
}
/**
* =
*/
public assignment(v: PartData): PartData
{
this.partId = v.partId;
for(const ite: csmVector.iterator<PartData> = v.link.begin(); ite.notEqual(v.link.end()); ite.preIncrement())
{
this.link.pushBack(ite.ptr().clone());
}
return this;
}
/**
*
* @param model 使
*/
public initialize(model: CubismModel): void
{
this.parameterIndex = model.getParameterIndex(this.partId);
this.partIndex = model.getPartIndex(this.partId);
model.setParameterValueByIndex(this.parameterIndex, 1);
}
/**
*
*/
public clone(): PartData
{
let clonePartData: PartData = new PartData();
clonePartData.partId = this.partId;
clonePartData.parameterIndex = this.parameterIndex;
clonePartData.partIndex = this.partIndex;
clonePartData.link = new csmVector<PartData>();
for(let ite: csmVector.iterator<PartData> = this.link.begin(); ite.notEqual(this.link.end()); ite.increment())
{
clonePartData.link.pushBack(ite.ptr().clone());
}
return clonePartData;
}
partId: CubismIdHandle; // パーツID
parameterIndex: number; // パラメータのインデックス
partIndex: number; // パーツのインデックス
link: csmVector<PartData>; // 連動するパラメータ
}
}
}

View File

@ -0,0 +1,47 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
export namespace Live2DCubismFramework
{
/**
*
*
*
*
*/
export abstract class ICubismAllocator
{
/**
*
*
* @param size
* @return '0'
*/
public abstract allocate(size: number): any;
/**
*
*
* @param memory
*/
public abstract deallocate(memory: any): void;
/**
*
* @param size
* @param alignment
* @return '0'
*/
public abstract allocateAligned(size: number, alignment: number): any;
/**
*
* @param alignedMemory
*/
public abstract deallocateAligned(alignedMemory: any): void;
}
}

View File

@ -0,0 +1,193 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
import {Live2DCubismFramework as cubismid} from './id/cubismid';
import {Live2DCubismFramework as csmmap} from './type/csmmap';
import csmMap = csmmap.csmMap;
import CubismIdHandle = cubismid.CubismIdHandle;
export namespace Live2DCubismFramework
{
/**
*
*
*
*/
export abstract class ICubismModelSetting
{
/**
* Moc
* @return Moc
*/
public abstract getModelFileName(): string;
/**
* 使
*
*/
public abstract getTextureCount(): number;
/**
*
* @return
*/
public abstract getTextureDirectory(): string;
/**
* 使
* @param index
* @return
*/
public abstract getTextureFileName(index: number): string;
/**
*
* @return
*/
public abstract getHitAreasCount(): number;
/**
* ID
*
* @param index index
* @return ID
*/
public abstract getHitAreaId(index: number): CubismIdHandle;
/**
*
* @param index
* @return
*/
public abstract getHitAreaName(index: number): string;
/**
*
* @return
*/
public abstract getPhysicsFileName(): string;
/**
*
* @return
*/
public abstract getPoseFileName(): string;
/**
*
* @return
*/
public abstract getExpressionCount(): number;
/**
*
* @param index
* @return
*/
public abstract getExpressionName(index: number): string;
/**
*
* @param index
* @return
*/
public abstract getExpressionFileName(index: number): string;
/**
*
* @return
*/
public abstract getMotionGroupCount(): number;
/**
*
* @param index
* @return
*/
public abstract getMotionGroupName(index: number): string;
/**
*
* @param groupName
* @return
*/
public abstract getMotionCount(groupName: string): number;
/**
*
* @param groupName
* @param index
* @return
*/
public abstract getMotionFileName(groupName: string, index: number): string;
/**
*
* @param groupName
* @param index
* @return
*/
public abstract getMotionSoundFileName(groupName: string, index: number): string;
/**
*
* @param groupName
* @param index
* @return []
*/
public abstract getMotionFadeInTimeValue(groupName: string, index: number): number;
/**
*
* @param groupName
* @param index
* @return []
*/
public abstract getMotionFadeOutTimeValue(groupName: string, index: number): number;
/**
*
* @return
*/
public abstract getUserDataFile(): string;
/**
*
* @param outLayoutMap csmMap
* @return true
* @return false
*/
public abstract getLayoutMap(outLayoutMap: csmMap<string, number>): boolean;
/**
*
* @return
*/
public abstract getEyeBlinkParameterCount(): number;
/**
* ID
* @param index
* @return ID
*/
public abstract getEyeBlinkParameterId(index: number): CubismIdHandle;
/**
*
* @return
*/
public abstract getLipSyncParameterCount(): number;
/**
*
* @param index
* @return ID
*/
public abstract getLipSyncParameterId(index: number): CubismIdHandle;
}
}

90
Framework/id/cubismid.ts Normal file
View File

@ -0,0 +1,90 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
import {Live2DCubismFramework as csmstring} from "../type/csmstring";
import csmString = csmstring.csmString;
export namespace Live2DCubismFramework
{
/**
* Drawable
*
* Drawable
*/
export class CubismId
{
/**
* ID
*/
public getString(): csmString
{
return this._id;
}
/**
*
*/
public constructor(id: string | csmString)
{
if(typeof(id) === 'string')
{
this._id = new csmString(id);
return;
}
this._id = id;
}
/**
* id
* @param c id
* @return true,false
*/
public isEqual(c: string | csmString | CubismId): boolean
{
if (typeof(c) === 'string')
{
return this._id.isEqual(c);
}
else if (c instanceof csmString)
{
return this._id.isEqual(c.s);
}
else if (c instanceof CubismId)
{
return this._id.isEqual(c._id.s);
}
return false;
}
/**
* id
* @param c id
* @return true,false
*/
public isNotEqual(c: string | csmString | CubismId): boolean
{
if (typeof(c) == 'string')
{
return !this._id.isEqual(c);
}
else if (c instanceof csmString)
{
return !this._id.isEqual(c.s);
}
else if (c instanceof CubismId)
{
return !this._id.isEqual(c._id.s);
}
return false;
}
private _id: csmString; // ID名
}
export declare type CubismIdHandle = CubismId;
}

View File

@ -0,0 +1,131 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
import {Live2DCubismFramework as csmvector} from "../type/csmvector";
import {Live2DCubismFramework as cubismid} from "./cubismid";
import {Live2DCubismFramework as csmstring} from "../type/csmstring";
import csmString = csmstring.csmString;
import CubismId = cubismid.CubismId;
import csmVector = csmvector.csmVector;
export namespace Live2DCubismFramework
{
/**
* ID
*
* ID
*/
export class CubismIdManager
{
/**
*
*/
public constructor()
{
this._ids = new csmVector<CubismId>();
}
/**
*
*/
public release(): void
{
for(let i: number = 0; i < this._ids.getSize(); ++i)
{
this._ids.set(i, void 0);
}
this._ids = null;
}
/**
* ID
*
* @param ids ID
* @param count ID
*/
public registerIds(ids: string[] | csmString[]): void
{
for(let i: number = 0; i < ids.length; i++)
{
this.registerId(ids[i]);
}
}
/**
* ID
*
* @param id ID
*/
public registerId(id: string | csmString): CubismId
{
let result: CubismId = null;
if ('string' == typeof(id))
{
if ((result = this.findId(id)) != null)
{
return result;
}
result = new CubismId(id);
this._ids.pushBack(result);
}
else
{
return this.registerId(id.s);
}
return result;
}
/**
* IDID
*
* @param id ID
*/
public getId(id: csmString | string): CubismId
{
return this.registerId(id);
}
/**
* IDID
*
* @return true
* @return false
*/
public isExist(id: csmString | string): boolean
{
if ('string' == typeof(id))
{
return (this.findId(id) != null);
}
return this.isExist(id.s);
}
/**
* IDID
*
* @param id ID
* @return IDNULL
*/
private findId(id: string): CubismId
{
for(let i: number = 0; i < this._ids.getSize(); ++i)
{
if(this._ids.at(i).getString().isEqual(id))
{
return this._ids.at(i);
}
}
return null;
}
private _ids: csmVector<CubismId>; // 登録されているIDのリスト
}
}

View File

@ -0,0 +1,283 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
import {Live2DCubismFramework as cubismjson} from "./utils/cubismjson";
import {Live2DCubismFramework as cubismidmanager} from "./id/cubismidmanager";
import {Live2DCubismFramework as cubismrenderer} from "./rendering/cubismrenderer";
import {CubismLogInfo, CubismLogWarning, CSM_ASSERT} from "./utils/cubismdebug";
import Value = cubismjson.Value;
import CubismIdManager = cubismidmanager.CubismIdManager;
import CubismRenderer = cubismrenderer.CubismRenderer;
export function strtod(s: string, endPtr: string[]): number
{
let index: number = 0;
for(let i: number = 1; ; i++)
{
let testC: string = s.slice(i - 1, i);
// 指数・マイナスの可能性があるのでスキップする
if(testC=='e' || testC=='-' || testC == 'E')
{
continue;
}
    // 文字列の範囲を広げていく
let test: string = s.substring(0, i);
let number: number = Number(test);
if(isNaN(number))
{
     // 数値として認識できなくなったので終了
break;
}
    // 最後に数値としてできたindexを格納しておく
index = i;
}
let d = parseFloat(s); // パースした数値
if(isNaN(d))
{
     // 数値として認識できなくなったので終了
d = NaN;
}
endPtr[0] = s.slice(index); // 後続の文字列
return d;
}
export namespace Live2DCubismFramework
{
// ファイルスコープの変数を初期化
let s_isStarted: boolean = false;
let s_isInitialized: boolean = false;
let s_option: Option = null;
let s_cubismIdManager: CubismIdManager = null;
/**
* Framework使
*/
export namespace Constant
{
export const vertexOffset: number = 0; // メッシュ頂点のオフセット値
export const vertexStep: number = 2; // メッシュ頂点のステップ値
}
export function csmDelete<T>(address: T): void
{
if(!address)
{
return;
}
address = void 0;
}
/**
* Live2D Cubism3 Original Workflow SDK
* CubismFramework.initialize()CubismFramework.dispose()
*/
export class CubismFramework
{
/**
* @brief Cubism FrameworkAPI使<br>
* API<br>
* <br>
*
*
* @param allocator ICubismAllocator
* @param option Option
*
* @return true
*/
public static startUp(option: Option = null): boolean
{
if(s_isStarted)
{
CubismLogInfo("CubismFramework::StartUp() is already done.");
return s_isStarted;
}
s_option = option;
if(s_option != null)
{
// TODO Core::csmSetLogFunction(s_option->LogFunction);
}
s_isStarted = true;
// Live2D Cubism Coreバージョン情報を表示
if(s_isStarted)
{
const version: number = 1; // TODO Core::csmGetVersion()
const major: number = ((version & 0xFF000000) >> 24);
const minor: number = ((version & 0x00FF0000) >> 16);
const patch: number = ((version & 0x0000FFFF));
const versionNumber: number = version;
CubismLogInfo("Live2D Cubism Core version: %02d.%02d.%04d (%d)", major, minor, patch, versionNumber);
}
CubismLogInfo("CubismFramework::StartUp() is complete.");
return s_isStarted;
}
/**
* StartUp()CubismFramework
* Dispose()CubismFramework
*/
public static cleanUp(): void
{
s_isStarted = false;
s_isInitialized = false;
s_option = null;
s_cubismIdManager = null;
}
/**
* Cubism Framework<br>
* Initialize()Dispose()
*/
public static initialize(): void
{
CSM_ASSERT(s_isStarted);
if(!s_isStarted)
{
CubismLogWarning("CubismFramework is not started.");
return;
}
// --- s_isInitializedによる連続初期化ガード ---
// 連続してリソース確保が行われないようにする。
// 再度Initialize()するには先にDispose()を実行する必要がある。
if (s_isInitialized)
{
CubismLogWarning("CubismFramework::Initialize() skipped, already initialized.");
return;
}
//---- static 初期化 ----
Value.staticInitializeNotForClientCall();
s_cubismIdManager = new CubismIdManager();
s_isInitialized = true;
CubismLogInfo("CubismFramework::Initialize() is complete.");
}
/**
* Cubism Framework
*
*
*/
public static dispose(): void
{
CSM_ASSERT(s_isStarted);
if(!s_isStarted)
{
CubismLogWarning("CubismFramework is not started.");
return;
}
// --- s_isInitializedによる未初期化解放ガード ---
// dispose()するには先にinitialize()を実行する必要がある。
if(!s_isInitialized) // false...リソース未確保の場合
{
CubismLogWarning("CubismFramework::Dispose() skipped, not initialized.");
return;
}
Value.staticReleaseNotForClientCall();
s_cubismIdManager.release();
s_cubismIdManager = void 0;
// レンダラの静的リソース(シェーダプログラム他)を解放する
CubismRenderer.StaticRelease();
s_isInitialized = false;
CubismLogInfo("CubismFramework::Dispose() is complete.");
}
/**
*
*
* @return
*/
public static getLoggingLevel(): Option.LogLevel
{
if (s_option != null)
{
return s_option.loggingLevel;
}
return Option.LogLevel.LogLevel_Off;
}
/**
* Cubism FrameworkAPI使
* @return API使true
*/
public static isStarted(): boolean
{
return s_isStarted;
}
/**
* Cubism Framework
* @return true
*/
public static isInitialized(): boolean
{
return s_isInitialized;
}
/**
* ID
* @return CubismManager
*/
public static getIdManager(): CubismIdManager
{
return s_cubismIdManager;
}
/**
* 使
*
*/
private constructor()
{
}
}
}
export class Option
{
loggingLevel: Option.LogLevel; // ログ出力レベルの設定
}
/**
*
*/
export namespace Option
{
export enum LogLevel
{
LogLevel_Verbose = 0, // 詳細ログ
LogLevel_Debug, // デバッグログ
LogLevel_Info, // Infoログ
LogLevel_Warning, // 警告ログ
LogLevel_Error, // エラーログ
LogLevel_Off // ログ出力無効
}
}

View File

@ -0,0 +1,226 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
import {Live2DCubismFramework as cubismvector2} from "./cubismvector2";
import CubismVector2 = cubismvector2.CubismVector2;
export namespace Live2DCubismFramework
{
/**
* 使
*/
export class CubismMath
{
/**
*
*
* @param value
* @param min
* @param max
* @return
*/
static range(value: number, min: number, max: number): number
{
if (value < min)
{
value = min;
}
else if (value > max)
{
value = max;
}
return value;
}
/**
*
*
* @param x
* @return sin(x)
*/
static sin(x: number): number
{
return Math.sin(x);
}
/**
*
*
* @param x ()
* @return cos(x)
*/
static cos(x: number): number
{
return Math.cos(x);
}
/**
*
*
* @param x
* @return
*/
static abs(x: number): number
{
return Math.abs(x);
}
/**
* ()
* @param x ->
* @return
*/
static sqrt(x: number): number
{
return Math.sqrt(x);
}
/**
*
*
*
* @param value
* @return
*/
static getEasingSine(value: number): number
{
if (value < 0.0)
{
return 0.0;
}
else if (value > 1.0)
{
return 1.0;
}
return 0.5 - 0.5 * this.cos(value * Math.PI);
}
/**
*
*
* @param left
* @param right
* @return
*/
static max(left: number, right: number): number
{
return (left > right)
? left
: right;
}
/**
*
*
* @param left
* @param right  
* @return
*/
static min(left: number, right: number): number
{
return (left > right)
? right
: left;
}
/**
*
*
* @param degrees
* @return
*/
static degreesToRadian(degrees: number): number
{
return (degrees / 180.0) * Math.PI;
}
/**
*
*
* @param radian
* @return
*/
static radianToDegrees(radian: number): number
{
return (radian * 180.0) / Math.PI;
}
/**
*
*
* @param from
* @param to
* @return
*/
static directionToRadian(from: CubismVector2, to: CubismVector2): number
{
const q1: number = Math.atan2(to.y, to.x);
const q2: number = Math.atan2(from.y, from.x);
let ret: number = q1 - q2;
while(ret < -Math.PI)
{
ret += Math.PI * 2.0;
}
while(ret > Math.PI)
{
ret -= Math.PI * 2.0;
}
return ret;
}
/**
*
*
* @param from
* @param to
* @return
*/
static directionToDegrees(from: CubismVector2, to: CubismVector2): number
{
const radian: number = this.directionToRadian(from, to);
let degree: number = this.radianToDegrees(radian);
if ((to.x - from.x) > 0.0)
{
degree = -degree;
}
return degree;
}
/**
*
*
* @param totalAngle
* @return
*/
static radianToDirection(totalAngle: number): CubismVector2
{
let ret: CubismVector2 = new CubismVector2();
ret.x = this.sin(totalAngle);
ret.y = this.cos(totalAngle);
return ret;
}
/**
*
*/
private constructor()
{
}
}
}

View File

@ -0,0 +1,279 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
export namespace Live2DCubismFramework
{
/**
* 4x4
*
* 4x4便
*/
export class CubismMatrix44
{
/**
*
*/
public constructor()
{
this._tr = new Float32Array(16); // 4 * 4のサイズ
this.loadIdentity();
}
/**
*
*
* @param a a
* @param b b
* @return
*/
public static multiply(a: Float32Array, b: Float32Array, dst: Float32Array): void
{
let c: Float32Array = new Float32Array(
[
0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0
]
);
let n: number = 4;
for (let i: number = 0; i < n; ++i)
{
for(let j: number = 0; j < n; ++j)
{
for(let k: number = 0; k < n; ++k)
{
c[j + i * 4] += a[k + i * 4] * b[j + k * 4];
}
}
}
for(let i: number = 0; i < 16; ++i)
{
dst[i] = c[i];
}
}
/**
*
*/
public loadIdentity(): void
{
let c: Float32Array = new Float32Array(
[
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0
]
);
this.setMatrix(c);
}
/**
*
*
* @param tr 164x4
*/
public setMatrix(tr: Float32Array): void
{
for(let i = 0; i < 16; ++i)
{
this._tr[i] = tr[i];
}
}
/**
*
*
* @return 164x4
*/
public getArray(): Float32Array
{
return this._tr;
}
/**
* X
* @return X
*/
public getScaleX(): number
{
return this._tr[0];
}
/**
* Y
*
* @return Y
*/
public getScaleY(): number
{
return this._tr[5];
}
/**
* X
* @return X
*/
public getTranslateX(): number
{
return this._tr[12];
}
/**
* Y
* @return Y
*/
public getTranslateY(): number
{
return this._tr[13];
}
/**
* X
*
* @param src X
* @return X
*/
public transformX(src: number): number
{
return this._tr[0] * src + this._tr[12];
}
/**
* Y
*
* @param src Y
* @return Y
*/
public transformY(src: number): number
{
return this._tr[5] * src + this._tr[13];
}
/**
* X
*/
public invertTransformX(src: number): number
{
return (src - this._tr[12]) / this._tr[0];
}
/**
* Y
*/
public invertTransformY(src: number): number
{
return (src - this._tr[13]) / this._tr[5];
}
/**
*
*
*
*
* @param x X
* @param y Y
*/
public translateRelative(x: number, y: number): void
{
let tr1: Float32Array = new Float32Array(
[
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
x, y, 0.0, 1.0
]
);
CubismMatrix44.multiply(tr1, this._tr, this._tr);
}
/**
*
*
*
*
* @param x X
* @param y y
*/
public translate(x: number, y: number): void
{
this._tr[12] = x;
this._tr[13] = y;
}
/**
* X
*
* @param x X
*/
public translateX(x: number): void
{
this._tr[12] = x;
}
/**
* Y
*
* @param y Y
*/
public translateY(y: number): void
{
this._tr[13] = y;
}
/**
*
*
* @param x X
* @param y Y
*/
public scaleRelative(x: number, y:number): void
{
let tr1: Float32Array = new Float32Array(
[
x, 0.0, 0.0, 0.0,
0.0, y, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0
]
);
CubismMatrix44.multiply(tr1, this._tr, this._tr);
}
/**
*
*
* @param x X
* @param y Y
*/
public scale(x: number, y: number): void
{
this._tr[0] = x;
this._tr[5] = y;
}
/**
*
*
* @param m
*/
public multiplyByMatrix(m: CubismMatrix44): void
{
CubismMatrix44.multiply(m.getArray(), this._tr, this._tr);
}
protected _tr: Float32Array; // 4x4行列データ
}
}

View File

@ -0,0 +1,263 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
import {Live2DCubismFramework as csmmap} from "../type/csmmap";
import {Live2DCubismFramework as cubismmatrix44} from "./cubismmatrix44";
import csmMap = csmmap.csmMap;
import CubismMatrix44 = cubismmatrix44.CubismMatrix44;
export namespace Live2DCubismFramework
{
/**
* 4x4
*
* 4x4
*/
export class CubismModelMatrix extends CubismMatrix44
{
/**
*
*
* @param w
* @param h
*/
constructor(w?: number, h?: number)
{
super();
this._width = (w !== undefined)
? w
: 0.0;
this._height = (h !== undefined)
? h
: 0.0;
// 原点(0, 0)を中心にして、画面に納まるような大きさで初期化
if (this._width > this._height)
{
this.setWidth(this._height / this._width);
}
else
{
this.setHeight(1.0);
}
}
/**
*
*
* @param w
*/
public setWidth(w: number): void
{
const scaleX: number = w / this._width;
const scaleY: number = scaleX;
this.scale(scaleX, scaleY);
}
/**
*
* @param h
*/
public setHeight(h: number): void
{
const scaleX: number = h / this._height;
const scaleY: number = scaleX;
this.scale(scaleX, scaleY);
}
/**
*
*
* @param x X
* @param y Y
*/
public setPosition(x: number, y: number): void
{
this.translate(x, y);
}
/**
*
*
* @param x X
* @param y Y
*
* @note widthheight
*/
public setCenterPosition(x: number, y: number)
{
this.centerX(x);
this.centerY(y);
}
/**
*
*
* @param y Y
*/
public top(y: number): void
{
this.setY(y);
}
/**
*
*
* @param y Y
*/
public bottom(y: number)
{
const h: number = this._height * this.getScaleY();
this.translateY(y - h);
}
/**
*
*
* @param x X
*/
public left(x: number): void
{
this.setX(x);
}
/**
*
*
* @param x X
*/
public right(x: number): void
{
const w = this._width * this.getScaleX();
this.translateX(x - w);
}
/**
* X
*
* @param x X
*/
public centerX(x: number): void
{
const w = this._width * this.getScaleX();
this.translateX(x - (w / 2.0));
}
/**
* X
*
* @param x X
*/
public setX(x: number): void
{
this.translateX(x);
}
/**
* Y
*
* @param y Y
*/
public centerY(y: number): void
{
const h: number = this._height * this.getScaleY();
this.translateY(y - (h / 2.0));
}
/**
* Y
*
* @param y Y
*/
public setY(y: number): void
{
this.translateY(y);
}
/**
*
*
* @param layout
*/
public setupFromLayout(layout: csmMap<string, number>): void
{
const keyWidth = "width";
const keyHeight = "height";
const keyX = "x";
const keyY = "y";
const keyCenterX = "center_x";
const keyCenterY = "center_y";
const keyTop = "top";
const keyBottom = "bottom";
const keyLeft = "left";
const keyRight = "right";
for(const ite: csmMap.iterator<string, number> = layout.begin(); ite.notEqual(layout.end()); ite.preIncrement())
{
const key: string = ite.ptr().first;
const value: number = ite.ptr().second;
if(key == keyWidth)
{
this.setWidth(value);
}
else if(key == keyHeight)
{
this.setHeight(value);
}
}
for(const ite: csmMap.iterator<string, number> = layout.begin(); ite.notEqual(layout.end()); ite.preIncrement())
{
const key: string = ite.ptr().first;
const value: number = ite.ptr().second;
if(key == keyX)
{
this.setX(value);
}
else if(key == keyY)
{
this.setY(value);
}
else if(key == keyCenterX)
{
this.centerX(value);
}
else if(key == keyCenterY)
{
this.centerY(value);
}
else if(key == keyTop)
{
this.top(value);
}
else if(key == keyBottom)
{
this.bottom(value);
}
else if(key == keyLeft)
{
this.left(value);
}
else if(key == keyRight)
{
this.right(value);
}
}
}
private _width: number; // 横幅
private _height: number; // 縦幅
}
}

View File

@ -0,0 +1,172 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
import {Live2DCubismFramework as cubismmath} from "./cubismmath";
import CubismMath = cubismmath.CubismMath;
export namespace Live2DCubismFramework
{
const FrameRate: number = 30;
const Epsilon: number = 0.01;
/**
*
*
*
*/
export class CubismTargetPoint
{
/**
*
*/
public constructor()
{
this._faceTargetX = 0.0;
this._faceTargetY = 0.0;
this._faceX = 0.0;
this._faceY = 0.0;
this._faceVX = 0.0;
this._faceVY = 0.0;
this._lastTimeSeconds = 0.0;
this._userTimeSeconds = 0.0;
}
/**
*
*/
public update(deltaTimeSeconds: number): void
{
// デルタ時間を加算する
this._userTimeSeconds += deltaTimeSeconds;
// 首を中央から左右に振るときの平均的な速さは 秒速度。加速・減速を考慮して、その2倍を最高速度とする
// 顔の振り具合を、中央0.0)から、左右は(+-1.0)とする
const faceParamMaxV: number = 40.0 / 10.0; // 7.5秒間に40分移動(5.3/sc)
const maxV: number = faceParamMaxV * 1.0 / FrameRate; // 1frameあたりに変化できる速度の上限
if(this._lastTimeSeconds == 0.0)
{
this._lastTimeSeconds = this._userTimeSeconds;
return;
}
const deltaTimeWeight: number = (this._userTimeSeconds - this._lastTimeSeconds) * FrameRate;
this._lastTimeSeconds = this._userTimeSeconds;
// 最高速度になるまでの時間を
const timeToMaxSpeed: number = 0.15;
const frameToMaxSpeed: number = timeToMaxSpeed * FrameRate; // sec * frame/sec
const maxA: number = deltaTimeWeight * maxV / frameToMaxSpeed; // 1frameあたりの加速度
// 目指す向きは、dx, dy方向のベクトルとなる
const dx: number = this._faceTargetX - this._faceX;
const dy: number = this._faceTargetY - this._faceY;
if(CubismMath.abs(dx) <= Epsilon && CubismMath.abs(dy) <= Epsilon)
{
return; // 変化なし
}
// 速度の最大よりも大きい場合は、速度を落とす
const d: number = CubismMath.sqrt((dx * dx) + (dy * dy));
// 進行方向の最大速度ベクトル
const vx: number = maxV * dx / d;
const vy: number = maxV * dy / d;
// 現在の速度から、新規速度への変化(加速度)を求める
let ax: number = vx - this._faceVX;
let ay: number = vy - this._faceVY;
const a: number = CubismMath.sqrt((ax * ax) + (ay * ay));
// 加速のとき
if(a < -maxA || a > maxA)
{
ax *= maxA / a;
ay *= maxA / a;
}
// 加速度を元の速度に足して、新速度とする
this._faceVX += ax;
this._faceVY += ay;
// 目的の方向に近づいたとき、滑らかに減速するための処理
// 設定された加速度で止まる事の出来る距離と速度の関係から
// 現在とりうる最高速度を計算し、それ以上の時は速度を落とす
// ※本来、人間は筋力で力(加速度)を調整できるため、より自由度が高いが、簡単な処理で済ませている
{
// 加速度、速度、距離の関係式。
// 2 6 2 3
// sqrt(a t + 16 a h t - 8 a h) - a t
// v = --------------------------------------
// 2
// 4 t - 2
// (t=1)
// 時刻tは、あらかじめ加速度、速度を1/60(フレームレート、単位なし)で
// 考えているので、tとして消してよい※未検証
const maxV: number = 0.5 * (CubismMath.sqrt((maxA * maxA) + 16.0 * maxA * d - 8.0 * maxA * d) - maxA);
const curV: number = CubismMath.sqrt((this._faceVX * this._faceVX) + (this._faceVY * this._faceVY));
if(curV > maxV)
{
// 現在の速度 > 最高速度のとき、最高速度まで減速
this._faceVX *= maxV / curV;
this._faceVY *= maxV / curV;
}
}
this._faceX += this._faceVX;
this._faceY += this._faceVY;
}
/**
* X
*
* @return X-1.0 ~ 1.0
*/
public getX(): number
{
return this._faceX;
}
/**
* Y
*
* @return Y-1.0 ~ 1.0
*/
public getY(): number
{
return this._faceY;
}
/**
*
*
* @param x X-1.0 ~ 1.0
* @param y Y-1.0 ~ 1.0
*/
public set(x: number, y: number): void
{
this._faceTargetX = x;
this._faceTargetY = y;
}
private _faceTargetX: number; // 顔の向きのX目標値この値に近づいていく
private _faceTargetY: number; // 顔の向きのY目標値この値に近づいていく
private _faceX: number; // 顔の向きX-1.0 ~ 1.0
private _faceY: number; // 顔の向きY-1.0 ~ 1.0
private _faceVX: number; // 顔の向きの変化速度X
private _faceVY: number; // 顔の向きの変化速度Y
private _lastTimeSeconds: number; // 最後の実行時間[秒]
private _userTimeSeconds: number; // デルタ時間の積算値[秒]
}
}

View File

@ -0,0 +1,180 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
export namespace Live2DCubismFramework
{
/**
* 2
*
* 2
*/
export class CubismVector2
{
/**
*
*/
public constructor(public x?: number, public y?: number)
{
this.x = (x == undefined)
? 0.0
: x;
this.y = (y == undefined)
? 0.0
: y;
}
/**
*
*
* @param vector2
* @return
*/
public add(vector2: CubismVector2): CubismVector2
{
let ret: CubismVector2 = new CubismVector2(0.0, 0.0);
ret.x = this.x + vector2.x;
ret.y = this.y + vector2.y;
return ret;
}
/**
*
*
* @param vector2
* @return
*/
public substract(vector2: CubismVector2): CubismVector2
{
let ret: CubismVector2 = new CubismVector2(0.0, 0.0);
ret.x = this.x - vector2.x;
ret.y = this.y - vector2.y;
return ret;
}
/**
*
*
* @param vector2
* @return  
*/
public multiply(vector2: CubismVector2): CubismVector2
{
let ret: CubismVector2 = new CubismVector2(0.0, 0.0);
ret.x = this.x * vector2.x;
ret.y = this.y * vector2.y;
return ret;
}
/**
* ()
*
* @param scalar
* @return  
*/
public multiplyByScaler(scalar: number): CubismVector2
{
return this.multiply(new CubismVector2(scalar, scalar));
}
/**
*
*
* @param vector2
* @return  
*/
public division(vector2: CubismVector2): CubismVector2
{
let ret: CubismVector2 = new CubismVector2(0.0, 0.0);
ret.x = this.x / vector2.x;
ret.y = this.y / vector2.y;
return ret;
}
/**
* ()
*
* @param scalar
* @return  
*/
public divisionByScalar(scalar: number): CubismVector2
{
return this.division(new CubismVector2(scalar, scalar));
}
/**
*
*
* @return
*/
public getLength(): number
{
return Math.sqrt(this.x * this.x + this.y * this.y);
}
/**
*
*
* @param a
* @return
*/
public getDistanceWith(a: CubismVector2): number
{
return Math.sqrt(((this.x - a.x) * (this.x - a.x)) + ((this.y - a.y) * (this.y - a.y)));
}
/**
*
*
* @param a
* @return
*/
public dot(a: CubismVector2): number
{
return (this.x * a.x) + (this.y * a.y);
}
/**
*
*/
public normalize(): void
{
const length: number = Math.pow((this.x * this.x) + (this.y * this.y), 0.5);
this.x = this.x / length;
this.y = this.y / length;
}
/**
*
*
*
*
* @param rhs
* @return true
* @return false
*/
public isEqual(rhs: CubismVector2): boolean
{
return (this.x == rhs.x) && (this.y == rhs.y);
}
/**
*
*
*
*
* @param rhs
* @return true
* @return false
*/
public isNotEqual(rhs: CubismVector2): boolean
{
return !(this.isEqual(rhs));
}
}
}

View File

@ -0,0 +1,312 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
import {Live2DCubismFramework as cubismmatrix44} from "./cubismmatrix44";
import CubismMatrix44 = cubismmatrix44.CubismMatrix44;
export namespace Live2DCubismFramework
{
/**
* 使便4x4
*
* 使便4x4
*/
export class CubismViewMatrix extends CubismMatrix44
{
/**
*
*/
public constructor()
{
super();
this._screenLeft = 0.0;
this._screenRight = 0.0;
this._screenTop = 0.0;
this._screenBottom = 0.0;
this._maxLeft = 0.0;
this._maxRight = 0.0;
this._maxTop = 0.0;
this._maxBottom = 0.0;
this._maxScale = 0.0;
this._minScale = 0.0;
}
/**
* 調
*
* @param x X
* @param y Y
*/
public adjustTranslate(x: number, y: number): void
{
if(this._tr[0] * this._maxLeft + (this._tr[12] + x) > this._screenLeft)
{
x = this._screenLeft - this._tr[0] * this._maxLeft - this._tr[12];
}
if(this._tr[0] * this._maxRight + (this._tr[12] + x) < this._screenRight)
{
x = this._screenRight - this._tr[0] * this._maxRight - this._tr[12];
}
if(this._tr[5] * this._maxTop + (this._tr[13] + y) < this._screenTop)
{
y = this._screenTop - this._tr[5] * this._maxTop - this._tr[13];
}
if(this._tr[5] * this._maxBottom + (this._tr[13] + y) > this._screenBottom)
{
y = this._screenBottom - this._tr[5] * this._maxBottom - this._tr[13];
}
let tr1: Float32Array = new Float32Array(
[
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
x, y, 0.0, 1.0
]
);
CubismMatrix44.multiply(tr1, this._tr, this._tr);
}
/**
* 調
*
* @param cx X
* @param cy Y
* @param scale 
*/
public adjustScale(cx: number, cy: number, scale: number): void
{
let maxScale: number = this.getMaxScale();
let minScale: number = this.getMinScale();
let targetScale = scale * this._tr[0];
if(targetScale < minScale)
{
if(this._tr[0] > 0.0)
{
scale = minScale / this._tr[0];
}
}
else if(targetScale > maxScale)
{
if(this._tr[0] > 0.0)
{
scale = maxScale / this._tr[0];
}
}
let tr1: Float32Array = new Float32Array(
[
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
cx, cy, 0.0, 1.0
]
);
let tr2: Float32Array = new Float32Array(
[
scale, 0.0, 0.0, 0.0,
0.0, scale, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0
]
);
let tr3: Float32Array = new Float32Array(
[
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
-cx, -cy, 0.0, 1.0,
]
);
CubismMatrix44.multiply(tr3, this._tr, this._tr);
CubismMatrix44.multiply(tr2, this._tr, this._tr);
CubismMatrix44.multiply(tr1, this._tr, this._tr);
}
/**
*
*
* @param left X
* @param right X
* @param bottom Y
* @param top Y
*/
public setScreenRect(left: number, right: number, bottom: number, top: number): void
{
this._screenLeft = left;
this._screenRight = right;
this._screenBottom = bottom;
this._screenTop = top;
}
/**
*
* @param left X
* @param right X
* @param bottom Y
* @param top Y
*/
public setMaxScreenRect(left: number, right: number, bottom: number, top: number): void
{
this._maxLeft = left;
this._maxRight = right;
this._maxTop = top;
this._maxBottom = bottom;
}
/**
*
* @param maxScale
*/
public setMaxScale(maxScale: number): void
{
this._maxScale = maxScale;
}
/**
*
* @param minScale
*/
public setMinScale(minScale: number): void
{
this._minScale = minScale;
}
/**
*
* @return
*/
public getMaxScale(): number
{
return this._maxScale;
}
/**
*
* @return
*/
public getMinScale(): number
{
return this._minScale;
}
/**
*
*
* @return true
* @return false
*/
public isMaxScale(): boolean
{
return this.getScaleX() >= this._maxScale;
}
/**
*
*
* @return true
* @return false
*/
public isMinScale(): boolean
{
return this.getScaleX() <= this._minScale;
}
/**
*
* @return X
*/
public getScreenLeft(): number
{
return this._screenLeft;
}
/**
*
* @return X
*/
public getScreenRight(): number
{
return this._screenRight;
}
/**
* Y
* @return Y
*/
public getScreenBottom(): number
{
return this._screenBottom;
}
/**
* Y
* @return Y
*/
public getScreenTop(): number
{
return this._screenTop;
}
/**
* X
* @return X
*/
public getMaxLeft(): number
{
return this._maxLeft;
}
/**
* X
* @return X
*/
public getMaxRight(): number
{
return this._maxRight;
}
/**
* Y
* @return Y
*/
public getMaxBottom(): number
{
return this._maxBottom;
}
/**
* Y
* @return Y
*/
public getMaxTop(): number
{
return this._maxTop;
}
private _screenLeft: number; // デバイスに対応する論理座標上の範囲左辺X軸位置
private _screenRight: number; // デバイスに対応する論理座標上の範囲右辺X軸位置
private _screenTop: number; // デバイスに対応する論理座標上の範囲上辺Y軸位置
private _screenBottom: number; // デバイスに対応する論理座標上の範囲下辺Y軸位置
private _maxLeft: number; // 論理座標上の移動可能範囲左辺X軸位置
private _maxRight: number; // 論理座標上の移動可能範囲右辺X軸位置
private _maxTop: number; // 論理座標上の移動可能範囲上辺Y軸位置
private _maxBottom: number; // 論理座標上の移動可能範囲下辺Y軸位置
private _maxScale: number; // 拡大率の最大値
private _minScale: number; // 拡大率の最小値
}
}

View File

@ -0,0 +1,106 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
import {Live2DCubismFramework as cubismmodel} from "./cubismmodel";
import CubismModel = cubismmodel.CubismModel;
import { CSM_ASSERT } from "../utils/cubismdebug";
export namespace Live2DCubismFramework
{
/**
* Moc
*
* Moc
*/
export class CubismMoc
{
/**
* Moc
*/
public static create(mocBytes: ArrayBuffer): CubismMoc
{
let cubismMoc: CubismMoc = null;
let moc: Live2DCubismCore.Moc = Live2DCubismCore.Moc.fromArrayBuffer(mocBytes);
if (moc)
{
cubismMoc = new CubismMoc(moc);
}
return cubismMoc;
}
/**
* Moc
*
* Moc
*/
public static delete(moc: CubismMoc): void
{
moc._moc._release();
moc._moc = null;
moc = null;
}
/**
*
*
* @return Moc
*/
createModel(): CubismModel
{
let cubismModel: CubismModel = null;
let model: Live2DCubismCore.Model = Live2DCubismCore.Model.fromMoc(this._moc);
if (model)
{
cubismModel = new CubismModel(model);
cubismModel.initialize();
++this._modelCount;
}
return cubismModel;
}
/**
*
*/
deleteModel(model: CubismModel): void
{
model.release();
model = void 0;
--this._modelCount;
}
/**
*
*/
private constructor(moc: Live2DCubismCore.Moc)
{
this._moc = moc;
this._modelCount = 0;
}
/**
*
*/
public release(): void
{
CSM_ASSERT(this._modelCount == 0);
this._moc._release();
this._moc = null;
}
_moc: Live2DCubismCore.Moc; ///< Mocデータ
_modelCount: number; ///< Mocデータから作られたモデルの個数
}
}

View File

@ -0,0 +1,803 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
/// <reference path="../../Core/live2dcubismcore" />
import {Live2DCubismFramework as cubismrenderer} from "../rendering/cubismrenderer";
import {Live2DCubismFramework as cubismid} from "../id/cubismid";
import {Live2DCubismFramework as cubismframework} from "../live2dcubismframework";
import {Live2DCubismFramework as csmmap} from "../type/csmmap";
import {Live2DCubismFramework as csmvector} from "../type/csmvector";
import {CSM_ASSERT} from "../utils/cubismdebug";
import CubismFramework = cubismframework.CubismFramework;
import CubismRenderer = cubismrenderer.CubismRenderer;
import csmVector = csmvector.csmVector;
import csmMap = csmmap.csmMap;
import CubismIdHandle = cubismid.CubismIdHandle;
export namespace Live2DCubismFramework
{
/**
*
*
* Moc
*/
export class CubismModel
{
/**
*
*/
public update(): void
{
// Update model
this._model.update();
this._model.drawables.resetDynamicFlags();
}
/**
*
*/
public getCanvasWidth(): number
{
if (this._model == null)
{
return 0.0;
}
return this._model.canvasinfo.CanvasWidth / this._model.canvasinfo.PixelsPerUnit;
}
/**
*
*/
public getCanvasHeight(): number
{
if (this._model == null)
{
return 0.0;
}
return this._model.canvasinfo.CanvasHeight / this._model.canvasinfo.PixelsPerUnit;
}
/**
*
*/
public saveParameters(): void
{
const parameterCount: number = this._model.parameters.count;
const savedParameterCount: number = this._savedParameters.getSize();
for (let i: number = 0; i < parameterCount; ++i)
{
if (i < savedParameterCount)
{
this._savedParameters.set(i, this._parameterValues[i]);
}
else
{
this._savedParameters.pushBack(this._parameterValues[i]);
}
}
}
/**
*
*/
public getModel(): Live2DCubismCore.Model
{
return this._model;
}
/**
*
* @param partId ID
* @return
*/
public getPartIndex(partId: CubismIdHandle): number
{
let partIndex: number;
const partCount: number = this._model.parts.count;
for(partIndex = 0; partIndex < partCount; ++partIndex)
{
if(partId == this._partIds.at(partIndex))
{
return partIndex;
}
}
// モデルに存在していない場合、非存在パーツIDリスト内にあるかを検索し、そのインデックスを返す
if(this._notExistPartId.isExist(partId))
{
return this._notExistPartId.getValue(partId);
}
// 非存在パーツIDリストにない場合、新しく要素を追加する
partIndex = partCount + this._notExistPartId.getSize();
this._notExistPartId.setValue(partId, partIndex);
this._notExistPartOpacities.appendKey(partIndex);
return partIndex;
}
/**
*
* @return
*/
public getPartCount(): number
{
const partCount: number = this._model.parts.count;
return partCount;
}
/**
* (Index)
* @param partIndex
* @param opacity
*/
public setPartOpacityByIndex(partIndex: number, opacity: number): void
{
if(this._notExistPartOpacities.isExist(partIndex))
{
this._notExistPartOpacities.setValue(partIndex,opacity);
return;
}
// インデックスの範囲内検知
CSM_ASSERT(0 <= partIndex && partIndex < this.getPartCount());
this._partOpacities[partIndex] = opacity;
}
/**
* (Id)
* @param partId ID
* @param opacity
*/
public setPartOpacityById(partId: CubismIdHandle, opacity: number): void
{
// 高速化のためにPartIndexを取得できる機構になっているが、外部からの設定の時は呼び出し頻度が低いため不要
const index: number = this.getPartIndex(partId);
if(index < 0)
{
return; // パーツがないのでスキップ
}
this.setPartOpacityByIndex(index, opacity);
}
/**
* (index)
* @param partIndex
* @return
*/
public getPartOpacityByIndex(partIndex: number): number
{
if(this._notExistPartOpacities.isExist(partIndex))
{
// モデルに存在しないパーツIDの場合、非存在パーツリストから不透明度を返す。
return this._notExistPartOpacities.getValue(partIndex);
}
// インデックスの範囲内検知
CSM_ASSERT(0 <= partIndex && partIndex < this.getPartCount());
return this._partOpacities[partIndex];
}
/**
* (id)
* @param partId
* @return
*/
public getPartOpacityById(partId: CubismIdHandle): number
{
// 高速化のためにPartIndexを取得できる機構になっているが、外部からの設定の時は呼び出し頻度が低いため不要
const index: number = this.getPartIndex(partId);
if(index < 0)
{
return 0; // パーツが無いのでスキップ
}
return this.getPartOpacityByIndex(index);
}
/**
*
* @param ID
* @return
*/
public getParameterIndex(parameterId: CubismIdHandle): number
{
let parameterIndex: number;
const idCount: number = this._model.parameters.count;
for(parameterIndex = 0; parameterIndex < idCount; ++parameterIndex)
{
if(parameterId != this._parameterIds.at(parameterIndex))
{
continue;
}
return parameterIndex;
}
// モデルに存在していない場合、非存在パラメータIDリスト内を検索し、そのインデックスを返す
if(this._notExistParameterId.isExist(parameterId))
{
return this._notExistParameterId.getValue(parameterId);
}
// 非存在パラメータIDリストにない場合新しく要素を追加する
parameterIndex = this._model.parameters.count + this._notExistParameterId.getSize();
this._notExistParameterId.setValue(parameterId, parameterIndex);
this._notExistParameterValues.appendKey(parameterIndex);
return parameterIndex;
}
/**
*
* @return
*/
public getParameterCount(): number
{
return this._model.parameters.count;
}
/**
*
* @param parameterIndex
* @return
*/
public getParameterMaximumValue(parameterIndex: number): number
{
return this._model.parameters.maximumValues[parameterIndex];
}
/**
*
* @param parameterIndex
* @return
*/
public getParameterMinimumValue(parameterIndex: number): number
{
return this._model.parameters.minimumValues[parameterIndex];
}
/**
*
* @param parameterIndex
* @return
*/
public getParameterDefaultValue(parameterIndex: number): number
{
return this._model.parameters.defaultValues[parameterIndex];
}
/**
*
* @param parameterIndex
* @return
*/
public getParameterValueByIndex(parameterIndex: number): number
{
if(this._notExistParameterValues.isExist(parameterIndex))
{
return this._notExistParameterValues.getValue(parameterIndex);
}
// インデックスの範囲内検知
CSM_ASSERT(0 <= parameterIndex && parameterIndex < this.getParameterCount());
return this._parameterValues[parameterIndex];
}
/**
*
* @param parameterId ID
* @return
*/
public getParameterValueById(parameterId: CubismIdHandle): number
{
// 高速化のためにparameterIndexを取得できる機構になっているが、外部からの設定の時は呼び出し頻度が低いため不要
const parameterIndex: number = this.getParameterIndex(parameterId);
return this.getParameterValueByIndex(parameterIndex);
}
/**
*
* @param parameterIndex
* @param value
* @param weight
*/
public setParameterValueByIndex(parameterIndex: number, value: number, weight: number = 1.0): void
{
if(this._notExistParameterValues.isExist(parameterIndex))
{
this._notExistParameterValues.setValue(
parameterIndex,
(weight == 1)
? value
: (this._notExistParameterValues.getValue(parameterIndex) * (1 - weight)) + (value * weight)
);
return;
}
// インデックスの範囲内検知
CSM_ASSERT(0 <= parameterIndex && parameterIndex < this.getParameterCount());
if(this._model.parameters.maximumValues[parameterIndex] < value)
{
value = this._model.parameters.maximumValues[parameterIndex];
}
if(this._model.parameters.minimumValues[parameterIndex] > value)
{
value = this._model.parameters.minimumValues[parameterIndex];
}
this._parameterValues[parameterIndex] = (weight == 1)
? value
: this._parameterValues[parameterIndex] = (this._parameterValues[parameterIndex] * (1 - weight)) + (value * weight);
}
/**
*
* @param parameterId ID
* @param value
* @param weight
*/
public setParameterValueById(parameterId: CubismIdHandle, value: number, weight: number = 1.0): void
{
const index: number = this.getParameterIndex(parameterId);
this.setParameterValueByIndex(index, value, weight);
}
/**
* (index)
* @param parameterIndex
* @param value
* @param weight
*/
public addParameterValueByIndex(parameterIndex: number, value: number, weight: number = 1.0): void
{
this.setParameterValueByIndex(parameterIndex, (this.getParameterValueByIndex(parameterIndex) + (value * weight)));
}
/**
* (id)
* @param parameterId
* @param value
* @param weight
*/
public addParameterValueById(parameterId: any, value: number, weight: number = 1.0): void
{
const index: number = this.getParameterIndex(parameterId);
this.addParameterValueByIndex(index, value, weight);
}
/**
*
* @param parameterId ID
* @param value
* @param weight
*/
public multiplyParameterValueById(parameterId: CubismIdHandle, value: number, weight: number = 1.0): void
{
const index: number = this.getParameterIndex(parameterId);
this.multiplyParameterValueByIndex(index, value, weight);
}
/**
*
* @param parameterIndex
* @param value 
* @param weight
*/
public multiplyParameterValueByIndex(parameterIndex: number, value: number, weight: number = 1.0): void
{
this.setParameterValueByIndex(parameterIndex, (this.getParameterValueByIndex(parameterIndex) * (1.0 + (value - 1.0) * weight)));
}
/**
* Drawable
* @param drawableId DrawableID
* @return Drawable
*/
public getDrawableIndex(drawableId: CubismIdHandle): number
{
const drawableCount = this._model.drawables.count;
for(let drawableIndex: number = 0; drawableIndex < drawableCount; ++drawableIndex)
{
if(this._drawableIds.at(drawableIndex) == drawableId)
{
return drawableIndex;
}
}
return -1;
}
/**
* Drawable
* @return drawable
*/
public getDrawableCount(): number
{
const drawableCount = this._model.drawables.count;
return drawableCount;
}
/**
* DrawableID
* @param drawableIndex Drawable
* @return drawableID
*/
public getDrawableId(drawableIndex: number): CubismIdHandle
{
const parameterIds: string[] = this._model.drawables.ids;
return CubismFramework.getIdManager().getId(parameterIds[drawableIndex]);
}
/**
* Drawable
* @return Drawable
*/
public getDrawableRenderOrders(): Int32Array
{
const renderOrders: Int32Array = this._model.drawables.renderOrders;
return renderOrders;
}
/**
* Drawable
* @param drawableIndex Drawable
* @return drawable
*/
public getDrawableTextureIndices(drawableIndex: number): number
{
const textureIndices: Int32Array = this._model.drawables.textureIndices;
return textureIndices[drawableIndex];
}
/**
* DrawableVertexPositions
*
* CubismModel.updateDrawable
*
* @param drawableIndex Drawable
* @retval true DrawableCubismModel.update
* @retval false DrawableCubismModel.update
*/
public getDrawableDynamicFlagVertexPositionsDidChange(drawableIndex: number): boolean
{
const dynamicFlags: Uint8Array = this._model.drawables.dynamicFlags;
return Live2DCubismCore.Utils.hasVertexPositionsDidChangeBit(dynamicFlags[drawableIndex]);
}
/**
* Drawable
* @param drawableIndex Drawable
* @return drawable
*/
public getDrawableVertexIndexCount(drawableIndex: number): number
{
const indexCounts: Int32Array = this._model.drawables.indexCounts;
return indexCounts[drawableIndex];
}
/**
* Drawable
* @param drawableIndex Drawable
* @return drawable
*/
public getDrawableVertexCount(drawableIndex: number): number
{
const vertexCounts = this._model.drawables.vertexCounts;
return vertexCounts[drawableIndex];
}
/**
* Drawable
* @param drawableIndex drawable
* @return drawable
*/
public getDrawableVertices(drawableIndex: number): Float32Array
{
return this.getDrawableVertexPositions(drawableIndex);
}
/**
* Drawable
* @param drarableIndex Drawable
* @return drawable
*/
public getDrawableVertexIndices(drawableIndex: number): Uint16Array
{
const indicesArray: Uint16Array[] = this._model.drawables.indices;
return indicesArray[drawableIndex];
}
/**
* Drawable
* @param drawableIndex Drawable
* @return drawable
*/
public getDrawableVertexPositions(drawableIndex: number): Float32Array
{
const verticesArray: Float32Array[] = this._model.drawables.vertexPositions;
return verticesArray[drawableIndex];
}
/**
* DrawableUV
* @param drawableIndex Drawable
* @return drawableUV
*/
public getDrawableVertexUvs(drawableIndex: number): Float32Array
{
const uvsArray: Float32Array[] = this._model.drawables.vertexUvs;
return uvsArray[drawableIndex];
}
/**
* Drawable
* @param drawableIndex Drawable
* @return drawable
*/
public getDrawableOpacity(drawableIndex: number): number
{
const opacities: Float32Array = this._model.drawables.opacities;
return opacities[drawableIndex];
}
/**
* Drawable
* @param drawableIndex Drawable
* @return drawable
*/
public getDrawableCulling(drawableIndex: number): boolean
{
const constantFlags = this._model.drawables.constantFlags;
return !Live2DCubismCore.Utils.hasIsDoubleSidedBit(constantFlags[drawableIndex]);
}
/**
* Drawable
* @param drawableIndex Drawable
* @return drawable
*/
public getDrawableBlendMode(drawableIndex: number): CubismRenderer.CubismBlendMode
{
const constantFlags = this._model.drawables.constantFlags;
return (Live2DCubismCore.Utils.hasBlendAdditiveBit(constantFlags[drawableIndex]))
? CubismRenderer.CubismBlendMode.CubismBlendMode_Additive
: (Live2DCubismCore.Utils.hasBlendMultiplicativeBit(constantFlags[drawableIndex]))
? CubismRenderer.CubismBlendMode.CubismBlendMode_Multiplicative
: CubismRenderer.CubismBlendMode.CubismBlendMode_Normal;
}
/**
* Drawable
* @return Drawable
*/
public getDrawableMasks(): Int32Array[]
{
const masks: Int32Array[] = this._model.drawables.masks;
return masks;
}
/**
* Drawable
* @return Drawable
*/
public getDrawableMaskCounts(): Int32Array
{
const maskCounts: Int32Array = this._model.drawables.maskCounts;
return maskCounts;
}
/**
* 使
*
* @return true 使
* @return false 使
*/
public isUsingMasking(): boolean
{
for(let d: number = 0; d < this._model.drawables.count; ++d)
{
if(this._model.drawables.maskCounts[d] <= 0)
{
continue;
}
return true;
}
return false;
}
/**
* Drawable
*
* @param drawableIndex Drawable
* @return true Drawable
* @return false Drawable
*/
public getDrawableDynamicFlagIsVisible(drawableIndex: number): boolean
{
const dynamicFlags: Uint8Array = this._model.drawables.dynamicFlags;
return Live2DCubismCore.Utils.hasIsVisibleBit(dynamicFlags[drawableIndex]);
}
/**
* DrawableDrawOrder
*
* CubismModel.updatedrawabledrawOrder
* drawOrderartMesh01000
* @param drawableIndex drawable
* @return true drawableCubismModel.update
* @return false drawableCubismModel.update
*/
public getDrawableDynamicFlagVisibilityDidChange(drawableIndex: number): boolean
{
const dynamicFlags: Uint8Array = this._model.drawables.dynamicFlags;
return Live2DCubismCore.Utils.hasVisibilityDidChangeBit(dynamicFlags[drawableIndex]);
}
/**
* Drawable
*
* CubismModel.updatedrawable
*
* @param drawableIndex drawable
* @return true DrawableCubismModel.update
* @return false DrawableCubismModel.update
*/
public getDrawableDynamicFlagOpacityDidChange(drawableIndex: number): boolean
{
const dynamicFlags: Uint8Array = this._model.drawables.dynamicFlags;
return Live2DCubismCore.Utils.hasOpacityDidChangeBit(dynamicFlags[drawableIndex]);
}
/**
* Drawable
*
* CubismModel.updateDrawable
*
* @param drawableIndex Drawable
* @return true DrawableCubismModel.update
* @return false DrawableCubismModel.update
*/
public getDrawableDynamicFlagRenderOrderDidChange(drawableIndex: number): boolean
{
const dynamicFlags: Uint8Array = this._model.drawables.dynamicFlags;
return Live2DCubismCore.Utils.hasRenderOrderDidChangeBit(dynamicFlags[drawableIndex]);
}
/**
*
*/
public loadParameters(): void
{
let parameterCount: number = this._model.parameters.count;
const savedParameterCount: number = this._savedParameters.getSize();
if(parameterCount > savedParameterCount)
{
parameterCount = savedParameterCount;
}
for(let i: number = 0; i < parameterCount; ++i)
{
this._parameterValues[i] = this._savedParameters.at(i);
}
}
/**
*
*/
public initialize(): void
{
CSM_ASSERT(this._model);
this._parameterValues = this._model.parameters.values;
this._partOpacities = this._model.parts.opacities;
this._parameterMaximumValues = this._model.parameters.maximumValues;
this._parameterMinimumValues = this._model.parameters.minimumValues;
{
const parameterIds: string[] = this._model.parameters.ids;
const parameterCount: number = this._model.parameters.count;
for(let i: number = 0; i < parameterCount; ++i)
{
this._parameterIds.pushBack(CubismFramework.getIdManager().getId(parameterIds[i]));
}
}
{
const partIds: string[] = this._model.parts.ids;
const partCount: number = this._model.parts.count;
for(let i: number = 0; i < partCount; ++i)
{
this._partIds.pushBack(CubismFramework.getIdManager().getId(partIds[i]));
}
}
{
const drawableIds: string[] = this._model.drawables.ids;
const drawableCount: number = this._model.drawables.count;
for(let i: number = 0; i < drawableCount; ++i)
{
this._drawableIds.pushBack(CubismFramework.getIdManager().getId(drawableIds[i]));
}
}
}
/**
*
* @param model
*/
public constructor(model: Live2DCubismCore.Model)
{
this._model = model;
this._parameterValues = null;
this._parameterMaximumValues = null;
this._parameterMinimumValues = null;
this._partOpacities = null;
this._savedParameters = new csmVector<number>();
this._parameterIds = new csmVector<CubismIdHandle>();
this._drawableIds = new csmVector<CubismIdHandle>();
this._partIds = new csmVector<CubismIdHandle>();
this._notExistPartId = new csmMap<CubismIdHandle, number>();
this._notExistParameterId = new csmMap<CubismIdHandle, number>();
this._notExistParameterValues = new csmMap<number, number>();
this._notExistPartOpacities = new csmMap<number, number>();
}
/**
*
*/
public release(): void
{
this._model.release();
this._model = null;
}
private _notExistPartOpacities: csmMap<number, number>; // 存在していないパーツの不透明度のリスト
private _notExistPartId: csmMap<CubismIdHandle, number>; // 存在していないパーツIDのリスト
private _notExistParameterValues: csmMap<number, number>; // 存在していないパラメータの値のリスト
private _notExistParameterId: csmMap<CubismIdHandle, number>; // 存在していないパラメータIDのリスト
private _savedParameters: csmVector<number>; // 保存されたパラメータ
private _model: Live2DCubismCore.Model; // モデル
private _parameterValues: Float32Array; // パラメータの値のリスト
private _parameterMaximumValues: Float32Array; // パラメータの最大値のリスト
private _parameterMinimumValues: Float32Array; // パラメータの最小値のリスト
private _partOpacities: Float32Array; // パーツの不透明度のリスト
private _parameterIds: csmVector<CubismIdHandle>;
private _partIds: csmVector<CubismIdHandle>;
private _drawableIds: csmVector<CubismIdHandle>;
}
}

View File

@ -0,0 +1,139 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
import {Live2DCubismFramework as cubismmodeluserdatajson} from "./cubismmodeluserdatajson";
import {Live2DCubismFramework as cubismid} from "../id/cubismid";
import {Live2DCubismFramework as csmstring} from "../type/csmstring";
import {Live2DCubismFramework as csmvector} from "../type/csmvector";
import {Live2DCubismFramework as cubismframework} from "../live2dcubismframework";
import CubismFramework = cubismframework.CubismFramework;
import csmVector = csmvector.csmVector;
import csmString = csmstring.csmString;
import CubismIdHandle = cubismid.CubismIdHandle;
import CubismModelUserDataJson = cubismmodeluserdatajson.CubismModelUserDataJson;
export namespace Live2DCubismFramework
{
const ArtMesh: string = "ArtMesh";
/**
*
*
* Json
*/
export class CubismModelUserDataNode
{
targetType: CubismIdHandle; // ユーザーデータターゲットタイプ
targetId: CubismIdHandle; // ユーザーデータターゲットのID
value: csmString; // ユーザーデータ
}
/**
*
*
*
*/
export class CubismModelUserData
{
/**
*
*
* @param buffer userdata3.json
* @param size
* @return
*/
public static create(buffer: ArrayBuffer, size: number): CubismModelUserData
{
let ret: CubismModelUserData = new CubismModelUserData();
ret.parseUserData(buffer, size);
return ret;
}
/**
*
*
* @param modelUserData
*/
public static delete(modelUserData: CubismModelUserData): void
{
modelUserData.release();
modelUserData = void 0;
modelUserData = null;
}
/**
* ArtMesh
*
* @return
*/
public getArtMeshUserDatas(): csmVector<CubismModelUserDataNode>
{
return this._artMeshUserDataNode;
}
/**
* userdata3.json
*
* @param buffer userdata3.json
* @param size
*/
public parseUserData(buffer: ArrayBuffer, size: number): void
{
let json: CubismModelUserDataJson = new CubismModelUserDataJson(buffer, size);
const typeOfArtMesh = CubismFramework.getIdManager().getId(ArtMesh);
const nodeCount: number = json.getUserDataCount();
for(let i: number = 0; i < nodeCount; i++)
{
let addNode: CubismModelUserDataNode = new CubismModelUserDataNode();
addNode.targetId = json.getUserDataId(i);
addNode.targetType = CubismFramework.getIdManager().getId(json.getUserDataTargetType(i));
addNode.value = new csmString(json.getUserDataValue(i));
this._userDataNodes.pushBack(addNode);
if(addNode.targetType == typeOfArtMesh)
{
this._artMeshUserDataNode.pushBack(addNode);
}
}
json.release();
json = void 0;
}
/**
*
*/
public constructor()
{
this._userDataNodes = new csmVector<CubismModelUserDataNode>();
this._artMeshUserDataNode = new csmVector<CubismModelUserDataNode>();
}
/**
*
*
*
*/
public release(): void
{
for(let i: number = 0; i < this._userDataNodes.getSize(); ++i)
{
this._userDataNodes.set(i, void 0);
}
this._userDataNodes = null;
}
private _userDataNodes: csmVector<CubismModelUserDataNode>; // ユーザーデータ構造体配列
private _artMeshUserDataNode: csmVector<CubismModelUserDataNode>; // 閲覧リストの保持
}
}

View File

@ -0,0 +1,99 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
import {Live2DCubismFramework as cubismjson} from "../utils/cubismjson";
import {Live2DCubismFramework as cubismid} from "../id/cubismid";
import {Live2DCubismFramework as cubismframework} from "../live2dcubismframework";
import CubismFramework = cubismframework.CubismFramework;
import CubismIdHandle = cubismid.CubismIdHandle;
import CubismJson = cubismjson.CubismJson;
export namespace Live2DCubismFramework
{
const Meta: string = "Meta";
const UserDataCount: string = "UserDataCount";
const TotalUserDataSize: string = "TotalUserDataSize";
const UserData: string = "UserData";
const Target: string = "Target";
const Id: string = "Id";
const Value: string = "Value";
export class CubismModelUserDataJson
{
/**
*
* @param buffer userdata3.json
* @param size
*/
public constructor(buffer: ArrayBuffer, size: number)
{
this._json = CubismJson.create(buffer, size);
}
/**
*
*/
public release(): void
{
CubismJson.delete(this._json);
}
/**
*
* @return
*/
public getUserDataCount(): number
{
return this._json.getRoot().getMap().getValue(Meta).getMap().getValue(UserDataCount).toInt();
}
/**
*
*
* @return
*/
public getTotalUserDataSize(): number
{
return this._json.getRoot().getMap().getValue(Meta).getMap().getValue(TotalUserDataSize).toInt();
}
/**
*
*
* @return
*/
public getUserDataTargetType(i: number): string
{
return this._json.getRoot().getMap().getValue(UserData).getVector().at(i).getMap().getValue(Target).getRawString();
}
/**
* ID
*
* @param i
* @return ID
*/
public getUserDataId(i: number): CubismIdHandle
{
return CubismFramework.getIdManager().getId(this._json.getRoot().getMap().getValue(UserData).getVector().at(i).getMap().getValue(Id).getRawString());
}
/**
*
*
* @param i
* @return
*/
public getUserDataValue(i: number): string
{
return this._json.getRoot().getMap().getValue(UserData).getVector().at(i).getMap().getValue(Value).getRawString();
}
private _json: CubismJson;
}
}

View File

@ -0,0 +1,466 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
import {Live2DCubismFramework as cubismframework} from "../live2dcubismframework";
import {Live2DCubismFramework as cubismmotionmanager} from "../motion/cubismmotionmanager";
import {Live2DCubismFramework as cubismtargetpoint} from "../math/cubismtargetpoint";
import {Live2DCubismFramework as cubismmodelmatrix} from "../math/cubismmodelmatrix";
import {Live2DCubismFramework as cubismmoc} from "./cubismmoc";
import {Live2DCubismFramework as cubismmodel} from "./cubismmodel";
import {Live2DCubismFramework as acubismmotion} from "../motion/acubismmotion";
import {Live2DCubismFramework as cubismmotion} from "../motion/cubismmotion";
import {Live2DCubismFramework as cubismexpressionmotion} from "../motion/cubismexpressionmotion";
import {Live2DCubismFramework as cubismpose} from "../effect/cubismpose";
import {Live2DCubismFramework as cubismmodeluserdata} from "./cubismmodeluserdata";
import {Live2DCubismFramework as cubismphysics} from "../physics/cubismphysics";
import {Live2DCubismFramework as cubismid} from "../id/cubismid";
import {Live2DCubismFramework as csmstring} from "../type/csmstring";
import {Live2DCubismFramework as cubismmotionqueuemanager} from "../motion/cubismmotionqueuemanager";
import {Live2DCubismFramework as cubismbreath} from "../effect/cubismbreath";
import {Live2DCubismFramework as cubismeyeblink} from "../effect/cubismeyeblink";
import {Live2DCubismFramework as cubismrenderer_webgl} from "../rendering/cubismrenderer_WebGL";
import {CubismLogError, CubismLogInfo} from "../utils/cubismdebug";
import CubismRenderer_WebGL = cubismrenderer_webgl.CubismRenderer_WebGL;
import CubismEyeBlink = cubismeyeblink.CubismEyeBlink;
import CubismBreath = cubismbreath.CubismBreath;
import CubismMotionQueueManager = cubismmotionqueuemanager.CubismMotionQueueManager;
import csmString = csmstring.csmString;
import Constant = cubismframework.Constant;
import CubismIdHandle = cubismid.CubismIdHandle;
import CubismPhysics = cubismphysics.CubismPhysics;
import CubismModelUserData = cubismmodeluserdata.CubismModelUserData;
import CubismPose = cubismpose.CubismPose;
import CubismExpressionMotion = cubismexpressionmotion.CubismExpressionMotion;
import CubismMotion = cubismmotion.CubismMotion;
import ACubismMotion = acubismmotion.ACubismMotion;
import CubismModel = cubismmodel.CubismModel;
import CubismMoc = cubismmoc.CubismMoc;
import CubismModelMatrix = cubismmodelmatrix.CubismModelMatrix;
import CubismTargetPoint = cubismtargetpoint.CubismTargetPoint;
import CubismMotionManager = cubismmotionmanager.CubismMotionManager;
export namespace Live2DCubismFramework
{
/**
* 使
*
* 使
*/
export class CubismUserModel
{
/**
*
*
*
*
* @return true
* @return false
*/
public isInitialized(): boolean
{
return this._initialized;
}
/**
*
*
*
*
* @param v
*/
public setInitialized(v: boolean): void
{
this._initialized = v;
}
/**
*
*
*
*
* @return true
* @return false
*/
public isUpdating(): boolean
{
return this._updating;
}
/**
*
*
*
*
* @param v
*/
public setUpdating(v: boolean): void
{
this._updating = v;
}
/**
*
* @param X
* @param Y
*/
public setDragging(x: number, y: number): void
{
this._dragManager.set(x, y);
}
/**
*
* @param x X
* @param y Y
* @param z Z
*/
public setAcceleration(x: number, y: number, z: number): void
{
this._accelerationX = x;
this._accelerationY = y;
this._accelerationZ = z;
}
/**
*
* @return
*/
public getModelMatrix(): CubismModelMatrix
{
return this._modelMatrix;
}
/**
*
* @param a
*/
public setOpacity(a: number): void
{
this._opacity = a;
}
/**
*
* @return
*/
public getOpacity(): number
{
return this._opacity;
}
/**
*
*
* @param buffer moc3
*/
public loadModel(buffer: ArrayBuffer)
{
this._moc = CubismMoc.create(buffer);
this._model = this._moc.createModel();
this._model.saveParameters();
if ((this._moc == null) || (this._model == null))
{
CubismLogError("Failed to CreateModel().");
return;
}
this._modelMatrix = new CubismModelMatrix(this._model.getCanvasWidth(), this._model.getCanvasHeight());
}
/**
*
* @param buffer motion3.json
* @param size
* @param name
* @return
*/
public loadMotion(buffer: ArrayBuffer, size: number, name: string): ACubismMotion
{
return CubismMotion.create(buffer, size);
}
/**
*
* @param buffer exp
* @param size
* @param name
*/
public loadExpression(buffer: ArrayBuffer, size: number, name: string): ACubismMotion
{
return CubismExpressionMotion.create(buffer, size);
}
/**
*
* @param buffer pose3.json
* @param size
*/
public loadPose(buffer: ArrayBuffer, size: number): void
{
this._pose = CubismPose.create(buffer, size);
}
/**
*
* @param buffer userdata3.json
* @param size
*/
public loadUserData(buffer: ArrayBuffer, size: number): void
{
this._modelUserData = CubismModelUserData.create(buffer, size);
}
/**
*
* @param buffer physics3.json
* @param size
*/
public loadPhysics(buffer: ArrayBuffer, size: number): void
{
this._physics = CubismPhysics.create(buffer, size);
}
/**
*
* @param drawableId DrawableID
* @param pointX X
* @param pointY Y
* @return true
* @return false
*/
public isHit(drawableId: CubismIdHandle, pointX: number, pointY: number): boolean
{
const drawIndex: number = this._model.getDrawableIndex(drawableId);
if(drawIndex < 0)
{
return false; // 存在しない場合はfalse
}
const count: number = this._model.getDrawableVertexCount(drawIndex);
const vertices: Float32Array = this._model.getDrawableVertices(drawIndex);
let left: number = vertices[0];
let right: number = vertices[0];
let top: number = vertices[1];
let bottom: number = vertices[1];
for(let j: number = 1; j < count; ++j)
{
let x = vertices[Constant.vertexOffset + j * Constant.vertexStep];
let y = vertices[Constant.vertexOffset + j * Constant.vertexStep + 1];
if(x < left)
{
left = x; // Min x
}
if(x > right)
{
right = x; // Max x
}
if(y < top)
{
top = y; // Min y
}
if(y > bottom)
{
bottom = y; // Max y
}
}
const tx: number = this._modelMatrix.invertTransformX(pointX);
const ty: number = this._modelMatrix.invertTransformY(pointY);
return ((left <= tx) && (tx <= right) && (top <= ty) && (ty <= bottom));
}
/**
*
* @return
*/
public getModel(): CubismModel
{
return this._model;
}
/**
*
* @return
*/
public getRenderer(): CubismRenderer_WebGL
{
return this._renderer;
}
/**
*
*/
public createRenderer(): void
{
if(this._renderer)
{
this.deleteRenderer();
}
this._renderer = new CubismRenderer_WebGL();
this._renderer.initialize(this._model);
}
/**
*
*/
public deleteRenderer(): void
{
if(this._renderer)
{
this._renderer = void 0;
this._renderer = null;
}
}
/**
*
*
* Event
*
*
*
* @param eventValue
*/
public motionEventFired(eventValue: csmString): void
{
CubismLogInfo("{0}", eventValue.s);
}
/**
*
*
* CubismMotionQueueManagerCallback
* CubismUserModelEventFired
*
* @param caller
* @param eventValue
* @param customData CubismUserModel
*/
public static cubismDefaultMotionEventCallback(caller: CubismMotionQueueManager, eventValue: csmString, customData: CubismUserModel): void
{
let model: CubismUserModel = customData;
if(model != null)
{
model.motionEventFired(eventValue);
}
}
/**
*
*/
public constructor()
{
// 各変数初期化
this._moc = null;
this._model = null;
this._motionManager = null;
this._expressionManager = null;
this._eyeBlink = null;
this._breath = null;
this._modelMatrix = null;
this._pose = null;
this._dragManager = null;
this._physics = null;
this._modelUserData = null;
this._initialized = false;
this._updating = false;
this._opacity = 1.0;
this._lipsync = true;
this._lastLipSyncValue = 0.0;
this._dragX = 0.0;
this._dragY = 0.0;
this._accelerationX = 0.0;
this._accelerationY = 0.0;
this._accelerationZ = 0.0;
this._debugMode = false;
this._renderer = null;
// モーションマネージャーを作成
this._motionManager = new CubismMotionManager();
this._motionManager.setEventCallback(CubismUserModel.cubismDefaultMotionEventCallback, this);
// 表情マネージャーを作成
this._expressionManager = new CubismMotionManager();
// ドラッグによるアニメーション
this._dragManager = new CubismTargetPoint();
}
/**
*
*/
public release()
{
this._motionManager.release();
this._motionManager = void 0;
this._motionManager = null;
this._expressionManager.release();
this._expressionManager = void 0;
this._expressionManager = null;
this._moc.deleteModel(this._model);
this._moc.release();
this._moc = void 0;
this._moc = null;
this._modelMatrix = void 0;
this._modelMatrix = null;
CubismPose.delete(this._pose);
CubismEyeBlink.delete(this._eyeBlink);
CubismBreath.delete(this._breath);
this._dragManager = void 0;
this._dragManager = null;
CubismPhysics.delete(this._physics);
CubismModelUserData.delete(this._modelUserData);
this.deleteRenderer();
}
protected _moc: CubismMoc; // Mocデータ
protected _model: CubismModel; // Modelインスタンス
protected _motionManager: CubismMotionManager; // モーション管理
protected _expressionManager: CubismMotionManager; // 表情管理
protected _eyeBlink: CubismEyeBlink; // 自動まばたき
protected _breath: CubismBreath; // 呼吸
protected _modelMatrix: CubismModelMatrix; // モデル行列
protected _pose: CubismPose; // ポーズ管理
protected _dragManager: CubismTargetPoint; // マウスドラッグ
protected _physics: CubismPhysics; // 物理演算
protected _modelUserData: CubismModelUserData; // ユーザーデータ
protected _initialized: boolean; // 初期化されたかどうか
protected _updating: boolean; // 更新されたかどうか
protected _opacity: number; // 不透明度
protected _lipsync: boolean; // リップシンクするかどうか
protected _lastLipSyncValue: number; // 最後のリップシンクの制御地
protected _dragX: number; // マウスドラッグのX位置
protected _dragY: number; // マウスドラッグのY位置
protected _accelerationX: number; // X軸方向の加速度
protected _accelerationY: number; // Y軸方向の加速度
protected _accelerationZ: number; // Z軸方向の加速度
protected _debugMode: boolean; // デバッグモードかどうか
private _renderer: CubismRenderer_WebGL; // レンダラ
}
}

View File

@ -0,0 +1,239 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
import {Live2DCubismFramework as cubismmath} from '../math/cubismmath';
import {Live2DCubismFramework as cubismmodel} from '../model/cubismmodel';
import {Live2DCubismFramework as cubismmotionqueueentry} from './cubismmotionqueueentry';
import {Live2DCubismFramework as csmstring} from '../type/csmstring';
import {Live2DCubismFramework as csmvector} from '../type/csmvector';
import { CSM_ASSERT } from '../utils/cubismdebug';
import csmVector = csmvector.csmVector;
import csmString = csmstring.csmString;
import CubismMotionQueueEntry = cubismmotionqueueentry.CubismMotionQueueEntry;
import CubismModel = cubismmodel.CubismModel;
import CubismMath = cubismmath.CubismMath;
export namespace Live2DCubismFramework
{
/**
*
*
* MotionQueueManager
*/
export abstract class ACubismMotion
{
/**
*
*/
public static delete(motion: ACubismMotion): void
{
motion.release();
motion = void 0;
motion = null;
}
/**
*
*/
public constructor()
{
this._fadeInSeconds = -1.0;
this._fadeOutSeconds = -1.0;
this._weight = 1.0;
this._offsetSeconds = 0.0; // 再生の開始時刻
this._firedEventValues = new csmVector<csmString>();
}
/**
*
*/
public release(): void
{
this._weight = 0.0;
}
/**
*
* @param model
* @param motionQueueEntry CubismMotionQueueManager
* @param userTimeSeconds []
*/
public updateParameters(model: CubismModel, motionQueueEntry: CubismMotionQueueEntry, userTimeSeconds: number): void
{
if(!motionQueueEntry.isAvailable() || motionQueueEntry.isFinished())
{
return;
}
if(!motionQueueEntry.isStarted())
{
motionQueueEntry.setIsStarted(true);
motionQueueEntry.setStartTime(userTimeSeconds - this._offsetSeconds); // モーションの開始時刻を記録
motionQueueEntry.setFadeInStartTime(userTimeSeconds); // フェードインの開始時刻
const duration: number = this.getDuration();
if(motionQueueEntry.getEndTime() < 0)
{
// 開始していないうちに終了設定している場合がある。
motionQueueEntry.setEndTime((duration <= 0) ? -1 : motionQueueEntry.getStartTime() + duration);
// duration == -1 の場合はループする
}
}
let fadeWeight: number = this._weight; // 現在の値と掛け合わせる割合
//---- フェードイン・アウトの処理 ----
// 単純なサイン関数でイージングする
const fadeIn: number = this._fadeInSeconds == 0.0
? 1.0
: CubismMath.getEasingSine((userTimeSeconds - motionQueueEntry.getFadeInStartTime()) / this._fadeInSeconds);
const fadeOut: number = (this._fadeOutSeconds == 0.0 || motionQueueEntry.getEndTime() < 0.0)
? 1.0
: CubismMath.getEasingSine((motionQueueEntry.getEndTime() - userTimeSeconds) / this._fadeOutSeconds);
fadeWeight = fadeWeight * fadeIn * fadeOut;
motionQueueEntry.setState(userTimeSeconds, fadeWeight);
CSM_ASSERT(0.0 <= fadeWeight && fadeWeight <= 1.0);
//---- 全てのパラメータIDをループする ----
this.doUpdateParameters(model, userTimeSeconds, fadeWeight, motionQueueEntry);
// 後処理
// 終了時刻を過ぎたら終了フラグを立てる(CubismMotionQueueManager)
if((motionQueueEntry.getEndTime() > 0) && (motionQueueEntry.getEndTime() < userTimeSeconds))
{
motionQueueEntry.setIsFinished(true); // 終了
}
}
/**
*
* @param fadeInSeconds []
*/
public setFadeInTime(fadeInSeconds: number): void
{
this._fadeInSeconds = fadeInSeconds;
}
/**
*
* @param fadeOutSeconds []
*/
public setFadeOutTime(fadeOutSeconds: number): void
{
this._fadeOutSeconds = fadeOutSeconds;
}
/**
*
* @return []
*/
public getFadeOutTime(): number
{
return this._fadeOutSeconds;
}
/**
*
* @return []
*/
public getFadeInTime(): number
{
return this._fadeInSeconds;
}
/**
*
* @param weight 0.0 - 1.0
*/
public setWeight(weight: number): void
{
this._weight = weight;
}
/**
*
* @return 0.0 - 1.0
*/
public getWeight(): number
{
return this._weight;
}
/**
*
* @return []
*
* @note -1
*
*
* -1
*/
public getDuration(): number
{
return -1.0;
}
/**
* 1
* @return []
*
* @note getDuration()
* ()-1
*/
public getLoopDuration(): number
{
return -1.0;
}
/**
*
* @param offsetSeconds []
*/
public setOffsetTime(offsetSeconds: number): void
{
this._offsetSeconds = offsetSeconds;
}
/**
*
*
*
*
*
* @param beforeCheckTimeSeconds []
* @param motionTimeSeconds []
*/
public getFiredEvent(beforeCheckTimeSeconds: number, motionTimeSeconds: number): csmVector<csmString>
{
return this._firedEventValues;
}
/**
*
* @param model
* @param userTimeSeconds []
* @param weight
* @param motionQueueEntry CubismMotionQueueManager
* @return true
* @return false
*/
public abstract doUpdateParameters(model: CubismModel, userTimeSeconds: number, weight: number, motionQueueEntry: CubismMotionQueueEntry): void;
public _fadeInSeconds: number; // フェードインにかかる時間[秒]
public _fadeOutSeconds: number; // フェードアウトにかかる時間[秒]
public _weight: number; // モーションの重み
public _offsetSeconds: number; // モーション再生の開始時間[秒]
public _firedEventValues: csmVector<csmString>;
}
}

View File

@ -0,0 +1,189 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
import {Live2DCubismFramework as acubismmotion} from './acubismmotion';
import {Live2DCubismFramework as cubismjson} from '../utils/cubismjson';
import {Live2DCubismFramework as cubismid} from '../id/cubismid';
import {Live2DCubismFramework as cubismframework} from '../live2dcubismframework';
import {Live2DCubismFramework as cubismmodel} from '../model/cubismmodel';
import {Live2DCubismFramework as cubismmotionqueueentry} from './cubismmotionqueueentry';
import {Live2DCubismFramework as csmvector} from '../type/csmvector';
import JsonFloat = cubismjson.JsonFloat;
import csmVector = csmvector.csmVector;
import CubismMotionQueueEntry = cubismmotionqueueentry.CubismMotionQueueEntry;
import CubismModel = cubismmodel.CubismModel;
import CubismFramework = cubismframework.CubismFramework;
import CubismIdHandle = cubismid.CubismIdHandle;
import CubismJson = cubismjson.CubismJson;
import Value = cubismjson.Value;
import ACubismMotion = acubismmotion.ACubismMotion;
export namespace Live2DCubismFramework
{
// exp3.jsonのキーとデフォルト
const ExpressionKeyFadeIn: string = "FadeInTime";
const ExpressionKeyFadeOut: string = "FadeOutTime";
const ExpressionKeyParameters: string = "Parameters";
const ExpressionKeyId: string = "Id";
const ExpressionKeyValue: string = "Value";
const ExpressionKeyBlend: string = "Blend";
const BlendValueAdd: string = "Add";
const BlendValueMultiply: string = "Multiply";
const BlendValueOverwrite: string = "Overwrite";
const DefaultFadeTime: number = 1.0;
/**
*
*
*
*/
export class CubismExpressionMotion extends ACubismMotion
{
/**
*
* @param buffer exp
* @param size
* @return
*/
public static create(buffer: ArrayBuffer, size: number): CubismExpressionMotion
{
let expression: CubismExpressionMotion = new CubismExpressionMotion();
let json: CubismJson = CubismJson.create(buffer, size);
let root: Value = json.getRoot();
// typescriptではnullを許容していないため仮の値を入れる
if(root.getMap().getValue(ExpressionKeyFadeIn) == null)
{
root.getMap().setValue(ExpressionKeyFadeIn, new JsonFloat(DefaultFadeTime));
}
if(root.getMap().getValue(ExpressionKeyFadeOut) == null)
{
root.getMap().setValue(ExpressionKeyFadeOut, new JsonFloat(DefaultFadeTime));
}
expression.setFadeInTime(root.getMap().getValue(ExpressionKeyFadeIn).toFloat(DefaultFadeTime)); // フェードイン
expression.setFadeOutTime(root.getMap().getValue(ExpressionKeyFadeOut).toFloat(DefaultFadeTime)); // フェードアウト
// 各パラメータについて
const parameterCount = root.getMap().getValue(ExpressionKeyParameters).getSize();
for(let i: number = 0; i < parameterCount; ++i)
{
let param: Value = root.getMap().getValue(ExpressionKeyParameters).getVector().at(i);
const parameterId: CubismIdHandle = CubismFramework.getIdManager().getId(param.getMap().getValue(ExpressionKeyId).getRawString()); // パラメータID
const value: number = param.getMap().getValue(ExpressionKeyValue).toFloat(); // 値
// 計算方法の設定
let blendType: CubismExpressionMotion.ExpressionBlendType;
if(param.getMap().getValue(ExpressionKeyBlend).isNull() || param.getMap().getValue(ExpressionKeyBlend).getString() == BlendValueAdd)
{
blendType = this.ExpressionBlendType.ExpressionBlendType_Add;
}
else if(param.getMap().getValue(ExpressionKeyBlend).getString() == BlendValueMultiply)
{
blendType = this.ExpressionBlendType.ExpressionBlendType_Multiply;
}
else if(param.getMap().getValue(ExpressionKeyBlend).getString() == BlendValueOverwrite)
{
blendType = this.ExpressionBlendType.ExpressionBlendType_Overwrite;
}
else
{
// その他 仕様にない値を設定した時は加算モードにすることで復旧
blendType = this.ExpressionBlendType.ExpressionBlendType_Add;
}
// 設定オブジェクトを作成してリストに追加する
let item: CubismExpressionMotion.ExpressionParameter = new CubismExpressionMotion.ExpressionParameter();
item.parameterId = parameterId;
item.blendType = blendType;
item.value = value;
expression._parameters.pushBack(item);
}
CubismJson.delete(json); // JSONデータは不要になったら削除する
return expression;
}
/**
*
* @param model
* @param userTimeSeconds []
* @param weight
* @param motionQueueEntry CubismMotionQueueManager
*/
public doUpdateParameters(model: CubismModel, userTimeSeconds: number, weight: number, motionQueueEntry: CubismMotionQueueEntry): void
{
for(let i: number = 0; i < this._parameters.getSize(); ++i)
{
let parameter: CubismExpressionMotion.ExpressionParameter = this._parameters.at(i);
switch(parameter.blendType)
{
case CubismExpressionMotion.ExpressionBlendType.ExpressionBlendType_Add:
{
model.addParameterValueById(parameter.parameterId, parameter.value, weight);
break;
}
case CubismExpressionMotion.ExpressionBlendType.ExpressionBlendType_Multiply:
{
model.multiplyParameterValueById(parameter.parameterId, parameter.value, weight);
break;
}
case CubismExpressionMotion.ExpressionBlendType.ExpressionBlendType_Overwrite:
{
model.setParameterValueById(parameter.parameterId, parameter.value, weight)
break;
}
default:
// 仕様にない値を設定した時はすでに加算モードになっている
break;
}
}
}
/**
*
*/
constructor()
{
super();
this._parameters = new csmVector<CubismExpressionMotion.ExpressionParameter>();
}
_parameters: csmVector<CubismExpressionMotion.ExpressionParameter>; // 表情のパラメータ情報リスト
}
export namespace CubismExpressionMotion
{
/**
*
*/
export enum ExpressionBlendType
{
ExpressionBlendType_Add = 0, // 加算
ExpressionBlendType_Multiply = 1, // 乗算
ExpressionBlendType_Overwrite = 2 // 上書き
}
/**
*
*/
export class ExpressionParameter
{
parameterId: CubismIdHandle; // パラメータID
blendType: ExpressionBlendType; // パラメータの演算種類
value: number; // 値
}
}
}

View File

@ -0,0 +1,805 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
import {Live2DCubismFramework as cubismmotionjson} from './cubismmotionjson';
import {Live2DCubismFramework as cubismmotioninternal} from './cubismmotioninternal';
import {Live2DCubismFramework as acubismmotion} from './acubismmotion';
import {Live2DCubismFramework as cubismmodel} from '../model/cubismmodel';
import {Live2DCubismFramework as cubismframework} from '../live2dcubismframework';
import {Live2DCubismFramework as cubismmotionqueueentry} from './cubismmotionqueueentry';
import {Live2DCubismFramework as cubismmath} from '../math/cubismmath';
import {Live2DCubismFramework as csmvector} from '../type/csmvector';
import {Live2DCubismFramework as cubismid} from '../id/cubismid';
import {Live2DCubismFramework as csmstring} from '../type/csmstring';
import {CubismLogDebug, CSM_ASSERT} from '../utils/cubismdebug';
import csmString = csmstring.csmString;
import CubismMotionData = cubismmotioninternal.CubismMotionData;
import CubismMotionSegment = cubismmotioninternal.CubismMotionSegment;
import CubismMotionPoint = cubismmotioninternal.CubismMotionPoint;
import CubismMotionEvent = cubismmotioninternal.CubismMotionEvent;
import CubismMotionSegmentType = cubismmotioninternal.CubismMotionSegmentType;
import CubismIdHandle = cubismid.CubismIdHandle;
import CubismMotionCurve = cubismmotioninternal.CubismMotionCurve;
import CubismMotionCurveTarget = cubismmotioninternal.CubismMotionCurveTarget;
import csmVector = csmvector.csmVector;
import CubismMath = cubismmath.CubismMath;
import CubismMotionQueueEntry = cubismmotionqueueentry.CubismMotionQueueEntry;
import CubismFramework = cubismframework.CubismFramework;
import CubismModel = cubismmodel.CubismModel;
import ACubismMotion = acubismmotion.ACubismMotion;
import CubismMotionJson = cubismmotionjson.CubismMotionJson;
export namespace Live2DCubismFramework
{
const EffectNameEyeBlink: string = "EyeBlink";
const EffectNameLipSync: string = "LipSync";
const TargetNameModel: string = "Model";
const TargetNameParameter: string = "Parameter";
const TargetNamePartOpacity: string = "PartOpacity";
function lerpPoints(a: CubismMotionPoint, b: CubismMotionPoint, t: number): CubismMotionPoint
{
let result: CubismMotionPoint = new CubismMotionPoint();
result.time = a.time + ((b.time - a.time) * t);
result.value = a.value + ((b.value - a.value) * t);
return result;
}
function linearEvaluate(points: CubismMotionPoint[], time: number): number
{
let t: number = (time - points[0].time) / (points[1].time - points[0].time);
if (t < 0.0)
{
t = 0.0;
}
return points[0].value + ((points[1].value - points[0].value) * t);
}
function bezierEvaluate(points: CubismMotionPoint[], time: number): number
{
let t: number = (time - points[0].time) / (points[3].time - points[0].time);
if (t < 0.0)
{
t = 0.0;
}
const p01: CubismMotionPoint = lerpPoints(points[0], points[1], t);
const p12: CubismMotionPoint = lerpPoints(points[1], points[2], t);
const p23: CubismMotionPoint = lerpPoints(points[2], points[3], t);
const p012: CubismMotionPoint = lerpPoints(p01, p12, t);
const p123: CubismMotionPoint = lerpPoints(p12, p23, t);
return lerpPoints(p012, p123, t).value;
}
function steppedEvaluate(points: CubismMotionPoint[], time: number): number
{
return points[0].value;
}
function inverseSteppedEvaluate(points: CubismMotionPoint[], time: number): number
{
return points[1].value;
}
function evaluateCurve(motionData: CubismMotionData, index: number, time: number): number
{
// Find segment to evaluate.
const curve: CubismMotionCurve = motionData.curves.at(index);
let target: number = -1;
const totalSegmentCount: number = curve.baseSegmentIndex + curve.segmentCount;
let pointPosition: number = 0;
for (let i: number = curve.baseSegmentIndex; i < totalSegmentCount; ++i)
{
// Get first point of next segment.
pointPosition = motionData.segments.at(i).basePointIndex
+ (motionData.segments.at(i).segmentType == CubismMotionSegmentType.CubismMotionSegmentType_Bezier
? 3
: 1);
// Break if time lies within current segment.
if (motionData.points.at(pointPosition).time > time)
{
target = i;
break;
}
}
if (target == -1)
{
return motionData.points.at(pointPosition).value;
}
const segment: CubismMotionSegment = motionData.segments.at(target);
return segment.evaluate(motionData.points.get(segment.basePointIndex), time);
}
/**
*
*
*
*/
export class CubismMotion extends ACubismMotion
{
/**
*
*
* @param buffer motion3.json
* @param size
* @return
*/
public static create(buffer: ArrayBuffer, size: number): CubismMotion
{
let ret: CubismMotion = new CubismMotion();
ret.parse(buffer, size);
ret._sourceFrameRate = ret._motionData.fps;
ret._loopDurationSeconds = ret._motionData.duration;
// NOTE: Editorではループありのモーション書き出しは非対応
// ret->_loop = (ret->_motionData->Loop > 0);
return ret;
}
/**
*
* @param model
* @param userTimeSeconds []
* @param fadeWeight
* @param motionQueueEntry CubismMotionQueueManager
*/
public doUpdateParameters(model: CubismModel, userTimeSeconds: number, fadeWeight: number, motionQueueEntry: CubismMotionQueueEntry): void
{
if (this._modelCurveIdEyeBlink == null)
{
this._modelCurveIdEyeBlink = CubismFramework.getIdManager().getId(EffectNameEyeBlink);
}
if (this._modelCurveIdLipSync == null)
{
this._modelCurveIdLipSync = CubismFramework.getIdManager().getId(EffectNameLipSync);
}
let timeOffsetSeconds: number = userTimeSeconds - motionQueueEntry.getStartTime();
if (timeOffsetSeconds < 0.0)
{
timeOffsetSeconds = 0.0; // エラー回避
}
let lipSyncValue: number = Number.MAX_VALUE;
let eyeBlinkValue: number = Number.MAX_VALUE;
//まばたき、リップシンクのうちモーションの適用を検出するためのビットmaxFlagCount個まで
const MaxTargetSize = 64;
let lipSyncFlags = 0;
let eyeBlinkFlags = 0;
//瞬き、リップシンクのターゲット数が上限を超えている場合
if (this._eyeBlinkParameterIds.getSize() > MaxTargetSize)
{
CubismLogDebug("too many eye blink targets : {0}", this._eyeBlinkParameterIds.getSize());
}
if (this._lipSyncParameterIds.getSize() > MaxTargetSize)
{
CubismLogDebug("too many lip sync targets : {0}", this._lipSyncParameterIds.getSize());
}
const tmpFadeIn: number = (this._fadeInSeconds <= 0.0)
? 1.0
: CubismMath.getEasingSine((userTimeSeconds - motionQueueEntry.getFadeInStartTime()) / this._fadeInSeconds);
const tmpFadeOut: number = (this._fadeOutSeconds <= 0.0 || motionQueueEntry.getEndTime() < 0.0)
? 1.0
: CubismMath.getEasingSine((motionQueueEntry.getEndTime() - userTimeSeconds) / this._fadeOutSeconds);
let value: number;
let c: number, parameterIndex: number;
// 'Repeat' time as necessary.
let time: number = timeOffsetSeconds;
if (this._isLoop)
{
while (time > this._motionData.duration)
{
time -= this._motionData.duration;
}
}
let curves: csmVector<CubismMotionCurve> = this._motionData.curves;
// Evaluate model curves.
for (c = 0; c < this._motionData.curveCount && curves.at(c).type == CubismMotionCurveTarget.CubismMotionCurveTarget_Model; ++c)
{
// Evaluate curve and call handler.
value = evaluateCurve(this._motionData, c, time);
if (curves.at(c).id == this._modelCurveIdEyeBlink)
{
eyeBlinkValue = value;
}
else if (curves.at(c).id == this._modelCurveIdLipSync)
{
lipSyncValue = value;
}
}
let parameterMotionCurveCount: number = 0;
for (; c < this._motionData.curveCount && curves.at(c).type == CubismMotionCurveTarget.CubismMotionCurveTarget_Parameter; ++c)
{
parameterMotionCurveCount++;
// Find parameter index.
parameterIndex = model.getParameterIndex(curves.at(c).id);
// Skip curve evaluation if no value in sink.
if (parameterIndex == -1)
{
continue;
}
const sourceValue: number = model.getParameterValueByIndex(parameterIndex);
// Evaluate curve and apply value.
value = evaluateCurve(this._motionData, c, time);
if (eyeBlinkValue != Number.MAX_VALUE)
{
for (let i: number = 0; i < this._eyeBlinkParameterIds.getSize() && i < MaxTargetSize; ++i)
{
if (this._eyeBlinkParameterIds.at(i) == curves.at(c).id)
{
value *= eyeBlinkValue;
eyeBlinkFlags |= 1 << i;
break;
}
}
}
if(lipSyncValue != Number.MAX_VALUE)
{
for(let i: number = 0; i < this._lipSyncParameterIds.getSize() && i < MaxTargetSize; ++i)
{
if(this._lipSyncParameterIds.at(i) == curves.at(c).id)
{
value += lipSyncValue;
lipSyncFlags |= 1 << i;
break;
}
}
}
let v: number;
// パラメータごとのフェード
if(curves.at(c).fadeInTime < 0.0 && curves.at(c).fadeOutTime < 0.0)
{
// モーションのフェードを適用
v = sourceValue + (value - sourceValue) * fadeWeight;
}
else
{
// パラメータに対してフェードインかフェードアウトが設定してある場合はそちらを適用
let fin: number;
let fout: number;
if(curves.at(c).fadeInTime < 0.0)
{
fin = tmpFadeIn;
}
else
{
fin = curves.at(c).fadeInTime == 0.0
? 1.0
:CubismMath.getEasingSine((userTimeSeconds - motionQueueEntry.getFadeInStartTime()) / curves.at(c).fadeInTime);
}
if(curves.at(c).fadeOutTime < 0.0)
{
fout = tmpFadeOut;
}
else
{
fout = (curves.at(c).fadeOutTime == 0.0 || motionQueueEntry.getEndTime() < 0.0)
? 1.0
: CubismMath.getEasingSine((motionQueueEntry.getEndTime() - userTimeSeconds) / curves.at(c).fadeOutTime);
}
const paramWeight: number = this._weight * fin * fout;
// パラメータごとのフェードを適用
v = sourceValue + (value - sourceValue) * paramWeight;
}
model.setParameterValueByIndex(parameterIndex, v, 1.0);
}
{
if(eyeBlinkValue != Number.MAX_VALUE)
{
for(let i: number = 0; i < this._eyeBlinkParameterIds.getSize() && i < MaxTargetSize; ++i)
{
const sourceValue: number = model.getParameterValueById(this._eyeBlinkParameterIds.at(i));
// モーションでの上書きがあった時にはまばたきは適用しない
if((eyeBlinkFlags >> i) & 0x01)
{
continue;
}
const v: number = sourceValue + (eyeBlinkValue - sourceValue) * fadeWeight;
model.setParameterValueById(this._eyeBlinkParameterIds.at(i), v);
}
}
if(lipSyncValue != Number.MAX_VALUE)
{
for(let i: number = 0; i < this._lipSyncParameterIds.getSize() && i < MaxTargetSize; ++i)
{
const sourceValue: number = model.getParameterValueById(this._lipSyncParameterIds.at(i));
// モーションでの上書きがあった時にはリップシンクは適用しない
if((lipSyncFlags >> i) & 0x01)
{
continue;
}
const v: number = sourceValue + (lipSyncValue - sourceValue) * fadeWeight;
model.setParameterValueById(this._lipSyncParameterIds.at(i), v);
}
}
}
for(; c < this._motionData.curveCount && curves.at(c).type == CubismMotionCurveTarget.CubismMotionCurveTarget_PartOpacity; ++c)
{
// Find parameter index.
parameterIndex = model.getParameterIndex(curves.at(c).id);
// Skip curve evaluation if no value in sink.
if(parameterIndex == -1)
{
continue;
}
// Evaluate curve and apply value.
value = evaluateCurve(this._motionData, c, time);
model.setParameterValueByIndex(parameterIndex, value);
}
if(timeOffsetSeconds >= this._motionData.duration)
{
if(this._isLoop)
{
motionQueueEntry.setStartTime(userTimeSeconds); // 最初の状態へ
if(this._isLoopFadeIn)
{
// ループ内でループ用フェードインが有効の時は、フェードイン設定し直し
motionQueueEntry.setFadeInStartTime(userTimeSeconds);
}
}
else
{
motionQueueEntry.setIsFinished(true);
}
}
this._lastWeight = fadeWeight;
}
/**
*
* @param loop
*/
public setIsLoop(loop: boolean): void
{
this._isLoop = loop;
}
/**
*
* @return true
* @return false
*/
public isLoop(): boolean
{
return this._isLoop;
}
/**
*
* @param loopFadeIn
*/
public setIsLoopFadeIn(loopFadeIn: boolean): void
{
this._isLoopFadeIn = loopFadeIn;
}
/**
*
*
* @return true
* @return false
*/
public isLoopFadeIn(): boolean
{
return this._isLoopFadeIn;
}
/**
*
*
* @return []
*/
public getDuration(): number
{
return this._isLoop ? -1.0 : this._loopDurationSeconds;
}
/**
*
*
* @return []
*/
public getLoopDuration(): number
{
return this._loopDurationSeconds;
}
/**
*
*
* @param parameterId ID
* @param value []
*/
public setParameterFadeInTime(parameterId: CubismIdHandle, value: number): void
{
let curves: csmVector<CubismMotionCurve> = this._motionData.curves;
for (let i: number = 0; i < this._motionData.curveCount; ++i)
{
if (parameterId == curves.at(i).id)
{
curves.at(i).fadeInTime = value;
return;
}
}
}
/**
*
* @param parameterId ID
* @param value []
*/
public setParameterFadeOutTime(parameterId: CubismIdHandle, value: number): void
{
let curves: csmVector<CubismMotionCurve> = this._motionData.curves;
for (let i: number = 0; i < this._motionData.curveCount; ++i)
{
if (parameterId == curves.at(i).id)
{
curves.at(i).fadeOutTime = value;
return;
}
}
}
/**
*
* @param parameterId ID
* @return []
*/
public getParameterFadeInTime(parameterId: CubismIdHandle): number
{
let curves: csmVector<CubismMotionCurve> = this._motionData.curves;
for (let i: number = 0; i < this._motionData.curveCount; ++i)
{
if (parameterId == curves.at(i).id)
{
return curves.at(i).fadeInTime;
}
}
return -1;
}
/**
*
*
* @param parameterId ID
* @return []
*/
public getParameterFadeOutTime(parameterId: CubismIdHandle): number
{
let curves: csmVector<CubismMotionCurve> = this._motionData.curves;
for (let i: number = 0; i < this._motionData.curveCount; ++i)
{
if (parameterId == curves.at(i).id)
{
return curves.at(i).fadeOutTime;
}
}
return -1;
}
/**
* ID
* @param eyeBlinkParameterIds ID
* @param lipSyncParameterIds ID
*/
public setEffectIds(eyeBlinkParameterIds: csmVector<CubismIdHandle>, lipSyncParameterIds: csmVector<CubismIdHandle>): void
{
this._eyeBlinkParameterIds = eyeBlinkParameterIds;
this._lipSyncParameterIds = lipSyncParameterIds;
}
/**
*
*/
public constructor()
{
super();
this._sourceFrameRate = 30.0;
this._loopDurationSeconds = -1.0;
this._isLoop = false; // trueから false へデフォルトを変更
this._isLoopFadeIn = true; // ループ時にフェードインが有効かどうかのフラグ
this._lastWeight = 0.0;
this._motionData = null;
this._modelCurveIdEyeBlink = null;
this._modelCurveIdLipSync = null;
this._eyeBlinkParameterIds = null;
this._lipSyncParameterIds = null;
}
/**
*
*/
public release(): void
{
this._motionData = void 0;
this._motionData = null;
}
/**
* motion3.json
*
* @param motionJson motion3.json
* @param size
*/
public parse(motionJson: ArrayBuffer, size: number): void
{
this._motionData = new CubismMotionData();
let json: CubismMotionJson = new CubismMotionJson(motionJson, size);
this._motionData.duration = json.getMotionDuration();
this._motionData.loop = json.isMotionLoop();
this._motionData.curveCount = json.getMotionCurveCount();
this._motionData.fps = json.getMotionFps();
this._motionData.eventCount = json.getEventCount();
if (json.isExistMotionFadeInTime())
{
this._fadeInSeconds = (json.getMotionFadeInTime() < 0.0)
? 1.0
: json.getMotionFadeInTime();
}
else
{
this._fadeInSeconds = 1.0;
}
if (json.isExistMotionFadeOutTime())
{
this._fadeOutSeconds = (json.getMotionFadeOutTime() < 0.0)
? 1.0
: json.getMotionFadeOutTime();
}
else
{
this._fadeOutSeconds = 1.0;
}
this._motionData.curves.updateSize(this._motionData.curveCount, CubismMotionCurve, true);
this._motionData.segments.updateSize(json.getMotionTotalSegmentCount(), CubismMotionSegment, true);
this._motionData.points.updateSize(json.getMotionTotalPointCount(), CubismMotionPoint, true);
this._motionData.events.updateSize(this._motionData.eventCount, CubismMotionEvent, true);
let totalPointCount: number = 0;
let totalSegmentCount: number = 0;
// Curves
for (let curveCount: number = 0; curveCount < this._motionData.curveCount; ++curveCount)
{
if (json.getMotionCurveTarget(curveCount) == TargetNameModel)
{
this._motionData.curves.at(curveCount).type = CubismMotionCurveTarget.CubismMotionCurveTarget_Model;
}
else if (json.getMotionCurveTarget(curveCount) == TargetNameParameter)
{
this._motionData.curves.at(curveCount).type = CubismMotionCurveTarget.CubismMotionCurveTarget_Parameter;
}
else if (json.getMotionCurveTarget(curveCount) == TargetNamePartOpacity)
{
this._motionData.curves.at(curveCount).type = CubismMotionCurveTarget.CubismMotionCurveTarget_PartOpacity;
}
this._motionData.curves.at(curveCount).id = json.getMotionCurveId(curveCount);
this._motionData.curves.at(curveCount).baseSegmentIndex = totalSegmentCount;
this._motionData.curves.at(curveCount).fadeInTime =
(json.isExistMotionCurveFadeInTime(curveCount))
? json.getMotionCurveFadeInTime(curveCount)
: -1.0 ;
this._motionData.curves.at(curveCount).fadeOutTime =
(json.isExistMotionCurveFadeOutTime(curveCount))
? json.getMotionCurveFadeOutTime(curveCount)
: -1.0;
// Segments
for (let segmentPosition: number = 0; segmentPosition < json.getMotionCurveSegmentCount(curveCount);)
{
if (segmentPosition == 0)
{
this._motionData.segments.at(totalSegmentCount).basePointIndex = totalPointCount;
this._motionData.points.at(totalPointCount).time = json.getMotionCurveSegment(curveCount, segmentPosition);
this._motionData.points.at(totalPointCount).value = json.getMotionCurveSegment(curveCount, segmentPosition + 1);
totalPointCount += 1;
segmentPosition += 2;
}
else
{
this._motionData.segments.at(totalSegmentCount).basePointIndex = totalPointCount - 1;
}
const segment: number = json.getMotionCurveSegment(curveCount, segmentPosition);
switch (segment)
{
case CubismMotionSegmentType.CubismMotionSegmentType_Linear:
{
this._motionData.segments.at(totalSegmentCount).segmentType = CubismMotionSegmentType.CubismMotionSegmentType_Linear;
this._motionData.segments.at(totalSegmentCount).evaluate = linearEvaluate;
this._motionData.points.at(totalPointCount).time = json.getMotionCurveSegment(curveCount, (segmentPosition + 1));
this._motionData.points.at(totalPointCount).value = json.getMotionCurveSegment(curveCount, (segmentPosition + 2));
totalPointCount += 1;
segmentPosition += 3;
break;
}
case CubismMotionSegmentType.CubismMotionSegmentType_Bezier:
{
this._motionData.segments.at(totalSegmentCount).segmentType = CubismMotionSegmentType.CubismMotionSegmentType_Bezier;
this._motionData.segments.at(totalSegmentCount).evaluate = bezierEvaluate;
this._motionData.points.at(totalPointCount).time = json.getMotionCurveSegment(curveCount, (segmentPosition + 1));
this._motionData.points.at(totalPointCount).value = json.getMotionCurveSegment(curveCount, (segmentPosition + 2));
this._motionData.points.at(totalPointCount + 1).time = json.getMotionCurveSegment(curveCount, (segmentPosition + 3));
this._motionData.points.at(totalPointCount + 1).value = json.getMotionCurveSegment(curveCount, (segmentPosition + 4));
this._motionData.points.at(totalPointCount + 2).time = json.getMotionCurveSegment(curveCount, (segmentPosition + 5));
this._motionData.points.at(totalPointCount + 2).value = json.getMotionCurveSegment(curveCount, (segmentPosition + 6));
totalPointCount += 3;
segmentPosition += 7;
break;
}
case CubismMotionSegmentType.CubismMotionSegmentType_Stepped:
{
this._motionData.segments.at(totalSegmentCount).segmentType = CubismMotionSegmentType.CubismMotionSegmentType_Stepped;
this._motionData.segments.at(totalSegmentCount).evaluate = steppedEvaluate;
this._motionData.points.at(totalPointCount).time = json.getMotionCurveSegment(curveCount, (segmentPosition + 1));
this._motionData.points.at(totalPointCount).value = json.getMotionCurveSegment(curveCount, (segmentPosition + 2));
totalPointCount += 1;
segmentPosition += 3;
break;
}
case CubismMotionSegmentType.CubismMotionSegmentType_InverseStepped:
{
this._motionData.segments.at(totalSegmentCount).segmentType = CubismMotionSegmentType.CubismMotionSegmentType_InverseStepped;
this._motionData.segments.at(totalSegmentCount).evaluate = inverseSteppedEvaluate;
this._motionData.points.at(totalPointCount).time = json.getMotionCurveSegment(curveCount, (segmentPosition + 1));
this._motionData.points.at(totalPointCount).value = json.getMotionCurveSegment(curveCount, (segmentPosition + 2));
totalPointCount += 1;
segmentPosition += 3;
break;
}
default:
{
CSM_ASSERT(0);
break;
}
}
++this._motionData.curves.at(curveCount).segmentCount;
++totalSegmentCount;
}
}
for (let userdatacount: number = 0; userdatacount < json.getEventCount(); ++userdatacount)
{
this._motionData.events.at(userdatacount).fireTime = json.getEventTime(userdatacount);
this._motionData.events.at(userdatacount).value = json.getEventValue(userdatacount);
}
json.release();
json = void 0;
json = null;
}
/**
*
*
*
*
*
* @param beforeCheckTimeSeconds []
* @param motionTimeSeconds []
*/
public getFiredEvent(beforeCheckTimeSeconds: number, motionTimeSeconds: number): csmVector<csmString>
{
this._firedEventValues.updateSize(0);
// イベントの発火チェック
for (let u: number = 0; u < this._motionData.eventCount; ++u)
{
if ((this._motionData.events.at(u).fireTime > beforeCheckTimeSeconds) &&
(this._motionData.events.at(u).fireTime <= motionTimeSeconds))
{
this._firedEventValues.pushBack(new csmString(this._motionData.events.at(u).value.s));
}
}
return this._firedEventValues;
}
public _sourceFrameRate: number; // ロードしたファイルのFPS。記述が無ければデフォルト値15fpsとなる
public _loopDurationSeconds: number; // mtnファイルで定義される一連のモーションの長さ
public _isLoop: boolean; // ループするか?
public _isLoopFadeIn: boolean; // ループ時にフェードインが有効かどうかのフラグ。初期値では有効。
public _lastWeight: number; // 最後に設定された重み
public _motionData: CubismMotionData; // 実際のモーションデータ本体
public _eyeBlinkParameterIds: csmVector<CubismIdHandle>; // 自動まばたきを適用するパラメータIDハンドルのリスト。 モデル(モデルセッティング)とパラメータを対応付ける。
public _lipSyncParameterIds: csmVector<CubismIdHandle>; // リップシンクを適用するパラメータIDハンドルのリスト。 モデル(モデルセッティング)とパラメータを対応付ける。
public _modelCurveIdEyeBlink: CubismIdHandle; // モデルが持つ自動まばたき用パラメータIDのハンドル。 モデルとモーションを対応付ける。
public _modelCurveIdLipSync: CubismIdHandle; // モデルが持つリップシンク用パラメータIDのハンドル。 モデルとモーションを対応付ける。
}
}

View File

@ -0,0 +1,157 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
import {Live2DCubismFramework as cubismid} from '../id/cubismid';
import {Live2DCubismFramework as csmstring} from '../type/csmstring';
import {Live2DCubismFramework as csmvector} from '../type/csmvector';
import csmVector = csmvector.csmVector;
import csmString = csmstring.csmString;
import CubismIdHandle = cubismid.CubismIdHandle;
export namespace Live2DCubismFramework
{
/**
* @brief
*
*
*/
export enum CubismMotionCurveTarget
{
CubismMotionCurveTarget_Model, // モデルに対して
CubismMotionCurveTarget_Parameter, // パラメータに対して
CubismMotionCurveTarget_PartOpacity // パーツの不透明度に対して
};
/**
* @brief
*
*
*/
export enum CubismMotionSegmentType
{
CubismMotionSegmentType_Linear = 0, // リニア
CubismMotionSegmentType_Bezier = 1, // ベジェ曲線
CubismMotionSegmentType_Stepped = 2, // ステップ
CubismMotionSegmentType_InverseStepped = 3 // インバースステップ
};
/**
* @brief
*
*
*/
export class CubismMotionPoint
{
time: number = 0.0; // 時間[秒]
value: number = 0.0; // 値
};
/**
*
*
* @param points
* @param time []
*/
export interface csmMotionSegmentEvaluationFunction
{
(
points: CubismMotionPoint[],
time: number
): number;
}
/**
* @brief
*
*
*/
export class CubismMotionSegment
{
/**
* @brief
*
*
*/
public constructor()
{
this.evaluate = null;
this.basePointIndex = 0;
this.segmentType = 0;
}
evaluate: csmMotionSegmentEvaluationFunction; // 使用する評価関数
basePointIndex: number; // 最初のセグメントへのインデックス
segmentType: number; // セグメントの種類
};
/**
* @brief
*
*
*/
export class CubismMotionCurve
{
public constructor()
{
this.type = CubismMotionCurveTarget.CubismMotionCurveTarget_Model;
this.segmentCount = 0;
this.baseSegmentIndex = 0;
this.fadeInTime = 0.0;
this.fadeOutTime = 0.0;
}
type: CubismMotionCurveTarget; // カーブの種類
id: CubismIdHandle; // カーブのID
segmentCount: number; // セグメントの個数
baseSegmentIndex: number; // 最初のセグメントのインデックス
fadeInTime: number; // フェードインにかかる時間[秒]
fadeOutTime: number; // フェードアウトにかかる時間[秒]
};
/**
*
*/
export class CubismMotionEvent
{
fireTime: number = 0.0;
value: csmString;
};
/**
* @brief
*
*
*/
export class CubismMotionData
{
public constructor()
{
this.duration = 0.0;
this.loop = false;
this.curveCount = 0;
this.eventCount = 0;
this.fps = 0.0;
this.curves = new csmVector<CubismMotionCurve>();
this.segments = new csmVector<CubismMotionSegment>();
this.points = new csmVector<CubismMotionPoint>();
this.events = new csmVector<CubismMotionEvent>();
}
duration: number; // モーションの長さ[秒]
loop: boolean; // ループするかどうか
curveCount: number; // カーブの個数
eventCount: number; // UserDataの個数
fps: number; // フレームレート
curves: csmVector<CubismMotionCurve>; // カーブのリスト
segments: csmVector<CubismMotionSegment>; // セグメントのリスト
points: csmVector<CubismMotionPoint>; // ポイントのリスト
events: csmVector<CubismMotionEvent>; // イベントのリスト
};
}

View File

@ -0,0 +1,282 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
import {Live2DCubismFramework as cubismjson} from '../utils/cubismjson';
import {Live2DCubismFramework as cubismid} from '../id/cubismid';
import {Live2DCubismFramework as cubismframework} from '../live2dcubismframework';
import {Live2DCubismFramework as csmstring} from '../type/csmstring';
import csmString = csmstring.csmString;
import CubismFramework = cubismframework.CubismFramework;
import CubismIdHandle = cubismid.CubismIdHandle;
import CubismJson = cubismjson.CubismJson;
export namespace Live2DCubismFramework
{
// JSON keys
const Meta: string = "Meta";
const Duration: string = "Duration";
const Loop: string = "Loop";
const CurveCount: string = "CurveCount";
const Fps: string = "Fps";
const TotalSegmentCount: string = "TotalSegmentCount";
const TotalPointCount: string = "TotalPointCount";
const Curves: string = "Curves";
const Target: string = "Target";
const Id: string = "Id";
const FadeInTime: string = "FadeInTime";
const FadeOutTime: string = "FadeOutTime";
const Segments: string = "Segments";
const UserData: string = "UserData";
const UserDataCount: string = "UserDataCount";
const TotalUserDataSize: string = "TotalUserDataSize";
const Time: string = "Time";
const Value: string = "Value";
/**
* motion3.json
*/
export class CubismMotionJson
{
/**
*
* @param buffer motion3.json
* @param size
*/
public constructor(buffer: ArrayBuffer, size: number)
{
this._json = CubismJson.create(buffer, size);
}
/**
*
*/
public release(): void
{
CubismJson.delete(this._json);
}
/**
*
* @return []
*/
public getMotionDuration(): number
{
return this._json.getRoot().getMap().getValue(Meta).getMap().getValue(Duration).toFloat();
}
/**
*
* @return true
* @return false
*/
public isMotionLoop(): boolean
{
return this._json.getRoot().getMap().getValue(Meta).getMap().getValue(Loop).toBoolean();
}
/**
*
* @return
*/
public getMotionCurveCount(): number
{
return this._json.getRoot().getMap().getValue(Meta).getMap().getValue(CurveCount).toInt();
}
/**
*
* @return [FPS]
*/
public getMotionFps(): number
{
return this._json.getRoot().getMap().getValue(Meta).getMap().getValue(Fps).toFloat();
}
/**
*
* @return
*/
public getMotionTotalSegmentCount(): number
{
return this._json.getRoot().getMap().getValue(Meta).getMap().getValue(TotalSegmentCount).toInt();
}
/**
*
* @return
*/
public getMotionTotalPointCount(): number
{
return this._json.getRoot().getMap().getValue(Meta).getMap().getValue(TotalPointCount).toInt();
}
/**
*
* @return true
* @return false
*/
public isExistMotionFadeInTime(): boolean
{
return this._json.getRoot().getMap().getValue(Meta).getMap().isExist(FadeInTime);
}
/**
*
* @return true
* @return false
*/
public isExistMotionFadeOutTime(): boolean
{
return this._json.getRoot().getMap().getValue(Meta).getMap().isExist(FadeOutTime);
}
/**
*
* @return []
*/
public getMotionFadeInTime(): number
{
return this._json.getRoot().getMap().getValue(Meta).getMap().getValue(FadeInTime).toFloat();
}
/**
*
* @return []
*/
public getMotionFadeOutTime(): number
{
return this._json.getRoot().getMap().getValue(Meta).getMap().getValue(FadeOutTime).toFloat();
}
/**
*
* @param curveIndex
* @return
*/
public getMotionCurveTarget(curveIndex: number): string
{
return this._json.getRoot().getMap().getValue(Curves).getVector().at(curveIndex).getMap().getValue(Target).getRawString();
}
/**
* ID
* @param curveIndex
* @return ID
*/
public getMotionCurveId(curveIndex: number): CubismIdHandle
{
return CubismFramework.getIdManager().getId(this._json.getRoot().getMap().getValue(Curves).getVector().at(curveIndex).getMap().getValue(Id).getRawString());
}
/**
*
* @param curveIndex
* @return true
* @return false
*/
public isExistMotionCurveFadeInTime(curveIndex: number): boolean
{
return this._json.getRoot().getMap().getValue(Curves).getVector().at(curveIndex).getMap().isExist(FadeInTime);
}
/**
*
* @param curveIndex
* @return true
* @return false
*/
public isExistMotionCurveFadeOutTime(curveIndex: number): boolean
{
return this._json.getRoot().getMap().getValue(Curves).getVector().at(curveIndex).getMap().isExist(FadeOutTime);
}
/**
*
* @param curveIndex
* @return []
*/
public getMotionCurveFadeInTime(curveIndex: number): number
{
return this._json.getRoot().getMap().getValue(Curves).getVector().at(curveIndex).getMap().getValue(FadeInTime).toFloat();
}
/**
*
* @param curveIndex
* @return []
*/
public getMotionCurveFadeOutTime(curveIndex: number): number
{
return this._json.getRoot().getMap().getValue(Curves).getVector().at(curveIndex).getMap().getValue(FadeOutTime).toFloat();
}
/**
*
* @param curveIndex
* @return
*/
public getMotionCurveSegmentCount(curveIndex: number): number
{
return this._json.getRoot().getMap().getValue(Curves).getVector().at(curveIndex).getMap().getValue(Segments).getVector().getSize();
}
/**
*
* @param curveIndex
* @param segmentIndex
* @return
*/
public getMotionCurveSegment(curveIndex: number, segmentIndex: number): number
{
return this._json.getRoot().getMap().getValue(Curves).getVector().at(curveIndex).getMap().getValue(Segments).getVector().at(segmentIndex).toFloat();
}
/**
*
* @return
*/
public getEventCount(): number
{
if(!this._json.getRoot().getMap().getValue(Meta).getMap().isExist(UserDataCount))
{
return 0;
}
return this._json.getRoot().getMap().getValue(Meta).getMap().getValue(UserDataCount).toInt();
}
/**
*
* @return
*/
public getTotalEventValueSize(): number
{
return this._json.getRoot().getMap().getValue(Meta).getMap().getValue(TotalUserDataSize).toInt();
}
/**
*
* @param userDataIndex
* @return []
*/
public getEventTime(userDataIndex: number): number
{
return this._json.getRoot().getMap().getValue(UserData).getVector().at(userDataIndex).getMap().getValue(Time).toInt();
}
/**
*
* @param userDataIndex
* @return
*/
public getEventValue(userDataIndex: number): csmString
{
return new csmString(this._json.getRoot().getMap().getValue(UserData).getVector().at(userDataIndex).getMap().getValue(Value).getRawString());
}
_json: CubismJson; // motion3.jsonのデータ
}
}

View File

@ -0,0 +1,127 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
import {Live2DCubismFramework as cubismmotionqueuemanager} from "./cubismmotionqueuemanager";
import {Live2DCubismFramework as acubismmotion} from './acubismmotion';
import {Live2DCubismFramework as cubismmodel} from '../model/cubismmodel';
import CubismMotionQueueEntryHandle = cubismmotionqueuemanager.CubismMotionQueueEntryHandle;
import CubismModel = cubismmodel.CubismModel;
import ACubismMotion = acubismmotion.ACubismMotion;
import CubismMotionQueueManager = cubismmotionqueuemanager.CubismMotionQueueManager;
export namespace Live2DCubismFramework
{
/**
*
*
*
*/
export class CubismMotionManager extends CubismMotionQueueManager
{
/**
*
*/
public constructor()
{
super();
this._currentPriority = 0;
this._reservePriority = 0;
}
/**
*
* @return
*/
public getCurrentPriority(): number
{
return this._currentPriority;
}
/**
*
* @return
*/
public getReservePriority(): number
{
return this._reservePriority;
}
/**
*
* @param val
*/
public setReservePriority(val: number): void
{
this._reservePriority = val;
}
/**
*
*
* @param motion
* @param autoDelete true
* @param priority
* @return IsFinished()使-1
*/
public startMotionPriority(motion: ACubismMotion, autoDelete: boolean, priority: number): CubismMotionQueueEntryHandle
{
if(priority == this._reservePriority)
{
this._reservePriority = 0; // 予約を解除
}
this._currentPriority = priority; // 再生中モーションの優先度を設定
return super.startMotion(motion, autoDelete, this._userTimeSeconds);
}
/**
*
*
* @param model
* @param deltaTimeSeconds []
* @return true
* @return false
*/
public updateMotion(model: CubismModel, deltaTimeSeconds: number): boolean
{
this._userTimeSeconds += deltaTimeSeconds;
const updated: boolean = super.doUpdateMotion(model, this._userTimeSeconds);
if(this.isFinished())
{
this._currentPriority = 0; // 再生中のモーションの優先度を解除
}
return updated;
}
/**
*
*
* @param priority
* @return true
* @return false
*/
public reserveMotion(priority: number): boolean
{
if((priority <= this._reservePriority) || (priority <= this._currentPriority))
{
return false;
}
this._reservePriority = priority;
return true;
}
_currentPriority: number; // 現在再生中のモーションの優先度
_reservePriority: number; // 再生予定のモーションの優先度。再生中は0になる。モーションファイルを別スレッドで読み込むときの機能。
}
}

View File

@ -0,0 +1,240 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
import {Live2DCubismFramework as acubismmotion} from './acubismmotion';
import {Live2DCubismFramework as cubismmotionqueuemanager} from './cubismmotionqueuemanager';
import CubismMotionQueueEntryHandle = cubismmotionqueuemanager.CubismMotionQueueEntryHandle;
import ACubismMotion = acubismmotion.ACubismMotion;
export namespace Live2DCubismFramework
{
/**
* CubismMotionQueueManager
*/
export class CubismMotionQueueEntry
{
/**
*
*/
public constructor()
{
this._autoDelete = false;
this._motion = null;
this._available = true;
this._finished = false;
this._started = false;
this._startTimeSeconds = -1.0;
this._fadeInStartTimeSeconds = 0.0;
this._endTimeSeconds = -1.0;
this._stateTimeSeconds = 0.0;
this._stateWeight = 0.0;
this._lastEventCheckSeconds = 0.0;
this._motionQueueEntryHandle = this;
}
/**
*
*/
public release(): void
{
if(this._autoDelete && this._motion)
{
ACubismMotion.delete(this._motion); //
}
}
/**
*
* @param fadeOutSeconds []
* @param userTimeSeconds []
*/
public startFadeout(fadeoutSeconds: number, userTimeSeconds: number): void
{
const newEndTimeSeconds: number = userTimeSeconds + fadeoutSeconds;
if(this._endTimeSeconds < 0.0 || newEndTimeSeconds < this._endTimeSeconds)
{
this._endTimeSeconds = newEndTimeSeconds;
}
}
/**
*
*
* @return true
* @return false
*/
public isFinished(): boolean
{
return this._finished;
}
/**
*
* @return true
* @return false
*/
public isStarted(): boolean
{
return this._started;
}
/**
*
* @return []
*/
public getStartTime(): number
{
return this._startTimeSeconds;
}
/**
*
* @return []
*/
public getFadeInStartTime(): number
{
return this._fadeInStartTimeSeconds;
}
/**
*
* @return
*/
public getEndTime(): number
{
return this._endTimeSeconds;
}
/**
*
* @param startTime
*/
public setStartTime(startTime: number): void
{
this._startTimeSeconds = startTime;
}
/**
*
* @param startTime []
*/
public setFadeInStartTime(startTime: number): void
{
this._fadeInStartTimeSeconds = startTime;
}
/**
*
* @param endTime []
*/
public setEndTime(endTime: number): void
{
this._endTimeSeconds = endTime;
}
/**
*
* @param f true
*/
public setIsFinished(f: boolean): void
{
this._finished = f;
}
/**
*
* @param f true
*/
public setIsStarted(f: boolean): void
{
this._started = f;
}
/**
*
* @return true
* @return false
*/
public isAvailable(): boolean
{
return this._available;
}
/**
*
* @param v true
*/
public setIsAvailable(v: boolean): void
{
this._available = v;
}
/**
*
* @param timeSeconds []
* @param weight
*/
public setState(timeSeconds: number, weight: number): void
{
this._stateTimeSeconds = timeSeconds;
this._stateWeight = weight;
}
/**
*
* @return []
*/
public getStateTime(): number
{
return this._stateTimeSeconds;
}
/**
*
* @return
*/
public getStateWeight(): number
{
return this._stateWeight;
}
/**
*
*
* @return []
*/
public getLastCheckEventTime(): number
{
return this._lastEventCheckSeconds;
}
/**
*
* @param checkTime []
*/
public setLastCheckEventTime(checkTime: number): void
{
this._lastEventCheckSeconds = checkTime;
}
_autoDelete: boolean; // 自動削除
_motion: ACubismMotion; // モーション
_available: boolean; // 有効化フラグ
_finished: boolean; // 終了フラグ
_started: boolean; // 開始フラグ
_startTimeSeconds: number; // モーション再生開始時刻[秒]
_fadeInStartTimeSeconds: number; // フェードイン開始時刻(ループの時は初回のみ)[秒]
_endTimeSeconds: number; // 終了予定時刻[秒]
_stateTimeSeconds: number; // 時刻の状態[秒]
_stateWeight: number;  // 重みの状態
_lastEventCheckSeconds: number; // 最終のMotion側のチェックした時間
_motionQueueEntryHandle: CubismMotionQueueEntryHandle; // インスタンスごとに一意の値を持つ識別番号
}
}

View File

@ -0,0 +1,342 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
import {Live2DCubismFramework as acubismmotion} from './acubismmotion';
import {Live2DCubismFramework as cubismmotionqueueentry} from './cubismmotionqueueentry';
import {Live2DCubismFramework as csmvector} from '../type/csmvector';
import {Live2DCubismFramework as cubismmodel} from '../model/cubismmodel';
import {Live2DCubismFramework as csmstring} from '../type/csmstring';
import csmString = csmstring.csmString;
import CubismModel = cubismmodel.CubismModel;
import csmVector = csmvector.csmVector;
import CubismMotionQueueEntry = cubismmotionqueueentry.CubismMotionQueueEntry;
import ACubismMotion = acubismmotion.ACubismMotion;
export namespace Live2DCubismFramework
{
/**
*
*
* CubismMotionACubismMotion使
*
* @note StartMotion()
*
* CubismMotionQueueManager使
*/
export class CubismMotionQueueManager
{
/**
*
*/
public constructor()
{
this._userTimeSeconds = 0.0;
this._eventCallBack = null;
this._eventCustomData = null;
this._motions = new csmVector<CubismMotionQueueEntry>();
}
/**
*
*/
public release(): void
{
for(let i: number = 0; i < this._motions.getSize(); ++i)
{
if(this._motions.at(i))
{
this._motions.at(i).release();
this._motions.set(i, void 0);
this._motions.set(i, null);
}
}
this._motions = null;
}
/**
*
*
*
*
* @param motion
* @param autoDelete true
* @param userTimeSeconds []
* @return IsFinished()使-1
*/
public startMotion(motion: ACubismMotion, autoDelete: boolean, userTimeSeconds: number): CubismMotionQueueEntryHandle
{
if(motion == null)
{
return InvalidMotionQueueEntryHandleValue;
}
let motionQueueEntry: CubismMotionQueueEntry = null;
// 既にモーションがあれば終了フラグを立てる
for(let i: number = 0; i < this._motions.getSize(); ++i)
{
motionQueueEntry = this._motions.at(i);
if(motionQueueEntry == null)
{
continue;
}
motionQueueEntry.startFadeout(motionQueueEntry._motion.getFadeOutTime(), userTimeSeconds); // フェードアウトを開始し終了する
}
motionQueueEntry = new CubismMotionQueueEntry(); // 終了時に破棄する
motionQueueEntry._autoDelete = autoDelete;
motionQueueEntry._motion = motion;
this._motions.pushBack(motionQueueEntry);
return motionQueueEntry._motionQueueEntryHandle;
}
/**
*
* @return true
* @return false
*/
public isFinished(): boolean
{
// ------- 処理を行う -------
// 既にモーションがあれば終了フラグを立てる
for(let ite: csmVector.iterator<CubismMotionQueueEntry> = this._motions.begin(); ite.notEqual(this._motions.end());)
{
let motionQueueEntry: CubismMotionQueueEntry = ite.ptr();
if(motionQueueEntry == null)
{
ite = this._motions.erase(ite); // 削除
continue;
}
let motion: ACubismMotion = motionQueueEntry._motion;
if(motion == null)
{
motionQueueEntry.release();
motionQueueEntry = void 0;
motionQueueEntry = null;
ite = this._motions.erase(ite); // 削除
continue;
}
// ----- 終了済みの処理があれば削除する ------
if(!motionQueueEntry.isFinished())
{
return false;
}
else
{
ite.preIncrement();
}
}
return true;
}
/**
*
* @param motionQueueEntryNumber
* @return true
* @return false
*/
public isFinishedByHandle(motionQueueEntryNumber: CubismMotionQueueEntryHandle): boolean
{
// 既にモーションがあれば終了フラグを立てる
for(let ite: csmVector.iterator<CubismMotionQueueEntry> = this._motions.begin(); ite.notEqual(this._motions.end());ite.increment())
{
let motionQueueEntry: CubismMotionQueueEntry = ite.ptr();
if(motionQueueEntry == null)
{
continue;
}
if(motionQueueEntry._motionQueueEntryHandle == motionQueueEntryNumber && !motionQueueEntry.isFinished())
{
return false;
}
}
return true;
}
/**
*
*/
public stopAllMotions(): void
{
// ------- 処理を行う -------
// 既にモーションがあれば終了フラグを立てる
for(let ite: csmVector.iterator<CubismMotionQueueEntry> = this._motions.begin(); ite.notEqual(this._motions.end());)
{
let motionQueueEntry: CubismMotionQueueEntry = ite.ptr();
if(motionQueueEntry == null)
{
ite = this._motions.erase(ite);
continue;
}
// ----- 終了済みの処理があれば削除する ------
motionQueueEntry.release();
motionQueueEntry = void 0;
motionQueueEntry = null;
ite = this._motions.erase(ite); // 削除
}
}
/**
* CubismMotionQueueEntry
* @param motionQueueEntryNumber
* @return CubismMotionQueueEntry
* @return null
*/
public getCubismMotionQueueEntry(motionQueueEntryNumber: any): CubismMotionQueueEntry
{
//------- 処理を行う -------
// 既にモーションがあれば終了フラグを立てる
for(let ite: csmVector.iterator<CubismMotionQueueEntry> = this._motions.begin(); ite.notEqual(this._motions.end()); ite.preIncrement())
{
let motionQueueEntry: CubismMotionQueueEntry = ite.ptr();
if(motionQueueEntry == null)
{
continue;
}
if(motionQueueEntry._motionQueueEntryHandle == motionQueueEntryNumber)
{
return motionQueueEntry;
}
}
return null;
}
/**
* Callback
*
* @param callback
* @param customData
*/
public setEventCallback(callback: CubismMotionEventFunction, customData: any = null): void
{
this._eventCallBack = callback;
this._eventCustomData = customData;
}
/**
*
*
* @param model
* @param userTimeSeconds []
* @return true
* @return false ()
*/
public doUpdateMotion(model: CubismModel, userTimeSeconds: number): boolean
{
let updated: boolean = false;
// ------- 処理を行う --------
// 既にモーションがあれば終了フラグを立てる
for(let ite: csmVector.iterator<CubismMotionQueueEntry> = this._motions.begin(); ite.notEqual(this._motions.end());)
{
let motionQueueEntry: CubismMotionQueueEntry = ite.ptr();
if(motionQueueEntry == null)
{
ite = this._motions.erase(ite); // 削除
continue;
}
let motion: ACubismMotion = motionQueueEntry._motion;
if(motion == null)
{
motionQueueEntry.release();
motionQueueEntry = void 0;
motionQueueEntry = null;
ite = this._motions.erase(ite); // 削除
continue;
}
// ------ 値を反映する ------
motion.updateParameters(model, motionQueueEntry, userTimeSeconds);
updated = true;
// ------ ユーザトリガーイベントを検査する ----
const firedList: csmVector<csmString> = motion.getFiredEvent(
motionQueueEntry.getLastCheckEventTime() - motionQueueEntry.getStartTime(),
userTimeSeconds - motionQueueEntry.getStartTime()
);
for(let i: number = 0; i < firedList.getSize(); ++i)
{
this._eventCallBack(this, firedList.at(i), this._eventCustomData);
}
motionQueueEntry.setLastCheckEventTime(userTimeSeconds);
// ------ 終了済みの処理があれば削除する ------
if(motionQueueEntry.isFinished())
{
motionQueueEntry.release();
motionQueueEntry = void 0;
motionQueueEntry = null;
ite = this._motions.erase(ite); // 削除
}
else
{
ite.preIncrement();
}
}
return updated;
}
_userTimeSeconds: number; // デルタ時間の積算値[秒]
_motions: csmVector<CubismMotionQueueEntry>; // モーション
_eventCallBack: CubismMotionEventFunction; // コールバック関数
_eventCustomData: any; // コールバックに戻されるデータ
}
/**
*
*
*
* @param caller CubismMotionQueueManager
* @param eventValue
* @param customData
*/
export interface CubismMotionEventFunction
{
(
caller: CubismMotionQueueManager,
eventValue: csmString,
customData: any
): void;
}
/**
*
*
*
*/
export declare type CubismMotionQueueEntryHandle = any;
export const InvalidMotionQueueEntryHandleValue: CubismMotionQueueEntryHandle = -1;
}

View File

@ -0,0 +1,826 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
import {Live2DCubismFramework as cubismphysicsinternal} from './cubismphysicsinternal';
import {Live2DCubismFramework as cubismmodel} from '../model/cubismmodel';
import {Live2DCubismFramework as cubismvector2} from '../math/cubismvector2';
import {Live2DCubismFramework as cubismmath} from '../math/cubismmath';
import {Live2DCubismFramework as cubismphysicsjson} from './cubismphysicsjson';
import CubismPhysicsJson = cubismphysicsjson.CubismPhysicsJson;
import CubismMath = cubismmath.CubismMath;
import CubismPhysicsRig = cubismphysicsinternal.CubismPhysicsRig;
import CubismPhysicsSubRig = cubismphysicsinternal.CubismPhysicsSubRig;
import CubismPhysicsInput = cubismphysicsinternal.CubismPhysicsInput;
import CubismPhysicsOutput = cubismphysicsinternal.CubismPhysicsOutput;
import CubismPhysicsParticle = cubismphysicsinternal.CubismPhysicsParticle;
import CubismPhysicsSource = cubismphysicsinternal.CubismPhysicsSource;
import CubismPhysicsTargetType = cubismphysicsinternal.CubismPhysicsTargetType;
import CubismPhysicsNormalization = cubismphysicsinternal.CubismPhysicsNormalization;
import CubismVector2 = cubismvector2.CubismVector2;
import CubismModel = cubismmodel.CubismModel;
export namespace Live2DCubismFramework
{
/// physics types tags.
const PhysicsTypeTagX: string = "X";
const PhysicsTypeTagY: string = "Y";
const PhysicsTypeTagAngle: string = "Angle";
/// Constant of air resistance.
const AirResistance: number = 5.0;
/// Constant of maximum weight of input and output ratio.
const MaximumWeight: number = 100.0;
/// Constant of threshold of movement.
const MovementThreshold: number = 0.001;
/**
*
*/
export class CubismPhysics
{
/**
*
* @param buffer physics3.json
* @param size
* @return
*/
public static create(buffer: ArrayBuffer, size: number): CubismPhysics
{
let ret: CubismPhysics = new CubismPhysics();
ret.parse(buffer, size);
ret._physicsRig.gravity.y = 0;
return ret;
}
/**
*
* @param physics
*/
public static delete(physics: CubismPhysics): void
{
physics.release();
physics = void 0;
physics = null;
}
/**
*
* @param model
* @param deltaTimeSeconds []
*/
public evaluate(model: CubismModel, deltaTimeSeconds: number): void
{
let totalAngle: {angle: number};
let weight: number;
let radAngle: number;
let outputValue: number;
let totalTranslation: CubismVector2 = new CubismVector2();
let currentSetting: CubismPhysicsSubRig;
let currentInput: CubismPhysicsInput[];
let currentOutput: CubismPhysicsOutput[];
let currentParticles: CubismPhysicsParticle[];
let parameterValue: Float32Array;
let parameterMaximumValue: Float32Array;
let parameterMinimumValue: Float32Array;
let parameterDefaultValue: Float32Array;
parameterValue = model.getModel().parameters.values;
parameterMaximumValue = model.getModel().parameters.maximumValues;
parameterMinimumValue = model.getModel().parameters.minimumValues;
parameterDefaultValue = model.getModel().parameters.defaultValues;
for(let settingIndex: number = 0; settingIndex < this._physicsRig.subRigCount; ++settingIndex)
{
totalAngle = {angle: 0.0};
totalTranslation.x = 0.0;
totalTranslation.y = 0.0;
currentSetting = this._physicsRig.settings.at(settingIndex);
currentInput = this._physicsRig.inputs.get(currentSetting.baseInputIndex);
currentOutput = this._physicsRig.outputs.get(currentSetting.baseOutputIndex);
currentParticles = this._physicsRig.particles.get(currentSetting.baseParticleIndex);
// Load input parameters
for(let i: number = 0; i < currentSetting.inputCount; ++i)
{
weight = currentInput[i].weight / MaximumWeight;
if(currentInput[i].sourceParameterIndex == -1)
{
currentInput[i].sourceParameterIndex = model.getParameterIndex(currentInput[i].source.id);
}
currentInput[i].getNormalizedParameterValue(
totalTranslation,
totalAngle,
parameterValue[currentInput[i].sourceParameterIndex],
parameterMinimumValue[currentInput[i].sourceParameterIndex],
parameterMaximumValue[currentInput[i].sourceParameterIndex],
parameterDefaultValue[currentInput[i].sourceParameterIndex],
currentSetting.normalizationPosition,
currentSetting.normalizationAngle,
currentInput[0].reflect,
weight
);
}
radAngle = CubismMath.degreesToRadian(-totalAngle.angle);
totalTranslation.x = (totalTranslation.x * CubismMath.cos(radAngle) - totalTranslation.y * CubismMath.sin(radAngle));
totalTranslation.y = (totalTranslation.x * CubismMath.sin(radAngle) + totalTranslation.y * CubismMath.cos(radAngle));
// Calculate particles position.
updateParticles(
currentParticles,
currentSetting.particleCount,
totalTranslation,
totalAngle.angle,
this._options.wind,
MovementThreshold * currentSetting.normalizationPosition.maximum,
deltaTimeSeconds,
AirResistance
);
// Update output parameters.
for (let i: number = 0; i < currentSetting.outputCount; ++i)
{
let particleIndex = currentOutput[i].vertexIndex;
if(particleIndex < 1 || particleIndex >= currentSetting.particleCount)
{
break;
}
if(currentOutput[i].destinationParameterIndex == -1)
{
currentOutput[i].destinationParameterIndex = model.getParameterIndex(currentOutput[i].destination.id);
}
let translation: CubismVector2 = new CubismVector2();
translation.x = currentParticles[particleIndex].position.x - currentParticles[particleIndex - 1].position.x;
translation.y = currentParticles[particleIndex].position.y - currentParticles[particleIndex - 1].position.y;
outputValue = currentOutput[i].getValue(
translation,
currentParticles,
particleIndex,
currentOutput[i].reflect,
this._options.gravity
);
let destinationParameterIndex = currentOutput[i].destinationParameterIndex;
let outParameterValue = parameterValue.slice(destinationParameterIndex);
updateOutputParameterValue(
outParameterValue,
parameterMinimumValue[destinationParameterIndex],
parameterMaximumValue[destinationParameterIndex],
outputValue,
currentOutput[i]
);
// 値を反映
for(let offset: number = destinationParameterIndex, outParamIndex: number = 0; offset < parameterValue.length; offset++, outParamIndex++)
{
parameterValue[offset] = outParameterValue[outParamIndex];
}
}
}
}
/**
*
* @param options
*/
public setOptions(options: CubismPhysics.Options): void
{
this._options = options;
}
/**
*
* @return
*/
public getOption(): CubismPhysics.Options
{
return this._options;
}
/**
*
*/
public constructor()
{
this._physicsRig = null;
// set default options
this._options = new CubismPhysics.Options();
this._options.gravity.y = -1.0;
this._options.gravity.x = 0;
this._options.wind.x = 0;
this._options.wind.y = 0;
}
/**
*
*/
public release(): void
{
this._physicsRig = void 0;
this._physicsRig = null;
}
/**
* physics3.json
* @param physicsJson physics3.json
* @param size
*/
public parse(physicsJson: ArrayBuffer, size: number): void
{
this._physicsRig = new CubismPhysicsRig();
let json: CubismPhysicsJson = new CubismPhysicsJson(physicsJson, size);
this._physicsRig.gravity = json.getGravity();
this._physicsRig.wind = json.getWind();
this._physicsRig.subRigCount = json.getSubRigCount();
this._physicsRig.settings.updateSize(this._physicsRig.subRigCount, CubismPhysicsSubRig, true);
this._physicsRig.inputs.updateSize(json.getTotalInputCount(), CubismPhysicsInput, true);
this._physicsRig.outputs.updateSize(json.getTotalOutputCount(), CubismPhysicsOutput, true);
this._physicsRig.particles.updateSize(json.getVertexCount(), CubismPhysicsParticle, true);
let inputIndex: number = 0, outputIndex: number = 0, particleIndex: number = 0;
for(let i: number = 0; i < this._physicsRig.settings.getSize(); ++i)
{
this._physicsRig.settings.at(i).normalizationPosition.minimum = json.getNormalizationPositionMinimumValue(i);
this._physicsRig.settings.at(i).normalizationPosition.maximum = json.getNormalizationPositionMaximumValue(i);
this._physicsRig.settings.at(i).normalizationPosition.defalut = json.getNormalizationPositionDefaultValue(i);
this._physicsRig.settings.at(i).normalizationAngle.minimum = json.getNormalizationAngleMinimumValue(i);
this._physicsRig.settings.at(i).normalizationAngle.maximum = json.getNormalizationAngleMaximumValue(i);
this._physicsRig.settings.at(i).normalizationAngle.defalut = json.getNormalizationAngleDefaultValue(i);
// Input
this._physicsRig.settings.at(i).inputCount = json.getInputCount(i);
this._physicsRig.settings.at(i).baseInputIndex = inputIndex;
for(let j: number = 0; j < this._physicsRig.settings.at(i).inputCount; ++j)
{
this._physicsRig.inputs.at(inputIndex + j).sourceParameterIndex = -1;
this._physicsRig.inputs.at(inputIndex + j).weight = json.getInputWeight(i, j);
this._physicsRig.inputs.at(inputIndex + j).reflect = json.getInputReflect(i, j);
if(json.getInputType(i, j) == PhysicsTypeTagX)
{
this._physicsRig.inputs.at(inputIndex + j).type = CubismPhysicsSource.CubismPhysicsSource_X;
this._physicsRig.inputs.at(inputIndex + j).getNormalizedParameterValue = getInputTranslationXFromNormalizedParameterValue;
}
else if(json.getInputType(i, j) == PhysicsTypeTagY)
{
this._physicsRig.inputs.at(inputIndex + j).type = CubismPhysicsSource.CubismPhysicsSource_Y;
this._physicsRig.inputs.at(inputIndex + j).getNormalizedParameterValue = getInputTranslationYFromNormalizedParamterValue;
}
else if(json.getInputType(i, j) == PhysicsTypeTagAngle)
{
this._physicsRig.inputs.at(inputIndex + j).type = CubismPhysicsSource.CubismPhysicsSource_Angle;
this._physicsRig.inputs.at(inputIndex + j).getNormalizedParameterValue = getInputAngleFromNormalizedParameterValue;
}
this._physicsRig.inputs.at(inputIndex + j).source.targetType = CubismPhysicsTargetType.CubismPhysicsTargetType_Parameter;
this._physicsRig.inputs.at(inputIndex + j).source.id = json.getInputSourceId(i, j);
}
inputIndex += this._physicsRig.settings.at(i).inputCount;
// Output
this._physicsRig.settings.at(i).outputCount = json.getOutputCount(i);
this._physicsRig.settings.at(i).baseOutputIndex = outputIndex;
for(let j: number = 0; j < this._physicsRig.settings.at(i).outputCount; ++j)
{
this._physicsRig.outputs.at(outputIndex + j).destinationParameterIndex = -1;
this._physicsRig.outputs.at(outputIndex + j).vertexIndex = json.getOutputVertexIndex(i, j);
this._physicsRig.outputs.at(outputIndex + j).angleScale = json.getOutputAngleScale(i, j);
this._physicsRig.outputs.at(outputIndex + j).weight = json.getOutputWeight(i, j);
this._physicsRig.outputs.at(outputIndex + j).destination.targetType = CubismPhysicsTargetType.CubismPhysicsTargetType_Parameter;
this._physicsRig.outputs.at(outputIndex + j).destination.id = json.getOutputDestinationId(i, j);
if(json.getOutputType(i, j) == PhysicsTypeTagX)
{
this._physicsRig.outputs.at(outputIndex + j).type = CubismPhysicsSource.CubismPhysicsSource_X;
this._physicsRig.outputs.at(outputIndex + j).getValue = getOutputTranslationX;
this._physicsRig.outputs.at(outputIndex + j).getScale = getOutputScaleTranslationX;
}
else if(json.getOutputType(i, j) == PhysicsTypeTagY)
{
this._physicsRig.outputs.at(outputIndex + j).type = CubismPhysicsSource.CubismPhysicsSource_Y;
this._physicsRig.outputs.at(outputIndex + j).getValue = getOutputTranslationY;
this._physicsRig.outputs.at(outputIndex + j).getScale = getOutputScaleTranslationY;
}
else if(json.getOutputType(i, j) == PhysicsTypeTagAngle)
{
this._physicsRig.outputs.at(outputIndex + j).type = CubismPhysicsSource.CubismPhysicsSource_Angle;
this._physicsRig.outputs.at(outputIndex + j).getValue = getOutputAngle;
this._physicsRig.outputs.at(outputIndex + j).getScale = getOutputScaleAngle;
}
this._physicsRig.outputs.at(outputIndex + j).reflect = json.getOutputReflect(i, j);
}
outputIndex += this._physicsRig.settings.at(i).outputCount;
// Particle
this._physicsRig.settings.at(i).particleCount = json.getParticleCount(i);
this._physicsRig.settings.at(i).baseParticleIndex = particleIndex;
for(let j: number = 0; j < this._physicsRig.settings.at(i).particleCount; ++j)
{
this._physicsRig.particles.at(particleIndex + j).mobility = json.getParticleMobility(i, j);
this._physicsRig.particles.at(particleIndex + j).delay = json.getParticleDelay(i, j);
this._physicsRig.particles.at(particleIndex + j).acceleration = json.getParticleAcceleration(i, j);
this._physicsRig.particles.at(particleIndex + j).radius = json.getParticleRadius(i, j);
this._physicsRig.particles.at(particleIndex + j).position = json.getParticlePosition(i, j);
}
particleIndex += this._physicsRig.settings.at(i).particleCount;
}
this.initialize();
json.release();
json = void 0;
json = null;
}
/**
*
*/
public initialize(): void
{
let strand: CubismPhysicsParticle[];
let currentSetting: CubismPhysicsSubRig;
let radius: CubismVector2;
for (let settingIndex: number = 0; settingIndex < this._physicsRig.subRigCount; ++settingIndex)
{
currentSetting = this._physicsRig.settings.at(settingIndex);
strand = this._physicsRig.particles.get(currentSetting.baseParticleIndex);
// Initialize the top of particle.
strand[0].initialPosition = new CubismVector2(0.0, 0.0);
strand[0].lastPosition = new CubismVector2(strand[0].initialPosition.x, strand[0].initialPosition.y);
strand[0].lastGravity = new CubismVector2(0.0, -1.0);
strand[0].lastGravity.y *= -1.0;
strand[0].velocity = new CubismVector2(0.0, 0.0);
strand[0].force = new CubismVector2(0.0, 0.0);
// Initialize paritcles.
for (let i: number = 1; i < currentSetting.particleCount; ++i)
{
radius = new CubismVector2(0.0, 0.0);
radius.y = strand[i].radius;
strand[i].initialPosition = new CubismVector2(strand[i - 1].initialPosition.x + radius.x, strand[i - 1].initialPosition.y + radius.y);
strand[i].position = new CubismVector2(strand[i].initialPosition.x, strand[i].initialPosition.y);
strand[i].lastPosition = new CubismVector2(strand[i].initialPosition.x, strand[i].initialPosition.y);
strand[i].lastGravity = new CubismVector2(0.0, -1.0);
strand[i].lastGravity.y *= -1.0;
strand[i].velocity = new CubismVector2(0.0, 0.0);
strand[i].force = new CubismVector2(0.0, 0.0);
}
}
}
_physicsRig: CubismPhysicsRig; // 物理演算のデータ
_options: CubismPhysics.Options; // オプション
}
export namespace CubismPhysics
{
/**
*
*/
export class Options
{
constructor()
{
this.gravity = new CubismVector2(0, 0);
this.wind = new CubismVector2(0, 0);
}
gravity: CubismVector2; // 重力方向
wind: CubismVector2; // 風の方向
}
}
/**
* Gets sign.
*
* @param value Evaluation target value.
*
* @return Sign of value.
*/
function sign(value: number): number
{
let ret: number = 0;
if(value > 0.0)
{
ret = 1;
}
else if(value < 0.0)
{
ret = -1;
}
return ret;
}
function getInputTranslationXFromNormalizedParameterValue(
targetTranslation: CubismVector2,
targetAngle: {angle: number},
value: number,
parameterMinimumValue: number,
parameterMaximumValue: number,
parameterDefaultValue: number,
normalizationPosition: CubismPhysicsNormalization,
normalizationAngle: CubismPhysicsNormalization,
isInverted: boolean,
weight: number): void
{
targetTranslation.x += normalizeParameterValue(
value,
parameterMinimumValue,
parameterMaximumValue,
parameterDefaultValue,
normalizationPosition.minimum,
normalizationPosition.maximum,
normalizationPosition.defalut,
isInverted
) * weight;
}
function getInputTranslationYFromNormalizedParamterValue(
targetTranslation: CubismVector2,
targetAngle: {angle: number},
value: number,
parameterMinimumValue: number,
parameterMaximumValue: number,
parameterDefaultValue: number,
normalizationPosition: CubismPhysicsNormalization,
normalizationAngle: CubismPhysicsNormalization,
isInverted: boolean,
weight: number): void
{
targetTranslation.y += normalizeParameterValue(
value,
parameterMinimumValue,
parameterMaximumValue,
parameterDefaultValue,
normalizationPosition.minimum,
normalizationPosition.maximum,
normalizationPosition.defalut,
isInverted
) * weight;
}
function getInputAngleFromNormalizedParameterValue(
targetTranslation: CubismVector2,
targetAngle: {angle: number},
value: number,
parameterMinimumValue: number,
parameterMaximumValue: number,
parameterDefaultValue: number,
normalizaitionPosition: CubismPhysicsNormalization,
normalizationAngle: CubismPhysicsNormalization,
isInverted: boolean,
weight: number): void
{
targetAngle.angle += normalizeParameterValue(
value,
parameterMinimumValue,
parameterMaximumValue,
parameterDefaultValue,
normalizationAngle.minimum,
normalizationAngle.maximum,
normalizationAngle.defalut,
isInverted,
) * weight;
}
function getOutputTranslationX(
translation: CubismVector2,
particles: CubismPhysicsParticle[],
particleIndex: number,
isInverted: boolean,
parentGravity: CubismVector2): number
{
let outputValue: number = translation.x;
if(isInverted)
{
outputValue *= -1.0;
}
return outputValue;
}
function getOutputTranslationY(
translation: CubismVector2,
particles: CubismPhysicsParticle[],
particleIndex: number,
isInverted: boolean,
parentGravity: CubismVector2): number
{
let outputValue: number = translation.y;
if(isInverted)
{
outputValue *= -1.0;
}
return outputValue;
}
function getOutputAngle(
translation: CubismVector2,
particles: CubismPhysicsParticle[],
particleIndex: number,
isInverted: boolean,
parentGravity: CubismVector2): number
{
let outputValue: number;
if(particleIndex >= 2)
{
parentGravity = particles[particleIndex - 1].position.substract(particles[particleIndex - 2].position);
}
else
{
parentGravity = parentGravity.multiplyByScaler(-1.0);
}
outputValue = CubismMath.directionToRadian(parentGravity, translation);
if(isInverted)
{
outputValue *= -1.0;
}
return outputValue;
}
function getRangeValue(min: number, max: number): number
{
let maxValue: number = CubismMath.max(min, max);
let minValue: number = CubismMath.min(min, max);
return CubismMath.abs(maxValue - minValue);
}
function getDefaultValue(min: number, max: number): number
{
const minValue: number = CubismMath.min(min, max);
return minValue + (getRangeValue(min, max) / 2.0);
}
function getOutputScaleTranslationX(translationScale: CubismVector2, angleScale: number): number
{
return JSON.parse(JSON.stringify(translationScale.x));
}
function getOutputScaleTranslationY(translationScale: CubismVector2, angleScale: number): number
{
return JSON.parse(JSON.stringify(translationScale.y));
}
function getOutputScaleAngle(translationScale: CubismVector2, angleScale: number): number
{
return JSON.parse(JSON.stringify(angleScale));
}
/**
* Updates particles.
*
* @param strand Target array of particle.
* @param strandCount Count of particle.
* @param totalTranslation Total translation value.
* @param totalAngle Total angle.
* @param windDirection Direction of Wind.
* @param thresholdValue Threshold of movement.
* @param deltaTimeSeconds Delta time.
* @param airResistance Air resistance.
*/
function updateParticles(
strand: CubismPhysicsParticle[],
strandCount: number,
totalTranslation: CubismVector2,
totalAngle: number,
windDirection: CubismVector2,
thresholdValue: number,
deltaTimeSeconds: number,
airResistance: number)
{
let totalRadian: number;
let delay: number;
let radian: number;
let currentGravity: CubismVector2;
let direction: CubismVector2 = new CubismVector2(0.0, 0.0);
let velocity: CubismVector2 = new CubismVector2(0.0, 0.0);
let force: CubismVector2 = new CubismVector2(0.0, 0.0);
let newDirection: CubismVector2 = new CubismVector2(0.0, 0.0);
strand[0].position = new CubismVector2(totalTranslation.x, totalTranslation.y);
totalRadian = CubismMath.degreesToRadian(totalAngle);
currentGravity = CubismMath.radianToDirection(totalRadian);
currentGravity.normalize();
for(let i: number = 1; i < strandCount; ++i)
{
strand[i].force = currentGravity.multiplyByScaler(strand[i].acceleration).add(windDirection);
strand[i].lastPosition = new CubismVector2(strand[i].position.x, strand[i].position.y);
delay = strand[i].delay * deltaTimeSeconds * 30.0;
direction = strand[i].position.substract(strand[i - 1].position);
radian = CubismMath.directionToRadian(strand[i].lastGravity, currentGravity) / airResistance;
direction.x = ((CubismMath.cos(radian) * direction.x) - (direction.y * CubismMath.sin(radian)));
direction.y = ((CubismMath.sin(radian) * direction.x) + (direction.y * CubismMath.cos(radian)));
strand[i].position = strand[i - 1].position.add(direction);
velocity = strand[i].velocity.multiplyByScaler(delay);
force = strand[i].force.multiplyByScaler(delay).multiplyByScaler(delay);
strand[i].position = strand[i].position.add(velocity).add(force);
newDirection = strand[i].position.substract(strand[i - 1].position);
newDirection.normalize();
strand[i].position = strand[i - 1].position.add(newDirection.multiplyByScaler(strand[i].radius));
if (CubismMath.abs(strand[i].position.x) < thresholdValue)
{
strand[i].position.x = 0.0;
}
if (delay != 0.0)
{
strand[i].velocity = strand[i].position.substract(strand[i].lastPosition);
strand[i].velocity = strand[i].velocity.divisionByScalar(delay);
strand[i].velocity = strand[i].velocity.multiplyByScaler(strand[i].mobility);
}
strand[i].force = new CubismVector2(0.0, 0.0);
strand[i].lastGravity = new CubismVector2(currentGravity.x, currentGravity.y);
}
}
/**
* Updates output parameter value.
* @param parameterValue Target parameter value.
* @param parameterValueMinimum Minimum of parameter value.
* @param parameterValueMaximum Maximum of parameter value.
* @param translation Translation value.
*/
function updateOutputParameterValue(
parameterValue: Float32Array,
parameterValueMinimum: number,
parameterValueMaximum: number,
translation: number,
output: CubismPhysicsOutput): void
{
let outputScale: number;
let value: number;
let weight: number;
outputScale = output.getScale(output.translationScale, output.angleScale);
value = translation * outputScale;
if (value < parameterValueMinimum)
{
if (value < output.valueBelowMinimum)
{
output.valueBelowMinimum = value;
}
value = parameterValueMinimum;
}
else if (value > parameterValueMaximum)
{
if (value > output.valueExceededMaximum)
{
output.valueExceededMaximum = value;
}
value = parameterValueMaximum;
}
weight = (output.weight / MaximumWeight);
if (weight >= 1.0)
{
parameterValue[0] = value;
}
else
{
value = (parameterValue[0] * (1.0 - weight)) + (value * weight);
parameterValue[0] = value;
}
}
function normalizeParameterValue(
value: number,
parameterMinimum: number,
parameterMaximum: number,
parameterDefault: number,
normalizedMinimum: number,
normalizedMaximum: number,
normalizedDefault: number,
isInverted: boolean)
{
let result: number = 0.0;
const maxValue: number = CubismMath.max(parameterMaximum, parameterMinimum);
if(maxValue < value)
{
return result;
}
const minValue: number = CubismMath.min(parameterMaximum, parameterMinimum);
if(minValue > value)
{
return result;
}
const minNormValue: number = CubismMath.min(normalizedMinimum, normalizedMaximum);
const maxNormValue: number = CubismMath.max(normalizedMinimum, normalizedMaximum);
const middleNormValue: number = normalizedDefault;
const middleValue: number = getDefaultValue(minValue, maxValue);
const paramValue: number = value - middleValue;
switch(sign(paramValue))
{
case 1:
{
const nLength: number = maxNormValue - middleNormValue;
const pLength: number = maxValue - middleValue;
if(pLength != 0.0)
{
result = paramValue * (nLength / pLength);
result += middleNormValue;
}
break;
}
case -1:
{
const nLength: number = minNormValue - middleNormValue;
const pLength: number = minValue - middleValue;
if(pLength != 0.0)
{
result = paramValue * (nLength / pLength);
result += middleNormValue;
}
break;
}
case 0:
{
result = middleNormValue;
break;
}
default:
{
break;
}
}
return (isInverted)
? result
: (result * -1.0);
}
}

View File

@ -0,0 +1,248 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
import {Live2DCubismFramework as cubismvector2} from '../math/cubismvector2';
import {Live2DCubismFramework as cubismid} from '../id/cubismid';
import {Live2DCubismFramework as csmvector} from '../type/csmvector';
import csmVector = csmvector.csmVector;
import CubismIdHandle = cubismid.CubismIdHandle;
import CubismVector2 = cubismvector2.CubismVector2;
export namespace Live2DCubismFramework
{
/**
*
*/
export enum CubismPhysicsTargetType
{
CubismPhysicsTargetType_Parameter, // パラメータに対して適用
}
/**
*
*/
export enum CubismPhysicsSource
{
CubismPhysicsSource_X, // X軸の位置から
CubismPhysicsSource_Y, // Y軸の位置から
CubismPhysicsSource_Angle, // 角度から
}
/**
* @brief 使
*
* 使
*/
export class PhysicsJsonEffectiveForces
{
constructor()
{
this.gravity = new CubismVector2(0, 0);
this.wind = new CubismVector2(0, 0);
}
gravity: CubismVector2; ///< 重力
wind: CubismVector2; ///< 風
}
/**
*
*/
export class CubismPhysicsParameter
{
id: CubismIdHandle; // パラメータ
targetType: CubismPhysicsTargetType; // 適用先の種類
}
/**
*
*/
export class CubismPhysicsNormalization
{
minimum: number; // 最大値
maximum: number; // 最小値
defalut: number; // デフォルト値
}
/**
* 使
*/
export class CubismPhysicsParticle
{
constructor()
{
this.initialPosition = new CubismVector2(0, 0);
this.position = new CubismVector2(0, 0);
this.lastPosition = new CubismVector2(0, 0);
this.lastGravity = new CubismVector2(0, 0);
this.force = new CubismVector2(0, 0);
this.velocity = new CubismVector2(0, 0);
}
initialPosition: CubismVector2; // 初期位置
mobility: number; // 動きやすさ
delay: number; // 遅れ
acceleration: number; // 加速度
radius: number; // 距離
position: CubismVector2; // 現在の位置
lastPosition: CubismVector2; // 最後の位置
lastGravity: CubismVector2; // 最後の重力
force: CubismVector2; // 現在かかっている力
velocity: CubismVector2; // 現在の速度
}
/**
*
*/
export class CubismPhysicsSubRig
{
constructor()
{
this.normalizationPosition = new CubismPhysicsNormalization();
this.normalizationAngle = new CubismPhysicsNormalization();
}
inputCount: number; // 入力の個数
outputCount: number; // 出力の個数
particleCount: number; // 物理点の個数
baseInputIndex: number; // 入力の最初のインデックス
baseOutputIndex: number; // 出力の最初のインデックス
baseParticleIndex: number; // 物理点の最初のインデックス
normalizationPosition: CubismPhysicsNormalization; // 正規化された位置
normalizationAngle: CubismPhysicsNormalization; // 正規化された角度
}
/**
*
* @param targetTranslation // 演算結果の移動値
* @param targetAngle // 演算結果の角度
* @param value // パラメータの値
* @param parameterMinimunValue // パラメータの最小値
* @param parameterMaximumValue // パラメータの最大値
* @param parameterDefaultValue // パラメータのデフォルト値
* @param normalizationPosition // 正規化された位置
* @param normalizationAngle // 正規化された角度
* @param isInverted // 値が反転されているか?
* @param weight // 重み
*/
export interface normalizedPhysicsParameterValueGetter
{
(
targetTranslation: CubismVector2,
targetAngle: {angle: number},
value: number,
parameterMinimunValue: number,
parameterMaximumValue: number,
parameterDefaultValue: number,
normalizationPosition: CubismPhysicsNormalization,
normalizationAngle: CubismPhysicsNormalization,
isInverted: boolean,
weight: number
): void
}
/**
*
* @param translation
* @param particles
* @param isInverted
* @param parentGravity
* @return
*/
export interface physicsValueGetter
{
(
translation: CubismVector2,
particles: CubismPhysicsParticle[],
particleIndex: number,
isInverted: boolean,
parentGravity: CubismVector2
): number
}
/**
*
* @param translationScale
* @param angleScale
* @return
*/
export interface physicsScaleGetter
{
(
translationScale: CubismVector2,
angleScale: number
): number;
}
/**
*
*/
export class CubismPhysicsInput
{
constructor()
{
this.source = new CubismPhysicsParameter();
}
source: CubismPhysicsParameter; // 入力元のパラメータ
sourceParameterIndex: number; // 入力元のパラメータのインデックス
weight: number; // 重み
type: number; // 入力の種類
reflect: boolean; // 値が反転されているかどうか
getNormalizedParameterValue: normalizedPhysicsParameterValueGetter; // 正規化されたパラメータ値の取得関数
}
/**
* @brief
*
*
*/
export class CubismPhysicsOutput
{
constructor()
{
this.destination = new CubismPhysicsParameter();
this.translationScale = new CubismVector2(0, 0);
}
destination: CubismPhysicsParameter; ///< 出力先のパラメータ
destinationParameterIndex: number; ///< 出力先のパラメータのインデックス
vertexIndex: number; ///< 振り子のインデックス
translationScale: CubismVector2; ///< 移動値のスケール
angleScale: number; ///< 角度のスケール
weight: number; /// 重み
type: CubismPhysicsSource; ///< 出力の種類
reflect: boolean; ///< 値が反転されているかどうか
valueBelowMinimum: number; ///< 最小値を下回った時の値
valueExceededMaximum: number; ///< 最大値をこえた時の値
getValue: physicsValueGetter; ///< 物理演算の値の取得関数
getScale: physicsScaleGetter; ///< 物理演算のスケール値の取得関数
}
/**
* @brief
*
*
*/
export class CubismPhysicsRig
{
constructor()
{
this.settings = new csmVector<CubismPhysicsSubRig>();
this.inputs = new csmVector<CubismPhysicsInput>();
this.outputs = new csmVector<CubismPhysicsOutput>();
this.particles = new csmVector<CubismPhysicsParticle>();
this.gravity = new CubismVector2(0, 0);
this.wind = new CubismVector2(0, 0);
}
subRigCount: number; ///< 物理演算の物理点の個数
settings: csmVector<CubismPhysicsSubRig>; ///< 物理演算の物理点の管理のリスト
inputs: csmVector<CubismPhysicsInput>; ///< 物理演算の入力のリスト
outputs: csmVector<CubismPhysicsOutput>; ///< 物理演算の出力のリスト
particles: csmVector<CubismPhysicsParticle>; ///< 物理演算の物理点のリスト
gravity: CubismVector2; ///< 重力
wind: CubismVector2; ///< 風
};
}

View File

@ -0,0 +1,407 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
import {Live2DCubismFramework as cubismjson} from '../utils/cubismjson';
import {Live2DCubismFramework as cubismvector2} from '../math/cubismvector2';
import {Live2DCubismFramework as cubismid} from '../id/cubismid';
import {Live2DCubismFramework as cubismframework} from '../live2dcubismframework';
import CubismFramework = cubismframework.CubismFramework;
import CubismIdHandle = cubismid.CubismIdHandle;
import CubismVector2 = cubismvector2.CubismVector2;
import CubismJson = cubismjson.CubismJson;
export namespace Live2DCubismFramework
{
// JSON keys
const Position: string = "Position";
const X: string = "X";
const Y: string = "Y";
const Angle: string = "Angle";
const Type: string = "Type";
const Id: string = "Id";
// Meta
const Meta: string = "Meta";
const EffectiveForces: string = "EffectiveForces";
const TotalInputCount: string = "TotalInputCount";
const TotalOutputCount: string = "TotalOutputCount";
const PhysicsSettingCount: string = "PhysicsSettingCount";
const Gravity: string = "Gravity";
const Wind: string = "Wind";
const VertexCount: string = "VertexCount";
// PhysicsSettings
const PhysicsSettings: string = "PhysicsSettings";
const Normalization: string = "Normalization";
const Minimum: string = "Minimum";
const Maximum: string = "Maximum";
const Default: string = "Default";
const Reflect: string = "Reflect";
const Weight: string = "Weight";
// Input
const Input: string = "Input";
const Source: string = "Source";
// Output
const Output: string = "Output";
const Scale: string = "Scale";
const VertexIndex: string = "VertexIndex";
const Destination: string = "Destination";
// Particle
const Vertices: string = "Vertices";
const Mobility: string = "Mobility";
const Delay: string = "Delay";
const Radius: string = "Radius";
const Acceleration: string = "Acceleration";
/**
* physics3.json
*/
export class CubismPhysicsJson
{
/**
*
* @param buffer physics3.json
* @param size
*/
public constructor(buffer: ArrayBuffer, size: number)
{
this._json = CubismJson.create(buffer, size);
}
/**
*
*/
public release(): void
{
CubismJson.delete(this._json);
}
/**
*
* @return
*/
public getGravity(): CubismVector2
{
let ret: CubismVector2 = new CubismVector2(0, 0);
ret.x = this._json.getRoot().getMap().getValue(Meta).getMap().getValue(EffectiveForces).getMap().getValue(Gravity).getMap().getValue(X).toFloat();
ret.y = this._json.getRoot().getMap().getValue(Meta).getMap().getValue(EffectiveForces).getMap().getValue(Gravity).getMap().getValue(Y).toFloat();
return ret;
}
/**
*
* @return
*/
public getWind(): CubismVector2
{
let ret: CubismVector2 = new CubismVector2(0, 0);
ret.x = this._json.getRoot().getMap().getValue(Meta).getMap().getValue(EffectiveForces).getMap().getValue(Wind).getMap().getValue(X).toFloat();
ret.y = this._json.getRoot().getMap().getValue(Meta).getMap().getValue(EffectiveForces).getMap().getValue(Wind).getMap().getValue(Y).toFloat();
return ret;
}
/**
*
* @return
*/
public getSubRigCount(): number
{
return this._json.getRoot().getMap().getValue(Meta).getMap().getValue(PhysicsSettingCount).toInt();
}
/**
*
* @return
*/
public getTotalInputCount(): number
{
return this._json.getRoot().getMap().getValue(Meta).getMap().getValue(TotalInputCount).toInt();
}
/**
*
* @return
*/
public getTotalOutputCount(): number
{
return this._json.getRoot().getMap().getValue(Meta).getMap().getValue(TotalOutputCount).toInt();
}
/**
*
* @return
*/
public getVertexCount(): number
{
return this._json.getRoot().getMap().getValue(Meta).getMap().getValue(VertexCount).toInt();
}
/**
*
* @param physicsSettingIndex
* @return
*/
public getNormalizationPositionMinimumValue(physicsSettingIndex: number): number
{
return this._json.getRoot().getMap().getValue(PhysicsSettings).getVector().at(physicsSettingIndex).getMap().getValue(Normalization).getMap().getValue(Position).getMap().getValue(Minimum).toFloat();
}
/**
*
* @param physicsSettingIndex
* @return
*/
public getNormalizationPositionMaximumValue(physicsSettingIndex: number): number
{
return this._json.getRoot().getMap().getValue(PhysicsSettings).getVector().at(physicsSettingIndex).getMap().getValue(Normalization).getMap().getValue(Position).getMap().getValue(Maximum).toFloat();
}
/**
*
* @param physicsSettingIndex
* @return
*/
public getNormalizationPositionDefaultValue(physicsSettingIndex: number): number
{
return this._json.getRoot().getMap().getValue(PhysicsSettings).getVector().at(physicsSettingIndex).getMap().getValue(Normalization).getMap().getValue(Position).getMap().getValue(Default).toFloat();
}
/**
*
* @param physicsSettingIndex
* @return
*/
public getNormalizationAngleMinimumValue(physicsSettingIndex: number): number
{
return this._json.getRoot().getMap().getValue(PhysicsSettings).getVector().at(physicsSettingIndex).getMap().getValue(Normalization).getMap().getValue(Angle).getMap().getValue(Minimum).toFloat();
}
/**
*
* @param physicsSettingIndex
* @return
*/
public getNormalizationAngleMaximumValue(physicsSettingIndex: number): number
{
return this._json.getRoot().getMap().getValue(PhysicsSettings).getVector().at(physicsSettingIndex).getMap().getValue(Normalization).getMap().getValue(Angle).getMap().getValue(Maximum).toFloat();
}
/**
*
* @param physicsSettingIndex
* @return
*/
public getNormalizationAngleDefaultValue(physicsSettingIndex: number): number
{
return this._json.getRoot().getMap().getValue(PhysicsSettings).getVector().at(physicsSettingIndex).getMap().getValue(Normalization).getMap().getValue(Angle).getMap().getValue(Default).toFloat();
}
/**
*
* @param physicsSettingIndex
* @return
*/
public getInputCount(physicsSettingIndex: number): number
{
return this._json.getRoot().getMap().getValue(PhysicsSettings).getVector().at(physicsSettingIndex).getMap().getValue(Input).getVector().getSize();
}
/**
*
* @param physicsSettingIndex
* @param inputIndex
* @return
*/
public getInputWeight(physicsSettingIndex: number, inputIndex: number): number
{
return this._json.getRoot().getMap().getValue(PhysicsSettings).getVector().at(physicsSettingIndex).getMap().getValue(Input).getVector().at(inputIndex).getMap().getValue(Weight).toFloat();
}
/**
*
* @param physicsSettingIndex
* @param inputIndex
* @return
*/
public getInputReflect(physicsSettingIndex: number, inputIndex: number): boolean
{
return this._json.getRoot().getMap().getValue(PhysicsSettings).getVector().at(physicsSettingIndex).getMap().getValue(Input).getVector().at(inputIndex).getMap().getValue(Reflect).toBoolean();
}
/**
*
* @param physicsSettingIndex
* @param inputIndex
* @return
*/
public getInputType(physicsSettingIndex: number, inputIndex: number): string
{
return this._json.getRoot().getMap().getValue(PhysicsSettings).getVector().at(physicsSettingIndex).getMap().getValue(Input).getVector().at(inputIndex).getMap().getValue(Type).getRawString();
}
/**
* ID
* @param physicsSettingIndex
* @param inputIndex
* @return ID
*/
public getInputSourceId(physicsSettingIndex: number, inputIndex: number): CubismIdHandle
{
return CubismFramework.getIdManager().getId(this._json.getRoot().getMap().getValue(PhysicsSettings).getVector().at(physicsSettingIndex).getMap().getValue(Input).getVector().at(inputIndex).getMap().getValue(Source).getMap().getValue(Id).getRawString());
}
/**
*
* @param physicsSettingIndex
* @return
*/
public getOutputCount(physicsSettingIndex: number): number
{
return this._json.getRoot().getMap().getValue(PhysicsSettings).getVector().at(physicsSettingIndex).getMap().getValue(Output).getVector().getSize();
}
/**
*
* @param physicsSettingIndex
* @param outputIndex
* @return
*/
public getOutputVertexIndex(physicsSettingIndex: number, outputIndex: number): number
{
return this._json.getRoot().getMap().getValue(PhysicsSettings).getVector().at(physicsSettingIndex).getMap().getValue(Output).getVector().at(outputIndex).getMap().getValue(VertexIndex).toInt();
}
/**
*
* @param physicsSettingIndex
* @param outputIndex
* @return
*/
public getOutputAngleScale(physicsSettingIndex: number, outputIndex: number): number
{
return this._json.getRoot().getMap().getValue(PhysicsSettings).getVector().at(physicsSettingIndex).getMap().getValue(Output).getVector().at(outputIndex).getMap().getValue(Scale).toFloat();
}
/**
*
* @param physicsSettingIndex
* @param outputIndex
* @return
*/
public getOutputWeight(physicsSettingIndex: number, outputIndex: number): number
{
return this._json.getRoot().getMap().getValue(PhysicsSettings).getVector().at(physicsSettingIndex).getMap().getValue(Output).getVector().at(outputIndex).getMap().getValue(Weight).toFloat();
}
/**
* ID
* @param physicsSettingIndex
* @param outputIndex 
* @return ID
*/
public getOutputDestinationId(physicsSettingIndex: number, outputIndex: number): CubismIdHandle
{
return CubismFramework.getIdManager().getId(this._json.getRoot().getMap().getValue(PhysicsSettings).getVector().at(physicsSettingIndex).getMap().getValue(Output).getVector().at(outputIndex).getMap().getValue(Destination).getMap().getValue(Id).getRawString());
}
/**
*
* @param physicsSettingIndex
* @param outputIndex
* @return
*/
public getOutputType(physicsSettingIndex: number, outputIndex: number): string
{
return this._json.getRoot().getMap().getValue(PhysicsSettings).getVector().at(physicsSettingIndex).getMap().getValue(Output).getVector().at(outputIndex).getMap().getValue(Type).getRawString();
}
/**
*
* @param physicsSettingIndex
* @param outputIndex
* @return
*/
public getOutputReflect(physicsSettingIndex: number, outputIndex: number): boolean
{
return this._json.getRoot().getMap().getValue(PhysicsSettings).getVector().at(physicsSettingIndex).getMap().getValue(Output).getVector().at(outputIndex).getMap().getValue(Reflect).toBoolean();
}
/**
*
* @param physicsSettingIndex
* @return
*/
public getParticleCount(physicsSettingIndex: number): number
{
return this._json.getRoot().getMap().getValue(PhysicsSettings).getVector().at(physicsSettingIndex).getMap().getValue(Vertices).getVector().getSize();
}
/**
*
* @param physicsSettingIndex
* @param vertexIndex
* @return
*/
public getParticleMobility(physicsSettingIndex: number, vertexIndex: number): number
{
return this._json.getRoot().getMap().getValue(PhysicsSettings).getVector().at(physicsSettingIndex).getMap().getValue(Vertices).getVector().at(vertexIndex).getMap().getValue(Mobility).toFloat();
}
/**
*
* @param physicsSettingIndex
* @param vertexIndex
* @return
*/
public getParticleDelay(physicsSettingIndex: number, vertexIndex: number): number
{
return this._json.getRoot().getMap().getValue(PhysicsSettings).getVector().at(physicsSettingIndex).getMap().getValue(Vertices).getVector().at(vertexIndex).getMap().getValue(Delay).toFloat();
}
/**
*
* @param physicsSettingIndex
* @param vertexIndex
* @return
*/
public getParticleAcceleration(physicsSettingIndex: number, vertexIndex: number): number
{
return this._json.getRoot().getMap().getValue(PhysicsSettings).getVector().at(physicsSettingIndex).getMap().getValue(Vertices).getVector().at(vertexIndex).getMap().getValue(Acceleration).toFloat();
}
/**
*
* @param physicsSettingIndex
* @param vertexIndex
* @return
*/
public getParticleRadius(physicsSettingIndex: number, vertexIndex: number): number
{
return this._json.getRoot().getMap().getValue(PhysicsSettings).getVector().at(physicsSettingIndex).getMap().getValue(Vertices).getVector().at(vertexIndex).getMap().getValue(Radius).toInt();
}
/**
*
* @param physicsSettingIndex
* @param vertexInde
* @return
*/
public getParticlePosition(physicsSettingIndex: number, vertexIndex): CubismVector2
{
let ret: CubismVector2 = new CubismVector2(0, 0);
ret.x = this._json.getRoot().getMap().getValue(PhysicsSettings).getVector().at(physicsSettingIndex).getMap().getValue(Vertices).getVector().at(vertexIndex).getMap().getValue(Position).getMap().getValue(X).toFloat();
ret.y = this._json.getRoot().getMap().getValue(PhysicsSettings).getVector().at(physicsSettingIndex).getMap().getValue(Vertices).getVector().at(vertexIndex).getMap().getValue(Position).getMap().getValue(Y).toFloat();
return ret;
}
_json: CubismJson; // physics3.jsonデータ
}
}

View File

@ -0,0 +1,312 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
import {Live2DCubismFramework as cubismmatrix44} from '../math/cubismmatrix44';
import {Live2DCubismFramework as cubismmodel} from '../model/cubismmodel';
import CubismModel = cubismmodel.CubismModel;
import CubismMatrix44 = cubismmatrix44.CubismMatrix44;
export namespace Live2DCubismFramework
{
/**
*
*
*
*/
export abstract class CubismRenderer
{
/**
*
*
* @return
*/
public static create(): CubismRenderer
{
return null;
}
/**
*
*/
public static delete(renderer: CubismRenderer): void
{
renderer = void 0;
renderer = null;
}
/**
*
*/
public static StaticRelease(): void
{
//CubismRenderer_WebGL.doStaticRelease();
}
/**
*
*
* @param model
*/
public initialize(model: CubismModel): void
{
this._model = model;
}
/**
*
*/
public drawModel(): void
{
if(this.getModel() == null) return;
/**
* doDrawModel
* saveProfile();
* restoreProfile();
*
*
*/
this.saveProfile();
this.doDrawModel();
this.restoreProfile();
}
/**
* Model-View-Projection
*
* @param matrix44 Model-View-Projection
*/
public setMvpMatrix(matrix44: CubismMatrix44): void
{
this._mvpMatrix4x4.setMatrix(matrix44.getArray());
}
/**
* Model-View-Projection
* @return Model-View-Projection
*/
public getMvpMatrix(): CubismMatrix44
{
return this._mvpMatrix4x4;
}
/**
*
* 0.0~1.01.0
* @param red
* @param green
* @param blue
* @param alpha α
*/
public setModelColor(red: number, green: number, blue: number, alpha: number): void
{
if(red < 0.0)
{
red = 0.0;
}
else if(red > 1.0)
{
red = 1.0;
}
if(green < 0.0)
{
green = 0.0;
}
else if(green > 1.0)
{
green = 1.0;
}
if(blue < 0.0)
{
blue = 0.0;
}
else if(blue > 1.0)
{
blue = 1.0;
}
if(alpha < 0.0)
{
alpha = 0.0;
}
else if(alpha > 1.0)
{
alpha = 1.0;
}
this._modelColor.R = red;
this._modelColor.G = green;
this._modelColor.B = blue;
this._modelColor.A = alpha;
}
/**
*
* 0.0~1.0(1.0)
*
* @return RGBA
*/
public getModelColor(): CubismRenderer.CubismTextureColor
{
return JSON.parse(JSON.stringify(this._modelColor));
}
/**
* α
* truefalse
*/
public setIsPremultipliedAlpha(enable: boolean): void
{
this._isPremultipliedAlpha = enable;
}
/**
* α
* @return true α
* @return false α
*/
public isPremultipliedAlpha(): boolean
{
return this._isPremultipliedAlpha;
}
/**
*
* truefalse
*/
public setIsCulling(culling: boolean): void
{
this._isCulling = culling;
}
/**
*
* @return true
* @return false
*/
public isCulling(): boolean
{
return this._isCulling;
}
/**
*
*
* @param n
*/
public setAnisotropy(n: number): void
{
this._anisortopy = n;
}
/**
*
* @return
*/
public getAnisotropy(): number
{
return this._anisortopy;
}
/**
*
* @return
*/
public getModel(): CubismModel
{
return this._model;
}
/**
*
*/
protected constructor()
{
this._isCulling = false;
this._isPremultipliedAlpha = false;
this._anisortopy = 0.0;
this._model = null;
this._modelColor = new CubismRenderer.CubismTextureColor();
// 単位行列に初期化
this._mvpMatrix4x4 = new CubismMatrix44();
this._mvpMatrix4x4.loadIdentity();
}
/**
*
*/
public abstract doDrawModel();
/**
*
*
* @param textureNo
* @param indexCount
* @param vertexCount
* @param indexArray
* @param vertexArray
* @param uvArray uv
* @param opacity
* @param colorBlendMode
*/
public abstract drawMesh(textureNo: number, indexCount: number, vertexCount: number,
indexArray: Uint16Array, vertexArray: Float32Array, uvArray: Float32Array,
opacity: number, colorBlendMode: CubismRenderer.CubismBlendMode);
/**
*
*/
public abstract saveProfile();
/**
*
*/
public abstract restoreProfile();
protected _mvpMatrix4x4: CubismMatrix44; // Model-View-Projection 行列
protected _modelColor: CubismRenderer.CubismTextureColor; // モデル自体のカラーRGBA
protected _isCulling: boolean; // カリングが有効ならtrue
protected _isPremultipliedAlpha: boolean; // 乗算済みαならtrue
protected _anisortopy: any; // テクスチャの異方性フィルタリングのパラメータ
protected _model: CubismModel; // レンダリング対象のモデル
}
export namespace CubismRenderer
{
export enum CubismBlendMode
{
CubismBlendMode_Normal = 0, // 通常
CubismBlendMode_Additive = 1, // 加算
CubismBlendMode_Multiplicative = 2, // 乗算
};
/**
* RGBA
*/
export class CubismTextureColor
{
/**
*
*/
constructor()
{
this.R = 1.0;
this.G = 1.0;
this.B = 1.0;
this.A = 1.0;
}
R: number; // 赤チャンネル
G: number; // 緑チャンネル
B: number; // 青チャンネル
A: number; // αチャンネル
}
}
}

File diff suppressed because it is too large Load Diff

12
Framework/tsconfig.json Normal file
View File

@ -0,0 +1,12 @@
{
"compilerOptions": {
"sourceMap": true,
"target": "es5",
"module": "es2015",
"moduleResolution": "node",
"lib": [
"dom",
"es2018"
]
}
}

360
Framework/type/csmmap.ts Normal file
View File

@ -0,0 +1,360 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
import { CubismLogDebug } from "../utils/cubismdebug";
export namespace Live2DCubismFramework
{
/**
* Key-Value
* csmMap使
*/
export class csmPair<_KeyT, _ValT>
{
/**
*
* @param key Key
* @param value Value
*/
public constructor(key?: _KeyT, value?: _ValT)
{
this.first = (key == undefined)
? null
: key;
this.second = (value == undefined)
? null
: value;
}
public first: _KeyT; // keyとして用いる変数
public second: _ValT; // valueとして用いる変数
}
/**
*
*/
export class csmMap<_KeyT, _ValT>
{
/**
*
* @param size
*/
public constructor(size?: number)
{
if(size != undefined)
{
if(size < 1)
{
this._keyValues = new Array();
this._dummyValue = null;
this._size = 0;
}
else
{
this._keyValues = new Array(size);
this._size = size;
}
}
else
{
this._keyValues = new Array();
this._dummyValue = null;
this._size = 0;
}
}
/**
*
*/
public release()
{
this.clear();
}
/**
*
* @param key
*/
public appendKey(key: _KeyT): void
{
// 新しくKey/Valueのペアを作る
this.prepareCapacity(this._size + 1, false); // 1つ以上入る隙間を作る
// 新しいkey/valueのインデックスは_size
this._keyValues[this._size] = new csmPair<_KeyT, _ValT>(key);
this._size += 1;
}
/**
* [key](get)
* @param key Value
*/
public getValue(key: _KeyT): _ValT
{
let found = -1;
for(let i: number = 0; i < this._size; i++)
{
if(this._keyValues[i].first == key)
{
found = i;
break;
}
}
if(found >= 0)
{
return this._keyValues[found].second;
}
else
{
this.appendKey(key); // 新規キーを追加
return this._keyValues[this._size - 1].second;
}
}
/**
* [key](set)
* @param key Value
* @param value Value
*/
public setValue(key: _KeyT, value: _ValT): void
{
let found = -1;
for(let i: number = 0; i < this._size; i++)
{
if(this._keyValues[i].first == key)
{
found = i;
break;
}
}
if(found >= 0)
{
this._keyValues[found].second = value;
}
else
{
this.appendKey(key); // 新規キーを追加
this._keyValues[this._size - 1].second = value;
}
}
/**
* Key
* @param key key
* @return true key
* @return false key
*/
public isExist(key: _KeyT): boolean
{
for(let i: number = 0; i < this._size; i++)
{
if(this._keyValues[i].first == key)
{
return true;
}
}
return false;
}
/**
* keyValue
*/
public clear(): void
{
this._keyValues = void 0;
this._keyValues = null;
this._keyValues = new Array();
this._size = 0;
}
/**
*
*
* @return
*/
public getSize(): number
{
return this._size;
}
/**
*
* @param newSize
* @param fitToSize truefalse2
*/
public prepareCapacity(newSize: number, fitToSize: boolean): void
{
if(newSize > this._keyValues.length)
{
if(this._keyValues.length == 0)
{
if(!fitToSize && newSize < csmMap.DefaultSize) newSize = csmMap.DefaultSize;
this._keyValues.length = newSize;
}
else
{
if(!fitToSize && newSize < this._keyValues.length * 2) newSize = this._keyValues.length * 2;
this._keyValues.length = newSize;
}
}
}
/**
*
*/
public begin(): csmMap.iterator<_KeyT, _ValT>
{
let ite: csmMap.iterator<_KeyT, _ValT> = new csmMap.iterator<_KeyT, _ValT>(this, 0);
return ite;
}
/**
*
*/
public end(): csmMap.iterator<_KeyT, _ValT>
{
let ite: csmMap.iterator<_KeyT, _ValT> = new csmMap.iterator<_KeyT, _ValT>(this, this._size); // 終了
return ite;
}
/**
*
*
* @param ite
*/
public erase(ite: csmMap.iterator<_KeyT, _ValT>): csmMap.iterator<_KeyT, _ValT>
{
let index: number = ite._index;
if(index < 0 || this._size <= index)
{
return ite; // 削除範囲外
}
// 削除
this._keyValues.splice(index, 1);
--this._size;
let ite2: csmMap.iterator<_KeyT, _ValT> = new csmMap.iterator<_KeyT, _ValT>(this, index); // 終了
return ite2;
}
/**
* 32
*/
public dumpAsInt()
{
for(let i = 0; i < this._size; i++)
{
CubismLogDebug("{0} ,", this._keyValues[i]);
CubismLogDebug("\n");
}
}
public static readonly DefaultSize = 10; // コンテナの初期化のデフォルトサイズ
public _keyValues: csmPair<_KeyT, _ValT>[];// key-valueペアの配列
public _dummyValue: _ValT; // 空の値を返す為のダミー
public _size: number; // コンテナの要素数
}
export namespace csmMap
{
/**
* csmMap<T>
*/
export class iterator<_KeyT, _ValT>
{
/**
*
*/
constructor(v?: csmMap<_KeyT, _ValT>, idx?: number)
{
this._map = (v != undefined)
? v
: new csmMap<_KeyT, _ValT>();
this._index = (idx != undefined)
? idx
: 0;
}
/**
* =
*/
public set(ite: iterator<_KeyT, _ValT>): iterator<_KeyT, _ValT>
{
this._index = ite._index;
this._map = ite._map;
return this;
}
/**
* ++
*/
public preIncrement(): iterator<_KeyT, _ValT>
{
++this._index;
return this;
}
/**
* --
*/
public preDecrement(): iterator<_KeyT, _ValT>
{
--this._index;
return this;
}
/**
* ++
*/
public increment(): iterator<_KeyT, _ValT>
{
let iteold = new iterator<_KeyT, _ValT>(this._map, this._index++); // 古い値を保存
this._map = iteold._map;
this._index = iteold._index;
return this;
}
/**
* --
*/
public decrement(): iterator<_KeyT, _ValT>
{
let iteold = new iterator<_KeyT, _ValT>(this._map, this._index); // 古い値を保存
this._map = iteold._map;
this._index = iteold._index;
return this;
}
/**
* *
*/
public ptr(): csmPair<_KeyT, _ValT>
{
return this._map._keyValues[this._index];
}
/**
* !=
*/
public notEqual(ite: iterator<_KeyT, _ValT>): boolean
{
return (this._index != ite._index) || (this._map != ite._map);
}
_index: number; // コンテナのインデックス値
_map: csmMap<_KeyT, _ValT>; // コンテナ
}
}
}

View File

@ -0,0 +1,92 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
export namespace Live2DCubismFramework
{
/**
* float
*/
export class csmRect
{
/**
*
* @param x X
* @param y Y
* @param w
* @param h
*/
public constructor(x?: number, y?: number, w?: number, h?: number)
{
this.x = x;
this.y = y;
this.width = w;
this.height = h;
}
/**
* X
*/
public getCenterX(): number
{
return this.x + 0.5 * this.width;
}
/**
* Y
*/
public getCenterY(): number
{
return this.y + 0.5 * this.height;
}
/**
* X
*/
public getRight(): number
{
return this.x + this.width;
}
/**
* Y
*/
public getBottom(): number
{
return this.y + this.height;
}
/**
*
* @param r
*/
public setRect(r: csmRect): void
{
this.x = r.x;
this.y = r.y;
this.width = r.width;
this.height = r.height;
}
/**
*
* @param w
* @param h
*/
public expand(w: number, h: number)
{
this.x -= w;
this.y -= h;
this.width += w * 2.0;
this.height += h * 2.0;
}
public x: number; // 左端X座標
public y: number; // 上端Y座標
public width: number; // 幅
public height: number; // 高さ
}
}

117
Framework/type/csmstring.ts Normal file
View File

@ -0,0 +1,117 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
export namespace Live2DCubismFramework
{
/**
*
*/
export class csmString
{
/**
*
*
* @param c
* @return
*/
public append(c: string, length?: number): csmString
{
this.s += (length !== undefined)
? c.substr(0, length)
: c;
return this;
}
/**
*
* @param length
* @param v
* @return
*/
public expansion(length: number, v: string): csmString
{
let ret: csmString = this;
for(let i = 0; i < length; i++)
{
ret.append(v);
}
return ret;
}
/**
*
*/
public getBytes(): number
{
return encodeURIComponent(this.s) .replace(/%../g, "x").length;
}
/**
*
*/
public getLength(): number
{
return this.s.length;
}
/**
*  <
* @param s
* @return true:
* @return false:
*/
public isLess(s: csmString): boolean
{
return this.s < s.s;
}
/**
* >
* @param s
* @return true:
* @return false:
*/
public isGreat(s: csmString): boolean
{
return this.s > s.s;
}
/**
* ==
* @param s
* @return true:
* @return false:
*/
public isEqual(s: string): boolean
{
return this.s == s;
}
/**
*
* @return true:
* @return false:
*/
public isEmpty(): boolean
{
return this.s.length == 0;
}
/**
*
*/
public constructor(s: string)
{
this.s = s;
}
s: string;
}
}

396
Framework/type/csmvector.ts Normal file
View File

@ -0,0 +1,396 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
export namespace Live2DCubismFramework
{
/**
*
*/
export class csmVector<T>
{
/**
*
* @param iniitalCapacity _capacity * sizeof(T)
* @param zeroClear true0
*/
constructor(initialCapacity: number = 0)
{
if(initialCapacity < 1)
{
this._ptr = new Array();
this._capacity = 0;
this._size = 0;
}
else
{
this._ptr = new Array(initialCapacity);
this._capacity = initialCapacity;
this._size = 0;
}
}
/**
*
*/
public at(index: number): T
{
return this._ptr[index];
}
/**
*
* @param index
* @param value
*/
public set(index: number, value: T): void
{
this._ptr[index] = value;
}
/**
*
*/
public get(offset: number = 0): T[]
{
let ret: T[] = new Array<T>();
for(let i = offset; i < this._size; i++)
{
ret.push(this._ptr[i]);
}
return ret;
}
/**
* pushBack
* @param value PushBack
*/
public pushBack(value: T): void
{
if(this._size >= this._capacity)
{
this.prepareCapacity(this._capacity == 0 ? csmVector.s_defaultSize : this._capacity * 2);
}
this._ptr[this._size++] = value;
}
/**
*
*/
public clear(): void
{
this._ptr.length = 0;
this._size = 0;
}
/**
*
* @return
*/
public getSize(): number
{
return this._size;
}
/**
*
* @param newSize
* @param value
*/
public assign(newSize: number, value: T): void
{
let curSize = this._size;
if(curSize < newSize)
{
this.prepareCapacity(newSize); // capacity更新
}
for(let i: number = 0; i < newSize; i++)
{
this._ptr[i] = value;
}
this._size = newSize;
}
/**
*
*/
public resize(newSize: number, value: T = null): void
{
this.updateSize(newSize, value, true);
}
/**
*
*/
public updateSize(newSize: number, value: any = null, callPlacementNew: boolean = true): void
{
let curSize: number = this._size;
if(curSize < newSize)
{
this.prepareCapacity(newSize); // capacity更新
if(callPlacementNew)
{
for(let i: number = this._size; i < newSize; i++)
{
if(typeof value == 'function') // new
{
this._ptr[i] = JSON.parse(JSON.stringify(new value()));
}
else // プリミティブ型なので値渡し
{
this._ptr[i] = value;
}
}
}
else
{
for(let i: number = this._size; i < newSize; i++)
{
this._ptr[i] = value;
}
}
}
else
{
// newSize <= this._size
//---
let sub = this._size - newSize;
this._ptr.splice(this._size - sub, sub); // 不要なので破棄する
}
this._size = newSize;
}
/**
*
* @param position
* @param begin 
* @param end
*/
public insert(position: csmVector.iterator<T>, begin: csmVector.iterator<T>, end: csmVector.iterator<T>): void
{
let dstSi: number = position._index;
let srcSi: number = begin._index;
let srcEi: number = end._index;
let addCount: number = srcEi - srcSi;
this.prepareCapacity(this._size + addCount);
// 挿入用の既存データをシフトして隙間を作る
let addSize = this._size - dstSi;
if(addSize > 0)
{
for(let i: number = 0; i < addSize; i++)
{
this._ptr.splice(dstSi + i, 0, null);
}
}
for(let i: number = srcSi; i < srcEi; i++, dstSi++)
{
this._ptr[dstSi] = begin._vector._ptr[i];
}
this._size = this._size + addCount;
}
/**
*
* @param index
* @return true
* @return false
*/
public remove(index: number): boolean
{
if(index < 0 || this._size <= index)
{
return false; // 削除範囲外
}
this._ptr.splice(index, 1);
--this._size;
return true;
}
/**
*
* @param ite
*/
public erase(ite: csmVector.iterator<T>): csmVector.iterator<T>
{
let index: number = ite._index;
if(index < 0 || this._size <= index)
{
return ite; // 削除範囲外
}
// 削除
this._ptr.splice(index, 1);
--this._size;
let ite2: csmVector.iterator<T> = new csmVector.iterator<T>(this, index); // 終了
return ite2;
}
/**
*
* @param newSize .
*/
public prepareCapacity(newSize: number): void
{
if(newSize > this._capacity)
{
if(this._capacity == 0)
{
this._ptr = new Array(newSize);
this._capacity = newSize;
}
else
{
this._ptr.length = newSize;
this._capacity = newSize;
}
}
}
/**
*
*/
public begin(): csmVector.iterator<T>
{
let ite: csmVector.iterator<T> = (this._size == 0)
? this.end()
: new csmVector.iterator<T>(this, 0);
return ite;
}
/**
*
*/
public end(): csmVector.iterator<T>
{
let ite: csmVector.iterator<T> = new csmVector.iterator<T>(this, this._size);
return ite;
}
public getOffset(offset: number): csmVector<T>
{
let newVector = new csmVector<T>();
newVector._ptr = this.get(offset);
newVector._size = this.get(offset).length;
newVector._capacity = this.get(offset).length;
return newVector;
}
_ptr: T[]; // コンテナの先頭アドレス
_size: number; // コンテナの要素数
_capacity: number; // コンテナのキャパシティ
static readonly s_defaultSize = 10; // コンテナ初期化のデフォルトサイズ
}
export namespace csmVector
{
export class iterator<T>
{
/**
*
*/
public constructor(v?: csmVector<T>, index?: number)
{
this._vector = (v != undefined) ? v : null;
this._index = (index != undefined) ? index : 0;
}
/**
*
*/
public set(ite: iterator<T>): iterator<T>
{
this._index = ite._index;
this._vector = ite._vector;
return this;
}
/**
* ++
*/
public preIncrement(): iterator<T>
{
++this._index;
return this;
}
/**
* --
*/
public preDecrement(): iterator<T>
{
--this._index;
return this;
}
/**
* ++
*/
public increment(): iterator<T>
{
let iteold = new iterator<T>(this._vector, this._index++);
this._vector = iteold._vector;
this._index = iteold._index;
return this;
}
/**
* --
*/
public decrement(): iterator<T>
{
let iteold = new iterator<T>(this._vector, this._index--); // 古い値を保存
this._vector = iteold._vector;
this._index = iteold._index;
return this;
}
/**
* ptr
*/
public ptr(): T
{
return this._vector._ptr[this._index];
}
/**
* =
*/
public substitution(ite: iterator<T>): iterator<T>
{
this._index = ite._index;
this._vector = ite._vector;
return this;
}
/**
* !=
*/
public notEqual(ite: iterator<T>): boolean
{
return (this._index != ite._index) || (this._vector != ite._vector);
}
_index: number; // コンテナのインデックス値
_vector: csmVector<T>; // コンテナ
}
}
}

View File

@ -0,0 +1,194 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
import {Live2DCubismFramework as live2dcubismframework, Option} from "../live2dcubismframework";
import CubismFramework = live2dcubismframework.CubismFramework;
import { CSM_LOG_LEVEL, CSM_LOG_LEVEL_VERBOSE, CSM_LOG_LEVEL_DEBUG, CSM_LOG_LEVEL_INFO, CSM_LOG_LEVEL_WARNING, CSM_LOG_LEVEL_ERROR } from "../cubismframeworkconfig";
export const CubismLogPrint = (level: Option.LogLevel, fmt: string, ... args) =>
{
Live2DCubismFramework.CubismDebug.print(level, "[CSM]" + fmt, args);
}
export const CubismLogPrintIn = (level: Option.LogLevel, fmt: string, ... args) =>
{
CubismLogPrint(level, fmt + "\n", args);
}
export let CSM_ASSERT = (expr) =>
{
console.assert(expr);
};
export let CubismLogVerbose = (fmt: string, ... args: any[]) => {};
export let CubismLogDebug = (fmt: string, ... args: any[]) => {};
export let CubismLogInfo = (fmt: string, ... args: any[]) => {};
export let CubismLogWarning = (fmt: string, ... args: any[]) => {};
export let CubismLogError = (fmt: string, ... args: any[]) => {};
if(CSM_LOG_LEVEL <= CSM_LOG_LEVEL_VERBOSE)
{
CubismLogVerbose = (fmt: string, ... args: any[]) =>
{
CubismLogPrintIn(Option.LogLevel.LogLevel_Verbose, "[V]" + fmt, args);
};
CubismLogDebug = (fmt: string, ... args: any[]) =>
{
CubismLogPrintIn(Option.LogLevel.LogLevel_Debug, "[D]" + fmt, args);
};
CubismLogInfo = (fmt: string, ... args: any[]) =>
{
CubismLogPrintIn(Option.LogLevel.LogLevel_Info, "[I]" + fmt, args);
};
CubismLogWarning = (fmt: string, ... args: any[]) =>
{
CubismLogPrintIn(Option.LogLevel.LogLevel_Warning, "[W]" + fmt, args);
};
CubismLogError = (fmt: string, ... args: any[]) =>
{
CubismLogPrintIn(Option.LogLevel.LogLevel_Error, "[E]" + fmt, args);
};
}
else if(CSM_LOG_LEVEL == CSM_LOG_LEVEL_DEBUG)
{
CubismLogDebug = (fmt: string, ... args: any[]) =>
{
CubismLogPrintIn(Option.LogLevel.LogLevel_Debug, "[D]" + fmt, args);
};
CubismLogInfo = (fmt: string, ... args: any[]) =>
{
CubismLogPrintIn(Option.LogLevel.LogLevel_Info, "[I]" + fmt, args);
};
CubismLogWarning = (fmt: string, ... args: any[]) =>
{
CubismLogPrintIn(Option.LogLevel.LogLevel_Warning, "[W]" + fmt, args);
};
CubismLogError = (fmt: string, ... args: any[]) =>
{
CubismLogPrintIn(Option.LogLevel.LogLevel_Error, "[E]" + fmt, args);
};
}
else if(CSM_LOG_LEVEL == CSM_LOG_LEVEL_INFO)
{
CubismLogInfo = (fmt: string, ... args: any[]) =>
{
CubismLogPrintIn(Option.LogLevel.LogLevel_Info, "[I]" + fmt, args);
};
CubismLogWarning = (fmt: string, ... args: any[]) =>
{
CubismLogPrintIn(Option.LogLevel.LogLevel_Warning, "[W]" + fmt, args);
};
CubismLogError = (fmt: string, ... args: any[]) =>
{
CubismLogPrintIn(Option.LogLevel.LogLevel_Error, "[E]" + fmt, args);
};
}
else if(CSM_LOG_LEVEL == CSM_LOG_LEVEL_WARNING)
{
CubismLogWarning = (fmt: string, ... args: any[]) =>
{
CubismLogPrintIn(Option.LogLevel.LogLevel_Warning, "[W]" + fmt, args);
};
CubismLogError = (fmt: string, ... args: any[]) =>
{
CubismLogPrintIn(Option.LogLevel.LogLevel_Error, "[E]" + fmt, args);
};
}
else if(CSM_LOG_LEVEL == CSM_LOG_LEVEL_ERROR)
{
CubismLogError = (fmt: string, ... args: any[]) =>
{
CubismLogPrintIn(Option.LogLevel.LogLevel_Error, "[E]" + fmt, args);
};
}
//------------ LIVE2D NAMESPACE ------------
export namespace Live2DCubismFramework
{
/**
*
*
*/
export class CubismDebug
{
/**
*
* CubismFramework.initialize()
*
* @param logLevel
* @param format
* @param ... args
*/
public static print(logLevel: Option.LogLevel, format: string, ... args: any[]): void
{
// オプションで設定されたログ出力レベルを下回る場合はログに出さない
// if(logLevel < CubismFramework.getLoggingLevel())
// {
// return;
// }
// TODO
// const Core::csmLogFunction logPrint = CubismFramework::CoreLogFunction;
// if (!logPrint)
// return;
let buffer: string = format;
buffer = buffer.replace(
/\{(\d+)\}/g,
(m, k) => // m="{0}", k="0"
{
return args[k];
}
);
// logPrint(buffer);
}
/**
*
* CubismFramework.initialize()
*
* @param logLevel
* @param data
* @param length
*/
public static dumpBytes(logLevel: Option.LogLevel, data: Uint8Array, length: number): void
{
for (let i: number = 0; i < length; i++)
{
if (i % 16 == 0 && i > 0) this.print(logLevel, "\n");
else if (i % 8 == 0 && i > 0) this.print(logLevel, " ");
this.print(logLevel, "{0} ", (data[i] & 0xFF));
}
this.print(logLevel, "\n");
}
/**
* private
*/
private constructor()
{
}
}
}
//------------ LIVE2D NAMESPACE ------------

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,136 @@
/*
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
export namespace Live2DCubismFramework
{
export class CubismString
{
/**
*
* @param format
* @param ...args
* @return
*/
public static getFormatedString(format: string, ... args: any[]): string
{
let ret: string = format;
return ret.replace(
/\{(\d+)\}/g,
(m, k) => // m="{0}", k="0"
{
return args[k];
}
);
}
/**
* textstartWord
* @param test
* @param startWord
* @return true textstartWord
* @return false textstartWord
*/
public static isStartWith(text: string, startWord: string): boolean
{
let textIndex = 0;
let startWordIndex = 0;
while(startWord[startWordIndex] != '\0')
{
if(text[textIndex] == '\0' || text[textIndex++] != startWord[startWordIndex++])
{
return false;
}
}
return false;
}
/**
* position
*
* @param string
* @param length
* @param position
* @param outEndPos (-1)
* @return
*/
public static stringToFloat(string: string, length: number, position: number, outEndPos: number[]): number
{
let i: number = position;
let minus: boolean = false; // マイナスフラグ
let period: boolean = false;
let v1: number = 0;
//負号の確認
let c: number = parseInt(string[i]);
if (c < 0)
{
minus = true;
i++;
}
//整数部の確認
for (; i < length; i++)
{
let c = string[i];
if (0 <= parseInt(c) && parseInt(c) <= 9)
{
v1 = v1 * 10 + (parseInt(c) - 0);
}
else if (c == '.')
{
period = true;
i++;
break;
}
else
{
break;
}
}
//小数部の確認
if (period)
{
let mul: number = 0.1;
for (; i < length; i++)
{
c = parseFloat(string[i]) & 0xFF;
if (0 <= c && c <= 9)
{
v1 += mul * (c - 0);
}
else
{
break;
}
mul *= 0.1; //一桁下げる
if (!c) break;
}
}
if (i == position)
{
//一文字も読み込まなかった場合
outEndPos[0] = -1; //エラー値が入るので呼び出し元で適切な処理を行う
return 0;
}
if (minus) v1 = -v1;
outEndPos[0] = i;
return v1;
}
/**
*
*/
private constructor()
{
}
}
}

125
README.md Normal file
View File

@ -0,0 +1,125 @@
# Cubism Web Samples
Live2D Cubism 3 Editorで出力したモデルを表示するアプリケーションのサンプル実装です。
Cubism Coreライブラリと組み合わせて使用します。
# フォルダ構成
- README.md ...本ドキュメント
- Core ...Coreライブラリが含まれるフォルダ
- Framework ...レンダリングやアニメーション機能などのソースコードが含まれるフォルダ
- Samples ...サンプルプロジェクトが含まれるフォルダ
- .vscode ...Visual Studio Codeのタスクや設定が含まれるフォルダ
# Live2D Cubism Core for Web
モデルをロードするためのライブラリです。
# TypeScript環境
1. node.jsをインストールします。
- https://nodejs.org/en/
2. typescriptをインストールします。
- https://www.typescriptlang.org/
3. Visual Studio Codeをインストールします。
4. 拡張機能として下記を追加します。
- Debugger for Chrome
- Live Server
5. Visual Studio Codeを再起動します。
6. ターミナルを起動し、package.jsonがあるディレクトリ上で npm install を実行すると、必要な物がインストールされます。
(例)E:\Workspace\CubismWebSamples
# TypeScript Core Binding
CoreライブラリはTypeScript用に以下プロジェクトでバインドし、出力されたファイルをCoreフォルダに入れる必要があります。
- https://github.com/Live2D/CubismBindings
CubismBindings/data/templates/js/.in/live2dcubismcore.tsの名前空間をLIVE2DCUBISMCOREからLive2DCubismCoreに変更し、
CubismBindingsのREADME.mdに従いバインドします。
# ビルド方法
1. Visual Studio Codeでプロジェクトフォルダを開きます。
(例)E:\Workspace\CubismWebSamples
2. ビルドし、JavaScriptを生成します。
ctrl+shift+Bでビルドタスクを選択
または ターミナル上で npm run build-sample を実行すると、JavaScriptが生成されます。
各タスクの説明
`npm:build-framework` : フレームワークのみをビルドし、JavaScriptファイルを生成します。
`npm:watch-framework` : フレームワークのみをウォッチし、変更が保存された際にJavaScriptファイルを生成します。
`npm:build-sample` : サンプルをビルドします。
`npm:watch-sample` : サンプルをウォッチします。
`npm:build-all` : フレームワークとサンプルをビルドします。
`npm:watch-all` : フレームワークとサンプルをウォッチします。
3. サーバーを起動します。
Visual Studio Codeの画面下の水色のフッターからGo Liveをクリックすると、サーバーが起動します。
4. 実行
F5で実行し、remote web site with sourcemapを選択します。
# SDKマニュアル
[Cubism SDK Manual](http://docs.live2d.com/cubism-sdk-manual/top/)
# 変更履歴
当リポジトリの変更履歴については[コミットログ](https://github.com/Live2D/CubismWebSamples/commits/master)を参照ください。
# TODO
以下Core内関数の実装
- csmSetLogFunction
- csmGetLogFunction
- csmSetLogFunction
- csmGetVersion
# ライセンス
Cubism Web Samples は Live2D Open Software License で提供しています。
- Live2D Open Software License
[日本語](http://www.live2d.com/eula/live2d-open-software-license-agreement_jp.html)
[English](http://www.live2d.com/eula/live2d-open-software-license-agreement_en.html)
Live2D Cubism Core for Web は Live2D Proprietary Software License で提供しています。
- Live2D Proprietary Software License
[日本語](http://www.live2d.com/eula/live2d-proprietary-software-license-agreement_jp.html)
[English](http://www.live2d.com/eula/live2d-proprietary-software-license-agreement_en.html)
Live2D のサンプルモデルは Free Material License で提供しています。
- Free Material License
[日本語](http://www.live2d.com/eula/live2d-free-material-license-agreement_jp.html)
[English](http://www.live2d.com/eula/live2d-free-material-license-agreement_en.html)
- Resources/Haru/*
- Resources/Hiyori/*
- Resources/Mark/*
直近会計年度の売上高が 1000 万円以上の事業者様がご利用になる場合は、SDKリリース(出版許諾)ライセンスに同意していただく必要がございます。
- [SDKリリース(出版許諾)ライセンス](http://www.live2d.com/ja/products/releaselicense)
*All business* users must obtain a Publication License. "Business" means an entity with the annual gross revenue more than ten million (10,000,000) JPY for the most recent fiscal year.
- [SDK Release (Publication) License](http://www.live2d.com/en/products/releaselicense)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

View File

@ -0,0 +1,55 @@
{
"Version": 3,
"FileReferences": {
"Moc": "Haru.moc3",
"Textures": [
"Haru.2048/texture_00.png",
"Haru.2048/texture_01.png"
],
"Pose": "Haru.pose3.json",
"Expressions": [
{"Name":"f00","File":"expressions/F01.exp3.json"},
{"Name":"f01","File":"expressions/F02.exp3.json"},
{"Name":"f02","File":"expressions/F03.exp3.json"},
{"Name":"f03","File":"expressions/F04.exp3.json"},
{"Name":"f04","File":"expressions/F05.exp3.json"},
{"Name":"f05","File":"expressions/F06.exp3.json"},
{"Name":"f06","File":"expressions/F07.exp3.json"},
{"Name":"f07","File":"expressions/F08.exp3.json"}
],
"Motions": {
"Idle": [
{"File":"motions/haru_g_idle.motion3.json" ,"FadeInTime":0.5, "FadeOutTime":0.5},
{"File":"motions/haru_g_m15.motion3.json" ,"FadeInTime":0.5, "FadeOutTime":0.5}
],
"TapBody": [
{"File":"motions/haru_g_m06.motion3.json" ,"FadeInTime":0.5, "FadeOutTime":0.5},
{"File":"motions/haru_g_m09.motion3.json" ,"FadeInTime":0.5, "FadeOutTime":0.5},
{"File":"motions/haru_g_m20.motion3.json" ,"FadeInTime":0.5, "FadeOutTime":0.5},
{"File":"motions/haru_g_m26.motion3.json" ,"FadeInTime":0.5, "FadeOutTime":0.5}
]
},
"UserData": "Haru.userdata3.json"
},
"Groups": [
{
"Target": "Parameter",
"Name": "LipSync",
"Ids": [
"ParamMouthOpenY"
]
},
{
"Target": "Parameter",
"Name": "EyeBlink",
"Ids": [
"ParamEyeLOpen",
"ParamEyeROpen"
]
}
],
"HitAreas": [
{"Name":"Head", "Id":"HitArea"},
{"Name":"Body", "Id":"HitArea2"}
]
}

View File

@ -0,0 +1,25 @@
{
"Type": "Live2D Pose",
"Groups": [
[
{
"Id": "Part01ArmLB001",
"Link": []
},
{
"Id": "Part01ArmRA001",
"Link": []
}
],
[
{
"Id": "Part01ArmRB001",
"Link": []
},
{
"Id": "Part01ArmLA001",
"Link": []
}
]
]
}

View File

@ -0,0 +1,24 @@
{
"Version": 3,
"Meta": {
"UserDataCount": 3,
"TotalUserDataSize": 9
},
"UserData": [
{
"Target": "ArtMesh",
"Id": "D_PSD_27",
"Value": "tai"
},
{
"Target": "ArtMesh",
"Id": "D_PSD_25",
"Value": "tai"
},
{
"Target": "ArtMesh",
"Id": "D_PSD_24",
"Value": "tai"
}
]
}

View File

@ -0,0 +1,10 @@
{
"Type": "Live2D Expression",
"Parameters": [
{
"Id": "ParamMouthForm",
"Value": 0.27,
"Blend": "Add"
}
]
}

View File

@ -0,0 +1,35 @@
{
"Type": "Live2D Expression",
"Parameters": [
{
"Id": "ParamBrowLY",
"Value": -1,
"Blend": "Add"
},
{
"Id": "ParamBrowRY",
"Value": -1,
"Blend": "Add"
},
{
"Id": "ParamBrowLForm",
"Value": 1,
"Blend": "Add"
},
{
"Id": "ParamBrowRForm",
"Value": 1,
"Blend": "Add"
},
{
"Id": "ParamMouthOpenY",
"Value": 1,
"Blend": "Add"
},
{
"Id": "ParamEyeForm",
"Value": 0.54,
"Blend": "Add"
}
]
}

View File

@ -0,0 +1,55 @@
{
"Type": "Live2D Expression",
"Parameters": [
{
"Id": "ParamBrowLY",
"Value": -1,
"Blend": "Add"
},
{
"Id": "ParamBrowRY",
"Value": -1,
"Blend": "Add"
},
{
"Id": "ParamBrowLX",
"Value": -1,
"Blend": "Add"
},
{
"Id": "ParamBrowRX",
"Value": -1,
"Blend": "Add"
},
{
"Id": "ParamBrowRAngle",
"Value": -1,
"Blend": "Add"
},
{
"Id": "ParamBrowLForm",
"Value": -1,
"Blend": "Add"
},
{
"Id": "ParamBrowRForm",
"Value": -1,
"Blend": "Add"
},
{
"Id": "ParamMouthForm",
"Value": -2,
"Blend": "Add"
},
{
"Id": "ParamMouthOpenY",
"Value": 1,
"Blend": "Add"
},
{
"Id": "ParamEyeForm",
"Value": -1,
"Blend": "Add"
}
]
}

View File

@ -0,0 +1,60 @@
{
"Type": "Live2D Expression",
"Parameters": [
{
"Id": "ParamEyeLOpen",
"Value": 0.8,
"Blend": "Multiply"
},
{
"Id": "ParamEyeROpen",
"Value": 0.8,
"Blend": "Multiply"
},
{
"Id": "ParamBrowLY",
"Value": -0.56,
"Blend": "Add"
},
{
"Id": "ParamBrowRY",
"Value": -0.56,
"Blend": "Add"
},
{
"Id": "ParamBrowRX",
"Value": -1,
"Blend": "Add"
},
{
"Id": "ParamBrowLAngle",
"Value": 0.35,
"Blend": "Add"
},
{
"Id": "ParamBrowRAngle",
"Value": 0.35,
"Blend": "Add"
},
{
"Id": "ParamBrowLForm",
"Value": -0.74,
"Blend": "Add"
},
{
"Id": "ParamBrowRForm",
"Value": -0.74,
"Blend": "Add"
},
{
"Id": "ParamMouthForm",
"Value": -1.76,
"Blend": "Add"
},
{
"Id": "ParamEyeForm",
"Value": 1,
"Blend": "Add"
}
]
}

View File

@ -0,0 +1,35 @@
{
"Type": "Live2D Expression",
"Parameters": [
{
"Id": "ParamEyeLOpen",
"Value": 0,
"Blend": "Multiply"
},
{
"Id": "ParamEyeLSmile",
"Value": 1,
"Blend": "Add"
},
{
"Id": "ParamEyeROpen",
"Value": 0,
"Blend": "Multiply"
},
{
"Id": "ParamEyeRSmile",
"Value": 1,
"Blend": "Add"
},
{
"Id": "ParamBrowLY",
"Value": 0.32,
"Blend": "Add"
},
{
"Id": "ParamBrowRY",
"Value": 0.32,
"Blend": "Add"
}
]
}

View File

@ -0,0 +1,35 @@
{
"Type": "Live2D Expression",
"Parameters": [
{
"Id": "ParamEyeLOpen",
"Value": 2,
"Blend": "Multiply"
},
{
"Id": "ParamEyeROpen",
"Value": 2,
"Blend": "Multiply"
},
{
"Id": "ParamBrowLY",
"Value": 1,
"Blend": "Add"
},
{
"Id": "ParamBrowRY",
"Value": 1,
"Blend": "Add"
},
{
"Id": "ParamMouthForm",
"Value": -1,
"Blend": "Add"
},
{
"Id": "ParamEyeBallForm",
"Value": -0.65,
"Blend": "Add"
}
]
}

View File

@ -0,0 +1,65 @@
{
"Type": "Live2D Expression",
"Parameters": [
{
"Id": "ParamEyeLOpen",
"Value": 0.89,
"Blend": "Multiply"
},
{
"Id": "ParamEyeROpen",
"Value": 0.89,
"Blend": "Multiply"
},
{
"Id": "ParamBrowLY",
"Value": -0.56,
"Blend": "Add"
},
{
"Id": "ParamBrowRY",
"Value": -0.56,
"Blend": "Add"
},
{
"Id": "ParamBrowLX",
"Value": -1,
"Blend": "Add"
},
{
"Id": "ParamBrowRX",
"Value": -1,
"Blend": "Add"
},
{
"Id": "ParamBrowLAngle",
"Value": 0.35,
"Blend": "Add"
},
{
"Id": "ParamBrowRAngle",
"Value": 0.35,
"Blend": "Add"
},
{
"Id": "ParamBrowLForm",
"Value": -0.74,
"Blend": "Add"
},
{
"Id": "ParamBrowRForm",
"Value": -0.74,
"Blend": "Add"
},
{
"Id": "ParamMouthForm",
"Value": -0.46,
"Blend": "Add"
},
{
"Id": "ParamTere",
"Value": 1,
"Blend": "Add"
}
]
}

View File

@ -0,0 +1,30 @@
{
"Type": "Live2D Expression",
"Parameters": [
{
"Id": "ParamEyeLOpen",
"Value": 0.8,
"Blend": "Multiply"
},
{
"Id": "ParamEyeROpen",
"Value": 0.8,
"Blend": "Multiply"
},
{
"Id": "ParamBrowLForm",
"Value": -0.33,
"Blend": "Add"
},
{
"Id": "ParamBrowRForm",
"Value": -0.33,
"Blend": "Add"
},
{
"Id": "ParamMouthForm",
"Value": -1.76,
"Blend": "Add"
}
]
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

View File

@ -0,0 +1,92 @@
{
"Version": 3,
"FileReferences": {
"Moc": "Hiyori.moc3",
"Textures": [
"Hiyori.2048/texture_00.png",
"Hiyori.2048/texture_01.png"
],
"Physics": "Hiyori.physics3.json",
"Pose": "Hiyori.pose3.json",
"UserData": "Hiyori.userdata3.json",
"Motions": {
"Idle": [
{
"File": "motions/Hiyori_m01.motion3.json",
"FadeInTime": 0.5,
"FadeOutTime": 0.5
},
{
"File": "motions/Hiyori_m02.motion3.json",
"FadeInTime": 0.5,
"FadeOutTime": 0.5
},
{
"File": "motions/Hiyori_m03.motion3.json",
"FadeInTime": 0.5,
"FadeOutTime": 0.5
},
{
"File": "motions/Hiyori_m05.motion3.json",
"FadeInTime": 0.5,
"FadeOutTime": 0.5
},
{
"File": "motions/Hiyori_m06.motion3.json",
"FadeInTime": 0.5,
"FadeOutTime": 0.5
},
{
"File": "motions/Hiyori_m07.motion3.json",
"FadeInTime": 0.5,
"FadeOutTime": 0.5
},
{
"File": "motions/Hiyori_m08.motion3.json",
"FadeInTime": 0.5,
"FadeOutTime": 0.5
},
{
"File": "motions/Hiyori_m09.motion3.json",
"FadeInTime": 0.5,
"FadeOutTime": 0.5
},
{
"File": "motions/Hiyori_m10.motion3.json",
"FadeInTime": 0.5,
"FadeOutTime": 0.5
}
],
"TapBody": [
{
"File": "motions/Hiyori_m04.motion3.json",
"FadeInTime": 0.5,
"FadeOutTime": 0.5
}
]
}
},
"Groups": [
{
"Target": "Parameter",
"Name": "LipSync",
"Ids": [
"ParamMouthOpenY"
]
},
{
"Target": "Parameter",
"Name": "EyeBlink",
"Ids": [
"ParamEyeLOpen",
"ParamEyeROpen"
]
}
],
"HitAreas": [
{
"Id": "HitArea",
"Name": "Body"
}
]
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,16 @@
{
"Type": "Live2D Pose",
"FadeInTime": 0.5,
"Groups": [
[
{
"Id": "PartArmA",
"Link": []
},
{
"Id": "PartArmB",
"Link": []
}
]
]
}

View File

@ -0,0 +1,44 @@
{
"Version": 3,
"Meta": {
"UserDataCount": 7,
"TotalUserDataSize": 35
},
"UserData": [
{
"Target": "ArtMesh",
"Id": "ArtMesh93",
"Value": "ribon"
},
{
"Target": "ArtMesh",
"Id": "ArtMesh94",
"Value": "ribon"
},
{
"Target": "ArtMesh",
"Id": "ArtMesh95",
"Value": "ribon"
},
{
"Target": "ArtMesh",
"Id": "ArtMesh57",
"Value": "ribon"
},
{
"Target": "ArtMesh",
"Id": "ArtMesh58",
"Value": "ribon"
},
{
"Target": "ArtMesh",
"Id": "ArtMesh59",
"Value": "ribon"
},
{
"Target": "ArtMesh",
"Id": "ArtMesh60",
"Value": "ribon"
}
]
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,882 @@
{
"Version": 3,
"Meta": {
"Duration": 4.467,
"Fps": 30.0,
"Loop": true,
"AreBeziersRestricted": false,
"CurveCount": 31,
"TotalSegmentCount": 106,
"TotalPointCount": 287,
"UserDataCount": 0,
"TotalUserDataSize": 0
},
"Curves": [
{
"Target": "Parameter",
"Id": "ParamAngleX",
"Segments": [
0,
1,
1,
0.211,
1,
0.422,
0,
0.633,
0,
1,
0.911,
0,
1.189,
5,
1.467,
5,
1,
1.689,
5,
1.911,
-16,
2.133,
-16,
1,
2.356,
-16,
2.578,
13.871,
2.8,
13.871,
1,
2.956,
13.871,
3.111,
0,
3.267,
0,
0,
4.467,
0
]
},
{
"Target": "Parameter",
"Id": "ParamAngleY",
"Segments": [
0,
0,
1,
0.211,
0,
0.422,
0,
0.633,
0,
1,
0.911,
0,
1.189,
-25,
1.467,
-25,
1,
1.689,
-25,
1.911,
-15.225,
2.133,
-11,
1,
2.356,
-6.775,
2.578,
-5.127,
2.8,
-2.5,
1,
2.956,
-0.661,
3.111,
0,
3.267,
0,
0,
4.467,
0
]
},
{
"Target": "Parameter",
"Id": "ParamAngleZ",
"Segments": [
0,
0,
1,
0.222,
0,
0.444,
0,
0.667,
0,
1,
0.756,
0,
0.844,
-4,
0.933,
-4,
1,
1.122,
-4,
1.311,
18,
1.5,
18,
1,
1.722,
18,
1.944,
-14,
2.167,
-14,
1,
2.567,
-14,
2.967,
-14,
3.367,
-14,
1,
3.511,
-14,
3.656,
-12,
3.8,
-12,
0,
4.467,
-12
]
},
{
"Target": "Parameter",
"Id": "ParamCheek",
"Segments": [
0,
1,
0,
4.467,
1
]
},
{
"Target": "Parameter",
"Id": "ParamEyeLOpen",
"Segments": [
0,
1.2,
1,
0.389,
1.2,
0.778,
1.148,
1.167,
1,
1,
1.211,
0.983,
1.256,
0,
1.3,
0,
1,
1.322,
0,
1.344,
0,
1.367,
0,
1,
1.422,
0,
1.478,
1,
1.533,
1,
1,
1.944,
1,
2.356,
1,
2.767,
1,
1,
2.811,
1,
2.856,
0,
2.9,
0,
1,
2.922,
0,
2.944,
0,
2.967,
0,
1,
3.022,
0,
3.078,
1,
3.133,
1,
0,
4.467,
1
]
},
{
"Target": "Parameter",
"Id": "ParamEyeLSmile",
"Segments": [
0,
0,
0,
4.467,
0
]
},
{
"Target": "Parameter",
"Id": "ParamEyeROpen",
"Segments": [
0,
1.2,
1,
0.389,
1.2,
0.778,
1.148,
1.167,
1,
1,
1.211,
0.983,
1.256,
0,
1.3,
0,
1,
1.322,
0,
1.344,
0,
1.367,
0,
1,
1.422,
0,
1.478,
1,
1.533,
1,
1,
1.944,
1,
2.356,
1,
2.767,
1,
1,
2.811,
1,
2.856,
0,
2.9,
0,
1,
2.922,
0,
2.944,
0,
2.967,
0,
1,
3.022,
0,
3.078,
1,
3.133,
1,
0,
4.467,
1
]
},
{
"Target": "Parameter",
"Id": "ParamEyeRSmile",
"Segments": [
0,
0,
0,
4.467,
0
]
},
{
"Target": "Parameter",
"Id": "ParamEyeBallX",
"Segments": [
0,
0,
1,
0.211,
0,
0.422,
0,
0.633,
0,
1,
0.911,
0,
1.189,
-0.44,
1.467,
-0.44,
1,
1.689,
-0.44,
1.911,
0.79,
2.133,
0.79,
1,
2.511,
0.79,
2.889,
0,
3.267,
0,
0,
4.467,
0
]
},
{
"Target": "Parameter",
"Id": "ParamEyeBallY",
"Segments": [
0,
0,
1,
0.211,
0,
0.422,
0,
0.633,
0,
1,
0.911,
0,
1.189,
-1,
1.467,
-1,
1,
1.689,
-1,
1.911,
-1,
2.133,
-1,
1,
2.511,
-1,
2.889,
0,
3.267,
0,
0,
4.467,
0
]
},
{
"Target": "Parameter",
"Id": "ParamBrowLY",
"Segments": [
0,
1,
1,
0.544,
1,
1.089,
1,
1.633,
1,
1,
1.856,
1,
2.078,
0,
2.3,
0,
1,
2.5,
0,
2.7,
1,
2.9,
1,
0,
4.467,
1
]
},
{
"Target": "Parameter",
"Id": "ParamBrowRY",
"Segments": [
0,
1,
1,
0.544,
1,
1.089,
1,
1.633,
1,
1,
1.856,
1,
2.078,
0,
2.3,
0,
1,
2.5,
0,
2.7,
1,
2.9,
1,
0,
4.467,
1
]
},
{
"Target": "Parameter",
"Id": "ParamBrowLX",
"Segments": [
0,
0,
0,
4.467,
0
]
},
{
"Target": "Parameter",
"Id": "ParamBrowRX",
"Segments": [
0,
0,
0,
4.467,
0
]
},
{
"Target": "Parameter",
"Id": "ParamBrowLAngle",
"Segments": [
0,
0,
0,
4.467,
0
]
},
{
"Target": "Parameter",
"Id": "ParamBrowRAngle",
"Segments": [
0,
0,
0,
4.467,
0
]
},
{
"Target": "Parameter",
"Id": "ParamBrowLForm",
"Segments": [
0,
-1,
0,
4.467,
-1
]
},
{
"Target": "Parameter",
"Id": "ParamBrowRForm",
"Segments": [
0,
-1,
0,
4.467,
-1
]
},
{
"Target": "Parameter",
"Id": "ParamMouthForm",
"Segments": [
0,
-2,
0,
4.467,
-2
]
},
{
"Target": "Parameter",
"Id": "ParamMouthOpenY",
"Segments": [
0,
0,
0,
4.467,
0
]
},
{
"Target": "Parameter",
"Id": "ParamBodyAngleX",
"Segments": [
0,
0,
1,
0.244,
0,
0.489,
0,
0.733,
0,
1,
0.933,
0,
1.133,
-7,
1.333,
-7,
1,
1.644,
-7,
1.956,
0,
2.267,
0,
0,
4.467,
0
]
},
{
"Target": "Parameter",
"Id": "ParamBodyAngleY",
"Segments": [
0,
0,
1,
0.244,
0,
0.489,
0,
0.733,
0,
0,
4.467,
0
]
},
{
"Target": "Parameter",
"Id": "ParamBodyAngleZ",
"Segments": [
0,
2,
1,
0.233,
2,
0.467,
0,
0.7,
0,
1,
0.733,
0,
0.767,
0,
0.8,
0,
1,
1,
0,
1.2,
-4,
1.4,
-4,
1,
1.711,
-4,
2.022,
5,
2.333,
5,
1,
2.567,
5,
2.8,
3.64,
3.033,
0,
1,
3.133,
-1.56,
3.233,
-3,
3.333,
-3,
1,
3.467,
-3,
3.6,
-2,
3.733,
-2,
0,
4.467,
-2
]
},
{
"Target": "Parameter",
"Id": "ParamBreath",
"Segments": [
0,
0,
1,
0.189,
0,
0.378,
1,
0.567,
1,
1,
0.711,
1,
0.856,
0,
1,
0,
1,
1.222,
0,
1.444,
1,
1.667,
1,
1,
1.889,
1,
2.111,
0,
2.333,
0,
1,
2.544,
0,
2.756,
1,
2.967,
1,
1,
3.167,
1,
3.367,
0,
3.567,
0,
0,
4.467,
0
]
},
{
"Target": "Parameter",
"Id": "ParamShoulder",
"Segments": [
0,
0.1,
1,
0.467,
0.1,
0.933,
1,
1.4,
1,
1,
1.844,
1,
2.289,
1,
2.733,
1,
1,
2.967,
1,
3.2,
-1,
3.433,
-1,
0,
4.467,
-1
]
},
{
"Target": "Parameter",
"Id": "ParamLeg",
"Segments": [
0,
1,
0,
4.467,
1
]
},
{
"Target": "Parameter",
"Id": "ParamArmLA",
"Segments": [
0,
-10,
0,
4.467,
-10
]
},
{
"Target": "Parameter",
"Id": "ParamArmRA",
"Segments": [
0,
-10,
0,
4.467,
-10
]
},
{
"Target": "Parameter",
"Id": "ParamHairAhoge",
"Segments": [
0,
0,
1,
0.3,
0,
0.6,
0,
0.9,
-0.012,
1,
1.067,
-0.019,
1.233,
-6.827,
1.4,
-6.827,
1,
1.511,
-6.827,
1.622,
7.958,
1.733,
7.958,
1,
1.944,
7.958,
2.156,
-7.565,
2.367,
-7.565,
1,
2.5,
-7.565,
2.633,
9.434,
2.767,
9.434,
1,
2.978,
9.434,
3.189,
-8.871,
3.4,
-8.871,
1,
3.5,
-8.871,
3.6,
7.588,
3.7,
7.588,
1,
3.789,
7.588,
3.878,
-3.904,
3.967,
-3.904,
1,
4.011,
-3.904,
4.056,
-0.032,
4.1,
-0.032,
0,
4.467,
-0.032
]
},
{
"Target": "PartOpacity",
"Id": "PartArmA",
"Segments": [
0,
0.997,
0,
4.467,
0.997
]
},
{
"Target": "PartOpacity",
"Id": "PartArmB",
"Segments": [
0,
0.001,
0,
4.467,
0.001
]
}
]
}

Some files were not shown because too many files have changed in this diff Show More