コード例 #1
0
ファイル: VoxelizedSolid.cs プロジェクト: mattMedemaLabs/TVGL
 /// <summary>
 /// Initializes a new instance of the <see cref="VoxelizedSolid"/> class.
 /// </summary>
 /// <param name="ts">The ts.</param>
 /// <param name="voxelSideLength">Length of the voxel side.</param>
 /// <param name="bounds">The bounds.</param>
 public VoxelizedSolid(TessellatedSolid ts, double voxelSideLength, IReadOnlyList <Vector3> bounds = null) : this()
 {
     if (bounds != null)
     {
         Bounds = new[] { bounds[0], bounds[1] }
     }
     ;
     else
     {
         Bounds = new[] { ts.Bounds[0], ts.Bounds[1] }
     };
     Dimensions      = Bounds[1].Subtract(Bounds[0]);
     SolidColor      = new Color(Constants.DefaultColor);
     VoxelSideLength = voxelSideLength;
     numVoxelsX      = (int)Math.Ceiling(Dimensions.X / VoxelSideLength);
     numVoxelsY      = (int)Math.Ceiling(Dimensions.Y / VoxelSideLength);
     numVoxelsZ      = (int)Math.Ceiling(Dimensions.Z / VoxelSideLength);
     voxels          = new IVoxelRow[numVoxelsY * numVoxelsZ];
     for (int i = 0; i < numVoxelsY * numVoxelsZ; i++)
     {
         voxels[i] = new VoxelRowSparse();
     }
     FillInFromTessellation(ts);
     FractionDense = 0;
     UpdateProperties();
 }
コード例 #2
0
ファイル: VoxelizedSolid.cs プロジェクト: mattMedemaLabs/TVGL
 /// <summary>
 /// Initializes a new instance of the <see cref="VoxelizedSolid"/> class.
 /// </summary>
 /// <param name="ts">The ts.</param>
 /// <param name="voxelsOnLongSide">The voxels on long side.</param>
 /// <param name="bounds">The bounds.</param>
 public VoxelizedSolid(TessellatedSolid ts, int voxelsOnLongSide, IReadOnlyList <Vector3> bounds = null) : this()
 {
     if (bounds != null)
     {
         Bounds = new[] { bounds[0], bounds[1] }
     }
     ;
     else
     {
         Bounds = new[] { ts.Bounds[0], ts.Bounds[1] }
     };
     Dimensions      = Bounds[1].Subtract(Bounds[0]);
     SolidColor      = new Color(ts.SolidColor.A, ts.SolidColor.R, ts.SolidColor.G, ts.SolidColor.B);
     VoxelSideLength = Math.Max(Dimensions.X, Math.Max(Dimensions.Y, Dimensions.Z)) / voxelsOnLongSide;
     numVoxelsX      = (int)Math.Ceiling(Dimensions.X / VoxelSideLength);
     numVoxelsY      = (int)Math.Ceiling(Dimensions.Y / VoxelSideLength);
     numVoxelsZ      = (int)Math.Ceiling(Dimensions.Z / VoxelSideLength);
     voxels          = new IVoxelRow[numVoxelsY * numVoxelsZ];
     for (int i = 0; i < numVoxelsY * numVoxelsZ; i++)
     {
         voxels[i] = new VoxelRowSparse(numVoxelsX);
     }
     FillInFromTessellation(ts);
     FractionDense = 0;
     UpdateProperties();
 }
コード例 #3
0
ファイル: VoxelRowSparse.cs プロジェクト: mattMedemaLabs/TVGL
 /// <summary>
 /// Intersects the specified other rows with this row.
 /// </summary>
 /// <param name="others">The others.</param>
 /// <param name="offset">The offset.</param>
 public void Intersect(IVoxelRow[] others, int offset = 0)
 {
     for (int i = 0; i < others.Length; i++)
     {
         IVoxelRow other = others[i];
         if (other is VoxelRowDense)
         {
             other = new VoxelRowSparse(other, other.maxNumberOfVoxels);
         }
         var otherIndices    = ((VoxelRowSparse)other).indices;
         var otherLength     = otherIndices.Count;
         var indexLowerBound = 0;
         if (otherLength == 0)
         {
             indices.Clear();
         }
         else
         {
             if (otherIndices[0] != 0)
             {
                 TurnOffRange(0, otherIndices[0], ref indexLowerBound);
             }
             for (int j = 1; j < otherLength - 1; j += 2)
             {
                 TurnOffRange(otherIndices[j], otherIndices[j + 1], ref indexLowerBound);
             }
             TurnOffRange(otherIndices[otherLength - 1], other.maxNumberOfVoxels, ref indexLowerBound);
         }
     }
 }
