// 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); }
// Process the models. private void ProcessModels(bool invertTextures, bool zIsUp) { // Make the dictionary of materials. foreach (ObjMaterial material in AllMaterials) { // Make the material's MaterialGroup. material.MatGroup = new MaterialGroup(); // Transparency. (Not used.) byte alpha = (byte)(material.Alpha * 255); // Diffuse. byte diffR = (byte)(material.Kd.X * 255); byte diffG = (byte)(material.Kd.Y * 255); byte diffB = (byte)(material.Kd.Z * 255); Color diffColor = Color.FromArgb(255, diffR, diffG, diffB); SolidColorBrush diffBrush = new SolidColorBrush(diffColor); DiffuseMaterial diffMat = new DiffuseMaterial(diffBrush); material.MatGroup.Children.Add(diffMat); // If it has a file, use it. if (material.Filename != null) { // Use the file. string filename = material.Filename; ImageBrush imgBrush = new ImageBrush(); imgBrush.ViewportUnits = BrushMappingMode.Absolute; imgBrush.TileMode = TileMode.Tile; // Invert the texture if necessary. if (invertTextures) { TransformGroup trans = new TransformGroup(); trans.Children.Add(new ScaleTransform(1, -1)); trans.Children.Add(new TranslateTransform(0, 1)); imgBrush.Transform = trans; } imgBrush.ImageSource = new BitmapImage(new Uri(filename, UriKind.Relative)); DiffuseMaterial imgMat = new DiffuseMaterial(imgBrush); material.MatGroup.Children.Add(imgMat); } // Specular. byte specR = (byte)(material.Ks.X * 255); byte specG = (byte)(material.Ks.Y * 255); byte specB = (byte)(material.Ks.Z * 255); Color specColor = Color.FromArgb(255, specR, specG, specB); SolidColorBrush specBrush = new SolidColorBrush(specColor); SpecularMaterial specMat = new SpecularMaterial(specBrush, material.Ns); material.MatGroup.Children.Add(specMat); // We ignore Ka and Tr. // Add it to the materials dictionary. MtlMaterials.Add(material.Name, material); } // Convert the object models into meshes. foreach (ObjModel model in AllObjectModels) { // Make the mesh. MeshGeometry3D mesh = new MeshGeometry3D(); Meshes.Add(mesh); MeshNames.Add(model.Name); MaterialNames.Add(model.MaterialName); // Make a new list of smoothing groups. Dictionary <int, Dictionary <Point3D, int> > smoothingGroups = new Dictionary <int, Dictionary <Point3D, int> >(); // Entry 0 is null (no smoothing). smoothingGroups.Add(0, null); // Make the faces. foreach (ObjFace face in model.Faces) { // Make the face's vertices. int numPoints = face.Vertices.Count; Point3D[] points = new Point3D[numPoints]; for (int i = 0; i < numPoints; i++) { points[i] = AllVertices[face.Vertices[i] - 1]; } // Get texture coordinates if present. Point[] textureCoords = null; if (face.TextureCoords.Count > 0) { textureCoords = new Point[numPoints]; for (int i = 0; i < numPoints; i++) { textureCoords[i] = AllTextureCoordinates[face.TextureCoords[i] - 1]; } } // Get normals if present. Vector3D[] normals = null; if (face.Normals.Count > 0) { normals = new Vector3D[numPoints]; for (int i = 0; i < numPoints; i++) { normals[i] = AllNormals[face.Normals[i] - 1]; } } // Get the point dictionary for this smoothing group. // Add new groups if needed. if (!smoothingGroups.ContainsKey(face.SmoothingGroup)) { smoothingGroups.Add(face.SmoothingGroup, new Dictionary <Point3D, int>()); } Dictionary <Point3D, int> pointDict = smoothingGroups[face.SmoothingGroup]; // Make the polygon. mesh.AddPolygon(pointDict: pointDict, textureCoords: textureCoords, normals: normals, points: points); } // If Z is up, rotate the model. if (zIsUp) { mesh.ApplyTransformation(D3.Rotate(D3.XVector(), D3.Origin, -90)); } } }