示例#1
0
        public void Noise(NoiseGenerator noise)
        {
            ComputePolygonNormals();
            ComputePointNormals("point_normals_smooth");

            var pointLocations = PointAttributes.FindOrNull <Vector3>("point_locations");
            var pointNormals   = PointAttributes.FindOrNull <Vector3>("point_normals_smooth");

            foreach (Point point in Points)
            {
                if (
                    (pointLocations != null) &&
                    pointLocations.ContainsKey(point)
                    )
                {
                    var pos    = pointLocations[point];
                    var normal = Vector3.Normalize(pointLocations[point]);
                    pointLocations[point] = pos + noise.Generate(pos) * normal;
                }
            }

            ComputePolygonCentroids();
            ComputePolygonNormals();
            SmoothNormalize("corner_normals", "polygon_normals", (2.0f * (float)System.Math.PI));
            BuildEdges();
        }
示例#2
0
        /// \warning This is inefficient! Try not to use this
        public void MergePoints()
        {
            Dictionary <Point, Point> removedPointToRemainingPoint = new Dictionary <Point, Point>();
            var   pointLocations = PointAttributes.FindOrNull <Vector3>("point_locations");
            float pointEpsilon   = 0.0000001f;

            //  Merge points
            foreach (Point p1 in Points)
            {
                Vector3 pos1 = pointLocations[p1];

                bool alreadyUsed = false;
                foreach (Point p2 in Points)
                {
                    if (p1 == p2)
                    {
                        continue;
                    }
                    if (removedPointToRemainingPoint.ContainsKey(p1))
                    {
                        continue;
                    }
                    Vector3 pos2 = pointLocations[p2];

                    float distanceSquared = pos1.DistanceSquared(pos2);

                    if (distanceSquared < pointEpsilon)
                    {
                        if (alreadyUsed)
                        {
                            System.Diagnostics.Debug.WriteLine("point already used");
                        }
                        removedPointToRemainingPoint[p2] = p1;
                        alreadyUsed = true;
                    }
                }
            }

            //  Merge polygons
            foreach (var polygon in Polygons)
            {
                polygon.ReplacePoints(removedPointToRemainingPoint);
            }

            foreach (var point in removedPointToRemainingPoint.Keys)
            {
                Points.Remove(point);
            }
        }
示例#3
0
        public void Transform(Matrix4 transform)
        {
            Matrix4 inverseTransposeTransform = Matrix4.Transpose(Matrix4.Invert(transform));

            //  Check.. Did I forget something?
            //  \todo Mark each attributemap how they should be transformed
            var polygonCentroids = PolygonAttributes.FindOrNull <Vector3>("polygon_centroids");
            var polygonNormals   = PolygonAttributes.FindOrNull <Vector3>("polygon_normals");
            var pointLocations   = PointAttributes.FindOrNull <Vector3>("point_locations");
            var pointNormals     = PointAttributes.FindOrNull <Vector3>("point_normals");
            var cornerNormals    = CornerAttributes.FindOrNull <Vector3>("corner_normals");

            //  Make copies of old points
            foreach (Point point in Points)
            {
                if (pointLocations != null && pointLocations.ContainsKey(point))
                {
                    pointLocations[point] = transform.TransformPoint(pointLocations[point]);
                }
                if (pointNormals != null && pointNormals.ContainsKey(point))
                {
                    pointNormals[point] = inverseTransposeTransform.TransformDirection(pointNormals[point]);
                }
            }
            foreach (Polygon polygon in Polygons)
            {
                if (polygonCentroids != null && polygonCentroids.ContainsKey(polygon))
                {
                    polygonCentroids[polygon] = transform.TransformPoint(polygonCentroids[polygon]);
                }
                if (polygonNormals != null && polygonNormals.ContainsKey(polygon))
                {
                    polygonNormals[polygon] = inverseTransposeTransform.TransformDirection(polygonNormals[polygon]);
                }
                if (cornerNormals != null)
                {
                    foreach (Corner corner in polygon.Corners)
                    {
                        if (cornerNormals.ContainsKey(corner))
                        {
                            cornerNormals[corner] = inverseTransposeTransform.TransformDirection(cornerNormals[corner]);
                        }
                    }
                }
            }
        }
