public override void AbcSetup( AlembicStream abcstream, AbcAPI.aiObject abcobj, AbcAPI.aiSchema abcschema) { base.AbcSetup(abcstream, abcobj, abcschema); m_trans = GetComponent<Transform>(); AbcAPI.aiPolyMeshGetSchemaSummary(abcschema, ref m_schema_summary); int peak_index_count = (int)m_schema_summary.peak_index_count; int peak_vertex_count = (int)m_schema_summary.peak_vertex_count; if(GetComponent<MeshRenderer>()==null) { int num_mesh_objects = AlembicUtils.ceildiv(peak_index_count, max_indices); AddMeshComponents(abcobj, m_trans, abcstream.m_data_type); var entry = new AlembicMesh.Entry { host = m_trans.gameObject, mesh = GetComponent<MeshFilter>().sharedMesh, renderer = GetComponent<MeshRenderer>(), }; m_meshes.Add(entry); #if UNITY_EDITOR if (abcstream.m_data_type == AlembicStream.MeshDataType.Mesh) { GetComponent<MeshRenderer>().sharedMaterial = GetDefaultMaterial(); } else if(abcstream.m_data_type == AlembicStream.MeshDataType.Texture) { GetComponent<MeshRenderer>().sharedMaterial = AssetDatabase.LoadAssetAtPath<Material>("Assets/AlembicImporter/Materials/AlembicStandard.mat"); } #endif for (int i = 1; i < num_mesh_objects; ++i) { string name = "Submesh_" + i; GameObject go = new GameObject(); Transform child = go.GetComponent<Transform>(); go.name = name; child.parent = m_trans; child.localPosition = Vector3.zero; child.localEulerAngles = Vector3.zero; child.localScale = Vector3.one; Mesh mesh = AddMeshComponents(abcobj, child, m_abcstream.m_data_type); mesh.name = name; child.GetComponent<MeshRenderer>().sharedMaterial = GetComponent<MeshRenderer>().sharedMaterial; entry = new Entry { host = go, mesh = mesh, renderer = child.GetComponent<MeshRenderer>(), }; m_meshes.Add(entry); } } if (abcstream.m_data_type == AlembicStream.MeshDataType.Mesh) { for (int i = 0; i < m_meshes.Count; ++i) { m_meshes[i].buf_indices = new int[0]; m_meshes[i].buf_vertices = new Vector3[0]; m_meshes[i].buf_normals = new Vector3[0]; m_meshes[i].buf_uvs = new Vector2[0]; } } else if (abcstream.m_data_type == AlembicStream.MeshDataType.Texture) { m_mtex = new TextureMeshData(); m_abc_mtex = new AbcAPI.aiTextureMeshData(); m_abc_mtex.tex_width = MeshTextureWidth; m_mtex.indices = CreateDataTexture(peak_index_count, 1, RenderTextureFormat.RInt); m_abc_mtex.tex_indices = m_mtex.indices.GetNativeTexturePtr(); m_mtex.vertices = CreateDataTexture(peak_vertex_count, 3, RenderTextureFormat.RFloat); m_abc_mtex.tex_vertices = m_mtex.vertices.GetNativeTexturePtr(); if (m_schema_summary.has_normals != 0) { int normal_count = m_schema_summary.is_normals_indexed != 0 ? peak_vertex_count : peak_index_count; m_mtex.normals = CreateDataTexture(normal_count, 3, RenderTextureFormat.RFloat); m_abc_mtex.tex_normals = m_mtex.normals.GetNativeTexturePtr(); } if (m_schema_summary.has_uvs != 0) { int uv_count = m_schema_summary.is_uvs_indexed != 0 ? peak_vertex_count : peak_index_count; m_mtex.uvs = CreateDataTexture(uv_count, 2, RenderTextureFormat.RFloat); m_abc_mtex.tex_uvs = m_mtex.uvs.GetNativeTexturePtr(); } if (m_schema_summary.has_velocities != 0) { m_mtex.velocities = CreateDataTexture(peak_vertex_count, 3, RenderTextureFormat.RFloat); m_abc_mtex.tex_velocities = m_mtex.velocities.GetNativeTexturePtr(); } for (int i = 0; i < m_meshes.Count; ++i) { m_meshes[i].mpb = new MaterialPropertyBlock(); m_meshes[i].mpb.SetVector("_DrawData", Vector4.zero); m_meshes[i].mpb.SetTexture("_Indices", m_mtex.indices); m_meshes[i].mpb.SetTexture("_Vertices", m_mtex.vertices); if (m_mtex.normals != null) { m_meshes[i].mpb.SetTexture("_Normals", m_mtex.normals); } if (m_mtex.uvs != null) { m_meshes[i].mpb.SetTexture("_UVs", m_mtex.uvs); } if (m_mtex.velocities != null) { m_meshes[i].mpb.SetTexture("_Velocities", m_mtex.velocities); } m_meshes[i].renderer.SetPropertyBlock(m_meshes[i].mpb); } } }
public static void UpdateAbcMesh(aiObject abc, Transform trans) { const int max_vertices = 65000; AlembicMesh abcmesh = trans.GetComponent <AlembicMesh>(); if (abcmesh == null) { abcmesh = trans.gameObject.AddComponent <AlembicMesh>(); var entry = new AlembicMesh.Entry { host = trans.gameObject, mesh = AddMeshComponents(abc, trans), vertex_cache = new Vector3[0], uv_cache = new Vector2[0], index_cache = new int[0], }; abcmesh.m_meshes.Add(entry); #if UNITY_EDITOR trans.GetComponent <MeshRenderer>().sharedMaterial = GetDefaultMaterial(); #endif } Material material = trans.GetComponent <MeshRenderer>().sharedMaterial; /* * { * AlembicMesh.Entry entry = abcmesh.m_meshes[0]; * Array.Resize(ref entry.index_cache, aiPolyMeshGetIndexCount(ctx)); * Array.Resize(ref entry.vertex_cache, aiPolyMeshGetVertexCount(ctx)); * aiPolyMeshCopyIndices(ctx, Marshal.UnsafeAddrOfPinnedArrayElement(entry.index_cache, 0)); * aiPolyMeshCopyVertices(ctx, Marshal.UnsafeAddrOfPinnedArrayElement(entry.vertex_cache, 0)); * entry.mesh.Clear(); * entry.mesh.vertices = entry.vertex_cache; * if(aiPolyMeshHasNormals(ctx)) * { * aiPolyMeshCopyNormals(ctx, Marshal.UnsafeAddrOfPinnedArrayElement(entry.vertex_cache, 0)); * entry.mesh.normals = entry.vertex_cache; * } * if (aiPolyMeshHasUVs(ctx)) * { * Array.Resize(ref entry.uv_cache, aiPolyMeshGetVertexCount(ctx)); * aiPolyMeshCopyUVs(ctx, Marshal.UnsafeAddrOfPinnedArrayElement(entry.uv_cache, 0)); * entry.mesh.uv = entry.uv_cache; * } * entry.mesh.SetIndices(entry.index_cache, MeshTopology.Triangles, 0); * //entry.mesh.RecalculateNormals(); // * * for (int i = 1; i < abcmesh.m_meshes.Count; ++i) * { * abcmesh.m_meshes[i].host.SetActive(false); * } * } */ aiSplitedMeshInfo smi_prev = default(aiSplitedMeshInfo); aiSplitedMeshInfo smi = default(aiSplitedMeshInfo); int nth_submesh = 0; for (; ;) { smi_prev = smi; smi = default(aiSplitedMeshInfo); bool is_end = aiPolyMeshGetSplitedMeshInfo(abc, ref smi, ref smi_prev, max_vertices); AlembicMesh.Entry entry; if (nth_submesh < abcmesh.m_meshes.Count) { entry = abcmesh.m_meshes[nth_submesh]; entry.host.SetActive(true); } else { string name = "Submesh_" + nth_submesh; GameObject go = new GameObject(); Transform child = go.GetComponent <Transform>(); go.name = name; child.parent = trans; child.localPosition = Vector3.zero; child.localEulerAngles = Vector3.zero; child.localScale = Vector3.one; Mesh mesh = AddMeshComponents(abc, child); mesh.name = name; child.GetComponent <MeshRenderer>().sharedMaterial = material; entry = new AlembicMesh.Entry { host = go, mesh = mesh, vertex_cache = new Vector3[0], uv_cache = new Vector2[0], index_cache = new int[0], }; abcmesh.m_meshes.Add(entry); } bool needs_index_update = entry.mesh.vertexCount == 0 || !aiPolyMeshIsTopologyConstant(abc); if (needs_index_update) { entry.mesh.Clear(); } // update positions { Array.Resize(ref entry.vertex_cache, smi.vertex_count); aiPolyMeshCopySplitedVertices(abc, Marshal.UnsafeAddrOfPinnedArrayElement(entry.vertex_cache, 0), ref smi); entry.mesh.vertices = entry.vertex_cache; } // update normals if (aiPolyMeshHasNormals(abc)) { // normals can reuse entry.vertex_cache aiPolyMeshCopySplitedNormals(abc, Marshal.UnsafeAddrOfPinnedArrayElement(entry.vertex_cache, 0), ref smi); entry.mesh.normals = entry.vertex_cache; } if (needs_index_update) { // update uvs if (aiPolyMeshHasUVs(abc)) { Array.Resize(ref entry.uv_cache, smi.vertex_count); aiPolyMeshCopySplitedUVs(abc, Marshal.UnsafeAddrOfPinnedArrayElement(entry.uv_cache, 0), ref smi); entry.mesh.uv = entry.uv_cache; } // update indices Array.Resize(ref entry.index_cache, smi.triangulated_index_count); aiPolyMeshCopySplitedIndices(abc, Marshal.UnsafeAddrOfPinnedArrayElement(entry.index_cache, 0), ref smi); entry.mesh.SetIndices(entry.index_cache, MeshTopology.Triangles, 0); } // recalculate normals if (!aiPolyMeshHasNormals(abc)) { entry.mesh.RecalculateNormals(); } ++nth_submesh; if (is_end) { break; } } for (int i = nth_submesh + 1; i < abcmesh.m_meshes.Count; ++i) { abcmesh.m_meshes[i].host.SetActive(false); } }