/// <summary> /// 文字列表現を出力します。 /// </summary> public void Dump() { Console.WriteLine(this); if (vertices.Count > 0) { UniqueVertex v = vertices[0]; v.Dump(); } }
/// <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; }
/// <summary> /// 指定位置に最も近い同一視頂点を見つけます。 /// </summary> /// <param name="position">位置</param> /// <param name="cell">探索対象セル</param> /// <param name="found">前回見つけた頂点</param> /// <param name="min_len_sq">前回見つけた頂点までの距離の平方</param> /// <returns></returns> public static UniqueVertex FindVertex(Vector3 position, UniqueCell cell, UniqueVertex found, ref float min_len_sq) { if (cell != null) { float len_sq; UniqueVertex v = cell.FindVertexAt(position, out len_sq); if (min_len_sq > len_sq) { min_len_sq = len_sq; found = v; } } return(found); }
/// 指定位置に最も近い同一視頂点を見つけます。 public UniqueVertex FindVertexAt(Vector3 position, out float min_len_sq) { min_len_sq = 10.0f; UniqueVertex found = null; foreach (UniqueVertex v in vertices) { float len_sq = LengthSq(position, v.position); if (min_len_sq > len_sq) { min_len_sq = len_sq; found = v; } } return(found); }
void FindOppositeVertex(UniqueVertex v) { Vector3 opp_p = v.GetOppositePosition(); float x = opp_p.X; float y = opp_p.Y; float z = opp_p.Z; int dx = GetSign(x); int dy = GetSign(y); int dz = GetSign(z); UniqueVertex opp_v = null; float min_len_sq = 10.0f; opp_v = FindVertex(opp_p, opposite_cell, opp_v, ref min_len_sq); if (dx != 0) { opp_v = FindVertex(opp_p, opposite_cell.GetNeighbor(dx, 0, 0), opp_v, ref min_len_sq); } if (dy != 0) { opp_v = FindVertex(opp_p, opposite_cell.GetNeighbor(0, dy, 0), opp_v, ref min_len_sq); } if (dz != 0) { opp_v = FindVertex(opp_p, opposite_cell.GetNeighbor(0, 0, dz), opp_v, ref min_len_sq); } if (dx != 0 && dy != 0) { opp_v = FindVertex(opp_p, opposite_cell.GetNeighbor(dx, dy, 0), opp_v, ref min_len_sq); } if (dy != 0 && dz != 0) { opp_v = FindVertex(opp_p, opposite_cell.GetNeighbor(0, dy, dz), opp_v, ref min_len_sq); } if (dz != 0 && dx != 0) { opp_v = FindVertex(opp_p, opposite_cell.GetNeighbor(dx, 0, dz), opp_v, ref min_len_sq); } if (dx != 0 && dy != 0 && dz != 0) { opp_v = FindVertex(opp_p, opposite_cell.GetNeighbor(dx, dy, dz), opp_v, ref min_len_sq); } v.opposite_vertex = opp_v; }
static void Main(string[] args) { if (args.Length < 1) { Console.WriteLine("TSOWeightCopy.exe <tso file>"); return; } string source_file = args[0]; TSOFile tso = new TSOFile(); tso.Load(source_file); UniqueVertex.nodes = tso.nodes; UniqueVertex.oppnode_idmap = create_oppnode_idmap(tso); Console.WriteLine("メッシュ:"); int i = 0; foreach (TSOMesh mesh in tso.meshes) { Console.WriteLine("{0} {1}", i, mesh.Name); i++; } Console.Write("メッシュを選択 (0-{0}): ", tso.meshes.Length - 1); int mesh_idx = 0; try { mesh_idx = int.Parse(Console.ReadLine()); } catch (System.FormatException e) { Console.WriteLine(e); return; } TSOMesh selected_mesh = null; try { selected_mesh = tso.meshes[mesh_idx]; } catch (IndexOutOfRangeException e) { Console.WriteLine(e); return; } Vector3 min = Vector3.Empty; Vector3 max = Vector3.Empty; int nvertices = 0; foreach (TSOSubMesh sub in selected_mesh.sub_meshes) { foreach (Vertex v in sub.vertices) { float x = v.position.X; float y = v.position.Y; float z = v.position.Z; if (min.X > x) { min.X = x; } if (min.Y > y) { min.Y = y; } if (min.Z > z) { min.Z = z; } if (max.X < x) { max.X = x; } if (max.Y < y) { max.Y = y; } if (max.Z < z) { max.Z = z; } nvertices++; } } Console.WriteLine("頂点数:{0}", nvertices); Console.WriteLine("min:{0}", UniqueVertex.ToString(min)); Console.WriteLine("max:{0}", UniqueVertex.ToString(max)); Cluster cluster = new Cluster(min, max); foreach (TSOSubMesh sub in selected_mesh.sub_meshes) { foreach (Vertex v in sub.vertices) { cluster.Push(v, sub); } } Console.WriteLine("同一視頂点数:{0}", cluster.vertices.Count); Console.WriteLine(); Console.WriteLine("方向:"); Console.WriteLine("0 左から右"); Console.WriteLine("1 右から左"); Console.Write("方向を選択 (0-1): "); int copy_dir = 0; try { copy_dir = int.Parse(Console.ReadLine()); } catch (System.FormatException e) { Console.WriteLine(e); return; } switch (copy_dir) { case 0: cluster.dir = CopyDirection.LtoR; break; case 1: cluster.dir = CopyDirection.RtoL; break; } cluster.AssignOppositeCells(); cluster.AssignOppositeVertices(); //cluster.Dump(); cluster.CopyOppositeWeights(); string dest_path = Path.GetDirectoryName(source_file); string dest_file = Path.GetFileNameWithoutExtension(source_file) + @".new.tso"; dest_path = Path.Combine(dest_path, dest_file); Console.WriteLine("Save File: " + dest_path); tso.Save(dest_path); }