/// <summary> /// ストリームから表情モーションを生成する /// </summary> /// <param name="stream">ストリーム</param> /// <param name="model">対象のモデル</param> public CubismExpressionMotion(Stream stream, CubismModel model) { // 表情モーションデータを読み込む var json = CubismExpressionJson.Create(stream); GlobalFadeInSeconds = Math.Min(Math.Max(json.FadeInTime, 0.0), 1.0); GlobalFadeOutSeconds = Math.Min(Math.Max(json.FadeOutTime, 0.0), 1.0); // パラメータを読み取る Parameters = new ExpressionParameter[json.Parameters.Length]; for (int index = 0; index < json.Parameters.Length; index++) { var parameter = new ExpressionParameter(); var parameter_item = json.Parameters[index]; parameter.Parameter = model.GetParameter(parameter_item.Id); switch (parameter_item.Blend) { case "Add": default: parameter.Blend = BlendType.Add; break; case "Multiply": parameter.Blend = BlendType.Multiply; break; case "Overwrite": parameter.Blend = BlendType.Overwrite; break; } parameter.Value = parameter_item.Value; Parameters[index] = parameter; } }
/// <summary> /// モデルを削除する。 /// </summary> /// <param name="model">削除するモデル</param> public void DeleteModel(CubismModel model) { if (model != null) { ModelCount--; Debug.Assert(0 <= ModelCount); } model = null; }
/// <summary> /// ストリームからポーズデータを読み込む。 /// </summary> /// <param name="stream">ストリーム</param> /// <param name="model">対象のモデル</param> public CubismPose(Stream stream, CubismModel model) { var json = CubismPoseJson.Create(stream); if (!double.IsNaN(json.FadeInTime) && (0.0 <= json.FadeInTime)) { FadeTimeSeconds = json.FadeInTime; } var part_groups = new List <PartData[]>(); foreach (var group_item in json.Groups) { var part_group = new List <PartData>(); foreach (var item in group_item) { CubismPart id = model.GetPart(item.Id); var part_data = new PartData(model, id); var linked_part_ids = new List <CubismPart>(); foreach (string linked_id_name in item.Link) { CubismPart linked_id = model.GetPart(linked_id_name); if (linked_id != null) { linked_part_ids.Add(linked_id); } } part_data.LinkedParts = linked_part_ids.ToArray(); part_group.Add(part_data); } part_groups.Add(part_group.ToArray()); } PartGroups = part_groups.ToArray(); Reset(); }
private static CubismMotionCurve ParseCurve(CubismMotionJson.CurveItem item, CubismModel model) { CubismMotionCurve curve = new CubismMotionCurve(); if (item.Target == "Model") { curve.Target = CubismMotionCurve.TargetType.Model; curve.Effect = new CubismId(item.Id); } else if (item.Target == "Parameter") { curve.Target = CubismMotionCurve.TargetType.Parameter; curve.Parameter = model.GetParameter(item.Id); if (curve.Parameter == null) { return(null); } } else if (item.Target == "PartOpacity") { curve.Target = CubismMotionCurve.TargetType.PartOpacity; curve.Part = model.GetPart(item.Id); if (curve.Part == null) { return(null); } } else { return(null); } curve.FadeInTime = item.FadeInTime; curve.FadeOutTime = item.FadeOutTime; // 制御点を読み込む // 初めの2アイテムは最初の制御点を示す var segment_item = item.Segments; int segment_count = item.Segments.Length; CubismMotionPoint last_point = new CubismMotionPoint(segment_item[0], segment_item[1]); // 以降の制御点を読み込む var segments = new List <ICubismMotionSegment>(); for (int segment_index = 2; segment_index < segment_count;) { switch ((CubismMotionSegmentType)segment_item[segment_index]) { case CubismMotionSegmentType.Linear: { var segment = new CubismMotionLinearSegment(); segment.Points[0] = last_point; segment.Points[1] = new CubismMotionPoint(segment_item[segment_index + 1], segment_item[segment_index + 2]); segments.Add(segment); last_point = segment.Points[1]; segment_index += 3; break; } case CubismMotionSegmentType.Bezier: { var segment = new CubismMotionBezierSegment(); segment.Points[0] = last_point; segment.Points[1] = new CubismMotionPoint(segment_item[segment_index + 1], segment_item[segment_index + 2]); segment.Points[2] = new CubismMotionPoint(segment_item[segment_index + 3], segment_item[segment_index + 4]); segment.Points[3] = new CubismMotionPoint(segment_item[segment_index + 5], segment_item[segment_index + 6]); segments.Add(segment); last_point = segment.Points[3]; segment_index += 7; break; } case CubismMotionSegmentType.Stepped: { var segment = new CubismMotionSteppedSegment(); segment.Points[0] = last_point; segment.Points[1] = new CubismMotionPoint(segment_item[segment_index + 1], segment_item[segment_index + 2]); segments.Add(segment); last_point = segment.Points[1]; segment_index += 3; break; } case CubismMotionSegmentType.InverseStepped: { var segment = new CubismMotionInverseSteppedSegment(); segment.Points[0] = last_point; segment.Points[1] = new CubismMotionPoint(segment_item[segment_index + 1], segment_item[segment_index + 2]); segments.Add(segment); last_point = segment.Points[1]; segment_index += 3; break; } default: throw new ArgumentOutOfRangeException(); } } curve.Segments = segments.ToArray(); return(curve); }
/// <summary> /// ストリームからモーションを生成する /// </summary> /// <param name="stream">ストリーム</param> /// <param name="setting_motion_item">CubismModelSettingJsonのこのモーションの設定</param> /// <param name="id_manager">IDマネージャー</param> public CubismMotion(Stream stream, CubismModelSettingJson.FileReferencesItem.MotionItem setting_motion_item, CubismModel model) { // モーションデータを読み込む var json = CubismMotionJson.Create(stream); Duration = json.Meta.Duration; CanLoop = json.Meta.Loop; // 標準のフェード時間を取得する。 // モデルのjsonファイルで指定されている値を優先的に適用するが、 // 無かったらモーションのjsonファイルの値を使う。 GlobalFadeInSeconds = (setting_motion_item != null) ? setting_motion_item.FadeInTime : 0.0; GlobalFadeInSeconds = !double.IsNaN(GlobalFadeInSeconds) ? GlobalFadeInSeconds : json.Meta.FadeInTime; GlobalFadeInSeconds = !double.IsNaN(GlobalFadeInSeconds) ? GlobalFadeInSeconds : 0.0; GlobalFadeOutSeconds = (setting_motion_item != null) ? setting_motion_item.FadeOutTime : 0.0; GlobalFadeOutSeconds = !double.IsNaN(GlobalFadeOutSeconds) ? GlobalFadeOutSeconds : json.Meta.FadeOutTime; GlobalFadeOutSeconds = !double.IsNaN(GlobalFadeOutSeconds) ? GlobalFadeOutSeconds : 0.0; // モーションカーブを内部形式に変換する var curve_list = new List <CubismMotionCurve>(); foreach (var item in json.Curves) { var curve = ParseCurve(item, model); if (curve == null) { continue; } if (curve.Target == CubismMotionCurve.TargetType.Model) { // ターゲットがモデルのとき、エフェクトIDが対象となる // これらはパラメータや不透明度を対象としたカーブより先に処理しなければいけないため別に管理する EffectCurves[curve.Effect] = curve; } else { curve_list.Add(curve); } } Curves = curve_list.ToArray(); // ユーザーデータを読み込む if ((json.UserData != null) && (json.Meta.UserDataCount == json.UserData.Length)) { int userdata_count = json.Meta.UserDataCount; Events = new CubismMotionEvent[userdata_count]; for (int index = 0; index < userdata_count; index++) { var userdata = new CubismMotionEvent(); userdata.FireTime = json.UserData[index].Time; userdata.Value = json.UserData[index].Value; Events[index] = userdata; } } else { Events = new CubismMotionEvent[0]; } }
/// <summary> /// コンストラクタ /// </summary> /// <param name="model">初期化に使用するモデル</param> public PartData(CubismModel model, CubismPart part) { Part = part; Part.TargetOpacity = 1.0; LinkedParts = null; }