Draw infinite world axes

With the following class derived from ViewportLayout you can draw the infinite world axes as shown in the following image:

 

The axes are drawn in 3 overridden methods:

DrawViewportBackground: the part of the axes beyond the far plane

DrawViewport: the part between the camera planes

DrawOverlay: the part nearer than the camera near plane


class MyViewportLayout : devDept.Eyeshot.ViewportLayout { protected override void DrawViewportBackground(DrawSceneParams data) { base.DrawViewportBackground(data); Plane farPlane = data.Viewport.Camera.FarPlane; Plane nearPlane = data.Viewport.Camera.NearPlane; Segment3D sX = new Segment3D(0, 0, 0, 1, 0, 0); Segment3D sY = new Segment3D(0, 0, 0, 0, 1, 0); Segment3D sZ = new Segment3D(0, 0, 0, 0, 0, 1); // Compute the intersections with the camera planes sX.IntersectWith(nearPlane, true, out ptXNear); sX.IntersectWith(farPlane, true, out ptXFar); sY.IntersectWith(nearPlane, true, out ptYNear); sY.IntersectWith(farPlane, true, out ptYFar); sZ.IntersectWith(nearPlane, true, out ptZNear); sZ.IntersectWith(farPlane, true, out ptZFar); var rc = data.RenderContext; rc.PushDepthStencilState(); rc.SetState(depthStencilStateType.DepthTestOff); rc.SetShader(shaderType.NoLights); // Draw in 2D the parts of the lines beyond the far camera plane // X axis DrawLinesBeyondFar(ptXNear, ptXFar, Color.Red); // Y axis DrawLinesBeyondFar(ptYNear, ptYFar, Color.Green); // Z axis DrawLinesBeyondFar(ptZNear, ptZFar, Color.Blue); rc.PopDepthStencilState(); } // Intersections with the camera planes Point3D ptXNear, ptXFar, ptYNear, ptYFar, ptZNear, ptZFar; protected override void DrawViewport(DrawSceneParams myParams) { base.DrawViewport(myParams); var rc = myParams.RenderContext; rc.SetShader(shaderType.NoLights); // Draw the 3D lines between the camera planes if (ptXNear != null && ptXFar != null) { rc.SetColorWireframe(Color.Red); rc.DrawLines(new Point3D[] { ptXNear, ptXFar }); } if (ptYNear != null && ptYFar != null) { rc.SetColorWireframe(Color.Green); rc.DrawLines(new Point3D[] { ptYNear, ptYFar }); } if (ptZNear != null && ptZFar != null) { rc.SetColorWireframe(Color.Blue); rc.DrawLines(new Point3D[] { ptZNear, ptZFar }); } } protected override void DrawOverlay(DrawSceneParams data) { // Draw in 2D the parts of the lines before the near camera plane renderContext.SetShader(shaderType.NoLights); // X axis DrawLinesBeforeNear(ptXNear, ptXFar, Color.Red); // Y axis DrawLinesBeforeNear(ptYNear, ptYFar, Color.Green); // Z axis DrawLinesBeforeNear(ptZNear, ptZFar, Color.Blue); } private void DrawLinesBeyondFar(Point3D nearPt, Point3D farPt, Color color) { if (farPt == null || nearPt == null) return; Vector3D dir = Vector3D.Subtract(farPt, nearPt); dir.Normalize(); Point3D pt1 = WorldToScreen(farPt); Point3D pt2 = WorldToScreen(farPt + dir); DrawLine(pt1, pt2, color); } private void DrawLinesBeforeNear(Point3D nearPt, Point3D farPt, Color color) { if (farPt == null || nearPt == null) return; Vector3D dir = Vector3D.Subtract(farPt, nearPt); dir.Normalize(); var pt1 = WorldToScreen(nearPt); var pt2 = WorldToScreen(nearPt - dir); DrawLine(pt1, pt2, color); } private void DrawLine(Point3D pt1, Point3D pt2, Color color) { if (pt1 == null || pt2 == null) return; Viewport viewport = Viewports[ActiveViewport]; Segment2D screenLine = new Segment2D(pt1, pt2); int[] viewFrame = new int[] { viewport.Location.X, Height - viewport.Location.Y - viewport.Size.Height, viewport.Size.Width, viewport.Size.Height }; int left = viewFrame[0]; int right = viewFrame[0] + viewFrame[2]; int bottom = viewFrame[1]; int top = viewFrame[1] + viewFrame[3] - 1; Point2D lowerLeft = new Point2D(left, bottom); Point2D lowerRight = new Point2D(right, bottom); Point2D upperLeft = new Point2D(left, top); Point2D upperRight = new Point2D(right, top); Segment2D[] screenLines = new Segment2D[] { new Segment2D(lowerLeft, lowerRight), new Segment2D(upperLeft, upperRight), new Segment2D(lowerLeft, upperLeft), new Segment2D(lowerRight, upperRight) }; Point2D ptAxis1 = null, ptAxis2 = null; Vector2D dir = Vector2D.Subtract(pt2, pt1); dir.Normalize(); // extend the segment outside the window limits screenLine.P1 = screenLine.P0 + dir * (Width + Height); // Compute the intersection of the screen line against the lower and upper border of the viewport Segment2D.Intersection(screenLine, screenLines[0], out ptAxis1); Segment2D.Intersection(screenLine, screenLines[1], out ptAxis2); bool clipAgainstVertical = true; if (ptAxis1 == null || ptAxis2 == null) { // Compute the intersection of the infinite screen line against the left and right border of the viewport Segment2D.Intersection(screenLine, screenLines[2], out ptAxis1); Segment2D.Intersection(screenLine, screenLines[3], out ptAxis2); } if (ptAxis1 != null) screenLine.P1 = ptAxis1; else if (ptAxis2 != null) screenLine.P1 = ptAxis2; renderContext.SetLineSize(1); renderContext.EnableThickLines(); renderContext.SetColorWireframe(color); renderContext.DrawLines(new float[] { (float) screenLine.P0.X, (float) screenLine.P0.Y, 0, (float) screenLine.P1.X, (float) screenLine.P1.Y, 0 }); } }

 

Have more questions? Submit a request

0 Comments

Please sign in to leave a comment.