public ShapefileRenderer( string filename, Context context, Ellipsoid globeShape, ShapefileAppearance appearance) { Shapefile shapefile = new Shapefile(filename); switch (shapefile.ShapeType) { case ShapeType.Point: PointShapefile pointShapefile = new PointShapefile(shapefile, context, globeShape, appearance); pointShapefile.DepthWrite = false; _shapefileGraphics = pointShapefile; break; case ShapeType.Polyline: PolylineShapefile polylineShapefile = new PolylineShapefile(shapefile, context, globeShape, appearance); polylineShapefile.DepthWrite = false; _shapefileGraphics = polylineShapefile; break; case ShapeType.Polygon: PolygonShapefile polygonShapefile = new PolygonShapefile(shapefile, context, globeShape, appearance); polygonShapefile.DepthWrite = false; _shapefileGraphics = polygonShapefile; break; default: throw new NotSupportedException("Rendering is not supported for " + shapefile.ShapeType.ToString() + " shapefiles."); } }
public PointShapefile( Shapefile shapefile, Context context, Ellipsoid globeShape, ShapefileAppearance appearance) { Verify.ThrowIfNull(shapefile); Verify.ThrowIfNull(context); Verify.ThrowIfNull(globeShape); Verify.ThrowIfNull(appearance); _billboards = new BillboardCollection(context); _billboards.Texture = Device.CreateTexture2D(appearance.Bitmap, TextureFormat.RedGreenBlueAlpha8, false); foreach (Shape shape in shapefile) { if (shape.ShapeType != ShapeType.Point) { throw new NotSupportedException("The type of an individual shape does not match the Shapefile type."); } Vector2D point = ((PointShape)shape).Position; Vector3D position = globeShape.ToVector3D(Trig.ToRadians(new Geodetic3D(point.X, point.Y))); Billboard billboard = new Billboard(); billboard.Position = position; _billboards.Add(billboard); } }
public static void ThrowIfNull(Ellipsoid globeShape) { if (globeShape == null) { throw new ArgumentNullException("globeShape"); } }
public EllipsoidSurfaceNormals() { _globeShape = new Ellipsoid(1, 1, _semiMinorAxis); _window = Device.CreateWindow(800, 600, "Chapter 2: Ellipsoid Surface Normals"); _window.Resize += OnResize; _window.RenderFrame += OnRenderFrame; _window.Keyboard.KeyDown += OnKeyDown; _sceneState = new SceneState(); _camera = new CameraLookAtPoint(_sceneState.Camera, _window, _globeShape); _instructions = new HeadsUpDisplay(); _instructions.Texture = Device.CreateTexture2D( Device.CreateBitmapFromText("Up - Increase semi-minor axis\nDown - Decrease semi-minor axis", new Font("Arial", 24)), TextureFormat.RedGreenBlueAlpha8, false); _instructions.Color = Color.Black; _clearState = new ClearState(); CreateScene(); /////////////////////////////////////////////////////////////////// _sceneState.Camera.Eye = Vector3D.UnitY; _sceneState.Camera.ZoomToTarget(2 * _globeShape.MaximumRadius); }
public EllipsoidTangentPlane(Ellipsoid ellipsoid, IEnumerable<Vector3D> positions) { if (ellipsoid == null) { throw new ArgumentNullException("ellipsoid"); } if (positions == null) { throw new ArgumentNullException("positions"); } if (!CollectionAlgorithms.EnumerableCountGreaterThanOrEqual(positions, 1)) { throw new ArgumentOutOfRangeException("positions", "At least one position is required."); } AxisAlignedBoundingBox box = new AxisAlignedBoundingBox(positions); _origin = ellipsoid.ScaleToGeodeticSurface(box.Center); _normal = ellipsoid.GeodeticSurfaceNormal(_origin); _d = -_origin.Dot(_origin); _yAxis = _origin.Cross(_origin.MostOrthogonalAxis).Normalize(); _xAxis = _yAxis.Cross(_origin).Normalize(); }
/// <summary> /// Initializes a new instance. /// </summary> /// <param name="camera">The renderer camera that is to be manipulated by the new instance.</param> /// <param name="window">The window in which the scene is drawn.</param> /// <param name="ellipsoid">The ellipsoid defining the shape of the globe.</param> public CameraLookAtPoint(Camera camera, GraphicsWindow window, Ellipsoid ellipsoid) { if (camera == null) { throw new ArgumentNullException("camera"); } if (window == null) { throw new ArgumentNullException("window"); } _camera = camera; _window = window; _centerPoint = camera.Target; _zoomFactor = 5.0; _zoomRateRangeAdjustment = ellipsoid.MaximumRadius; _maximumZoomRate = Double.MaxValue; _minimumZoomRate = ellipsoid.MaximumRadius / 100.0; _rotateFactor = 1.0 / ellipsoid.MaximumRadius; _rotateRateRangeAdjustment = ellipsoid.MaximumRadius; _maximumRotateRate = 1.0; _minimumRotateRate = 1.0 / 5000.0; // TODO: Should really be: // _range = (camera.Eye - camera.Target).Magnitude; _range = ellipsoid.MaximumRadius * 2.0; MouseEnabled = true; }
public void Construct() { Ellipsoid ellipsoid = new Ellipsoid(new Vector3D(1, 2, 3)); Assert.AreEqual(1, ellipsoid.Radii.X); Assert.AreEqual(2, ellipsoid.Radii.Y); Assert.AreEqual(3, ellipsoid.Radii.Z); Ellipsoid ellipsoid2 = new Ellipsoid(4, 5, 6); Assert.AreEqual(new Vector3D(4, 5, 6), ellipsoid2.Radii); Ellipsoid sphere = Ellipsoid.UnitSphere; Assert.IsTrue(sphere.RadiiSquared.Equals((new Vector3D(1, 1, 1)))); Assert.IsTrue(sphere.OneOverRadiiSquared.Equals((new Vector3D(1, 1, 1)))); }
public static Mesh Compute(Ellipsoid ellipsoid, int numberOfSlicePartitions, int numberOfStackPartitions, GeographicGridEllipsoidVertexAttributes vertexAttributes) { if (numberOfSlicePartitions < 3) { throw new ArgumentOutOfRangeException("numberOfSlicePartitions"); } if (numberOfStackPartitions < 2) { throw new ArgumentOutOfRangeException("numberOfStackPartitions"); } if ((vertexAttributes & GeographicGridEllipsoidVertexAttributes.Position) != GeographicGridEllipsoidVertexAttributes.Position) { throw new ArgumentException("Positions must be provided.", "vertexAttributes"); } Mesh mesh = new Mesh(); mesh.PrimitiveType = PrimitiveType.Triangles; mesh.FrontFaceWindingOrder = WindingOrder.Counterclockwise; int numberOfVertices = NumberOfVertices(numberOfSlicePartitions, numberOfStackPartitions); VertexAttributeDoubleVector3 positionsAttribute = new VertexAttributeDoubleVector3("position", numberOfVertices); mesh.Attributes.Add(positionsAttribute); IndicesUnsignedInt indices = new IndicesUnsignedInt(3 * NumberOfTriangles(numberOfSlicePartitions, numberOfStackPartitions)); mesh.Indices = indices; IList<Vector3H> normals = null; if ((vertexAttributes & GeographicGridEllipsoidVertexAttributes.Normal) == GeographicGridEllipsoidVertexAttributes.Normal) { VertexAttributeHalfFloatVector3 normalsAttribute = new VertexAttributeHalfFloatVector3("normal", numberOfVertices); mesh.Attributes.Add(normalsAttribute); normals = normalsAttribute.Values; } IList<Vector2H> textureCoordinates = null; if ((vertexAttributes & GeographicGridEllipsoidVertexAttributes.TextureCoordinate) == GeographicGridEllipsoidVertexAttributes.TextureCoordinate) { VertexAttributeHalfFloatVector2 textureCoordinateAttribute = new VertexAttributeHalfFloatVector2("textureCoordinate", numberOfVertices); mesh.Attributes.Add(textureCoordinateAttribute); textureCoordinates = textureCoordinateAttribute.Values; } // // Create lookup table // double[] cosTheta = new double[numberOfSlicePartitions]; double[] sinTheta = new double[numberOfSlicePartitions]; for (int j = 0; j < numberOfSlicePartitions; ++j) { double theta = Trig.TwoPi * (((double)j) / numberOfSlicePartitions); cosTheta[j] = Math.Cos(theta); sinTheta[j] = Math.Sin(theta); } // // Create positions // IList<Vector3D> positions = positionsAttribute.Values; positions.Add(new Vector3D(0, 0, ellipsoid.Radii.Z)); for (int i = 1; i < numberOfStackPartitions; ++i) { double phi = Math.PI * (((double)i) / numberOfStackPartitions); double sinPhi = Math.Sin(phi); double xSinPhi = ellipsoid.Radii.X * sinPhi; double ySinPhi = ellipsoid.Radii.Y * sinPhi; double zCosPhi = ellipsoid.Radii.Z * Math.Cos(phi); for (int j = 0; j < numberOfSlicePartitions; ++j) { positions.Add(new Vector3D(cosTheta[j] * xSinPhi, sinTheta[j] * ySinPhi, zCosPhi)); } } positions.Add(new Vector3D(0, 0, -ellipsoid.Radii.Z)); if ((normals != null) || (textureCoordinates != null)) { for (int i = 0; i < positions.Count; ++i) { Vector3D deticSurfaceNormal = ellipsoid.GeodeticSurfaceNormal(positions[i]); if (normals != null) { normals.Add(deticSurfaceNormal.ToVector3H()); } if (textureCoordinates != null) { textureCoordinates.Add(SubdivisionUtility.ComputeTextureCoordinate(deticSurfaceNormal)); } } } // // Triangle fan top row // for (int j = 1; j < numberOfSlicePartitions; ++j) { indices.AddTriangle(new TriangleIndicesUnsignedInt(0, j, j + 1)); } indices.AddTriangle(new TriangleIndicesUnsignedInt(0, numberOfSlicePartitions, 1)); // // Middle rows are triangle strips // for (int i = 0; i < numberOfStackPartitions - 2; ++i) { int topRowOffset = (i * numberOfSlicePartitions) + 1; int bottomRowOffset = ((i + 1) * numberOfSlicePartitions) + 1; for (int j = 0; j < numberOfSlicePartitions - 1; ++j) { indices.AddTriangle(new TriangleIndicesUnsignedInt(bottomRowOffset + j, bottomRowOffset + j + 1, topRowOffset + j + 1)); indices.AddTriangle(new TriangleIndicesUnsignedInt(bottomRowOffset + j, topRowOffset + j + 1, topRowOffset + j)); } indices.AddTriangle(new TriangleIndicesUnsignedInt(bottomRowOffset + numberOfSlicePartitions - 1, bottomRowOffset, topRowOffset)); indices.AddTriangle(new TriangleIndicesUnsignedInt(bottomRowOffset + numberOfSlicePartitions - 1, topRowOffset, topRowOffset + numberOfSlicePartitions - 1)); } // // Triangle fan bottom row // int lastPosition = positions.Count - 1; for (int j = lastPosition - 1; j > lastPosition - numberOfSlicePartitions; --j) { indices.AddTriangle(new TriangleIndicesUnsignedInt(lastPosition, j, j - 1)); } indices.AddTriangle(new TriangleIndicesUnsignedInt(lastPosition, lastPosition - numberOfSlicePartitions, lastPosition - 1)); return mesh; }
public static Mesh Compute(Ellipsoid ellipsoid, int numberOfSubdivisions, SubdivisionEllipsoidVertexAttributes vertexAttributes) { if (numberOfSubdivisions < 0) { throw new ArgumentOutOfRangeException("numberOfSubdivisions"); } if ((vertexAttributes & SubdivisionEllipsoidVertexAttributes.Position) != SubdivisionEllipsoidVertexAttributes.Position) { throw new ArgumentException("Positions must be provided.", "vertexAttributes"); } Mesh mesh = new Mesh(); mesh.PrimitiveType = PrimitiveType.Triangles; mesh.FrontFaceWindingOrder = WindingOrder.Counterclockwise; int numberOfVertices = SubdivisionUtility.NumberOfVertices(numberOfSubdivisions); VertexAttributeDoubleVector3 positionsAttribute = new VertexAttributeDoubleVector3("position", numberOfVertices); mesh.Attributes.Add(positionsAttribute); IndicesUnsignedInt indices = new IndicesUnsignedInt(3 * SubdivisionUtility.NumberOfTriangles(numberOfSubdivisions)); mesh.Indices = indices; SubdivisionMesh subdivisionMesh = new SubdivisionMesh(); subdivisionMesh.Ellipsoid = ellipsoid; subdivisionMesh.Positions = positionsAttribute.Values; subdivisionMesh.Indices = indices; if ((vertexAttributes & SubdivisionEllipsoidVertexAttributes.Normal) == SubdivisionEllipsoidVertexAttributes.Normal) { VertexAttributeHalfFloatVector3 normalsAttribute = new VertexAttributeHalfFloatVector3("normal", numberOfVertices); mesh.Attributes.Add(normalsAttribute); subdivisionMesh.Normals = normalsAttribute.Values; } if ((vertexAttributes & SubdivisionEllipsoidVertexAttributes.TextureCoordinate) == SubdivisionEllipsoidVertexAttributes.TextureCoordinate) { VertexAttributeHalfFloatVector2 textureCoordinateAttribute = new VertexAttributeHalfFloatVector2("textureCoordinate", numberOfVertices); mesh.Attributes.Add(textureCoordinateAttribute); subdivisionMesh.TextureCoordinate = textureCoordinateAttribute.Values; } // // Initial tetrahedron // double negativeRootTwoOverThree = -Math.Sqrt(2.0) / 3.0; const double negativeOneThird = -1.0 / 3.0; double rootSixOverThree = Math.Sqrt(6.0) / 3.0; Vector3D n0 = new Vector3D(0, 0, 1); Vector3D n1 = new Vector3D(0, (2.0 * Math.Sqrt(2.0)) / 3.0, negativeOneThird); Vector3D n2 = new Vector3D(-rootSixOverThree, negativeRootTwoOverThree, negativeOneThird); Vector3D n3 = new Vector3D(rootSixOverThree, negativeRootTwoOverThree, negativeOneThird); Vector3D p0 = n0.MultiplyComponents(ellipsoid.Radii); Vector3D p1 = n1.MultiplyComponents(ellipsoid.Radii); Vector3D p2 = n2.MultiplyComponents(ellipsoid.Radii); Vector3D p3 = n3.MultiplyComponents(ellipsoid.Radii); subdivisionMesh.Positions.Add(p0); subdivisionMesh.Positions.Add(p1); subdivisionMesh.Positions.Add(p2); subdivisionMesh.Positions.Add(p3); if ((subdivisionMesh.Normals != null) || (subdivisionMesh.TextureCoordinate != null)) { Vector3D d0 = ellipsoid.GeodeticSurfaceNormal(p0); Vector3D d1 = ellipsoid.GeodeticSurfaceNormal(p1); Vector3D d2 = ellipsoid.GeodeticSurfaceNormal(p2); Vector3D d3 = ellipsoid.GeodeticSurfaceNormal(p3); if (subdivisionMesh.Normals != null) { subdivisionMesh.Normals.Add(d0.ToVector3H()); subdivisionMesh.Normals.Add(d1.ToVector3H()); subdivisionMesh.Normals.Add(d2.ToVector3H()); subdivisionMesh.Normals.Add(d3.ToVector3H()); } if (subdivisionMesh.TextureCoordinate != null) { subdivisionMesh.TextureCoordinate.Add(SubdivisionUtility.ComputeTextureCoordinate(d0)); subdivisionMesh.TextureCoordinate.Add(SubdivisionUtility.ComputeTextureCoordinate(d1)); subdivisionMesh.TextureCoordinate.Add(SubdivisionUtility.ComputeTextureCoordinate(d2)); subdivisionMesh.TextureCoordinate.Add(SubdivisionUtility.ComputeTextureCoordinate(d3)); } } Subdivide(subdivisionMesh, new TriangleIndicesUnsignedInt(0, 1, 2), numberOfSubdivisions); Subdivide(subdivisionMesh, new TriangleIndicesUnsignedInt(0, 2, 3), numberOfSubdivisions); Subdivide(subdivisionMesh, new TriangleIndicesUnsignedInt(0, 3, 1), numberOfSubdivisions); Subdivide(subdivisionMesh, new TriangleIndicesUnsignedInt(1, 3, 2), numberOfSubdivisions); return mesh; }
public static Mesh Compute(Ellipsoid ellipsoid, int numberOfSlicePartitions, int numberOfStackPartitions, GeographicGridEllipsoidVertexAttributes vertexAttributes) { if (numberOfSlicePartitions < 3) { throw new ArgumentOutOfRangeException("numberOfSlicePartitions"); } if (numberOfStackPartitions < 2) { throw new ArgumentOutOfRangeException("numberOfStackPartitions"); } if ((vertexAttributes & GeographicGridEllipsoidVertexAttributes.Position) != GeographicGridEllipsoidVertexAttributes.Position) { throw new ArgumentException("Positions must be provided.", "vertexAttributes"); } Mesh mesh = new Mesh(); mesh.PrimitiveType = PrimitiveType.Triangles; mesh.FrontFaceWindingOrder = WindingOrder.Counterclockwise; int numberOfVertices = NumberOfVertices(numberOfSlicePartitions, numberOfStackPartitions); VertexAttributeDoubleVector3 positionsAttribute = new VertexAttributeDoubleVector3("position", numberOfVertices); mesh.Attributes.Add(positionsAttribute); IndicesUnsignedInt indices = new IndicesUnsignedInt(3 * NumberOfTriangles(numberOfSlicePartitions, numberOfStackPartitions)); mesh.Indices = indices; IList <Vector3H> normals = null; if ((vertexAttributes & GeographicGridEllipsoidVertexAttributes.Normal) == GeographicGridEllipsoidVertexAttributes.Normal) { VertexAttributeHalfFloatVector3 normalsAttribute = new VertexAttributeHalfFloatVector3("normal", numberOfVertices); mesh.Attributes.Add(normalsAttribute); normals = normalsAttribute.Values; } IList <Vector2H> textureCoordinates = null; if ((vertexAttributes & GeographicGridEllipsoidVertexAttributes.TextureCoordinate) == GeographicGridEllipsoidVertexAttributes.TextureCoordinate) { VertexAttributeHalfFloatVector2 textureCoordinateAttribute = new VertexAttributeHalfFloatVector2("textureCoordinate", numberOfVertices); mesh.Attributes.Add(textureCoordinateAttribute); textureCoordinates = textureCoordinateAttribute.Values; } // // Create lookup table // double[] cosTheta = new double[numberOfSlicePartitions]; double[] sinTheta = new double[numberOfSlicePartitions]; for (int j = 0; j < numberOfSlicePartitions; ++j) { double theta = Trig.TwoPi * (((double)j) / numberOfSlicePartitions); cosTheta[j] = Math.Cos(theta); sinTheta[j] = Math.Sin(theta); } // // Create positions // IList <Vector3D> positions = positionsAttribute.Values; positions.Add(new Vector3D(0, 0, ellipsoid.Radii.Z)); for (int i = 1; i < numberOfStackPartitions; ++i) { double phi = Math.PI * (((double)i) / numberOfStackPartitions); double sinPhi = Math.Sin(phi); double xSinPhi = ellipsoid.Radii.X * sinPhi; double ySinPhi = ellipsoid.Radii.Y * sinPhi; double zCosPhi = ellipsoid.Radii.Z * Math.Cos(phi); for (int j = 0; j < numberOfSlicePartitions; ++j) { positions.Add(new Vector3D(cosTheta[j] * xSinPhi, sinTheta[j] * ySinPhi, zCosPhi)); } } positions.Add(new Vector3D(0, 0, -ellipsoid.Radii.Z)); if ((normals != null) || (textureCoordinates != null)) { for (int i = 0; i < positions.Count; ++i) { Vector3D deticSurfaceNormal = ellipsoid.GeodeticSurfaceNormal(positions[i]); if (normals != null) { normals.Add(deticSurfaceNormal.ToVector3H()); } if (textureCoordinates != null) { textureCoordinates.Add(SubdivisionUtility.ComputeTextureCoordinate(deticSurfaceNormal)); } } } // // Triangle fan top row // for (int j = 1; j < numberOfSlicePartitions; ++j) { indices.AddTriangle(new TriangleIndicesUnsignedInt(0, j, j + 1)); } indices.AddTriangle(new TriangleIndicesUnsignedInt(0, numberOfSlicePartitions, 1)); // // Middle rows are triangle strips // for (int i = 0; i < numberOfStackPartitions - 2; ++i) { int topRowOffset = (i * numberOfSlicePartitions) + 1; int bottomRowOffset = ((i + 1) * numberOfSlicePartitions) + 1; for (int j = 0; j < numberOfSlicePartitions - 1; ++j) { indices.AddTriangle(new TriangleIndicesUnsignedInt(bottomRowOffset + j, bottomRowOffset + j + 1, topRowOffset + j + 1)); indices.AddTriangle(new TriangleIndicesUnsignedInt(bottomRowOffset + j, topRowOffset + j + 1, topRowOffset + j)); } indices.AddTriangle(new TriangleIndicesUnsignedInt(bottomRowOffset + numberOfSlicePartitions - 1, bottomRowOffset, topRowOffset)); indices.AddTriangle(new TriangleIndicesUnsignedInt(bottomRowOffset + numberOfSlicePartitions - 1, topRowOffset, topRowOffset + numberOfSlicePartitions - 1)); } // // Triangle fan bottom row // int lastPosition = positions.Count - 1; for (int j = lastPosition - 1; j > lastPosition - numberOfSlicePartitions; --j) { indices.AddTriangle(new TriangleIndicesUnsignedInt(lastPosition, j, j - 1)); } indices.AddTriangle(new TriangleIndicesUnsignedInt(lastPosition, lastPosition - numberOfSlicePartitions, lastPosition - 1)); return(mesh); }
private void SetShape() { _globeShape = new Ellipsoid( Ellipsoid.ScaledWgs84.Radii.X, Ellipsoid.ScaledWgs84.Radii.Y, _semiMinorAxis); _p = _globeShape.ToVector3D(new Geodetic2D(Trig.ToRadians(40), Trig.ToRadians(40))); _q = _globeShape.ToVector3D(new Geodetic2D(Trig.ToRadians(120), Trig.ToRadians(-30))); }
public PolygonShapefile( Shapefile shapefile, Context context, Ellipsoid globeShape, ShapefileAppearance appearance) { Verify.ThrowIfNull(shapefile); Verify.ThrowIfNull(context); Verify.ThrowIfNull(globeShape); _polyline = new OutlinedPolylineTexture(); _polygons = new List<Polygon>(); VertexAttributeDoubleVector3 positionAttribute = new VertexAttributeDoubleVector3("position"); VertexAttributeRGBA colorAttribute = new VertexAttributeRGBA("color"); VertexAttributeRGBA outlineColorAttribute = new VertexAttributeRGBA("outlineColor"); IndicesUnsignedInt indices = new IndicesUnsignedInt(); Random r = new Random(3); IList<Vector3D> positions = new List<Vector3D>(); foreach (Shape shape in shapefile) { if (shape.ShapeType != ShapeType.Polygon) { throw new NotSupportedException("The type of an individual shape does not match the Shapefile type."); } PolygonShape polygonShape = (PolygonShape)shape; for (int j = 0; j < polygonShape.Count; ++j) { Color color = Color.FromArgb(127, r.Next(256), r.Next(256), r.Next(256)); positions.Clear(); ShapePart part = polygonShape[j]; for (int i = 0; i < part.Count; ++i) { Vector2D point = part[i]; positions.Add(globeShape.ToVector3D(Trig.ToRadians(new Geodetic3D(point.X, point.Y)))); // // For polyline // positionAttribute.Values.Add(globeShape.ToVector3D(Trig.ToRadians(new Geodetic3D(point.X, point.Y)))); colorAttribute.AddColor(color); outlineColorAttribute.AddColor(Color.Black); if (i != 0) { indices.Values.Add((uint)positionAttribute.Values.Count - 2); indices.Values.Add((uint)positionAttribute.Values.Count - 1); } } try { Polygon p = new Polygon(context, globeShape, positions); p.Color = color; _polygons.Add(p); } catch (ArgumentOutOfRangeException) // Not enough positions after cleaning { } } } Mesh mesh = new Mesh(); mesh.PrimitiveType = PrimitiveType.Lines; mesh.Attributes.Add(positionAttribute); mesh.Attributes.Add(colorAttribute); mesh.Attributes.Add(outlineColorAttribute); mesh.Indices = indices; _polyline.Set(context, mesh); }
public Polygon(Context context, Ellipsoid globeShape, IEnumerable<Vector3D> positions) { Verify.ThrowIfNull(context); Verify.ThrowIfNull(globeShape); // // Pipeline Stage 1a: Clean up - Remove duplicate positions // List<Vector3D> cleanPositions = (List<Vector3D>)SimplePolygonAlgorithms.Cleanup(positions); // // Pipeline Stage 1b: Clean up - Swap winding order // EllipsoidTangentPlane plane = new EllipsoidTangentPlane(globeShape, cleanPositions); ICollection<Vector2D> positionsOnPlane = plane.ComputePositionsOnPlane(cleanPositions); if (SimplePolygonAlgorithms.ComputeWindingOrder(positionsOnPlane) == PolygonWindingOrder.Clockwise) { cleanPositions.Reverse(); //((List<Vector2D>)positionsOnPlane).Reverse(); } // // Pipeline Stage 2: Triangulate // IndicesUnsignedInt indices = EarClippingOnEllipsoid.Triangulate(cleanPositions); //IndicesInt32 indices = EarClipping.Triangulate(positionsOnPlane); // // Pipeline Stage 3: Subdivide // TriangleMeshSubdivisionResult result = TriangleMeshSubdivision.Compute(cleanPositions, indices, Trig.ToRadians(1)); // // Pipeline Stage 4: Set height // VertexAttributeDoubleVector3 positionsAttribute = new VertexAttributeDoubleVector3( "position", (result.Indices.Values.Count / 3) + 2); foreach (Vector3D position in result.Positions) { positionsAttribute.Values.Add(globeShape.ScaleToGeocentricSurface(position)); } Mesh mesh = new Mesh(); mesh.PrimitiveType = PrimitiveType.Triangles; mesh.FrontFaceWindingOrder = WindingOrder.Counterclockwise; mesh.Attributes.Add(positionsAttribute); mesh.Indices = result.Indices; ShaderProgram sp = Device.CreateShaderProgram( EmbeddedResources.GetText("OpenGlobe.Scene.Renderables.Polygon.Shaders.PolygonVS.glsl"), EmbeddedResources.GetText("OpenGlobe.Scene.Renderables.Polygon.Shaders.PolygonFS.glsl")); ((Uniform<Vector3F>)sp.Uniforms["u_globeOneOverRadiiSquared"]).Value = globeShape.OneOverRadiiSquared.ToVector3F(); _colorUniform = (Uniform<Vector4F>)sp.Uniforms["u_color"]; _drawState = new DrawState(); _drawState.RenderState.Blending.Enabled = true; _drawState.RenderState.Blending.SourceRGBFactor = SourceBlendingFactor.SourceAlpha; _drawState.RenderState.Blending.SourceAlphaFactor = SourceBlendingFactor.SourceAlpha; _drawState.RenderState.Blending.DestinationRGBFactor = DestinationBlendingFactor.OneMinusSourceAlpha; _drawState.RenderState.Blending.DestinationAlphaFactor = DestinationBlendingFactor.OneMinusSourceAlpha; _drawState.ShaderProgram = sp; _meshBuffers = Device.CreateMeshBuffers(mesh, _drawState.ShaderProgram.VertexAttributes, BufferHint.StaticDraw); _primitiveType = mesh.PrimitiveType; Color = Color.White; }
public void CentricSurfaceNormal() { Vector3D v = new Vector3D(1, 2, 3); Assert.AreEqual(v.Normalize(), Ellipsoid.CentricSurfaceNormal(v)); }
public void ToVector3D() { Ellipsoid ellipsoid = new Ellipsoid(1, 1, 0.7); Assert.IsTrue(Vector3D.UnitX.EqualsEpsilon(ellipsoid.ToVector3D(new Geodetic3D(0, 0, 0)), 1e-10)); Assert.IsTrue(Vector3D.UnitY.EqualsEpsilon(ellipsoid.ToVector3D(new Geodetic3D(Trig.ToRadians(90), 0, 0)), 1e-10)); Assert.IsTrue(new Vector3D(0, 0, 0.7).EqualsEpsilon(ellipsoid.ToVector3D(new Geodetic3D(0, Trig.ToRadians(90), 0)), 1e-10)); }
public static Mesh Compute(Ellipsoid ellipsoid, int numberOfPartitions, CubeMapEllipsoidVertexAttributes vertexAttributes) { if (numberOfPartitions < 0) { throw new ArgumentOutOfRangeException("numberOfPartitions"); } if ((vertexAttributes & CubeMapEllipsoidVertexAttributes.Position) != CubeMapEllipsoidVertexAttributes.Position) { throw new ArgumentException("Positions must be provided.", "vertexAttributes"); } Mesh mesh = new Mesh(); mesh.PrimitiveType = PrimitiveType.Triangles; mesh.FrontFaceWindingOrder = WindingOrder.Counterclockwise; int numberOfVertices = NumberOfVertices(numberOfPartitions); VertexAttributeDoubleVector3 positionsAttribute = new VertexAttributeDoubleVector3("position", numberOfVertices); mesh.Attributes.Add(positionsAttribute); IndicesUnsignedInt indices = new IndicesUnsignedInt(3 * NumberOfTriangles(numberOfPartitions)); mesh.Indices = indices; CubeMapMesh CubeMapMesh = new CubeMapMesh(); CubeMapMesh.Ellipsoid = ellipsoid; CubeMapMesh.NumberOfPartitions = numberOfPartitions; CubeMapMesh.Positions = positionsAttribute.Values; CubeMapMesh.Indices = indices; if ((vertexAttributes & CubeMapEllipsoidVertexAttributes.Normal) == CubeMapEllipsoidVertexAttributes.Normal) { VertexAttributeHalfFloatVector3 normalsAttribute = new VertexAttributeHalfFloatVector3("normal", numberOfVertices); mesh.Attributes.Add(normalsAttribute); CubeMapMesh.Normals = normalsAttribute.Values; } if ((vertexAttributes & CubeMapEllipsoidVertexAttributes.TextureCoordinate) == CubeMapEllipsoidVertexAttributes.TextureCoordinate) { VertexAttributeHalfFloatVector2 textureCoordinateAttribute = new VertexAttributeHalfFloatVector2("textureCoordinate", numberOfVertices); mesh.Attributes.Add(textureCoordinateAttribute); CubeMapMesh.TextureCoordinate = textureCoordinateAttribute.Values; } // // Initial cube. In the plane, z = -1: // // +y // | // Q2 * p3 Q1 // / | \ // p0 *--+--* p2 +x // \ | / // Q3 * p1 Q4 // | // // Similarly, p4 to p7 are in the plane z = 1. // CubeMapMesh.Positions.Add(new Vector3D(-1, 0, -1)); CubeMapMesh.Positions.Add(new Vector3D(0, -1, -1)); CubeMapMesh.Positions.Add(new Vector3D(1, 0, -1)); CubeMapMesh.Positions.Add(new Vector3D(0, 1, -1)); CubeMapMesh.Positions.Add(new Vector3D(-1, 0, 1)); CubeMapMesh.Positions.Add(new Vector3D(0, -1, 1)); CubeMapMesh.Positions.Add(new Vector3D(1, 0, 1)); CubeMapMesh.Positions.Add(new Vector3D(0, 1, 1)); // // Edges // // 0 -> 1, 1 -> 2, 2 -> 3, 3 -> 0. Plane z = -1 // 4 -> 5, 5 -> 6, 6 -> 7, 7 -> 4. Plane z = 1 // 0 -> 4, 1 -> 5, 2 -> 6, 3 -> 7. From plane z = -1 to plane z - 1 // int[] edge0to1 = AddEdgePositions(0, 1, CubeMapMesh); int[] edge1to2 = AddEdgePositions(1, 2, CubeMapMesh); int[] edge2to3 = AddEdgePositions(2, 3, CubeMapMesh); int[] edge3to0 = AddEdgePositions(3, 0, CubeMapMesh); int[] edge4to5 = AddEdgePositions(4, 5, CubeMapMesh); int[] edge5to6 = AddEdgePositions(5, 6, CubeMapMesh); int[] edge6to7 = AddEdgePositions(6, 7, CubeMapMesh); int[] edge7to4 = AddEdgePositions(7, 4, CubeMapMesh); int[] edge0to4 = AddEdgePositions(0, 4, CubeMapMesh); int[] edge1to5 = AddEdgePositions(1, 5, CubeMapMesh); int[] edge2to6 = AddEdgePositions(2, 6, CubeMapMesh); int[] edge3to7 = AddEdgePositions(3, 7, CubeMapMesh); AddFaceTriangles(edge0to4, edge0to1, edge1to5, edge4to5, CubeMapMesh); // Q3 Face AddFaceTriangles(edge1to5, edge1to2, edge2to6, edge5to6, CubeMapMesh); // Q4 Face AddFaceTriangles(edge2to6, edge2to3, edge3to7, edge6to7, CubeMapMesh); // Q1 Face AddFaceTriangles(edge3to7, edge3to0, edge0to4, edge7to4, CubeMapMesh); // Q2 Face AddFaceTriangles(ReversedArray(edge7to4), edge4to5, edge5to6, ReversedArray(edge6to7), CubeMapMesh); // Plane z = 1 AddFaceTriangles(edge1to2, ReversedArray(edge0to1), ReversedArray(edge3to0), edge2to3, CubeMapMesh); // Plane z = -1 CubeToEllipsoid(CubeMapMesh); return(mesh); }
public GlobeClipmapTerrain(Context context, RasterSource terrainSource, EsriRestImagery imagery, Ellipsoid ellipsoid, int clipmapPosts) { _terrainSource = terrainSource; _ellipsoid = ellipsoid; _clipmapPosts = clipmapPosts; _clipmapSegments = _clipmapPosts - 1; int clipmapLevels = _terrainSource.Levels.Count; _clipmapLevels = new ClipmapLevel[clipmapLevels]; for (int i = 0; i < _clipmapLevels.Length; ++i) { _clipmapLevels[i] = new ClipmapLevel(); } for (int i = 0; i < _clipmapLevels.Length; ++i) { RasterLevel terrainLevel = _terrainSource.Levels[i]; _clipmapLevels[i].Terrain = terrainLevel; _clipmapLevels[i].HeightTexture = Device.CreateTexture2D(new Texture2DDescription(_clipmapPosts, _clipmapPosts, TextureFormat.Red32f)); _clipmapLevels[i].NormalTexture = Device.CreateTexture2D(new Texture2DDescription(_clipmapPosts, _clipmapPosts, TextureFormat.RedGreenBlue32f)); _clipmapLevels[i].CoarserLevel = i == 0 ? null : _clipmapLevels[i - 1]; _clipmapLevels[i].FinerLevel = i == _clipmapLevels.Length - 1 ? null : _clipmapLevels[i + 1]; // Aim for roughly one imagery texel per geometry texel. // Find the first imagery level that meets our resolution needs. double longitudeResRequired = terrainLevel.PostDeltaLongitude; double latitudeResRequired = terrainLevel.PostDeltaLatitude; RasterLevel imageryLevel = null; for (int j = 0; j < imagery.Levels.Count; ++j) { imageryLevel = imagery.Levels[j]; if (imageryLevel.PostDeltaLongitude <= longitudeResRequired && imageryLevel.PostDeltaLatitude <= latitudeResRequired) { break; } } _clipmapLevels[i].Imagery = imageryLevel; _clipmapLevels[i].ImageryWidth = (int)Math.Ceiling(_clipmapPosts * terrainLevel.PostDeltaLongitude / imageryLevel.PostDeltaLongitude); _clipmapLevels[i].ImageryHeight = (int)Math.Ceiling(_clipmapPosts * terrainLevel.PostDeltaLatitude / imageryLevel.PostDeltaLatitude); _clipmapLevels[i].ImageryTexture = Device.CreateTexture2D(new Texture2DDescription(_clipmapLevels[i].ImageryWidth, _clipmapLevels[i].ImageryHeight, TextureFormat.RedGreenBlue8, false)); } _shaderProgram = Device.CreateShaderProgram( EmbeddedResources.GetText("OpenGlobe.Scene.Terrain.ClipmapTerrain.GlobeClipmapVS.glsl"), EmbeddedResources.GetText("OpenGlobe.Scene.Terrain.ClipmapTerrain.GlobeClipmapFS.glsl")); _fillPatchPosts = (clipmapPosts + 1) / 4; // M _fillPatchSegments = _fillPatchPosts - 1; // Create the MxM block used to fill the ring and the field. Mesh fieldBlockMesh = RectangleTessellator.Compute( new RectangleD(new Vector2D(0.0, 0.0), new Vector2D(_fillPatchSegments, _fillPatchSegments)), _fillPatchSegments, _fillPatchSegments); _fillPatch = context.CreateVertexArray(fieldBlockMesh, _shaderProgram.VertexAttributes, BufferHint.StaticDraw); // Create the Mx3 block used to fill the space between the MxM blocks in the ring Mesh ringFixupHorizontalMesh = RectangleTessellator.Compute( new RectangleD(new Vector2D(0.0, 0.0), new Vector2D(_fillPatchSegments, 2.0)), _fillPatchSegments, 2); _horizontalFixupPatch = context.CreateVertexArray(ringFixupHorizontalMesh, _shaderProgram.VertexAttributes, BufferHint.StaticDraw); // Create the 3xM block used to fill the space between the MxM blocks in the ring Mesh ringFixupVerticalMesh = RectangleTessellator.Compute( new RectangleD(new Vector2D(0.0, 0.0), new Vector2D(2.0, _fillPatchSegments)), 2, _fillPatchSegments); _verticalFixupPatch = context.CreateVertexArray(ringFixupVerticalMesh, _shaderProgram.VertexAttributes, BufferHint.StaticDraw); Mesh offsetStripHorizontalMesh = RectangleTessellator.Compute( new RectangleD(new Vector2D(0.0, 0.0), new Vector2D(2 * _fillPatchPosts, 1.0)), 2 * _fillPatchPosts, 1); _horizontalOffsetPatch = context.CreateVertexArray(offsetStripHorizontalMesh, _shaderProgram.VertexAttributes, BufferHint.StaticDraw); Mesh offsetStripVerticalMesh = RectangleTessellator.Compute( new RectangleD(new Vector2D(0.0, 0.0), new Vector2D(1.0, 2 * _fillPatchPosts - 1)), 1, 2 * _fillPatchPosts - 1); _verticalOffsetPatch = context.CreateVertexArray(offsetStripVerticalMesh, _shaderProgram.VertexAttributes, BufferHint.StaticDraw); Mesh centerMesh = RectangleTessellator.Compute(new RectangleD(new Vector2D(0.0, 0.0), new Vector2D(2.0, 2.0)), 2, 2); _centerPatch = context.CreateVertexArray(centerMesh, _shaderProgram.VertexAttributes, BufferHint.StaticDraw); Mesh degenerateTriangleMesh = CreateDegenerateTriangleMesh(); _degenerateTrianglePatch = context.CreateVertexArray(degenerateTriangleMesh, _shaderProgram.VertexAttributes, BufferHint.StaticDraw); _patchOriginInClippedLevel = (Uniform<Vector2F>)_shaderProgram.Uniforms["u_patchOriginInClippedLevel"]; _levelScaleFactor = (Uniform<Vector2F>)_shaderProgram.Uniforms["u_levelScaleFactor"]; _levelZeroWorldScaleFactor = (Uniform<Vector2F>)_shaderProgram.Uniforms["u_levelZeroWorldScaleFactor"]; _levelOffsetFromWorldOrigin = (Uniform<Vector2F>)_shaderProgram.Uniforms["u_levelOffsetFromWorldOrigin"]; _heightExaggeration = (Uniform<float>)_shaderProgram.Uniforms["u_heightExaggeration"]; _viewPosInClippedLevel = (Uniform<Vector2F>)_shaderProgram.Uniforms["u_viewPosInClippedLevel"]; _fineLevelOriginInCoarse = (Uniform<Vector2F>)_shaderProgram.Uniforms["u_fineLevelOriginInCoarse"]; _unblendedRegionSize = (Uniform<Vector2F>)_shaderProgram.Uniforms["u_unblendedRegionSize"]; _oneOverBlendedRegionSize = (Uniform<Vector2F>)_shaderProgram.Uniforms["u_oneOverBlendedRegionSize"]; _fineTextureOrigin = (Uniform<Vector2F>)_shaderProgram.Uniforms["u_fineTextureOrigin"]; _showBlendRegions = (Uniform<bool>)_shaderProgram.Uniforms["u_showBlendRegions"]; _useBlendRegions = (Uniform<bool>)_shaderProgram.Uniforms["u_useBlendRegions"]; _oneOverClipmapSize = (Uniform<float>)_shaderProgram.Uniforms["u_oneOverClipmapSize"]; _color = (Uniform<Vector3F>)_shaderProgram.Uniforms["u_color"]; _blendRegionColor = (Uniform<Vector3F>)_shaderProgram.Uniforms["u_blendRegionColor"]; _terrainToImageryResolutionRatio = (Uniform<Vector2F>)_shaderProgram.Uniforms["u_terrainToImageryResolutionRatio"]; _terrainOffsetInImagery = (Uniform<Vector2F>)_shaderProgram.Uniforms["u_terrainOffsetInImagery"]; _oneOverImagerySize = (Uniform<Vector2F>)_shaderProgram.Uniforms["u_oneOverImagerySize"]; _showImagery = (Uniform<bool>)_shaderProgram.Uniforms["u_showImagery"]; _lighting = (Uniform<bool>)_shaderProgram.Uniforms["u_shade"]; ((Uniform<Vector3F>)_shaderProgram.Uniforms["u_globeRadiiSquared"]).Value = ellipsoid.RadiiSquared.ToVector3F(); _renderState = new RenderState(); _renderState.FacetCulling.FrontFaceWindingOrder = fieldBlockMesh.FrontFaceWindingOrder; _primitiveType = fieldBlockMesh.PrimitiveType; float oneOverBlendedRegionSize = (float)(10.0 / _clipmapPosts); _oneOverBlendedRegionSize.Value = new Vector2F(oneOverBlendedRegionSize, oneOverBlendedRegionSize); float unblendedRegionSize = (float)(_clipmapSegments / 2 - _clipmapPosts / 10.0 - 1); _unblendedRegionSize.Value = new Vector2F(unblendedRegionSize, unblendedRegionSize); _useBlendRegions.Value = true; _showImagery.Value = true; _oneOverClipmapSize.Value = 1.0f / clipmapPosts; _updater = new ClipmapUpdater(context, _clipmapLevels); HeightExaggeration = 0.00001f; }
public static Mesh Compute(Ellipsoid ellipsoid, int numberOfPartitions, CubeMapEllipsoidVertexAttributes vertexAttributes) { if (numberOfPartitions < 0) { throw new ArgumentOutOfRangeException("numberOfPartitions"); } if ((vertexAttributes & CubeMapEllipsoidVertexAttributes.Position) != CubeMapEllipsoidVertexAttributes.Position) { throw new ArgumentException("Positions must be provided.", "vertexAttributes"); } Mesh mesh = new Mesh(); mesh.PrimitiveType = PrimitiveType.Triangles; mesh.FrontFaceWindingOrder = WindingOrder.Counterclockwise; int numberOfVertices = NumberOfVertices(numberOfPartitions); VertexAttributeDoubleVector3 positionsAttribute = new VertexAttributeDoubleVector3("position", numberOfVertices); mesh.Attributes.Add(positionsAttribute); IndicesUnsignedInt indices = new IndicesUnsignedInt(3 * NumberOfTriangles(numberOfPartitions)); mesh.Indices = indices; CubeMapMesh CubeMapMesh = new CubeMapMesh(); CubeMapMesh.Ellipsoid = ellipsoid; CubeMapMesh.NumberOfPartitions = numberOfPartitions; CubeMapMesh.Positions = positionsAttribute.Values; CubeMapMesh.Indices = indices; if ((vertexAttributes & CubeMapEllipsoidVertexAttributes.Normal) == CubeMapEllipsoidVertexAttributes.Normal) { VertexAttributeHalfFloatVector3 normalsAttribute = new VertexAttributeHalfFloatVector3("normal", numberOfVertices); mesh.Attributes.Add(normalsAttribute); CubeMapMesh.Normals = normalsAttribute.Values; } if ((vertexAttributes & CubeMapEllipsoidVertexAttributes.TextureCoordinate) == CubeMapEllipsoidVertexAttributes.TextureCoordinate) { VertexAttributeHalfFloatVector2 textureCoordinateAttribute = new VertexAttributeHalfFloatVector2("textureCoordinate", numberOfVertices); mesh.Attributes.Add(textureCoordinateAttribute); CubeMapMesh.TextureCoordinate = textureCoordinateAttribute.Values; } // // Initial cube. In the plane, z = -1: // // +y // | // Q2 * p3 Q1 // / | \ // p0 *--+--* p2 +x // \ | / // Q3 * p1 Q4 // | // // Similarly, p4 to p7 are in the plane z = 1. // CubeMapMesh.Positions.Add(new Vector3D(-1, 0, -1)); CubeMapMesh.Positions.Add(new Vector3D(0, -1, -1)); CubeMapMesh.Positions.Add(new Vector3D(1, 0, -1)); CubeMapMesh.Positions.Add(new Vector3D(0, 1, -1)); CubeMapMesh.Positions.Add(new Vector3D(-1, 0, 1)); CubeMapMesh.Positions.Add(new Vector3D(0, -1, 1)); CubeMapMesh.Positions.Add(new Vector3D(1, 0, 1)); CubeMapMesh.Positions.Add(new Vector3D(0, 1, 1)); // // Edges // // 0 -> 1, 1 -> 2, 2 -> 3, 3 -> 0. Plane z = -1 // 4 -> 5, 5 -> 6, 6 -> 7, 7 -> 4. Plane z = 1 // 0 -> 4, 1 -> 5, 2 -> 6, 3 -> 7. From plane z = -1 to plane z - 1 // int[] edge0to1 = AddEdgePositions(0, 1, CubeMapMesh); int[] edge1to2 = AddEdgePositions(1, 2, CubeMapMesh); int[] edge2to3 = AddEdgePositions(2, 3, CubeMapMesh); int[] edge3to0 = AddEdgePositions(3, 0, CubeMapMesh); int[] edge4to5 = AddEdgePositions(4, 5, CubeMapMesh); int[] edge5to6 = AddEdgePositions(5, 6, CubeMapMesh); int[] edge6to7 = AddEdgePositions(6, 7, CubeMapMesh); int[] edge7to4 = AddEdgePositions(7, 4, CubeMapMesh); int[] edge0to4 = AddEdgePositions(0, 4, CubeMapMesh); int[] edge1to5 = AddEdgePositions(1, 5, CubeMapMesh); int[] edge2to6 = AddEdgePositions(2, 6, CubeMapMesh); int[] edge3to7 = AddEdgePositions(3, 7, CubeMapMesh); AddFaceTriangles(edge0to4, edge0to1, edge1to5, edge4to5, CubeMapMesh); // Q3 Face AddFaceTriangles(edge1to5, edge1to2, edge2to6, edge5to6, CubeMapMesh); // Q4 Face AddFaceTriangles(edge2to6, edge2to3, edge3to7, edge6to7, CubeMapMesh); // Q1 Face AddFaceTriangles(edge3to7, edge3to0, edge0to4, edge7to4, CubeMapMesh); // Q2 Face AddFaceTriangles(ReversedArray(edge7to4), edge4to5, edge5to6, ReversedArray(edge6to7), CubeMapMesh); // Plane z = 1 AddFaceTriangles(edge1to2, ReversedArray(edge0to1), ReversedArray(edge3to0), edge2to3, CubeMapMesh); // Plane z = -1 CubeToEllipsoid(CubeMapMesh); return mesh; }
private void myButton1_Click(object sender, EventArgs e) { _window = Device.CreateWindow(800, 600, "Chapter 13: Clipmap Terrain on a Globe"); _ellipsoid = Ellipsoid.Wgs84; WorldWindTerrainSource terrainSource = new WorldWindTerrainSource(); GMapRestImagery imagery = new GMapRestImagery(); _clipmap = new GlobeClipmapTerrain(_window.Context, terrainSource, imagery, _ellipsoid, 511); _clipmap.HeightExaggeration = 1.0f; IList<GridResolution> gridResolutions = new List<GridResolution>(); gridResolutions.Add(new GridResolution( new Interval(0, 1000000, IntervalEndpoint.Closed, IntervalEndpoint.Open), new Vector2D(0.005, 0.005))); gridResolutions.Add(new GridResolution( new Interval(1000000, 2000000, IntervalEndpoint.Closed, IntervalEndpoint.Open), new Vector2D(0.01, 0.01))); gridResolutions.Add(new GridResolution( new Interval(2000000, 20000000, IntervalEndpoint.Closed, IntervalEndpoint.Open), new Vector2D(0.05, 0.05))); gridResolutions.Add(new GridResolution( new Interval(20000000, double.MaxValue, IntervalEndpoint.Closed, IntervalEndpoint.Open), new Vector2D(0.1, 0.1))); _sceneState = new SceneState(); _sceneState.DiffuseIntensity = 0.90f; _sceneState.SpecularIntensity = 0.05f; _sceneState.AmbientIntensity = 0.05f; _sceneState.Camera.FieldOfViewY = Math.PI / 3.0; _clearState = new ClearState(); _clearState.Color = Color.White; _sceneState.Camera.PerspectiveNearPlaneDistance = 0.000001 * _ellipsoid.MaximumRadius; _sceneState.Camera.PerspectiveFarPlaneDistance = 10.0 * _ellipsoid.MaximumRadius; _sceneState.SunPosition = new Vector3D(200000, 300000, 200000) * _ellipsoid.MaximumRadius; _lookCamera = new CameraLookAtPoint(_sceneState.Camera, _window, _ellipsoid); _lookCamera.Range = 1.5 * _ellipsoid.MaximumRadius; _globe = new RayCastedGlobe(_window.Context); _globe.Shape = _ellipsoid; Bitmap bitmap = new Bitmap("NE2_50M_SR_W_4096.jpg"); _globe.Texture = Device.CreateTexture2D(bitmap, TextureFormat.RedGreenBlue8, false); //_globe.GridResolutions = new GridResolutionCollection(gridResolutions); _clearDepth = new ClearState(); _clearDepth.Buffers = ClearBuffers.DepthBuffer | ClearBuffers.StencilBuffer; //_window.Keyboard.KeyDown += OnKeyDown; _window.Resize += OnResize; _window.RenderFrame += OnRenderFrame; _window.PreRenderFrame += OnPreRenderFrame; _hudFont = new Font("Arial", 16); _hud = new HeadsUpDisplay(); _hud.Color = Color.Blue; //_flyCamera = new CameraFly(_sceneState.Camera, _window); //_flyCamera.MovementRate = 1200.0; //_flyCamera.InputEnabled = true; _sceneState.Camera.Target = new Vector3D(115, -35, 100.0); _window.Run(30); }
/// <summary> /// Sets the <see cref="CenterPoint"/> and <see cref="FixedToLocalRotation"/> properties so that the /// camera is looking at a given longitude, latitude, and height and is oriented in that point's local /// East-North-Up frame. This method does not change the <see cref="Azimuth"/>, <see cref="Elevation"/>, /// or <see cref="Range"/> properties, but the existing values of those properties are interpreted in the /// new reference frame. /// </summary> /// <param name="longitude">The longitude of the point to look at, in radians.</param> /// <param name="latitude">The latitude of the point to look at, in radians.</param> /// <param name="height">The height of the point to look at, in meters above the <see cref="Ellipsoid"/> surface.</param> public void ViewPoint(Ellipsoid ellipsoid, Geodetic3D geographic) { _centerPoint = ellipsoid.ToVector3D(geographic); // Fixed to East-North-Up rotation, from Wikipedia's "Geodetic System" topic. double cosLon = Math.Cos(geographic.Longitude); double cosLat = Math.Cos(geographic.Latitude); double sinLon = Math.Sin(geographic.Longitude); double sinLat = Math.Sin(geographic.Latitude); _fixedToLocalRotation = new Matrix3D(-sinLon, cosLon, 0.0, -sinLat * cosLon, -sinLat * sinLon, cosLat, cosLat * cosLon, cosLat * sinLon, sinLat); UpdateCameraFromParameters(); }
public ShapefileWorker(Context context, Ellipsoid globeShape, MessageQueue doneQueue) { _context = context; _globeShape = globeShape; _doneQueue = doneQueue; }
public PolylineShapefile( Shapefile shapefile, Context context, Ellipsoid globeShape, ShapefileAppearance appearance) { Verify.ThrowIfNull(shapefile); Verify.ThrowIfNull(context); Verify.ThrowIfNull(globeShape); Verify.ThrowIfNull(appearance); _polyline = new OutlinedPolylineTexture(); int positionsCount = 0; int indicesCount = 0; PolylineCapacities(shapefile, out positionsCount, out indicesCount); VertexAttributeDoubleVector3 positionAttribute = new VertexAttributeDoubleVector3("position", positionsCount); VertexAttributeRGBA colorAttribute = new VertexAttributeRGBA("color", positionsCount); VertexAttributeRGBA outlineColorAttribute = new VertexAttributeRGBA("outlineColor", positionsCount); IndicesUnsignedInt indices = new IndicesUnsignedInt(indicesCount); foreach (Shape shape in shapefile) { if (shape.ShapeType != ShapeType.Polyline) { throw new NotSupportedException("The type of an individual shape does not match the Shapefile type."); } PolylineShape polylineShape = (PolylineShape)shape; for (int j = 0; j < polylineShape.Count; ++j) { ShapePart part = polylineShape[j]; for (int i = 0; i < part.Count; ++i) { Vector2D point = part[i]; positionAttribute.Values.Add(globeShape.ToVector3D(Trig.ToRadians(new Geodetic3D(point.X, point.Y)))); colorAttribute.AddColor(appearance.PolylineColor); outlineColorAttribute.AddColor(appearance.PolylineOutlineColor); if (i != 0) { indices.Values.Add((uint)positionAttribute.Values.Count - 2); indices.Values.Add((uint)positionAttribute.Values.Count - 1); } } } } Mesh mesh = new Mesh(); mesh.PrimitiveType = PrimitiveType.Lines; mesh.Attributes.Add(positionAttribute); mesh.Attributes.Add(colorAttribute); mesh.Attributes.Add(outlineColorAttribute); mesh.Indices = indices; _polyline.Set(context, mesh); _polyline.Width = appearance.PolylineWidth; _polyline.OutlineWidth = appearance.PolylineOutlineWidth; }
public double Height(Ellipsoid shape) { return shape.ToGeodetic3D(Eye).Height; }
public void ToGeodetic3D() { Ellipsoid ellipsoid = new Ellipsoid(6378137.0, 6378137.0, 6356752.314245); Vector3D v = ellipsoid.ToVector3D(new Geodetic3D(0, 0, 0)); Geodetic3D g = ellipsoid.ToGeodetic3D(v); Assert.AreEqual(0.0, g.Longitude, 1e-10); Assert.AreEqual(0.0, g.Latitude, 1e-8); Assert.AreEqual(0.0, g.Height, 1e-10); v = ellipsoid.ToVector3D(new Geodetic3D(Trig.ToRadians(45.0), Trig.ToRadians(-60.0), -123.4)); g = ellipsoid.ToGeodetic3D(v); Assert.AreEqual(Trig.ToRadians(45.0), g.Longitude, 1e-10); Assert.AreEqual(Trig.ToRadians(-60.0), g.Latitude, 1e-3); Assert.AreEqual(-123.4, g.Height, 1e-3); v = ellipsoid.ToVector3D(new Geodetic3D(Trig.ToRadians(-97.3), Trig.ToRadians(71.2), 1188.7)); g = ellipsoid.ToGeodetic3D(v); Assert.AreEqual(Trig.ToRadians(-97.3), g.Longitude, 1e-10); Assert.AreEqual(Trig.ToRadians(71.2), g.Latitude, 1e-3); Assert.AreEqual(1188.7, g.Height, 1e-3); }
private void OnKeyDown(object sender, KeyboardKeyEventArgs e) { if ((e.Key == KeyboardKey.Up) || (e.Key == KeyboardKey.Down)) { if (e.Key == KeyboardKey.Up) { _semiMinorAxis = Math.Min(_semiMinorAxis + _semiMinorAxisDelta, 1.0); } else { _semiMinorAxis = Math.Max(_semiMinorAxis - _semiMinorAxisDelta, 0.1); } _globeShape = new Ellipsoid(1, 1, _semiMinorAxis); CreateScene(); } }