static UnityEngine.Mesh CopyMesh(UnityEngine.Mesh src, bool copyBlendShape = false) { var dst = new UnityEngine.Mesh(); dst.name = src.name + "(copy)"; #if UNITY_2017_3_OR_NEWER dst.indexFormat = src.indexFormat; #endif dst.vertices = src.vertices; dst.normals = src.normals; dst.tangents = src.tangents; dst.colors = src.colors; dst.uv = src.uv; dst.uv2 = src.uv2; dst.uv3 = src.uv3; dst.uv4 = src.uv4; dst.boneWeights = src.boneWeights; dst.bindposes = src.bindposes; dst.subMeshCount = src.subMeshCount; for (int i = 0; i < dst.subMeshCount; ++i) { dst.SetIndices(src.GetIndices(i), src.GetTopology(i), i); } dst.RecalculateBounds(); if (copyBlendShape) { var vertices = src.vertices; var normals = src.normals; #if VRM_NORMALIZE_BLENDSHAPE_TANGENT var tangents = src.tangents.Select(x => (Vector3)x).ToArray(); #else Vector3[] tangents = null; #endif for (int i = 0; i < src.blendShapeCount; ++i) { src.GetBlendShapeFrameVertices(i, 0, vertices, normals, tangents); dst.AddBlendShapeFrame( src.GetBlendShapeName(i), src.GetBlendShapeFrameWeight(i, 0), vertices, normals, tangents ); } } return(dst); }
static int AddBlendShapeFrame(IntPtr L) { try { ToLua.CheckArgsCount(L, 6); UnityEngine.Mesh obj = (UnityEngine.Mesh)ToLua.CheckObject(L, 1, typeof(UnityEngine.Mesh)); string arg0 = ToLua.CheckString(L, 2); float arg1 = (float)LuaDLL.luaL_checknumber(L, 3); UnityEngine.Vector3[] arg2 = ToLua.CheckObjectArray <UnityEngine.Vector3>(L, 4); UnityEngine.Vector3[] arg3 = ToLua.CheckObjectArray <UnityEngine.Vector3>(L, 5); UnityEngine.Vector3[] arg4 = ToLua.CheckObjectArray <UnityEngine.Vector3>(L, 6); obj.AddBlendShapeFrame(arg0, arg1, arg2, arg3, arg4); return(0); } catch (Exception e) { return(LuaDLL.toluaL_exception(L, e)); } }
static public int AddBlendShapeFrame(IntPtr l) { try { UnityEngine.Mesh self=(UnityEngine.Mesh)checkSelf(l); System.String a1; checkType(l,2,out a1); System.Single a2; checkType(l,3,out a2); UnityEngine.Vector3[] a3; checkArray(l,4,out a3); UnityEngine.Vector3[] a4; checkArray(l,5,out a4); UnityEngine.Vector3[] a5; checkArray(l,6,out a5); self.AddBlendShapeFrame(a1,a2,a3,a4,a5); pushValue(l,true); return 1; } catch(Exception e) { return error(l,e); } }
protected virtual void CreateMeshPrimitive(MeshPrimitive primitive, string meshName, int meshID, int primitiveIndex) { var meshAttributes = BuildMeshAttributes(primitive, meshID, primitiveIndex); var vertexCount = primitive.Attributes[SemanticProperties.POSITION].Value.Count; UnityEngine.Mesh mesh = new UnityEngine.Mesh { vertices = primitive.Attributes.ContainsKey(SemanticProperties.POSITION) ? meshAttributes[SemanticProperties.POSITION].AccessorContent.AsVertices.ToUnityVector3() : null, normals = primitive.Attributes.ContainsKey(SemanticProperties.NORMAL) ? meshAttributes[SemanticProperties.NORMAL].AccessorContent.AsNormals.ToUnityVector3() : null, uv = primitive.Attributes.ContainsKey(SemanticProperties.TexCoord(0)) ? meshAttributes[SemanticProperties.TexCoord(0)].AccessorContent.AsTexcoords.ToUnityVector2() : null, uv2 = primitive.Attributes.ContainsKey(SemanticProperties.TexCoord(1)) ? meshAttributes[SemanticProperties.TexCoord(1)].AccessorContent.AsTexcoords.ToUnityVector2() : null, uv3 = primitive.Attributes.ContainsKey(SemanticProperties.TexCoord(2)) ? meshAttributes[SemanticProperties.TexCoord(2)].AccessorContent.AsTexcoords.ToUnityVector2() : null, uv4 = primitive.Attributes.ContainsKey(SemanticProperties.TexCoord(3)) ? meshAttributes[SemanticProperties.TexCoord(3)].AccessorContent.AsTexcoords.ToUnityVector2() : null, colors = primitive.Attributes.ContainsKey(SemanticProperties.Color(0)) ? meshAttributes[SemanticProperties.Color(0)].AccessorContent.AsColors.ToUnityColor() : null, triangles = primitive.Indices != null ? meshAttributes[SemanticProperties.INDICES].AccessorContent.AsTriangles : MeshPrimitive.GenerateTriangles(vertexCount), tangents = primitive.Attributes.ContainsKey(SemanticProperties.TANGENT) ? meshAttributes[SemanticProperties.TANGENT].AccessorContent.AsTangents.ToUnityVector4(true) : null }; if (primitive.Attributes.ContainsKey(SemanticProperties.JOINT) && primitive.Attributes.ContainsKey(SemanticProperties.WEIGHT)) { Vector4[] bones = new Vector4[1]; Vector4[] weights = new Vector4[1]; LoadSkinnedMeshAttributes(meshID, primitiveIndex, ref bones, ref weights); if (bones.Length != mesh.vertices.Length || weights.Length != mesh.vertices.Length) { Debug.LogError("Not enough skinning data (bones:" + bones.Length + " weights:" + weights.Length + " verts:" + mesh.vertices.Length + ")"); return; } BoneWeight[] bws = new BoneWeight[mesh.vertices.Length]; int maxBonesIndex = 0; for (int i = 0; i < bws.Length; ++i) { // Unity seems expects the the sum of weights to be 1. float[] normalizedWeights = GLTFUtils.normalizeBoneWeights(weights[i]); bws[i].boneIndex0 = (int)bones[i].x; bws[i].weight0 = normalizedWeights[0]; bws[i].boneIndex1 = (int)bones[i].y; bws[i].weight1 = normalizedWeights[1]; bws[i].boneIndex2 = (int)bones[i].z; bws[i].weight2 = normalizedWeights[2]; bws[i].boneIndex3 = (int)bones[i].w; bws[i].weight3 = normalizedWeights[3]; maxBonesIndex = (int)Mathf.Max(maxBonesIndex, bones[i].x, bones[i].y, bones[i].z, bones[i].w); } mesh.boneWeights = bws; // initialize inverseBindMatrix array with identity matrix in order to output a valid mesh object Matrix4x4[] bindposes = new Matrix4x4[maxBonesIndex + 1]; for (int j = 0; j <= maxBonesIndex; ++j) { bindposes[j] = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, Vector3.one); } mesh.bindposes = bindposes; } if (primitive.Targets != null && primitive.Targets.Count > 0) { for (int b = 0; b < primitive.Targets.Count; ++b) { Vector3[] deltaVertices = new Vector3[primitive.Targets[b]["POSITION"].Value.Count]; Vector3[] deltaNormals = new Vector3[primitive.Targets[b]["POSITION"].Value.Count]; Vector3[] deltaTangents = new Vector3[primitive.Targets[b]["POSITION"].Value.Count]; if (primitive.Targets[b].ContainsKey("POSITION")) { NumericArray num = new NumericArray(); deltaVertices = primitive.Targets[b]["POSITION"].Value.AsVector3Array(ref num, _assetCache.BufferCache[0], false).ToUnityVector3(true); } if (primitive.Targets[b].ContainsKey("NORMAL")) { NumericArray num = new NumericArray(); deltaNormals = primitive.Targets[b]["NORMAL"].Value.AsVector3Array(ref num, _assetCache.BufferCache[0], true).ToUnityVector3(true); } //if (primitive.Targets[b].ContainsKey("TANGENT")) //{ // deltaTangents = primitive.Targets[b]["TANGENT"].Value.AsVector3Array(ref num, _assetCache.BufferCache[0], true).ToUnityVector3(true); //} mesh.AddBlendShapeFrame(GLTFUtils.buildBlendShapeName(meshID, b), 1.0f, deltaVertices, deltaNormals, deltaTangents); } } mesh.RecalculateBounds(); mesh.RecalculateTangents(); mesh = _assetManager.saveMesh(mesh, meshName + "_" + meshID + "_" + primitiveIndex); UnityEngine.Material material = primitive.Material != null && primitive.Material.Id >= 0 ? getMaterial(primitive.Material.Id) : defaultMaterial; _assetManager.addPrimitiveMeshData(meshID, primitiveIndex, mesh, material); }
public void AddToMesh(Mesh mesh, string name) { Profiler.BeginSample("AddBlendShapeFrame"); mesh.AddBlendShapeFrame(name, 1f, positions, normals, tangents); Profiler.EndSample(); }
/// <summary> /// VrmLib.Mesh => UnityEngine.Mesh /// </summary> /// <param name="mesh"></param> /// <param name="src"></param> /// <param name="skin"></param> public static UnityEngine.Mesh LoadSharedMesh(VrmLib.Mesh src, VrmLib.Skin skin = null) { // submesh 方式 var mesh = new UnityEngine.Mesh(); mesh.vertices = src.VertexBuffer.Positions.GetSpan <Vector3>().ToArray(); mesh.normals = src.VertexBuffer.Normals?.GetSpan <Vector3>().ToArray(); mesh.uv = src.VertexBuffer.TexCoords?.GetSpan <Vector2>().ToArray(); mesh.colors = src.VertexBuffer.Colors?.GetSpan <Color>().ToArray(); if (src.VertexBuffer.Weights != null && src.VertexBuffer.Joints != null) { var boneWeights = new BoneWeight[mesh.vertexCount]; if (src.VertexBuffer.Weights.Count != mesh.vertexCount || src.VertexBuffer.Joints.Count != mesh.vertexCount) { throw new ArgumentException(); } var weights = src.VertexBuffer.Weights.GetSpan <Vector4>(); var joints = src.VertexBuffer.Joints.GetSpan <VrmLib.SkinJoints>(); if (skin != null) { mesh.bindposes = skin.InverseMatrices.GetSpan <Matrix4x4>().ToArray(); } for (int i = 0; i < weights.Length; ++i) { var w = weights[i]; boneWeights[i].weight0 = w.x; boneWeights[i].weight1 = w.y; boneWeights[i].weight2 = w.z; boneWeights[i].weight3 = w.w; } for (int i = 0; i < joints.Length; ++i) { var j = joints[i]; boneWeights[i].boneIndex0 = j.Joint0; boneWeights[i].boneIndex1 = j.Joint1; boneWeights[i].boneIndex2 = j.Joint2; boneWeights[i].boneIndex3 = j.Joint3; } mesh.boneWeights = boneWeights; } mesh.subMeshCount = src.Submeshes.Count; var triangles = src.IndexBuffer.GetAsIntList(); for (int i = 0; i < src.Submeshes.Count; ++i) { var submesh = src.Submeshes[i]; mesh.SetTriangles(triangles.GetRange(submesh.Offset, submesh.DrawCount), i); } foreach (var morphTarget in src.MorphTargets) { var positions = morphTarget.VertexBuffer.Positions != null ? morphTarget.VertexBuffer.Positions.GetSpan <Vector3>().ToArray() : new Vector3[mesh.vertexCount] // dummy ; mesh.AddBlendShapeFrame(morphTarget.Name, 100.0f, positions, null, null); } mesh.RecalculateBounds(); mesh.RecalculateTangents(); return(mesh); }
/// <summary> /// VrmLib.Mesh => UnityEngine.Mesh /// </summary> /// <param name="mesh"></param> /// <param name="src"></param> /// <param name="skin"></param> public static Mesh LoadSharedMesh(VrmLib.Mesh src, Skin skin = null) { Profiler.BeginSample("MeshImporterShared.LoadSharedMesh"); var mesh = new Mesh(); var positions = src.VertexBuffer.Positions.Bytes.Reinterpret <Vector3>(1); var normals = src.VertexBuffer.Normals?.Bytes.Reinterpret <Vector3>(1) ?? default; var texCoords = src.VertexBuffer.TexCoords?.Bytes.Reinterpret <Vector2>(1) ?? default; var colors = src.VertexBuffer.Colors?.Bytes.Reinterpret <Color>(1) ?? default; var weights = src.VertexBuffer.Weights?.GetAsVector4Array() ?? default; var joints = src.VertexBuffer.Joints?.GetAsSkinJointsArray() ?? default; using (var vertices = new NativeArray <MeshVertex>(positions.Length, Allocator.TempJob)) { // JobとBindPoseの更新を並行して行う var jobHandle = new InterleaveMeshVerticesJob(vertices, positions, normals, texCoords, colors, weights, joints) .Schedule(vertices.Length, 1); JobHandle.ScheduleBatchedJobs(); // BindPoseを更新 if (weights.IsCreated && joints.IsCreated) { if (weights.Length != positions.Length || joints.Length != positions.Length) { throw new ArgumentException(); } if (skin != null) { mesh.bindposes = skin.InverseMatrices.GetSpan <Matrix4x4>().ToArray(); } } // Jobを完了 jobHandle.Complete(); // 頂点を更新 MeshVertex.SetVertexBufferParamsToMesh(mesh, vertices.Length); mesh.SetVertexBufferData(vertices, 0, 0, vertices.Length); // 出力のNativeArrayを開放 } // Indexを更新 switch (src.IndexBuffer.ComponentType) { case AccessorValueType.UNSIGNED_BYTE: { var intIndices = src.IndexBuffer.GetAsIntArray(); mesh.SetIndexBufferParams(intIndices.Length, IndexFormat.UInt32); mesh.SetIndexBufferData(intIndices, 0, 0, intIndices.Length); break; } case AccessorValueType.UNSIGNED_SHORT: { var shortIndices = src.IndexBuffer.Bytes.Reinterpret <ushort>(1); mesh.SetIndexBufferParams(shortIndices.Length, IndexFormat.UInt16); mesh.SetIndexBufferData(shortIndices, 0, 0, shortIndices.Length); break; } case AccessorValueType.UNSIGNED_INT: { var intIndices = src.IndexBuffer.Bytes.Reinterpret <uint>(1); mesh.SetIndexBufferParams(intIndices.Length, IndexFormat.UInt32); mesh.SetIndexBufferData(intIndices, 0, 0, intIndices.Length); break; } default: throw new NotImplementedException(); } // SubMeshを更新 mesh.subMeshCount = src.Submeshes.Count; for (var i = 0; i < src.Submeshes.Count; ++i) { var subMesh = src.Submeshes[i]; mesh.SetSubMesh(i, new SubMeshDescriptor(subMesh.Offset, subMesh.DrawCount)); } // MorphTargetを更新 foreach (var morphTarget in src.MorphTargets) { var morphTargetPositions = morphTarget.VertexBuffer.Positions != null ? morphTarget.VertexBuffer.Positions.GetSpan <Vector3>().ToArray() : new Vector3[mesh.vertexCount] // dummy ; mesh.AddBlendShapeFrame(morphTarget.Name, 100.0f, morphTargetPositions, null, null); } // 各種パラメーターを再計算 mesh.RecalculateBounds(); mesh.RecalculateTangents(); if (src.VertexBuffer.Normals == null) { mesh.RecalculateNormals(); } Profiler.EndSample(); return(mesh); }
public static Mesh LoadDivided(MeshGroup meshGroup) { Profiler.BeginSample("MeshImporterDivided.LoadDivided"); var vertexCount = meshGroup.Meshes.Sum(mesh => mesh.VertexBuffer.Count); var indexCount = meshGroup.Meshes.Sum(mesh => mesh.IndexBuffer.Count); var resultMesh = new Mesh(); // 頂点バッファ・BindPoseを構築して更新 UpdateVerticesAndBindPose(meshGroup, vertexCount, resultMesh); // インデックスバッファを構築して更新 UpdateIndices(meshGroup, vertexCount, indexCount, resultMesh); // SubMeshを更新 resultMesh.subMeshCount = meshGroup.Meshes.Count; var indexOffset = 0; for (var i = 0; i < meshGroup.Meshes.Count; ++i) { var mesh = meshGroup.Meshes[i]; resultMesh.SetSubMesh(i, new SubMeshDescriptor(indexOffset, mesh.IndexBuffer.Count)); indexOffset += mesh.IndexBuffer.Count; } // 各種データを再構築 resultMesh.RecalculateBounds(); resultMesh.RecalculateTangents(); if (meshGroup.Meshes.Any(mesh => mesh.VertexBuffer.Normals == null)) { resultMesh.RecalculateNormals(); } // BlendShapeを更新 var blendShapeCount = meshGroup.Meshes[0].MorphTargets.Count; for (var i = 0; i < blendShapeCount; ++i) { var positionsCount = 0; var normalsCount = 0; foreach (var mesh in meshGroup.Meshes) { var morphTarget = mesh.MorphTargets[i]; positionsCount += morphTarget.VertexBuffer.Positions.Count; normalsCount += morphTarget.VertexBuffer.Normals?.Count ?? morphTarget.VertexBuffer.Count; } using (var blendShapePositions = new NativeArray <Vector3>(positionsCount, Allocator.Temp)) using (var blendShapeNormals = new NativeArray <Vector3>(normalsCount, Allocator.Temp)) { var blendShapePositionOffset = 0; var blendShapeNormalOffset = 0; foreach (var mesh in meshGroup.Meshes) { var morphTarget = mesh.MorphTargets[i]; NativeArray <Vector3> .Copy( morphTarget.VertexBuffer.Positions.Bytes.Reinterpret <Vector3>(1), blendShapePositions.GetSubArray(blendShapePositionOffset, morphTarget.VertexBuffer.Positions.Count)); if (morphTarget.VertexBuffer.Normals != null) { // nullならdefault(0)のまま NativeArray <Vector3> .Copy( morphTarget.VertexBuffer.Normals.Bytes.Reinterpret <Vector3>(1), blendShapeNormals.GetSubArray(blendShapeNormalOffset, morphTarget.VertexBuffer.Normals.Count)); } blendShapePositionOffset += morphTarget.VertexBuffer.Positions.Count; blendShapeNormalOffset += morphTarget.VertexBuffer.Normals?.Count ?? morphTarget.VertexBuffer.Count; } resultMesh.AddBlendShapeFrame(meshGroup.Meshes[0].MorphTargets[i].Name, 100.0f, blendShapePositions.ToArray(), blendShapeNormals.ToArray(), null); } } Profiler.EndSample(); return(resultMesh); }
public static UnityEngine.Mesh LoadDivided(VrmLib.MeshGroup src) { var dst = new UnityEngine.Mesh(); // // vertices // var vertexCount = src.Meshes.Sum(x => x.VertexBuffer.Count); var positions = new List <Vector3>(vertexCount); var normals = new List <Vector3>(vertexCount); var uv = new List <Vector2>(vertexCount); var boneWeights = new List <BoneWeight>(vertexCount); for (int meshIndex = 0; meshIndex < src.Meshes.Count; ++meshIndex) { var mesh = src.Meshes[meshIndex]; positions.AddRange(mesh.VertexBuffer.Positions.GetSpan <Vector3>()); normals.AddRange(mesh.VertexBuffer.Normals.GetSpan <Vector3>()); uv.AddRange(mesh.VertexBuffer.TexCoords.GetSpan <Vector2>()); if (src.Skin != null) { var j = mesh.VertexBuffer.Joints.GetSpan <VrmLib.SkinJoints>(); var w = mesh.VertexBuffer.Weights.GetSpan <Vector4>(); for (int i = 0; i < mesh.VertexBuffer.Count; ++i) { var jj = j[i]; var ww = w[i]; boneWeights.Add(new BoneWeight { boneIndex0 = jj.Joint0, boneIndex1 = jj.Joint1, boneIndex2 = jj.Joint2, boneIndex3 = jj.Joint3, weight0 = ww.x, weight1 = ww.y, weight2 = ww.z, weight3 = ww.w, }); } } } dst.name = src.Name; dst.vertices = positions.ToArray(); dst.normals = normals.ToArray(); dst.uv = uv.ToArray(); if (src.Skin != null) { dst.boneWeights = boneWeights.ToArray(); } // // skin // if (src.Skin != null) { dst.bindposes = src.Skin.InverseMatrices.GetSpan <Matrix4x4>().ToArray(); } // // triangles // dst.subMeshCount = src.Meshes.Count; var offset = 0; for (int meshIndex = 0; meshIndex < src.Meshes.Count; ++meshIndex) { var mesh = src.Meshes[meshIndex]; var indices = mesh.IndexBuffer.GetAsIntArray().Select(x => offset + x).ToArray(); dst.SetTriangles(indices, meshIndex); offset += mesh.VertexBuffer.Count; } dst.RecalculateBounds(); dst.RecalculateTangents(); // // blendshape // var blendShapeCount = src.Meshes[0].MorphTargets.Count; for (int i = 0; i < blendShapeCount; ++i) { positions.Clear(); normals.Clear(); var name = src.Meshes[0].MorphTargets[i].Name; for (int meshIndex = 0; meshIndex < src.Meshes.Count; ++meshIndex) { var morphTarget = src.Meshes[meshIndex].MorphTargets[i]; positions.AddRange(morphTarget.VertexBuffer.Positions.GetSpan <Vector3>()); if (morphTarget.VertexBuffer.Normals != null) { normals.AddRange(morphTarget.VertexBuffer.Normals.GetSpan <Vector3>()); } else { // fill zero normals.AddRange(Enumerable.Range(0, morphTarget.VertexBuffer.Count).Select(x => Vector3.zero)); } } dst.AddBlendShapeFrame(name, 100.0f, positions.ToArray(), normals.ToArray(), null); } return(dst); }