Esempio n. 1
0
        /// <summary>
        /// Use the render packages returned from the visualization manager to update the visuals.
        /// The visualization event arguments will contain a set of render packages and an id representing 
        /// the associated node. Visualizations for the background preview will return an empty id.
        /// </summary>
        /// <param name="e"></param>
        public void RenderDrawables(VisualizationEventArgs e)
        {
            //check the id, if the id is meant for another watch,
            //then ignore it
            if (e.Id != _id)
            {
                return;
            }

            Debug.WriteLine(string.Format("Rendering visuals for {0}", e.Id));

            var sw = new Stopwatch();
            sw.Start();

            Points = null;
            Lines = null;
            Mesh = null;
            XAxes = null;
            YAxes = null;
            ZAxes = null;
            PointsSelected = null;
            LinesSelected = null;
            MeshSelected = null;
            Text = null;
            MeshCount = 0;

            //separate the selected packages
            var packages = e.Packages.Where(x => x.Selected == false)
                .Where(rp=>rp.TriangleVertices.Count % 9 == 0)
                .ToArray();
            var selPackages = e.Packages
                .Where(x => x.Selected)
                .Where(rp => rp.TriangleVertices.Count % 9 == 0)
                .ToArray();

            //pre-size the points collections
            var pointsCount = packages.Select(x => x.PointVertices.Count/3).Sum();
            var selPointsCount = selPackages.Select(x => x.PointVertices.Count / 3).Sum();
            var points = new Point3DCollection(pointsCount);
            var pointsSelected = new Point3DCollection(selPointsCount);

            //pre-size the lines collections
            //these sizes are conservative as the axis lines will be
            //taken from the linestripvertex collections as well.
            var lineCount = packages.Select(x => x.LineStripVertices.Count/3).Sum();
            var lineSelCount = selPackages.Select(x => x.LineStripVertices.Count / 3).Sum();
            var lines = new Point3DCollection(lineCount);
            var linesSelected = new Point3DCollection(lineSelCount);
            var redLines = new Point3DCollection(lineCount);
            var greenLines = new Point3DCollection(lineCount);
            var blueLines = new Point3DCollection(lineCount);

            //pre-size the text collection
            var textCount = e.Packages.Count(x => x.DisplayLabels);
            var text = new List<BillboardTextItem>(textCount);

            //http://blogs.msdn.com/b/timothyc/archive/2006/08/31/734308.aspx
            //presize the mesh collections
            var meshVertCount = packages.Select(x => x.TriangleVertices.Count / 3).Sum();
            var meshVertSelCount = selPackages.Select(x => x.TriangleVertices.Count / 3).Sum();

            var mesh = new MeshGeometry3D();
            var meshSel = new MeshGeometry3D();
            var verts = new Point3DCollection(meshVertCount);
            var vertsSel = new Point3DCollection(meshVertSelCount);
            var norms = new Vector3DCollection(meshVertCount);
            var normsSel = new Vector3DCollection(meshVertSelCount);
            var tris = new Int32Collection(meshVertCount);
            var trisSel = new Int32Collection(meshVertSelCount);
                
            foreach (var package in packages)
            {
                ConvertPoints(package, points, text);
                ConvertLines(package, lines, redLines, greenLines, blueLines, text);
                ConvertMeshes(package, verts, norms, tris);
            }

            foreach (var package in selPackages)
            {
                ConvertPoints(package, pointsSelected, text);
                ConvertLines(package, linesSelected, redLines, greenLines, blueLines, text);
                ConvertMeshes(package, vertsSel, normsSel, trisSel);
            }

            sw.Stop();
            Debug.WriteLine(string.Format("RENDER: {0} ellapsed for updating background preview.", sw.Elapsed));

            var vm = (IWatchViewModel)DataContext;
            if (vm.CheckForLatestRenderCommand.CanExecute(e.TaskId))
            {
                vm.CheckForLatestRenderCommand.Execute(e.TaskId);
            }

            points.Freeze();
            pointsSelected.Freeze();
            lines.Freeze();
            linesSelected.Freeze();
            redLines.Freeze();
            greenLines.Freeze();
            blueLines.Freeze();
            verts.Freeze();
            norms.Freeze();
            tris.Freeze();
            vertsSel.Freeze();
            normsSel.Freeze();
            trisSel.Freeze();

            Dispatcher.Invoke(new Action<Point3DCollection, Point3DCollection,
                Point3DCollection, Point3DCollection, Point3DCollection, Point3DCollection,
                Point3DCollection, Point3DCollection, Vector3DCollection, Int32Collection, 
                Point3DCollection, Vector3DCollection, Int32Collection, MeshGeometry3D,
                MeshGeometry3D, List<BillboardTextItem>>(SendGraphicsToView), DispatcherPriority.Render,
                               new object[] {points, pointsSelected, lines, linesSelected, redLines, 
                                   greenLines, blueLines, verts, norms, tris, vertsSel, normsSel, 
                                   trisSel, mesh, meshSel, text});
        }
        /// <summary>
        /// Creates a billboard.
        /// </summary>
        /// <param name="position">The position (centre).</param>
        /// <param name="width">The width of the billboard.</param>
        /// <param name="height">The height of the billboard.</param>
        /// <param name="depthOffset">The depth offset.</param>
        /// <returns>The points of the billboard.</returns>
        public Point3DCollection CreateBillboard(Point3D position, double width = 1.0, double height = 1.0, double depthOffset = 0.0)
        {
            double halfWidth = width / 2.0;
            double halfHeight = height / 2.0;

            var outline = new[]
                {
                    new Vector(-halfWidth, halfHeight), new Vector(-halfWidth, -halfHeight), new Vector(halfWidth, halfHeight),
                    new Vector(halfWidth, -halfHeight)
                };

            var positions = new Point3DCollection(4);

                var screenPoint = (Point4D)position * this.visualToScreen;
                foreach (var v in outline)
                {
                    var p = screenPoint;
                    p.X += v.X * p.W;
                    p.Y += v.Y * p.W;
                    if (depthOffset != 0)
                    {
                        p.Z -= depthOffset * p.W;
                        p *= this.screenToVisual;
                        positions.Add(new Point3D(p.X / p.W, p.Y / p.W, p.Z / p.W));
                    }
                    else
                    {
                        p *= this.screenToVisual;
                        Debug.Assert(Math.Abs(p.W - 1) < 1e-6, "Something wrong with the homogeneous coordinates.");
                        positions.Add(new Point3D(p.X, p.Y, p.Z));
                    }
                }

            positions.Freeze();
            return positions;
        }
        /// <summary>
        /// Creates the positions for the specified points.
        /// </summary>
        /// <param name="points">
        /// The points.
        /// </param>
        /// <param name="size">
        /// The size of the points.
        /// </param>
        /// <param name="depthOffset">
        /// The depth offset. A positive number (e.g. 0.0001) moves the point towards the camera.
        /// </param>
        /// <returns>
        /// The positions collection.
        /// </returns>
        public Point3DCollection CreatePositions(IList<Point3D> points, double size = 1.0, double depthOffset = 0.0)
        {
            double halfSize = size / 2.0;
            int numPoints = points.Count;

            var outline = new[]
                {
                    new Vector(-halfSize, halfSize), new Vector(-halfSize, -halfSize), new Vector(halfSize, halfSize),
                    new Vector(halfSize, -halfSize)
                };

            var positions = new Point3DCollection(numPoints * 4);

            for (int i = 0; i < numPoints; i++)
            {
                var screenPoint = (Point4D)points[i] * this.visualToScreen;
                foreach (var v in outline)
                {
                    var p = screenPoint;
                    p.X += v.X * p.W;
                    p.Y += v.Y * p.W;
                    if (depthOffset != 0)
                    {
                        p.Z -= depthOffset * p.W;
                        p *= this.screenToVisual;
                        positions.Add(new Point3D(p.X / p.W, p.Y / p.W, p.Z / p.W));
                    }
                    else
                    {
                        p *= this.screenToVisual;
                        Debug.Assert(Math.Abs(p.W - 1) < 1e-6, "Something wrong with the homogeneous coordinates.");
                        positions.Add(new Point3D(p.X, p.Y, p.Z));
                    }
                }
            }

            positions.Freeze();
            return positions;
        }
        /// <summary>
        /// Gets the billboard positions with the current screen transform.
        /// </summary>
        /// <param name="billboards">The billboards.</param>
        /// <param name="offset">The offset.</param>
        /// <param name="pinWidth">Width of the pins.</param>
        /// <returns>The mesh vertices.</returns>
        public Point3DCollection GetPinPositions(IList<Billboard> billboards, Vector offset, double pinWidth)
        {
            var pinStart = new Point(0, 0);
            var pinEnd = pinStart + (offset * (1 + (2 * pinWidth / offset.Length)));
            var pinNormal = new Vector(pinEnd.Y, -pinEnd.X);
            pinNormal.Normalize();
            pinNormal *= pinWidth * 0.5;

            var pinPoints = new Point[4];
            pinPoints[0] = new Point(0, 0) + (pinNormal * 0.5);
            pinPoints[1] = new Point(0, 0) - (pinNormal * 0.5);
            pinPoints[2] = pinEnd - pinNormal;
            pinPoints[3] = pinEnd + pinNormal;

            var positions = new Point3DCollection(billboards.Count * 4);
            foreach (var bb in billboards)
            {
                Point4D screenPoint;
                if (!bb.WorldDepthOffset.Equals(0))
                {
                    var viewPoint = (Point4D)bb.Position * this.visualToProjection;
                    screenPoint = new Point4D(viewPoint.X, viewPoint.Y, viewPoint.Z + bb.WorldDepthOffset, viewPoint.W) * this.projectionToScreen;
                }
                else
                {
                    screenPoint = (Point4D)bb.Position * this.visualToScreen;
                }

                double spw = screenPoint.W;
                double spx = screenPoint.X;
                double spy = screenPoint.Y;
                double spz = screenPoint.Z - ((bb.DepthOffset - 1e-5) * spw);

                foreach (var pinPoint in pinPoints)
                {
                    var p = new Point4D(spx + (pinPoint.X * spw), spy + (pinPoint.Y * spw), spz, spw) * this.screenToVisual;
                    double wi = 1 / p.W;
                    positions.Add(new Point3D(p.X * wi, p.Y * wi, p.Z * wi));
                }
            }

            positions.Freeze();
            return positions;
        }
        /// <summary>
        /// Gets the billboard positions with the current screen transform.
        /// </summary>
        /// <param name="billboards">The billboards.</param>
        /// <param name="offset">The offset.</param>
        /// <returns>The positions.</returns>
        public Point3DCollection GetPositions(IList<Billboard> billboards, Vector offset)
        {
            var positions = new Point3DCollection(billboards.Count * 4);

            foreach (var bb in billboards)
            {
                Point4D screenPoint;
                if (!bb.WorldDepthOffset.Equals(0))
                {
                    var viewPoint = (Point4D)bb.Position * this.visualToProjection;
                    screenPoint = new Point4D(viewPoint.X, viewPoint.Y, viewPoint.Z + bb.WorldDepthOffset, viewPoint.W) * this.projectionToScreen;
                }
                else
                {
                    screenPoint = (Point4D)bb.Position * this.visualToScreen;
                }

                double spw = screenPoint.W;
                double spx = screenPoint.X;
                double spy = screenPoint.Y;
                double spz = screenPoint.Z - (bb.DepthOffset * spw);

                // Convert bottom-left corner to visual space
                var p = new Point4D(spx + ((bb.Left + offset.X) * spw), spy + ((bb.Bottom + offset.Y) * spw), spz, spw) * this.screenToVisual;
                double wi = 1 / p.W;
                positions.Add(new Point3D(p.X * wi, p.Y * wi, p.Z * wi));

                // Convert bottom-right corner to visual space
                p = new Point4D(spx + ((bb.Right + offset.X) * spw), spy + ((bb.Bottom + offset.Y) * spw), spz, spw) * this.screenToVisual;
                wi = 1 / p.W;
                positions.Add(new Point3D(p.X * wi, p.Y * wi, p.Z * wi));

                // Convert top-right corner to visual space
                p = new Point4D(spx + ((bb.Right + offset.X) * spw), spy + ((bb.Top + offset.Y) * spw), spz, spw) * this.screenToVisual;
                wi = 1 / p.W;
                positions.Add(new Point3D(p.X * wi, p.Y * wi, p.Z * wi));

                // Convert top-left corner to visual space
                p = new Point4D(spx + ((bb.Left + offset.X) * spw), spy + ((bb.Top + offset.Y) * spw), spz, spw) * this.screenToVisual;
                wi = 1 / p.W;
                positions.Add(new Point3D(p.X * wi, p.Y * wi, p.Z * wi));
            }

            positions.Freeze();
            return positions;
        }
