Example #1
0
        public static MeshGroup Clone(this MeshGroup src)
        {
            throw new NotImplementedException();

            // var dst = new MeshGroup(src.Name);

            // return dst;
        }
        /// <summary>
        /// Integrate meshes to a single mesh
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public static MeshGroup CreateSingleMesh(this Model model, string name)
        {
            // new mesh to store result
            var meshGroup = new MeshGroup(name);
            var mesh      = new Mesh
            {
                VertexBuffer = new VertexBuffer()
            };

            meshGroup.Meshes.Add(mesh);

            var useCountList = GetNodeSkinUseCount(model);

            // new Skin.
            // Joints has include all joint
            meshGroup.Skin = new Skin();
            for (int i = 0; i < useCountList.Length; ++i)
            {
                if (useCountList[i] > 0)
                {
                    // add joint that has bone weight
                    meshGroup.Skin.Joints.Add(model.Nodes[i]);
                }
            }
            model.Skins.Clear();
            model.Skins.Add(meshGroup.Skin);

            // concatenate all mesh
            foreach (var node in model.Root.Traverse().Skip(1))
            {
                var g = node.MeshGroup;
                if (g != null)
                {
                    foreach (var m in g.Meshes)
                    {
                        if (g.Skin != null && m.VertexBuffer.Joints != null && m.VertexBuffer.Weights != null)
                        {
                            var jointIndexMap = g.Skin.Joints.Select(x => meshGroup.Skin.Joints.IndexOf(x)).ToArray();
                            mesh.Append(m.VertexBuffer, m.IndexBuffer, m.Submeshes, m.MorphTargets, jointIndexMap);
                        }
                        else
                        {
                            var rootIndex = meshGroup.Skin.Joints.IndexOf(node);
                            mesh.Append(m.VertexBuffer, m.IndexBuffer, m.Submeshes, m.MorphTargets, null, rootIndex, node.Matrix);
                        }
                    }
                }
            }

            foreach (var target in mesh.MorphTargets)
            {
                target.VertexBuffer.Resize(mesh.VertexBuffer.Count);
            }

            return(meshGroup);
        }
Example #3
0
        /// <summary>
        /// Meshを置き換える。
        ///
        /// src=null, dst!=null で追加。
        /// src!=null, dst=null で削除。
        /// </summary>
        /// <param name = "src">置き換え元</param>
        /// <param name = "dst">置き換え先</param>
        public void MeshReplace(MeshGroup src, MeshGroup dst)
        {
            // replace: Meshes
            if (src != null)
            {
                Model.MeshGroups.RemoveAll(x => x == src);
            }
            if (dst != null && !Model.MeshGroups.Contains(dst))
            {
                Model.MeshGroups.Add(dst);
            }

            // replace: Node.Mesh
            foreach (var node in Model.Nodes)
            {
                if (src != null && src == node.MeshGroup)
                {
                    node.MeshGroup = dst;
                }
            }

            // fix VRM
            if (Model.Vrm != null)
            {
                // replace: VrmBlendShape.Mesh
                if (Model.Vrm.BlendShape != null)
                {
                    foreach (var x in Model.Vrm.BlendShape.BlendShapeList)
                    {
                        for (int i = 0; i < x.BlendShapeValues.Count; ++i)
                        {
                            var v = x.BlendShapeValues[i];
                            if (src != null && src == v.Mesh)
                            {
                                v.Mesh = dst;
                            }
                        }
                    }
                }

                // replace: VrmFirstPerson.MeshAnnotations
                if (src != null)
                {
                    Model.Vrm.FirstPerson.Annotations.RemoveAll(x => x.Mesh == src);
                }
                if (dst != null && !Model.Vrm.FirstPerson.Annotations.Any(x => x.Mesh == dst))
                {
                    Model.Vrm.FirstPerson.Annotations.Add(
                        new FirstPersonMeshAnnotation(dst, FirstPersonMeshType.Auto));
                }
            }
        }
