예제 #1
0
        private void WriteCameraProperty([NotNull] MvdCameraMotion cameraMotion, int id)
        {
            var writer = _writer;

            writer.Write((byte)104);
            writer.Write((byte)2);
            writer.Write(id);
            writer.Write(32);

            writer.Write(cameraMotion.CameraPropertyFrames.Count); // 1 frame
            writer.Write(0);

            foreach (var frame in cameraMotion.CameraPropertyFrames)
            {
                writer.Write(frame.FrameNumber);
                writer.Write(frame.Enabled);
                writer.Write(frame.IsPerspective);
                writer.Write(frame.Alpha);
                writer.Write(frame.EffectEnabled);
                writer.Write(frame.DynamicFovEnabled);
                writer.Write(frame.DynamicFovRate);
                writer.Write(frame.DynamicFovCoefficient);
                writer.Write(frame.RelatedModelId);
                writer.Write(frame.RelatedBoneId);
            }
        }
예제 #2
0
        private MvdCameraMotion[] CreateCameraMotions([NotNull] CharacterImasMotionAsset mainCamera, [NotNull] ScenarioObject baseScenario, [CanBeNull] CharacterImasMotionAsset cameraAppeal, AppealType appealType)
        {
            var camera               = CreateCamera();
            var cameraFrames         = CreateFrames(mainCamera, baseScenario, cameraAppeal, appealType);
            var cameraPropertyFrames = CreatePropertyFrames();

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

            result.DisplayName = CameraName;
            result.EnglishName = CameraName;

            return(new[] { result });
        }
예제 #3
0
        private void WriteCamera([NotNull] MvdCameraMotion cameraMotion, int id)
        {
            var writer = _writer;

            writer.Write((byte)96);
            writer.Write((byte)3);
            writer.Write(id);
            writer.Write(64);

            writer.Write(cameraMotion.CameraFrames.Count);

            writer.Write(4);
            // stream.Write(BitConverter.GetBytes(cameraSequence.motiondata[boneindex].Count), 0, 4);
            // It seems the value is always 1 in our case...
            writer.Write(1);

            var i = 0;

            foreach (var frame in cameraMotion.CameraFrames)
            {
                writer.Write(i); // layer index
                writer.Write(frame.FrameNumber);

                writer.Write(frame.Distance);
                writer.Write(frame.Position);
                writer.Write(frame.Rotation);
                writer.Write(frame.FieldOfView);
                writer.Write(frame.IsSpline);

                WriteZeroBlocks(writer, 3);

                writer.Write(frame.TranslationInterpolation);
                writer.Write(frame.RotationInterpolation);
                writer.Write(frame.DistanceInterpolation);
                writer.Write(frame.FovInterpolation);
            }

            ++i;
        }
예제 #4
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 });
        }