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); }
/// <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)); } } }
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); }
/// <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); }
/// <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; } } }
public FirstPersonMeshAnnotation(MeshGroup mesh, FirstPersonMeshType flag) { Mesh = mesh; FirstPersonFlag = flag; }
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); }
public BlendShapeBindValue(MeshGroup mesh, string name, float value) { Mesh = mesh; Name = name; Value = value; }