Example #4
0
        public static ValueTuple <MeshGroup, MeshGroup> SepareteByHeadBone(this MeshGroup g, HashSet <int> boneIndices)
        {
            if (g.Meshes.Count > 1)
            {
                throw new NotImplementedException("MeshGroup.Meshes.Count must 1");
            }

            var src = g.Meshes[0];

            if (src.Topology != TopologyType.Triangles)
            {
                throw new InvalidOperationException("not GltfPrimitiveMode.Triangles");
            }

            var(headTriangles, bodyTriangles) = MeshSplitter.SplitTrianglesByBoneIndices(src, boneIndices);

            MeshGroup head = default(MeshGroup);

            if (headTriangles.Any())
            {
                var mesh = MeshSplitter.SeparateMesh(src, headTriangles, true);
                head = new MeshGroup(g.Name + ".headMesh")
                {
                    Skin = g.Skin,
                };
                head.Meshes.Add(mesh);
            }

            MeshGroup body = default(MeshGroup);

            if (bodyTriangles.Any())
            {
                var mesh = MeshSplitter.SeparateMesh(src, bodyTriangles);
                body = new MeshGroup(g.Name)
                {
                    Skin = g.Skin,
                };
                body.Meshes.Add(mesh);
            }

            return(head, body);
        }
Example #5
0
        /// <summary>
        /// MorphTarget が有る Mesh と無い Mesh に分ける
        /// </summary>
        /// <param name="g"></param>
        /// <returns></returns>
        public static ValueTuple <MeshGroup, MeshGroup> SepareteByMorphTarget(this MeshGroup g)
        {
            if (g.Meshes.Count > 1)
            {
                throw new NotImplementedException("MeshGroup.Meshes.Count must 1");
            }

            var src = g.Meshes[0];

            if (src.Topology != TopologyType.Triangles)
            {
                throw new InvalidOperationException("not GltfPrimitiveMode.Triangles");
            }

            var(withTriangles, withoutTriangles) = MeshSplitter.SplitTriangles(src);

            MeshGroup with = default(MeshGroup);

            if (withTriangles.Any())
            {
                var mesh = MeshSplitter.SeparateMesh(src, withTriangles, true);
                with = new MeshGroup(g.Name + ".blendshape")
                {
                    Skin = g.Skin,
                };
                with.Meshes.Add(mesh);
            }

            MeshGroup without = default(MeshGroup);

            if (withoutTriangles.Any())
            {
                var mesh = MeshSplitter.SeparateMesh(src, withoutTriangles);
                without = new MeshGroup(g.Name)
                {
                    Skin = g.Skin,
                };
                without.Meshes.Add(mesh);
            }

            return(with, without);
        }
Example #6
0
        /// <summary>
        /// Meshを置き換える。
        ///
        /// src=null, dst!=null で追加。
        /// src!=null, dst=null で削除。
        /// </summary>
        /// <param name = "src">置き換え元</param>
        /// <param name = "dst">置き換え先</param>
        public void MeshReplace(MeshGroup src, MeshGroup dst)
        {
            // replace: Meshes
            if (src != null)
            {
                Model.MeshGroups.RemoveAll(x => x == src);
            }
            if (dst != null && !Model.MeshGroups.Contains(dst))
            {
                Model.MeshGroups.Add(dst);
            }

            // replace: Node.Mesh
            foreach (var node in Model.Nodes)
            {
                if (src != null && src == node.MeshGroup)
                {
                    node.MeshGroup = dst;
                }
            }
        }
Example #7
0
 public FirstPersonMeshAnnotation(MeshGroup mesh, FirstPersonMeshType flag)
 {
     Mesh            = mesh;
     FirstPersonFlag = flag;
 }