示例#4
0
        public void Geodesate(float radius)
        {
            float rInv             = 1.0f / radius;
            var   polygonCentroids = PolygonAttributes.FindOrNull <Vector3>("polygon_centroids");
            var   polygonNormals   = PolygonAttributes.FindOrNull <Vector3>("polygon_normals");
            var   pointLocations   = PointAttributes.FindOrNull <Vector3>("point_locations");
            var   pointNormals     = PointAttributes.FindOrNull <Vector3>("point_normals");
            var   cornerNormals    = CornerAttributes.FindOrNull <Vector3>("corner_normals");

            //  Make copies of old points
            foreach (Point point in Points)
            {
                if (
                    (pointLocations != null) &&
                    pointLocations.ContainsKey(point)
                    )
                {
                    Vector3 newNormal = Vector3.Normalize(pointLocations[point]);
                    pointLocations[point] = radius * newNormal;
                    if (
                        (pointNormals != null) &&
                        pointNormals.ContainsKey(point)
                        )
                    {
                        pointNormals[point] = newNormal;
                    }
                }
            }
            foreach (Polygon polygon in Polygons)
            {
                if (
                    (polygonCentroids != null) &&
                    polygonCentroids.ContainsKey(polygon)
                    )
                {
                    Vector3 newNormalizedCentroid = Vector3.Normalize(polygonCentroids[polygon]);
                    polygonCentroids[polygon] = radius * newNormalizedCentroid;
                    if (
                        (polygonNormals != null) &&
                        polygonNormals.ContainsKey(polygon)
                        )
                    {
                        polygonNormals[polygon] = newNormalizedCentroid;
                    }
                }
                if (cornerNormals != null)
                {
                    foreach (Corner corner in polygon.Corners)
                    {
                        if (
                            cornerNormals.ContainsKey(corner)
                            )
                        {
                            if (pointNormals.ContainsKey(corner.Point))
                            {
                                cornerNormals[corner] = pointNormals[corner.Point];
                            }
                            else if (pointLocations.ContainsKey(corner.Point))
                            {
                                cornerNormals[corner] = pointLocations[corner.Point] * rInv;
                            }
                        }
                    }
                }
            }
        }
示例#5
0
        public void MergeFast(Geometry other, Polygon thisPolygon, Polygon otherPolygon)
        {
            Dictionary <Point, Point> otherPointsToNewPoints = new Dictionary <Point, Point>();

            var   pointLocationsSelf  = PointAttributes.FindOrNull <Vector3>("point_locations");
            var   pointLocationsOther = other.PointAttributes.FindOrNull <Vector3>("point_locations");
            float pointEpsilon        = 0.0001f;

            //  Merge points
            foreach (Point otherPoint in other.Points)
            {
                Vector3 otherPosition = pointLocationsOther[otherPoint];

                bool existingPointCloseEnough = false;
                foreach (Corner existingCorner in thisPolygon.Corners)
                {
                    Point   existingPoint    = existingCorner.Point;
                    Vector3 existingPosition = pointLocationsSelf[existingPoint];

                    float distanceSquared = existingPosition.DistanceSquared(otherPosition);

                    if (distanceSquared < pointEpsilon)
                    {
                        existingPointCloseEnough           = true;
                        otherPointsToNewPoints[otherPoint] = existingPoint;
                        break;
                    }
                }
                if (existingPointCloseEnough == false)
                {
                    otherPointsToNewPoints[otherPoint] = MakePoint(otherPosition);
                }
            }

            RemovePolygon(thisPolygon);

            //  Merge polygons
            foreach (Polygon otherPolygon2 in other.Polygons)
            {
                if (otherPolygon != otherPolygon2)
                {
                    Polygon newPolygon = MakePolygon();
                    foreach (Corner otherCorner in otherPolygon.Corners)
                    {
                        Point otherPoint = otherCorner.Point;
                        Point newPoint   = otherPointsToNewPoints[otherPoint];
                        newPolygon.MakeCorner(newPoint);
                    }
                }
            }

            //  Finally, remove unused points
            HashSet <Point> usedPoints = new HashSet <Point>();

            foreach (Polygon polygon in Polygons)
            {
                foreach (Corner corner in polygon.Corners)
                {
                    usedPoints.Add(corner.Point);
                }
            }
            List <Point> pointsToRemove = new List <Point>();

            foreach (Point point in Points)
            {
                if (usedPoints.Contains(point) == false)
                {
                    pointsToRemove.Add(point);
                }
            }
            foreach (Point pointToRemove in pointsToRemove)
            {
                Points.Remove(pointToRemove);
            }
        }
