示例#1
0
        /// 頂点を追加します。
        public void Push(Vertex a, TSOSubMesh sub)
        {
            int        x    = GetX(a.position.X);
            int        y    = GetY(a.position.Y);
            int        z    = GetZ(a.position.Z);
            UniqueCell cell = GetCell(x, y, z);

            cell.Push(a, sub);
        }
示例#2
0
 private Matrix[] ClipBoneMatrices(TSOSubMesh sub_mesh, TMOFile tmo)
 {
     Matrix[] clipped_boneMatrices = new Matrix[sub_mesh.maxPalettes];
     for (int numPalettes = 0; numPalettes < sub_mesh.maxPalettes; numPalettes++)
     {
         TSONode tso_node = sub_mesh.GetBone(numPalettes);
         TMONode tmo_node = tmo.FindNodeByName(tso_node.Name);
         clipped_boneMatrices[numPalettes] = tso_node.OffsetMatrix * tmo_node.combined_matrix;
     }
     return(clipped_boneMatrices);
 }
示例#3
0
 /// 警告 'ボーン参照が見つかりませんでした' を出力します。
 public void WarnBoneIndexNotFound(Vertex a, TSOSubMesh sub)
 {
     Console.WriteLine("### 警告: ボーン参照が見つかりませんでした。修正は諦めます。");
     Dump();
     for (int i = 0; i < 4; i++)
     {
         SkinWeight sw   = skin_weights[i];
         SkinWeight a_sw = a.skin_weights[i];
         Console.WriteLine("{0} sw({1} {2}) a sw({3} {4})", i, sw.bone_index, sw.weight, sub.bone_indices[a_sw.bone_index], a_sw.weight);
     }
     Console.WriteLine();
 }
示例#4
0
 /// <summary>
 /// 同一視頂点を生成します。
 /// </summary>
 /// <param name="a">頂点</param>
 /// <param name="sub">頂点を含むサブメッシュ</param>
 public UniqueVertex(Vertex a, TSOSubMesh sub)
 {
     this.vertices     = new Dictionary <Vertex, TSOSubMesh>();
     vertices[a]       = sub;
     this.position     = a.position;
     this.skin_weights = new SkinWeight[4];
     for (int i = 0; i < 4; i++)
     {
         SkinWeight sw = a.skin_weights[i];
         skin_weights[i] = new SkinWeight(sub.bone_indices[sw.bone_index], sw.weight);
     }
     opposite_vertex = null;
 }
示例#5
0
        /// 対称位置にある同一視頂点のスキンウェイトを複写します。
        public void CopyOppositeWeights()
        {
            if (opposite_vertex == null)
            {
                return;
            }

            if (opposite_vertex == this)
            {
                return;
            }

            //ウェイト値がずれている場合は警告する。
            bool weights_gap_found = false;

            for (int i = 0; i < 4; i++)
            {
                SkinWeight sw     = skin_weights[i];
                SkinWeight opp_sw = opposite_vertex.skin_weights[i];
                if (Math.Abs(sw.weight - opp_sw.weight) >= 1.0e-2f)
                {
                    weights_gap_found = true;
                    break;
                }
            }
            if (weights_gap_found)
            {
                WarnOppositeWeights();
            }

            for (int i = 0; i < 4; i++)
            {
                SkinWeight sw     = skin_weights[i];
                SkinWeight opp_sw = opposite_vertex.skin_weights[i];
                sw.bone_index = GetOppositeBoneIndex(opp_sw.bone_index);
                sw.weight     = opp_sw.weight;
            }

            foreach (KeyValuePair <Vertex, TSOSubMesh> pair in vertices)
            {
                Vertex     a   = pair.Key;
                TSOSubMesh sub = pair.Value;
                CopyWeights(a, sub);
            }
        }
示例#6
0
        /// 頂点を追加します。
        public void Push(Vertex a, TSOSubMesh sub)
        {
            bool found = false;

            foreach (UniqueVertex v in vertices)
            {
                if (LengthSq(a.position, v.position) < float.Epsilon)
                {
                    v.Push(a, sub);
                    found = true;
                    break;
                }
            }
            if (!found)
            {
                vertices.Add(new UniqueVertex(a, sub));
            }
        }
示例#7
0
        /// 同じ位置にある頂点を追加します。
        public void Push(Vertex a, TSOSubMesh sub)
        {
            vertices[a] = sub;

            //頂点のボーン参照が最初の頂点と異なる場合は警告する。
            for (int i = 0; i < 4; i++)
            {
                SkinWeight sw   = skin_weights[i];
                SkinWeight a_sw = a.skin_weights[i];
                if (sw.weight != 0.0f)
                {
                    if (sw.bone_index != sub.bone_indices[a_sw.bone_index])
                    {
                        Console.WriteLine("### 警告: ボーン参照が最初の頂点と異なります。");
                        Dump();
                        Console.WriteLine("{0} sw({1} {2}) a sw({3} {4})", i, sw.bone_index, sw.weight, sub.bone_indices[a_sw.bone_index], a_sw.weight);
                    }
                }
            }
        }