Example #8
0
        private static VrmLib.MeshGroup CreateMesh(UnityEngine.Mesh mesh, Renderer renderer, List <UnityEngine.Material> materials)
        {
            var meshGroup = new VrmLib.MeshGroup(mesh.name);
            var vrmMesh   = new VrmLib.Mesh();

            vrmMesh.VertexBuffer = new VrmLib.VertexBuffer();
            vrmMesh.VertexBuffer.Add(VrmLib.VertexBuffer.PositionKey, ToBufferAccessor(mesh.vertices));

            if (mesh.boneWeights.Length == mesh.vertexCount)
            {
                vrmMesh.VertexBuffer.Add(
                    VrmLib.VertexBuffer.WeightKey,
                    ToBufferAccessor(mesh.boneWeights.Select(x =>
                                                             new Vector4(x.weight0, x.weight1, x.weight2, x.weight3)).ToArray()
                                     ));
                vrmMesh.VertexBuffer.Add(
                    VrmLib.VertexBuffer.JointKey,
                    ToBufferAccessor(mesh.boneWeights.Select(x =>
                                                             new SkinJoints((ushort)x.boneIndex0, (ushort)x.boneIndex1, (ushort)x.boneIndex2, (ushort)x.boneIndex3)).ToArray()
                                     ));
            }
            if (mesh.uv.Length == mesh.vertexCount)
            {
                vrmMesh.VertexBuffer.Add(VrmLib.VertexBuffer.TexCoordKey, ToBufferAccessor(mesh.uv));
            }
            if (mesh.normals.Length == mesh.vertexCount)
            {
                vrmMesh.VertexBuffer.Add(VrmLib.VertexBuffer.NormalKey, ToBufferAccessor(mesh.normals));
            }
            if (mesh.colors.Length == mesh.vertexCount)
            {
                vrmMesh.VertexBuffer.Add(VrmLib.VertexBuffer.ColorKey, ToBufferAccessor(mesh.colors));
            }
            vrmMesh.IndexBuffer = ToBufferAccessor(mesh.triangles);

            int offset = 0;

            for (int i = 0; i < mesh.subMeshCount; i++)
            {
#if UNITY_2019
                var subMesh = mesh.GetSubMesh(i);
                try
                {
                    vrmMesh.Submeshes.Add(new VrmLib.Submesh(offset, subMesh.indexCount, materials.IndexOf(renderer.sharedMaterials[i])));
                }
                catch (Exception ex)
                {
                    Debug.LogError(ex);
                }
                offset += subMesh.indexCount;
#else
                var triangles = mesh.GetTriangles(i);
                try
                {
                    vrmMesh.Submeshes.Add(new VrmLib.Submesh(offset, triangles.Length, materials.IndexOf(renderer.sharedMaterials[i])));
                }
                catch (Exception ex)
                {
                    Debug.LogError(ex);
                }
                offset += triangles.Length;
#endif
            }

            for (int i = 0; i < mesh.blendShapeCount; i++)
            {
                var blendShapeVertices = mesh.vertices;
                var usePosition        = blendShapeVertices != null && blendShapeVertices.Length > 0;

                var blendShapeNormals = mesh.normals;
                var useNormal         = usePosition && blendShapeNormals != null && blendShapeNormals.Length == blendShapeVertices.Length;
                // var useNormal = usePosition && blendShapeNormals != null && blendShapeNormals.Length == blendShapeVertices.Length && !exportOnlyBlendShapePosition;

                var blendShapeTangents = mesh.tangents.Select(y => (Vector3)y).ToArray();
                //var useTangent = usePosition && blendShapeTangents != null && blendShapeTangents.Length == blendShapeVertices.Length;
                // var useTangent = false;

                var frameCount = mesh.GetBlendShapeFrameCount(i);
                mesh.GetBlendShapeFrameVertices(i, frameCount - 1, blendShapeVertices, blendShapeNormals, null);

                if (usePosition)
                {
                    var morphTarget = new VrmLib.MorphTarget(mesh.GetBlendShapeName(i));
                    morphTarget.VertexBuffer = new VrmLib.VertexBuffer();
                    morphTarget.VertexBuffer.Add(VrmLib.VertexBuffer.PositionKey, ToBufferAccessor(blendShapeVertices));
                    vrmMesh.MorphTargets.Add(morphTarget);
                }
            }

            meshGroup.Meshes.Add(vrmMesh);
            return(meshGroup);
        }
Example #9
0
 public BlendShapeBindValue(MeshGroup mesh, string name, float value)
 {
     Mesh  = mesh;
     Name  = name;
     Value = value;
 }