コード例 #4
0
ファイル: VoxelRowSparse.cs プロジェクト: mattMedemaLabs/TVGL
 /// <summary>
 /// Initializes a new instance of the <see cref="VoxelRowSparse"/> struct.
 /// </summary>
 /// <param name="row">The row.</param>
 internal VoxelRowSparse(IVoxelRow row, int length)
 {
     maxNumberOfVoxels = (ushort)length;
     if (row is VoxelRowSparse sparse)
     {
         indices = new List <ushort>(sparse.indices);
     }
     else
     {
         indices = new List <ushort>();
         var    denseRow = ((VoxelRowDense)row);
         var    lastVal  = false;
         ushort i        = 0;
         foreach (var thisByte in denseRow.values)
         {
             var currentByte = thisByte;
             for (int j = 0; j < 8; j++)
             {
                 var currentVal = (currentByte & 0b10000000) != 0;
                 if (currentVal != lastVal)
                 {
                     lastVal = currentVal;
                     indices.Add(i);
                 }
                 currentByte <<= 1;
                 i++;
             }
         }
         if (lastVal)
         {
             indices.Add(i);
         }
     }
 }
コード例 #5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="VoxelizedSolid"/> class.
        /// </summary>
        /// <param name="ts">The ts.</param>
        /// <param name="voxelSideLength">Length of the voxel side.</param>
        /// <param name="bounds">The bounds.</param>
        public VoxelizedSolid(TessellatedSolid ts, double voxelSideLength, IReadOnlyList <double[]> bounds = null) : this()
        {
            Bounds = new double[2][];
            if (bounds != null)
            {
                Bounds[0] = (double[])bounds[0].Clone();
                Bounds[1] = (double[])bounds[1].Clone();
            }
            else
            {
                Bounds[0] = (double[])ts.Bounds[0].Clone();
                Bounds[1] = (double[])ts.Bounds[1].Clone();
            }
            Dimensions      = Bounds[1].subtract(Bounds[0]);
            SolidColor      = new Color(Constants.DefaultColor);
            VoxelSideLength = voxelSideLength;
            var voxelsPerSide = Dimensions.Select(d => (int)Math.Ceiling(d / VoxelSideLength)).ToArray();

            numVoxelsX = voxelsPerSide[0];
            numVoxelsY = voxelsPerSide[1];
            numVoxelsZ = voxelsPerSide[2];
            voxels     = new IVoxelRow[numVoxelsY * numVoxelsZ];
            for (int i = 0; i < numVoxelsY * numVoxelsZ; i++)
            {
                voxels[i] = new VoxelRowSparse();
            }
            FillInFromTessellation(ts);
            FractionDense = 0;
            UpdateProperties();
        }
コード例 #6
0
ファイル: VoxelizedSolid.cs プロジェクト: mattMedemaLabs/TVGL
 /// <summary>
 /// Initializes a new instance of the <see cref="VoxelizedSolid"/> class.
 /// </summary>
 /// <param name="vs">The vs.</param>
 internal VoxelizedSolid(VoxelizedSolid vs) : this()
 {
     Bounds          = new[] { vs.Bounds[0], vs.Bounds[1] };
     Dimensions      = Bounds[1].Subtract(Bounds[0]);
     SolidColor      = new Color(vs.SolidColor.A, vs.SolidColor.R, vs.SolidColor.G, vs.SolidColor.B);
     VoxelSideLength = vs.VoxelSideLength;
     numVoxelsX      = vs.numVoxelsX;
     numVoxelsY      = vs.numVoxelsY;
     numVoxelsZ      = vs.numVoxelsZ;
     voxels          = new IVoxelRow[numVoxelsY * numVoxelsZ];
     for (int i = 0; i < numVoxelsY * numVoxelsZ; i++)
     {
         voxels[i] = new VoxelRowSparse(vs.voxels[i], numVoxelsX);
     }
     FractionDense = 0;
     UpdateProperties();
 }
コード例 #7
0
ファイル: VoxelRowDense.cs プロジェクト: mattMedemaLabs/TVGL
 /// <summary>
 /// Initializes a new instance of the <see cref="VoxelRowDense"/> struct.
 /// This is typically used to copy an existing dense row, or convert from
 /// a sparse row.
 /// </summary>
 /// <param name="row">The row.</param>
 /// <param name="numBytes">The number bytes.</param>
 internal VoxelRowDense(IVoxelRow row, int length) : this(length)
 {
     if (row is VoxelRowSparse sparse)
     {
         if (sparse.indices.Any())
         {
             for (int i = 0; i < sparse.indices.Count; i += 2)
             {
                 TurnOnRange(sparse.indices[i], sparse.indices[i + 1]);
             }
         }
     }
     else
     {
         values = (byte[])((VoxelRowDense)row).values.Clone();
     }
 }
コード例 #8
0
ファイル: VoxelRowSparse.cs プロジェクト: mattMedemaLabs/TVGL
 /// <summary>
 /// Subtracts the specified subtrahend rows from this row.
 /// </summary>
 /// <param name="subtrahends">The subtrahends.</param>
 /// <param name="offset">The offset.</param>
 public void Subtract(IVoxelRow[] subtrahends, int offset = 0)
 {
     for (int i = 0; i < subtrahends.Length; i++)
     {
         IVoxelRow subtrahend = subtrahends[i];
         if (subtrahend is VoxelRowDense)
         {
             subtrahend = new VoxelRowSparse(subtrahend, subtrahend.maxNumberOfVoxels);
         }
         var otherIndices    = ((VoxelRowSparse)subtrahend).indices;
         var otherLength     = otherIndices.Count;
         var indexLowerBound = 0;
         for (int j = 0; j < otherLength; j += 2)
         {
             TurnOffRange(otherIndices[j], otherIndices[j + 1], ref indexLowerBound);
         }
     }
 }
