// 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); } }
// 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)); } } }