Skip to content

Commit

Permalink
[MillionDance] Respect frame rate scaling of camera and dance in appe…
Browse files Browse the repository at this point in the history
…als (#38)
  • Loading branch information
hozuki committed Aug 22, 2020
1 parent 28ff1ae commit cc0eb1f
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 28 deletions.
38 changes: 22 additions & 16 deletions src/MillionDance/Core/MvdCreator.Camera.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,14 @@ private MvdCameraFrame[] CreateFrames([NotNull] CharacterImasMotionAsset mainCam

var cameraFrameList = new List<MvdCameraFrame>();

var appealTimes = AppealHelper.CollectAppealTimeInfo(baseScenario);
var appealTimes = appealType != AppealType.None ? AppealHelper.CollectAppealTimeInfo(baseScenario) : default;

var transform60FpsTo30Fps = _conversionConfig.Transform60FpsTo30Fps;
var scaleToVmdSize = _conversionConfig.ScaleToVmdSize;
var unityToVmdScale = _scalingConfig.ScaleUnityToVmd;

for (var mltdFrameIndex = 0; mltdFrameIndex < animationFrameCount; ++mltdFrameIndex) {
if (_conversionConfig.Transform60FpsTo30Fps) {
if (transform60FpsTo30Fps) {
if (mltdFrameIndex % 2 == 1) {
continue;
}
Expand All @@ -81,14 +82,6 @@ private MvdCameraFrame[] CreateFrames([NotNull] CharacterImasMotionAsset mainCam
var shouldUseAppeal = appealType != AppealType.None && (appealTimes.StartFrame <= mltdFrameIndex && mltdFrameIndex < appealTimes.EndFrame) && appealAnimation != null;
var animation = shouldUseAppeal ? appealAnimation : mainAnimation;

int mvdFrameIndex;

if (_conversionConfig.Transform60FpsTo30Fps) {
mvdFrameIndex = mltdFrameIndex / 2;
} else {
mvdFrameIndex = mltdFrameIndex;
}

int projectedFrameIndex;

if (shouldUseAppeal) {
Expand All @@ -98,16 +91,29 @@ private MvdCameraFrame[] CreateFrames([NotNull] CharacterImasMotionAsset mainCam
indexInAppeal = appealAnimation.FrameCount - 1;
}

projectedFrameIndex = indexInAppeal;
// `indexInAppeal`, unlike `mltdFrameIndex`, has not been scaled yet
if (transform60FpsTo30Fps) {
projectedFrameIndex = indexInAppeal / 2;
} else {
projectedFrameIndex = indexInAppeal;
}
} else {
projectedFrameIndex = mltdFrameIndex;
}

var frame = animation.CameraFrames[projectedFrameIndex];
var motionFrame = animation.CameraFrames[projectedFrameIndex];

int mvdFrameIndex;

if (transform60FpsTo30Fps) {
mvdFrameIndex = mltdFrameIndex / 2;
} else {
mvdFrameIndex = mltdFrameIndex;
}

var mvdFrame = new MvdCameraFrame(mvdFrameIndex);

var position = new Vector3(frame.PositionX, frame.PositionY, frame.PositionZ);
var position = new Vector3(motionFrame.PositionX, motionFrame.PositionY, motionFrame.PositionZ);

position = position.FixUnityToMmd();

Expand All @@ -117,7 +123,7 @@ private MvdCameraFrame[] CreateFrames([NotNull] CharacterImasMotionAsset mainCam

mvdFrame.Position = position;

var target = new Vector3(frame.TargetX, frame.TargetY, frame.TargetZ);
var target = new Vector3(motionFrame.TargetX, motionFrame.TargetY, motionFrame.TargetZ);

target = target.FixUnityToMmd();

Expand All @@ -131,12 +137,12 @@ private MvdCameraFrame[] CreateFrames([NotNull] CharacterImasMotionAsset mainCam

var q = CameraOrientation.QuaternionLookAt(in position, in target, in Vector3.UnitY);

var rotation = CameraOrientation.ComputeMmdOrientation(in q, frame.AngleZ);
var rotation = CameraOrientation.ComputeMmdOrientation(in q, motionFrame.AngleZ);

mvdFrame.Rotation = rotation;

// MVD has good support of dynamic FOV. So here we can animate its value.
var fov = FocalLengthToFov(frame.FocalLength);
var fov = FocalLengthToFov(motionFrame.FocalLength);
mvdFrame.FieldOfView = MathHelper.DegreesToRadians(fov);

cameraFrameList.Add(mvdFrame);
Expand Down
29 changes: 17 additions & 12 deletions src/MillionDance/Core/VmdCreator.Dance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,36 +110,39 @@ private VmdBoneFrame[] CreateBoneFrames([NotNull] IBodyAnimationSource mainDance
var lastSoughtFrame = -1;

// OK, now perform iterations
for (var naturalFrameIndex = 0; naturalFrameIndex < resultFrameCount; ++naturalFrameIndex) {
for (var mltdFrameIndex = 0; mltdFrameIndex < resultFrameCount; ++mltdFrameIndex) {
if (transform60FpsTo30Fps) {
if (naturalFrameIndex % 2 == 1) {
if (mltdFrameIndex % 2 == 1) {
continue;
}
}

var shouldUseAppeal = appealType != AppealType.None && (appealTimes.StartFrame <= naturalFrameIndex && naturalFrameIndex < appealTimes.EndFrame) && appealAnimation != null;
var shouldUseAppeal = appealType != AppealType.None && (appealTimes.StartFrame <= mltdFrameIndex && mltdFrameIndex < appealTimes.EndFrame) && appealAnimation != null;

var animation = shouldUseAppeal ? appealAnimation : mainAnimation;

int keyFrameIndexStart;
int projectedFrameIndex;

if (shouldUseAppeal) {
var indexInAppeal = naturalFrameIndex - appealTimes.StartFrame;
var indexInAppeal = mltdFrameIndex - appealTimes.StartFrame;

if (indexInAppeal >= appealAnimation.FrameCount) {
indexInAppeal = appealAnimation.FrameCount - 1;
}

keyFrameIndexStart = indexInAppeal * animatedBoneCount;
// `indexInAppeal`, unlike `mltdFrameIndex`, has not been scaled yet
if (transform60FpsTo30Fps) {
projectedFrameIndex = indexInAppeal / 2;
} else {
projectedFrameIndex = indexInAppeal;
}
} else {
var actualFrameIndex = CalculateSeekFrameTarget(naturalFrameIndex, seekFrameControls, ref lastSoughtFrame, ref seekFrameCounter);

keyFrameIndexStart = actualFrameIndex * animatedBoneCount;
projectedFrameIndex = CalculateSeekFrameTarget(mltdFrameIndex, seekFrameControls, ref lastSoughtFrame, ref seekFrameCounter);
}

var formationList = shouldUseAppeal ? appealFormationList : baseFormationList;

formationList.TryGetCurrentValue(naturalFrameIndex, out var formations);
formationList.TryGetCurrentValue(mltdFrameIndex, out var formations);

Vector4 idolOffset;

Expand All @@ -149,6 +152,8 @@ private VmdBoneFrame[] CreateBoneFrames([NotNull] IBodyAnimationSource mainDance
idolOffset = formations[formationNumber - 1];
}

var keyFrameIndexStart = projectedFrameIndex * animatedBoneCount;

for (var j = 0; j < animatedBoneCount; ++j) {
var keyFrame = animation.KeyFrames[keyFrameIndexStart + j];
var mltdBoneName = GetMltdBoneNameWithoutBodyScale(boneNameCache, keyFrame);
Expand Down Expand Up @@ -278,9 +283,9 @@ private VmdBoneFrame[] CreateBoneFrames([NotNull] IBodyAnimationSource mainDance
int vmdFrameIndex;

if (_conversionConfig.Transform60FpsTo30Fps) {
vmdFrameIndex = naturalFrameIndex / 2;
vmdFrameIndex = mltdFrameIndex / 2;
} else {
vmdFrameIndex = naturalFrameIndex;
vmdFrameIndex = mltdFrameIndex;
}

var mltdBoneName = GetMltdBoneNameWithoutBodyScale(boneNameCache, mltdBone.Path);
Expand Down

0 comments on commit cc0eb1f

Please sign in to comment.