示例#1
0
    /// <summary>
    /// 材質モーフ計算
    /// </summary>
    void ComputeMaterialMorph()
    {
        if (0 < material_morph.meshes.Length)
        {
            //各材質を初期化しておく
            MaterialMorph.MaterialMorphParameter[] composite_mul = Enumerable.Repeat(MaterialMorph.MaterialMorphParameter.one, material_morph.source.Length).ToArray();
            MaterialMorph.MaterialMorphParameter[] composite_add = Enumerable.Repeat(MaterialMorph.MaterialMorphParameter.zero, material_morph.source.Length).ToArray();

            // 表情ごとに計算する
            bool is_update = false;
            foreach (var morph in material_morph.script)
            {
                if (morph.Compute(composite_mul, composite_add))
                {
                    is_update = true;
                }
            }

            if (is_update)
            {
                //全材質計算
                bool has_all_target = false;
                if (-1 == material_morph.meshes[0].indices.LastOrDefault())
                {
                    //最後に-1(≒uint.MaxValue)が有れば
                    //全材質モーフが有る
                    has_all_target = true;
                }
                if (has_all_target)
                {
                    //全材質モーフが有れば
                    //全材質に反映
                    MaterialMorph.MaterialMorphParameter composite_mul_all = composite_mul.Last();
                    MaterialMorph.MaterialMorphParameter composite_add_all = composite_add.Last();
                    for (int i = 0, i_max = material_morph.source.Length - 1; i < i_max; ++i)
                    {
                        composite_mul[i] *= composite_mul_all;
                        composite_add[i] += composite_add_all;
                    }
                }

                // ここで計算結果を入れていく
                for (int r = 0, r_max = renderers.Length; r < r_max; ++r)
                {
                    for (int m = 0, m_max = material_morph.source.Length - ((has_all_target)? 1: 0); m < m_max; ++m)
                    {
                        int index = material_morph.meshes[r].indices[m];
                        if (index < renderer_shared_materials_[r].Length)
                        {
                            ApplyMaterialMorph(renderer_shared_materials_[r][index]
                                               , material_morph.source[m]
                                               , composite_mul[m]
                                               , composite_add[m]
                                               );
                        }
                    }
                }
            }
        }
    }
示例#2
0
    /// <summary>
    /// 材質モーフ反映
    /// </summary>
    /// <param name='material'>反映先マテリアル</param>
    /// <param name='composite'>反映するデータ</param>
    private static void ApplyMaterialMorph(Material material, MaterialMorph.MaterialMorphParameter source, MaterialMorph.MaterialMorphParameter composite_mul, MaterialMorph.MaterialMorphParameter composite_add)
    {
        MaterialMorph.MaterialMorphParameter composite = source * composite_mul + composite_add;
        material.SetColor("_Color", composite.color);
        material.SetFloat("_Opacity", composite.color.a);
        material.SetColor("_AmbColor", composite.ambient);
        material.SetColor("_SpecularColor", composite.specular);
        material.SetFloat("_Shininess", composite.specular.a);
        material.SetColor("_OutlineColor", composite.outline_color);
        material.SetFloat("_OutlineWidth", composite.outline_width);
#if MFU_CHANGEABLE_TEXTURE_COLOR_SHADER //テクスチャカラーの変更出来るシェーダーが無いので無効化
        material.SetColor("_MainTexColor", composite.texture_color);
        material.SetColor("_SphereTexColor", composite.sphere_color);
        material.SetColor("_ToonTexColor", composite.toon_color);
#endif //MFU_CHANGEABLE_TEXTURE_COLOR_SHADER
    }
