public override void Run(CommandArgs e) { var mode = this.Scene.Mode; Action reset = null; if (mode != EditMode.ModelMode && mode != EditMode.AccessoryMode && mode != EditMode.EffectMode || mode == EditMode.ModelMode && this.Scene.ActiveModel == null || mode == EditMode.AccessoryMode && this.Scene.ActiveAccessory == null || mode == EditMode.EffectMode && this.Scene.ActiveEffect == null) { MessageBox.Show(this.ApplicationForm, Util.Bilingual ( this.Scene.Language, "対象のモデル、アクセサリ、またはエフェクトがありません。\r\n対象のキーフレームを選択してから実行してください。", "No target selected.\r\nPlease select one or more keyframes to rotate." ), Util.Bilingual(this.Scene.Language, this.Text, this.EnglishText), MessageBoxButtons.OK, MessageBoxIcon.Information); e.Cancel = true; return; } using (new EnableScreenObjectBlock(this.Scene)) using (var image = new ScreenImage_2D(Point.Empty, Resources.Origin)) using (var f = new ApplyRotationForm(this.Scene.Language) { Position = position, Rotation = rotation, IsMoveOnly = isMoveOnly, }) try { this.Scene.ScreenObjects.Add(image); f.ValueChanged += (sender, e2) => { var camera = this.Scene.ActiveCamera ?? this.Scene.Cameras.First(); var pt = Vector3.Project ( f.Position, 0, 0, this.Scene.ScreenSize.Width, this.Scene.ScreenSize.Height, this.Scene.SystemInformation.NearPlane, this.Scene.SystemInformation.FarPlane, camera.ViewMatrix * camera.ProjectionMatrix ); image.Position = new Point((int)pt.X - image.Size.Width / 2, (int)pt.Y - image.Size.Height / 2); Apply(mode, f, true, ref reset); }; var rt = f.ShowDialog(this.ApplicationForm); if (reset != null) { reset(); reset = null; } if (rt != DialogResult.OK) { e.Cancel = true; return; } position = f.Position; rotation = f.Rotation; isMoveOnly = f.IsMoveOnly; using (new UndoBlock(this.Scene)) Apply(mode, f, false, ref reset); } finally { this.Scene.ScreenObjects.Remove(image); } }
void Apply(EditMode mode, ApplyRotationForm f, bool previewOnly, ref Action reset) { var rotate = !f.IsMoveOnly; var quaternion = Quaternion.RotationYawPitchRoll(MathHelper.ToRadians(f.Rotation.Y), MathHelper.ToRadians(f.Rotation.X), MathHelper.ToRadians(f.Rotation.Z)); var offset = Matrix.Translation(-f.Position) * Matrix.RotationQuaternion(quaternion) * Matrix.Translation(f.Position); if (reset != null) { reset(); reset = null; } switch (mode) { case EditMode.AccessoryMode: var acc = this.Scene.ActiveAccessory; if (acc != null) { foreach (var i in acc.SelectedLayers) { var local = i.CurrentLocalMotion; var newLocal = new MotionData ( Vector3.TransformCoordinate(local.Move, offset), rotate ? Quaternion.Multiply(quaternion, local.Rotation) : local.Rotation ); reset += () => i.CurrentLocalMotion = local; i.CurrentLocalMotion = newLocal; } if (!previewOnly) { foreach (var i in acc.Layers.SelectMany(_ => _.SelectedFrames)) { var resetPosition = i.Position; var resetQuaternion = i.Quaternion; reset += () => { i.Position = resetPosition; i.Quaternion = resetQuaternion; }; if (rotate) { i.Quaternion = Quaternion.Multiply(quaternion, i.Quaternion); } i.Position = Vector3.TransformCoordinate(i.Position, offset); } } } break; case EditMode.EffectMode: var eff = this.Scene.ActiveEffect; if (eff != null) { var local = eff.CurrentMotion; var newLocal = new MotionData ( Vector3.TransformCoordinate(local.Move, offset), rotate ? Quaternion.Multiply(quaternion, local.Rotation) : local.Rotation ); reset += () => eff.CurrentMotion = local; eff.CurrentMotion = newLocal; if (!previewOnly) { foreach (var i in eff.SelectedFrames) { var resetPosition = i.Position; var resetQuaternion = i.Quaternion; reset += () => { i.Position = resetPosition; i.Quaternion = resetQuaternion; }; if (rotate) { i.Quaternion = Quaternion.Multiply(quaternion, i.Quaternion); } i.Position = Vector3.TransformCoordinate(i.Position, offset); } } } break; case EditMode.ModelMode: var model = this.Scene.ActiveModel; if (model != null) { foreach (var bone in model.Bones) { var initialPosition = Matrix.Translation(bone.InitialPosition); if (bone.ParentBoneID != -1) { initialPosition *= GetMotion(model.Bones, bone); } var offsetWithInitialPosition = initialPosition * offset * Matrix.Invert(initialPosition); Vector3 scale; Quaternion rotation; Vector3 translation; offsetWithInitialPosition.Decompose(out scale, out rotation, out translation); foreach (var i in bone.SelectedLayers) { var local = i.CurrentLocalMotion; var newLocal = new MotionData ( (bone.BoneFlags & BoneType.XYZ) != 0 ? Vector3.TransformCoordinate(local.Move, offsetWithInitialPosition) : local.Move, (bone.BoneFlags & BoneType.Rotate) != 0 && rotate ? Quaternion.Multiply(rotation, local.Rotation) : local.Rotation ); reset += () => i.CurrentLocalMotion = local; i.CurrentLocalMotion = newLocal; } if (!previewOnly) { foreach (var i in bone.Layers.SelectMany(_ => _.SelectedFrames)) { var resetPosition = i.Position; var resetQuaternion = i.Quaternion; reset += () => { i.Position = resetPosition; i.Quaternion = resetQuaternion; }; if (rotate) { i.Quaternion = Quaternion.Multiply(quaternion, i.Quaternion); } i.Position = Vector3.TransformCoordinate(i.Position, offsetWithInitialPosition); } } } } break; } }
void Apply(EditMode mode, ApplyRotationForm f, bool previewOnly, ref Action reset) { var rotate = !f.IsMoveOnly; var quaternion = Quaternion.RotationYawPitchRoll(MathHelper.ToRadians(f.Rotation.Y), MathHelper.ToRadians(f.Rotation.X), MathHelper.ToRadians(f.Rotation.Z)); var offset = Matrix.Translation(-f.Position) * Matrix.RotationQuaternion(quaternion) * Matrix.Translation(f.Position); if (reset != null) { reset(); reset = null; } switch (mode) { case EditMode.AccessoryMode: var acc = this.Scene.ActiveAccessory; if (acc != null) { foreach (var i in acc.SelectedLayers) { var local = i.CurrentLocalMotion; var newLocal = new MotionData ( Vector3.TransformCoordinate(local.Move, offset), rotate ? Quaternion.Multiply(quaternion, local.Rotation) : local.Rotation ); reset += () => i.CurrentLocalMotion = local; i.CurrentLocalMotion = newLocal; } if (!previewOnly) foreach (var i in acc.Layers.SelectMany(_ => _.SelectedFrames)) { var resetPosition = i.Position; var resetQuaternion = i.Quaternion; reset += () => { i.Position = resetPosition; i.Quaternion = resetQuaternion; }; if (rotate) i.Quaternion = Quaternion.Multiply(quaternion, i.Quaternion); i.Position = Vector3.TransformCoordinate(i.Position, offset); } } break; case EditMode.EffectMode: var eff = this.Scene.ActiveEffect; if (eff != null) { var local = eff.CurrentMotion; var newLocal = new MotionData ( Vector3.TransformCoordinate(local.Move, offset), rotate ? Quaternion.Multiply(quaternion, local.Rotation) : local.Rotation ); reset += () => eff.CurrentMotion = local; eff.CurrentMotion = newLocal; if (!previewOnly) foreach (var i in eff.SelectedFrames) { var resetPosition = i.Position; var resetQuaternion = i.Quaternion; reset += () => { i.Position = resetPosition; i.Quaternion = resetQuaternion; }; if (rotate) i.Quaternion = Quaternion.Multiply(quaternion, i.Quaternion); i.Position = Vector3.TransformCoordinate(i.Position, offset); } } break; case EditMode.ModelMode: var model = this.Scene.ActiveModel; if (model != null) foreach (var bone in model.Bones) { var initialPosition = Matrix.Translation(bone.InitialPosition); if (bone.ParentBoneID != -1) initialPosition *= GetMotion(model.Bones, bone); var offsetWithInitialPosition = initialPosition * offset * Matrix.Invert(initialPosition); Vector3 scale; Quaternion rotation; Vector3 translation; offsetWithInitialPosition.Decompose(out scale, out rotation, out translation); foreach (var i in bone.SelectedLayers) { var local = i.CurrentLocalMotion; var newLocal = new MotionData ( (bone.BoneFlags & BoneType.XYZ) != 0 ? Vector3.TransformCoordinate(local.Move, offsetWithInitialPosition) : local.Move, (bone.BoneFlags & BoneType.Rotate) != 0 && rotate ? Quaternion.Multiply(rotation, local.Rotation) : local.Rotation ); reset += () => i.CurrentLocalMotion = local; i.CurrentLocalMotion = newLocal; } if (!previewOnly) foreach (var i in bone.Layers.SelectMany(_ => _.SelectedFrames)) { var resetPosition = i.Position; var resetQuaternion = i.Quaternion; reset += () => { i.Position = resetPosition; i.Quaternion = resetQuaternion; }; if (rotate) i.Quaternion = Quaternion.Multiply(quaternion, i.Quaternion); i.Position = Vector3.TransformCoordinate(i.Position, offsetWithInitialPosition); } } break; } }