-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #24 from nasshu2916/feature/amin-reduce-key
フレーム削減周りのリファクタ
- Loading branch information
Showing
7 changed files
with
147 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
namespace ArtNet.Editor | ||
{ | ||
public struct KeyFrameData | ||
{ | ||
public float Time { get; } | ||
public byte Value { get; } | ||
|
||
public KeyFrameData(float time, byte value) | ||
{ | ||
Time = time; | ||
Value = value; | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
|
||
namespace ArtNet.Editor | ||
{ | ||
public static class KeyFrameReducer | ||
{ | ||
public static List<KeyFrameData> Reduce(List<KeyFrameData> keyFrameData) | ||
{ | ||
if (keyFrameData.Count <= 2) return keyFrameData; | ||
|
||
var newDmxFrameData = new List<KeyFrameData> { keyFrameData[0] }; | ||
var latest = keyFrameData[0]; | ||
|
||
for (var i = 1; i < keyFrameData.Count - 1; i++) | ||
{ | ||
var current = keyFrameData[i]; | ||
if (latest.Value == current.Value) continue; | ||
|
||
newDmxFrameData.Add(current); | ||
latest = current; | ||
} | ||
|
||
newDmxFrameData.Add(keyFrameData[^1]); | ||
return newDmxFrameData; | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using UnityEngine; | ||
|
||
namespace ArtNet.Editor | ||
{ | ||
public class RamerDouglasPeucker | ||
{ | ||
private readonly float _threshold; | ||
|
||
public RamerDouglasPeucker(float errorThreshold) | ||
{ | ||
_threshold = errorThreshold * errorThreshold; | ||
} | ||
|
||
public List<Keyframe> Reduce(ReadOnlySpan<Keyframe> keys) | ||
{ | ||
return Execute(keys, 0, keys.Length - 1); | ||
} | ||
|
||
private List<Keyframe> Execute(ReadOnlySpan<Keyframe> keys, int startIndex, int endIndex) | ||
{ | ||
if (endIndex - startIndex < 2) | ||
{ | ||
return new List<Keyframe> { keys[startIndex], keys[endIndex] }; | ||
} | ||
|
||
// 最大距離のKeyframeを探索 | ||
var maxDistance = 0f; | ||
var maxIndex = startIndex; | ||
for (var i = startIndex + 1; i < endIndex; i++) | ||
{ | ||
var distance = PerpendicularDistanceSquared(keys[i], keys[startIndex], keys[endIndex]); | ||
if (distance <= maxDistance) continue; | ||
|
||
maxIndex = i; | ||
maxDistance = distance; | ||
} | ||
|
||
// 最大距離が閾値未満なら直線を返す | ||
if (maxDistance < _threshold) | ||
{ | ||
return new List<Keyframe> { keys[startIndex], keys[endIndex] }; | ||
} | ||
|
||
// 最大距離の点で再帰的に処理 | ||
var result1 = Execute(keys, startIndex, maxIndex); | ||
var result2 = Execute(keys, maxIndex, endIndex); | ||
|
||
// 重複を取り除いて結合 | ||
result1.RemoveAt(result1.Count - 1); | ||
result1.AddRange(result2); | ||
|
||
return result1; | ||
} | ||
|
||
/// <summary> | ||
/// 垂線距離の2乗を計算 | ||
/// </summary> | ||
private static float PerpendicularDistanceSquared(Keyframe point, Keyframe startPoint, Keyframe endPoint) | ||
{ | ||
var dx = endPoint.time - startPoint.time; | ||
var dy = endPoint.value - startPoint.value; | ||
|
||
var denominator = dx * dx + dy * dy; | ||
|
||
if (denominator < 1e-6f) | ||
{ | ||
var psx = point.time - startPoint.time; | ||
var psy = point.value - startPoint.value; | ||
return psx * psx + psy * psy; | ||
} | ||
|
||
var numerator = dy * point.time - dx * point.value + endPoint.time * startPoint.value - endPoint.value * startPoint.time; | ||
return (numerator * numerator) / denominator; | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.