示例#3
0
        /// <summary>
        /// 材質モーフ作成
        /// </summary>
        /// <param name='morph_manager'>表情マネージャー</param>
        /// <param name='morphs'>モーフのゲームオブジェクト</param>
        /// <param name='creation_info'>メッシュ作成情報</param>
        void CreateMaterialMorph(MorphManager morph_manager, GameObject[] morphs, MeshCreationInfo[] creation_info)
        {
            //インデックスと元データの作成
            List<uint> original_indices = format_.morph_list.morph_data.Where(x=>(PMXFormat.MorphData.MorphType.Material == x.morph_type)) //該当モーフに絞る
                                                                        .SelectMany(x=>x.morph_offset.Select(y=>((PMXFormat.MaterialMorphOffset)y).material_index)) //インデックスの取り出しと連結
                                                                        .Distinct() //重複したインデックスの削除
                                                                        .ToList(); //ソートに向けて一旦リスト化
            original_indices.Sort(); //ソート
            if (uint.MaxValue == original_indices.LastOrDefault()) {
                //最後が uint.MaxValue(≒-1) なら
                //全材質対象が存在するので全インデックスを取得
                original_indices = Enumerable.Range(0, format_.material_list.material.Length + 1).Select(x=>(uint)x).ToList();
                original_indices[format_.material_list.material.Length] = uint.MaxValue; //uint.MaxValueを忘れない
            }
            int[] indices = original_indices.Select(x=>(int)x).ToArray();
            MaterialMorph.MaterialMorphParameter[] source = indices.Where(x=>x<format_.material_list.material.Length)
                                                                    .Select(x=>{  //インデックスを用いて、元データをパック
                                                                            MaterialMorph.MaterialMorphParameter result = new MaterialMorph.MaterialMorphParameter();
                                                                            if (0 <= x) {
                                                                                //-1(全材質対象)で無いなら
                                                                                //元データを取得
                                                                                PMXFormat.Material y = format_.material_list.material[x];
                                                                                result.color = y.diffuse_color;
                                                                                result.specular = new Color(y.specular_color.r, y.specular_color.g, y.specular_color.b, y.specularity);
                                                                                result.ambient = y.ambient_color;
                                                                                result.outline_color = y.edge_color;
                                                                                result.outline_width = y.edge_size;
                                                                                result.texture_color = Color.white;
                                                                                result.sphere_color = Color.white;
                                                                                result.toon_color = Color.white;
                                                                            } else {
                                                                                //-1(全材質対象)なら
                                                                                //適当にでっち上げる
                                                                                result = MaterialMorph.MaterialMorphParameter.zero;
                                                                            }
                                                                            return result;
                                                                        })
                                                                    .ToArray();

            //インデックス逆引き用辞書の作成
            Dictionary<uint, uint> index_reverse_dictionary = new Dictionary<uint, uint>();
            for (uint i = 0, i_max = (uint)indices.Length; i < i_max; ++i) {
                index_reverse_dictionary.Add((uint)indices[i], i);
            }

            //個別モーフスクリプトの作成
            MaterialMorph[] script = Enumerable.Range(0, format_.morph_list.morph_data.Length)
                                                .Where(x=>PMXFormat.MorphData.MorphType.Material == format_.morph_list.morph_data[x].morph_type) //該当モーフに絞る
                                                .Select(x=>AssignMaterialMorph(morphs[x], format_.morph_list.morph_data[x], index_reverse_dictionary))
                                                .ToArray();

            //材質リアサイン辞書の作成
            Dictionary<uint, uint>[] material_reassign_dictionary = new Dictionary<uint, uint>[creation_info.Length + 1];
            for (int i = 0, i_max = creation_info.Length; i < i_max; +++i) {
                material_reassign_dictionary[i] = new Dictionary<uint, uint>();
                for (uint k = 0, k_max = (uint)creation_info[i].value.Length; k < k_max; ++k) {
                    material_reassign_dictionary[i][creation_info[i].value[k].material_index] = k;
                }
                if (-1 == indices.LastOrDefault()) {
                    //indices の最後が -1(≒uint.MaxValue) なら
                    //全材質対象が存在するので材質リアサイン辞書に追加
                    material_reassign_dictionary[i][uint.MaxValue] = uint.MaxValue;
                }
            }

            //メッシュ別インデックスの作成
            int invalid_material_index = format_.material_list.material.Length;
            MorphManager.MaterialMorphPack.Meshes[] multi_indices = new MorphManager.MaterialMorphPack.Meshes[creation_info.Length];
            for (int i = 0, i_max = creation_info.Length; i < i_max; ++i) {
                multi_indices[i] = new MorphManager.MaterialMorphPack.Meshes();
                multi_indices[i].indices = new int[indices.Length];
                for (int k = 0, k_max = indices.Length; k < k_max; ++k) {
                    if (material_reassign_dictionary[i].ContainsKey((uint)indices[k])) {
                        //この材質で有効なら
                        multi_indices[i].indices[k] = (int)material_reassign_dictionary[i][(uint)indices[k]];
                    } else {
                        //この材質では無効なら
                        multi_indices[i].indices[k] = invalid_material_index; //最大材質数を設定(uint.MaxValueでは無いので注意)
                    }
                }
            }

            //表情マネージャーにインデックス・元データ・スクリプトの設定
            morph_manager.material_morph = new MorphManager.MaterialMorphPack(multi_indices, source, script);
        }
示例#4
0
 /// <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;
 }