示例#1
0
 public static CubeType[][][] ReadModelVolmetic(string modelFile, double scaleMultiplyier, Transform3D transform, ModelTraceVoxel traceType, Action<double, double> resetProgress, Action incrementProgress)
 {
     return ReadModelVolmetic(modelFile, scaleMultiplyier, scaleMultiplyier, scaleMultiplyier, transform, traceType, resetProgress, incrementProgress);
 }
示例#2
0
        /// <summary>
        /// Volumes are calculated across axis where they are whole numbers (rounded to 0 decimal places).
        /// </summary>
        /// <param name="modelFile"></param>
        /// <param name="scaleMultiplyierX"></param>
        /// <param name="scaleMultiplyierY"></param>
        /// <param name="scaleMultiplyierZ"></param>
        /// <param name="transform"></param>
        /// <param name="traceType"></param>
        /// <param name="resetProgress"></param>
        /// <param name="incrementProgress"></param>
        /// <returns></returns>
        public static CubeType[][][] ReadModelVolmetic(string modelFile, double scaleMultiplyierX, double scaleMultiplyierY, double scaleMultiplyierZ, Transform3D transform, ModelTraceVoxel traceType, Action<double, double> resetProgress, Action incrementProgress)
        {
            var model = MeshHelper.Load(modelFile, ignoreErrors: true);

            // How far to check in from the proposed Volumetric edge.
            // This number is just made up, but small enough that it still represents the corner edge of the Volumetric space.
            // But still large enough that it isn't the exact corner.
            const double offset = 0.00000456f;

            if (scaleMultiplyierX > 0 && scaleMultiplyierY > 0 && scaleMultiplyierZ > 0 && scaleMultiplyierX != 1.0f && scaleMultiplyierY != 1.0f && scaleMultiplyierZ != 1.0f)
            {
                model.TransformScale(scaleMultiplyierX, scaleMultiplyierY, scaleMultiplyierZ);
            }

            var tbounds = model.Bounds;
            if (transform != null)
                tbounds = transform.TransformBounds(tbounds);

            var xMin = (int)Math.Floor(tbounds.X);
            var yMin = (int)Math.Floor(tbounds.Y);
            var zMin = (int)Math.Floor(tbounds.Z);

            var xMax = (int)Math.Ceiling(tbounds.X + tbounds.SizeX);
            var yMax = (int)Math.Ceiling(tbounds.Y + tbounds.SizeY);
            var zMax = (int)Math.Ceiling(tbounds.Z + tbounds.SizeZ);

            var xCount = xMax - xMin;
            var yCount = yMax - yMin;
            var zCount = zMax - zMin;

            var ccubic = ArrayHelper.Create<CubeType>(xCount, yCount, zCount);

            if (resetProgress != null)
            {
                double count = (from GeometryModel3D gm in model.Children select gm.Geometry as MeshGeometry3D).Aggregate<MeshGeometry3D, double>(0, (current, g) => current + (g.TriangleIndices.Count / 3));
                if (traceType == ModelTraceVoxel.ThinSmoothed || traceType == ModelTraceVoxel.ThickSmoothedUp)
                {
                    count += (xCount * yCount * zCount * 3);
                }

                resetProgress.Invoke(0, count);
            }

            #region basic ray trace of every individual triangle.

            foreach (var model3D in model.Children)
            {
                var gm = (GeometryModel3D)model3D;
                var g = gm.Geometry as MeshGeometry3D;
                var materials = gm.Material as MaterialGroup;
                System.Windows.Media.Color color = Colors.Transparent;

                if (materials != null)
                {
                    var material = materials.Children.OfType<DiffuseMaterial>().FirstOrDefault();

                    if (material != null && material != null && material.Brush is SolidColorBrush)
                    {
                        color = ((SolidColorBrush)material.Brush).Color;
                    }
                }

                for (var t = 0; t < g.TriangleIndices.Count; t += 3)
                {
                    if (incrementProgress != null)
                    {
                        incrementProgress.Invoke();
                    }

                    var p1 = g.Positions[g.TriangleIndices[t]];
                    var p2 = g.Positions[g.TriangleIndices[t + 1]];
                    var p3 = g.Positions[g.TriangleIndices[t + 2]];

                    if (transform != null)
                    {
                        p1 = transform.Transform(p1);
                        p2 = transform.Transform(p2);
                        p3 = transform.Transform(p3);
                    }

                    var minBound = MeshHelper.Min(p1, p2, p3).Floor();
                    var maxBound = MeshHelper.Max(p1, p2, p3).Ceiling();

                    Point3D[] rays;

                    for (var y = minBound.Y; y < maxBound.Y; y++)
                    {
                        for (var z = minBound.Z; z < maxBound.Z; z++)
                        {
                            if (traceType == ModelTraceVoxel.Thin || traceType == ModelTraceVoxel.ThinSmoothed)
                            {
                                rays = new Point3D[] // 1 point ray trace in the center.
                                    {
                                        new Point3D(xMin, y + 0.5 + offset, z + 0.5 + offset), new Point3D(xMax, y + 0.5 + offset, z + 0.5 + offset)
                                    };
                            }
                            else
                            {
                                rays = new Point3D[] // 4 point ray trace within each corner of the expected Volumetric cube.
                                    {
                                        new Point3D(xMin, y + offset, z + offset), new Point3D(xMax, y + offset, z + offset),
                                        new Point3D(xMin, y + 1 - offset, z + offset), new Point3D(xMax, y + 1 - offset, z + offset),
                                        new Point3D(xMin, y + offset, z + 1 - offset), new Point3D(xMax, y + offset, z + 1 - offset),
                                        new Point3D(xMin, y + 1 - offset, z + 1 - offset), new Point3D(xMax, y + 1 - offset, z + 1 - offset)
                                    };
                            }

                            Point3D intersect;
                            int normal;
                            if (MeshHelper.RayIntersetTriangleRound(p1, p2, p3, rays, out intersect, out normal))
                            {
                                ccubic[(int)Math.Floor(intersect.X) - xMin][(int)Math.Floor(intersect.Y) - yMin][(int)Math.Floor(intersect.Z) - zMin] = CubeType.Cube;
                            }
                        }
                    }

                    for (var x = minBound.X; x < maxBound.X; x++)
                    {
                        for (var z = minBound.Z; z < maxBound.Z; z++)
                        {
                            if (traceType == ModelTraceVoxel.Thin || traceType == ModelTraceVoxel.ThinSmoothed)
                            {
                                rays = new Point3D[] // 1 point ray trace in the center.
                                    {
                                        new Point3D(x + 0.5 + offset, yMin, z + 0.5 + offset), new Point3D(x + 0.5 + offset, yMax, z + 0.5 + offset)
                                    };
                            }
                            else
                            {
                                rays = new Point3D[] // 4 point ray trace within each corner of the expected Volumetric cube.
                                    {
                                        new Point3D(x + offset, yMin, z + offset), new Point3D(x + offset, yMax, z + offset),
                                        new Point3D(x + 1 - offset, yMin, z + offset), new Point3D(x + 1 - offset, yMax, z + offset),
                                        new Point3D(x + offset, yMin, z + 1 - offset), new Point3D(x + offset, yMax, z + 1 - offset),
                                        new Point3D(x + 1 - offset, yMin, z + 1 - offset), new Point3D(x + 1 - offset, yMax, z + 1 - offset)
                                    };
                            }

                            Point3D intersect;
                            int normal;
                            if (MeshHelper.RayIntersetTriangleRound(p1, p2, p3, rays, out intersect, out normal))
                            {
                                ccubic[(int)Math.Floor(intersect.X) - xMin][(int)Math.Floor(intersect.Y) - yMin][(int)Math.Floor(intersect.Z) - zMin] = CubeType.Cube;
                            }
                        }
                    }

                    for (var x = minBound.X; x < maxBound.X; x++)
                    {
                        for (var y = minBound.Y; y < maxBound.Y; y++)
                        {
                            if (traceType == ModelTraceVoxel.Thin || traceType == ModelTraceVoxel.ThinSmoothed)
                            {
                                rays = new Point3D[] // 1 point ray trace in the center.
                                    {
                                        new Point3D(x + 0.5 + offset, y + 0.5 + offset, zMin), new Point3D(x + 0.5 + offset, y + 0.5 + offset, zMax),
                                    };
                            }
                            else
                            {
                                rays = new Point3D[] // 4 point ray trace within each corner of the expected Volumetric cube.
                                    {
                                        new Point3D(x + offset, y + offset, zMin), new Point3D(x + offset, y + offset, zMax),
                                        new Point3D(x + 1 - offset, y + offset, zMin), new Point3D(x + 1 - offset, y + offset, zMax),
                                        new Point3D(x + offset, y + 1 - offset, zMin), new Point3D(x + offset, y + 1 - offset, zMax),
                                        new Point3D(x + 1 - offset, y + 1 - offset, zMin), new Point3D(x + 1 - offset, y + 1 - offset, zMax)
                                    };
                            }

                            Point3D intersect;
                            int normal;
                            if (MeshHelper.RayIntersetTriangleRound(p1, p2, p3, rays, out intersect, out normal))
                            {
                                ccubic[(int)Math.Floor(intersect.X) - xMin][(int)Math.Floor(intersect.Y) - yMin][(int)Math.Floor(intersect.Z) - zMin] = CubeType.Cube;
                            }
                        }
                    }
                }
            }

            #endregion

            CrawlExterior(ccubic);

            if (traceType == ModelTraceVoxel.ThinSmoothed || traceType == ModelTraceVoxel.ThickSmoothedUp)
            {
                CalculateAddedInverseCorners(ccubic, incrementProgress);
                CalculateAddedSlopes(ccubic, incrementProgress);
                CalculateAddedCorners(ccubic, incrementProgress);
            }

            //if (traceType == ModelTraceVoxel.ThickSmoothedDown)
            //{
            //    CalculateSubtractedCorners(ccubic);
            //    CalculateSubtractedSlopes(ccubic);
            //    CalculateSubtractedInverseCorners(ccubic);
            //}

            return ccubic;
        }
