Beispiel #1
0
        public static VertexData getVertexData(Mesh mesh, int index, WXMeshVertexLayout vertexLayout)
        {
            VertexData result = default(VertexData);

            result.index   = index;
            result.vertice = mesh.vertices[index];
            if (vertexLayout.NORMAL)
            {
                result.normal = mesh.normals[index];
            }
            else
            {
                result.normal = default(Vector3);
            }
            if (vertexLayout.COLOR)
            {
                result.color = mesh.colors[index];
            }
            else
            {
                result.color = default(Color);
            }
            if (vertexLayout.UV)
            {
                result.uv = mesh.uv[index];
            }
            else
            {
                result.uv = default(Vector2);
            }
            if (vertexLayout.UV1)
            {
                result.uv2 = mesh.uv2[index];
            }
            else
            {
                result.uv2 = default(Vector2);
            }
            if (vertexLayout.BONE)
            {
                BoneWeight boneWeight = mesh.boneWeights[index];
                result.boneWeight.x = boneWeight.weight0;
                result.boneWeight.y = boneWeight.weight1;
                result.boneWeight.z = boneWeight.weight2;
                result.boneWeight.w = boneWeight.weight3;
                result.boneIndex.x  = (float)boneWeight.boneIndex0;
                result.boneIndex.y  = (float)boneWeight.boneIndex1;
                result.boneIndex.z  = (float)boneWeight.boneIndex2;
                result.boneIndex.w  = (float)boneWeight.boneIndex3;
            }
            else
            {
                result.boneWeight = default(Vector4);
                result.boneIndex  = default(Vector4);
            }
            if (vertexLayout.TANGENT)
            {
                result.tangent = mesh.tangents[index];
            }
            else
            {
                result.tangent = default(Vector4);
            }
            return(result);
        }