示例#6
0
        /// \todo Accelerate by sorting along major axis
        public void Merge(Geometry other)
        {
            Dictionary <Point, Point> otherPointsToNewPoints = new Dictionary <Point, Point>();

            var   pointLocationsSelf  = PointAttributes.FindOrNull <Vector3>("point_locations");
            var   pointLocationsOther = other.PointAttributes.FindOrNull <Vector3>("point_locations");
            float pointEpsilon        = 0.0001f;

            //  Merge points
            foreach (Point otherPoint in other.Points)
            {
                Vector3 otherPosition = pointLocationsOther[otherPoint];

                bool existingPointCloseEnough = false;
                foreach (Point existingPoint in Points)
                {
                    Vector3 existingPosition = pointLocationsSelf[existingPoint];

                    float distanceSquared = existingPosition.DistanceSquared(otherPosition);

                    if (distanceSquared < pointEpsilon)
                    {
                        existingPointCloseEnough           = true;
                        otherPointsToNewPoints[otherPoint] = existingPoint;
                        break;
                    }
                }
                if (existingPointCloseEnough == false)
                {
                    otherPointsToNewPoints[otherPoint] = MakePoint(otherPosition);
                }
            }

            //  Merge polygons
            foreach (Polygon otherPolygon in other.Polygons)
            {
                //  Test if we can find at least single matching polygon
                Polygon matchingPolygon = null;
                foreach (Polygon existingPolygon in Polygons)
                {
                    //  Test that all other corners can be found
                    bool missingCorners = false;
                    foreach (Corner otherCorner in otherPolygon.Corners)
                    {
                        Point newPoint    = otherPointsToNewPoints[otherCorner.Point];
                        bool  cornerFound = false;
                        //  Find matching corner
                        foreach (Corner existingCorner in existingPolygon.Corners)
                        {
                            if (newPoint == existingCorner.Point)
                            {
                                cornerFound = true;
                                break;
                            }
                        }
                        //  No matching corner found, continue
                        if (cornerFound == false)
                        {
                            missingCorners = true;
                            break;
                        }
                    }
                    if (missingCorners == true)
                    {
                        continue;
                    }
                    //  No missing corners - polygons match
                    matchingPolygon = existingPolygon;
                    break;
                }

                if (matchingPolygon != null)
                {
                    //  There was a matching polygon, delete it and do not create new from other
                    RemovePolygon(matchingPolygon);
                    //Polygons.Remove(matchingPolygon);
                }
                else
                {
                    //  There was no match, add new from other
                    Polygon newPolygon = MakePolygon();
                    foreach (Corner otherCorner in otherPolygon.Corners)
                    {
                        Point otherPoint = otherCorner.Point;
                        Point newPoint   = otherPointsToNewPoints[otherPoint];
                        newPolygon.MakeCorner(newPoint);
                    }
                }
            }

            //  Finally, remove unused points
            HashSet <Point> usedPoints = new HashSet <Point>();

            foreach (Polygon polygon in Polygons)
            {
                foreach (Corner corner in polygon.Corners)
                {
                    usedPoints.Add(corner.Point);
                }
            }
            List <Point> pointsToRemove = new List <Point>();

            foreach (Point point in Points)
            {
                if (usedPoints.Contains(point) == false)
                {
                    pointsToRemove.Add(point);
                }
            }
            foreach (Point pointToRemove in pointsToRemove)
            {
                Points.Remove(pointToRemove);
            }
        }