Beispiel #1
0
            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);
            }
Beispiel #2
0
 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));
     }
 }
Beispiel #3
0
	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();
 }
Beispiel #6
0
        /// <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);
        }
Beispiel #7
0
        /// <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);
        }
Beispiel #8
0
        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);
        }