示例#8
0
        void CopyWeights(Vertex a, TSOSubMesh sub)
        {
            //ボーン参照が見つからない場合は警告する。
            bool bone_index_not_found = false;

            for (int i = 0; i < 4; i++)
            {
                SkinWeight sw         = skin_weights[i];
                SkinWeight a_sw       = a.skin_weights[i];
                int        a_bone_idx = Array.IndexOf(sub.bone_indices, sw.bone_index);
                if (a_bone_idx == -1)
                {
                    a_bone_idx = sub.AddBone(GetBone(sw.bone_index));
                }
                if (a_bone_idx == -1)
                {
                    if (sw.weight == 0.0f)
                    {
                        a_sw.bone_index = 0;
                        a_sw.weight     = 0.0f;
                    }
                    else
                    {
                        bone_index_not_found = true;
                    }
                }
                else
                {
                    a_sw.bone_index = a_bone_idx;
                    a_sw.weight     = sw.weight;
                }
            }
            if (bone_index_not_found)
            {
                WarnBoneIndexNotFound(a, sub);
            }
        }
示例#9
0
        public static List <TSOSubMesh> CreateSubMeshes(List <TSOFace> faces, int max_palettes)
        {
            List <TSOFace> faces_1 = faces;
            List <TSOFace> faces_2 = new List <TSOFace>();

            Heap <int> bh = new Heap <int>();
            Heap <UnifiedPositionTexcoordVertex> vh = new Heap <UnifiedPositionTexcoordVertex>();

            List <ushort>          vert_indices        = new List <ushort>();
            Dictionary <int, bool> adding_bone_indices = new Dictionary <int, bool>();
            List <TSOSubMesh>      sub_meshes          = new List <TSOSubMesh>();

            Console.WriteLine("  vertices bone_indices");
            Console.WriteLine("  -------- ------------");

            while (faces_1.Count != 0)
            {
                int spec = faces_1[0].spec;
                bh.Clear();
                vh.Clear();
                vert_indices.Clear();

                foreach (TSOFace f in faces_1)
                {
                    if (f.spec != spec)
                    {
                        faces_2.Add(f);
                        continue;
                    }
                    adding_bone_indices.Clear();
                    foreach (UnifiedPositionVertex v in f.vertices)
                    {
                        foreach (SkinWeight sw in v.skin_weights)
                        {
                            if (sw.weight < WeightEpsilon)
                            {
                                continue;
                            }
                            if (bh.ContainsKey(sw.bone_index))
                            {
                                continue;
                            }
                            adding_bone_indices[sw.bone_index] = true;
                        }
                    }
                    if (bh.Count + adding_bone_indices.Count > max_palettes)
                    {
                        faces_2.Add(f);
                        continue;
                    }
                    foreach (int bone_index in adding_bone_indices.Keys)
                    {
                        bh.Add(bone_index);
                    }
                    foreach (UnifiedPositionVertex v in f.vertices)
                    {
                        UnifiedPositionTexcoordVertex a = new UnifiedPositionTexcoordVertex(v, bh.map);
                        if (!vh.ContainsKey(a))
                        {
                            vh.Add(a);
                        }
                        vert_indices.Add(vh[a]);
                    }
                }
                //Console.WriteLine("#vert_indices:{0}", vert_indices.Count);
                ushort[] optimized_indices = NvTriStrip.Optimize(vert_indices.ToArray());
                //Console.WriteLine("#optimized_indices:{0}", optimized_indices.Length);

                TSOSubMesh sub = new TSOSubMesh();
                sub.spec = spec;
                //Console.WriteLine("#bone_indices:{0}", bh.Count);
                sub.bone_indices = bh.ary.ToArray();

                UnifiedPositionTexcoordVertex[] vertices = new UnifiedPositionTexcoordVertex[optimized_indices.Length];
                for (int i = 0; i < optimized_indices.Length; i++)
                {
                    vertices[i] = vh.ary[optimized_indices[i]];
                }
                sub.vertices = vertices;

                Console.WriteLine("  {0,8} {1,12}", sub.vertices.Length, sub.bone_indices.Length);

                sub_meshes.Add(sub);

                List <TSOFace> faces_tmp = faces_1;
                faces_1 = faces_2;
                faces_2 = faces_tmp;
                faces_tmp.Clear();
            }
            return(sub_meshes);
        }