Esempio n. 6
0
        private void RebuildGeometry()
        {
            Point3DCollection points = new Point3DCollection(4);
            foreach (Point3D p3d in _Points)
            {
                Vector3D dir = (p3d - _CenterPoint) * _visualToScreen;
                dir.Z = 0;
                dir.Normalize();
                Vector delta = new Vector(-dir.Y, dir.X);

                Point4D pIn4 = (Point4D)(new Point3D(p3d.X - _CenterPoint.X, p3d.Y - _CenterPoint.Y, p3d.Z - _CenterPoint.Z));
                Point4D pOut4 = pIn4 * _visualToScreen;
                pOut4.X += delta.X * pOut4.W;
                pOut4.Y += delta.Y * pOut4.W;
                pOut4 *= _screenToVisual;
                Point3D pOut = new Point3D(
                    pOut4.X / pOut4.W * (_TextWidth / (2d * WidthSizeFactor)) + _CenterPoint.X,
                    pOut4.Y / pOut4.W * (_TextHeight / (2d * HeightSizeFactor)) + _CenterPoint.Y,
                    pOut4.Z / pOut4.W + _CenterPoint.Z);
                points.Add(pOut);
            }
            points.Freeze();
            _mesh.Positions = points;
        }
        /// <summary>
        /// Creates the positions for the specified line segments.
        /// </summary>
        /// <param name="points">
        /// The points of the line segments.
        /// </param>
        /// <param name="thickness">
        /// The thickness of the line.
        /// </param>
        /// <param name="depthOffset">
        /// The depth offset. A positive number (e.g. 0.0001) moves the point towards the camera.
        /// </param>
        /// <param name="clipping">
        /// The clipping.
        /// </param>
        /// <returns>
        /// The positions collection.
        /// </returns>
        public Point3DCollection CreatePositions(
            IList<Point3D> points,
            double thickness = 1.0,
            double depthOffset = 0.0,
            CohenSutherlandClipping clipping = null)
        {
            var halfThickness = thickness * 0.5;
            var segmentCount = points.Count / 2;

            var positions = new Point3DCollection(segmentCount * 4);

            for (int i = 0; i < segmentCount; i++)
            {
                int startIndex = i * 2;

                var startPoint = points[startIndex];
                var endPoint = points[startIndex + 1];

                // Transform the start and end points to screen space
                var s0 = (Point4D)startPoint * this.visualToScreen;
                var s1 = (Point4D)endPoint * this.visualToScreen;

                if (clipping != null)
                {
                    // Apply a clipping rectangle
                    var x0 = s0.X / s0.W;
                    var y0 = s0.Y / s0.W;
                    var x1 = s1.X / s1.W;
                    var y1 = s1.Y / s1.W;

                    if (!clipping.ClipLine(ref x0, ref y0, ref x1, ref y1))
                    {
                        continue;
                    }

                    s0.X = x0 * s0.W;
                    s0.Y = y0 * s0.W;
                    s1.X = x1 * s1.W;
                    s1.Y = y1 * s1.W;
                }

                var lx = (s1.X / s1.W) - (s0.X / s0.W);
                var ly = (s1.Y / s1.W) - (s0.Y / s0.W);
                var l2 = (lx * lx) + (ly * ly);

                var p00 = s0;
                var p01 = s0;
                var p10 = s1;
                var p11 = s1;

                if (l2.Equals(0))
                {
                    // coinciding points (in world space or screen space)
                    var dz = halfThickness;

                    // TODO: make a square with the thickness as side length
                    p00.X -= dz * p00.W;
                    p00.Y -= dz * p00.W;

                    p01.X -= dz * p01.W;
                    p01.Y += dz * p01.W;

                    p10.X += dz * p10.W;
                    p10.Y -= dz * p10.W;

                    p11.X += dz * p11.W;
                    p11.Y += dz * p11.W;
                }
                else
                {
                    var m = halfThickness / Math.Sqrt(l2);

                    // the normal (dx,dy)
                    var dx = -ly * m;
                    var dy = lx * m;

                    // segment start points
                    p00.X += dx * p00.W;
                    p00.Y += dy * p00.W;
                    p01.X -= dx * p01.W;
                    p01.Y -= dy * p01.W;

                    // segment end points
                    p10.X += dx * p10.W;
                    p10.Y += dy * p10.W;
                    p11.X -= dx * p11.W;
                    p11.Y -= dy * p11.W;
                }

                if (!depthOffset.Equals(0))
                {
                    // Adjust the z-coordinate by the depth offset
                    p00.Z -= depthOffset;
                    p01.Z -= depthOffset;
                    p10.Z -= depthOffset;
                    p11.Z -= depthOffset;

                    // Transform from screen space to world space
                    p00 *= this.screenToVisual;
                    p01 *= this.screenToVisual;
                    p10 *= this.screenToVisual;
                    p11 *= this.screenToVisual;

                    positions.Add(new Point3D(p00.X / p00.W, p00.Y / p00.W, p00.Z / p00.W));
                    positions.Add(new Point3D(p01.X / p00.W, p01.Y / p01.W, p01.Z / p01.W));
                    positions.Add(new Point3D(p10.X / p00.W, p10.Y / p10.W, p10.Z / p10.W));
                    positions.Add(new Point3D(p11.X / p00.W, p11.Y / p11.W, p11.Z / p11.W));
                }
                else
                {
                    // Transform from screen space to world space
                    p00 *= this.screenToVisual;
                    p01 *= this.screenToVisual;
                    p10 *= this.screenToVisual;
                    p11 *= this.screenToVisual;

                    positions.Add(new Point3D(p00.X, p00.Y, p00.Z));
                    positions.Add(new Point3D(p01.X, p01.Y, p01.Z));
                    positions.Add(new Point3D(p10.X, p10.Y, p10.Z));
                    positions.Add(new Point3D(p11.X, p11.Y, p11.Z));
                }
            }

            positions.Freeze();
            return positions;
        }
