private void MakeObjects(out MeshGeometry3D cameraMesh, out MeshGeometry3D boxMesh, out MeshGeometry3D edgeMesh, out Point3D cameraCenter) { // Make a "camera." cameraMesh = new MeshGeometry3D(); cameraMesh.AddBox(new Point3D(-0.6, -0.5, -0.2), D3.XVector(1.2), D3.YVector(1), D3.ZVector(0.4)); Point3D[] points = G3.MakePolygonPoints(20, new Point3D(0, 0, -0.7), D3.XVector(0.3), D3.YVector(0.3)); cameraMesh.AddCylinder(points, D3.ZVector(0.7), true); points = G3.MakePolygonPoints(20, new Point3D(0, 0, -0.8), D3.XVector(0.4), D3.YVector(0.4)); cameraMesh.AddCylinder(points, D3.ZVector(0.2), true); cameraMesh.AddBox(new Point3D(0.3, 0.5, -0.1), D3.XVector(0.2), D3.YVector(0.2), D3.ZVector(0.2)); MainGroup.Children.Add(cameraMesh.MakeModel(Brushes.LightBlue)); // Transform the camera and vector. Transform3DGroup trans = new Transform3DGroup(); RotateTransform3D r1 = D3.Rotate(D3.XVector(), D3.Origin, -45); trans.Children.Add(r1); RotateTransform3D r2 = D3.Rotate(D3.YVector(), D3.Origin, -45); trans.Children.Add(r2); // See where we need to translate to make the camera point at the origin. Point3D lookAtPoint = new Point3D(0, 0, -3.5); lookAtPoint = trans.Transform(lookAtPoint); TranslateTransform3D t1 = new TranslateTransform3D( -lookAtPoint.X, -lookAtPoint.Y, -lookAtPoint.Z); trans.Children.Add(t1); cameraMesh.ApplyTransformation(trans); cameraCenter = trans.Transform(D3.Origin); // Make a target box. boxMesh = new MeshGeometry3D(); boxMesh.AddBox(new Point3D(-0.75, -0.75, -0.75), D3.XVector(1.5), D3.YVector(1.5), D3.ZVector(1.5)); MainGroup.Children.Add(boxMesh.MakeModel(Brushes.LightGreen)); // Make the box's edges. edgeMesh = new MeshGeometry3D(); HashSet <Edge> edges = new HashSet <Edge>(); edgeMesh.AddBox(new Point3D(-0.75, -0.75, -0.75), D3.XVector(1.5), D3.YVector(1.5), D3.ZVector(1.5), edges: edges); MainGroup.Children.Add(edgeMesh.MakeModel(Brushes.Black)); }
public static void AddAxes(this MeshGeometry3D mesh, double xmax, double thickness, bool start_at_origin, bool show_tick_marks, double tick_thickness, double tick_width) { double xmin, ymin, zmin; if (start_at_origin) { xmin = 0; ymin = 0; zmin = 0; } else { xmin = -xmax; ymin = -xmax; zmin = -xmax; } mesh.AddSegment(xmin, 0, 0, xmax, 0, 0, thickness); mesh.AddSegment(0, ymin, 0, 0, xmax, 0, thickness); mesh.AddSegment(0, 0, zmin, 0, 0, xmax, thickness); if (show_tick_marks) { Vector3D ux = new Vector3D(thickness, 0, 0); Vector3D uy = new Vector3D(0, thickness, 0); Vector3D uz = new Vector3D(0, 0, thickness); for (int x = (int)xmin; x <= (int)xmax; x++) { Point3D corner = new Point3D( x - tick_thickness * 0.5 * thickness, -tick_width * 0.5 * thickness, -tick_width * 0.5 * thickness); mesh.AddBox(corner, tick_thickness * ux, tick_width * uy, tick_width * uz); } for (int y = (int)ymin; y <= (int)xmax; y++) { Point3D corner = new Point3D( -tick_width * 0.5 * thickness, y - tick_thickness * 0.5 * thickness, -tick_width * 0.5 * thickness); mesh.AddBox(corner, tick_width * ux, tick_thickness * uy, tick_width * uz); } for (int z = (int)zmin; z <= (int)xmax; z++) { Point3D corner = new Point3D( -tick_width * 0.5 * thickness, -tick_width * 0.5 * thickness, z - tick_thickness * 0.5 * thickness); mesh.AddBox(corner, tick_width * ux, tick_width * uy, tick_thickness * uz); } } }
// Make rows of bars in the X and Z directions. private void MakeRowColumnBars(double xmin, double ymin, double zmin, double dx, double gap, double[,] values, string[] frontLabels, string[] sideLabels, Brush[,] barBrushes, Brush[] bgBrushes, Brush[] fgBrushes, FontFamily ff, Model3DGroup group) { int numX = values.GetUpperBound(0) + 1; int numZ = values.GetUpperBound(1) + 1; double x = xmin; double z; double fontSize = 0.3; for (int ix = 0; ix < numX; ix++) { z = zmin; for (int iz = 0; iz < numZ; iz++) { // Make the bar. MeshGeometry3D barMesh = new MeshGeometry3D(); Point3D corner = new Point3D(x, ymin, z); barMesh.AddBox(corner, D3.XVector(dx), D3.YVector(YScale * values[ix, iz]), D3.ZVector(dx)); group.Children.Add(barMesh.MakeModel(barBrushes[ix, iz])); z += dx + gap; } // Display the front label. const double textWid = 2; MakeLabel(frontLabels[ix], new Point3D(x + dx, ymin, z + textWid), D3.ZVector(-textWid), D3.XVector(-dx), bgBrushes[ix], fgBrushes[ix], fontSize, ff, HorizontalAlignment.Left, VerticalAlignment.Center, group); x += dx + gap; } // Display the side labels. z = zmin + dx; double xmax = xmin + numX * dx + (numX - 1) * gap; for (int iz = 0; iz < numZ; iz++) { const double textWid = 2; MakeLabel(sideLabels[iz], new Point3D(xmax + gap, ymin, z), D3.XVector(textWid), D3.ZVector(-dx), Brushes.Transparent, Brushes.Black, fontSize, ff, HorizontalAlignment.Left, VerticalAlignment.Center, group); //MakeLabel(sideLabels[iz], // new Point3D(xmin - textWid - gap, ymin, z), // D3.XVector(textWid), D3.ZVector(-dx), // Brushes.Transparent, Brushes.Black, fontSize, ff, // HorizontalAlignment.Left, VerticalAlignment.Center, group); z += dx + gap; } }
// Define the model. private void DefineModel(Model3DGroup group) { // Show the axes. MeshExtensions.AddAxes(group); MeshGeometry3D mesh1 = new MeshGeometry3D(); double dx = 3 / Math.Sqrt(3); mesh1.AddBox(new Point3D(-dx, -dx, -dx), D3.XVector(2 * dx), D3.YVector(2 * dx), D3.ZVector(2 * dx)); group.Children.Add(mesh1.MakeModel(new SolidColorBrush(Colors.LightBlue))); const int numTheta = 60; const int numPhi = 30; MeshGeometry3D mesh2 = new MeshGeometry3D(); Point3D center = new Point3D(0, 0, 0); mesh2.AddSphere(center, 3, numTheta, numPhi, true); MaterialGroup material = new MaterialGroup(); Color color = Color.FromArgb(64, 128, 128, 128); material.Children.Add(new DiffuseMaterial(new SolidColorBrush(color))); material.Children.Add(new SpecularMaterial(Brushes.White, 100)); group.Children.Add(mesh2.MakeModel(material)); }
public static void AddSegment(this MeshGeometry3D mesh, Point3D point1, Point3D point2, Vector3D up, double thickness, bool extend) { // Get the segment's vector. Vector3D v = point2 - point1; if (extend) { // Increase the segment's length on both ends by thickness / 2. Vector3D n = v.Scale(thickness / 2.0); point1 -= n; point2 += n; v += 2 * n; } // Get the scaled up vector. Vector3D n1 = up.Scale(thickness / 2.0); // Get another scaled perpendicular vector. Vector3D n2 = Vector3D.CrossProduct(v, n1); n2 = n2.Scale(thickness / 2.0); // Make a skinny box. mesh.AddBox(point1 - n1 - n2, v, 2 * n1, 2 * n2); }
// Make cube popcorn. private void MakeBoxPopcorn(MeshGeometry3D mesh, int depth, Point3D center, List <Vector3D> directions, double r, double g, double b, double colorFactor, double radius, double radiusFactor) { // Add a cube to the mesh. Point3D corner = center + new Vector3D(-radius, -radius, -radius); mesh.AddBox(corner, D3.XVector(2 * radius), D3.YVector(2 * radius), D3.ZVector(2 * radius)); NumBoxes++; // See if we're done. if (--depth < 0) { return; } // Make smaller boxes. double newRadius = radius * radiusFactor; r *= colorFactor; g *= colorFactor; b *= colorFactor; foreach (Vector3D direction in directions) { Point3D newCenter = center + (radius + newRadius) * direction; MakeBoxPopcorn(mesh, depth, newCenter, directions, r, g, b, colorFactor, newRadius, radiusFactor); } }
// Add a parallelepiped defined by a corner point and three edge vectors. // The vectors should have more or less the orientation of the X, Y, and Z axes. // The corner point should be the back, lower, left corner // analogous to the smallest X, Y, and Z coordinates. // Texture coordinates are optional. // Points are shared on each face and not between faces. public static void AddBox(this MeshGeometry3D mesh, Point3D corner, Vector3D vx, Vector3D vy, Vector3D vz, Point[] textureCoords = null) { mesh.AddBox(corner, vx, vy, vz, textureCoords, textureCoords, textureCoords, textureCoords, textureCoords, textureCoords); }
/// Make the ground mesh. void MakeGround(double groundY) { MeshGeometry3D groundMesh = new MeshGeometry3D(); const double dx = 15; const double dy = 1; const double dz = dx; Point3D corner = new Point3D(-dx / 2, groundY - dy, -dz / 2); groundMesh.AddBoxWrapped(corner, D3.XVector(dx), D3.YVector(dy), D3.ZVector(dz)); Point[] topCoords = { new Point(0.1, 0.1), new Point(0.1, 0.9), new Point(0.9, 0.9), new Point(0.9, 0.1), }; Point[] frontCoords = { new Point(0.0, 0.1), new Point(0.0, 0.9), new Point(0.1, 0.9), new Point(0.1, 0.1), }; Point[] leftCoords = { new Point(0.9, 0.0), new Point(0.1, 0.0), new Point(0.1, 0.1), new Point(0.9, 0.1), }; Point[] rightCoords = { new Point(0.1, 1.0), new Point(0.9, 1.0), new Point(0.9, 0.9), new Point(0.1, 0.9), }; Point[] backCoords = { new Point(1.0, 0.9), new Point(1.0, 0.1), new Point(0.9, 0.1), new Point(0.9, 0.9), }; Point[] bottomCoords = { new Point(0.9, 0.1), new Point(0.9, 0.9), new Point(0.1, 0.9), new Point(0.1, 0.1), }; groundMesh.AddBox(corner, D3.XVector(dx), D3.YVector(dy), D3.ZVector(dz), frontCoords, leftCoords, rightCoords, backCoords, topCoords, bottomCoords); _group.Children.Add(groundMesh.MakeModel(System.IO.Path.Combine(_resDir, @"rock.jpg"))); }
// Add a parallelepiped with wrapped texture coordinates. public static void AddBoxWrapped(this MeshGeometry3D mesh, Point3D corner, Vector3D vx, Vector3D vy, Vector3D vz) { // Get texture coordinates for the pieces. Point[] frontCoords = { new Point(0.25, 0.75), new Point(0.50, 0.75), new Point(0.50, 0.50), new Point(0.25, 0.50), }; Point[] leftCoords = { new Point(0.00, 0.25), new Point(0.00, 0.50), new Point(0.25, 0.50), new Point(0.25, 0.25), }; Point[] rightCoords = { new Point(0.75, 0.50), new Point(0.75, 0.25), new Point(0.50, 0.25), new Point(0.50, 0.50), }; Point[] backCoords = { new Point(0.50, 0.00), new Point(0.25, 0.00), new Point(0.25, 0.25), new Point(0.50, 0.25), }; Point[] topCoords = { new Point(0.25, 0.50), new Point(0.50, 0.50), new Point(0.50, 0.25), new Point(0.25, 0.25), }; Point[] bottomCoords = { new Point(0.25, 1.00), new Point(0.50, 1.00), new Point(0.50, 0.75), new Point(0.25, 0.75), }; // Add a point to use all texture coordinates in the area (0, 0) - (1, 1). mesh.Positions.Add(new Point3D()); mesh.TextureCoordinates.Add(new Point(1, 1)); // Add the box. mesh.AddBox(corner, vx, vy, vz, frontCoords, leftCoords, rightCoords, backCoords, topCoords, bottomCoords); }
// Define the model. private void DefineModel() { // Make a cube. MeshGeometry3D mesh = new MeshGeometry3D(); mesh.AddBox(new Point3D(-2, -2, -2), D3.XVector(4), D3.YVector(4), D3.ZVector(4)); MainGroup.Children.Add(mesh.MakeModel(Brushes.LightBlue)); // Add some two-dimensional text. AddLabel(backCanvas, 0, 150, "More Text in Back", 30); AddLabel(foreCanvas, 0, 200, "More Text on Top", 30); }
// Make a box with sides parallel to the coordinate axes // centered at the given point with the give side lengths. public static void AddBox(this MeshGeometry3D mesh, Point3D center, double dx, double dy, double dz) { mesh.AddBox( new Point3D( center.X - dx * 0.5, center.Y - dy * 0.5, center.Z - dz * 0.5), new Vector3D(dx, 0, 0), new Vector3D(0, dy, 0), new Vector3D(0, 0, dz)); }
public static void AddZAxis(Model3DGroup group, double length = 4, double thickness = 0.1) { MeshGeometry3D mesh = new MeshGeometry3D(); Point3D origin = D3.Origin - D3.XVector(thickness / 2) - D3.YVector(thickness / 2) - D3.ZVector(thickness / 2); mesh.AddBox(origin, D3.XVector(thickness), D3.YVector(thickness), D3.ZVector(length)); group.Children.Add(mesh.MakeModel(Brushes.Blue)); }
// Make a cube at the origin. public static void AddOrigin(Model3DGroup group, double cubeThickness = 0.102) { MeshGeometry3D mesh = new MeshGeometry3D(); Point3D origin = D3.Origin - D3.XVector(cubeThickness / 2) - D3.YVector(cubeThickness / 2) - D3.ZVector(cubeThickness / 2); mesh.AddBox(origin, D3.XVector(cubeThickness), D3.YVector(cubeThickness), D3.ZVector(cubeThickness)); group.Children.Add(mesh.MakeModel(Brushes.Black)); }
// Make a Menger sponge. private void MakeSponge(MeshGeometry3D mesh, int depth, Rect3D rect) { // See if we are at the end of the recursion. if (depth == 0) { // Just draw the box. Vector3D vx = D3.XVector(rect.SizeX); Vector3D vy = D3.YVector(rect.SizeY); Vector3D vz = D3.ZVector(rect.SizeZ); mesh.AddBox(rect.Location, vx, vy, vz); } else { // Divide the volume. depth--; double dx = rect.SizeX / 3.0; double dy = rect.SizeY / 3.0; double dz = rect.SizeZ / 3.0; for (int ix = 0; ix < 3; ix++) { for (int iy = 0; iy < 3; iy++) { if ((ix == 1) && (iy == 1)) { continue; } for (int iz = 0; iz < 3; iz++) { if ((iz == 1) && ((ix == 1) || (iy == 1))) { continue; } Rect3D newRect = new Rect3D( rect.X + dx * ix, rect.Y + dy * iy, rect.Z + dz * iz, dx, dy, dz); MakeSponge(mesh, depth, newRect); } } } } }
// Return a MeshGeometry3D representing this mesh's vertices as boxes. public static MeshGeometry3D ToVertexBoxes(this MeshGeometry3D mesh, double thickness) { // Make a mesh to hold the result. MeshGeometry3D boxes = new MeshGeometry3D(); // Make vectors of the desired lengths. Vector3D ux = new Vector3D(thickness, 0, 0); Vector3D uy = new Vector3D(0, thickness, 0); Vector3D uz = new Vector3D(0, 0, thickness); Vector3D ux2 = ux / 2; Vector3D uy2 = uy / 2; Vector3D uz2 = uz / 2; // Loop through the mesh's vertices. foreach (Point3D vertex in mesh.Positions) { // Add a box for this vertex. boxes.AddBox(vertex - ux2 - uy2 - uz2, ux, uy, uz); } return(boxes); }
// Define the model. private void DefineModel() { // Make a cube. MeshGeometry3D mesh = new MeshGeometry3D(); mesh.AddBox(new Point3D(-2, -2, -2), D3.XVector(4), D3.YVector(4), D3.ZVector(4)); MainGroup.Children.Add(mesh.MakeModel(Brushes.LightBlue)); // Create circles for the points. PointCircles = new Ellipse[PointLocations.Length]; for (int i = 0; i < PointLocations.Length; i++) { PointCircles[i] = new Ellipse(); foreCanvas.Children.Add(PointCircles[i]); PointCircles[i].Width = 20; PointCircles[i].Height = 20; PointCircles[i].Stroke = Brushes.Red; PointCircles[i].StrokeThickness = 5; } PositionCircles(); }
// Make a row of bars in the X direction. private void MakeBars(double xmin, double ymin, double zmin, double dx, double gap, double[] values, string[] frontLabels, string[] topLabels, Brush[] barBrushes, Brush[] bgBrushes, Brush[] fgBrushes, FontFamily ff, Model3DGroup group) { double x = xmin; double fontSize = 0.4; for (int i = 0; i < values.Length; i++) { // Make the bar. MeshGeometry3D barMesh = new MeshGeometry3D(); Point3D corner = new Point3D(x, ymin, zmin); barMesh.AddBox(corner, D3.XVector(dx), D3.YVector(YScale * values[i]), D3.ZVector(dx)); group.Children.Add(barMesh.MakeModel(barBrushes[i])); // Display the front label. const double textWid = 1.8; MakeLabel(frontLabels[i], new Point3D(x + dx, ymin, textWid + zmin + dx + gap), D3.ZVector(-textWid), D3.XVector(-dx), bgBrushes[i], fgBrushes[i], fontSize, ff, HorizontalAlignment.Left, VerticalAlignment.Center, group); // Display the top label. MakeLabel(topLabels[i], new Point3D(x, ymin + YScale * values[i], zmin - 0.1), D3.XVector(dx), D3.YVector(dx), Brushes.Transparent, fgBrushes[i], fontSize, ff, HorizontalAlignment.Center, VerticalAlignment.Bottom, group); x += dx + gap; } }
// Define the model. private void DefineModel(Model3DGroup group) { // Make a box. MeshGeometry3D mesh1 = new MeshGeometry3D(); mesh1.AddBox(new Point3D(1, -1, 0), D3.XVector(2), D3.YVector(2), D3.ZVector(2), D3.UnitTextures); group.Children.Add(mesh1.MakeModel("wood.jpg")); // Make a cube with every face different. MeshGeometry3D mesh2 = new MeshGeometry3D(); Point[][] textureCoords = D3.SectionTextureCoords(2, 3); mesh2.AddBox(new Point3D(0, 1, -2), D3.XVector(2), D3.YVector(2), D3.ZVector(2), textureCoords[0], textureCoords[1], textureCoords[2], textureCoords[3], textureCoords[4], textureCoords[5]); group.Children.Add(mesh2.MakeModel("all.jpg")); // Make a green parallelepiped. MeshGeometry3D mesh3 = new MeshGeometry3D(); mesh3.AddBox(new Point3D(-4, -1, -3), new Vector3D(2, 0.5, -0.5), new Vector3D(0, 2, -0.5), new Vector3D(-0.5, 0, 2)); group.Children.Add(mesh3.MakeModel(Brushes.LightGreen)); // Make a wrapped box. MeshGeometry3D mesh4 = new MeshGeometry3D(); mesh4.AddBoxWrapped(new Point3D(-3, -1, 0), D3.XVector(2), D3.YVector(2), D3.ZVector(2)); group.Children.Add(mesh4.MakeModel("wrapper.png")); // Show the axes. MeshExtensions.AddAxes(group); }
// Make a row of stacked bars in the X direction. private void MakeStackedBars(double xmin, double ymin, double zmin, double dx, double gap, double[,] values, string[] frontLabels, Brush[] barBrushes, Brush bgBrush, Brush fgBrush, FontFamily ff, Model3DGroup group) { double x = xmin; int numX = values.GetUpperBound(0) + 1; int numZ = values.GetUpperBound(1) + 1; double fontSize = 0.45; for (int ix = 0; ix < numX; ix++) { double y = ymin; for (int iz = 0; iz < numZ; iz++) { // Make this piece of the bar. MeshGeometry3D barMesh = new MeshGeometry3D(); Point3D corner = new Point3D(x, y, zmin); barMesh.AddBox(corner, D3.XVector(dx), D3.YVector(YScale * values[ix, iz]), D3.ZVector(dx)); group.Children.Add(barMesh.MakeModel(barBrushes[iz])); y += YScale * values[ix, iz]; } // Display the front label. const double textWid = 1.5; MakeLabel(frontLabels[ix], new Point3D(x + dx, ymin, textWid + zmin + dx + gap), D3.ZVector(-textWid), D3.XVector(-dx), bgBrush, fgBrush, fontSize, FontFamily, HorizontalAlignment.Left, VerticalAlignment.Center, group); x += dx + gap; } }
// Define the model. private void DefineModel() { // Make a cube. MeshGeometry3D mesh = new MeshGeometry3D(); mesh.AddBox(new Point3D(-2, -2, -2), D3.XVector(4), D3.YVector(4), D3.ZVector(4)); MainGroup.Children.Add(mesh.MakeModel(Brushes.LightBlue)); // Create labels for the points. PointLabels = new Label[LabelLocations.Length]; for (int i = 0; i < LabelLocations.Length; i++) { PointLabels[i] = new Label(); foreCanvas.Children.Add(PointLabels[i]); PointLabels[i].Content = string.Format("({0}, {1}, {2})", LabelLocations[i].X, LabelLocations[i].Y, LabelLocations[i].Z); PointLabels[i].Background = new SolidColorBrush(Color.FromArgb(64, 255, 255, 255)); PointLabels[i].FontWeight = FontWeights.Bold; } PositionLabels(); }
// Define the model. private void DefineModel() { // Show the axes. //MainGroup.AddAxisModels(); // Make the materials for selected and deselected models. SelectedMaterial = new DiffuseMaterial(Brushes.Fuchsia); DeselectedMaterial = new DiffuseMaterial(Brushes.LightBlue); //SelectedMaterial = new DiffuseMaterial(Brushes.Indigo); //DeselectedMaterial = new DiffuseMaterial(Brushes.Lavender); // Make a bunch of cubes. const int xmax = 2; const double wid = 0.25; const double radius = wid / 2; Vector3D vx = D3.XVector(wid); Vector3D vy = D3.YVector(wid); Vector3D vz = D3.ZVector(wid); for (int ix = -xmax; ix <= xmax; ix++) { for (int iy = -xmax; iy <= xmax; iy++) { for (int iz = -xmax; iz <= xmax; iz++) { MeshGeometry3D mesh = new MeshGeometry3D(); mesh.AddBox(new Point3D(ix - radius, iy - radius, iz - radius), vx, vy, vz); MainGroup.Children.Add(new GeometryModel3D(mesh, DeselectedMaterial)); } } } int num = 2 * xmax + 1; num = num * num * num; Console.WriteLine(num + " cubes"); }
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(); } }
// Add the model to the Model3DGroup. private void DefineModel(Model3DGroup model_group) { // Make the normal and selected materials. NormalMaterial = new DiffuseMaterial(Brushes.LightGreen); SelectedMaterial = new DiffuseMaterial(Brushes.Red); // Create some cubes. for (int x = -5; x <= 3; x += 4) { for (int y = -5; y <= 3; y += 4) { for (int z = -5; z <= 3; z += 4) { // Make a cube with lower left corner (x, y, z). MeshGeometry3D mesh = new MeshGeometry3D(); mesh.AddBox(x, y, z, 2, 2, 2); GeometryModel3D model = new GeometryModel3D(mesh, NormalMaterial); model_group.Children.Add(model); // Remember that this model is selectable. SelectableModels.Add(model); } } } // test cage adding MeshGeometry3D cagemesh = new MeshGeometry3D(); cagemesh.AddCage(5, 5, 5, 2, 2, 2, 0.05); var cagemodel = new GeometryModel3D(cagemesh, NormalMaterial); model_group.Children.Add(cagemodel); SelectableModels.Add(cagemodel); // test cylinder adding MeshGeometry3D cylindermesh = new MeshGeometry3D(); cylindermesh.AddSmoothCylinder(new Point3D(7, 7, 7), new Vector3D(1, 1, 1), 0.5, 20); var cylindermodel = new GeometryModel3D(cylindermesh, NormalMaterial); model_group.Children.Add(cylindermodel); SelectableModels.Add(cylindermodel); // test sphere adding MeshGeometry3D spheremesh = new MeshGeometry3D(); spheremesh.AddSmoothSphere(new Point3D(8.5, 8.5, 8.5), Math.Sqrt(3 * 0.5 + 0.5 * 0.5), 20, 40); var spheremodel = new GeometryModel3D(spheremesh, NormalMaterial); model_group.Children.Add(spheremodel); SelectableModels.Add(spheremodel); // add cone MeshGeometry3D conemesh = new MeshGeometry3D(); conemesh.AddCone(new Point3D(9, 9, 9), new Vector3D(1, 1, 1), 0.5, -0.2, 20); var conemodel = new GeometryModel3D(conemesh, NormalMaterial); model_group.Children.Add(conemodel); SelectableModels.Add(conemodel); // X axis. MeshGeometry3D mesh_x = MeshExtensions.XAxisArrow(1, 7); model_group.Children.Add(mesh_x.SetMaterial(Brushes.Red, false)); var forwardmodel = "前方".To3DLabel(new Point3D(8.5, 0.5, 0), new Vector3D(0, 0, 1), new Vector3D(0, 1, 0), Brushes.Red, 0.5); model_group.Children.Add(forwardmodel); // Y axis. MeshGeometry3D mesh_y = MeshExtensions.YAxisArrow(1, 7); model_group.Children.Add(mesh_y.SetMaterial(Brushes.Green, false)); var upmodel = "上方".To3DLabel(new Point3D(0, 8.5, 0), new Vector3D(0, 0, 1), new Vector3D(0, 1, 0), Brushes.Green, 0.5); model_group.Children.Add(upmodel); // Z axis. MeshGeometry3D mesh_z = MeshExtensions.ZAxisArrow(1, 7); model_group.Children.Add(mesh_z.SetMaterial(Brushes.Blue, false)); var rightmodel = "右方".To3DLabel(new Point3D(0, 0, 9), new Vector3D(0, 0, 1), new Vector3D(0, 1, 0), Brushes.Blue, 0.5); model_group.Children.Add(rightmodel); }
// Define the model. private void DefineModel() { // Axes. //MainGroup.Children.Add(MeshExtensions.XAxisModel(4, 0.1)); //MainGroup.Children.Add(MeshExtensions.YAxisModel(4, 0.1)); //MainGroup.Children.Add(MeshExtensions.ZAxisModel(4, 0.1)); //MainGroup.Children.Add(MeshExtensions.OriginModel(0.12)); // Make the ground. MeshGeometry3D groundMesh = new MeshGeometry3D(); const double dx = 4; const double dy = 1; const double dz = dx; const double groundY = -2; Point3D corner = new Point3D(-dx / 2, groundY - dy, -dz / 2); Point[] topCoords = { new Point(0, 0), new Point(0, dz), new Point(dx, dz), new Point(dx, 0), }; Point[] sideCoords = { new Point(0, 0), new Point(0, dz), new Point(dy, dz), new Point(dy, 0), }; groundMesh.AddBox(corner, D3.XVector(dx), D3.YVector(dy), D3.ZVector(dz), sideCoords, sideCoords, sideCoords, sideCoords, topCoords, topCoords); MainGroup.Children.Add(groundMesh.MakeModel("metal.jpg")); // This group represents the whole robot. RobotGroup = new Model3DGroup(); MainGroup.Children.Add(RobotGroup); // Base. const double baseWidth = 0.4; const double baseLength = 2.5; MeshGeometry3D baseMesh = new MeshGeometry3D(); baseMesh.AddBox(new Point3D(-baseWidth / 2, 0, -baseWidth / 2), D3.XVector(baseWidth), D3.YVector(baseLength), D3.ZVector(baseWidth)); GeometryModel3D baseModel = baseMesh.MakeModel(Brushes.Pink); const int numCyl = 20; const double bJointWidth = 0.5; const double bJointRadius = 0.5; Point3D[] bPgon = G3.MakePolygonPoints(numCyl, new Point3D(0, 0, 0), D3.XVector(bJointRadius), D3.ZVector(-bJointRadius)); baseMesh.AddCylinder(bPgon, D3.YVector(bJointWidth), true); BaseGroup = JoinBones(RobotGroup, new TranslateTransform3D(0, groundY, 0)); BaseGroup.Children.Add(baseModel); // Shoulder. const double shoulderWidth = 0.4; const double shoulderLength = 2; MeshGeometry3D shoulderMesh = new MeshGeometry3D(); shoulderMesh.AddBox(new Point3D(-shoulderWidth / 2, 0, -shoulderWidth / 2), D3.XVector(shoulderWidth), D3.YVector(shoulderLength), D3.ZVector(shoulderWidth)); const double sJointWidth = 0.5; const double sJointRadius = 0.4; Point3D[] sPgon = G3.MakePolygonPoints(numCyl, new Point3D(0, 0, -sJointWidth / 2), D3.XVector(sJointRadius), D3.YVector(sJointRadius)); shoulderMesh.AddCylinder(sPgon, D3.ZVector(sJointWidth), true); GeometryModel3D shoulderModel = shoulderMesh.MakeModel(Brushes.LightGreen); ShoulderGroup = JoinBones(BaseGroup, new TranslateTransform3D(0, baseLength, 0)); ShoulderGroup.Children.Add(shoulderModel); // Elbow. const double elbowWidth = 0.4; const double elbowLength = 1.5; MeshGeometry3D elbowMesh = new MeshGeometry3D(); elbowMesh.AddBox(new Point3D(-elbowWidth / 2, 0, -elbowWidth / 2), D3.XVector(elbowWidth), D3.YVector(elbowLength), D3.ZVector(elbowWidth)); const double eJointWidth = 0.5; const double eJointRadius = 0.4; Point3D[] ePgon = G3.MakePolygonPoints(numCyl, new Point3D(0, 0, -eJointWidth / 2), D3.XVector(eJointRadius), D3.YVector(eJointRadius)); elbowMesh.AddCylinder(ePgon, D3.ZVector(eJointWidth), true); GeometryModel3D elbowModel = elbowMesh.MakeModel(Brushes.LightBlue); ElbowGroup = JoinBones(ShoulderGroup, new TranslateTransform3D(0, shoulderLength, 0)); ElbowGroup.Children.Add(elbowModel); // Wrist. const double wDx = 1.5; const double wDy = 0.2; const double wDz = 0.4; MeshGeometry3D wristMesh = new MeshGeometry3D(); wristMesh.AddBox(new Point3D(-wDx / 2, 0, -wDz / 2), D3.XVector(wDx), D3.YVector(wDy), D3.ZVector(wDz)); const double wJointRadius = 0.3; Point3D[] wPgon = G3.MakePolygonPoints(numCyl, new Point3D(0, -wDy / 2, 0), D3.XVector(wJointRadius), D3.ZVector(-wJointRadius)); wristMesh.AddCylinder(wPgon, D3.YVector(wDy), true); GeometryModel3D wristModel = wristMesh.MakeModel(Brushes.Red); WristGroup = JoinBones(ElbowGroup, new TranslateTransform3D(0, elbowLength, 0)); WristGroup.Children.Add(wristModel); // Finger 1. const double fDx = 0.1; const double fDy = 0.5; const double fDz = 0.2; MeshGeometry3D finger1Mesh = new MeshGeometry3D(); finger1Mesh.AddBox(new Point3D(-fDx / 2, 0, -fDz / 2), D3.XVector(fDx), D3.YVector(fDy), D3.ZVector(fDz)); GeometryModel3D finger1Model = finger1Mesh.MakeModel(Brushes.Green); Finger1Group = JoinBones(WristGroup, new TranslateTransform3D(-fDx / 2, wDy, 0)); Finger1Group.Children.Add(finger1Model); // Finger 2. MeshGeometry3D finger2Mesh = new MeshGeometry3D(); finger2Mesh.AddBox(new Point3D(-fDx / 2, 0, -fDz / 2), D3.XVector(fDx), D3.YVector(fDy), D3.ZVector(fDz)); GeometryModel3D finger2Model = finger2Mesh.MakeModel(Brushes.Green); Finger2Group = JoinBones(WristGroup, new TranslateTransform3D(fDx / 2, wDy, 0)); Finger2Group.Children.Add(finger2Model); }
// Define the model. private void DefineModel(Model3DGroup group) { // Axes. MeshExtensions.AddAxes(group); MeshGeometry3D mesh1 = new MeshGeometry3D(); MeshGeometry3D mesh2 = new MeshGeometry3D(); MeshGeometry3D mesh3 = new MeshGeometry3D(); MeshGeometry3D mesh4 = new MeshGeometry3D(); double x0 = -5; Point3D center = new Point3D(x0, 0, 4.5); // Box. mesh1.AddBox(center + new Vector3D(-0.5, 0, -1), D3.XVector(1), D3.YVector(3), D3.ZVector(2)); center.X += 2; // Box wrapped. mesh2.AddBoxWrapped(center + new Vector3D(-0.5, 0, -1), D3.XVector(1), D3.YVector(3), D3.ZVector(2)); center.X += 2; // Cone. Point3D[] circle = G3.MakePolygonPoints(20, center, D3.XVector(1), D3.ZVector(-1)); mesh1.AddCone(center, circle, D3.YVector(4)); center.X += 2; // Cone frustum. circle = G3.MakePolygonPoints(20, center, D3.XVector(1), D3.ZVector(-1)); mesh1.AddConeFrustum(center, circle, D3.YVector(4), 3); center.X += 2; // Cone frustum w/cutting plane. circle = G3.MakePolygonPoints(20, center, D3.XVector(1), D3.ZVector(-1)); mesh1.AddConeFrustum(center, circle, D3.YVector(4), center + new Vector3D(0, 2, 0), new Vector3D(0, 1, 1)); center.X += 2; // Start a new row. center.X = x0; center.Z -= 3; // Cube. MeshGeometry3D cubeMesh = new MeshGeometry3D(); cubeMesh.AddCube(); cubeMesh.ApplyTransformation(new ScaleTransform3D(1, 1.5, 0.5)); cubeMesh.ApplyTransformation( new TranslateTransform3D(center.X, center.Y + 1.5, 0)); mesh3.Merge(cubeMesh); center.X += 2; // Cylinder. Point3D[] polygon = G3.MakePolygonPoints(7, center, D3.XVector(1), D3.ZVector(-1)); mesh1.AddCylinder(polygon, new Vector3D(0, 2, -1)); center.X += 2; // Cylinder. circle = G3.MakePolygonPoints(20, center, D3.XVector(1), D3.ZVector(-1)); mesh1.AddCylinder(circle, new Vector3D(0, 2, -1), true); center.X += 2; // Cylinder w/cutting planes. polygon = G3.MakePolygonPoints(7, center, D3.XVector(1), D3.ZVector(-1)); mesh1.AddCylinder(polygon, new Vector3D(0, 1, 0), center + new Vector3D(0, 2, 0), new Vector3D(0, 2, 1), center + new Vector3D(0, -2, 0), new Vector3D(0, 2, -1)); center.X += 2; // Cylinder w/cutting planes. polygon = G3.MakePolygonPoints(7, center, D3.XVector(1), D3.ZVector(-1)); mesh1.AddCylinder(polygon, new Vector3D(0, 1, 0), center + new Vector3D(0, 2, 0), new Vector3D(0, 2, 1), center + new Vector3D(0, -2, 0), new Vector3D(0, 2, -1), true); center.X += 2; // Start a new row. center.X = x0; center.Z -= 3; // Dodecahedron. MeshGeometry3D dodMesh = new MeshGeometry3D(); dodMesh.AddDodecahedron(); double dodScale = 1 / G3.DodecahedronCircumradius(); dodMesh.ApplyTransformation(new ScaleTransform3D(dodScale, dodScale, dodScale)); dodMesh.ApplyTransformation( new TranslateTransform3D(center.X, center.Y + 0.5, center.Z)); mesh3.Merge(dodMesh); center.X += 2; // Frustum. polygon = G3.MakePolygonPoints(5, center, D3.XVector(1), D3.ZVector(-1)); mesh1.AddFrustum(center, polygon, D3.YVector(4), 2); center.X += 2; // Icosahedron. MeshGeometry3D icoMesh = new MeshGeometry3D(); icoMesh.AddIcosahedron(); double icoScale = 1 / G3.IcosahedronCircumradius(); icoMesh.ApplyTransformation(new ScaleTransform3D(icoScale, icoScale, icoScale)); icoMesh.ApplyTransformation( new TranslateTransform3D(center.X, center.Y + 0.5, center.Z)); mesh3.Merge(icoMesh); center.X += 2; // Octahedron. MeshGeometry3D octMesh = new MeshGeometry3D(); octMesh.AddOctahedron(); double octScale = 1 / G3.OctahedronCircumradius(); octMesh.ApplyTransformation(new ScaleTransform3D(octScale, octScale, octScale)); octMesh.ApplyTransformation( new TranslateTransform3D(center.X, center.Y + 0.5, center.Z)); mesh3.Merge(octMesh); center.X += 2; // Pyramid. polygon = G3.MakePolygonPoints(6, center, D3.XVector(1), D3.ZVector(-1)); mesh1.AddPyramid(center, polygon, D3.YVector(3)); center.X += 2; // Start a new row. center.X = x0; center.Z -= 3; // Sphere. mesh1.AddSphere(center + new Vector3D(0, 1, 0), 1, 20, 10); center.X += 2; // Tetrahedron. MeshGeometry3D tetMesh = new MeshGeometry3D(); tetMesh.AddTetrahedron(); double tetScale = 1 / G3.TetrahedronCircumradius(); tetMesh.ApplyTransformation(new ScaleTransform3D(tetScale, tetScale, tetScale)); tetMesh.ApplyTransformation( new TranslateTransform3D(center.X, center.Y + 0.5, center.Z)); mesh3.Merge(tetMesh); center.X += 2; // Textured sphere. mesh4.Positions.Add(new Point3D()); mesh4.TextureCoordinates.Add(new Point(1.01, 1.01)); mesh4.AddTexturedSphere(center + new Vector3D(0, 1, 0), 1, 20, 10); center.X += 2; // Textured torus. mesh4.AddTexturedTorus(center + new Vector3D(0, 1, 0), 0.6, 0.4, 30, 15); center.X += 2; // Torus. mesh1.AddTorus(center + new Vector3D(0, 1, 0), 0.6, 0.4, 30, 15); center.X += 2; // Start a new row. center.X = x0; center.Z -= 3; group.Children.Add(mesh1.MakeModel(Brushes.LightGreen)); group.Children.Add(mesh2.MakeModel("wrapper.png")); group.Children.Add(mesh3.MakeModel(Brushes.LightBlue)); group.Children.Add(mesh4.MakeModel("world.jpg")); }