Esempio n. 1
0
        private static MvdCameraObject CreateCamera()
        {
            var cam = new MvdCameraObject();

            cam.DisplayName = CameraName;
            cam.EnglishName = CameraName;

            cam.Id = 0;

            return(cam);
        }
Esempio n. 2
0
        private int WriteNameList([NotNull] MvdCameraObject camera, int startId, out int count)
        {
            count = 0;

            _writer.Write(startId);

            WriteVariableLengthString(camera.DisplayName, Utf8WithoutBom);

            ++count;

            // Omitted...

            return(startId + 1);
        }
Esempio n. 3
0
        private IReadOnlyList <MvdCameraMotion> CreateCameraMotions([NotNull] CharacterImasMotionAsset cameraMotion)
        {
            const string cameraName = "カメラ00"; // Localization error (Mr. mogg, please!), MUST NOT USE "Camera00"!

            MvdCameraObject CreateCamera()
            {
                var cam = new MvdCameraObject();

                cam.DisplayName = cameraName;
                cam.EnglishName = cameraName;

                cam.Id = 0;

                return(cam);
            }

            IReadOnlyList <MvdCameraFrame> CreateFrames()
            {
                var animation           = CameraAnimation.CreateFrom(cameraMotion);
                var animationFrameCount = animation.CameraFrames.Count;

                var cameraFrameList = new List <MvdCameraFrame>();

                for (var i = 0; i < animationFrameCount; ++i)
                {
                    if (_conversionConfig.Transform60FpsTo30Fps)
                    {
                        if (i % 2 == 1)
                        {
                            continue;
                        }
                    }

                    int frameIndex;

                    if (_conversionConfig.Transform60FpsTo30Fps)
                    {
                        frameIndex = i / 2;
                    }
                    else
                    {
                        frameIndex = i;
                    }

                    var frame    = animation.CameraFrames[i];
                    var mvdFrame = new MvdCameraFrame(frameIndex);

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

                    pos = pos.FixUnityToOpenTK();

                    if (_conversionConfig.ScaleToVmdSize)
                    {
                        pos = pos * _scalingConfig.ScaleUnityToVmd;
                    }

                    mvdFrame.Position = pos;

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

                    target = target.FixUnityToOpenTK();

                    if (_conversionConfig.ScaleToVmdSize)
                    {
                        target = target * _scalingConfig.ScaleUnityToVmd;
                    }

                    var delta = target - pos;

                    mvdFrame.Distance = delta.Length;

                    var lookAtMatrix = Matrix4.LookAt(pos, target, Vector3.UnitY);
                    var q            = lookAtMatrix.ExtractRotation();

                    var rot = q.DecomposeRad();

                    rot.Z = MathHelper.DegreesToRadians(frame.AngleZ);

                    rot.Y = MathHelper.Pi - rot.Y;

                    if (rot.Y < 0)
                    {
                        rot.Y += MathHelper.TwoPi;
                    }

                    if (delta.Z < 0)
                    {
                        rot.Y = -(MathHelper.Pi + rot.Y);
                    }

                    rot.Z = -rot.Z;

                    if (rot.X < -MathHelper.PiOver2)
                    {
                        rot.X = rot.X + MathHelper.Pi;
                    }
                    else if (rot.X > MathHelper.PiOver2)
                    {
                        rot.X = -(MathHelper.Pi - rot.X);
                    }

                    mvdFrame.Rotation = rot;

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

                    cameraFrameList.Add(mvdFrame);
                }

                return(cameraFrameList);
            }

            IReadOnlyList <MvdCameraPropertyFrame> CreatePropertyFrames()
            {
                var list = new List <MvdCameraPropertyFrame>();

                var f = new MvdCameraPropertyFrame(0);

                f.Enabled               = true;
                f.IsPerspective         = true;
                f.Alpha                 = 1;
                f.EffectEnabled         = true;
                f.DynamicFovEnabled     = false;
                f.DynamicFovRate        = 0.1f;
                f.DynamicFovCoefficient = 1;
                f.RelatedBoneId         = -1;
                f.RelatedModelId        = -1;

                list.Add(f);

                return(list);
            }

            // https://photo.stackexchange.com/questions/41273/how-to-calculate-the-fov-in-degrees-from-focal-length-or-distance
            float FocalLengthToFov(float focalLength)
            {
                // By experiments, MLTD seems to use a 15mm or 16mm camera.
                const float sensorSize = 12; // unit: mm, as the unit of MLTD camera frame is also mm
                var         fovRad     = 2 * (float)Math.Atan((sensorSize / 2) / focalLength);
                var         fovDeg     = MathHelper.RadiansToDegrees(fovRad);

                return(fovDeg);
            }

            var camera               = CreateCamera();
            var cameraFrames         = CreateFrames();
            var cameraPropertyFrames = CreatePropertyFrames();

            var result = new MvdCameraMotion(camera, cameraFrames, cameraPropertyFrames);

            result.DisplayName = cameraName;
            result.EnglishName = cameraName;

            return(new[] { result });
        }