Esempio n. 8
0
            private static Model3D GenerateTreeMap3DModel(int index, int count)
            {
                MeshGeometry3D meshGeometry3D = new MeshGeometry3D();

                Point3DCollection positions = new Point3DCollection();
                positions.Add(new Point3D(0, 0, 1));
                positions.Add(new Point3D(0, 0, 0));
                positions.Add(new Point3D(1, 0, 0));
                positions.Add(new Point3D(1, 0, 1));
                positions.Add(new Point3D(0, 1, 1));
                positions.Add(new Point3D(0, 1, 0));
                positions.Add(new Point3D(1, 1, 0));
                positions.Add(new Point3D(1, 1, 1));
                positions.Freeze();

                Int32Collection triangleIndices = new Int32Collection();
                triangleIndices.Add(0);
                triangleIndices.Add(1);
                triangleIndices.Add(2);

                triangleIndices.Add(2);
                triangleIndices.Add(3);
                triangleIndices.Add(0);

                triangleIndices.Add(4);
                triangleIndices.Add(7);
                triangleIndices.Add(6);

                triangleIndices.Add(6);
                triangleIndices.Add(5);
                triangleIndices.Add(4);

                triangleIndices.Add(0);
                triangleIndices.Add(3);
                triangleIndices.Add(7);

                triangleIndices.Add(7);
                triangleIndices.Add(4);
                triangleIndices.Add(0);

                triangleIndices.Add(1);
                triangleIndices.Add(5);
                triangleIndices.Add(6);

                triangleIndices.Add(6);
                triangleIndices.Add(2);
                triangleIndices.Add(1);

                triangleIndices.Add(3);
                triangleIndices.Add(2);
                triangleIndices.Add(6);

                triangleIndices.Add(6);
                triangleIndices.Add(7);
                triangleIndices.Add(3);

                triangleIndices.Add(0);
                triangleIndices.Add(4);
                triangleIndices.Add(5);

                triangleIndices.Add(5);
                triangleIndices.Add(7);
                triangleIndices.Add(0);

                triangleIndices.Freeze();

                // finally set the data
                meshGeometry3D.TriangleIndices = triangleIndices;
                meshGeometry3D.Positions = positions;

                // create the geometry model
                GeometryModel3D geom3D = new GeometryModel3D();
                geom3D.Geometry = meshGeometry3D;

                Color color = ColorHelper.HsbToRgb(index / (float)count, .9f, 1f);
                SolidColorBrush solidColorBrush = color.ToBrush();
                solidColorBrush.Freeze();

                geom3D.Material = new DiffuseMaterial(solidColorBrush);

                return geom3D;
            }
        private void RebuildGeometry()
        {
            double halfThickness = Thickness / 2.0;
            int numLines = Points.Count / 2;

            Point3DCollection positions = new Point3DCollection(numLines * 4);

            for (int i = 0; i < numLines; i++)
            {
                int startIndex = i * 2;

                Point3D startPoint = Points[startIndex];
                Point3D endPoint = Points[startIndex + 1];

                AddSegment(positions, startPoint, endPoint, halfThickness);
            }

            positions.Freeze();
            _mesh.Positions = positions;

            Int32Collection indices = new Int32Collection(Points.Count * 3);

            for (int i = 0; i < Points.Count / 2; i++)
            {
                indices.Add(i * 4 + 2);
                indices.Add(i * 4 + 1);
                indices.Add(i * 4 + 0);

                indices.Add(i * 4 + 2);
                indices.Add(i * 4 + 3);
                indices.Add(i * 4 + 1);
            }

            indices.Freeze();
            _mesh.TriangleIndices = indices;
        }
