private void parseIKList(BinaryReader br) { // the number of Vertexes short num = br.ReadInt16(); Log.Debug("PMD", "IK: " + num.ToString()); if (num > 0) { IK = new IK[num]; for (int i = 0; i < num; i++) { IK ik = new IK(); ik.ik_bone_index = br.ReadInt16(); ik.ik_target_bone_index = br.ReadInt16(); ik.ik_chain_length = br.ReadByte(); ik.iterations = br.ReadInt16(); ik.control_weight = br.ReadSingle(); ik.ik_child_bone_index = new short[ik.ik_chain_length]; for (int j = 0; j < ik.ik_chain_length; j++) { ik.ik_child_bone_index[j] = br.ReadInt16(); } IK[i] = ik; } } else { IK = null; } }
public void Load(string filename) { using (var fs = File.OpenRead(filename)) using (var bs = new BinaryReader(fs)) { // header string s = bs.ReadString(); Log.Debug("RMC", "MAGIC: " + s); // VertNormUv Log.Debug("RMC", "VertNormUv"); VertNormUv = ReadFloats(bs); // Index Log.Debug("RMC", "Index"); Index = ReadShorts(bs); // Bone Log.Debug("RMC", "Bone"); Bones = new Bone[bs.ReadUInt32()]; Log.Debug("RMC", "count : " + Bones.Length.ToString()); for (int i = 0; i < Bones.Length; i++) { Bones[i] = new Bone(); Bones[i].name = bs.ReadString(); Bones[i].parent = bs.ReadInt16(); Bones[i].tail = bs.ReadInt16(); Bones[i].type = bs.ReadByte(); Bones[i].ik = bs.ReadInt16(); Bones[i].head_pos = ReadFloats(bs, 3); Bones[i].is_leg = bs.ReadBoolean(); } // IKs Log.Debug("RMC", "IK"); IKs = new IK[bs.ReadUInt32()]; Log.Debug("RMC", "count : " + IKs.Length.ToString()); for (int i = 0; i < IKs.Length; i++) { IKs[i] = new IK(); IKs[i].ik_bone_index = bs.ReadInt32(); IKs[i].ik_target_bone_index = bs.ReadInt32(); IKs[i].ik_chain_length = bs.ReadByte(); IKs[i].iterations = bs.ReadInt32(); IKs[i].control_weight = bs.ReadSingle(); IKs[i].ik_child_bone_index = new short[bs.ReadUInt32()]; for (int j = 0; j < IKs[i].ik_child_bone_index.Length; j++) { IKs[i].ik_child_bone_index[j] = bs.ReadInt16(); } } // Materials Log.Debug("RMC", "Material"); Materials = new FMaterial[bs.ReadUInt32()]; Log.Debug("RMC", "count : " + Materials.Length.ToString()); for (int i = 0; i < Materials.Length; i++) { Materials[i] = new FMaterial(); Materials[i].diffuse_color = ReadFloats(bs, 4); Materials[i].power = bs.ReadSingle(); Materials[i].specular_color = ReadFloats(bs, 3); Materials[i].emmisive_color = ReadFloats(bs, 3); Materials[i].toon_index = bs.ReadByte(); Materials[i].edge_flag = bs.ReadByte(); Materials[i].face_vert_count = bs.ReadInt32(); if (bs.ReadBoolean()) { Materials[i].texture = bs.ReadString(); Log.Debug("RMC", "load texture in material ... " + Materials[i].texture); var sf = bs.ReadByte(); if (sf == 1) { Materials[i].sph = bs.ReadString(); Materials[i].spa = null; Log.Debug("RMC", "load sphere(sph) in material ... " + Materials[i].sph); } else if (sf == 2) { Materials[i].sph = null; Materials[i].spa = bs.ReadString(); Log.Debug("RMC", "load sphere(spa) in material ... " + Materials[i].spa); } } Materials[i].face_vert_offset = bs.ReadInt32(); Materials[i].bone_num = bs.ReadInt32(); Log.Debug("RMC", "Bone num: " + Materials[i].bone_num.ToString()); Materials[i].weight = bs.ReadBytes(VertNormUv.Length / 8 * 3); Materials[i].bone_inv_map = new int[48]; // ad-hock for (int j = 0; j < Materials[i].bone_inv_map.Length; j++) { Materials[i].bone_inv_map[j] = bs.ReadInt32(); } } // ToonNames Log.Debug("RMC", "ToonNames"); ToonNames = new string[11]; for (int i = 0; i < 11; i++) { ToonNames[i] = bs.ReadString(); Log.Debug("RMC", ToonNames[i]); } } }
public void Load(string filename) { using(var fs = File.OpenRead(filename)) using(var bs = new BinaryReader(fs)) { // header string s = bs.ReadString(); Log.Debug("RMC", "MAGIC: " + s); // VertNormUv Log.Debug("RMC", "VertNormUv"); VertNormUv = ReadFloats(bs); // Index Log.Debug("RMC", "Index"); Index = ReadShorts(bs); // Bone Log.Debug("RMC", "Bone"); Bones = new Bone[bs.ReadUInt32()]; Log.Debug("RMC", "count : " + Bones.Length.ToString()); for (int i = 0; i < Bones.Length; i++) { Bones[i] = new Bone(); Bones[i].name = bs.ReadString(); Bones[i].parent = bs.ReadInt16(); Bones[i].tail = bs.ReadInt16(); Bones[i].type = bs.ReadByte(); Bones[i].ik = bs.ReadInt16(); Bones[i].head_pos = ReadFloats(bs, 3); Bones[i].is_leg = bs.ReadBoolean(); } // IKs Log.Debug("RMC", "IK"); IKs = new IK[bs.ReadUInt32()]; Log.Debug("RMC", "count : " + IKs.Length.ToString()); for (int i = 0; i < IKs.Length; i++) { IKs[i] = new IK(); IKs[i].ik_bone_index = bs.ReadInt32(); IKs[i].ik_target_bone_index = bs.ReadInt32(); IKs[i].ik_chain_length = bs.ReadByte(); IKs[i].iterations = bs.ReadInt32(); IKs[i].control_weight = bs.ReadSingle(); IKs[i].ik_child_bone_index = new short[bs.ReadUInt32()]; for (int j = 0; j < IKs[i].ik_child_bone_index.Length; j++) { IKs[i].ik_child_bone_index[j] = bs.ReadInt16(); } } // Materials Log.Debug("RMC", "Material"); Materials = new FMaterial[bs.ReadUInt32()]; Log.Debug("RMC", "count : " + Materials.Length.ToString()); for (int i = 0; i < Materials.Length; i++) { Materials[i] = new FMaterial(); Materials[i].diffuse_color = ReadFloats(bs, 4); Materials[i].power = bs.ReadSingle(); Materials[i].specular_color = ReadFloats(bs, 3); Materials[i].emmisive_color = ReadFloats(bs, 3); Materials[i].toon_index = bs.ReadByte(); Materials[i].edge_flag = bs.ReadByte(); Materials[i].face_vert_count = bs.ReadInt32(); if (bs.ReadBoolean()) { Materials[i].texture = bs.ReadString(); Log.Debug("RMC", "load texture in material ... " + Materials[i].texture); var sf = bs.ReadByte(); if (sf == 1) { Materials[i].sph = bs.ReadString(); Materials[i].spa = null; Log.Debug("RMC", "load sphere(sph) in material ... " + Materials[i].sph); } else if (sf == 2) { Materials[i].sph = null; Materials[i].spa = bs.ReadString(); Log.Debug("RMC", "load sphere(spa) in material ... " + Materials[i].spa); } } Materials[i].face_vert_offset = bs.ReadInt32(); Materials[i].bone_num = bs.ReadInt32(); Log.Debug("RMC", "Bone num: " + Materials[i].bone_num.ToString()); Materials[i].weight = bs.ReadBytes(VertNormUv.Length / 8 * 3); Materials[i].bone_inv_map = new int[48]; // ad-hock for (int j = 0; j < Materials[i].bone_inv_map.Length; j++) { Materials[i].bone_inv_map[j] = bs.ReadInt32(); } } // ToonNames Log.Debug("RMC", "ToonNames"); ToonNames = new string[11]; for (int i = 0; i < 11; i++) { ToonNames[i] = bs.ReadString(); Log.Debug("RMC", ToonNames[i]); } } }
private void ccdIK1(IK ik) { var effecterVecs = new float[4]; var targetVecs = new float[4]; var targetInvs = new float[4]; var effecterInvs = new float[4]; var axis = new float[3]; var mQuatworks = new double[4]; var mMatworks = new float[16]; var effecter = Surface.RenderBones[ik.ik_bone_index]; var target = Surface.RenderBones[ik.ik_target_bone_index]; getCurrentPosition(effecterVecs, effecter); for (int i = 0; i < ik.iterations; i++) { for (int j = 0; j < ik.ik_chain_length; j++) { var b = Surface.RenderBones[ik.ik_child_bone_index[j]]; clearUpdateFlags(b, target); getCurrentPosition(targetVecs, target); if (b.bone.is_leg) { if (i == 0) { var ba = Surface.RenderBones[ik.ik_child_bone_index[ik.ik_chain_length - 1]]; getCurrentPosition(targetInvs, b); getCurrentPosition(effecterInvs, ba); double eff_len = Matrix.Length(effecterVecs[0] - effecterInvs[0], effecterVecs[1] - effecterInvs[1], effecterVecs[2] - effecterInvs[2]); double b_len = Matrix.Length(targetInvs[0] - effecterInvs[0], targetInvs[1] - effecterInvs[1], targetInvs[2] - effecterInvs[2]); double t_len = Matrix.Length(targetVecs[0] - targetInvs[0], targetVecs[1] - targetInvs[1], targetVecs[2] - targetInvs[2]); double angle1 = Math.Acos((eff_len * eff_len - b_len * b_len - t_len * t_len) / (2 * b_len * t_len)); if (!double.IsNaN(angle1)) { axis[0] = -1; axis[1] = axis[2] = 0; Quaternion.createFromAngleAxis(mQuatworks, angle1, axis); Quaternion.mul(b.quaternion, b.quaternion, mQuatworks); Quaternion.toMatrixPreserveTranslate(b.matrix_current, b.quaternion); } } continue; } if (Matrix.Length(targetVecs[0] - effecterVecs[0], targetVecs[1] - effecterVecs[1], targetVecs[2] - effecterVecs[2]) < 0.001f) { // clear all foreach (var c in Surface.RenderBones) { c.updated = false; } return; } float[] current = getCurrentMatrix(b); Vector.invertM(mMatworks, 0, current, 0); Matrix.MultiplyMV(effecterInvs, 0, mMatworks, 0, effecterVecs, 0); Matrix.MultiplyMV(targetInvs, 0, mMatworks, 0, targetVecs, 0); // calculate rotation angle/axis Vector.normalize(effecterInvs); Vector.normalize(targetInvs); double angle2 = Math.Acos(Vector.dot(effecterInvs, targetInvs)); angle2 *= ik.control_weight; if (!double.IsNaN(angle2)) { Vector.cross(axis, targetInvs, effecterInvs); Vector.normalize(axis); if (!double.IsNaN(axis[0]) && !double.IsNaN(axis[1]) && !double.IsNaN(axis[2])) { Quaternion.createFromAngleAxis(mQuatworks, angle2, axis); Quaternion.mul(b.quaternion, b.quaternion, mQuatworks); Quaternion.toMatrixPreserveTranslate(b.matrix_current, b.quaternion); } } } } // clear all foreach (var b in Surface.RenderBones) { b.updated = false; } }