216 lines
9.4 KiB
C#
216 lines
9.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using JD.Kernel.Structs;
|
|
using JD.LogService;
|
|
using TeaBox;
|
|
using JD.Serialization;
|
|
|
|
namespace JD.Timeline.Dance
|
|
{
|
|
/// <summary>
|
|
/// Validation to check that dance tape is valid
|
|
/// </summary>
|
|
public class DanceDocumentValidation
|
|
{
|
|
public static void Validate(Tape tape, ILogger context)
|
|
{
|
|
ValidateMoveModels(context, tape);
|
|
ValidatePictoModels(context, tape);
|
|
foreach (var track in tape.Tracks)
|
|
{
|
|
if (track is MoveTrack)
|
|
{
|
|
var moveTrack = track as MoveTrack;
|
|
switch (moveTrack.MoveType)
|
|
{
|
|
case MotionClip.MoveType_Enum.MoveType_HandOnly:
|
|
ValidateMoveTrack(context, moveTrack);
|
|
break;
|
|
case MotionClip.MoveType_Enum.MoveType_FullBody:
|
|
ValidateCameraMoveTrack(context, moveTrack);
|
|
break;
|
|
}
|
|
}
|
|
else if (track is PictoTrack)
|
|
{
|
|
ValidatePictoTrack(context, track as PictoTrack);
|
|
}
|
|
else if (track is GoldEffectTrack)
|
|
{
|
|
ValidateGoldEffectTrack(context, track as GoldEffectTrack);
|
|
}
|
|
else if (track is CommunityDancerTrack)
|
|
{
|
|
//No validation yet
|
|
}
|
|
else
|
|
{
|
|
context.LogError("Track '{0}' has to be a MoveTrack or a PictoTrack.", track.Name);
|
|
}
|
|
}
|
|
|
|
foreach (var clip in tape.Clips)
|
|
{
|
|
if (clip.CollisionsWithOther)
|
|
{
|
|
context.LogWarning(new FileLocation(tape.Id, new List<uint> { clip.Id }), $"{clip.ToStringDetailed()} has a collision with an other clip.");
|
|
}
|
|
var sameIdClipCount = tape.Clips.Count(x => x.Id == clip.Id);
|
|
if (sameIdClipCount != 1)
|
|
{
|
|
context.LogError(new FileLocation(tape.Id, new List<uint> { clip.Id }), $"{sameIdClipCount} clips have the same id '{clip.Id}'");
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void ValidateMoveTrack(ILogger context, MoveTrack track)
|
|
{
|
|
if (!MoveTrack.NameValidationRegexHandOnly.IsMatch(track.Name))
|
|
{
|
|
context.LogError($"Track '{track.Name}' has an invalid name.");
|
|
}
|
|
|
|
foreach (var clip in track.Clips())
|
|
{
|
|
if (clip is MotionClip)
|
|
{
|
|
var motionClip = clip as MotionClip;
|
|
if (motionClip.CoachId != track.CoachId)
|
|
{
|
|
context.LogError(new FileLocation(track.Tape.Id, new List<uint> { clip.Id }), $"{clip.ToStringDetailed()} CoachId is different from Track one.");
|
|
}
|
|
if (motionClip.MoveType != MotionClip.MoveType_Enum.MoveType_HandOnly)
|
|
{
|
|
context.LogError(new FileLocation(track.Tape.Id, new List<uint> { clip.Id }), $"{clip.ToStringDetailed()} MoveType is invalid.");
|
|
}
|
|
if (string.IsNullOrEmpty(motionClip.Model.Name))
|
|
{
|
|
context.LogError(new FileLocation(track.Tape.Id, new List<uint> { clip.Id }), $"{clip.ToStringDetailed()} has a model with empty name.");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
context.LogError(new FileLocation(track.Tape.Id, new List<uint> { clip.Id }), $"{clip.ToStringDetailed()} has in an invalid type.");
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void ValidateMoveModels(ILogger context, Tape tape)
|
|
{
|
|
foreach (var moveModel in tape.MoveModels())
|
|
{
|
|
foreach (var clip in moveModel.Instances)
|
|
{
|
|
if (Math.Abs(clip.BeatDuration - moveModel.BeatDuration) > float.Epsilon)
|
|
{
|
|
context.LogError(new FileLocation(tape.Id, new List<uint> { clip.Id }), $"{clip.ToStringDetailed()} has a different duration than its model.");
|
|
}
|
|
if (clip.Color != moveModel.Color)
|
|
{
|
|
context.LogError(new FileLocation(tape.Id, new List<uint> { clip.Id }), $"{clip.ToStringDetailed()} has a different color than its model.");
|
|
}
|
|
if (!clip.ClassifierPath.Equals(moveModel.ClassifierPath))
|
|
{
|
|
context.LogError(new FileLocation(tape.Id, new List<uint> { clip.Id }), $"{clip.ToStringDetailed()} has a different classifierpath than its model.");
|
|
}
|
|
if (clip.MoveType != moveModel.MoveType)
|
|
{
|
|
context.LogError(new FileLocation(tape.Id, new List<uint> { clip.Id }), $"{clip.ToStringDetailed()} has a different move type than its model.");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void ValidateCameraMoveTrack(ILogger context, MoveTrack track)
|
|
{
|
|
if (!MoveTrack.NameValidationRegexFullBody.IsMatch(track.Name))
|
|
{
|
|
context.LogError($"Track '{track.Name}' has an invalid name.");
|
|
}
|
|
foreach (var clip in track.Clips())
|
|
{
|
|
if (clip is MotionClip)
|
|
{
|
|
var motionClip = clip as MotionClip;
|
|
if (motionClip.CoachId != track.CoachId)
|
|
{
|
|
context.LogError(new FileLocation(track.Tape.Id, new List<uint> { clip.Id }), $"{clip.ToStringDetailed()} CoachId is different from Track one.");
|
|
}
|
|
if (motionClip.MoveType != MotionClip.MoveType_Enum.MoveType_FullBody)
|
|
{
|
|
context.LogError(new FileLocation(track.Tape.Id, new List<uint> { clip.Id }), $"{clip.ToStringDetailed()} MoveType is invalid.");
|
|
}
|
|
if (string.IsNullOrEmpty(motionClip.Model.Name))
|
|
{
|
|
context.LogError(new FileLocation(track.Tape.Id, new List<uint> { clip.Id }), $"{clip.ToStringDetailed()} has a model with empty name.");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
context.LogError(new FileLocation(track.Tape.Id, new List<uint> { clip.Id }), $"{clip.ToStringDetailed()} has in an invalid type. It should be a MotionClip.");
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void ValidatePictoTrack(ILogger context, PictoTrack track)
|
|
{
|
|
if (!PictoTrack.NameValidationRegex.IsMatch(track.Name))
|
|
{
|
|
context.LogError($"Track '{track.Name}' has an invalid name.");
|
|
}
|
|
foreach (var clip in track.Clips())
|
|
{
|
|
if (clip is PictogramClip)
|
|
{
|
|
var pictoClip = clip as PictogramClip;
|
|
if (string.IsNullOrEmpty(pictoClip.Model.Name))
|
|
{
|
|
context.LogError(new FileLocation(track.Tape.Id, new List<uint> { clip.Id }), $"{clip.ToStringDetailed()} has a model with empty name.");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
context.LogError(new FileLocation(track.Tape.Id, new List<uint> { clip.Id }), $"{clip.ToStringDetailed()} has in an invalid type. It shloud be a PictogramClip.");
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void ValidatePictoModels(ILogger context, Tape tape)
|
|
{
|
|
foreach (var pictogramModel in tape.PictogramModels())
|
|
{
|
|
foreach (var clip in pictogramModel.Instances)
|
|
{
|
|
if (!clip.PictoPath.Equals(pictogramModel.PictoPath))
|
|
{
|
|
context.LogError(new FileLocation(tape.Id, new List<uint> { clip.Id }), $"{clip.ToStringDetailed()} has a different classifierpath than its model.");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void ValidateGoldEffectTrack(ILogger context, GoldEffectTrack track)
|
|
{
|
|
if (track.Name != GoldEffectTrack.DefaultName)
|
|
{
|
|
context.LogError($"Track '{track.Name}' has an invalid name.");
|
|
}
|
|
foreach (var clip in track.Clips())
|
|
{
|
|
if (clip is GoldEffectClip)
|
|
{
|
|
var goldEffect = clip as GoldEffectClip;
|
|
if (Math.Abs(goldEffect.BeatDuration - GoldEffectClip.FixedDurationInBeats) > float.Epsilon)
|
|
{
|
|
context.LogError(new FileLocation(track.Tape.Id, new List<uint> { clip.Id }), $"{clip.ToStringDetailed()} duration needs to be {GoldEffectClip.FixedDurationInBeats}.");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
context.LogError(new FileLocation(track.Tape.Id, new List<uint> { clip.Id }), $"{clip.ToStringDetailed()} has in an invalid type. It should be a GoldEffectClip");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|