Esempio n. 10
0
        /// <summary>
        /// Creates the positions for the specified points.
        /// </summary>
        /// <param name="points">
        /// The points.
        /// </param>
        /// <param name="size">
        /// The size of the points.
        /// </param>
        /// <param name="depthOffset">
        /// The depth offset. A positive number (e.g. 0.0001) moves the point towards the camera.
        /// </param>
        /// <returns>
        /// The positions collection.
        /// </returns>
        public Point3DCollection CreatePositions(IList<Point3D> points, double size = 1.0, double depthOffset = 0.0)
        {
            double halfSize = size / 2.0;
            int numPoints = points.Count;

            var outline = new[]
                {
                    new Vector(-halfSize, halfSize), new Vector(-halfSize, -halfSize), new Vector(halfSize, halfSize),
                    new Vector(halfSize, -halfSize)
                };

            var positions = new Point3DCollection(numPoints * 4);

            for (int i = 0; i < numPoints; i++)
            {
                var screenPoint = (Point4D)points[i] * this.visualToScreen;

                double spx = screenPoint.X;
                double spy = screenPoint.Y;
                double spz = screenPoint.Z;
                double spw = screenPoint.W;

                if (!depthOffset.Equals(0))
                {
                    spz -= depthOffset * spw;
                }

                var p0 = new Point4D(spx, spy, spz, spw) * this.screenToVisual;
                double pwinverse = 1 / p0.W;

                foreach (var v in outline)
                {
                    var p = new Point4D(spx + v.X * spw, spy + v.Y * spw, spz, spw) * this.screenToVisual;
                    positions.Add(new Point3D(p.X * pwinverse, p.Y * pwinverse, p.Z * pwinverse));
                }
            }

            positions.Freeze();
            return positions;
        }
        /// <summary>
        /// Gets the billboard positions with the current screen transform.
        /// </summary>
        /// <returns>The positions.</returns>
        public Point3DCollection GetPositions(IList<Billboard> billboards)
        {
            var positions = new Point3DCollection(billboards.Count * 4);
            foreach (var bb in billboards)
            {
                var screenPoint = (Point4D)bb.Position * this.visualToScreen;

                double spx = screenPoint.X;
                double spy = screenPoint.Y;
                double spz = screenPoint.Z;
                double spw = screenPoint.W;

                if (!bb.DepthOffset.Equals(0))
                {
                    spz -= bb.DepthOffset * spw;
                }

                var p0 = new Point4D(spx, spy, spz, spw) * this.screenToVisual;
                double pwinverse = 1 / p0.W;

                var p1 = new Point4D(spx + bb.Left * spw, spy + bb.Bottom * spw, spz, spw) * this.screenToVisual;
                positions.Add(new Point3D(p1.X * pwinverse, p1.Y * pwinverse, p1.Z * pwinverse));

                var p2 = new Point4D(spx + bb.Right * spw, spy + bb.Bottom * spw, spz, spw) * this.screenToVisual;
                positions.Add(new Point3D(p2.X * pwinverse, p2.Y * pwinverse, p2.Z * pwinverse));

                var p3 = new Point4D(spx + bb.Right * spw, spy + bb.Top * spw, spz, spw) * this.screenToVisual;
                positions.Add(new Point3D(p3.X * pwinverse, p3.Y * pwinverse, p3.Z * pwinverse));

                var p4 = new Point4D(spx + bb.Left * spw, spy + bb.Top * spw, spz, spw) * this.screenToVisual;
                positions.Add(new Point3D(p4.X * pwinverse, p4.Y * pwinverse, p4.Z * pwinverse));
            }

            positions.Freeze();
            return positions;
        }
        /// <summary>
        /// Creates the positions for the specified line segments.
        /// </summary>
        /// <param name="points">
        /// The points of the line segments.
        /// </param>
        /// <param name="thickness">
        /// The thickness of the line.
        /// </param>
        /// <param name="depthOffset">
        /// The depth offset. A positive number (e.g. 0.0001) moves the point towards the camera.
        /// </param>
        /// <param name="clipping">
        /// The clipping.
        /// </param>
        /// <returns>
        /// The positions collection.
        /// </returns>
        public Point3DCollection CreatePositions(
            IList<Point3D> points,
            double thickness = 1.0,
            double depthOffset = 0.0,
            CohenSutherlandClipping clipping = null)
        {
            double halfThickness = thickness * 0.5;
            int segmentCount = points.Count / 2;

            var positions = new Point3DCollection(segmentCount * 4);

            for (int i = 0; i < segmentCount; i++)
            {
                int startIndex = i * 2;

                Point3D startPoint = points[startIndex];
                Point3D endPoint = points[startIndex + 1];

                var s0 = (Point4D)startPoint * this.visualToScreen;
                var s1 = (Point4D)endPoint * this.visualToScreen;

                if (clipping != null)
                {
                    double x0 = s0.X / s0.W;
                    double y0 = s0.Y / s0.W;
                    double x1 = s1.X / s1.W;
                    double y1 = s1.Y / s1.W;

                    if (!clipping.ClipLine(ref x0, ref y0, ref x1, ref y1))
                    {
                        continue;
                    }

                    s0.X = x0 * s0.W;
                    s0.Y = y0 * s0.W;
                    s1.X = x1 * s1.W;
                    s1.Y = y1 * s1.W;
                }

                double lx = s1.X / s1.W - s0.X / s0.W;
                double ly = s1.Y / s1.W - s0.Y / s0.W;
                double m = halfThickness / Math.Sqrt(lx * lx + ly * ly);

                double dx = -ly * m;
                double dy = lx * m;

                var p00 = s0;
                var p01 = s0;
                var p10 = s1;
                var p11 = s1;

                p00.X += dx * p00.W;
                p00.Y += dy * p00.W;
                p01.X -= dx * p01.W;
                p01.Y -= dy * p01.W;
                p10.X += dx * p10.W;
                p10.Y += dy * p10.W;
                p11.X -= dx * p11.W;
                p11.Y -= dy * p11.W;
                if (depthOffset != 0)
                {
                    p00.Z -= depthOffset;
                    p01.Z -= depthOffset;
                    p10.Z -= depthOffset;
                    p11.Z -= depthOffset;

                    p00 *= this.screenToVisual;
                    p01 *= this.screenToVisual;
                    p10 *= this.screenToVisual;
                    p11 *= this.screenToVisual;

                    positions.Add(new Point3D(p00.X / p00.W, p00.Y / p00.W, p00.Z / p00.W));
                    positions.Add(new Point3D(p01.X / p00.W, p01.Y / p01.W, p01.Z / p01.W));
                    positions.Add(new Point3D(p10.X / p00.W, p10.Y / p10.W, p10.Z / p10.W));
                    positions.Add(new Point3D(p11.X / p00.W, p11.Y / p11.W, p11.Z / p11.W));
                }
                else
                {
                    p00 *= this.screenToVisual;
                    p01 *= this.screenToVisual;
                    p10 *= this.screenToVisual;
                    p11 *= this.screenToVisual;

                    positions.Add(new Point3D(p00.X, p00.Y, p00.Z));
                    positions.Add(new Point3D(p01.X, p01.Y, p01.Z));
                    positions.Add(new Point3D(p10.X, p10.Y, p10.Z));
                    positions.Add(new Point3D(p11.X, p11.Y, p11.Z));
                }
            }

            positions.Freeze();
            return positions;
        }