示例#3
0
 public static CubeType[][][] ReadModelVolmetic(string modelFile, double scaleMultiplyier, Transform3D transform, ModelTraceVoxel traceType)
 {
     return ReadModelVolmetic(modelFile, scaleMultiplyier, scaleMultiplyier, scaleMultiplyier, transform, traceType, null, null);
 }
示例#4
0
        public static MyVoxelMap BuildAsteroidFromModel(bool multiThread, string sourceVolumetricFile, string material, string faceMaterial, bool fillObject, string interiorMaterial, ModelTraceVoxel traceType, double scale, Transform3D transform, Action <double, double> resetProgress, Action incrementProgress)
        {
            var volmeticMap = Modelling.ReadModelVolmetic(sourceVolumetricFile, scale, transform, traceType, resetProgress, incrementProgress);
            var size        = new Vector3I(volmeticMap.Length + 12, volmeticMap[0].Length + 12, volmeticMap[0][0].Length + 12);

            var action = (Action <MyVoxelBuilderArgs>) delegate(MyVoxelBuilderArgs e)
            {
                if (e.CoordinatePoint.X > 5 && e.CoordinatePoint.Y > 5 && e.CoordinatePoint.Z > 5 &&
                    (e.CoordinatePoint.X <= volmeticMap.Length + 5) && (e.CoordinatePoint.Y <= volmeticMap[0].Length + 5) && (e.CoordinatePoint.Z <= volmeticMap[0][0].Length + 5))
                {
                    var cube = volmeticMap[e.CoordinatePoint.X - 6][e.CoordinatePoint.Y - 6][e.CoordinatePoint.Z - 6];
                    if (cube == CubeType.Interior && fillObject)
                    {
                        e.Volume = 0xff;    // 100%
                        if (interiorMaterial != null)
                        {
                            e.Material = interiorMaterial;
                        }
                    }
                    else if (cube == CubeType.Cube)
                    {
                        e.Volume = 0xff;    // 100% "11111111"
                    }
                    else if (cube.ToString().StartsWith("InverseCorner"))
                    {
                        e.Volume = 0xD4;    // 83%  "11010100"
                    }
                    else if (cube.ToString().StartsWith("Slope"))
                    {
                        e.Volume = 0x7F;    // 50%  "01111111"
                    }
                    else if (cube.ToString().StartsWith("NormalCorner"))
                    {
                        e.Volume = 0x2B;    // 16%  "00101011"
                    }
                    else
                    {
                        e.Volume = 0x00;    // 0%   "00000000"
                    }
                }
                else
                {
                    e.Volume = 0x00;
                }
            };

            return(BuildAsteroid(multiThread, size, material, faceMaterial, action));
        }
