コード例 #1
0
        /// <summary>
        /// メッシュを描画。
        /// cameraPositionは x, y : [-∞, +∞], z : [-∞, 0)
        /// x, y が大きいほどカメラが右下に移動する
        /// zが小さいほどズームアウトする
        /// </summary>
        /// <param name="cameraPosition">x, y : [-∞, +∞], z : [-∞, 0).x, y が大きいほどカメラが右下に移動する.zが小さいほどズームアウトする</param>
        public void DrawMesh(PatchMesh mesh, string textureKey, PatchMeshRenderResources resources, DXColor col, Size formSize, Vector3 cameraPosition)
        {
            List <VertexPositionColorTexture> rawVertices = new List <VertexPositionColorTexture>();

            for (int i = 0; i < mesh.vertices.Count; i++)
            {
                Vector3 pos = vec3(mesh.vertices[i].position);
                pos.Y *= -1;
                Vector2 coord = vec2(mesh.vertices[i].GetTexcoord(textureKey));
                rawVertices.Add(new VertexPositionColorTexture(pos, col, coord));
            }

            List <int> rawIndices = new List <int>();

            for (int i = 0; i < mesh.triangles.Count; i++)
            {
                if (mesh.triangles[i].TextureKey != textureKey)
                {
                    continue;
                }
                rawIndices.Add(mesh.triangles[i].Idx0);
                rawIndices.Add(mesh.triangles[i].Idx1);
                rawIndices.Add(mesh.triangles[i].Idx2);
            }

            var texture = resources.GetTexture(PatchMeshRenderResources.GenerateResourceKey(mesh, textureKey));

            Draw(rawVertices, rawIndices, texture, formSize, cameraPosition, PrimitiveTopology.TriangleList);
        }
コード例 #2
0
        /// <summary>
        /// 2つの骨格つきメッシュをスケルトン情報を元に結合する
        /// 1. スケルトンに合わせて各メッシュをざっくり移動・ボーン方向にARAP
        /// 2. メッシュ同士が自然に繋がるように位置・角度・スケールを調整(fitting(), adjustposition())
        /// 3. 繋ぎ目が重なるようにARAP(expand())
        /// 4. 新しいARAP可能なひとつのメッシュを生成(combine)                                                                                                                                                                                                                                                                                          /// </summary>
        /// (5. リソースの更新。これはここでやるべきなのだろうか?)
        /// </summary>
        public static PatchSkeletalMesh Connect(PatchSkeletalMesh smesh1, PatchSkeletalMesh smesh2, PatchSkeleton refSkeleton, PatchMeshRenderResources resources)
        {
            if (refSkeleton == null)
            {
                return(null);
            }

            // メッシュ・骨格データはConnect()内で変更されうるのでコピーしたものを使う
            PatchSkeletalMesh smesh1_t = PatchSkeletalMesh.Copy(smesh1);
            PatchSkeletalMesh smesh2_t = PatchSkeletalMesh.Copy(smesh2);

#if DEBUG
            PatchSkeletalMeshRenderer.ToBitmap(smesh1_t, smesh1_t.sections, alignment: true).Save("smesh1_t.png");
            PatchSkeletalMeshRenderer.ToBitmap(smesh2_t, smesh2_t.sections, alignment: true).Save("smesh2_t.png");
#endif
            var refSkeleton_t = PatchSkeleton.Copy(refSkeleton);

            // smesh1, smesh2で同じボーンを共有している(結合すべき)切り口を探す
            // これらの切り口の付近を変形することでメッシュを繋げる
            PatchSection      section1;
            PatchSection      section2;
            PatchSkeletonBone crossingBone;

            bool canConnect = CanConnect(new List <PatchSkeletalMesh>()
            {
                smesh1, smesh2
            }, refSkeleton);
            bool canConnect_t = CanConnect(new List <PatchSkeletalMesh>()
            {
                smesh1_t, smesh2_t
            }, refSkeleton_t);

            bool found = FindConnectingSections(smesh1_t, smesh2_t, refSkeleton_t, out section1, out section2, out crossingBone);
            if (!found)
            {
                return(null);
            }
#if _DEBUG
            PatchSkeletalMeshRenderer.ToBitmap(smesh1_t, new List <CharacterRange>()
            {
                section1
            }).Save("output/3_mesh1_t_seciton1.png");
            PatchSkeletalMeshRenderer.ToBitmap(smesh2_t, new List <CharacterRange>()
            {
                section2
            }).Save("output/4_mesh2_t_section2.png");
#endif

            // 2つのsmeshが重なるように位置調整およびARAP変形をする
            smesh1_t.mesh.BeginDeformation();
            smesh2_t.mesh.BeginDeformation();
            Deform(smesh1_t, smesh2_t, refSkeleton_t, section1, section2, crossingBone);
            smesh2_t.mesh.EndDeformation();
            smesh1_t.mesh.EndDeformation();
#if _DEBUG
            PatchSkeletalMeshRenderer.ToBitmap(smesh1_t).Save("output/6_mesh1_t_deformed.png");
            PatchSkeletalMeshRenderer.ToBitmap(smesh2_t).Save("output/7_mesh2_t_deformed.png");
#endif

            // 2つの変形済みのsmeshを1つのsmeshに結合して、ARAPできるようにする
            var combinedSMesh = Combine(smesh1_t, smesh2_t, section1, section2);
#if _DEBUG
            PatchSkeletalMeshRenderer.ToBitmap(combinedSMesh, combinedSMesh.sections).Save("output/8_conbinedMesh.png");
#endif

            if (resources != null)
            {
                List <string> textureKeys = resources.GetResourceKeyByPatchMesh(smesh1.mesh);
                textureKeys.AddRange(resources.GetResourceKeyByPatchMesh(smesh2.mesh));

                foreach (var key in textureKeys)
                {
                    string patchKey = key.Split(':').Last();
                    string newKey   = PatchMeshRenderResources.GenerateResourceKey(combinedSMesh.mesh, patchKey);
                    // TODO: テクスチャはコピーしたほうが良い?
                    resources.Add(newKey, resources.GetTexture(key));
                }
            }

            return(combinedSMesh);
        }
