Skip to content

Instantly share code, notes, and snippets.

@mfakane
Created May 20, 2012 17:21
Show Gist options
  • Save mfakane/2758817 to your computer and use it in GitHub Desktop.
Save mfakane/2758817 to your computer and use it in GitHub Desktop.
MMMCameraModify.exe のソース
// Mono.Cecil required
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Mono.Cecil;
using Mono.Cecil.Cil;
namespace MMMCameraModify
{
class Program
{
static void Main(string[] args)
{
if (!args.Any())
{
Console.Error.WriteLine("MMMCameraModify: MikuMikuMoving.exe not provided");
return;
}
var path = args.First();
var sysdir = Path.Combine(Path.GetDirectoryName(path), "System");
var dar = new DefaultAssemblyResolver();
dar.AddSearchDirectory(sysdir);
var asm = AssemblyDefinition.ReadAssembly(path, new ReaderParameters
{
AssemblyResolver = dar,
});
var refs = Directory.EnumerateFiles(sysdir, "*.dll").Where(_ => !_.EndsWith("DxOpenNI.dll") && !_.EndsWith("MsKinect.dll")).Select(_ => AssemblyDefinition.ReadAssembly(_)).ToArray();
var slimDX = refs.Single(_ => _.Name.Name == "SlimDX");
var mm = asm.MainModule;
var camera = mm.Types.Single(_ => _.FullName == "MikuMikuMoving.Camera");
var updateViewMatrixWithoutEvent = camera.Methods.Single(_ => _.Name == "UpdateViewMatrixWithoutEvent");
var types = new Dictionary<string, TypeDefinition>
{
{ "Vector3", slimDX.MainModule.GetType("SlimDX.Vector3") },
{ "Quaternion", slimDX.MainModule.GetType("SlimDX.Quaternion") },
{ "Matrix", slimDX.MainModule.GetType("SlimDX.Matrix") },
};
// phi: -X
// theta: -Y
// zangle: Z
var body = updateViewMatrixWithoutEvent.Body;
body.Variables.Clear();
body.Variables.Add(new VariableDefinition("q", mm.Import(types["Quaternion"])));
body.Variables.Add(new VariableDefinition("mq", mm.Import(types["Matrix"])));
body.Variables.Add(new VariableDefinition("position", mm.Import(types["Vector3"])));
body.Variables.Add(new VariableDefinition("up", mm.Import(types["Vector3"])));
var il = body.GetILProcessor();
body.Instructions.Clear();
// var q = Quaternion.RotationYawPitchRoll(-this.theta, -this.phi, this.zangle);
body.Instructions.Add(il.Create(OpCodes.Ldarg_0));
body.Instructions.Add(il.Create(OpCodes.Ldfld, mm.Import(camera.Fields.Single(_ => _.Name == "theta"))));
body.Instructions.Add(il.Create(OpCodes.Neg));
body.Instructions.Add(il.Create(OpCodes.Ldarg_0));
body.Instructions.Add(il.Create(OpCodes.Ldfld, mm.Import(camera.Fields.Single(_ => _.Name == "phi"))));
body.Instructions.Add(il.Create(OpCodes.Neg));
body.Instructions.Add(il.Create(OpCodes.Ldarg_0));
body.Instructions.Add(il.Create(OpCodes.Ldfld, mm.Import(camera.Fields.Single(_ => _.Name == "zangle"))));
body.Instructions.Add(il.Create(OpCodes.Call, mm.Import(types["Quaternion"].Methods.Single(_ => _.Name == "RotationYawPitchRoll" && _.Parameters.Count == 3))));
body.Instructions.Add(il.Create(OpCodes.Stloc_0));
// var mq = Matrix.RotationQuaternion(q);
body.Instructions.Add(il.Create(OpCodes.Ldloc_0));
body.Instructions.Add(il.Create(OpCodes.Call, mm.Import(types["Matrix"].Methods.Single(_ => _.Name == "RotationQuaternion" && _.Parameters.Count == 1))));
body.Instructions.Add(il.Create(OpCodes.Stloc_1));
// var position = Vector3.TransformCoordinate(new Vector3(0, 0, this.radius), mq);
body.Instructions.Add(il.Create(OpCodes.Ldc_R4, 0f));
body.Instructions.Add(il.Create(OpCodes.Ldc_R4, 0f));
body.Instructions.Add(il.Create(OpCodes.Ldarg_0));
body.Instructions.Add(il.Create(OpCodes.Ldfld, mm.Import(camera.Fields.Single(_ => _.Name == "radius"))));
body.Instructions.Add(il.Create(OpCodes.Newobj, mm.Import(types["Vector3"].Methods.Single(_ => _.Name == ".ctor" && _.Parameters.Count == 3))));
body.Instructions.Add(il.Create(OpCodes.Ldloc_1));
body.Instructions.Add(il.Create(OpCodes.Call, mm.Import(types["Vector3"].Methods.Single(_ => _.Name == "TransformCoordinate" && _.Parameters.Count == 2 && _.ReturnType.Name == "Vector3"))));
body.Instructions.Add(il.Create(OpCodes.Stloc_2));
// var up = Vector3.TransformCoordinate(Vector3.UnitY, mq);
body.Instructions.Add(il.Create(OpCodes.Call, mm.Import(types["Vector3"].Methods.Single(_ => _.Name == "get_UnitY"))));
body.Instructions.Add(il.Create(OpCodes.Ldloc_1));
body.Instructions.Add(il.Create(OpCodes.Call, mm.Import(types["Vector3"].Methods.Single(_ => _.Name == "TransformCoordinate" && _.Parameters.Count == 2 && _.ReturnType.Name == "Vector3"))));
body.Instructions.Add(il.Create(OpCodes.Stloc_3));
// this.position = position;
body.Instructions.Add(il.Create(OpCodes.Ldarg_0));
body.Instructions.Add(il.Create(OpCodes.Ldloc_2));
body.Instructions.Add(il.Create(OpCodes.Stfld, mm.Import(camera.Fields.Single(_ => _.Name == "position"))));
// this.nofovPosition = position;
body.Instructions.Add(il.Create(OpCodes.Ldarg_0));
body.Instructions.Add(il.Create(OpCodes.Ldloc_2));
body.Instructions.Add(il.Create(OpCodes.Stfld, mm.Import(camera.Fields.Single(_ => _.Name == "nofovPosition"))));
// this.Center = this.cameramove + this.targetRotate + this.FollowMove;
body.Instructions.Add(il.Create(OpCodes.Ldarg_0));
body.Instructions.Add(il.Create(OpCodes.Ldarg_0));
body.Instructions.Add(il.Create(OpCodes.Ldfld, mm.Import(camera.Fields.Single(_ => _.Name == "cameramove"))));
body.Instructions.Add(il.Create(OpCodes.Ldarg_0));
body.Instructions.Add(il.Create(OpCodes.Ldfld, mm.Import(camera.Fields.Single(_ => _.Name == "targetRotate"))));
body.Instructions.Add(il.Create(OpCodes.Call, mm.Import(types["Vector3"].Methods.Single(_ => _.Name == "op_Addition" && _.Parameters.Count == 2 && _.Parameters.All(p => p.ParameterType.Name == "Vector3")))));
body.Instructions.Add(il.Create(OpCodes.Ldarg_0));
body.Instructions.Add(il.Create(OpCodes.Ldfld, mm.Import(camera.Fields.Single(_ => _.Name == "FollowMove"))));
body.Instructions.Add(il.Create(OpCodes.Call, mm.Import(types["Vector3"].Methods.Single(_ => _.Name == "op_Addition" && _.Parameters.Count == 2 && _.Parameters.All(p => p.ParameterType.Name == "Vector3")))));
body.Instructions.Add(il.Create(OpCodes.Stfld, mm.Import(camera.Fields.Single(_ => _.Name == "Center"))));
// position = Vector3.TransformCoordinate(new Vector3(0, 0, Math.Abs(this.radius) * 2), mq);
body.Instructions.Add(il.Create(OpCodes.Ldc_R4, 0f));
body.Instructions.Add(il.Create(OpCodes.Ldc_R4, 0f));
body.Instructions.Add(il.Create(OpCodes.Ldarg_0));
body.Instructions.Add(il.Create(OpCodes.Ldfld, mm.Import(camera.Fields.Single(_ => _.Name == "radius"))));
body.Instructions.Add(il.Create(OpCodes.Call, mm.Import(typeof(Math).GetMethod("Abs", new[] { typeof(float) }))));
body.Instructions.Add(il.Create(OpCodes.Ldc_R4, 2f));
body.Instructions.Add(il.Create(OpCodes.Mul));
body.Instructions.Add(il.Create(OpCodes.Newobj, mm.Import(types["Vector3"].Methods.Single(_ => _.Name == ".ctor" && _.Parameters.Count == 3))));
body.Instructions.Add(il.Create(OpCodes.Ldloc_1));
body.Instructions.Add(il.Create(OpCodes.Call, mm.Import(types["Vector3"].Methods.Single(_ => _.Name == "TransformCoordinate" && _.Parameters.Count == 2 && _.ReturnType.Name == "Vector3"))));
body.Instructions.Add(il.Create(OpCodes.Stloc_2));
// this.View = Matrix.LookAtLH(this.Center + this.position, this.Center + this.position - position, up);
body.Instructions.Add(il.Create(OpCodes.Ldarg_0));
body.Instructions.Add(il.Create(OpCodes.Ldarg_0));
body.Instructions.Add(il.Create(OpCodes.Ldfld, mm.Import(camera.Fields.Single(_ => _.Name == "Center"))));
body.Instructions.Add(il.Create(OpCodes.Ldarg_0));
body.Instructions.Add(il.Create(OpCodes.Ldfld, mm.Import(camera.Fields.Single(_ => _.Name == "position"))));
body.Instructions.Add(il.Create(OpCodes.Call, mm.Import(types["Vector3"].Methods.Single(_ => _.Name == "op_Addition" && _.Parameters.Count == 2 && _.Parameters.All(p => p.ParameterType.Name == "Vector3")))));
body.Instructions.Add(il.Create(OpCodes.Ldarg_0));
body.Instructions.Add(il.Create(OpCodes.Ldfld, mm.Import(camera.Fields.Single(_ => _.Name == "Center"))));
body.Instructions.Add(il.Create(OpCodes.Ldarg_0));
body.Instructions.Add(il.Create(OpCodes.Ldfld, mm.Import(camera.Fields.Single(_ => _.Name == "position"))));
body.Instructions.Add(il.Create(OpCodes.Call, mm.Import(types["Vector3"].Methods.Single(_ => _.Name == "op_Addition" && _.Parameters.Count == 2 && _.Parameters.All(p => p.ParameterType.Name == "Vector3")))));
body.Instructions.Add(il.Create(OpCodes.Ldloc_2));
body.Instructions.Add(il.Create(OpCodes.Call, mm.Import(types["Vector3"].Methods.Single(_ => _.Name == "op_Subtraction" && _.Parameters.Count == 2 && _.Parameters.All(p => p.ParameterType.Name == "Vector3")))));
body.Instructions.Add(il.Create(OpCodes.Ldloc_3));
body.Instructions.Add(il.Create(OpCodes.Call, mm.Import(types["Matrix"].Methods.Single(_ => _.Name == "LookAtLH" && _.Parameters.Count == 3))));
body.Instructions.Add(il.Create(OpCodes.Call, mm.Import(camera.Methods.Single(_ => _.Name == "set_View"))));
body.Instructions.Add(il.Create(OpCodes.Ret));
mm.Import(camera);
asm.Write(path);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment