コード例 #1
0
        private void SolidifyLoop(int j, int lastJ, SweepPlanePoint[,] sweepPlane, List<SweepPlanePoint> activePts, HashSet<SweepPlanePoint> inactiveInteriorPts, SweepPlanePoint[] neighboringSweepPlanePts)
        {
            for (int i = 0; i < xCellLength; i++) //Iterate across the cross-section plane to add voxel shell and mark active interior points
                for (int k = 0; k < zCellLength; k++)
                {
                    SweepPlanePoint pt = sweepPlane[i, k];
                    Part p = GetPartAtVoxelPos(i, j, k);

                    if (pt == null) //If there is a section of voxel there, but no pt, add a new voxel shell pt to the sweep plane
                    {
                        if ((object)p != null)
                        {
                            sweepPlane[i, k] = new SweepPlanePoint(p, i, k);
                            continue;
                        }
                    }
                    else
                    {
                        if ((object)p == null) //If there is a pt there, but no part listed, this is an interior pt or the cross-section is shrinking
                        {
                            if (pt.mark == SweepPlanePoint.MarkingType.VoxelShell) //label it as active so that it can be determined if it is interior or not once all the points have been updated
                            {
                                activePts.Add(pt); //And add it to the list of active interior pts
                                pt.mark = SweepPlanePoint.MarkingType.Active;
                            }
                            else if (pt.mark == SweepPlanePoint.MarkingType.VoxelShellPreviouslyInterior) //if this shell was previously interior, we need to know so that we can set it to the correct active
                            {
                                activePts.Add(pt); //And add it to the list of active interior pts
                                pt.mark = SweepPlanePoint.MarkingType.ActivePassedThroughInternalShell;
                            }
                            //Only other situation is that it is an inactive point, in which case we do nothing here, because it is already taken care of
                        }
                        else if (pt.mark == SweepPlanePoint.MarkingType.Clear)
                        {
                            pt.mark = SweepPlanePoint.MarkingType.VoxelShell;
                            pt.part = p;
                        }
                        else if (pt.mark != SweepPlanePoint.MarkingType.VoxelShell && pt.mark != SweepPlanePoint.MarkingType.VoxelShellPreviouslyInterior)  //only run this if it's not already labeled as part of a voxel shell
                        {  //Make sure the point is labeled as a voxel shell if there is already a part there
                            inactiveInteriorPts.Remove(pt);
                            pt.mark = SweepPlanePoint.MarkingType.VoxelShellPreviouslyInterior;     //this marks that this point was once part of the voxel shell
                            pt.part = p;
                            pt.jLastInactive = j;
                        }
                    }
                }
            for (int i = 0; i < activePts.Count; i++) //Then, iterate through all active points for this section
            {
                SweepPlanePoint activeInteriorPt = activePts[i]; //Get active interior pt
                if (activeInteriorPt.i + 1 < xCellLength) //And all of its 4-neighbors
                    neighboringSweepPlanePts[0] = sweepPlane[activeInteriorPt.i + 1, activeInteriorPt.k];
                else
                    neighboringSweepPlanePts[0] = null;
                if (activeInteriorPt.i - 1 > 0)
                    neighboringSweepPlanePts[1] = sweepPlane[activeInteriorPt.i - 1, activeInteriorPt.k];
                else
                    neighboringSweepPlanePts[1] = null;
                if (activeInteriorPt.k + 1 < zCellLength)
                    neighboringSweepPlanePts[2] = sweepPlane[activeInteriorPt.i, activeInteriorPt.k + 1];
                else
                    neighboringSweepPlanePts[2] = null;
                if (activeInteriorPt.k - 1 > 0)
                    neighboringSweepPlanePts[3] = sweepPlane[activeInteriorPt.i, activeInteriorPt.k - 1];
                else
                    neighboringSweepPlanePts[3] = null;

                bool remove = false;
                for (int m = 0; m < neighboringSweepPlanePts.Length; m++)// (SweepPlanePoint neighbor in neighboringSweepPlanePts)//Check if the active point is surrounded by all 4 neighbors
                {
                    SweepPlanePoint neighbor = neighboringSweepPlanePts[m];
                    if (neighbor == null || neighbor.mark == SweepPlanePoint.MarkingType.Clear) //If any of them are null or marked clear, this active point is not an interior point
                    {                                                                       //In that case, it should be set to be removed
                        remove = true;
                        break;
                    }
                }
                if (remove) //If it is set to be removed...
                {
                    for (int m = 0; m < neighboringSweepPlanePts.Length; m++)// //Go through all the neighboring points
                    {
                        SweepPlanePoint neighbor = neighboringSweepPlanePts[m];
                        if (neighbor != null && neighbor.mark == SweepPlanePoint.MarkingType.InactiveInterior) //For the ones that exist, and are inactive interior...
                        {
                            inactiveInteriorPts.Remove(neighbor); //remove them from inactiveInterior
                            neighbor.mark = SweepPlanePoint.MarkingType.Active; //...mark them active
                            activePts.Add(neighbor); //And add them to the end of activePts
                        }
                    }
                    sweepPlane[activeInteriorPt.i, activeInteriorPt.k].mark = SweepPlanePoint.MarkingType.Clear; //Then, set this point to be marked clear in the sweepPlane
                }
                else
                { //If it's surrounded by other points, it's inactive; add it to that list
                    if (activeInteriorPt.mark == SweepPlanePoint.MarkingType.ActivePassedThroughInternalShell)
                    {
                        if (activeInteriorPt.jLastInactive < j)
                            for (int mJ = activeInteriorPt.jLastInactive; mJ < j; mJ++)
                                SetVoxelPointNoLock(activeInteriorPt.i, mJ, activeInteriorPt.k);       //used to make sure that internal part boundaries for cargo bays don't result in dips in cross-section
                        else
                            for (int mJ = lastJ; mJ <= activeInteriorPt.jLastInactive; mJ++)
                                SetVoxelPointNoLock(activeInteriorPt.i, mJ, activeInteriorPt.k);       //used to make sure that internal part boundaries for cargo bays don't result in dips in cross-section

                    }

                    activeInteriorPt.mark = SweepPlanePoint.MarkingType.InactiveInterior;
                    inactiveInteriorPts.Add(activeInteriorPt);
                }
            }
            activePts.Clear(); //Clear activePts every iteration

            foreach (SweepPlanePoint inactivePt in inactiveInteriorPts) //Any remaining inactive interior pts are guaranteed to be on the inside of the vehicle
            {
                SetVoxelPointNoLock(inactivePt.i, j, inactivePt.k, inactivePt.part); //Get each and update the voxel accordingly
            }
        }