コード例 #3
0
        public static PatchSkeletalMesh Connect(List <PatchSkeletalMesh> smeshes, PatchSkeleton refSkeleton, PatchMeshRenderResources resources)
        {
            var overlapPairs = GetOverlappedPairs(smeshes, refSkeleton);

            if (overlapPairs.Count <= 0)
            {
                return(null);
            }

            var newMesh = overlapPairs[0].Item1;
            List <PatchSkeletalMesh> aggregated = new List <PatchSkeletalMesh>();

            aggregated.Add(overlapPairs[0].Item1);

            int _orgCnt = overlapPairs.Count;

            for (int j = 0; j < overlapPairs.Count; j++)
            {
                for (int i = 0; i < overlapPairs.Count; i++)
                {
                    var pair = overlapPairs[i];
                    if (aggregated.Contains(pair.Item1) && !aggregated.Contains(pair.Item2))
                    {
                        newMesh = Connect(newMesh, pair.Item2, refSkeleton, resources);
                        aggregated.Add(pair.Item2);
                        overlapPairs.RemoveAt(i);
                        break;
                    }
                    else if (!aggregated.Contains(pair.Item1) && aggregated.Contains(pair.Item2))
                    {
                        newMesh = Connect(newMesh, pair.Item1, refSkeleton, resources);
                        aggregated.Add(pair.Item1);
                        overlapPairs.RemoveAt(i);
                        break;
                    }
                }
                System.Diagnostics.Debug.Assert(aggregated.Count == j + 2);
                System.Diagnostics.Debug.Assert(overlapPairs.Count == _orgCnt - j - 1);
            }

            return(newMesh);
        }
コード例 #4
0
 /// <summary>
 /// メッシュを描画。
 /// cameraPositionは x, y : [-∞, +∞], z : [-∞, 0)
 /// x, y が大きいほどカメラが右下に移動する
 /// zが小さいほどズームアウトする
 /// </summary>
 /// <param name="cameraPosition">x, y : [-∞, +∞], z : [-∞, 0).x, y が大きいほどカメラが右下に移動する.zが小さいほどズームアウトする</param>
 public void DrawMesh(PatchMesh mesh, string textureKey, PatchMeshRenderResources resources, Size formSize, Vector3 cameraPosition)
 {
     DrawMesh(mesh, textureKey, resources, DXColor.White, formSize, cameraPosition);
 }
コード例 #5
0
        public static PatchSkeletalMesh Connect(PatchSkeletalMesh patch1, PatchSkeletalMesh patch2, PatchSkeleton refSkeleton, PatchMeshRenderResources resources)
        {
            if (refSkeleton == null)
            {
                return(null);
            }

            if (!System.IO.Directory.Exists("output_Connector2"))
            {
                System.IO.Directory.CreateDirectory("output_Connector2");
            }

            FLib.FileManager.OpenExplorer("output_Connector2");

#if _DEBUG
            PatchSkeletalMeshRenderer.ToBitmap(patch1).Save("output_Connector2/1_patch1.png");
            PatchSkeletalMeshRenderer.ToBitmap(patch2).Save("output_Connector2/1_patch2.png");
#endif
            // 1. パッチをコピー
            PatchSkeletalMesh patch1_t = PatchSkeletalMesh.Copy(patch1);
            PatchSkeletalMesh patch2_t = PatchSkeletalMesh.Copy(patch2);
            var refSkeleton_t          = PatchSkeleton.Copy(refSkeleton);

            // 2. patch1, patch2の接続面および対応するボーンを探す
            PatchSection      section1;
            PatchSection      section2;
            PatchSkeletonBone crossingBone;
            bool swap;
            bool found = ConnectableSections(patch1_t, patch2_t, refSkeleton_t, out section1, out section2, out crossingBone, out swap);
            if (!found)
            {
                return(null);
            }

            if (swap)
            {
                FMath.Swap(ref patch1_t, ref patch2_t);
                FMath.Swap(ref section1, ref section2);
            }

#if _DEBUG
            PatchSkeletalMeshRenderer.ToBitmap(patch1_t, new List <CharacterRange>()
            {
                section1
            }).Save("output_Connector2/2_patch1.png");
            PatchSkeletalMeshRenderer.ToBitmap(patch2_t, new List <CharacterRange>()
            {
                section2
            }).Save("output_Connector2/2_patch2.png");
#endif

            // 3. 2つのパッチが重なるように位置調整およびARAP変形
            patch1_t.mesh.BeginDeformation();
            patch2_t.mesh.BeginDeformation();
            Deform(patch1_t, patch2_t, refSkeleton_t, section1, section2, crossingBone);
            patch2_t.mesh.EndDeformation();
            patch1_t.mesh.EndDeformation();

#if _DEBUG
            PatchSkeletalMeshRenderer.ToBitmap(patch1_t, new List <CharacterRange>()
            {
                section1
            }).Save("output_Connector2/3_patch1.png");
            PatchSkeletalMeshRenderer.ToBitmap(patch2_t, new List <CharacterRange>()
            {
                section2
            }).Save("output_Connector2/3_patch2.png");
#endif

            // 4. 2つのパッチのテクスチャを合成して、新しいパッチを生成

//            TODO:メッシュをビットマップ画像として書き出してリサンプリング

            // todo
            var combinedSMesh = Combine(patch1_t, patch2_t, section1, section2);


            // 5. 新しいパッチに使うテクスチャをリソースに登録

            // todo
            if (resources != null)
            {
                List <string> textureKeys = resources.GetResourceKeyByPatchMesh(patch1.mesh);
                textureKeys.AddRange(resources.GetResourceKeyByPatchMesh(patch2.mesh));

                foreach (var key in textureKeys)
                {
                    string patchKey = key.Split(':').Last();
                    string newKey   = PatchMeshRenderResources.GenerateResourceKey(combinedSMesh.mesh, patchKey);
                    resources.Add(newKey, resources.GetTexture(key));
                }
            }
            return(combinedSMesh);
        }
コード例 #6
0
        /// <summary>
        ///
        /// - ざっくり位置合わせ(オーバーラップさせる)
        /// - 接続後の境界を計算
        /// - それにあせてボーンと垂直方向に画像を変形
        /// - リサンプリング
        ///
        /// ・対応する境界線を探す(2D)
        /// ・ざっくり重なるように移動・拡大操作(2D)
        /// ・seam carving method(3D?)
        /// ・graphcut textures(2D)
        /// ・poisson blending(2D) (opencvを使う)
        /// ・resampleしてpatchmeshに戻す(3D)
        /// </summary>
        /// <param name="patches"></param>
        /// <param name="refSkeleton"></param>
        /// <param name="resources"></param>
        /// <returns></returns>
        public static PatchSkeletalMesh Connect(List <PatchSkeletalMesh> patches, PatchSkeleton refSkeleton, PatchMeshRenderResources resources)
        {
            var overlapPairs = OverlapPatchPairs(patches, refSkeleton);

            if (overlapPairs.Count <= 0)
            {
                return(null);
            }

            var newPatch = overlapPairs[0].Item1;
            List <PatchSkeletalMesh> aggregated = new List <PatchSkeletalMesh>();

            aggregated.Add(overlapPairs[0].Item1);

            for (int j = 0; j < overlapPairs.Count; j++)
            {
                // newPatchと接続可能なpatchをひとつ探して繋げる
                // O(N^2)だけど、patchesの総数はせいぜい十数個なので問題ない
                for (int i = 0; i < overlapPairs.Count; i++)
                {
                    var pair = overlapPairs[i];
                    if (aggregated.Contains(pair.Item1) && !aggregated.Contains(pair.Item2))
                    {
                        var connected = Connect(newPatch, pair.Item2, refSkeleton, resources);
                        if (connected != null)
                        {
                            newPatch = connected;
                            aggregated.Add(pair.Item2);
                            overlapPairs.RemoveAt(i);
                            break;
                        }
                    }
                    else if (!aggregated.Contains(pair.Item1) && aggregated.Contains(pair.Item2))
                    {
                        if (newPatch != null)
                        {
                            var connected = Connect(newPatch, pair.Item1, refSkeleton, resources);
                            if (connected != null)
                            {
                                newPatch = connected;
                                aggregated.Add(pair.Item1);
                                overlapPairs.RemoveAt(i);
                                break;
                            }
                        }
                    }
                }
            }

            return(newPatch);
        }