Exemplo n.º 1
0
 // 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);
                 }
             }
         }
     }
 }
        // 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));
                }
            }
        }