Beispiel #2
0
        private byte[] WriteMeshFile(ref JSONObject metadata)
        {
            MemoryStream fileStream = new MemoryStream();

            //ushort subMeshCount = (ushort)mesh.subMeshCount;
            string item = meshName;

            // 分析vertexLayout
            WXMeshVertexLayout vertexLayout = new WXMeshVertexLayout(mesh);

            List <Transform> bones = new List <Transform>();

            for (int j = 0; j < renderer.bones.Length; j++)
            {
                Transform item2 = renderer.bones[j];
                if (bones.IndexOf(item2) == -1)
                {
                    bones.Add(item2);
                }
            }

            //List<VertexData> vertexDatas = new List<VertexData>();
            //List<VertexData> boneGroupVertex = new List<VertexData>();
            //List<VertexData> vertexDataQueue = new List<VertexData>();
            //int[] positionInBoneGroup = new int[3];
            //List<int> indiceList = new List<int>();
            //List<int> allBoneIndexes = new List<int>();
            //List<int> vertexUsingBone = new List<int>();
            //VertexData vertexData;
            //for (int i = 0; i < subMeshCount; i++)
            //{
            //    int[] indices = mesh.GetIndices(i);
            //    for (int indiceIter = 0; indiceIter < indices.Length; indiceIter += 3)
            //    {
            //        // indice start
            //        for (int k = 0; k < 3; k++)
            //        {
            //            int indiceIndex = indiceIter + k;
            //            int vertexIndex = indices[indiceIndex];
            //            positionInBoneGroup[k] = -1;
            //            int ii = 0;
            //            while (ii < boneGroupVertex.Count)
            //            {
            //                if (boneGroupVertex[ii].index == vertexIndex)
            //                {
            //                    positionInBoneGroup[k] = ii;
            //                    break;
            //                }
            //                ii++;
            //                continue;
            //            }
            //            if (positionInBoneGroup[k] == -1)
            //            {
            //                vertexData = getVertexData(mesh, vertexIndex, vertexLayout);
            //                vertexDataQueue.Add(vertexData);
            //                // 每个点最多关联4根骨骼,所以遍历4下
            //                for (ii = 0; ii < 4; ii++)
            //                {
            //                    float bone = vertexData.boneIndex[ii];
            //                    if (allBoneIndexes.IndexOf((int)bone) == -1 && vertexUsingBone.IndexOf((int)bone) == -1)
            //                    {
            //                        vertexUsingBone.Add((int)bone);
            //                    }
            //                }
            //            }
            //        }
            //        // 没到达最大骨骼数 目前不知道这个24最大骨骼限制是干嘛用的
            //        if (allBoneIndexes.Count + vertexUsingBone.Count <= MaxBoneCount)
            //        {
            //            for (int l = 0; l < vertexUsingBone.Count; l++)
            //            {
            //                allBoneIndexes.Add(vertexUsingBone[l]);
            //            }
            //            int num8 = 1;
            //            for (int l = 0; l < 3; l++)
            //            {
            //                if (positionInBoneGroup[l] == -1)
            //                {
            //                    indiceList.Add(vertexDatas.Count + boneGroupVertex.Count - 1 + num8++);
            //                }
            //                else
            //                {
            //                    indiceList.Add(vertexDatas.Count + positionInBoneGroup[l]);
            //                }
            //            }
            //            for (int l = 0; l < vertexDataQueue.Count; l++)
            //            {
            //                boneGroupVertex.Add(vertexDataQueue[l]);
            //            }
            //        }
            //        else
            //        {
            //            for (int l = 0; l < boneGroupVertex.Count; l++)
            //            {
            //                vertexDatas.Add(boneGroupVertex[l]);
            //            }
            //            // 回退一位?
            //            indiceIter -= 3;
            //            boneGroupVertex = new List<VertexData>();
            //            allBoneIndexes = new List<int>();
            //        }

            //        // 最后一个face了
            //        if (indiceIter + 3 == indices.Length)
            //        {
            //            for (int l = 0; l < boneGroupVertex.Count; l++)
            //            {
            //                vertexDatas.Add(boneGroupVertex[l]);
            //            }
            //            boneGroupVertex = new List<VertexData>();
            //            allBoneIndexes = new List<int>();
            //        }
            //        vertexUsingBone = new List<int>();
            //        vertexDataQueue = new List<VertexData>();
            //        // indice end
            //    }
            //}
            long vertexStart     = 0L;
            long vertexLength    = 0L;
            long indiceStart     = 0L;
            long indiceLength    = 0L;
            long boneEndPosition = 0L;

            // 记录vertexBuffer在总buffer里的起始位置,一般是0
            vertexStart = fileStream.Position;
            // 用于算包围球,计算模型的重心(所有点的位置均值)
            Vector3 vertexPositionAddup = new Vector3(0, 0, 0);

            // 遍历mesh里的所有定点
            for (int j = 0; j < mesh.vertexCount; j++)
            {
                Vector3 vector = mesh.vertices[j];

                // 写入position
                wxFileUtil.WriteData(fileStream, vector.x * -1f, vector.y, vector.z);
                // 统计position,用于算包围盒
                vertexPositionAddup.Set(vertexPositionAddup.x + vector.x * -1f, vertexPositionAddup.y + vector.y, vertexPositionAddup.z + vector.z);

                // 如果vertexLayout有normal,写入normal
                if (vertexLayout.NORMAL)
                {
                    Vector3 vector2 = mesh.normals[j];
                    wxFileUtil.WriteData(fileStream, vector2.x * -1f, vector2.y, vector2.z);
                }
                // 如果vertexLayout有color,写入color
                if (vertexLayout.COLOR)
                {
                    Color color = mesh.colors[j];
                    wxFileUtil.WriteData(fileStream, color.r, color.g, color.b, color.a);
                }
                // 如果vertexLayout有uv,写入uv
                if (vertexLayout.UV)
                {
                    Vector2 vector3 = mesh.uv[j];
                    wxFileUtil.WriteData(fileStream, vector3.x, vector3.y * -1f + 1f);
                }
                // 如果vertexLayout有uv1,写入uv1
                if (vertexLayout.UV1)
                {
                    Vector2 vector4 = mesh.uv2[j];
                    wxFileUtil.WriteData(fileStream, vector4.x, vector4.y * -1f + 1f);
                }
                if (vertexLayout.BONE)
                {
                    BoneWeight boneWeight = mesh.boneWeights[j];
                    wxFileUtil.WriteData(
                        fileStream,
                        boneWeight.weight0,
                        boneWeight.weight1,
                        boneWeight.weight2,
                        boneWeight.weight3
                        );
                    wxFileUtil.WriteData(
                        fileStream,
                        (float)boneWeight.boneIndex0,
                        (float)boneWeight.boneIndex1,
                        (float)boneWeight.boneIndex2,
                        (float)boneWeight.boneIndex3
                        );
                }
                // 如果vertexLayout有tangent,写入tangent
                if (vertexLayout.TANGENT)
                {
                    Vector4 vector5 = mesh.tangents[j];
                    wxFileUtil.WriteData(fileStream, vector5.x * -1f, vector5.y, vector5.z, vector5.w);
                }
            }
            // 记录vertexBuffer在buffer里的结束位置
            vertexLength = fileStream.Position - vertexStart;

            // 记录indiceBuffer在buffer里的起始位置
            indiceStart = fileStream.Position;
            // indiceBuffer指的是给模型绘制面时,每个面所用的顶点index。在unity里叫triangles
            int[] triangles = mesh.triangles;
            for (int j = 0; j < triangles.Length; j++)
            {
                wxFileUtil.WriteData(fileStream, (ushort)triangles[j]);
            }
            // 记录indexBuffer在buffer里的结束位置
            indiceLength = fileStream.Position - indiceStart;

            // 因为读取的时候是根据4位来读的所以末尾补0
            long isFour = indiceLength % 4;

            if (isFour != 0)
            {
                wxFileUtil.WriteData(fileStream, (ushort)0.0);
            }

            long boneStartPosition = fileStream.Position;

            if (mesh.bindposes != null && mesh.bindposes.Length != 0)
            {
                Matrix4x4[] bonePoses = new Matrix4x4[mesh.bindposes.Length];
                for (int i = 0; i < mesh.bindposes.Length; i++)
                {
                    bonePoses[i] = mesh.bindposes[i];
                    bonePoses[i] = bonePoses[i].inverse;
                    Vector3    s   = default(Vector3);
                    Quaternion q   = default(Quaternion);
                    Vector3    pos = default(Vector3);
                    MathUtil.Decompose(bonePoses[i].transpose, out s, out q, out pos);
                    pos.x       *= -1f;
                    q.x         *= -1f;
                    q.w         *= -1f;
                    bonePoses[i] = Matrix4x4.TRS(pos, q, s);
                }
                for (int i = 0; i < mesh.bindposes.Length; i++)
                {
                    Matrix4x4 matrix4x = bonePoses[i];
                }
                for (int i = 0; i < mesh.bindposes.Length; i++)
                {
                    Matrix4x4 inverse = bonePoses[i].inverse;
                    for (int j = 0; j < 16; j++)
                    {
                        wxFileUtil.WriteData(fileStream, inverse[j]);
                    }
                }
                boneEndPosition = fileStream.Position;
            }
            long bonePoseLength = boneEndPosition - boneStartPosition;

            fileStream.Close();

            metadata.AddField("indiceFormat", 1);                              //   BIT16 = 1,BIT32 = 2
            metadata.AddField("vertexLayout", vertexLayout.GetLayoutString()); //"POSITION,NORMAL,COLOR,UV,BLENDWEIGHT,BLENDINDICES,TANGENT",
            metadata.AddField("vertexStart", 0);
            metadata.AddField("vertexLength", vertexLength);
            metadata.AddField("indiceStart", vertexLength);  // indice的偏移量
            metadata.AddField("indiceLength", indiceLength); // indice的长度
            metadata.AddField("bonePoseStart", boneStartPosition);
            metadata.AddField("bonePoseLength", bonePoseLength);
            metadata.AddField("capsule", GetCapsule());

            bool       succ        = false;
            JSONObject bonesObject = GetSkinPaths(renderer.sharedMesh.name, ref succ);

            metadata.AddField("rootBone", bonesObject.GetField("root"));
            metadata.AddField("bones", bonesObject.GetField("bones"));
            metadata.AddField("version", 1);

            // 加入submesh
            JSONObject subMeshs = new JSONObject(JSONObject.Type.ARRAY);

#if !UNITY_2017_1_OR_NEWER
            int indexStart = 0;
#endif
            ushort subMeshCount = (ushort)mesh.subMeshCount;
            for (int i = 0; i < subMeshCount; i++)
            {
                JSONObject subMeshObj = new JSONObject(JSONObject.Type.OBJECT);
#if !UNITY_2017_1_OR_NEWER
                subMeshObj.AddField("start", indexStart);
                subMeshObj.AddField("length", mesh.GetIndices(i).Length);
                indexStart += mesh.GetIndices(i).Length;
#else
                subMeshObj.AddField("start", mesh.GetIndexStart(i));
                subMeshObj.AddField("length", mesh.GetIndexCount(i));
#endif
                subMeshs.Add(subMeshObj);
            }
            // submesh一般指的是mesh里的其中一部分,所以用indiceBuffer的区间表示
            metadata.AddField("subMeshs", subMeshs);

            return(fileStream.ToArray());
        }
        private byte[] WriteMeshFile(ref JSONObject metadata)
        {
            MemoryStream fileStream = new MemoryStream();

            string             meshName     = mesh.name;
            WXMeshVertexLayout vertexLayout = new WXMeshVertexLayout(mesh);
            ushort             subMeshCount = (ushort)mesh.subMeshCount;

            long vertexStart  = 0L;
            long vertexLength = 0L;
            long indiceStart  = 0L;
            long indiceLength = 0L;

            vertexStart = fileStream.Position;
            Vector3 vertexPositionMax = new Vector3(0, 0, 0);

            for (int j = 0; j < mesh.vertexCount; j++)
            {
                Vector3 vector = mesh.vertices[j];
                wxFileUtil.WriteData(fileStream, vector.x * -1f, vector.y, vector.z);
                vertexPositionMax.Set(vertexPositionMax.x + vector.x * -1f, vertexPositionMax.y + vector.y, vertexPositionMax.z + vector.z);

                if (vertexLayout.NORMAL)
                {
                    Vector3 vector2 = mesh.normals[j];
                    wxFileUtil.WriteData(fileStream, vector2.x * -1f, vector2.y, vector2.z);
                }
                if (vertexLayout.COLOR)
                {
                    Color color = mesh.colors[j];
                    wxFileUtil.WriteData(fileStream, color.r, color.g, color.b, color.a);
                }
                if (vertexLayout.UV)
                {
                    Vector2 vector3 = mesh.uv[j];
                    wxFileUtil.WriteData(fileStream, vector3.x, vector3.y * -1f + 1f);
                }
                if (vertexLayout.UV1)
                {
                    Vector2 vector4 = mesh.uv2[j];
                    wxFileUtil.WriteData(fileStream, vector4.x, vector4.y * -1f + 1f);
                }
                if (vertexLayout.TANGENT)
                {
                    Vector4 vector5 = mesh.tangents[j];
                    wxFileUtil.WriteData(fileStream, vector5.x * -1f, vector5.y, vector5.z, vector5.w);
                }
            }
            vertexLength = fileStream.Position - vertexStart;

            indiceStart = fileStream.Position;
            int[] triangles = mesh.triangles;
            for (int j = 0; j < triangles.Length; j++)
            {
                wxFileUtil.WriteData(fileStream, (ushort)triangles[j]);
            }
            indiceLength = fileStream.Position - indiceStart;
            fileStream.Close();

            vertexPositionMax.Set(vertexPositionMax.x / mesh.vertices.Length, vertexPositionMax.y / mesh.vertices.Length, vertexPositionMax.z / mesh.vertices.Length);
            float capsuleRadius = CalCapsuleRadius(vertexPositionMax, mesh.vertices);

            JSONObject capsule = new JSONObject(JSONObject.Type.OBJECT);

            capsule.AddField("x", vertexPositionMax.x);
            capsule.AddField("y", vertexPositionMax.y);
            capsule.AddField("z", vertexPositionMax.z);
            capsule.AddField("radius", capsuleRadius);

            metadata.AddField("indiceFormat", 1);                              //   BIT16 = 1,BIT32 = 2
            metadata.AddField("vertexLayout", vertexLayout.GetLayoutString()); //"POSITION,NORMAL,COLOR,UV,BLENDWEIGHT,BLENDINDICES,TANGENT",
            metadata.AddField("vertexStart", 0);
            metadata.AddField("vertexLength", vertexLength);
            metadata.AddField("indiceStart", vertexLength);  // indice的偏移量
            metadata.AddField("indiceLength", indiceLength); // indice的长度
            metadata.AddField("capsule", capsule);
            metadata.AddField("version", 1);


            JSONObject subMeshs = new JSONObject(JSONObject.Type.ARRAY);

#if !UNITY_2017_1_OR_NEWER
            int indexStart = 0;
#endif
            for (int i = 0; i < subMeshCount; i++)
            {
                JSONObject subMeshObj = new JSONObject(JSONObject.Type.OBJECT);
#if UNITY_2017_1_OR_NEWER
                subMeshObj.AddField("start", mesh.GetIndexStart(i));
                subMeshObj.AddField("length", mesh.GetIndexCount(i));
#else
                subMeshObj.AddField("start", indexStart);
                subMeshObj.AddField("length", mesh.GetIndices(i).Length);
                indexStart += mesh.GetIndices(i).Length;
#endif
                subMeshs.Add(subMeshObj);
            }
            metadata.AddField("subMeshs", subMeshs);

            JSONObject boundBox       = new JSONObject(JSONObject.Type.OBJECT);
            JSONObject boundBoxCenter = new JSONObject(JSONObject.Type.ARRAY);
            boundBoxCenter.Add(mesh.bounds.center.x);
            boundBoxCenter.Add(mesh.bounds.center.y);
            boundBoxCenter.Add(mesh.bounds.center.z);
            JSONObject boundBoxSize = new JSONObject(JSONObject.Type.ARRAY);
            boundBoxSize.Add(mesh.bounds.size.x);
            boundBoxSize.Add(mesh.bounds.size.y);
            boundBoxSize.Add(mesh.bounds.size.z);
            boundBox.AddField("center", boundBoxCenter);
            boundBox.AddField("size", boundBoxSize);
            metadata.AddField("boundBox", boundBox);

            return(fileStream.ToArray());
        }