private static PMDFormat.FaceVertexList ConvertFaceVertexList(PMXFormat pmx) { PMDFormat.FaceVertexList result = new PMDFormat.FaceVertexList(); result.face_vert_count = (uint)pmx.face_vertex_list.face_vert_index.Length; result.face_vert_index = pmx.face_vertex_list.face_vert_index.Select(x => (ushort)x).ToArray(); return(result); }
/// <summary> /// GameObjectを作成する /// </summary> /// <param name='format'>内部形式データ</param> /// <param name='use_rigidbody'>剛体を使用するか</param> /// <param name='animation_type'>アニメーションタイプ</param> /// <param name='use_ik'>IKを使用するか</param> /// <param name='scale'>スケール</param> public static GameObject CreateGameObject(PMXFormat format, bool use_rigidbody, AnimationType animation_type, bool use_ik, float scale) { GameObject result; using (PMXConverter converter = new PMXConverter()) { result = converter.CreateGameObject_(format, use_rigidbody, animation_type, use_ik, scale); } return result; }
private static PMDFormat.Vertex ConvertVertex(PMXFormat pmx, int vertex_index) { PMDFormat.Vertex result = new PMDFormat.Vertex(); PMXFormat.Vertex pmx_vertex = pmx.vertex_list.vertex[vertex_index]; result.pos = pmx_vertex.pos; result.normal_vec = pmx_vertex.normal_vec; result.uv = pmx_vertex.uv; switch (pmx_vertex.bone_weight.method) { case PMXFormat.Vertex.WeightMethod.BDEF1: goto case PMXFormat.Vertex.WeightMethod.BDEF2; case PMXFormat.Vertex.WeightMethod.BDEF2: //BDEF1,BDEF2なら //完全互換 result.bone_num = new ushort[]{(ushort)pmx_vertex.bone_weight.bone1_ref, (ushort)pmx_vertex.bone_weight.bone2_ref}; result.bone_weight = (byte)(pmx_vertex.bone_weight.bone1_weight * 100.0f + 0.5f); break; case PMXFormat.Vertex.WeightMethod.BDEF4: //BDEF4なら //ボーン3,4の情報を捨てる result.bone_num = new ushort[]{(ushort)pmx_vertex.bone_weight.bone1_ref, (ushort)pmx_vertex.bone_weight.bone2_ref}; float bone1_weight = pmx_vertex.bone_weight.bone1_weight / (pmx_vertex.bone_weight.bone1_weight + pmx_vertex.bone_weight.bone2_weight); result.bone_weight = (byte)(bone1_weight * 100.0f + 0.5f); break; case PMXFormat.Vertex.WeightMethod.SDEF: //SDEFなら //SDEFの情報を捨ててBDEF2扱い goto case PMXFormat.Vertex.WeightMethod.BDEF2; case PMXFormat.Vertex.WeightMethod.QDEF: //QDEFなら //BDEF4と同じ対応 goto case PMXFormat.Vertex.WeightMethod.BDEF4; default: throw new System.ArgumentOutOfRangeException(); } result.edge_flag = (byte)((0.5f <= pmx_vertex.edge_magnification)? 1: 0); return result; }
public static PMXFormat Load(BinaryReader reader) { PMXFormat pmxFormat = new PMXFormat(); pmxFormat.Reload(reader); return(pmxFormat); }
private static PMDFormat.Header ConvertHeader(PMXFormat.Header pmx_header) { PMDFormat.Header result = new PMDFormat.Header(); result.magic = pmx_header.magic; result.version = pmx_header.version; result.model_name = pmx_header.model_name; result.comment = pmx_header.comment; return result; }
private static PMDFormat.VertexList ConvertVertexList(PMXFormat pmx) { PMDFormat.VertexList result = new PMDFormat.VertexList(); result.vert_count = (uint)pmx.vertex_list.vertex.Length; result.vertex = new PMDFormat.Vertex[result.vert_count]; for (int i = 0; i < result.vert_count; i++) { result.vertex[i] = ConvertVertex(pmx, i); } return result; }
private static PMDFormat.Bone ConvertBone(PMXFormat pmx, int bone_index) { PMDFormat.Bone result = new PMDFormat.Bone(); PMXFormat.Bone pmx_bone = pmx.bone_list.bone[bone_index]; result.bone_name = pmx_bone.bone_name; result.parent_bone_index = (ushort)((uint.MaxValue == pmx_bone.parent_bone_index)? ushort.MaxValue: pmx_bone.parent_bone_index); result.tail_pos_bone_index = ushort.MaxValue; #if false //PMD側 0:回転 1:回転と移動 2:IK 3:不明 4:IK影響下 5:回転影響下 6:IK接続先 7:非表示 8:捻り 9:回転運動 result.bone_type = pmx_bone.bone_flag;
public HelixViewerPanel(string path) { InitializeComponent(); var builder = new MeshBuilder(); format_ = LoadPmxMaterials(path); MeshCreationInfo creation_info = CreateMeshCreationInfoSingle(); var mats = format_.material_list.material.Length; var models = new Model3DGroup(); for (int i = 0, i_max = creation_info.value.Length; i < i_max; ++i) { //format_.face_vertex_list.face_vert_indexを[start](含む)から[start+count](含まず)迄取り出し int[] indices = creation_info.value[i].plane_indices.Select(x => (int)creation_info.reassign_dictionary[x]) //頂点リアサインインデックス変換 .ToArray(); MeshGeometry3D mesh = new MeshGeometry3D(); mesh.Positions = new Point3DCollection(format_.vertex_list.vertex.Select(x => x.pos)); mesh.TextureCoordinates = new PointCollection(format_.vertex_list.vertex.Select(x => x.uv)); indices.ToList() .ForEach(x => mesh.TriangleIndices.Add(x)); var textureIndex = format_.material_list.material[i].usually_texture_index; Material material; if (textureIndex == uint.MaxValue) { material = new DiffuseMaterial(new SolidColorBrush(Color.FromRgb(160, 160, 160))); } else { // Texture ImageBrush colors_brush = new ImageBrush { ImageSource = new BitmapImage( new Uri(Path.Combine(format_.meta_header.folder, format_.texture_list.texture_file[textureIndex]), UriKind.Relative)) }; material = new DiffuseMaterial(colors_brush); } var model = new GeometryModel3D(mesh, material); model.BackMaterial = material; models.Children.Add(model); } PreviewModel.Content = models; }
private static PMDFormat.BoneList ConvertBoneList(PMXFormat pmx) { PMDFormat.BoneList result = new PMDFormat.BoneList(); result.bone_count = (ushort)pmx.bone_list.bone.Length; result.bone = new PMDFormat.Bone[result.bone_count]; for (int i = 0; i < result.bone_count; i++) { result.bone[i] = ConvertBone(pmx, i); } return(result); }
private static PMDFormat.VertexList ConvertVertexList(PMXFormat pmx) { PMDFormat.VertexList result = new PMDFormat.VertexList(); result.vert_count = (uint)pmx.vertex_list.vertex.Length; result.vertex = new PMDFormat.Vertex[result.vert_count]; for (int i = 0; i < result.vert_count; i++) { result.vertex[i] = ConvertVertex(pmx, i); } return(result); }
private static PMDFormat.MaterialList ConvertMaterialList(PMXFormat pmx) { PMDFormat.MaterialList result = new PMDFormat.MaterialList(); result.material_count = (uint)pmx.material_list.material.Length; result.material = new PMDFormat.Material[result.material_count]; for (int i = 0; i < result.material_count; i++) { result.material[i] = ConvertMaterial(pmx, i); } return(result); }
/// <summary> /// GameObjectを作成する /// </summary> /// <param name='format'>内部形式データ</param> /// <param name='use_rigidbody'>剛体を使用するか</param> /// <param name='animation_type'>アニメーションタイプ</param> /// <param name='use_ik'>IKを使用するか</param> /// <param name='scale'>スケール</param> public static GameObject CreateGameObject(PMXFormat format, bool use_rigidbody, AnimationType animation_type, bool use_ik, float scale) { GameObject result; using (var converter = new PMXConverter()) { result = converter.CreateGameObject_(format, use_rigidbody, animation_type, use_ik, scale); } return(result); }
/// <summary> /// GameObjectを作成する /// </summary> /// <param name='format'>内部形式データ</param> /// <param name='use_rigidbody'>剛体を使用するか</param> /// <param name='use_mecanim'>Mecanimを使用するか</param> /// <param name='use_ik'>IKを使用するか</param> /// <param name='scale'>スケール</param> private GameObject CreateGameObject_(PMXFormat format, bool use_rigidbody, bool use_mecanim, bool use_ik, float scale) { format_ = format; use_rigidbody_ = use_rigidbody; use_mecanim_ = use_mecanim; use_ik_ = use_ik; scale_ = scale; root_game_object_ = new GameObject(format_.meta_header.name); MMDEngine engine = root_game_object_.AddComponent<MMDEngine>(); //MMDEngine追加 root_game_object_.AddComponent<Animation>(); // アニメーションを追加 MeshCreationInfo[] creation_info = CreateMeshCreationInfo(); // メッシュを作成する為の情報を作成 Mesh[] mesh = CreateMesh(creation_info); // メッシュの生成・設定 Material[][] materials = CreateMaterials(creation_info); // マテリアルの生成・設定 GameObject[] bones = CreateBones(); // ボーンの生成・設定 SkinnedMeshRenderer[] renderers = BuildingBindpose(mesh, materials, bones); // バインドポーズの作成 CreateMorph(mesh, materials, bones, renderers, creation_info); // モーフの生成・設定 // IKの登録 if (use_ik_) { engine.bone_controllers = EntryBoneController(bones); engine.ik_list = engine.bone_controllers.Where(x=>null != x.ik_solver) .Select(x=>x.ik_solver) .ToArray(); } // 剛体関連 if (use_rigidbody_) { GameObject[] rigids = CreateRigids(); AssignRigidbodyToBone(bones, rigids); SetRigidsSettings(bones, rigids); GameObject[] joints = CreateJoints(rigids); GlobalizeRigidbody(joints); // 非衝突グループ List<int>[] ignoreGroups = SettingIgnoreRigidGroups(rigids); int[] groupTarget = GetRigidbodyGroupTargets(rigids); MMDEngine.Initialize(engine, scale_, groupTarget, ignoreGroups, rigids); } // Mecanim設定 (not work yet..) #if UNITY_4_0 || UNITY_4_1 if (use_mecanim_) { AvatarSettingScript avt_setting = new AvatarSettingScript(root_game_object_); avt_setting.SettingAvatar(); } #endif return root_game_object_; }
private PMXFormat Read() { format_ = new PMXFormat(); format_.header = ReadHeader(); format_.vertex_list = ReadVertexList(); format_.face_vertex_list = ReadFaceVertexList(); format_.texture_list = ReadTextureList(); format_.material_list = ReadMaterialList(); format_.bone_list = ReadBoneList(); format_.morph_list = ReadMorphList(); format_.display_frame_list = ReadDisplayFrameList(); format_.rigidbody_list = ReadRigidbodyList(); format_.rigidbody_joint_list = ReadRigidbodyJointList(); return(format_); }
/// <summary> /// PMXファイルの取得 /// </summary> /// <param name='pmd'>PMDファイル</param> /// <returns>内部形式データ</returns> public static PMXFormat PMD2PMX(PMDFormat pmd) { PMXFormat result = new PMXFormat(); result.meta_header = CreateMetaHeader(pmd); result.header = ConvertHeader(pmd.head, pmd.eg_head, pmd); result.vertex_list = ConvertVertexList(pmd); result.face_vertex_list = ConvertFaceVertexList(pmd); result.texture_list = ConvertTextureList(pmd); result.material_list = ConvertMaterialList(pmd, x=>CreateTextureIndex(ref result.texture_list.texture_file, x)); result.bone_list = ConvertBoneList(pmd); result.morph_list = ConvertMorphList(pmd); result.display_frame_list = ConvertDisplayFrameList(pmd); result.rigidbody_list = ConvertRigidbodyList(pmd); result.rigidbody_joint_list = ConvertRigidbodyJointList(pmd); return result; }
private PMXFormat Read() { format_ = new PMXFormat(); format_.meta_header = CreateMetaHeader(); format_.header = ReadHeader(); format_.vertex_list = ReadVertexList(); format_.face_vertex_list = ReadFaceVertexList(); format_.texture_list = ReadTextureList(); format_.material_list = ReadMaterialList(); format_.bone_list = ReadBoneList(); format_.morph_list = ReadMorphList(); format_.display_frame_list = ReadDisplayFrameList(); format_.rigidbody_list = ReadRigidbodyList(); format_.rigidbody_joint_list = ReadRigidbodyJointList(); return format_; }
MeshCreationInfo CreateMeshCreationInfoSingle(PMXFormat format) { MeshCreationInfo result = new MeshCreationInfo(); //全マテリアルを設定 result.value = CreateMeshCreationInfoPacks(format); //全頂点を設定 result.all_vertices = Enumerable.Range(0, format.vertex_list.vertex.Length).Select(x => (uint)x).ToArray(); //頂点リアサインインデックス用辞書作成 result.reassign_dictionary = new Dictionary <uint, uint>(result.all_vertices.Length); for (uint i = 0, i_max = (uint)result.all_vertices.Length; i < i_max; ++i) { result.reassign_dictionary[i] = i; } return(result); }
/// <summary> /// ボーンモーフ設定 /// </summary> /// <returns>ボーンモーフスクリプト</returns> /// <param name='morph'>モーフのゲームオブジェクト</param> /// <param name='data'>PMX用モーフデータ</param> /// <param name='index_reverse_dictionary'>インデックス逆引き用辞書</param> BoneMorph AssignBoneMorph(GameObject morph, PMXFormat.MorphData data, Dictionary<uint, uint> index_reverse_dictionary) { BoneMorph result = morph.AddComponent<BoneMorph>(); result.panel = (MorphManager.PanelType)data.handle_panel; result.indices = data.morph_offset.Select(x=>((PMXFormat.BoneMorphOffset)x).bone_index) //インデックスを取り出し .Select(x=>(int)index_reverse_dictionary[x]) //逆変換を掛ける .ToArray(); result.values = data.morph_offset.Select(x=>{ PMXFormat.BoneMorphOffset y = (PMXFormat.BoneMorphOffset)x; BoneMorph.BoneMorphParameter param = new BoneMorph.BoneMorphParameter(); param.position = y.move_value * scale_; param.rotation = y.rotate_value; return param; }) .ToArray(); return result; }
/// <summary> /// PMXファイルの取得 /// </summary> /// <param name='pmd'>PMDファイル</param> /// <returns>内部形式データ</returns> public static PMXFormat PMD2PMX(PMDFormat pmd) { PMXFormat result = new PMXFormat(); result.meta_header = CreateMetaHeader(pmd); result.header = ConvertHeader(pmd.head, pmd.eg_head, pmd); result.vertex_list = ConvertVertexList(pmd); result.face_vertex_list = ConvertFaceVertexList(pmd); result.texture_list = ConvertTextureList(pmd); result.material_list = ConvertMaterialList(pmd, x => CreateTextureIndex(ref result.texture_list.texture_file, x)); result.bone_list = ConvertBoneList(pmd); result.morph_list = ConvertMorphList(pmd); result.display_frame_list = ConvertDisplayFrameList(pmd); result.rigidbody_list = ConvertRigidbodyList(pmd); result.rigidbody_joint_list = ConvertRigidbodyJointList(pmd); return(result); }
private static PMDFormat.Vertex ConvertVertex(PMXFormat pmx, int vertex_index) { PMDFormat.Vertex result = new PMDFormat.Vertex(); PMXFormat.Vertex pmx_vertex = pmx.vertex_list.vertex[vertex_index]; result.pos = pmx_vertex.pos; result.normal_vec = pmx_vertex.normal_vec; result.uv = pmx_vertex.uv; switch (pmx_vertex.bone_weight.method) { case PMXFormat.Vertex.WeightMethod.BDEF1: goto case PMXFormat.Vertex.WeightMethod.BDEF2; case PMXFormat.Vertex.WeightMethod.BDEF2: //BDEF1,BDEF2なら //完全互換 result.bone_num = new ushort[] { (ushort)pmx_vertex.bone_weight.bone1_ref, (ushort)pmx_vertex.bone_weight.bone2_ref }; result.bone_weight = (byte)(pmx_vertex.bone_weight.bone1_weight * 100.0f + 0.5f); break; case PMXFormat.Vertex.WeightMethod.BDEF4: //BDEF4なら //ボーン3,4の情報を捨てる result.bone_num = new ushort[] { (ushort)pmx_vertex.bone_weight.bone1_ref, (ushort)pmx_vertex.bone_weight.bone2_ref }; float bone1_weight = pmx_vertex.bone_weight.bone1_weight / (pmx_vertex.bone_weight.bone1_weight + pmx_vertex.bone_weight.bone2_weight); result.bone_weight = (byte)(bone1_weight * 100.0f + 0.5f); break; case PMXFormat.Vertex.WeightMethod.SDEF: //SDEFなら //SDEFの情報を捨ててBDEF2扱い goto case PMXFormat.Vertex.WeightMethod.BDEF2; case PMXFormat.Vertex.WeightMethod.QDEF: //QDEFなら //BDEF4と同じ対応 goto case PMXFormat.Vertex.WeightMethod.BDEF4; default: throw new System.ArgumentOutOfRangeException(); } result.edge_flag = (byte)((0.5f <= pmx_vertex.edge_magnification)? 1: 0); return(result); }
MeshCreationInfo.Pack[] CreateMeshCreationInfoPacks(PMXFormat format) { uint plane_start = 0; //マテリアル単位のMeshCreationInfo.Packを作成する return(Enumerable.Range(0, format.material_list.material.Length) .Select(x => { MeshCreationInfo.Pack pack = new MeshCreationInfo.Pack(); pack.material_index = (uint)x; uint plane_count = format.material_list.material[x].face_vert_count; pack.plane_indices = format.face_vertex_list.face_vert_index.Skip((int)plane_start) .Take((int)plane_count) .ToArray(); pack.vertices = pack.plane_indices.Distinct() //重複削除 .ToArray(); plane_start += plane_count; return pack; }) .ToArray()); }
/// <summary> /// PMDファイルの取得 /// </summary> /// <param name='pmx'>PMXファイル</param> /// <returns>内部形式データ</returns> public static PMDFormat PMX2PMD(PMXFormat pmx) { PMDFormat result = new PMDFormat(); ConvertPathes(result, pmx); result.head = ConvertHeader(pmx.header); result.vertex_list = ConvertVertexList(pmx); result.face_vertex_list = ConvertFaceVertexList(pmx); result.material_list = ConvertMaterialList(pmx); result.bone_list = ConvertBoneList(pmx); result.ik_list = ConvertIKList(pmx); result.skin_list = ConvertSkinList(pmx); result.skin_name_list = ConvertSkinNameList(pmx); result.bone_name_list = ConvertBoneNameList(pmx); result.bone_display_list = ConvertBoneDisplayList(pmx); result.eg_head = ConvertEnglishHeader(pmx); result.eg_bone_name_list = ConvertEnglishBoneNameList(pmx); result.eg_skin_name_list = ConvertEnglishSkinNameList(pmx); result.eg_bone_display_list = ConvertEnglishBoneDisplayList(pmx); result.toon_texture_list = ConvertToonTextureList(pmx); result.rigidbody_list = ConvertRigidbodyList(pmx); result.rigidbody_joint_list = ConvertRigidbodyJointList(pmx); return result; }
private PMXFormat Read() { try { format_ = new PMXFormat(); format_.meta_header = CreateMetaHeader(); format_.header = ReadHeader(); format_.vertex_list = ReadVertexList(); format_.face_vertex_list = ReadFaceVertexList(); format_.texture_list = ReadTextureList(); format_.material_list = ReadMaterialList(); format_.bone_list = ReadBoneList(); format_.morph_list = ReadMorphList(); format_.display_frame_list = ReadDisplayFrameList(); format_.rigidbody_list = ReadRigidbodyList(); format_.rigidbody_joint_list = ReadRigidbodyJointList(); } catch (System.Exception e) { Debug.Log(e.Message); } return(format_); }
/// <summary> /// PMDファイルの取得 /// </summary> /// <param name='pmx'>PMXファイル</param> /// <returns>内部形式データ</returns> public static PMDFormat PMX2PMD(PMXFormat pmx) { PMDFormat result = new PMDFormat(); ConvertPathes(result, pmx); result.head = ConvertHeader(pmx.header); result.vertex_list = ConvertVertexList(pmx); result.face_vertex_list = ConvertFaceVertexList(pmx); result.material_list = ConvertMaterialList(pmx); result.bone_list = ConvertBoneList(pmx); result.ik_list = ConvertIKList(pmx); result.skin_list = ConvertSkinList(pmx); result.skin_name_list = ConvertSkinNameList(pmx); result.bone_name_list = ConvertBoneNameList(pmx); result.bone_display_list = ConvertBoneDisplayList(pmx); result.eg_head = ConvertEnglishHeader(pmx); result.eg_bone_name_list = ConvertEnglishBoneNameList(pmx); result.eg_skin_name_list = ConvertEnglishSkinNameList(pmx); result.eg_bone_display_list = ConvertEnglishBoneDisplayList(pmx); result.toon_texture_list = ConvertToonTextureList(pmx); result.rigidbody_list = ConvertRigidbodyList(pmx); result.rigidbody_joint_list = ConvertRigidbodyJointList(pmx); return(result); }
/// <summary> /// GameObjectを作成する /// </summary> /// <param name='format'>内部形式データ</param> /// <param name='use_rigidbody'>剛体を使用するか</param> /// <param name='animation_type'>アニメーションタイプ</param> /// <param name='use_ik'>IKを使用するか</param> /// <param name='scale'>スケール</param> private GameObject CreateGameObject_(PMXFormat format, bool use_rigidbody, AnimationType animation_type, bool use_ik, float scale) { format_ = format; use_ik_ = use_ik; scale_ = scale; root_game_object_ = new GameObject(format_.meta_header.name); try { var creationInfo = CreateMeshCreationInfo(); var mesh = CreateMesh(creationInfo); var materials = CreateMaterials(creationInfo); SetMeshRenderer(mesh, materials); return(root_game_object_); } catch (Exception e) { //UnityEngine.Object.DestroyImmediate(root_game_object_); Debug.LogError(e + " " + e.Message); return(root_game_object_); } }
public static List <Texture2D> GetTextureList(Coocoo3DMain appBody, StorageFolder storageFolder, PMXFormat pmx) { List <Texture2D> textures = new List <Texture2D>(); List <string> paths = new List <string>(); List <string> relativePaths = new List <string>(); foreach (var vTex in pmx.Textures) { string relativePath = vTex.TexturePath.Replace("//", "\\").Replace('/', '\\'); string texPath = Path.Combine(storageFolder.Path, relativePath); paths.Add(texPath); relativePaths.Add(relativePath); } lock (appBody.mainCaches.TextureCaches) { for (int i = 0; i < pmx.Textures.Count; i++) { Texture2DPack tex = appBody.mainCaches.TextureCaches.GetOrCreate(paths[i]); if (tex.Status != GraphicsObjectStatus.loaded) { tex.Mark(GraphicsObjectStatus.loading); } tex.relativePath = relativePaths[i]; tex.folder = storageFolder; textures.Add(tex.texture2D); } } return(textures); }
/// <summary> /// 物理素材の作成 /// </summary> /// <returns>物理素材</returns> /// <param name='rigidbody'>PMX用剛体データ</param> /// <param name='index'>剛体インデックス</param> PhysicMaterial CreatePhysicMaterial(PMXFormat.Rigidbody[] rigidbodys, uint index) { PMXFormat.Rigidbody rigidbody = rigidbodys[index]; PhysicMaterial material = new PhysicMaterial(format_.meta_header.name + "_r" + rigidbody.name); material.bounciness = rigidbody.recoil; material.staticFriction = rigidbody.friction; material.dynamicFriction = rigidbody.friction; string name = GetFilePathString(rigidbody.name); string file_name = format_.meta_header.folder + "/Physics/" + index.ToString() + "_" + name + ".asset"; AssetDatabase.CreateAsset(material, file_name); return material; }
/// <summary> /// 無影マテリアル確認 /// </summary> /// <returns>true:無影, false:影放ち</returns> /// <param name='material'>シェーダーを設定するマテリアル</param> bool IsNoCastShadowMaterial(PMXFormat.Material material) { bool result; if (0 != (PMXFormat.Material.Flag.CastShadow & material.flag)) { //影放ち result = false; } else { //無影 result = true; } return result; }
private static PMDFormat.Material ConvertMaterial(PMXFormat pmx, int material_index) { PMDFormat.Material result = new PMDFormat.Material(); PMXFormat.Material pmx_material = pmx.material_list.material[material_index]; result.diffuse_color = pmx_material.diffuse_color; result.alpha = result.diffuse_color.a; result.diffuse_color.a = 1.0f; result.specularity = pmx_material.specularity; result.specular_color = pmx_material.specular_color; result.mirror_color = pmx_material.ambient_color; if (0 < pmx_material.common_toon) { //共通トゥーン string toon_name = "toon" + pmx_material.common_toon.ToString("00") + ".bmp"; int toon_name_index = -1; for (int i = 0, i_max = pmx.texture_list.texture_file.Length; i < i_max; ++i) { if (toon_name == pmx.texture_list.texture_file[i]) { //既存の pmx.texture_list.texture_file に有れば //使う toon_name_index = i; break; } } if (toon_name_index < 0) { //既存の pmx.texture_list.texture_file になければ //後ろに追加する string[] texture_file = new string[pmx.texture_list.texture_file.Length + 1]; System.Array.Copy(pmx.texture_list.texture_file, texture_file, pmx.texture_list.texture_file.Length); texture_file[pmx.texture_list.texture_file.Length] = toon_name; //最後に追加 toon_name_index = pmx.texture_list.texture_file.Length; pmx.texture_list.texture_file = texture_file; } result.toon_index = (byte)toon_name_index; } else { //自前トゥーン result.toon_index = (byte)pmx_material.toon_texture_index; } result.edge_flag = (byte)((0 != ((int)pmx_material.flag & (int)PMXFormat.Material.Flag.Edge))? 1: 0); result.face_vert_count = pmx_material.face_vert_count; if (uint.MaxValue != pmx_material.sphere_texture_index) { string tex = pmx.texture_list.texture_file[pmx_material.sphere_texture_index]; result.sphere_map_name = ((0 == tex.IndexOf("./"))? tex.Substring(2): tex); //"./"開始なら除去 #if MFU_PMX2PMD_SPHERE_MAP_NAME_ADD_EXTENSION_FOR_SPHERE_MODE //スフィアモードの為に、拡張子を付加する(ファイルパスが変更されるのでMMDConverter側で2重拡張子に対応する迄無効化) switch (pmx_material.sphere_mode) { case PMXFormat.Material.SphereMode.AddSphere: result.sphere_map_name += ".spa"; break; case PMXFormat.Material.SphereMode.MulSphere: result.sphere_map_name += ".sph"; break; default: break; } #endif } if (uint.MaxValue != pmx_material.usually_texture_index) { string tex = pmx.texture_list.texture_file[pmx_material.usually_texture_index]; result.texture_file_name = ((0 == tex.IndexOf("./"))? tex.Substring(2): tex); //"./"開始なら除去 } return(result); }
/// <summary> /// ジョイントにばねなどのパラメータを設定する /// </summary> /// <param name='joint'>PMX用ジョイントデータ</param> /// <param name='conf'>Unity用ジョイント</param> void SetDrive(PMXFormat.Joint joint, ConfigurableJoint conf) { JointDrive drive; // Position if (joint.spring_position.x != 0.0f) { drive = new JointDrive(); drive.positionSpring = joint.spring_position.x * scale_; conf.xDrive = drive; } if (joint.spring_position.y != 0.0f) { drive = new JointDrive(); drive.positionSpring = joint.spring_position.y * scale_; conf.yDrive = drive; } if (joint.spring_position.z != 0.0f) { drive = new JointDrive(); drive.positionSpring = joint.spring_position.z * scale_; conf.zDrive = drive; } // Angular if (joint.spring_rotation.x != 0.0f) { drive = new JointDrive(); drive.mode = JointDriveMode.PositionAndVelocity; drive.positionSpring = joint.spring_rotation.x; conf.angularXDrive = drive; } if (joint.spring_rotation.y != 0.0f || joint.spring_rotation.z != 0.0f) { drive = new JointDrive(); drive.mode = JointDriveMode.PositionAndVelocity; drive.positionSpring = (joint.spring_rotation.y + joint.spring_rotation.z) * 0.5f; conf.angularYZDrive = drive; } }
/// <summary> /// 材質モーフ設定 /// </summary> /// <returns>材質モーフスクリプト</returns> /// <param name='morph'>モーフのゲームオブジェクト</param> /// <param name='data'>PMX用モーフデータ</param> /// <param name='index_reverse_dictionary'>インデックス逆引き用辞書</param> MaterialMorph AssignMaterialMorph(GameObject morph, PMXFormat.MorphData data, Dictionary<uint, uint> index_reverse_dictionary) { MaterialMorph result = morph.AddComponent<MaterialMorph>(); result.panel = (MorphManager.PanelType)data.handle_panel; result.indices = data.morph_offset.Select(x=>((PMXFormat.MaterialMorphOffset)x).material_index) //インデックスを取り出し .Select(x=>(int)index_reverse_dictionary[x]) //逆変換を掛ける .ToArray(); result.values = data.morph_offset.Select(x=>{ PMXFormat.MaterialMorphOffset y = (PMXFormat.MaterialMorphOffset)x; MaterialMorph.MaterialMorphParameter param = new MaterialMorph.MaterialMorphParameter(); param.color = y.diffuse; param.specular = new Color(y.specular.r, y.specular.g, y.specular.b, y.specularity); param.ambient = y.ambient; param.outline_color = y.edge_color; param.outline_width = y.edge_size; param.texture_color = y.texture_coefficient; param.sphere_color = y.sphere_texture_coefficient; param.toon_color = y.toon_texture_coefficient; return param; }) .ToArray(); result.operation = data.morph_offset.Select(x=>(MaterialMorph.OperationType)((PMXFormat.MaterialMorphOffset)x).offset_method) .ToArray(); return result; }
private uint CastIntRead(BinaryReader bin, PMXFormat.Header.IndexSize index_size) { uint result = 0; switch(index_size) { case PMXFormat.Header.IndexSize.Byte1: result = (uint)binary_reader_.ReadByte(); if (byte.MaxValue == result) { result = uint.MaxValue; } break; case PMXFormat.Header.IndexSize.Byte2: result = (uint)binary_reader_.ReadUInt16(); if (ushort.MaxValue == result) { result = uint.MaxValue; } break; case PMXFormat.Header.IndexSize.Byte4: result = binary_reader_.ReadUInt32(); break; default: throw new System.ArgumentOutOfRangeException(); } return result; }
/// <summary> /// ボーンウェイトをUnity用に変換する /// </summary> /// <returns>Unity用ボーンウェイト</returns> /// <param name='bone_weight'>PMX用ボーンウェイト</param> BoneWeight ConvertBoneWeight(PMXFormat.BoneWeight bone_weight) { //HACK: 取り敢えずボーンウェイトタイプを考えずにBDEFx系として登録する BoneWeight result = new BoneWeight(); switch (bone_weight.method) { case PMXFormat.Vertex.WeightMethod.BDEF1: goto case PMXFormat.Vertex.WeightMethod.BDEF4; case PMXFormat.Vertex.WeightMethod.BDEF2: goto case PMXFormat.Vertex.WeightMethod.BDEF4; case PMXFormat.Vertex.WeightMethod.BDEF4: //BDEF4なら result.boneIndex0 = (int)bone_weight.bone1_ref; result.weight0 = bone_weight.bone1_weight; result.boneIndex1 = (int)bone_weight.bone2_ref;; result.weight1 = bone_weight.bone2_weight; result.boneIndex2 = (int)bone_weight.bone3_ref; result.weight2 = bone_weight.bone3_weight; result.boneIndex3 = (int)bone_weight.bone4_ref; result.weight3 = bone_weight.bone4_weight; break; case PMXFormat.Vertex.WeightMethod.SDEF: //SDEFなら //HACK: BDEF4と同じ対応 goto case PMXFormat.Vertex.WeightMethod.BDEF4; case PMXFormat.Vertex.WeightMethod.QDEF: //QDEFなら //HACK: BDEF4と同じ対応 goto case PMXFormat.Vertex.WeightMethod.BDEF4; default: throw new System.ArgumentOutOfRangeException(); } return result; }
/// <summary> /// マテリアルをUnity用に変換する /// </summary> /// <returns>Unity用マテリアル</returns> /// <param name='material'>PMX用マテリアル</param> Material ConvertMaterial(PMXFormat.Material material) { //先にテクスチャ情報を検索 Texture2D main_texture = null; if (material.usually_texture_index < format_.texture_list.texture_file.Length) { string texture_file_name = format_.texture_list.texture_file[material.usually_texture_index]; string path = format_.meta_header.folder + "/" + texture_file_name; main_texture = (Texture2D)AssetDatabase.LoadAssetAtPath(path, typeof(Texture2D)); } //マテリアルに設定 Material result = new Material(Shader.Find(GetMmdShaderPath(material, main_texture))); // シェーダに依って値が有ったり無かったりするが、設定してもエラーに為らない様なので全部設定 result.SetColor("_Color", material.diffuse_color); result.SetColor("_AmbColor", material.ambient_color); result.SetFloat("_Opacity", material.diffuse_color.a); result.SetColor("_SpecularColor", material.specular_color); result.SetFloat("_Shininess", material.specularity); // エッジ result.SetFloat("_OutlineWidth", material.edge_size); result.SetColor("_OutlineColor", material.edge_color); // スフィアテクスチャ if (material.sphere_texture_index < format_.texture_list.texture_file.Length) { string sphere_texture_file_name = format_.texture_list.texture_file[material.sphere_texture_index]; string path = format_.meta_header.folder + "/" + sphere_texture_file_name; Texture2D sphere_texture = (Texture2D)UnityEditor.AssetDatabase.LoadAssetAtPath(path, typeof(Texture2D)); switch (material.sphere_mode) { case PMXFormat.Material.SphereMode.AddSphere: // 加算 result.SetTexture("_SphereAddTex", sphere_texture); result.SetTextureScale("_SphereAddTex", new Vector2(1, -1)); break; case PMXFormat.Material.SphereMode.MulSphere: // 乗算 result.SetTexture("_SphereMulTex", sphere_texture); result.SetTextureScale("_SphereMulTex", new Vector2(1, -1)); break; case PMXFormat.Material.SphereMode.SubTexture: // サブテクスチャ //サブテクスチャ用シェーダーが無いので設定しない break; default: //empty. break; } } // トゥーンテクスチャ { string toon_texture_name = null; if (0 < material.common_toon) { //共通トゥーン toon_texture_name = "toon" + material.common_toon.ToString("00") + ".bmp"; } else if (material.toon_texture_index < format_.texture_list.texture_file.Length) { //自前トゥーン toon_texture_name = format_.texture_list.texture_file[material.toon_texture_index]; } if (!string.IsNullOrEmpty(toon_texture_name)) { string resource_path = UnityEditor.AssetDatabase.GetAssetPath(Shader.Find("MMD/HalfLambertOutline")); Texture2D toon_texture = (Texture2D)UnityEditor.AssetDatabase.LoadAssetAtPath(resource_path, typeof(Texture2D)); result.SetTexture("_ToonTex", toon_texture); result.SetTextureScale("_ToonTex", new Vector2(1, -1)); } } // テクスチャが空でなければ登録 if (null != main_texture) { result.mainTexture = main_texture; result.mainTextureScale = new Vector2(1, -1); } return result; }
/// <summary> /// 頂点モーフ設定 /// </summary> /// <returns>頂点モーフスクリプト</returns> /// <param name='morph'>モーフのゲームオブジェクト</param> /// <param name='data'>PMX用モーフデータ</param> /// <param name='index_reverse_dictionary'>インデックス逆引き用辞書</param> VertexMorph AssignVertexMorph(GameObject morph, PMXFormat.MorphData data, Dictionary<uint, uint> index_reverse_dictionary) { VertexMorph result = morph.AddComponent<VertexMorph>(); result.panel = (MorphManager.PanelType)data.handle_panel; result.indices = data.morph_offset.Select(x=>((PMXFormat.VertexMorphOffset)x).vertex_index) //インデックスを取り出し .Select(x=>(int)index_reverse_dictionary[x]) //逆変換を掛ける .ToArray(); result.values = data.morph_offset.Select(x=>((PMXFormat.VertexMorphOffset)x).position_offset * scale_).ToArray(); return result; }
/// <summary> /// ボーンをボーンコントローラースクリプトに変換する /// </summary> /// <returns>ボーンコントローラースクリプト</returns> /// <param name='ik_data'>PMX用ボーンデータ</param> /// <param name='bone_index'>該当IKデータのボーン通しインデックス</param> /// <param name='bones'>ボーンのゲームオブジェクト</param> BoneController ConvertBoneController(PMXFormat.Bone bone, int bone_index, GameObject[] bones) { BoneController result = bones[bone_index].GetComponent<BoneController>(); if (0.0f != bone.additional_rate) { //付与親が有るなら result.additive_parent = bones[bone.additional_parent_index].GetComponent<BoneController>(); result.additive_rate = bone.additional_rate; result.add_local = (0 != (PMXFormat.Bone.Flag.AddLocal & bone.bone_flag)); result.add_move = (0 != (PMXFormat.Bone.Flag.AddMove & bone.bone_flag)); result.add_rotate = (0 != (PMXFormat.Bone.Flag.AddRotation & bone.bone_flag)); } if (use_ik_) { //IKを使用するなら if (0 != (PMXFormat.Bone.Flag.IkFlag & bone.bone_flag)) { //IKが有るなら result.ik_solver = bones[bone_index].AddComponent<CCDIKSolver>(); result.ik_solver.target = bones[bone.ik_data.ik_bone_index].transform; result.ik_solver.controll_weight = bone.ik_data.limit_angle / 4; //HACK: CCDIKSolver側で4倍している様なので此処で逆補正 result.ik_solver.iterations = (int)bone.ik_data.iterations; result.ik_solver.chains = bone.ik_data.ik_link.Select(x=>x.target_bone_index).Select(x=>bones[x].transform).ToArray(); //IK制御下のBoneController登録 result.ik_solver_targets = Enumerable.Repeat(result.ik_solver.target, 1) .Concat(result.ik_solver.chains) .Select(x=>x.GetComponent<BoneController>()) .ToArray(); //IK制御先のボーンについて、物理演算の挙動を調べる var operation_types = Enumerable.Repeat(bone.ik_data.ik_bone_index, 1) //IK対象先をEnumerable化 .Concat(bone.ik_data.ik_link.Select(x=>x.target_bone_index)) //IK制御下を追加 .Join(format_.rigidbody_list.rigidbody, x=>x, y=>y.rel_bone_index, (x,y)=>y.operation_type); //剛体リストから関連ボーンにIK対象先・IK制御下と同じボーンを持つ物を列挙し、剛体タイプを返す foreach (var operation_type in operation_types) { if (PMXFormat.Rigidbody.OperationType.Static != operation_type) { //ボーン追従で無い(≒物理演算)なら //IK制御の無効化 result.ik_solver.enabled = false; break; } } } } return result; }
/// <summary> /// UV・追加UVモーフ設定 /// </summary> /// <returns>UVモーフスクリプト</returns> /// <param name='morph'>モーフのゲームオブジェクト</param> /// <param name='data'>PMX用モーフデータ</param> /// <param name='index_reverse_dictionary'>インデックス逆引き用辞書</param> UvMorph AssignUvMorph(GameObject morph, PMXFormat.MorphData data, Dictionary<uint, uint> index_reverse_dictionary) { UvMorph result = morph.AddComponent<UvMorph>(); result.panel = (MorphManager.PanelType)data.handle_panel; result.indices = data.morph_offset.Select(x=>((PMXFormat.UVMorphOffset)x).vertex_index) //インデックスを取り出し .Select(x=>(int)index_reverse_dictionary[x]) //逆変換を掛ける .ToArray(); result.values = data.morph_offset.Select(x=>((PMXFormat.UVMorphOffset)x).uv_offset) .Select(x=>new Vector2(x.x, x.y)) .ToArray(); return result; }
/// <summary> /// Unity側のRigidbodyの設定を行う /// </summary> /// <param name='rigidbody'>PMX用剛体データ</param> /// <param name='targetBone'>設定対象のゲームオブジェクト</param> void UnityRigidbodySetting(PMXFormat.Rigidbody pmx_rigidbody, GameObject target) { Rigidbody rigidbody = target.GetComponent<Rigidbody>(); if (null != rigidbody) { //既にRigidbodyが付与されているなら //質量は合算する rigidbody.mass += pmx_rigidbody.weight; //減衰値は平均を取る rigidbody.drag = (rigidbody.drag + pmx_rigidbody.position_dim) * 0.5f; rigidbody.angularDrag = (rigidbody.angularDrag + pmx_rigidbody.rotation_dim) * 0.5f; } else { //まだRigidbodyが付与されていないなら rigidbody = target.AddComponent<Rigidbody>(); rigidbody.isKinematic = (PMXFormat.Rigidbody.OperationType.Static == pmx_rigidbody.operation_type); rigidbody.mass = Mathf.Max(float.Epsilon, pmx_rigidbody.weight); rigidbody.drag = pmx_rigidbody.position_dim; rigidbody.angularDrag = pmx_rigidbody.rotation_dim; } }
/// <summary> /// ジョイントに移動・回転制限のパラメータを設定する /// </summary> /// <param name='joint'>PMX用ジョイントデータ</param> /// <param name='conf'>Unity用ジョイント</param> void SetMotionAngularLock(PMXFormat.Joint joint, ConfigurableJoint conf) { SoftJointLimit jlim; // Motionの固定 if (joint.constrain_pos_lower.x == 0.0f && joint.constrain_pos_upper.x == 0.0f) { conf.xMotion = ConfigurableJointMotion.Locked; } else { conf.xMotion = ConfigurableJointMotion.Limited; } if (joint.constrain_pos_lower.y == 0.0f && joint.constrain_pos_upper.y == 0.0f) { conf.yMotion = ConfigurableJointMotion.Locked; } else { conf.yMotion = ConfigurableJointMotion.Limited; } if (joint.constrain_pos_lower.z == 0.0f && joint.constrain_pos_upper.z == 0.0f) { conf.zMotion = ConfigurableJointMotion.Locked; } else { conf.zMotion = ConfigurableJointMotion.Limited; } // 角度の固定 if (joint.constrain_rot_lower.x == 0.0f && joint.constrain_rot_upper.x == 0.0f) { conf.angularXMotion = ConfigurableJointMotion.Locked; } else { conf.angularXMotion = ConfigurableJointMotion.Limited; float hlim = Mathf.Max(-joint.constrain_rot_lower.x, -joint.constrain_rot_upper.x); //回転方向が逆なので負数 float llim = Mathf.Min(-joint.constrain_rot_lower.x, -joint.constrain_rot_upper.x); SoftJointLimit jhlim = new SoftJointLimit(); jhlim.limit = Mathf.Clamp(hlim * Mathf.Rad2Deg, -180.0f, 180.0f); conf.highAngularXLimit = jhlim; SoftJointLimit jllim = new SoftJointLimit(); jllim.limit = Mathf.Clamp(llim * Mathf.Rad2Deg, -180.0f, 180.0f); conf.lowAngularXLimit = jllim; } if (joint.constrain_rot_lower.y == 0.0f && joint.constrain_rot_upper.y == 0.0f) { conf.angularYMotion = ConfigurableJointMotion.Locked; } else { // 値がマイナスだとエラーが出るので注意 conf.angularYMotion = ConfigurableJointMotion.Limited; float lim = Mathf.Min(Mathf.Abs(joint.constrain_rot_lower.y), Mathf.Abs(joint.constrain_rot_upper.y));//絶対値の小さい方 jlim = new SoftJointLimit(); jlim.limit = lim * Mathf.Clamp(Mathf.Rad2Deg, 0.0f, 180.0f); conf.angularYLimit = jlim; } if (joint.constrain_rot_lower.z == 0f && joint.constrain_rot_upper.z == 0f) { conf.angularZMotion = ConfigurableJointMotion.Locked; } else { conf.angularZMotion = ConfigurableJointMotion.Limited; float lim = Mathf.Min(Mathf.Abs(-joint.constrain_rot_lower.z), Mathf.Abs(-joint.constrain_rot_upper.z));//絶対値の小さい方//回転方向が逆なので負数 jlim = new SoftJointLimit(); jlim.limit = Mathf.Clamp(lim * Mathf.Rad2Deg, 0.0f, 180.0f); conf.angularZLimit = jlim; } }
/// <summary> /// エッジマテリアル確認 /// </summary> /// <returns>true:エッジ有り, false:無エッジ</returns> /// <param name='material'>シェーダーを設定するマテリアル</param> bool IsEdgeMaterial(PMXFormat.Material material) { bool result; if (0 != (PMXFormat.Material.Flag.Edge & material.flag)) { //エッジ有りなら result = true; } else { //エッジ無し result = false; } return result; }
/// <summary> /// 剛体をUnity用に変換する /// </summary> /// <returns>Unity用剛体ゲームオブジェクト</returns> /// <param name='rigidbody'>PMX用剛体データ</param> GameObject ConvertRigidbody(PMXFormat.Rigidbody rigidbody) { GameObject result = new GameObject("r" + rigidbody.name); //result.AddComponent<Rigidbody>(); // 1つのゲームオブジェクトに複数の剛体が付く事が有るので本体にはrigidbodyを適用しない //位置・回転の設定 result.transform.position = rigidbody.collider_position * scale_; result.transform.rotation = Quaternion.Euler(rigidbody.collider_rotation * Mathf.Rad2Deg); // Colliderの設定 switch (rigidbody.shape_type) { case PMXFormat.Rigidbody.ShapeType.Sphere: EntrySphereCollider(rigidbody, result); break; case PMXFormat.Rigidbody.ShapeType.Box: EntryBoxCollider(rigidbody, result); break; case PMXFormat.Rigidbody.ShapeType.Capsule: EntryCapsuleCollider(rigidbody, result); break; default: throw new System.ArgumentException(); } return result; }
/// <summary> /// 背面カリングマテリアル確認 /// </summary> /// <returns>true:背面カリングする, false:背面カリングしない</returns> /// <param name='material'>シェーダーを設定するマテリアル</param> bool IsCullBackMaterial(PMXFormat.Material material) { bool result; if (0 != (PMXFormat.Material.Flag.Reversible & material.flag)) { //両面描画なら //背面カリングしない result = false; } else { //両面描画で無いなら //背面カリングする result = true; } return result; }
/// <summary> /// GameObjectを作成する /// </summary> /// <param name='format'>内部形式データ</param> /// <param name='use_rigidbody'>剛体を使用するか</param> /// <param name='use_mecanim'>Mecanimを使用するか</param> /// <param name='use_ik'>IKを使用するか</param> /// <param name='scale'>スケール</param> public static GameObject CreateGameObject(PMXFormat format, bool use_rigidbody, bool use_mecanim, bool use_ik, float scale) { PMXConverter converter = new PMXConverter(); return converter.CreateGameObject_(format, use_rigidbody, use_mecanim, use_ik, scale); }
/// <summary> /// MMDシェーダーパスの取得 /// </summary> /// <returns>MMDシェーダーパス</returns> /// <param name='material'>シェーダーを設定するマテリアル</param> /// <param name='texture'>シェーダーに設定するメインテクスチャ</param> string GetMmdShaderPath(PMXFormat.Material material, Texture2D texture) { string result = "MMD/"; if (IsTransparentMaterial(material, texture)) { result += "Transparent/"; } result += "PMDMaterial"; if (IsEdgeMaterial(material)) { result += "-with-Outline"; } if (IsCullBackMaterial(material)) { result += "-CullBack"; } if (IsNoCastShadowMaterial(material)) { result += "-NoCastShadow"; } #if MFU_ENABLE_NO_RECEIVE_SHADOW_SHADER //影受け無しのシェーダはまだ無いので無効化 if (IsNoReceiveShadowMaterial(material)) { result += "-NoReceiveShadow"; } #endif //MFU_ENABLE_NO_RECEIVE_SHADOW_SHADER return result; }
/// <summary> /// GameObjectを作成する /// </summary> /// <param name='format'>内部形式データ</param> /// <param name='use_rigidbody'>剛体を使用するか</param> /// <param name='use_mecanim'>Mecanimを使用するか</param> /// <param name='use_ik'>IKを使用するか</param> /// <param name='scale'>スケール</param> private GameObject CreateGameObject_(PMXFormat format, bool use_rigidbody, bool use_mecanim, bool use_ik, float scale) { format_ = format; use_rigidbody_ = use_rigidbody; use_mecanim_ = use_mecanim; use_ik_ = use_ik; scale_ = scale; root_game_object_ = new GameObject(format_.meta_header.name); MMDEngine engine = root_game_object_.AddComponent<MMDEngine>(); //MMDEngine追加 engine.scale = scale_; MeshCreationInfo[] creation_info = CreateMeshCreationInfo(); // メッシュを作成する為の情報を作成 Mesh[] mesh = CreateMesh(creation_info); // メッシュの生成・設定 Material[][] materials = CreateMaterials(creation_info); // マテリアルの生成・設定 GameObject[] bones = CreateBones(); // ボーンの生成・設定 SkinnedMeshRenderer[] renderers = BuildingBindpose(mesh, materials, bones); // バインドポーズの作成 CreateMorph(mesh, materials, bones, renderers, creation_info); // モーフの生成・設定 // BoneController・IKの登録(use_ik_を使った判定はEntryBoneController()の中で行う) { engine.bone_controllers = EntryBoneController(bones); engine.ik_list = engine.bone_controllers.Where(x=>null != x.ik_solver) .Select(x=>x.ik_solver) .ToArray(); } // 剛体関連 if (use_rigidbody_) { GameObject[] rigids = CreateRigids(); AssignRigidbodyToBone(bones, rigids); SetRigidsSettings(bones, rigids); GameObject[] joints = CreateJoints(rigids); GlobalizeRigidbody(joints); // 非衝突グループ List<int>[] ignoreGroups = SettingIgnoreRigidGroups(rigids); int[] groupTarget = GetRigidbodyGroupTargets(rigids); MMDEngine.Initialize(engine, groupTarget, ignoreGroups, rigids); } // Mecanim設定 #if UNITY_4_2 if (use_mecanim_) { //アニメーター追加 AvatarSettingScript avatar_setting = new AvatarSettingScript(root_game_object_, bones); avatar_setting.SettingAvatar(); string path = format_.meta_header.folder + "/"; string name = GetFilePathString(format_.meta_header.name); string file_name = path + name + ".avatar.asset"; avatar_setting.CreateAsset(file_name); } else { root_game_object_.AddComponent<Animation>(); // アニメーション追加 } #else //UNITY_4_2 root_game_object_.AddComponent<Animation>(); // アニメーション追加 #endif //UNITY_4_2 return root_game_object_; }
private static void ConvertPathes(PMDFormat pmd, PMXFormat pmx) { pmd.path = pmx.meta_header.path; pmd.name = pmx.meta_header.name; pmd.folder = pmx.meta_header.folder; }
/// <summary> /// 影受け無しマテリアル確認 /// </summary> /// <returns>true:影受け無し, false:影受け</returns> /// <param name='material'>シェーダーを設定するマテリアル</param> bool IsNoReceiveShadowMaterial(PMXFormat.Material material) { bool result; if (0 != (PMXFormat.Material.Flag.ReceiveSelfShadow & material.flag)) { //影受け result = false; } else { //影受け無し result = true; } return result; }
/// <summary> /// 透過マテリアル確認 /// </summary> /// <returns>true:透過, false:不透明</returns> /// <param name='material'>シェーダーを設定するマテリアル</param> /// <param name='texture'>シェーダーに設定するメインテクスチャ</param> bool IsTransparentMaterial(PMXFormat.Material material, Texture2D texture) { bool result = false; result = result || (material.diffuse_color.a < 1.0f); if (null != texture) { #if UNITY_4_2 result = result || texture.alphaIsTransparency; #else // TODO: 上記if内の代替コード必須です // result = result; #endif } return result; }
/// <summary> /// ConfigurableJointの値を設定する /// </summary> /// <param name='joint'>PMX用ジョイントデータ</param> /// <param name='conf'>Unity用ジョイント</param> void SetAttributeConfigurableJoint(PMXFormat.Joint joint, ConfigurableJoint conf) { SetMotionAngularLock(joint, conf); SetDrive(joint, conf); }