// Add a sphere with texture coordinates. public static void AddTexturedSphere(this MeshGeometry3D mesh, Point3D center, double radius, int numTheta, int numPhi, bool smooth = false) { double dtheta = 2 * Math.PI / numTheta; double dphi = Math.PI / numPhi; double theta = 0; for (int t = 0; t < numTheta; t++) { double phi = 0; for (int p = 0; p < numPhi; p++) { // Find this piece's points. Point3D point1 = G3.SpherePoint(center, radius, theta, phi).Round(); Point3D point2 = G3.SpherePoint(center, radius, theta, phi + dphi).Round(); Point3D point3 = G3.SpherePoint(center, radius, theta + dtheta, phi + dphi).Round(); Point3D point4 = G3.SpherePoint(center, radius, theta + dtheta, phi).Round(); // Find this piece's texture coordinates. Point coords1 = new Point((double)t / numTheta, (double)p / numPhi); Point coords2 = new Point((double)t / numTheta, (double)(p + 1) / numPhi); Point coords3 = new Point((double)(t + 1) / numTheta, (double)(p + 1) / numPhi); Point coords4 = new Point((double)(t + 1) / numTheta, (double)p / numPhi); // Find this piece's normals. Vector3D normal1 = (Vector3D)G3.SpherePoint(D3.Origin, 1, theta, phi).Round(); Vector3D normal2 = (Vector3D)G3.SpherePoint(D3.Origin, 1, theta, phi + dphi).Round(); Vector3D normal3 = (Vector3D)G3.SpherePoint(D3.Origin, 1, theta + dtheta, phi + dphi).Round(); Vector3D normal4 = (Vector3D)G3.SpherePoint(D3.Origin, 1, theta + dtheta, phi).Round(); // Make the first triangle. int index = mesh.Positions.Count; mesh.Positions.Add(point1); if (smooth) { mesh.Normals.Add(normal1); } mesh.TextureCoordinates.Add(coords1); mesh.Positions.Add(point2); if (smooth) { mesh.Normals.Add(normal2); } mesh.TextureCoordinates.Add(coords2); mesh.Positions.Add(point3); if (smooth) { mesh.Normals.Add(normal3); } mesh.TextureCoordinates.Add(coords3); mesh.TriangleIndices.Add(index++); mesh.TriangleIndices.Add(index++); mesh.TriangleIndices.Add(index++); // Make the second triangle. mesh.Positions.Add(point1); if (smooth) { mesh.Normals.Add(normal1); } mesh.TextureCoordinates.Add(coords1); mesh.Positions.Add(point3); if (smooth) { mesh.Normals.Add(normal3); } mesh.TextureCoordinates.Add(coords3); mesh.Positions.Add(point4); if (smooth) { mesh.Normals.Add(normal4); } mesh.TextureCoordinates.Add(coords4); mesh.TriangleIndices.Add(index++); mesh.TriangleIndices.Add(index++); mesh.TriangleIndices.Add(index++); phi += dphi; } theta += dtheta; } }
public SceneModel3D(double sideLength, double axisThickness) { this.ModelVisual3D = new ModelVisual3D(); var sceneModel3DGroup = new Model3DGroup(); // Scene plane building var halfSideLength = sideLength / 2; var axisRadius = axisThickness / 2; var planeGeometryModel3D = new GeometryModel3D(); var planeMeshGeometry3D = new MeshGeometry3D(); MeshGeometry3DHelper.AddTriangle( planeMeshGeometry3D, new Point3D(halfSideLength, -halfSideLength, 0), new Point3D(halfSideLength, halfSideLength, 0), new Point3D(-halfSideLength, halfSideLength, 0)); MeshGeometry3DHelper.AddTriangle( planeMeshGeometry3D, new Point3D(halfSideLength, -halfSideLength, 0), new Point3D(-halfSideLength, halfSideLength, 0), new Point3D(-halfSideLength, -halfSideLength, 0)); planeGeometryModel3D.Geometry = planeMeshGeometry3D; planeGeometryModel3D.Material = new DiffuseMaterial(Brushes.DimGray); // Ox axis var xAxisGeometryModel3D = new GeometryModel3D(); var xAxisMeshGeometry3D = new MeshGeometry3D(); MeshGeometry3DHelper.AddSmoothCylinder( xAxisMeshGeometry3D, new Point3D(0, 0, 0), new Vector3D(halfSideLength, 0, 0), axisRadius); xAxisGeometryModel3D.Geometry = xAxisMeshGeometry3D; xAxisGeometryModel3D.Material = new DiffuseMaterial(Brushes.Green); // Oy axis var yAxisGeometryModel3D = new GeometryModel3D(); var yAxisMeshGeometry3D = new MeshGeometry3D(); MeshGeometry3DHelper.AddSmoothCylinder( yAxisMeshGeometry3D, new Point3D(0, 0, 0), new Vector3D(0, halfSideLength, 0), axisRadius); yAxisGeometryModel3D.Geometry = yAxisMeshGeometry3D; yAxisGeometryModel3D.Material = new DiffuseMaterial(Brushes.Red); // Oz axis var zAxisGeometryModel3D = new GeometryModel3D(); var zAxisMeshGeometry3D = new MeshGeometry3D(); MeshGeometry3DHelper.AddSmoothCylinder( zAxisMeshGeometry3D, new Point3D(0, 0, 0), new Vector3D(0, 0, halfSideLength), axisRadius); zAxisGeometryModel3D.Geometry = zAxisMeshGeometry3D; zAxisGeometryModel3D.Material = new DiffuseMaterial(Brushes.Blue); sceneModel3DGroup.Children.Add(planeGeometryModel3D); sceneModel3DGroup.Children.Add(xAxisGeometryModel3D); sceneModel3DGroup.Children.Add(yAxisGeometryModel3D); sceneModel3DGroup.Children.Add(zAxisGeometryModel3D); this.ModelVisual3D.Content = sceneModel3DGroup; }
// Make a model with a material group. public static GeometryModel3D MakeModel(this MeshGeometry3D mesh, MaterialGroup material) { return(new GeometryModel3D(mesh, material)); }
public static void AddConeFrustum(this MeshGeometry3D mesh, Point3D center, Point3D[] polygon, Vector3D axis, double length, bool smoothSides = false) { mesh.AddFrustum(center, polygon, axis, length, true); }
// Add a polygon with a variable argument list of points // and no texture coordinates. public static void AddPolygon(this MeshGeometry3D mesh, Dictionary <Point3D, int> pointDict = null, params Point3D[] points) { mesh.AddPolygon(points, pointDict, null); }
// Add a regular polygon with optional texture coordinates. public static void AddRegularPolygon(this MeshGeometry3D mesh, int numSides, Point3D center, Vector3D vx, Vector3D vy, Point[] textureCoords = null) { mesh.AddRegularPolygon(numSides, center, vx, vy, null, textureCoords); }
public MainViewModel() { EffectsManager = new DefaultEffectsManager(); // ---------------------------------------------- // titles this.Title = "Lighting Demo"; this.SubTitle = "WPF & SharpDX"; // ---------------------------------------------- // camera setup this.Camera = new PerspectiveCamera { Position = new Point3D(100, 100, 100), LookDirection = new Vector3D(-100, -100, -100), UpDirection = new Vector3D(0, 1, 0) }; // ---------------------------------------------- // setup scene this.AmbientLightColor = Colors.DimGray; this.Light1Color = Colors.LightGray; this.Light1Direction = new Vector3D(-100, -100, -100); SetupCameraBindings(Camera); // ---------------------------------------------- // ---------------------------------------------- // scene model3d this.ModelMaterial = PhongMaterials.Silver; // ---------------------------------------------- // floor model3d var b2 = new MeshBuilder(true, true, true); b2.AddBox(new Vector3(0.0f, 0, 0.0f), 150, 1, 150, BoxFaces.All); b2.AddBox(new Vector3(0, 25, 70), 150, 50, 20); b2.AddBox(new Vector3(0, 25, -70), 150, 50, 20); this.Floor = b2.ToMeshGeometry3D(); this.FloorMaterial = PhongMaterials.Bisque; this.FloorMaterial.DiffuseMap = TextureModel.Create(new System.Uri(@"TextureCheckerboard2.jpg", System.UriKind.RelativeOrAbsolute).ToString()); this.FloorMaterial.NormalMap = TextureModel.Create(new System.Uri(@"TextureCheckerboard2_dot3.jpg", System.UriKind.RelativeOrAbsolute).ToString()); var caritems = Load3ds("leone.3DBuilder.obj").Select(x => x.Geometry as MeshGeometry3D).ToArray(); var scale = new Vector3(1f); foreach (var item in caritems) { for (int i = 0; i < item.Positions.Count; ++i) { item.Positions[i] = item.Positions[i] * scale; } } Model = MeshGeometry3D.Merge(caritems); ModelTransform = new Media3D.RotateTransform3D() { Rotation = new Media3D.AxisAngleRotation3D(new Vector3D(1, 0, 0), -90) }; Instances = new Matrix[6]; for (int i = 0; i < Instances.Length; ++i) { Instances[i] = Matrix.Translation(new Vector3(15 * i - 30, 15 * (i % 2) - 30, 0)); } OutlineInstances = new Matrix[6]; for (int i = 0; i < Instances.Length; ++i) { OutlineInstances[i] = Matrix.Translation(new Vector3(15 * i - 30, 15 * (i % 2), 0)); } var blendDesc = new BlendStateDescription(); blendDesc.RenderTarget[0] = new RenderTargetBlendDescription { IsBlendEnabled = true, BlendOperation = BlendOperation.Add, AlphaBlendOperation = BlendOperation.Add, SourceBlend = BlendOption.One, DestinationBlend = BlendOption.One, SourceAlphaBlend = BlendOption.Zero, DestinationAlphaBlend = BlendOption.One, RenderTargetWriteMask = ColorWriteMaskFlags.All }; BlendDescription = blendDesc; DepthStencilDescription = new DepthStencilStateDescription() { IsDepthEnabled = true, DepthComparison = Comparison.LessEqual, DepthWriteMask = DepthWriteMask.Zero }; }
// Add a polygon with points stored in an array. // Texture coordinates are optional. public static void AddPolygon(this MeshGeometry3D mesh, Point3D[] points, Point[] textureCoords = null) { mesh.AddPolygon(points, null, textureCoords); }
private MeshGeometry3D createLast(double x) { MeshGeometry3D mesh = new MeshGeometry3D(); double l2 = 7; double w2 = 1.1; double h = 1; mesh.Positions.Add(new Point3D(x, 0, 0)); mesh.Positions.Add(new Point3D(x, h, 0)); mesh.Positions.Add(new Point3D(x + w2, 0, 0)); mesh.Positions.Add(new Point3D(x + w2, h, 0)); mesh.Positions.Add(new Point3D(x, 0, l2)); mesh.Positions.Add(new Point3D(x, h, l2)); mesh.Positions.Add(new Point3D(x + w2, 0, l2)); mesh.Positions.Add(new Point3D(x + w2, h, l2)); // Front side triangles mesh.TriangleIndices.Add(4); mesh.TriangleIndices.Add(6); mesh.TriangleIndices.Add(7); mesh.TriangleIndices.Add(4); mesh.TriangleIndices.Add(7); mesh.TriangleIndices.Add(5); // right side triangles mesh.TriangleIndices.Add(6); mesh.TriangleIndices.Add(2); mesh.TriangleIndices.Add(3); mesh.TriangleIndices.Add(6); mesh.TriangleIndices.Add(3); mesh.TriangleIndices.Add(7); // back side triangles mesh.TriangleIndices.Add(2); mesh.TriangleIndices.Add(0); mesh.TriangleIndices.Add(1); mesh.TriangleIndices.Add(2); mesh.TriangleIndices.Add(1); mesh.TriangleIndices.Add(3); // left side triangles mesh.TriangleIndices.Add(0); mesh.TriangleIndices.Add(4); mesh.TriangleIndices.Add(5); mesh.TriangleIndices.Add(0); mesh.TriangleIndices.Add(5); mesh.TriangleIndices.Add(1); // top side triangles mesh.TriangleIndices.Add(5); mesh.TriangleIndices.Add(7); mesh.TriangleIndices.Add(3); mesh.TriangleIndices.Add(5); mesh.TriangleIndices.Add(3); mesh.TriangleIndices.Add(1); // bottom side triangles mesh.TriangleIndices.Add(6); mesh.TriangleIndices.Add(4); mesh.TriangleIndices.Add(0); mesh.TriangleIndices.Add(6); mesh.TriangleIndices.Add(0); mesh.TriangleIndices.Add(2); return(mesh); }
// Define the model. private void DefineModel(Model3DGroup group) { // Make the initial surface. int numX = 40; int numZ = 40; Point3D[,] surface = G3.InitSurface(0, numX, -3, 3, numZ, -3, 3); // Add some craters. AddCrater(surface, -1, 0, 1.5, 0.3); AddCrater(surface, 1.6, -1.5, 0.5, 0.4); AddCrater(surface, 1.5, 1.5, 0.75, 0.3); AddCrater(surface, 0.5, -0.6, 1.25, 0.1); // Add some relatively large-scale randomness to random points. Random rand = new Random(0); for (int i = 0; i < 10; i++) { int ix = rand.Next(0, numX); int iz = rand.Next(0, numZ); surface[ix, iz].Y += rand.NextDouble(-0.1, 0.1); } // Fractalize. surface = G3.FractalizeSurface(surface, 2, 1, -0.05, 0.05); // Translate to center better. TranslateTransform3D trans = new TranslateTransform3D(0, 1, 0); numX = surface.GetUpperBound(0) + 1; numZ = surface.GetUpperBound(1) + 1; for (int ix = 0; ix < numX; ix++) { for (int iz = 0; iz < numZ; iz++) { surface[ix, iz] = trans.Transform(surface[ix, iz]); } } // Make the mesh. MeshGeometry3D mesh1 = new MeshGeometry3D(); mesh1.AddSurface(surface); // Apply a height map. double minY = surface[0, 0].Y; double maxY = minY; foreach (Point3D point in surface) { if (minY > point.Y) { minY = point.Y; } if (maxY < point.Y) { maxY = point.Y; } } mesh1.ApplyHeightMap(0, 1, minY, maxY); GradientStopCollection stops = new GradientStopCollection(); stops.Add(new GradientStop(Colors.Gray, 0)); stops.Add(new GradientStop(Colors.LightGray, 0.25)); stops.Add(new GradientStop(Colors.LightGray, 0.75)); stops.Add(new GradientStop(Colors.White, 1)); LinearGradientBrush brush = new LinearGradientBrush(stops, new Point(0, 0), new Point(1, 1)); group.Children.Add(mesh1.MakeModel(brush)); }
private MeshGeometry3D createE(double x) { MeshGeometry3D mesh = new MeshGeometry3D(); double l1 = 5.5, l3 = 7; double w1 = .6, w4 = .6; double h = 1; mesh.Positions.Add(new Point3D(x, 0, 0)); mesh.Positions.Add(new Point3D(x, h, 0)); mesh.Positions.Add(new Point3D(x + w1, 0, 0)); mesh.Positions.Add(new Point3D(x + w1, h, 0)); mesh.Positions.Add(new Point3D(x - w4, 0, l1)); mesh.Positions.Add(new Point3D(x - w4, h, l1)); mesh.Positions.Add(new Point3D(x, 0, l1)); mesh.Positions.Add(new Point3D(x, h, l1)); mesh.Positions.Add(new Point3D(x + w1, 0, l1)); mesh.Positions.Add(new Point3D(x + w1, h, l1)); mesh.Positions.Add(new Point3D(x - w4, 0, l3)); mesh.Positions.Add(new Point3D(x - w4, h, l3)); mesh.Positions.Add(new Point3D(x + w1, 0, l3)); mesh.Positions.Add(new Point3D(x + w1, h, l3)); // Front side triangles mesh.TriangleIndices.Add(10); mesh.TriangleIndices.Add(12); mesh.TriangleIndices.Add(13); mesh.TriangleIndices.Add(10); mesh.TriangleIndices.Add(13); mesh.TriangleIndices.Add(11); // right side triangles mesh.TriangleIndices.Add(12); mesh.TriangleIndices.Add(2); mesh.TriangleIndices.Add(3); mesh.TriangleIndices.Add(12); mesh.TriangleIndices.Add(3); mesh.TriangleIndices.Add(13); // left side triangles mesh.TriangleIndices.Add(0); mesh.TriangleIndices.Add(6); mesh.TriangleIndices.Add(7); mesh.TriangleIndices.Add(0); mesh.TriangleIndices.Add(7); mesh.TriangleIndices.Add(1); // left side triangles mesh.TriangleIndices.Add(4); mesh.TriangleIndices.Add(10); mesh.TriangleIndices.Add(11); mesh.TriangleIndices.Add(4); mesh.TriangleIndices.Add(11); mesh.TriangleIndices.Add(5); // Back side triangles mesh.TriangleIndices.Add(2); mesh.TriangleIndices.Add(0); mesh.TriangleIndices.Add(1); mesh.TriangleIndices.Add(2); mesh.TriangleIndices.Add(1); mesh.TriangleIndices.Add(3); // back side triangles mesh.TriangleIndices.Add(6); mesh.TriangleIndices.Add(4); mesh.TriangleIndices.Add(5); mesh.TriangleIndices.Add(6); mesh.TriangleIndices.Add(5); mesh.TriangleIndices.Add(7); // top side triangles mesh.TriangleIndices.Add(7); mesh.TriangleIndices.Add(9); mesh.TriangleIndices.Add(3); mesh.TriangleIndices.Add(7); mesh.TriangleIndices.Add(3); mesh.TriangleIndices.Add(1); // bottom side triangles mesh.TriangleIndices.Add(8); mesh.TriangleIndices.Add(6); mesh.TriangleIndices.Add(0); mesh.TriangleIndices.Add(8); mesh.TriangleIndices.Add(0); mesh.TriangleIndices.Add(2); // top side triangles mesh.TriangleIndices.Add(11); mesh.TriangleIndices.Add(13); mesh.TriangleIndices.Add(9); mesh.TriangleIndices.Add(11); mesh.TriangleIndices.Add(9); mesh.TriangleIndices.Add(5); // back side triangles mesh.TriangleIndices.Add(6); mesh.TriangleIndices.Add(4); mesh.TriangleIndices.Add(5); mesh.TriangleIndices.Add(6); mesh.TriangleIndices.Add(5); mesh.TriangleIndices.Add(7); // bottom side triangles mesh.TriangleIndices.Add(12); mesh.TriangleIndices.Add(10); mesh.TriangleIndices.Add(4); mesh.TriangleIndices.Add(12); mesh.TriangleIndices.Add(4); mesh.TriangleIndices.Add(8); return(mesh); }
private void BuildSolid() { int[] Key = new int[88]; Key[0] = 0; Key[1] = 1; Key[2] = 3; Key[87] = 4; int k; for (int i = 3; i < 87; i++) { int n = i % 12; if (n == 3 || n == 8) { k = 0; } else if (n == 5 || n == 10 || n == 0) { k = 2; } else if (n == 7 || n == 2) { k = 3; } else { k = 1; } Key[i] = k; } MeshGeometry3D mesh = new MeshGeometry3D(); mGeometry = new GeometryModel3D(mesh, new DiffuseMaterial(Brushes.PaleVioletRed)); Transform3DGroup t3d = new Transform3DGroup(); mGeometry.Transform = t3d; double x = 0; for (int j = 0; j < 88; j++) { int type = Key[j]; if (type == 0) { mesh = createC(x); x = x + .9; mGeometry = new GeometryModel3D(mesh, new DiffuseMaterial(Brushes.White)); } else if (type == 1) { mesh = createSharp(x); x = x + .85; mGeometry = new GeometryModel3D(mesh, new DiffuseMaterial(Brushes.Black)); } else if (type == 2) { mesh = createD(x); x = x + .7; mGeometry = new GeometryModel3D(mesh, new DiffuseMaterial(Brushes.White)); } else if (type == 3) { mesh = createE(x); x = x + .6; mGeometry = new GeometryModel3D(mesh, new DiffuseMaterial(Brushes.White)); } else if (type == 4) { mesh = createLast(x); x = x + .9; mGeometry = new GeometryModel3D(mesh, new DiffuseMaterial(Brushes.White)); } mGeometry.Transform = t3d; group.Children.Add(mGeometry); } }
private MeshGeometry3D createD(double x) { MeshGeometry3D mesh = new MeshGeometry3D(); double l1 = 5.5, l3 = 7; double w5 = .7, w6 = .55, w7 = 1.05; double h = 1; mesh.Positions.Add(new Point3D(x, 0, 0)); mesh.Positions.Add(new Point3D(x, h, 0)); mesh.Positions.Add(new Point3D(x + w5, 0, 0)); mesh.Positions.Add(new Point3D(x + w5, h, 0)); mesh.Positions.Add(new Point3D(x, 0, l1)); mesh.Positions.Add(new Point3D(x, h, l1)); mesh.Positions.Add(new Point3D(x + w5, 0, l1)); mesh.Positions.Add(new Point3D(x + w5, h, l1)); mesh.Positions.Add(new Point3D(x - w6, 0, l1)); mesh.Positions.Add(new Point3D(x - w6, h, l1)); mesh.Positions.Add(new Point3D(x + w7, 0, l1)); mesh.Positions.Add(new Point3D(x + w7, h, l1)); mesh.Positions.Add(new Point3D(x - w6, 0, l3)); mesh.Positions.Add(new Point3D(x - w6, h, l3)); mesh.Positions.Add(new Point3D(x + w7, 0, l3)); mesh.Positions.Add(new Point3D(x + w7, h, l3)); // Front side triangles mesh.TriangleIndices.Add(12); mesh.TriangleIndices.Add(14); mesh.TriangleIndices.Add(15); mesh.TriangleIndices.Add(12); mesh.TriangleIndices.Add(15); mesh.TriangleIndices.Add(13); // right side triangles mesh.TriangleIndices.Add(14); mesh.TriangleIndices.Add(10); mesh.TriangleIndices.Add(11); mesh.TriangleIndices.Add(14); mesh.TriangleIndices.Add(11); mesh.TriangleIndices.Add(15); // back side triangles mesh.TriangleIndices.Add(10); mesh.TriangleIndices.Add(6); mesh.TriangleIndices.Add(7); mesh.TriangleIndices.Add(10); mesh.TriangleIndices.Add(7); mesh.TriangleIndices.Add(11); // right side triangles mesh.TriangleIndices.Add(6); mesh.TriangleIndices.Add(2); mesh.TriangleIndices.Add(3); mesh.TriangleIndices.Add(6); mesh.TriangleIndices.Add(3); mesh.TriangleIndices.Add(7); // Back side triangles mesh.TriangleIndices.Add(2); mesh.TriangleIndices.Add(0); mesh.TriangleIndices.Add(1); mesh.TriangleIndices.Add(2); mesh.TriangleIndices.Add(1); mesh.TriangleIndices.Add(3); // left side triangles mesh.TriangleIndices.Add(0); mesh.TriangleIndices.Add(4); mesh.TriangleIndices.Add(5); mesh.TriangleIndices.Add(0); mesh.TriangleIndices.Add(5); mesh.TriangleIndices.Add(1); // back side triangles mesh.TriangleIndices.Add(4); mesh.TriangleIndices.Add(8); mesh.TriangleIndices.Add(9); mesh.TriangleIndices.Add(4); mesh.TriangleIndices.Add(9); mesh.TriangleIndices.Add(5); // left side triangles mesh.TriangleIndices.Add(8); mesh.TriangleIndices.Add(12); mesh.TriangleIndices.Add(13); mesh.TriangleIndices.Add(8); mesh.TriangleIndices.Add(13); mesh.TriangleIndices.Add(9); // top side triangles mesh.TriangleIndices.Add(13); mesh.TriangleIndices.Add(15); mesh.TriangleIndices.Add(11); mesh.TriangleIndices.Add(13); mesh.TriangleIndices.Add(11); mesh.TriangleIndices.Add(9); // top side triangles mesh.TriangleIndices.Add(5); mesh.TriangleIndices.Add(7); mesh.TriangleIndices.Add(3); mesh.TriangleIndices.Add(5); mesh.TriangleIndices.Add(3); mesh.TriangleIndices.Add(1); // bottom side triangles mesh.TriangleIndices.Add(14); mesh.TriangleIndices.Add(12); mesh.TriangleIndices.Add(8); mesh.TriangleIndices.Add(14); mesh.TriangleIndices.Add(8); mesh.TriangleIndices.Add(10); // bottom side triangles mesh.TriangleIndices.Add(6); mesh.TriangleIndices.Add(4); mesh.TriangleIndices.Add(0); mesh.TriangleIndices.Add(6); mesh.TriangleIndices.Add(0); mesh.TriangleIndices.Add(2); return(mesh); }
protected void UpdateModel(Vector3 up) { var left = new Vector3(up.Y, up.Z, up.X); var front = Vector3.Cross(left, up); if (!isRightHanded) { front *= -1; left *= -1; } var builder = new MeshBuilder(true, true, false); builder.AddCubeFace(new Vector3(0, 0, 0), front, up, size, size, size); builder.AddCubeFace(new Vector3(0, 0, 0), -front, up, size, size, size); builder.AddCubeFace(new Vector3(0, 0, 0), left, up, size, size, size); builder.AddCubeFace(new Vector3(0, 0, 0), -left, up, size, size, size); builder.AddCubeFace(new Vector3(0, 0, 0), up, left, size, size, size); builder.AddCubeFace(new Vector3(0, 0, 0), -up, -left, size, size, size); var mesh = builder.ToMesh(); CreateTextureCoordinates(mesh); var pts = new List <Vector3>(); var center = up * -size / 2 * 1.1f; int phi = 24; for (int i = 0; i < phi; i++) { double angle = 0 + (360 * i / (phi - 1)); double angleRad = angle / 180 * Math.PI; var dir = (left * (float)Math.Cos(angleRad)) + (front * (float)Math.Sin(angleRad)); pts.Add(center + (dir * (size - 0.75f))); pts.Add(center + (dir * (size + 1.1f))); } builder = new MeshBuilder(false, false, false); builder.AddTriangleStrip(pts); var pie = builder.ToMesh(); int count = pie.Indices.Count; for (int i = 0; i < count;) { var v1 = pie.Indices[i++]; var v2 = pie.Indices[i++]; var v3 = pie.Indices[i++]; pie.Indices.Add(v1); pie.Indices.Add(v3); pie.Indices.Add(v2); } var newMesh = MeshGeometry3D.Merge(new MeshGeometry3D[] { pie, mesh }); if (!isRightHanded) { for (int i = 0; i < newMesh.Positions.Count; ++i) { var p = newMesh.Positions[i]; p.Z *= -1; newMesh.Positions[i] = p; } } newMesh.TextureCoordinates = new Vector2Collection(Enumerable.Repeat(new Vector2(-1, -1), pie.Positions.Count)); newMesh.Colors = new Color4Collection(Enumerable.Repeat(new Color4(1f, 1f, 1f, 1f), pie.Positions.Count)); newMesh.TextureCoordinates.AddRange(mesh.TextureCoordinates); newMesh.Colors.AddRange(Enumerable.Repeat(new Color4(1, 1, 1, 1), mesh.Positions.Count)); ViewBoxMeshModel.Geometry = newMesh; }
// Make stacked pie slices. private void MakeStackedPieSlices(Point3D center, double r, double height, double[,] values, Brush[,] brushes, int numPieces, Model3DGroup group) { // Calculate percentages. int numLevels = values.GetUpperBound(0) + 1; int numWedges = values.GetUpperBound(1) + 1; int numValues = values.Length; double total = 0; foreach (double value in values) { total += value; } double[,] percents = new double[2, numWedges]; for (int level = 0; level < numLevels; level++) { for (int slice = 0; slice < numWedges; slice++) { percents[level, slice] = values[level, slice] / total; } } // Draw slices. double minTheta = 0; for (int wedge = 0; wedge < numWedges; wedge++) { // Get this wedge's total percent. double wedgePercent = 0; for (int level = 0; level < numLevels; level++) { wedgePercent += percents[level, wedge]; } // Calculate the size of the wedge in degrees. double maxTheta = minTheta + 360.0 * wedgePercent; int wedgePieces = (int)(numPieces * wedgePercent); if (wedgePieces < 2) { wedgePieces = 2; } // Make the slices. double y = center.Y; for (int level = 0; level < numLevels; level++) { // Calculate the slice's height. double sliceHgt = height * percents[level, wedge] / wedgePercent; MeshGeometry3D mesh = new MeshGeometry3D(); Point3D sliceCenter = new Point3D(center.X, y, center.Z); mesh.AddPieSlice(sliceCenter, sliceHgt, minTheta, maxTheta, r, wedgePieces); group.Children.Add(mesh.MakeModel(brushes[level, wedge])); y += sliceHgt; } minTheta = maxTheta; } }
/// <summary> /// Generates triangle from 3 points. /// </summary> /// <param name="p0">A Kit3D.Windows.Media.Media3D.Point3D that specifies /// 3D point for visualization component.</param> /// <param name="p1">A Kit3D.Windows.Media.Media3D.Point3D that specifies /// 3D point for visualization component.</param> /// <param name="p2">A Kit3D.Windows.Media.Media3D.Point3D that specifies /// 3D point for visualization component.</param> /// <returns>A Kit3D.Windows.Media.Media3D.Model3DGroup that specifies /// trianle of triangle.</returns> private Model3DGroup CreateTriangleModel(Point3D p0, Point3D p1, Point3D p2) { MeshGeometry3D mesh = new MeshGeometry3D(); mesh.Positions.Add(p0); mesh.Positions.Add(p1); mesh.Positions.Add(p2); mesh.TriangleIndices.Add(0); mesh.TriangleIndices.Add(1); mesh.TriangleIndices.Add(2); mesh.TextureCoordinates.Add(new Point(1, 1)); mesh.TextureCoordinates.Add(new Point(1, 0)); mesh.TextureCoordinates.Add(new Point(0, 1)); Material material = new DiffuseMaterial(new Kit3DBrush( new SolidColorBrush(CalculateColor(CalculateNormal(p0, p1, p2))))); GeometryModel3D model = new GeometryModel3D( mesh, material); Model3DGroup group = new Model3DGroup(); group.Children.Add(model); return group; }
private static Rect3D CalculateBounds(MeshGeometry3D mesh, Matrix3D tx) { return(CalculateBounds(mesh.Positions, tx)); }
public static void AddPolygon(this MeshGeometry3D mesh, Point3D[] points, Dictionary <Point3D, int> pointDict = null, Point[] textureCoords = null) { // Make a point dictionary. if (pointDict == null) { pointDict = new Dictionary <Point3D, int>(); } // Get the first two point indices. int indexA, indexB, indexC; Point3D roundedA = points[0].Round(); if (textureCoords == null) { indexA = mesh.PointIndex(roundedA, pointDict); } else { indexA = mesh.PointIndex(roundedA, textureCoords[0], pointDict); } Point3D roundedC = points[1].Round(); if (textureCoords == null) { indexC = mesh.PointIndex(roundedC, pointDict); } else { indexC = mesh.PointIndex(roundedC, textureCoords[1], pointDict); } // Make triangles. Point3D roundedB; for (int i = 2; i < points.Length; i++) { indexB = indexC; roundedB = roundedC; // Get the next point. roundedC = points[i].Round(); if (textureCoords == null) { indexC = mesh.PointIndex(points[i].Round(), pointDict); } else { indexC = mesh.PointIndex(points[i].Round(), textureCoords[i], pointDict); } // If two of the points are the same, skip this triangle. if ((roundedA != roundedB) && (roundedB != roundedC) && (roundedC != roundedA)) { mesh.TriangleIndices.Add(indexA); mesh.TriangleIndices.Add(indexB); mesh.TriangleIndices.Add(indexC); } } }
protected override void BeginTransition3D(TransitionElement transitionElement, ContentPresenter oldContent, ContentPresenter newContent, Viewport3D viewport) { Brush clone = CreateBrush(oldContent); Size size = transitionElement.RenderSize; MeshGeometry3D leftDoor = CreateMesh(new Point3D(), new Vector3D(size.Width / 2, 0, 0), new Vector3D(0, size.Height, 0), 1, 1, new Rect(0, 0, 0.5, 1)); GeometryModel3D leftDoorGeometry = new GeometryModel3D(); leftDoorGeometry.Geometry = leftDoor; leftDoorGeometry.Material = new DiffuseMaterial(clone); AxisAngleRotation3D leftRotation = new AxisAngleRotation3D(new Vector3D(0, 1, 0), 0); leftDoorGeometry.Transform = new RotateTransform3D(leftRotation); GeometryModel3D rightDoorGeometry = new GeometryModel3D(); MeshGeometry3D rightDoor = CreateMesh(new Point3D(size.Width / 2, 0, 0), new Vector3D(size.Width / 2, 0, 0), new Vector3D(0, size.Height, 0), 1, 1, new Rect(0.5, 0, 0.5, 1)); rightDoorGeometry.Geometry = rightDoor; rightDoorGeometry.Material = new DiffuseMaterial(clone); AxisAngleRotation3D rightRotation = new AxisAngleRotation3D(new Vector3D(0, 1, 0), 0); rightDoorGeometry.Transform = new RotateTransform3D(rightRotation, size.Width, 0, 0); Model3DGroup doors = new Model3DGroup(); doors.Children.Add(leftDoorGeometry); doors.Children.Add(rightDoorGeometry); ModelVisual3D model = new ModelVisual3D(); model.Content = doors; viewport.Children.Add(model); DoubleAnimation da = new DoubleAnimation(90 - 0.5 * FieldOfView, Duration); leftRotation.BeginAnimation(AxisAngleRotation3D.AngleProperty, da); da = new DoubleAnimation(-(90 - 0.5 * FieldOfView), Duration); rightRotation.BeginAnimation(AxisAngleRotation3D.AngleProperty, da); da = new DoubleAnimation(0, Duration); da.Completed += delegate { EndTransition(transitionElement, oldContent, newContent); }; clone.BeginAnimation(Brush.OpacityProperty, da); }
public static void AddPolygon(this MeshGeometry3D mesh, params Point3D[] points) { mesh.AddPolygon(points, null); }
private void CreateCone(MeshGeometry3D mesh, Point3D endPoint, Vector3D axis, double radius1, double radius2, int numSides) { // Get two vectors perpendicular to the axis. Vector3D top_v1; if ((axis.Z < -0.01) || (axis.Z > 0.01)) { top_v1 = new Vector3D(axis.Z, axis.Z, -axis.X - axis.Y); } else { top_v1 = new Vector3D(-axis.Y - axis.Z, axis.X, axis.X); } Vector3D top_v2 = Vector3D.CrossProduct(top_v1, axis); Vector3D bot_v1 = top_v1; Vector3D bot_v2 = top_v2; // Make the top vectors have length radius1. top_v1 *= (radius1 / top_v1.Length); top_v2 *= (radius1 / top_v2.Length); // Make the bottom vectors have length radius2. bot_v1 *= (radius2 / bot_v1.Length); bot_v2 *= (radius2 / bot_v2.Length); // Make the top end cap. // Make the end point. int pt0 = mesh.Positions.Count; // Index of end_point. mesh.Positions.Add(endPoint); // Make the top points. double theta = 0; double dtheta = 2 * Math.PI / numSides; for (int i = 0; i < numSides; i++) { mesh.Positions.Add(endPoint + Math.Cos(theta) * top_v1 + Math.Sin(theta) * top_v2); theta += dtheta; } // Make the top triangles. int pt1 = mesh.Positions.Count - 1; // Index of last point. int pt2 = pt0 + 1; // Index of first point in this cap. for (int i = 0; i < numSides; i++) { mesh.TriangleIndices.Add(pt0); mesh.TriangleIndices.Add(pt1); mesh.TriangleIndices.Add(pt2); pt1 = pt2++; } // Make the bottom end cap. // Make the end point. pt0 = mesh.Positions.Count; // Index of end_point2. Point3D end_point2 = endPoint + axis; mesh.Positions.Add(end_point2); // Make the bottom points. theta = 0; for (int i = 0; i < numSides; i++) { mesh.Positions.Add(end_point2 + Math.Cos(theta) * bot_v1 + Math.Sin(theta) * bot_v2); theta += dtheta; } // Make the bottom triangles. theta = 0; pt1 = mesh.Positions.Count - 1; // Index of last point. pt2 = pt0 + 1; // Index of first point in this cap. for (int i = 0; i < numSides; i++) { mesh.TriangleIndices.Add(pt0); mesh.TriangleIndices.Add(pt2); mesh.TriangleIndices.Add(pt1); pt1 = pt2++; } // Make the sides. // Add the points to the mesh. int first_side_point = mesh.Positions.Count; theta = 0; for (int i = 0; i < numSides; i++) { Point3D p1 = endPoint + Math.Cos(theta) * top_v1 + Math.Sin(theta) * top_v2; mesh.Positions.Add(p1); Point3D p2 = endPoint + axis + Math.Cos(theta) * bot_v1 + Math.Sin(theta) * bot_v2; mesh.Positions.Add(p2); theta += dtheta; } // Make the side triangles. pt1 = mesh.Positions.Count - 2; pt2 = pt1 + 1; int pt3 = first_side_point; int pt4 = pt3 + 1; for (int i = 0; i < numSides; i++) { mesh.TriangleIndices.Add(pt1); mesh.TriangleIndices.Add(pt2); mesh.TriangleIndices.Add(pt4); mesh.TriangleIndices.Add(pt1); mesh.TriangleIndices.Add(pt4); mesh.TriangleIndices.Add(pt3); pt1 = pt3; pt3 += 2; pt2 = pt4; pt4 += 2; } }
// Make a model with a diffuse brush. public static GeometryModel3D MakeModel(this MeshGeometry3D mesh, Brush brush) { Material material = new DiffuseMaterial(brush); return(new GeometryModel3D(mesh, material)); }
MeshGeometry3D GenMesh() { // 00 - 01 - 02 - 03 ... // / / // 10 - 11 - 12 // Nx * Ny Points // triangles = (Nx-1)*(Ny-1) * 2 int Nx = 20; int Ny = 5; // th = 180 ~ 0 dth = + 180/(Nx-1) double th0 = -180; double dth = (0 - 360.0) / (double)(Nx - 1); double x0 = 0.5; //double R0 = 0.5; Point3D[,] p3Dm2D = new Point3D[Nx, Ny]; for (int i = 0; i < Nx; i++) { for (int j = 0; j < Ny; j++) { // Rectangle /* double x = 1.0 / (double)(Nx - 1) * i; * double y = 1.0 / (double)(Ny - 1) * j; * double z = 0; */ // Cylinder double th = th0 + i * dth; double x = x0 + R0 * Math.Cos(th / 180 * Math.PI); double y = 1.0 / (double)(Ny - 1) * j; double z = R0 * Math.Sin(th / 180 * Math.PI); p3Dm2D[i, j] = new Point3D(x, y, z); } } Point[,] pTexture = new Point[Nx, Ny]; for (int i = 0; i < Nx; i++) { for (int j = 0; j < Ny; j++) { pTexture[i, j] = new Point(1.0 / (double)(Nx - 1) * i, 1.0 - (1.0 / (double)(Ny - 1) * j)); } } MeshGeometry3D mesh1 = new MeshGeometry3D(); Point3DCollection pts = new Point3DCollection(); for (int i = 0; i < Nx; i++) { for (int j = 0; j < Ny; j++) { pts.Add(p3Dm2D[i, j]); } } PointCollection tpts = new PointCollection(); for (int i = 0; i < Nx; i++) { for (int j = 0; j < Ny; j++) { tpts.Add(pTexture[i, j]); } } Int32Collection tri = new Int32Collection(); // (i,j) (1) i+1,j (2) // // i, j+1 (0) i+1, j+1 (3) // tri 0,1,2,2,3,1 for (int i = 0; i < Nx - 1; i++) { for (int j = 0; j < Ny - 1; j++) { tri.Add(j + Ny * i); //1 tri.Add(j + 1 + Ny * i); //0 tri.Add(j + Ny * (i + 1)); //2 tri.Add((j + 1) + Ny * (i + 1)); //3 tri.Add(j + Ny * (i + 1)); //2 tri.Add(j + 1 + Ny * i); //0 } } mesh1.Positions = pts; mesh1.TextureCoordinates = tpts; mesh1.TriangleIndices = tri; return(mesh1); }
// These methods delegate their work to pyramid and frustum methods. public static void AddCone(this MeshGeometry3D mesh, Point3D center, Point3D[] polygon, Vector3D axis, bool smoothSides = false) { mesh.AddPyramid(center, polygon, axis, true); }
private void Create3D() { //定义网格 MeshGeometry3D mesh = new MeshGeometry3D(); //设置 MeshGeometry3D 的顶点位置的集合。Positions属性指定的点表示构成三维网格的三角形的顶点。 //环绕顺序(指定构成网格每个三角形的 Position 的顺序)确定了给定面是正面还是背面。 //正面三角形以逆时针顺序环绕;背面三角形以顺时针顺序环绕。 //定义8个三维空间点 mesh.Positions.Add(new Point3D(-10, -10, 10)); mesh.Positions.Add(new Point3D(10, -10, 10)); mesh.Positions.Add(new Point3D(10, 10, 10)); mesh.Positions.Add(new Point3D(-10, 10, 10)); mesh.Positions.Add(new Point3D(-10, -10, -10)); mesh.Positions.Add(new Point3D(10, -10, -10)); mesh.Positions.Add(new Point3D(10, 10, -10)); mesh.Positions.Add(new Point3D(-10, 10, -10)); //TriangleIndices:获取或设置 MeshGeometry3D 的三角形索引的集合。(组成3D可视形状) //对于给定的三维网格而言,指定三角形的顶点位置的顺序确定了此三角形面是正面还是背面。 //Windows Presentation Foundation三维实现采用逆时针环绕顺序;也就是说,当从网格的正面看时,应以逆时针顺序指定用于确定正面网格三角形的位置的点。 //对 TriangleIndices 属性的设置为可选操作。 如果不指定索引,则以非索引的方式绘制三角形。 每个组的三个位置将成为一个三角形。 // 前面 逆时针从0号点开始,又回到0号点,组成2个三角形 mesh.TriangleIndices.Add(0); mesh.TriangleIndices.Add(1); mesh.TriangleIndices.Add(2); mesh.TriangleIndices.Add(2); mesh.TriangleIndices.Add(3); mesh.TriangleIndices.Add(0); // 背面 mesh.TriangleIndices.Add(6); mesh.TriangleIndices.Add(5); mesh.TriangleIndices.Add(4); mesh.TriangleIndices.Add(4); mesh.TriangleIndices.Add(7); mesh.TriangleIndices.Add(6); // 右面 mesh.TriangleIndices.Add(1); mesh.TriangleIndices.Add(5); mesh.TriangleIndices.Add(2); mesh.TriangleIndices.Add(5); mesh.TriangleIndices.Add(6); mesh.TriangleIndices.Add(2); // 上面 mesh.TriangleIndices.Add(2); mesh.TriangleIndices.Add(6); mesh.TriangleIndices.Add(3); mesh.TriangleIndices.Add(3); mesh.TriangleIndices.Add(6); mesh.TriangleIndices.Add(7); // 底面 mesh.TriangleIndices.Add(5); mesh.TriangleIndices.Add(1); mesh.TriangleIndices.Add(0); mesh.TriangleIndices.Add(0); mesh.TriangleIndices.Add(4); mesh.TriangleIndices.Add(5); // 左面 mesh.TriangleIndices.Add(4); mesh.TriangleIndices.Add(0); mesh.TriangleIndices.Add(3); mesh.TriangleIndices.Add(3); mesh.TriangleIndices.Add(7); mesh.TriangleIndices.Add(4); //父元素对象 World = new ModelVisual3D(); // // 创建三维几何图形 GeometryModel3D m3DGeometry = new GeometryModel3D(); m3DGeometry.Geometry = mesh; //漫射材料 m3DGeometry.Material = new DiffuseMaterial(Brushes.Red); ModelVisual3D box01 = new ModelVisual3D(); box01.Content = m3DGeometry; //环境光元素设置 ModelVisual3D ambientlight = new ModelVisual3D(); // AmbientLight abl = new AmbientLight(); abl.Color = Colors.Gray; ambientlight.Content = abl; // ModelVisual3D directionallight = new ModelVisual3D(); // DirectionalLight dl = new DirectionalLight(); dl.Color = Colors.White; dl.Direction = new Vector3D(0, 0, -1); directionallight.Content = dl; //定义三维变换 Transform3DGroup traneform3dgroup = new Transform3DGroup(); // TranslateTransform3D tlt3d = new TranslateTransform3D(); tlt3d.OffsetX = 0; tlt3d.OffsetY = 0; tlt3d.OffsetZ = 0; traneform3dgroup.Children.Add(tlt3d); //尺寸大小变换设置 ScaleTransform3D st3d = new ScaleTransform3D(); st3d.CenterX = 0; st3d.CenterY = 0; st3d.CenterZ = 0; //缩小 st3d.ScaleX = 1; st3d.ScaleY = 1; st3d.ScaleZ = 1; traneform3dgroup.Children.Add(st3d); //旋转变换设置 RotateTransform3D rtf3d = new RotateTransform3D(); rtf3d.CenterX = 0; rtf3d.CenterY = 0; rtf3d.CenterZ = 0; //设置绕指定轴进行指定角度的三维旋转 AxisAngleRotation3D aar = new AxisAngleRotation3D(); aar.Angle = angle; //旋转轴X分量、Y分量和Z分量组成的矢量 aar.Axis = new Vector3D(vX, vY, vZ); rtf3d.Rotation = aar; traneform3dgroup.Children.Add(rtf3d); World.Transform = traneform3dgroup; // //环境光线加入3D模型组合体 World.Children.Add(ambientlight); //定向光线加入3D模型组合体 World.Children.Add(directionallight); World.Children.Add(box01); // //三维变换组中的子变换数 transforms = traneform3dgroup.Children.Count; //赋予3D控件 this.viewport3d.Children.Add(World); }
public static void AddConeFrustum(this MeshGeometry3D mesh, Point3D center, Point3D[] polygon, Vector3D axis, Point3D planePt, Vector3D n, bool smoothSides = false) { mesh.AddFrustum(center, polygon, axis, planePt, n, true); }
/// Define the model. void DefineModelRobot() { Width = 450; Height = 700; // Axes. MeshExtensions.AddXAxis(_group, 15, 0.1); // red = x MeshExtensions.AddYAxis(_group, 12, 0.1); // green = y MeshExtensions.AddZAxis(_group, 15, 0.1); // blue = z MeshExtensions.AddOrigin(_group, 0.5); // black // Make the ground. const double groundY = -5; MakeGround(groundY); // Various robot dimensions. const double headR = 1.5; // Head radius. const double neckLen = headR; // Neck length. const double backLen = 3 * headR; // Back length. const double shouW = 3 * headR; // Shoulder width. const double uaLen = 2 * headR; // Upper arm length. const double laLen = 2 * headR; // Lower arm length const double hipsW = 2 * headR; // Hip width. const double ulLen = 2 * headR; // Upper leg length. const double llLen = 2 * headR; // Lower leg length. const double boneR = 0.3; // Bone radius. const double jointR = 0.4; // Joint radius. const double height = 2 * headR + neckLen + backLen + ulLen + llLen; const double headY = height - headR; // Distance from center of head to ground. Brush boneBrush = Brushes.PowderBlue; // This group represents the whole robot. _groupRobot = new Model3DGroup(); _group.Children.Add(_groupRobot); _groupRobot.Transform = new TranslateTransform3D(0, headY + groundY, 0); // Head. // Skull. MeshGeometry3D skullMesh = new MeshGeometry3D(); skullMesh.AddSphere(D3.Origin, headR, 20, 10, true); GeometryModel3D skullModel = skullMesh.MakeModel(boneBrush); // Nose. MeshGeometry3D noseMesh = new MeshGeometry3D(); Point3D noseCenter = new Point3D(0, 0, headR); Point3D[] nosePoints = G3.MakePolygonPoints(10, noseCenter, D3.XVector(headR * 0.2), D3.YVector(headR * 0.2)); Vector3D noseAxis = new Vector3D(0, 0, headR); noseMesh.AddConeFrustum(noseCenter, nosePoints, noseAxis, headR * 0.5); GeometryModel3D noseModel = noseMesh.MakeModel(Brushes.Orange); // Eyes and smile. MeshGeometry3D eyeMesh = new MeshGeometry3D(); Point3D eyeCenter = SphericalToCartesian(headR, -Math.PI * 0.2, Math.PI * 0.4); eyeMesh.AddSphere(eyeCenter, headR * 0.2, 10, 5, false); eyeCenter = SphericalToCartesian(headR, Math.PI * 0.2, Math.PI * 0.4); eyeMesh.AddSphere(eyeCenter, headR * 0.2, 10, 5, false); eyeCenter = SphericalToCartesian(headR, Math.PI * 0, Math.PI * 0.7); eyeMesh.AddSphere(eyeCenter, headR * 0.1, 10, 5, false); eyeCenter = SphericalToCartesian(headR, Math.PI * 0.1, Math.PI * 0.67); eyeMesh.AddSphere(eyeCenter, headR * 0.1, 10, 5, false); eyeCenter = SphericalToCartesian(headR, -Math.PI * 0.1, Math.PI * 0.67); eyeMesh.AddSphere(eyeCenter, headR * 0.1, 10, 5, false); eyeCenter = SphericalToCartesian(headR, Math.PI * 0.15, Math.PI * 0.6); eyeMesh.AddSphere(eyeCenter, headR * 0.1, 10, 5, false); eyeCenter = SphericalToCartesian(headR, -Math.PI * 0.15, Math.PI * 0.6); eyeMesh.AddSphere(eyeCenter, headR * 0.1, 10, 5, false); GeometryModel3D eyeModel = eyeMesh.MakeModel(Brushes.Black); // Hat. MeshGeometry3D hatMesh = new MeshGeometry3D(); Point3D hatCenter = new Point3D(0, headR * 0.75, 0); hatMesh.AddSphere(hatCenter, headR * 0.75, 20, 10, true); const double hatR = headR * 1.2; Point3D[] hatPgon = G3.MakePolygonPoints(20, hatCenter, D3.XVector(hatR), D3.ZVector(hatR)); hatMesh.AddCylinder(hatPgon, D3.YVector(-0.2), true); GeometryModel3D hatModel = hatMesh.MakeModel(Brushes.SaddleBrown); // Head groups. _groupHead = JoinBones(_groupRobot, null); _groupHead.Children.Add(skullModel); _groupHead.Children.Add(noseModel); _groupHead.Children.Add(eyeModel); _groupHead.Children.Add(hatModel); // Neck. MeshGeometry3D neckMesh = new MeshGeometry3D(); Point3D[] neckPgon = G3.MakePolygonPoints(10, D3.Origin, D3.XVector(boneR), D3.ZVector(boneR)); neckMesh.AddCylinder(neckPgon, D3.YVector(-neckLen), true); GeometryModel3D neckModel = neckMesh.MakeModel(boneBrush); _groupNeck = JoinBones(_groupHead, new TranslateTransform3D(0, -headR, 0)); _groupNeck.Children.Add(neckModel); // Shoulders. MeshGeometry3D shoulderMesh = new MeshGeometry3D(); Point3D[] shouldersPgon = G3.MakePolygonPoints(10, new Point3D(-shouW / 2, 0, 0), D3.ZVector(boneR), D3.YVector(-boneR)); shoulderMesh.AddCylinder(shouldersPgon, D3.XVector(shouW), true); GeometryModel3D shoulderModel = shoulderMesh.MakeModel(boneBrush); _groupShoulder = JoinBones(_groupNeck, new TranslateTransform3D(0, -neckLen, 0)); _groupShoulder.Children.Add(shoulderModel); // Left upper arm. MeshGeometry3D luArmMesh = new MeshGeometry3D(); luArmMesh.AddCylinder(neckPgon, D3.YVector(-uaLen), true); luArmMesh.AddSphere(D3.Origin, jointR, 10, 5, true); GeometryModel3D luArmModel = luArmMesh.MakeModel(boneBrush); _groupLeftUpperArm = JoinBones(_groupShoulder, new TranslateTransform3D(shouW / 2, 0, 0)); _groupLeftUpperArm.Children.Add(luArmModel); // Right upper arm. MeshGeometry3D ruArmMesh = new MeshGeometry3D(); ruArmMesh.AddCylinder(neckPgon, D3.YVector(-uaLen), true); ruArmMesh.AddSphere(D3.Origin, jointR, 10, 5, true); GeometryModel3D ruArmModel = ruArmMesh.MakeModel(boneBrush); _groupRightUpperArm = JoinBones(_groupShoulder, new TranslateTransform3D(-shouW / 2, 0, 0)); _groupRightUpperArm.Children.Add(ruArmModel); // Left lower arm. MeshGeometry3D llArmMesh = new MeshGeometry3D(); llArmMesh.AddCylinder(neckPgon, D3.YVector(-laLen), true); llArmMesh.AddSphere(D3.Origin, jointR, 10, 5, true); GeometryModel3D llArmModel = llArmMesh.MakeModel(boneBrush); _groupLeftLowerArm = JoinBones(_groupLeftUpperArm, new TranslateTransform3D(0, -uaLen, 0)); _groupLeftLowerArm.Children.Add(llArmModel); // Right lower arm. MeshGeometry3D rlArmMesh = new MeshGeometry3D(); rlArmMesh.AddCylinder(neckPgon, D3.YVector(-laLen), true); rlArmMesh.AddSphere(D3.Origin, jointR, 10, 5, true); GeometryModel3D rlArmModel = rlArmMesh.MakeModel(boneBrush); _groupRightLowerArm = JoinBones(_groupRightUpperArm, new TranslateTransform3D(0, -uaLen, 0)); _groupRightLowerArm.Children.Add(rlArmModel); // Back and hips. MeshGeometry3D backMesh = new MeshGeometry3D(); backMesh.AddCylinder(neckPgon, D3.YVector(-backLen), true); GeometryModel3D backModel = backMesh.MakeModel(boneBrush); MeshGeometry3D hipsMesh = new MeshGeometry3D(); Point3D[] hipsPgon = G3.MakePolygonPoints(10, new Point3D(-hipsW / 2, -backLen, 0), D3.ZVector(boneR), D3.YVector(-boneR)); hipsMesh.AddCylinder(hipsPgon, D3.XVector(hipsW), true); GeometryModel3D hipsModel = hipsMesh.MakeModel(boneBrush); _groupBack = JoinBones(_groupNeck, new TranslateTransform3D(0, -neckLen, 0)); _groupBack.Children.Add(backModel); _groupBack.Children.Add(hipsModel); // Left upper leg. MeshGeometry3D luLegMesh = new MeshGeometry3D(); luLegMesh.AddCylinder(neckPgon, D3.YVector(-ulLen), true); luLegMesh.AddSphere(D3.Origin, jointR, 10, 5, true); GeometryModel3D luLegModel = luLegMesh.MakeModel(boneBrush); _groupLeftUpperLeg = JoinBones(_groupBack, new TranslateTransform3D(-hipsW / 2, -backLen, 0)); _groupLeftUpperLeg.Children.Add(luLegModel); // Right upper leg. MeshGeometry3D ruLegMesh = new MeshGeometry3D(); ruLegMesh.AddCylinder(neckPgon, D3.YVector(-ulLen), true); ruLegMesh.AddSphere(D3.Origin, jointR, 10, 5, true); GeometryModel3D ruLegModel = ruLegMesh.MakeModel(boneBrush); _groupRightUpperLeg = JoinBones(_groupBack, new TranslateTransform3D(hipsW / 2, -backLen, 0)); _groupRightUpperLeg.Children.Add(ruLegModel); // Left lower leg. MeshGeometry3D llLegMesh = new MeshGeometry3D(); llLegMesh.AddCylinder(neckPgon, D3.YVector(-llLen), true); llLegMesh.AddSphere(D3.Origin, jointR, 10, 5, true); GeometryModel3D llLegModel = llLegMesh.MakeModel(boneBrush); _groupLeftLowerLeg = JoinBones(_groupLeftUpperLeg, new TranslateTransform3D(0, -ulLen, 0)); _groupLeftLowerLeg.Children.Add(llLegModel); // Right lower leg. MeshGeometry3D rlLegMesh = new MeshGeometry3D(); rlLegMesh.AddCylinder(neckPgon, D3.YVector(-llLen), true); rlLegMesh.AddSphere(D3.Origin, jointR, 10, 5, true); GeometryModel3D rlLegModel = rlLegMesh.MakeModel(boneBrush); _groupRightLowerLeg = JoinBones(_groupRightUpperLeg, new TranslateTransform3D(0, -ulLen, 0)); _groupRightLowerLeg.Children.Add(rlLegModel); }
// Add a textured torus. public static void AddTexturedTorus(this MeshGeometry3D mesh, Point3D center, double R, double r, int numTheta, int numPhi, bool smooth = false) { double dtheta = 2 * Math.PI / numTheta; double dphi = 2 * Math.PI / numPhi; double theta = Math.PI; // Puts the texture's top/bottom on the inside. for (int t = 0; t < numTheta; t++) { double phi = 0; for (int p = 0; p < numPhi; p++) { // Find this piece's points. Point3D point1 = G3.TorusPoint(center, R, r, theta, phi).Round(); Point3D point2 = G3.TorusPoint(center, R, r, theta + dtheta, phi).Round(); Point3D point3 = G3.TorusPoint(center, R, r, theta + dtheta, phi + dphi).Round(); Point3D point4 = G3.TorusPoint(center, R, r, theta, phi + dphi).Round(); // Find this piece's normals. Vector3D normal1 = G3.TorusNormal(D3.Origin, R, r, theta, phi); Vector3D normal2 = G3.TorusNormal(D3.Origin, R, r, theta + dtheta, phi); Vector3D normal3 = G3.TorusNormal(D3.Origin, R, r, theta + dtheta, phi + dphi); Vector3D normal4 = G3.TorusNormal(D3.Origin, R, r, theta, phi + dphi); // Find this piece's texture coordinates. Point coords1 = new Point(1 - (double)p / numPhi, 1 - (double)t / numTheta); Point coords2 = new Point(1 - (double)p / numPhi, 1 - (double)(t + 1) / numTheta); Point coords3 = new Point(1 - (double)(p + 1) / numPhi, 1 - (double)(t + 1) / numTheta); Point coords4 = new Point(1 - (double)(p + 1) / numPhi, 1 - (double)t / numTheta); // Make the first triangle. int index = mesh.Positions.Count; mesh.Positions.Add(point1); if (smooth) { mesh.Normals.Add(normal1); } mesh.TextureCoordinates.Add(coords1); mesh.Positions.Add(point2); if (smooth) { mesh.Normals.Add(normal2); } mesh.TextureCoordinates.Add(coords2); mesh.Positions.Add(point3); if (smooth) { mesh.Normals.Add(normal3); } mesh.TextureCoordinates.Add(coords3); mesh.TriangleIndices.Add(index++); mesh.TriangleIndices.Add(index++); mesh.TriangleIndices.Add(index++); // Make the second triangle. mesh.Positions.Add(point1); if (smooth) { mesh.Normals.Add(normal1); } mesh.TextureCoordinates.Add(coords1); mesh.Positions.Add(point3); if (smooth) { mesh.Normals.Add(normal3); } mesh.TextureCoordinates.Add(coords3); mesh.Positions.Add(point4); if (smooth) { mesh.Normals.Add(normal4); } mesh.TextureCoordinates.Add(coords4); mesh.TriangleIndices.Add(index++); mesh.TriangleIndices.Add(index++); mesh.TriangleIndices.Add(index++); phi += dphi; } theta += dtheta; } // Add texture coordinates 1.01 to prevent "seams." mesh.Positions.Add(new Point3D()); mesh.TextureCoordinates.Add(new Point(1.01, 1.01)); }
/// Define the model. void DefineModelGarden() { Width = 700; Height = 700; // Rock sections. MeshGeometry3D rockMesh = new MeshGeometry3D(); AddRectangle(rockMesh, new Point3D(-3, 0, -1), new Point3D(-3, 0, +1), new Point3D(-1, 0, +1), new Point3D(-1, 0, -1)); AddRectangle(rockMesh, new Point3D(+1, 0, -1), new Point3D(+1, 0, +1), new Point3D(+3, 0, +1), new Point3D(+3, 0, -1)); AddRectangle(rockMesh, new Point3D(-1, 0, +1), new Point3D(-1, 0, +3), new Point3D(+1, 0, +3), new Point3D(+1, 0, +1)); ImageBrush rockBrush = new ImageBrush(); rockBrush.ImageSource = new BitmapImage(new Uri(System.IO.Path.Combine(_resDir, @"rocks.jpg"), UriKind.Relative)); Material rockMaterial = new DiffuseMaterial(rockBrush); GeometryModel3D rockModel = new GeometryModel3D(rockMesh, rockMaterial); _group.Children.Add(rockModel); // Grass sections. MeshGeometry3D grassMesh = new MeshGeometry3D(); AddRectangle(grassMesh, new Point3D(-3, 0, -3), new Point3D(-3, 0, -1), new Point3D(-1, 0, -1), new Point3D(-1, 0, -3)); AddRectangle(grassMesh, new Point3D(-3, 0, +1), new Point3D(-3, 0, +3), new Point3D(-1, 0, +3), new Point3D(-1, 0, +1)); AddRectangle(grassMesh, new Point3D(+1, 0, -3), new Point3D(+1, 0, -1), new Point3D(+3, 0, -1), new Point3D(+3, 0, -3)); AddRectangle(grassMesh, new Point3D(+1, 0, +1), new Point3D(+1, 0, +3), new Point3D(+3, 0, +3), new Point3D(+3, 0, +1)); ImageBrush grassBrush = new ImageBrush(); grassBrush.ImageSource = new BitmapImage(new Uri(System.IO.Path.Combine(_resDir, @"grass.jpg"), UriKind.Relative)); Material grassMaterial = new DiffuseMaterial(grassBrush); GeometryModel3D grassModel = new GeometryModel3D(grassMesh, grassMaterial); _group.Children.Add(grassModel); // Water. MeshGeometry3D waterMesh = new MeshGeometry3D(); AddRectangle(waterMesh, new Point3D(-1, 0, -1), new Point3D(-1, 0, +1), new Point3D(+1, 0, +1), new Point3D(+1, 0, -1)); ImageBrush waterBrush = new ImageBrush(); waterBrush.ImageSource = new BitmapImage(new Uri(System.IO.Path.Combine(_resDir, @"water.jpg"), UriKind.Relative)); Material waterMaterial = new DiffuseMaterial(waterBrush); GeometryModel3D waterModel = new GeometryModel3D(waterMesh, waterMaterial); _group.Children.Add(waterModel); // Cube brick face. MeshGeometry3D brickMesh = new MeshGeometry3D(); AddRectangle(brickMesh, new Point3D(-1, 2, -1), new Point3D(-1, 0, -1), new Point3D(+1, 0, -1), new Point3D(+1, 2, -1)); ImageBrush brickBrush = new ImageBrush(); brickBrush.ImageSource = new BitmapImage(new Uri(System.IO.Path.Combine(_resDir, @"bricks.jpg"), UriKind.Relative)); Material brickMaterial = new DiffuseMaterial(brickBrush); GeometryModel3D brickModel = new GeometryModel3D(brickMesh, brickMaterial); _group.Children.Add(brickModel); // Cube metal face. MeshGeometry3D metalMesh = new MeshGeometry3D(); AddRectangle(metalMesh, new Point3D(+1, 2, -1), new Point3D(+1, 0, -1), new Point3D(+1, 0, -3), new Point3D(+1, 2, -3)); ImageBrush metalBrush = new ImageBrush(); metalBrush.ImageSource = new BitmapImage(new Uri(System.IO.Path.Combine(_resDir, @"metal.jpg"), UriKind.Relative)); Material metalMaterial = new DiffuseMaterial(metalBrush); GeometryModel3D metalModel = new GeometryModel3D(metalMesh, metalMaterial); _group.Children.Add(metalModel); // Cube wood face. MeshGeometry3D woodMesh = new MeshGeometry3D(); AddRectangle(woodMesh, new Point3D(-1, 2, -3), new Point3D(-1, 2, -1), new Point3D(+1, 2, -1), new Point3D(+1, 2, -3)); ImageBrush woodBrush = new ImageBrush(); woodBrush.ImageSource = new BitmapImage(new Uri(System.IO.Path.Combine(_resDir, @"wood.jpg"), UriKind.Relative)); Material woodMaterial = new DiffuseMaterial(woodBrush); GeometryModel3D woodModel = new GeometryModel3D(woodMesh, woodMaterial); _group.Children.Add(woodModel); // Cube fire face. MeshGeometry3D fireMesh = new MeshGeometry3D(); AddRectangle(fireMesh, new Point3D(-1, 2, -3), new Point3D(-1, 0, -3), new Point3D(-1, 0, -1), new Point3D(-1, 2, -1)); ImageBrush fireBrush = new ImageBrush(); fireBrush.ImageSource = new BitmapImage(new Uri(System.IO.Path.Combine(_resDir, @"fire.jpg"), UriKind.Relative)); Material fireMaterial = new DiffuseMaterial(fireBrush); GeometryModel3D fireModel = new GeometryModel3D(fireMesh, fireMaterial); _group.Children.Add(fireModel); // Cube cloth face. MeshGeometry3D clothMesh = new MeshGeometry3D(); AddRectangle(clothMesh, new Point3D(+1, 2, -3), new Point3D(+1, 0, -3), new Point3D(-1, 0, -3), new Point3D(-1, 2, -3)); ImageBrush clothBrush = new ImageBrush(); clothBrush.ImageSource = new BitmapImage(new Uri(System.IO.Path.Combine(_resDir, @"cloth.jpg"), UriKind.Relative)); Material clothMaterial = new DiffuseMaterial(clothBrush); GeometryModel3D clothModel = new GeometryModel3D(clothMesh, clothMaterial); _group.Children.Add(clothModel); // Skybox meshes. MeshGeometry3D sky1Mesh = new MeshGeometry3D(); AddRectangle(sky1Mesh, new Point3D(-6, +7, +6), new Point3D(-6, -5, +6), new Point3D(-6, -5, -6), new Point3D(-6, +7, -6)); ImageBrush sky1Brush = new ImageBrush(); sky1Brush.ImageSource = new BitmapImage(new Uri(System.IO.Path.Combine(_resDir, @"clouds.jpg"), UriKind.Relative)); MaterialGroup sky1Group = new MaterialGroup(); sky1Group.Children.Add(new DiffuseMaterial(sky1Brush)); sky1Group.Children.Add(new EmissiveMaterial(new SolidColorBrush( Color.FromArgb(255, 128, 128, 128)))); GeometryModel3D sky1Model = new GeometryModel3D(sky1Mesh, sky1Group); _group.Children.Add(sky1Model); MeshGeometry3D sky2Mesh = new MeshGeometry3D(); AddRectangle(sky2Mesh, new Point3D(-6, +7, -6), new Point3D(-6, -5, -6), new Point3D(+6, -5, -6), new Point3D(+6, +7, -6)); ImageBrush sky2Brush = new ImageBrush(); sky2Brush.ImageSource = new BitmapImage(new Uri(System.IO.Path.Combine(_resDir, @"clouds.jpg"), UriKind.Relative)); MaterialGroup sky2Group = new MaterialGroup(); sky2Group.Children.Add(new DiffuseMaterial(sky2Brush)); sky2Group.Children.Add(new EmissiveMaterial(new SolidColorBrush( Color.FromArgb(255, 64, 64, 64)))); GeometryModel3D sky2Model = new GeometryModel3D(sky2Mesh, sky2Group); _group.Children.Add(sky2Model); MeshGeometry3D sky3Mesh = new MeshGeometry3D(); AddRectangle(sky3Mesh, new Point3D(-6, -5, +6), new Point3D(+6, -5, +6), new Point3D(+6, -5, -6), new Point3D(-6, -5, -6)); ImageBrush sky3Brush = new ImageBrush(); sky3Brush.ImageSource = new BitmapImage(new Uri(System.IO.Path.Combine(_resDir, @"clouds.jpg"), UriKind.Relative)); Material sky3Material = new DiffuseMaterial(sky3Brush); GeometryModel3D sky3Model = new GeometryModel3D(sky3Mesh, sky3Material); _group.Children.Add(sky3Model); }
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); }
void Window_Loaded(object sender, RoutedEventArgs e) { ThreeDeeType which = ThreeDeeType.Robot; _resDir = System.IO.Path.Combine(Utils.GetSourcePath(), "Resources"); // Define WPF objects. ModelVisual3D visual3d = new ModelVisual3D(); _group = new Model3DGroup(); visual3d.Content = _group; mainViewport.Children.Add(visual3d); // Define the camera. _camera = new PerspectiveCamera { FieldOfView = 60 }; _cameraController = new SphericalCameraController(_camera, mainViewport, this, mainGrid, mainGrid); // Define the lights. Color darker = Color.FromArgb(255, 96, 96, 96); Color dark = Color.FromArgb(255, 128, 128, 128); _group.Children.Add(new AmbientLight(darker)); _group.Children.Add(new DirectionalLight(dark, new Vector3D(0, -1, 0))); _group.Children.Add(new DirectionalLight(dark, new Vector3D(1, -3, -2))); _group.Children.Add(new DirectionalLight(dark, new Vector3D(-1, 3, 2))); ///// Define the model. if (which == ThreeDeeType.Robot) { // Move back a bit from the origin. Point3D coords = _cameraController.SphericalCoordinates; coords.X = 20; //coords.Y = 20; _cameraController.SphericalCoordinates = coords; DefineModelRobot(); // Some animation. red = x green = y blue = z // Mesh defines the surface. MeshGeometry3D animMesh = new MeshGeometry3D(); Point3D pt = D3.Origin; //////// box int size = 2; animMesh.AddBox(pt, new Vector3D(size, 0, 0), new Vector3D(0, size, 0), new Vector3D(0, 0, size)); //////// sphere //double radius = 2; //animMesh.AddSphere(pt, radius, 30, 10, true); //pt.Z += 2.5; //pt.X += 1; //animMesh.AddSphere(pt, radius, 30, 10, true); //////////// Common var dur = new Duration(TimeSpan.FromMilliseconds(5000)); // Model is the thing that is manipulated. GeometryModel3D animModel = animMesh.MakeModel(Brushes.Violet); _group.Children.Add(animModel); var transGroup = new Transform3DGroup(); animModel.Transform = transGroup; //////////// stretch ScaleTransform3D myScaleTransform3D = new ScaleTransform3D(); myScaleTransform3D.ScaleX = 2; myScaleTransform3D.ScaleY = 0.5; myScaleTransform3D.ScaleZ = 1; // Add the scale transform to the Transform3DGroup. //myTransform3DGroup.Children.Add(myScaleTransform3D); transGroup.Children.Add(myScaleTransform3D); //////////// Move var anim = new DoubleAnimation(0.0, 3, dur) { BeginTime = TimeSpan.FromSeconds(0), RepeatBehavior = RepeatBehavior.Forever }; var offsetTransform = new TranslateTransform3D(); //offsetTransform.BeginAnimation(TranslateTransform3D.OffsetXProperty, anim); //offsetTransform.BeginAnimation(TranslateTransform3D.OffsetYProperty, anim); offsetTransform.BeginAnimation(TranslateTransform3D.OffsetZProperty, anim); transGroup.Children.Add(offsetTransform); ///////// rotation var startAxis = new Vector3D(1, 0, 0);// (0, 1, 0); var rot = new AxisAngleRotation3D(startAxis, 180); var myRotateTransform = new RotateTransform3D(rot); // end, duration var rotateTo = new Vector3D(-1, -1, -1); var myVectorAnimation = new Vector3DAnimation(rotateTo, dur) { RepeatBehavior = RepeatBehavior.Forever }; myRotateTransform.Rotation.BeginAnimation(AxisAngleRotation3D.AxisProperty, myVectorAnimation); transGroup.Children.Add(myRotateTransform); } else if (which == ThreeDeeType.Garden) { DefineModelGarden(); } }
/// <summary> /// The export mesh. /// </summary> /// <param name="m"> /// The m. /// </param> /// <param name="t"> /// The t. /// </param> public void ExportMesh(MeshGeometry3D m, Transform3D t) { if (m == null) { throw new ArgumentNullException("m"); } if (t == null) { throw new ArgumentNullException("t"); } // mapping from local indices (0-based) to the obj file indices (1-based) var vertexIndexMap = new Dictionary<int, int>(); var textureIndexMap = new Dictionary<int, int>(); var normalIndexMap = new Dictionary<int, int>(); int index = 0; if (m.Positions != null) { foreach (var v in m.Positions) { vertexIndexMap.Add(index++, this.vertexIndex++); var p = t.Transform(v.ToPoint3D()); this.writer.WriteLine( string.Format( CultureInfo.InvariantCulture, "v {0} {1} {2}", p.X, this.SwitchYZ ? p.Z : p.Y, this.SwitchYZ ? -p.Y : p.Z)); } this.writer.WriteLine(string.Format("# {0} vertices", index)); } if (m.TextureCoordinates != null) { index = 0; foreach (var vt in m.TextureCoordinates) { textureIndexMap.Add(index++, this.textureIndex++); this.writer.WriteLine(string.Format(CultureInfo.InvariantCulture, "vt {0} {1}", vt.X, 1 - vt.Y)); } this.writer.WriteLine(string.Format("# {0} texture coordinates", index)); } if (m.Normals != null && ExportNormals) { index = 0; foreach (var vn in m.Normals) { normalIndexMap.Add(index++, this.normalIndex++); this.writer.WriteLine( string.Format(CultureInfo.InvariantCulture, "vn {0} {1} {2}", vn.X, vn.Y, vn.Z)); } this.writer.WriteLine(string.Format("# {0} normals", index)); } Func<int, string> formatIndices = i0 => { bool hasTextureIndex = textureIndexMap.ContainsKey(i0); bool hasNormalIndex = normalIndexMap.ContainsKey(i0); if (hasTextureIndex && hasNormalIndex) { return string.Format("{0}/{1}/{2}", vertexIndexMap[i0], textureIndexMap[i0], normalIndexMap[i0]); } if (hasTextureIndex) { return string.Format("{0}/{1}", vertexIndexMap[i0], textureIndexMap[i0]); } if (hasNormalIndex) { return string.Format("{0}//{1}", vertexIndexMap[i0], normalIndexMap[i0]); } return vertexIndexMap[i0].ToString(); }; if (m.Indices != null) { for (int i = 0; i < m.Indices.Count; i += 3) { int i0 = m.Indices[i]; int i1 = m.Indices[i + 1]; int i2 = m.Indices[i + 2]; this.writer.WriteLine("f {0} {1} {2}", formatIndices(i0), formatIndices(i1), formatIndices(i2)); } this.writer.WriteLine(string.Format("# {0} faces", m.Indices.Count / 3)); } this.writer.WriteLine(); }
/// <summary> /// Initializes a new instance of the <see cref="ContourHelperDX" /> class. /// </summary> /// <param name="planeOrigin">The plane origin.</param> /// <param name="planeNormal">The plane normal.</param> /// <param name="originalMesh">The original mesh.</param> public ContourHelperDX(Media3D.Point3D planeOrigin, Vector3 planeNormal, MeshGeometry3D originalMesh) { var hasNormals = originalMesh.Normals != null && originalMesh.Normals.Count > 0; var hasTextureCoordinates = originalMesh.TextureCoordinates != null && originalMesh.TextureCoordinates.Count > 0; this.normals = hasNormals ? new Vector3[3] : null; this.textures = hasTextureCoordinates ? new Vector2[3] : null; this.positionCount = originalMesh.Positions.Count; this.meshPositions = originalMesh.Positions.ToArray(); this.meshNormals = hasNormals ? originalMesh.Normals.ToArray() : null; this.meshTextureCoordinates = hasTextureCoordinates ? originalMesh.TextureCoordinates.ToArray() : null; // Determine the equation of the plane as // ax + by + cz + d = 0 var l = (float)Math.Sqrt((planeNormal.X * planeNormal.X) + (planeNormal.Y * planeNormal.Y) + (planeNormal.Z * planeNormal.Z)); this.a = planeNormal.X / l; this.b = planeNormal.Y / l; this.c = planeNormal.Z / l; this.d = -(float)((planeNormal.X * planeOrigin.X) + (planeNormal.Y * planeOrigin.Y) + (planeNormal.Z * planeOrigin.Z)); }