static int _m_GetSubMesh(RealStatePtr L) { try { ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L); UnityEngine.Mesh.MeshData gen_to_be_invoked; translator.Get(L, 1, out gen_to_be_invoked); { int _index = LuaAPI.xlua_tointeger(L, 2); UnityEngine.Rendering.SubMeshDescriptor gen_ret = gen_to_be_invoked.GetSubMesh(_index); translator.Push(L, gen_ret); translator.Update(L, 1, gen_to_be_invoked); return(1); } } catch (System.Exception gen_e) { return(LuaAPI.luaL_error(L, "c# exception:" + gen_e)); } }
public static SharedMesh ToSharedMesh(this Mesh mesh) { System.Console.WriteLine($"Vertex count:{mesh.vertexCount}"); UVector3[] vertices = mesh.vertices; SharedMesh sharedMesh = new SharedMesh(); sharedMesh.positions = new NVector3[vertices.Length]; MetaAttributeList attributes = new EmptyMetaAttributeList(vertices.Length); for (int i = 0; i < vertices.Length; i++) { sharedMesh.positions[i] = new NVector3(vertices[i].x, vertices[i].y, vertices[i].z); } List <AttributeDefinition> attributeDefinitions = new List <AttributeDefinition>(); UVector3[] normals = mesh.normals; if (normals != null && normals.Length > 0) { int k = attributeDefinitions.Count; attributeDefinitions.Add(new AttributeDefinition(AttributeType.Normals, 222.0194f)); attributes = attributes.AddAttributeType <NVector3F>(); for (int i = 0; i < normals.Length; i++) { attributes[i] = attributes[i].Set(k, new NVector3F(normals[i].x, normals[i].y, normals[i].z)); } } UVector2[] uvs1 = mesh.uv; if (uvs1 != null && uvs1.Length > 0) { int k = attributeDefinitions.Count; attributeDefinitions.Add(new AttributeDefinition(AttributeType.UVs, 90.21234f, 0)); attributes = attributes.AddAttributeType <NVector2F>(); for (int i = 0; i < uvs1.Length; i++) { attributes[i] = attributes[i].Set(k, new NVector2F(uvs1[i].x, uvs1[i].y)); } } UVector2[] uvs2 = mesh.uv2; if (uvs2 != null && uvs2.Length > 0) { int k = attributeDefinitions.Count; attributeDefinitions.Add(new AttributeDefinition(AttributeType.UVs, 9.021234f, 1)); attributes = attributes.AddAttributeType <NVector2F>(); for (int i = 0; i < uvs2.Length; i++) { attributes[i] = attributes[i].Set(k, new NVector2F(uvs2[i].x, uvs2[i].y)); } } /* * UVector2[] uvs3 = mesh.uv3; * if (uvs3 != null && uvs3.Length > 0) * { * int k = attributeDefinitions.Count; * attributeDefinitions.Add(new AttributeDefinition(AttributeType.UVs)); * attributes = attributes.AddAttributeType<NVector2F>(); * for (int i = 0; i < uvs3.Length; i++) * { * attributes[i] = attributes[i].Set(k, new NVector2F(uvs3[i].x, uvs3[i].y)); * } * } * * UVector2[] uvs4 = mesh.uv4; * if (uvs4 != null && uvs4.Length > 0) * { * int k = attributeDefinitions.Count; * attributeDefinitions.Add(new AttributeDefinition(AttributeType.UVs)); * attributes = attributes.AddAttributeType<NVector2F>(); * for (int i = 0; i < uvs4.Length; i++) * { * attributes[i] = attributes[i].Set(k, new NVector2F(uvs4[i].x, uvs4[i].y)); * } * } * * UVector2[] uvs5 = mesh.uv5; * if (uvs5 != null && uvs5.Length > 0) * { * int k = attributeDefinitions.Count; * attributeDefinitions.Add(new AttributeDefinition(AttributeType.UVs)); * attributes = attributes.AddAttributeType<NVector2F>(); * for (int i = 0; i < uvs5.Length; i++) * { * attributes[i] = attributes[i].Set(k, new NVector2F(uvs5[i].x, uvs5[i].y)); * } * } * * UVector2[] uvs6 = mesh.uv6; * if (uvs6 != null && uvs6.Length > 0) * { * int k = attributeDefinitions.Count; * attributeDefinitions.Add(new AttributeDefinition(AttributeType.UVs)); * attributes = attributes.AddAttributeType<NVector2F>(); * for (int i = 0; i < uvs6.Length; i++) * { * attributes[i] = attributes[i].Set(k, new NVector2F(uvs6[i].x, uvs6[i].y)); * } * } * * UVector2[] uvs7 = mesh.uv7; * if (uvs7 != null && uvs7.Length > 0) * { * int k = attributeDefinitions.Count; * attributeDefinitions.Add(new AttributeDefinition(AttributeType.UVs)); * attributes = attributes.AddAttributeType<NVector2F>(); * for (int i = 0; i < uvs7.Length; i++) * { * attributes[i] = attributes[i].Set(k, new NVector2F(uvs7[i].x, uvs7[i].y)); * } * } * * UVector2[] uvs8 = mesh.uv8; * if (uvs8 != null && uvs8.Length > 0) * { * int k = attributeDefinitions.Count; * attributeDefinitions.Add(new AttributeDefinition(AttributeType.UVs)); * attributes = attributes.AddAttributeType<NVector2F>(); * for (int i = 0; i < uvs8.Length; i++) * { * attributes[i] = attributes[i].Set(k, new NVector2F(uvs8[i].x, uvs8[i].y)); * } * } */ UColor32[] colors = mesh.colors32; if (colors != null && colors.Length > 0) { int k = attributeDefinitions.Count; attributeDefinitions.Add(new AttributeDefinition(AttributeType.Colors, 0.0001)); attributes = attributes.AddAttributeType <NColor32>(); for (int i = 0; i < colors.Length; i++) { attributes[i] = attributes[i].Set(k, new NColor32(colors[i].r, colors[i].g, colors[i].b, colors[i].a)); } } UBoneWeight[] boneWeights = mesh.boneWeights; if (boneWeights != null && boneWeights.Length > 0) { int k = attributeDefinitions.Count; attributeDefinitions.Add(new AttributeDefinition(AttributeType.BoneWeights, 1f)); attributes = attributes.AddAttributeType <NBoneWeight>(); for (int i = 0; i < boneWeights.Length; i++) { attributes[i] = attributes[i].Set(k, new NBoneWeight( boneWeights[i].boneIndex0, boneWeights[i].boneIndex1, boneWeights[i].boneIndex2, boneWeights[i].boneIndex3, boneWeights[i].weight0, boneWeights[i].weight1, boneWeights[i].weight2, boneWeights[i].weight3)); } } sharedMesh.attributeDefinitions = attributeDefinitions.ToArray(); sharedMesh.attributes = attributes; sharedMesh.triangles = mesh.triangles; sharedMesh.groups = new Group[mesh.subMeshCount]; for (int i = 0; i < mesh.subMeshCount; i++) { UnityEngine.Rendering.SubMeshDescriptor submeshDesc = mesh.GetSubMesh(i); sharedMesh.groups[i] = new Group { firstIndex = submeshDesc.indexStart, indexCount = submeshDesc.indexCount }; } return(sharedMesh); }
public void RetrieveLitSkinnedMeshData(Mesh uMesh, Entity meshEntity, EntityManager entityManager) { List <int> duplicateVertexIndex = new List <int>(); List <Vector4> duplicateBoneIndex = new List <Vector4>(); Dictionary <int, Vector4> existingVertex2NewBoneIndex = new Dictionary <int, Vector4>(); Dictionary <int, int> boneIndexCounter = new Dictionary <int, int>(); List <int> gpuDrawRange = new List <int>(); BoneWeight[] boneWeights = uMesh.boneWeights; int[] triangles = uMesh.triangles; //Separate mesh into different draw range for gpu skinning use for (int subMeshIndex = 0; subMeshIndex < uMesh.subMeshCount; subMeshIndex++) { UnityEngine.Rendering.SubMeshDescriptor uSubMeshDescriptor = uMesh.GetSubMesh(subMeshIndex); int curIndex = uSubMeshDescriptor.indexStart; int lastIndex = uSubMeshDescriptor.indexStart; int endIndex = curIndex + uSubMeshDescriptor.indexCount; while (curIndex < endIndex) { int curBoneCount = boneIndexCounter.Count; for (int offset = 0; offset < 3; offset++) { int vertexIndex = triangles[curIndex + offset]; BoneWeight boneWeight = boneWeights[vertexIndex]; curBoneCount += CalcToBeAddBoneIndexCount(boneIndexCounter, boneWeight); } if (curBoneCount > MeshSkinningConfig.GPU_SKINNING_MAX_BONES) { gpuDrawRange.Add(curIndex); Debug.Log("GPU SkinnedMesh Draw Range[" + lastIndex + ":" + curIndex + "] BoneCount:" + boneIndexCounter.Count); lastIndex = curIndex; boneIndexCounter.Clear(); } else { for (int offset = 0; offset < 3; offset++) { int vertexIndex = triangles[curIndex + offset]; BoneWeight curBoneWeight = boneWeights[vertexIndex]; //restore the new bone index and set it to the mesh later Vector4 newBoneIndex = new Vector4(); newBoneIndex.x = GetNewBoneIndex(boneIndexCounter, curBoneWeight.weight0, curBoneWeight.boneIndex0); newBoneIndex.y = GetNewBoneIndex(boneIndexCounter, curBoneWeight.weight1, curBoneWeight.boneIndex1); newBoneIndex.z = GetNewBoneIndex(boneIndexCounter, curBoneWeight.weight2, curBoneWeight.boneIndex2); newBoneIndex.w = GetNewBoneIndex(boneIndexCounter, curBoneWeight.weight3, curBoneWeight.boneIndex3); Vector4 existingNewBoneIndex = new Vector4(); bool isExist = existingVertex2NewBoneIndex.TryGetValue(vertexIndex, out existingNewBoneIndex); if (isExist && newBoneIndex != existingNewBoneIndex) { bool needAdd = true; int newVertexIndex = 0; for (int j = 0; j < duplicateVertexIndex.Count; j++) { if (duplicateVertexIndex[j] == vertexIndex && duplicateBoneIndex[j] == newBoneIndex) { newVertexIndex = uMesh.vertexCount + j; triangles[curIndex + offset] = newVertexIndex; needAdd = false; break; } } if (needAdd) { duplicateVertexIndex.Add(vertexIndex); duplicateBoneIndex.Add(newBoneIndex); newVertexIndex = uMesh.vertexCount + duplicateVertexIndex.Count - 1; triangles[curIndex + offset] = newVertexIndex; existingVertex2NewBoneIndex[newVertexIndex] = newBoneIndex; } } else { existingVertex2NewBoneIndex[vertexIndex] = newBoneIndex; } } curIndex += 3; } } if (lastIndex != curIndex) { gpuDrawRange.Add(curIndex); Debug.Log("GPU SkinnedMesh Draw Range[" + lastIndex + ":" + curIndex + "] BoneCount:" + boneIndexCounter.Count); } } Debug.Log("GPU SkinnedMesh Duplicate VertexCount:" + duplicateVertexIndex.Count); Debug.Log("GPU SkinnedMesh DrawCalls: " + gpuDrawRange.Count); //generate UMeshDataCache and adding duplicate vertices into UMeshDataCache int newVertexCount = uMesh.vertexCount + duplicateVertexIndex.Count; RetrieveLitMeshData(uMesh, newVertexCount); for (int i = 0; i < duplicateVertexIndex.Count; i++) { int curVertexIndex = uMesh.vertexCount + i; int originalVertexIndex = duplicateVertexIndex[i]; uPositions[curVertexIndex] = uPositions[originalVertexIndex]; uUVs[curVertexIndex] = uUVs[originalVertexIndex]; uNormals[curVertexIndex] = uNormals[originalVertexIndex]; uTangents[curVertexIndex] = uTangents[originalVertexIndex]; uBiTangents[curVertexIndex] = uBiTangents[originalVertexIndex]; uBoneWeights[curVertexIndex] = uBoneWeights[originalVertexIndex]; uBoneIndices[curVertexIndex] = uBoneIndices[originalVertexIndex]; uColors[curVertexIndex] = uColors[originalVertexIndex]; } //Update the indices, some of the triangles reference to the duplicate vertex for (int i = 0; i < triangles.Length; i++) { uIndices[i] = Convert.ToUInt16(triangles[i]); } //Restore the original vertex bone index for switching GPU skinning to CPU skinning in the runtime DynamicBuffer <OriginalVertexBoneIndex> obiBuffer = entityManager.AddBuffer <OriginalVertexBoneIndex>(meshEntity); for (int i = 0; i < newVertexCount; i++) { Vector4 uBoneIndex = uBoneIndices[i]; obiBuffer.Add(new OriginalVertexBoneIndex { BoneIndex = new float4(uBoneIndex.x, uBoneIndex.y, uBoneIndex.z, uBoneIndex.w) }); Vector4 newBoneIndex = existingVertex2NewBoneIndex[i]; uBoneIndices[i] = newBoneIndex; } //Add GPUSkinnedMeshDrawRange for SkinnedMeshRendererConversion use. DynamicBuffer <GPUSkinnedMeshDrawRange> gsmdrBuffer = entityManager.AddBuffer <GPUSkinnedMeshDrawRange>(meshEntity); for (int i = 0; i < gpuDrawRange.Count; i++) { gsmdrBuffer.Add(new GPUSkinnedMeshDrawRange { TriangleIndex = gpuDrawRange[i] }); } }