Esempio n. 13
0
        private void SetPoints()
        {
            if (!this.ShowLinesVisual3D)
            {
                this.LinePoints.Clear();
            }

            if (!this.ShowPointsVisual3D)
            {
                this.Points.Clear();
            }

            if (this.ShowLinesVisual3D || this.ShowPointsVisual3D)
            {
                var newPoints =
                    PointsAndLinesDemo.MainWindow.GeneratePoints(this.NumberOfPoints, this.watch.ElapsedMilliseconds * 0.001)
                        .ToArray();
                if (this.ShowPointsVisual3D)
                {
                    var pc = new Point3DCollection(newPoints);
                    pc.Freeze();
                    this.Points = pc;
                }

                if (this.ShowLinesVisual3D)
                {
                    var pc = new Point3DCollection(newPoints);
                    pc.Freeze();
                    this.LinePoints = pc;
                }
            }
        }
Esempio n. 14
0
        /// <summary>
        /// Use the render packages returned from the visualization manager to update the visuals.
        /// The visualization event arguments will contain a set of render packages and an id representing 
        /// the associated node. Visualizations for the background preview will return an empty id.
        /// </summary>
        /// <param name="e"></param>
        private void RenderDrawables(VisualizationEventArgs e)
        {
            try
            {
                //check the id, if the id is meant for another watch,
                //then ignore it
                if (e.Id != _id)
                {
                    return;
                }

                var sw = new Stopwatch();
                sw.Start();

                Points = null;
                Lines = null;
                Mesh = null;
                XAxes = null;
                YAxes = null;
                ZAxes = null;
                PointsSelected = null;
                LinesSelected = null;
                MeshSelected = null;
                Text = null;
                MeshCount = 0;

                //separate the selected packages
                var packages = e.Packages.Where(x => x.Selected == false).ToArray();
                var selPackages = e.Packages.Where(x => x.Selected).ToArray();

                //pre-size the points collections
                var pointsCount = packages.Select(x => x.PointVertices.Count/3).Sum();
                var selPointsCount = selPackages.Select(x => x.PointVertices.Count / 3).Sum();
                var points = new Point3DCollection(pointsCount);
                var pointsSelected = new Point3DCollection(selPointsCount);

                //pre-size the lines collections
                //these sizes are conservative as the axis lines will be
                //taken from the linestripvertex collections as well.
                var lineCount = packages.Select(x => x.LineStripVertices.Count/3).Sum();
                var lineSelCount = selPackages.Select(x => x.LineStripVertices.Count / 3).Sum();
                var lines = new Point3DCollection(lineCount);
                var linesSelected = new Point3DCollection(lineSelCount);
                var redLines = new Point3DCollection(lineCount);
                var greenLines = new Point3DCollection(lineCount);
                var blueLines = new Point3DCollection(lineCount);

                //pre-size the text collection
                var textCount = e.Packages.Count(x => x.DisplayLabels);
                var text = new List<BillboardTextItem>(textCount);

                //http://blogs.msdn.com/b/timothyc/archive/2006/08/31/734308.aspx
                //presize the mesh collections
                var meshVertCount = packages.Select(x => x.TriangleVertices.Count / 3).Sum();
                var meshVertSelCount = selPackages.Select(x => x.TriangleVertices.Count / 3).Sum();

                var mesh = new MeshGeometry3D();
                var meshSel = new MeshGeometry3D();
                var verts = new Point3DCollection(meshVertCount);
                var vertsSel = new Point3DCollection(meshVertSelCount);
                var norms = new Vector3DCollection(meshVertCount);
                var normsSel = new Vector3DCollection(meshVertSelCount);
                var tris = new Int32Collection(meshVertCount);
                var trisSel = new Int32Collection(meshVertSelCount);

                foreach (var package in packages)
                {
                    ConvertPoints(package, points, text);
                    ConvertLines(package, lines, redLines, greenLines, blueLines, text);
                    ConvertMeshes(package, verts, norms, tris);
                }

                foreach (var package in selPackages)
                {
                    ConvertPoints(package, pointsSelected, text);
                    ConvertLines(package, linesSelected, redLines, greenLines, blueLines, text);
                    ConvertMeshes(package, vertsSel, normsSel, trisSel);
                }

                points.Freeze();
                pointsSelected.Freeze();
                Points = points;
                PointsSelected = pointsSelected;

                lines.Freeze();
                linesSelected.Freeze();
                redLines.Freeze();
                greenLines.Freeze();
                blueLines.Freeze();
                Lines = lines;
                LinesSelected = linesSelected;
                XAxes = redLines;
                YAxes = greenLines;
                ZAxes = blueLines;

                verts.Freeze();
                norms.Freeze();
                tris.Freeze();
                vertsSel.Freeze();
                normsSel.Freeze();
                trisSel.Freeze();

                mesh.Positions = verts;
                mesh.Normals = norms;
                mesh.TriangleIndices = tris;
                meshSel.Positions = vertsSel;
                meshSel.Normals = normsSel;
                meshSel.TriangleIndices = trisSel;

                Mesh = mesh;
                MeshSelected = meshSel;

                Text = text;

                sw.Stop();

                Debug.WriteLine(string.Format("{0} ellapsed for updating background preview.", sw.Elapsed));
            }
            catch (InvalidOperationException exp)
            {
                Debug.WriteLine("WARNING: Exception occured in rendering " + exp.ToString());
            }
        }