Beispiel #1
0
        void RefreshRenderer(object tag)
        {
            List <int> triangles     = new List <int>(capacity: all_triangles.Length);
            List <int> stems         = new List <int>(capacity: all_stems.Length);
            List <int> alt_triangles = new List <int>();
            List <int> alt_stems     = new List <int>();

            lock (sketch.geometries_lock)
            {
                var geometries = sketch.geometries;

                for (int i = geom_ids.Count - 1; i >= 0; --i)
                {
                    int  geom_id = geom_ids[i];
                    Geom geom    = geometries[geom_id];

                    /* Concurrent writes to 'geom' could occur, but only the 'gindex' field, and
                     * only to add/remove the GINDEX_HIDDEN flag or to change it to GINDEX_DESTROYED.
                     * If that occurs, this MeshGameObject will be scheduled for another update
                     * at the next Flush() anyway.
                     */
                    List <int> triangles1, stems1;
                    uint       gmask = geom.gindex & GINDEX_MASK;

                    if (gmask == GINDEX_REG)
                    {
                        /* Geometry is visible */
                        triangles1 = triangles;
                        stems1     = stems;
                    }
                    else if (gmask == GINDEX_ALT)
                    {
                        triangles1 = alt_triangles;
                        stems1     = alt_stems;
                    }
                    else
                    {
                        if (geom.gindex == GINDEX_DESTROYED)
                        {
                            /* Geom was destroyed */
                            int last = geom_ids.Count - 1;
                            geom_ids[i] = geom_ids[last];
                            geom_ids.RemoveAt(last);

                            geometries[geom_id].gindex =
                                (((uint)sketch.geom_free_head_mainthread) << GINDEX_SHIFT) | GINDEX_FREE;
                            sketch.geom_free_head_mainthread = geom_id;
                        }
                        continue;
                    }

                    int start, stop;
                    start = geom.triangle_start * 3;
                    stop  = geom.triangle_stop * 3;
                    if (stop == 0xFFFF * 3)
                    {
                        stop = all_triangles.Length;
                    }
                    for (int j = start; j < stop; j++)
                    {
                        triangles1.Add(all_triangles[j]);
                    }

                    start = geom.stem_start * 2;
                    stop  = geom.stem_stop * 2;
                    if (stop == 0xFFFF * 2)
                    {
                        stop = all_stems.Length;
                    }
                    for (int j = start; j < stop; j++)
                    {
                        stems1.Add(all_stems[j]);
                    }
                }
            }
            geom_ids.TrimExcess();

            bool any_triangle_1 = triangles.Count > 0;
            bool any_triangle_2 = alt_triangles.Count > 0;
            bool any_stem_1     = (stems.Count > 0 && sketch.stemMaterial != null);
            bool any_stem_2     = (alt_stems.Count > 0 && sketch.stemAlternateMaterial != null);

            stem_mat     = sketch.stemMaterial;
            stem_alt_mat = sketch.stemAlternateMaterial;
            face_mat     = null;
            face_alt_mat = null;

            if (any_triangle_1 || any_stem_1 || any_triangle_2 || any_stem_2)
            {
                mesh.subMeshCount = (any_triangle_1 ? 1 : 0) + (any_stem_1 ? 1 : 0) +
                                    (any_triangle_2 ? 1 : 0) + (any_stem_2 ? 1 : 0);
                Material[] mats    = new Material[mesh.subMeshCount];
                int        submesh = 0;

                if (any_triangle_1)
                {
                    mesh.SetTriangles(triangles, submesh, calculateBounds: false);
                    face_mat      = face_mat_builder.GetMaterial();
                    mats[submesh] = face_mat;
                    submesh++;
                }
                if (any_stem_1)
                {
                    mesh.SetIndices(stems.ToArray(), MeshTopology.Lines, submesh, calculateBounds: false);
                    mats[submesh] = stem_mat;
                    submesh++;
                }
                if (any_triangle_2)
                {
                    mesh.SetTriangles(alt_triangles, submesh, calculateBounds: false);
                    face_alt_mat  = face_mat_builder.GetAlternateMaterial();
                    mats[submesh] = face_alt_mat;
                    submesh++;
                }
                if (any_stem_2)
                {
                    mesh.SetIndices(alt_stems.ToArray(), MeshTopology.Lines, submesh, calculateBounds: false);
                    mats[submesh] = stem_alt_mat;
                    submesh++;
                }

                mesh.RecalculateBounds();

                if (renderer == null)
                {
                    var go = Instantiate(sketch.largeSketchMeshPrefab, sketch.transform);
                    go.GetComponent <MeshFilter>().sharedMesh = mesh;
                    renderer = go.GetComponent <MeshRenderer>();
                }
                renderer.sharedMaterials = mats;

                foreach (var script in renderer.GetComponents <IMeshModified>())
                {
                    script.Modified();
                }
            }
            else
            {
                if (renderer != null)
                {
                    Destroy(renderer.gameObject);
                    renderer = null;
                }
            }
            current_tag = tag;
        }