コード例 #2
0
        private void SolidifyVoxel(int lowJ, int highJ, bool increasingJ)
        {
            SweepPlanePoint[,] plane;
            lock (clearedPlanes)
            {
                while (clearedPlanes.Count == 0)
                    Monitor.Wait(clearedPlanes);

                plane = clearedPlanes.Pop();
            }

            try
            {
                int xLength = plane.GetLength(0);
                int zLength = plane.GetLength(1);
                if (xLength < xCellLength || zLength < zCellLength)
                    plane = new SweepPlanePoint[Math.Max(xCellLength, xLength), Math.Max(zCellLength, zLength)];

                //SweepPlanePoint[,] sweepPlane = new SweepPlanePoint[xCellLength, zCellLength];
                List<SweepPlanePoint> activePts = new List<SweepPlanePoint>();
                HashSet<SweepPlanePoint> inactiveInteriorPts = new HashSet<SweepPlanePoint>();
                SweepPlanePoint[] neighboringSweepPlanePts = new SweepPlanePoint[4];

                if (increasingJ)
                    for (int j = lowJ; j < highJ; j++) //Iterate from back of vehicle to front
                    {
                        SolidifyLoop(j, j - 1, plane, activePts, inactiveInteriorPts, neighboringSweepPlanePts);
                    }
                else
                    for (int j = highJ - 1; j >= lowJ; j--) //Iterate from front of vehicle to back
                    {
                        SolidifyLoop(j, j + 1, plane, activePts, inactiveInteriorPts, neighboringSweepPlanePts);
                    }

                //Cleanup
                //sweepPlane = null;
                activePts = null;
                inactiveInteriorPts = null;
                neighboringSweepPlanePts = null;
            }
            catch (Exception e)
            {
                ThreadSafeDebugLogger.Instance.RegisterException(e);
            }
            finally
            {
                CleanSweepPlane(plane);
                lock (clearedPlanes)
                {
                    clearedPlanes.Push(plane);
                    Monitor.Pulse(clearedPlanes);
                }
            }
        }
コード例 #3
0
        private void CleanSweepPlane(SweepPlanePoint[,] sweepPlane)
        {
            int lengthX, lengthZ;
            lengthX = sweepPlane.GetLength(0);
            lengthZ = sweepPlane.GetLength(1);

            for (int i = 0; i < lengthX; i++)
                for (int k = 0; k < lengthZ; k++)
                {
                    SweepPlanePoint pt = sweepPlane[i, k];
                    if(pt != null)
                    {
                        pt.Clear();
                    }
                }
        }