示例#5
0
 public static MyVoxelMap BuildAsteroidFromModel(bool multiThread, string sourceVolumetricFile, string material, string faceMaterial, bool fillObject, string interiorMaterial, ModelTraceVoxel traceType, double scale, Transform3D transform)
 {
     return(BuildAsteroidFromModel(multiThread, sourceVolumetricFile, material, faceMaterial, fillObject, interiorMaterial, traceType, scale, transform, null, null));
 }
示例#6
0
        public static MyVoxelMap BuildAsteroidFromModel(bool multiThread, string sourceVolumetricFile, string material, string faceMaterial, bool fillObject, string interiorMaterial, ModelTraceVoxel traceType, double scale, Transform3D transform, Action<double, double> resetProgress, Action incrementProgress)
        {
            var volmeticMap = Modelling.ReadModelVolmetic(sourceVolumetricFile, scale, transform, traceType, resetProgress, incrementProgress);
            var size = new Vector3I(volmeticMap.Length + 12, volmeticMap[0].Length + 12, volmeticMap[0][0].Length + 12);

            var action = (Action<MyVoxelBuilderArgs>)delegate(MyVoxelBuilderArgs e)
            {
                if (e.CoordinatePoint.X > 5 && e.CoordinatePoint.Y > 5 && e.CoordinatePoint.Z > 5 &&
                    (e.CoordinatePoint.X <= volmeticMap.Length + 5) && (e.CoordinatePoint.Y <= volmeticMap[0].Length + 5) && (e.CoordinatePoint.Z <= volmeticMap[0][0].Length + 5))
                {
                    var cube = volmeticMap[e.CoordinatePoint.X - 6][e.CoordinatePoint.Y - 6][e.CoordinatePoint.Z - 6];
                    if (cube == CubeType.Interior && fillObject)
                    {
                        e.Volume = 0xff;    // 100%
                        if (interiorMaterial != null)
                        {
                            e.Material = interiorMaterial;
                        }
                    }
                    else if (cube == CubeType.Cube)
                        e.Volume = 0xff;    // 100% "11111111"
                    else if (cube.ToString().StartsWith("InverseCorner"))
                        e.Volume = 0xD4;    // 83%  "11010100"
                    else if (cube.ToString().StartsWith("Slope"))
                        e.Volume = 0x7F;    // 50%  "01111111"
                    else if (cube.ToString().StartsWith("NormalCorner"))
                        e.Volume = 0x2B;    // 16%  "00101011"
                    else
                        e.Volume = 0x00;    // 0%   "00000000"
                }
                else
                {
                    e.Volume = 0x00;
                }
            };

            return BuildAsteroid(multiThread, size, material, faceMaterial, action);
        }
示例#7
0
 public static MyVoxelMap BuildAsteroidFromModel(bool multiThread, string sourceVolumetricFile, string material, string faceMaterial, bool fillObject, string interiorMaterial, ModelTraceVoxel traceType, double scale, Transform3D transform)
 {
     return BuildAsteroidFromModel(multiThread, sourceVolumetricFile, material, faceMaterial, fillObject, interiorMaterial, traceType, scale, transform, null, null);
 }