Exemplo n.º 1
0
        /// <summary>
        /// Add data for the stroke object to the LivePolyMeshObject. Later, when the stroke
        /// is modified, we'll use its modified callback to update the stroke data keyed by
        /// this stroke - see onStrokeModified.
        /// </summary>
        private void addStrokePolygonData(KeyedPolyMeshObject polyMeshObj,
                                          StrokeObject strokeObj,
                                          List <Vector3> strokeMeshPositions,
                                          List <Polygon> strokeMeshPolygons,
                                          List <Edge> strokeSmoothEdges,
                                          List <Color> strokeColors)
        {
            polyMeshObj.AddDataFor(strokeObj, strokeMeshPositions,
                                   strokeMeshPolygons,
                                   strokeSmoothEdges,
                                   strokeColors);

            // TODO: This counting is hacky and not-robust :(
            foreach (var polygon in strokeMeshPolygons)
            {
                addedTriangleCount += (polygon.Count - 2) * 2; // double-sided means twice as
                                                               // many triangles.
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Called when a stroke is modified, this method updates the polygons in the
        /// stroke's associated LivePolyMeshObject with the polygons that define the newly
        /// modified stroke.
        /// </summary>
        private void onStrokeModified(StrokeObject strokeObj)
        {
            using (new ProfilerSample("StrokePolyMeshManager: onStrokeModified")) {
                KeyedPolyMeshObject polyMeshObj;
                if (!_strokeMeshes.TryGetValue(strokeObj, out polyMeshObj))
                {
                    throw new System.InvalidOperationException(
                              "No LivePolyMeshObject found for stroke: " + strokeObj);
                }

                PolyMesh polyMesh;
                var      curStrokePosIndices = Pool <List <int> > .Spawn();

                curStrokePosIndices.Clear();
                var curStrokePolyIndices = Pool <List <int> > .Spawn();

                curStrokePolyIndices.Clear();
                KeyedPolyMeshObject.NotifyPolyMeshModifiedAction modificationsFinishedCallback;
                try {
                    // Begin our modification of the data in the PolyMesh for this Stroke.
                    polyMeshObj.ModifyDataFor(strokeObj,
                                              out polyMesh,
                                              curStrokePosIndices,
                                              curStrokePolyIndices,
                                              out modificationsFinishedCallback);

                    var newStrokeMeshPolygons = Pool <List <Polygon> > .Spawn();

                    newStrokeMeshPolygons.Clear();
                    var newStrokeMeshPositions = Pool <List <Vector3> > .Spawn();

                    newStrokeMeshPositions.Clear();
                    var newStrokeSmoothEdges = Pool <List <Edge> > .Spawn();

                    newStrokeSmoothEdges.Clear();
                    var newStrokeColors = Pool <List <Color> > .Spawn();

                    newStrokeColors.Clear();
                    var addedStrokeMeshPositionIndices = Pool <List <int> > .Spawn();

                    addedStrokeMeshPositionIndices.Clear();
                    var addedStrokeMeshPolygonIndices = Pool <List <int> > .Spawn();

                    addedStrokeMeshPolygonIndices.Clear();
                    var finalPositionIndices = Pool <List <int> > .Spawn();

                    finalPositionIndices.Clear();
                    try {
                        using (new ProfilerSample("getStrokePolygons")) {
                            // Get polygon data for the entirety of the stroke.
                            // TODO: _Removing_ smooth edges is not supported.
                            polyMesher.FillPolyMeshData(strokeObj,
                                                        newStrokeMeshPositions,
                                                        newStrokeMeshPolygons,
                                                        newStrokeSmoothEdges,
                                                        newStrokeColors);
                        }

                        var hasColors = newStrokeColors != null && newStrokeColors.Count > 0;

                        using (new ProfilerSample("Add/modify PolyMesh stroke positions")) {
                            // Re-use existing position indices or add new ones to fit the modified
                            // stroke.
                            // Also take care of vertex colors here, because those always match the
                            // positions.
                            for (int i = 0; i < newStrokeMeshPositions.Count; i++)
                            {
                                int existingPositionIdx = -1;
                                if (i < curStrokePosIndices.Count)
                                {
                                    existingPositionIdx = curStrokePosIndices[i];
                                }
                                if (existingPositionIdx != -1)
                                {
                                    // Modify the position at the existing position index.
                                    polyMesh.SetPosition(existingPositionIdx, newStrokeMeshPositions[i]);
                                    if (hasColors)
                                    {
                                        polyMesh.SetColor(existingPositionIdx, newStrokeColors[i]);
                                    }

                                    // Remember what this position index wound up being; the polygons of
                                    // the stroke need to re-index into the final position index list.
                                    finalPositionIndices.Add(existingPositionIdx);
                                }
                                else
                                {
                                    // Add the position and remember the added position index.
                                    int addedPositionIdx;
                                    polyMesh.AddPosition(newStrokeMeshPositions[i], out addedPositionIdx);
                                    addedStrokeMeshPositionIndices.Add(addedPositionIdx);
                                    if (hasColors)
                                    {
                                        polyMesh.AddColor(newStrokeColors[i]);
                                    }

                                    // Remember what this position index wound up being.
                                    finalPositionIndices.Add(addedPositionIdx);
                                }
                            }
                        }

                        using (new ProfilerSample("Add/modify PolyMesh stroke polygons")) {
                            // Re-use existing polygon indices or add new ones to fit the modified
                            // stroke.
                            for (int i = 0; i < newStrokeMeshPolygons.Count; i++)
                            {
                                // First, re-index the polygon to refer to the final position indices of
                                // the mesh. We constructed this list during the Add Positions step above.
                                var newStrokeMeshPolygon = newStrokeMeshPolygons[i];
                                for (int v = 0; v < newStrokeMeshPolygon.verts.Count; v++)
                                {
                                    newStrokeMeshPolygon.verts[v]
                                        = finalPositionIndices[newStrokeMeshPolygon.verts[v]];
                                }

                                int existingPolygonIdx = -1;
                                if (i < curStrokePolyIndices.Count)
                                {
                                    existingPolygonIdx = curStrokePolyIndices[i];
                                }
                                if (existingPolygonIdx != -1)
                                {
                                    // Modify the polygon at the existing position index.
                                    Polygon replacedPolygon;
                                    polyMesh.SetPolygon(existingPolygonIdx, newStrokeMeshPolygon,
                                                        out replacedPolygon);
                                    // (Add the vertex index list of the replaced polygon back to its pool.)
                                    replacedPolygon.RecycleVerts();
                                }
                                else
                                {
                                    // Add the polygon and remember the added polygon index.
                                    int addedPolygonIdx;
                                    polyMesh.AddPolygon(newStrokeMeshPolygon, out addedPolygonIdx);

                                    addedTriangleCount += (newStrokeMeshPolygon.Count - 2) * 2;
                                    // (double-sided tris, also TODO: this is SUPER HACKY D: )

                                    addedStrokeMeshPolygonIndices.Add(addedPolygonIdx);
                                }
                            }
                        }

                        using (new ProfilerSample("Mark new PolyMesh edges smooth")) {
                            foreach (var newStrokeSmoothEdge in newStrokeSmoothEdges)
                            {
                                // Re-index the edge to refer to final positions in the PolyMesh.
                                var finalSmoothEdge = new Edge(finalPositionIndices[newStrokeSmoothEdge.a],
                                                               finalPositionIndices[newStrokeSmoothEdge.b]);
                                polyMesh.MarkEdgeSmooth(finalSmoothEdge);
                            }
                        }

                        using (new ProfilerSample("Call modifications-finished callback")) {
                            // Notify that we've finished modifying the keyed object (the stroke object),
                            // and include any new positions or polygons we may have added to do so.
                            modificationsFinishedCallback(strokeObj,
                                                          addedStrokeMeshPositionIndices,
                                                          addedStrokeMeshPolygonIndices);
                        }
                    }
                    finally {
                        newStrokeMeshPolygons.Clear();
                        Pool <List <Polygon> > .Recycle(newStrokeMeshPolygons);

                        newStrokeMeshPolygons.Clear();
                        Pool <List <Vector3> > .Recycle(newStrokeMeshPositions);

                        newStrokeSmoothEdges.Clear();
                        Pool <List <Edge> > .Recycle(newStrokeSmoothEdges);

                        addedStrokeMeshPositionIndices.Clear();
                        Pool <List <int> > .Recycle(addedStrokeMeshPositionIndices);

                        addedStrokeMeshPolygonIndices.Clear();
                        Pool <List <int> > .Recycle(addedStrokeMeshPolygonIndices);

                        finalPositionIndices.Clear();
                        Pool <List <int> > .Recycle(finalPositionIndices);
                    }
                }
                finally {
                    curStrokePolyIndices.Clear();
                    Pool <List <int> > .Recycle(curStrokePolyIndices);

                    curStrokePosIndices.Clear();
                    Pool <List <int> > .Recycle(curStrokePosIndices);
                }
            }
        }
Exemplo n.º 3
0
 private void finalizeStroke()
 {
     _curStrokeObject = null;
 }
Exemplo n.º 4
0
 private void initStroke()
 {
     _curStrokeObject = Instantiate(outputStrokeObjectPrefab);
     _curStrokeObject.transform.parent = outputParentObject;
 }