コード例 #1
0
ファイル: AlembicMesh.cs プロジェクト: efwff/AlembicImporter
    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);
            }
        }
    }
コード例 #2
0
    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);
        }
    }