コード例 #9
0
ファイル: VoxelRowSparse.cs プロジェクト: mattMedemaLabs/TVGL
 /// <summary>
 /// Unions the specified other rows with this row.
 /// </summary>
 /// <param name="others">The others.</param>
 /// <param name="offset">The offset.</param>
 public void Union(IVoxelRow[] others, int offset = 0)
 {
     for (int i = 0; i < others.Length; i++)
     {
         IVoxelRow other = others[i];
         if (other is VoxelRowDense)
         {
             other = new VoxelRowSparse(other, other.maxNumberOfVoxels);
         }
         var otherIndices    = ((VoxelRowSparse)other).indices;
         var otherLength     = otherIndices.Count;
         var indexLowerBound = 0;
         for (int j = 0; j < otherLength; j += 2)
         {
             TurnOnRange(otherIndices[j], otherIndices[j + 1], ref indexLowerBound);
         }
     }
 }
コード例 #10
0
 public VoxelizedSolid(VoxelizedSolid vs) : this()
 {
     Bounds          = new double[2][];
     Bounds[0]       = (double[])vs.Bounds[0].Clone();
     Bounds[1]       = (double[])vs.Bounds[1].Clone();
     Dimensions      = Bounds[1].subtract(Bounds[0]);
     SolidColor      = new Color(vs.SolidColor.A, vs.SolidColor.R, vs.SolidColor.G, vs.SolidColor.B);
     VoxelSideLength = vs.VoxelSideLength;
     numVoxelsX      = vs.numVoxelsX;
     numVoxelsY      = vs.numVoxelsY;
     numVoxelsZ      = vs.numVoxelsZ;
     voxels          = new IVoxelRow[numVoxelsY * numVoxelsZ];
     for (int i = 0; i < numVoxelsY * numVoxelsZ; i++)
     {
         voxels[i] = new VoxelRowSparse(vs.voxels[i], numVoxelsX);
     }
     FractionDense = 0;
     UpdateProperties();
 }
コード例 #11
0
ファイル: VoxelizedSolid.cs プロジェクト: mattMedemaLabs/TVGL
        /// <summary>
        /// Initializes a new instance of the <see cref="VoxelizedSolid"/> class.
        /// </summary>
        /// <param name="ts">The ts.</param>
        /// <param name="voxelsOnLongSide">The voxels on long side.</param>
        /// <param name="bounds">The bounds.</param>
        public VoxelizedSolid(IEnumerable <Polygon> loops, int voxelsOnLongSide, IReadOnlyList <Vector2> bounds) : this()
        {
            Bounds          = new[] { new Vector3(bounds[0], 0), new Vector3(bounds[1], 1) };
            Dimensions      = Bounds[1].Subtract(Bounds[0]);
            VoxelSideLength = Math.Max(Dimensions.X, Math.Max(Dimensions.Y, Dimensions.Z)) / voxelsOnLongSide;
            numVoxelsX      = (int)Math.Ceiling(Dimensions.X / VoxelSideLength);
            numVoxelsY      = (int)Math.Ceiling(Dimensions.Y / VoxelSideLength);
            numVoxelsZ      = 1;
            voxels          = new IVoxelRow[numVoxelsY * numVoxelsZ];
            for (int i = 0; i < numVoxelsY * numVoxelsZ; i++)
            {
                voxels[i] = new VoxelRowSparse(numVoxelsX);
            }

            var yBegin = Bounds[0][1] + VoxelSideLength / 2;
            var inverseVoxelSideLength = 1 / VoxelSideLength; // since its quicker to multiple then to divide, maybe doing this once at the top will save some time
                                                              //if (loops.Any())
                                                              //{  // multiple enumeration warning so commenting out above condition. but that sound be a problem for next line
            var intersections = loops.AllPolygonIntersectionPointsAlongHorizontalLines(yBegin, numVoxelsY,
                                                                                       VoxelSideLength, out var yStartIndex);
            var numYlines = intersections.Count;

            for (int j = -Math.Min(0, yStartIndex); j < numYlines; j++)
            {
                var intersectionPoints   = intersections[j];
                var numXRangesOnThisLine = intersectionPoints.Length;
                for (var m = 0; m < numXRangesOnThisLine; m += 2)
                {
                    var sp = (ushort)((intersectionPoints[m] - Bounds[0][0]) * inverseVoxelSideLength);
                    var ep = (ushort)((intersectionPoints[m + 1] - Bounds[0][0]) * inverseVoxelSideLength);
                    if (ep >= numVoxelsX)
                    {
                        ep = (ushort)(numVoxelsX - 1);
                    }
                    ((VoxelRowSparse)voxels[yStartIndex + j]).indices.Add(sp);
                    ((VoxelRowSparse)voxels[yStartIndex + j]).indices.Add(ep);
                }
            }
            //}
            FractionDense = 0;
            UpdateProperties();
        }