示例#1
0
    /// <summary>
    /// Creates a new VoxelBlob from the provided filestream.
    /// </summary>
    /// <returns>
    /// The from file.
    /// </returns>
    /// <param name='aFile'>
    /// A file.
    /// </param>
    /// <param name='aCallback'>
    /// A callback.
    /// </param>
    public static IEnumerator NewFromFile(System.IO.FileStream aFile, bool trackVoxelBounds,
                                          DeserilizationCompleted aCallback)
    {
        VoxelBlob result;

        using (System.IO.BinaryReader fin = new System.IO.BinaryReader(aFile)) {
            int  width, height, depth;
            int3 start, end;
            if (!ReadHeader(fin, out height, out width, out depth, out start, out end))
            {
                aCallback(new VoxelBlob(kTestSize, kTestSize, kTestSize, trackVoxelBounds));
            }

            result = new VoxelBlob(width, height, depth, trackVoxelBounds);

            for (int aLayer = start.y; aLayer <= end.y; ++aLayer)
            {
                for (int aRow = start.z; aRow <= end.z; ++aRow)
                {
                    for (int aCol = start.x; aCol <= end.x; ++aCol)
                    {
                        result[aCol, aLayer, aRow] = fin.ReadByte();

                        if (Scheduler.ShouldYield())
                        {
                            yield return(null);
                        }
                    }
                }
            }
            fin.Close();
        }

        aCallback(result);
    }
示例#2
0
    /// <summary>
    /// Makes a new blob that should strain the chunk regeneration
    /// </summary>
    public static VoxelBlob NewFpsTestBlob()
    {
        VoxelBlob blob = new VoxelBlob(kTestSize, kTestSize, kTestSize, true);

        int on = 0;

        for (int x = 0; x < 300; ++x)
        {
            if ((x % 2) == 0)
            {
                on = (on + 2) % 4;
            }
            for (int y = 0; y < 128; ++y)
            {
                if ((y % 2) == 0)
                {
                    on = (on + 2) % 4;
                }
                for (int z = 0; z < 300; ++z)
                {
                    if (on > 1 && !(x == 17 && z == 17))
                    {
                        blob[x, y, z] = MeshManager.kVoxelFirstMat;
                    }
                    on = (on + 1) % 4;
                }
            }
        }
        return(blob);
    }
示例#3
0
    public static VoxelBlob NewTestDisc()
    {
        VoxelBlob blob = new VoxelBlob(kTestSize, kTestSize, kTestSize, false);

        int origin = kTestSize / 2;

        // Disc with ~25mm radius.
        for (int aLayer = 0; aLayer < 30; ++aLayer)
        {
            for (float r = 0; r < 24.85f / kVoxelSizeInMm; ++r)
            {
                for (float angle = 0.0f; angle < 90.0f; angle += 0.25f)
                {
                    float radians = angle * Mathf.Deg2Rad;
                    float x       = Mathf.Cos(radians);
                    float y       = Mathf.Sin(radians);

                    PlaceRadialBlock(blob,
                                     origin + r * x,
                                     aLayer,
                                     origin + r * y);
                }
            }
        }

        return(blob);
    }
示例#4
0
        public VoxelRegionEnumerator(VoxelBlob aBlob, int aLayer, bool isReverse)
        {
            bool isEmpty;

            int2 minBoundary;
            int2 maxBoundary;

            aBlob.GetLayer(aLayer, ref m_layer, out isEmpty, out minBoundary, out maxBoundary);

            m_width  = m_layer.GetLength(0);
            m_depth  = m_layer.GetLength(1);
            m_region = new VoxelRegion(m_width, m_depth, minBoundary, maxBoundary);

            m_minVals = minBoundary;
            m_maxVals = maxBoundary;

            if (isReverse)
            {
                m_x = maxBoundary.x - 1;
                m_z = maxBoundary.y - 1;
                DirectedMoveNext = ReverseMoveNext;
            }
            else
            {
                m_x = minBoundary.x;
                m_z = minBoundary.y;
                DirectedMoveNext = ForwardMoveNext;
            }

            // Positioned before the first region when created;
            // <http://msdn.microsoft.com/en-us/library/system.collections.ienumerator.movenext(v=vs.110).aspx>
        }
示例#5
0
    public static VoxelBlob NewFromFile(System.IO.FileStream aFile, bool trackVoxelBounds)
    {
        VoxelBlob result = null;

        using (System.IO.BinaryReader fin = new System.IO.BinaryReader(aFile)) {
            int  width, height, depth;
            int3 start, end;
            if (!ReadHeader(fin, out height, out width, out depth, out start, out end))
            {
                return(new VoxelBlob(kTestSize, kTestSize, kTestSize, trackVoxelBounds));
            }

            result = new VoxelBlob(width, height, depth, trackVoxelBounds);

            for (int aLayer = start.y; aLayer <= end.y; ++aLayer)
            {
                for (int aRow = start.z; aRow <= end.z; ++aRow)
                {
                    for (int aCol = start.x; aCol <= end.x; ++aCol)
                    {
                        result[aCol, aLayer, aRow] = fin.ReadByte();
                    }
                }
            }
            fin.Close();
        }

        return(result);
    }
示例#6
0
    public void Apply(MeshManager manager)
    {
        VoxelBlob targetData = manager.m_blob;
        byte      newMat     = material;

        material = targetData[width, layer, depth];
        targetData[width, layer, depth] = newMat;
        manager.MarkChunksForRegenForPoint(width, layer, depth);
    }
示例#7
0
    public void Update()
    {
        if (addBlob)
        {
            addBlob = false;
            VoxelBlob tempBlob = new VoxelBlob(targetVoxelLength, 1, targetVoxelLength, false);
            myManager.AddVoxelBlob(Convert(tempBlob));

            Text.Log("added picture");
        }
    }
示例#8
0
    static void PlaceRadialBlock(VoxelBlob aBlob, float rawX, int aLayer, float rawZ)
    {
        int lowX = Mathf.FloorToInt(rawX);
        int lowZ = Mathf.FloorToInt(rawZ);

        aBlob[lowX, aLayer, lowZ] = 1;

        int highX = Mathf.CeilToInt(rawX);
        int highZ = Mathf.CeilToInt(rawZ);

        aBlob[highX, aLayer, highZ] = 1;
    }
示例#9
0
    IEnumerator DoApply(MeshManager manager, DeltaDoneDelegate onDone, bool undo)
    {
        VoxelBlob targetData = manager.m_blob;

        foreach (BlobHolder holder in blobs.Values)
        {
            if (Scheduler.ShouldYield())
            {
                yield return(null);
            }
            VoxelBlob blob = holder.blob;
            if (holder.unDone == undo)
            {
                continue;
            }
            for (int x = 0; x < blob.width; ++x)
            {
                for (int y = 0; y < blob.height; ++y)
                {
                    for (int z = 0; z < blob.depth; ++z)
                    {
                        byte newMat = blob[x, y, z];
                        if (newMat != System.Convert.ToByte(0))
                        {
                            int  dataX  = x + (int)blob.position.x;
                            int  dataY  = y + (int)blob.position.y;
                            int  dataZ  = z + (int)blob.position.z;
                            byte oldMat = targetData[dataX, dataY, dataZ];
                            if (oldMat == 0)
                            {
                                oldMat = MeshManager.kVoxelSubtract;
                            }
                            if (newMat == MeshManager.kVoxelSubtract)
                            {
                                newMat = 0;
                            }

                            blob[x, y, z] = oldMat;
                            targetData[dataX, dataY, dataZ] = newMat;
                            manager.MarkChunksForRegenForPoint(dataX, dataY, dataZ);
                        }
                    }
                }
            }
            holder.unDone = undo;
        }

        if (onDone != null)
        {
            onDone();
        }
    }
示例#10
0
    /// <summary>
    /// Returns a voxel blob with the object moved closer
    /// to the origin.
    /// </summary>
    /// <returns>
    /// Returns a compacted voxel blob.
    /// </returns>
    public VoxelBlob CompactBlob()
    {
        VoxelBlob compacted = new VoxelBlob(width, depth, height, true);

        int xMin = minVoxelBounds[0];
        int yMin = minVoxelBounds[1];
        int zMin = minVoxelBounds[2];

        if (xMin < 0 || yMin < 0 || zMin < 0)
        {
            return(this);
        }

        if (!m_trackVoxelBounds)
        {
            xMin = width;
            yMin = depth;
            zMin = height;

            for (int x = 0; x < width; ++x)
            {
                for (int y = 0; y < depth; ++y)
                {
                    for (int z = 0; z < height; ++z)
                    {
                        int block = this[x, y, z];

                        if (block > 0)
                        {
                            xMin = Mathf.Min(x, xMin);
                            yMin = Mathf.Min(y, yMin);
                            zMin = Mathf.Min(z, zMin);
                        }
                    }     // end z for
                }         // end y for
            }             // end x for
        }

        for (int x = xMin; x < width; ++x)
        {
            for (int y = yMin; y < depth; ++y)
            {
                for (int z = zMin; z < height; ++z)
                {
                    compacted[x - xMin, y - yMin, z - zMin] = this[x, y, z];
                }
            }
        }
        compacted.position = new Vector3(xMin, yMin, zMin);
        return(compacted);
    }
示例#11
0
    void Awake()
    {
        Dispatcher.AddListener(MenuController.kEventNewBlob, ClearMeshes);

        m_trans         = transform;
        m_cameraTrans   = Camera.main.transform;
        m_deltaFuture   = new Stack <IDelta>();
        m_deltaHistory  = new Stack <IDelta>();
        m_enabledMeshes = new List <VoxelMesh>();

        if (useTestBlob)
        {
            m_blob = VoxelBlob.NewTestDisc();
        }
        else if (useFpsTestBlob)
        {
            m_blob = VoxelBlob.NewFpsTestBlob();
        }
        else
        {
            m_blob = new VoxelBlob(VoxelBlob.kTestSize, VoxelBlob.kTestSize, VoxelBlob.kTestSize, true);
        }

        string[] launchArguments = System.Environment.GetCommandLineArgs();
        if (launchArguments != null)
        {
            for (int i = launchArguments.Length - 1; i > -1; i--)
            {
                if (launchArguments[i].Contains(".radiant") || launchArguments[i].Contains(".Radiant"))
                {
                    if (System.IO.File.Exists(launchArguments[i]))
                    {
                        Dispatcher <string> .Broadcast(MenuController.kEventLoadScene, launchArguments[i]);

                        i = -1;
                    }
                }
            }
        }

        m_colliderCache        = new BoxCollider[kColliderCacheDim * kColliderCacheDim * kColliderCacheDim];
        m_chunkPositionCurrent = WorldToChunk(m_cameraTrans.position);

        // NOTE: When we load data in the future, we'll need to find a suitable
        // location for the player.
        CreateCollisionCache();
        Scheduler.StartCoroutine(LoadVisualChunks());
        Scheduler.StartCoroutine(UpdateVisualChunks());
        Dispatcher.Broadcast(kOnForceRefresh);
    }
示例#12
0
    public IEnumerator GenerateSupport(byte support, VoxelBlob source)
    {
        System.Array.Copy(source.m_data, m_data, source.m_data.Length);

        for (int x = 0; x < width; ++x)
        {
            int minX = Mathf.Max(0, x - 1);
            int maxX = Mathf.Min(width - 1, x + 1);

            for (int z = 0; z < depth; ++z)
            {
                int minZ = Mathf.Max(0, z - 1);
                int maxZ = Mathf.Min(depth - 1, z + 1);

                bool isBlockPresent = this[x, height - 1, z] != 0;
                for (int y = height - 2; y >= 0; --y)
                {
                    if (!isBlockPresent)
                    {
                        isBlockPresent = this[x, y, z] != 0;
                        continue;
                    }

                    // First pass: Generate support under each block.
                    if (this[minX, y, minZ] == 0 &&
                        this[minX, y, minZ] == 0 &&
                        this[minX, y, z] == 0 &&
                        this[minX, y, maxZ] == 0 &&
                        this[x, y, minZ] == 0 &&
                        this[x, y, z] == 0 &&
                        this[x, y, maxZ] == 0 &&
                        this[maxX, y, minZ] == 0 &&
                        this[maxX, y, z] == 0 &&
                        this[maxX, y, maxZ] == 0)
                    {
                        this[x, y, z] = support;
                    }
                }
                if (Scheduler.ShouldYield())
                {
                    yield return(null);
                }
            }
        }
    }
示例#13
0
    /// <summary>
    /// Coalesce all of the blobs into one blob.
    /// </summary>
    public VoxelBlob MakeSingleBlob()
    {
        //find our bounds
        Vector3 lowerBound = Vector3.one * float.MaxValue;
        Vector3 upperBound = Vector3.one * float.MinValue;

        foreach (BlobHolder holder in blobs.Values)
        {
            VoxelBlob blob = holder.blob;
            int3      size = blob.size;
            for (int i = 0; i < 3; ++i)
            {
                lowerBound[i] = Mathf.Min(lowerBound[i], blob.position[i]);
                upperBound[i] = Mathf.Max(upperBound[i], blob.position[i] + size[i]);
            }
        }

        Vector3   blobSize = upperBound - lowerBound;
        VoxelBlob target   = new VoxelBlob((int)blobSize[0], (int)blobSize[1], (int)blobSize[2], false);

        target.position = lowerBound;

        foreach (BlobHolder holder in blobs.Values)
        {
            VoxelBlob blob   = holder.blob;
            Vector3   offset = blob.position - target.position;
            for (int x = 0; x < blob.width; ++x)
            {
                for (int y = 0; y < blob.height; ++y)
                {
                    for (int z = 0; z < blob.depth; ++z)
                    {
                        target[x + (int)offset.x, y + (int)offset.y, z + (int)offset.z] =
                            blob[x, y, z];
                    }
                }
            }
        }

        return(target);
    }
示例#14
0
    public byte this[int x, int y, int z] {
        set {
            int3 chunk = new int3(x, y, z) / blobSize;
            chunk *= blobSize;

            //if we already have that chunk, assign to that, otherwise create a new one
            VoxelBlob blob;
            if (blobs.ContainsKey(chunk))
            {
                blob = blobs[chunk].blob;
            }
            else
            {
                blob          = new VoxelBlob(blobSize, blobSize, blobSize, false);
                blob.position = new Vector3(chunk.x, chunk.y, chunk.z);
                blobs.Add(chunk, new BlobHolder(blob));
            }

            blob[x - chunk.x, y - chunk.y, z - chunk.z] = value;
        }
    }
示例#15
0
    public VoxelBlob Convert(VoxelBlob aPart)
    {
        float minLength        = Mathf.Min(image.width, image.height);
        int   conversionFactor = Mathf.FloorToInt((float)minLength / (float)targetVoxelLength);
        int   voxelCount       = 0;

        for (int aRow = 0; aRow < targetVoxelLength; ++aRow)
        {
            for (int aCol = 0; aCol < targetVoxelLength; ++aCol)
            {
                Color sourceColor = image.GetPixel(aCol * conversionFactor, aRow * conversionFactor);
                if (sourceColor.r > redCutoff && sourceColor.g > greenCutoff &&
                    sourceColor.b > blueCutoff && sourceColor.a > alphaCutoff)
                {
                    //Text.Log("A row = " + aRow + "   a col = " + aCol);
                    //Text.Log(aPart[aRow,0,0]);
                    voxelCount++;
                    aPart[aRow, 0, aCol] = 1;
                }
            }
        }
        Text.Log("Created this many voxels from the picture " + voxelCount);
        return(aPart);
    }
示例#16
0
    public static VoxelBlob NewExtrusionBlob()
    {
        VoxelBlob blob = new VoxelBlob(kTestSize, kTestSize, kTestSize, true);

        int origin = kTestSize / 2;

        for (int aLayer = 0; aLayer < 20; ++aLayer)
        {
            for (float r = 45 / kVoxelSizeInMm; r < 70 / kVoxelSizeInMm; ++r)
            {
                for (float angle = -45; angle <= 45.0f; angle += 0.25f)
                {
                    float radians = angle * Mathf.Deg2Rad;
                    float x       = Mathf.Cos(radians);
                    float y       = Mathf.Sin(radians);

                    PlaceRadialBlock(blob,
                                     origin + r * x,
                                     aLayer,
                                     origin + r * y);

                    PlaceRadialBlock(blob,
                                     Mathf.Floor(origin + r * Mathf.Cos(75.0f * Mathf.Deg2Rad)),
                                     aLayer,
                                     Mathf.Floor(origin + r * Mathf.Sin(75.0f * Mathf.Deg2Rad)));

                    PlaceRadialBlock(blob,
                                     Mathf.Floor(origin + r * Mathf.Cos(-75.0f * Mathf.Deg2Rad)),
                                     aLayer,
                                     Mathf.Floor(origin + r * Mathf.Sin(-75.0f * Mathf.Deg2Rad)));
                }
            }
        }

        return(blob);
    }
示例#17
0
    const int kTestBlockSize = 150;    //150;

    /// <summary>
    /// Returns a test blob of the default test size.
    /// </summary>
    /// <returns>
    /// The test BLOB.
    /// </returns>
    public static VoxelBlob NewTestBlob()
    {
        VoxelBlob blob = new VoxelBlob(kTestSize, kTestSize, kTestSize, true);

        // A 20x20 square centered at the platform origin
        // for kTestSize = 100.
        int start      = (kTestSize - kTestBlockSize) / 2;    // -> 145.5
        int spaceStart = (kTestBlockSize / 2) - 1 + start;
        int spaceEnd   = spaceStart + 0;

        /*for (int aLayer = 0; aLayer < blob.height; ++aLayer) {
         *      for (int aRow = 0; aRow < blob.width; ++aRow) {
         *              for (int aCol = 0; aCol < blob.depth; ++aCol) {
         *                       blob[aRow, aLayer, aCol] = 1;
         *              }
         *      }
         * }*/

        for (int aLayer = 2; aLayer < 4; ++aLayer)
        {
            for (int aRow = start; aRow < start + kTestBlockSize; ++aRow)
            {
                //for (int aRow = (kTestSize - 15) / 2; aRow < (kTestSize - 15) / 2 + 30; ++aRow) {
                for (int aCol = start; aCol < start + kTestBlockSize; ++aCol)
                {
                    // Uncomment for a split square.
                    if (aCol < spaceStart || aCol > spaceEnd || aRow % 2 == 0)
                    {
                        blob[aCol, aLayer, aRow] = 1;
                    }
                }
            }
        }

        return(blob);
    }
示例#18
0
 IEnumerator SetVoxelsInBlob(byte threshold, VoxelBlob blob, byte[,,] data, byte[,,] debugData)
 {
     for (int x = scanVolumeStart.x; x < scanVolumeEnd.x; ++x)
     {
         for (int y = scanVolumeStart.y; y < scanVolumeEnd.y; ++y)
         {
             for (int z = scanVolumeStart.z; z < scanVolumeEnd.z; ++z)
             {
                 if (data[x, y, z] <= threshold)
                 {
                     blob[x, y, z] = 1;
                 }
                 else
                 {
                     blob[x, y, z] = 0;
                 }
             }
         }
         if (Scheduler.ShouldYield())
         {
             yield return(null);
         }
     }
 }
示例#19
0
 public void SaveStlFromBlob(VoxelBlob blob, System.IO.Stream aStream, bool shouldClose)
 {
     Scheduler.StartCoroutine(GenFacesFromBlob(blob), this);
     Scheduler.StartCoroutine(WriteStlBinaryToStream(aStream, shouldClose), this);
 }
示例#20
0
        public VoxelSurfaceEnumerator(VoxelBlob aBlob, VoxelRegion sourceRegion,
                                      int voxelLayer, int printLayer, float layerHeight, bool isReverse)
        {
            // We don't want to surface the first layer, we want 100% infill instead.
            if (printLayer == 0)
            {
                DirectedMoveNext = Empty;
                return;
            }

            float logicalHeight = Mathf.Repeat(printLayer * layerHeight, VoxelBlob.kVoxelSizeInMm);

            if (!(Mathf.Approximately(logicalHeight, 0) ||
                  Mathf.Approximately(logicalHeight + layerHeight, VoxelBlob.kVoxelSizeInMm)))
            {
                // We're neither at the bottom of a voxel nor
                // at the top, so we don't care about surfacing.
                DirectedMoveNext = Empty;
                return;
            }

            // NOTE: Caching the information means that we're not thread safe!
            if (m_width != aBlob.width || m_depth != aBlob.depth)
            {
                m_currentLayer    = new byte[aBlob.width, aBlob.depth];
                m_checkLayer      = new byte[aBlob.width, aBlob.depth];
                m_otherCheckLayer = new byte[aBlob.width, aBlob.depth];
            }

            bool isEmpty;
            bool checkedFirstLayer = false;

            // Grab the adjacent layers to check for space.
            if (Mathf.Approximately(logicalHeight, 0.0f) && voxelLayer > 0)
            {
                // At the bottom of a voxel, so we need to check the lower layer.
                aBlob.GetLayer(voxelLayer - 1, ref m_checkLayer, out isEmpty, out m_minVals, out m_maxVals);
                checkedFirstLayer = true;
            }
            if (Mathf.Approximately(logicalHeight + layerHeight, VoxelBlob.kVoxelSizeInMm) &&
                voxelLayer + 1 < aBlob.height)
            {
                if (!checkedFirstLayer)
                {
                    aBlob.GetLayer(voxelLayer + 1, ref m_checkLayer, out isEmpty, out m_minVals, out m_maxVals);
                }
                else
                {
                    aBlob.GetLayer(voxelLayer + 1, ref m_otherCheckLayer, out isEmpty, out m_minVals, out m_maxVals);
                    for (int x = m_minVals.x; x <= m_maxVals.x; x++)
                    {
                        for (int y = m_minVals.y; y <= m_maxVals.y; y++)
                        {
                            m_checkLayer[x, y] = (byte)Mathf.Min(m_checkLayer[x, y], m_otherCheckLayer[x, y]);
                        }
                    }
                }
            }

            // Grab the current layer for later comparison.
            aBlob.GetLayer(voxelLayer, ref m_currentLayer, out isEmpty, out m_minVals, out m_maxVals);
            if (isEmpty)
            {
                DirectedMoveNext = Empty;
                return;
            }

            m_width = m_checkLayer.GetLength(0);
            m_depth = m_checkLayer.GetLength(1);

            m_region       = new VoxelRegion(m_width, m_depth, m_minVals, m_maxVals);
            m_sourceRegion = sourceRegion;

            if (isReverse)
            {
                // This means we're actually within a voxel, and so we
                // shouldn't do anything.
                m_x = m_maxVals.x - 1;
                m_z = m_maxVals.y - 1;
                DirectedMoveNext = ReverseMoveNext;
            }
            else
            {
                m_x = m_minVals.x;
                m_z = m_minVals.y;
                DirectedMoveNext = ForwardMoveNext;
            }

            // Positioned before the first region when created;
            // <http://msdn.microsoft.com/en-us/library/system.collections.ienumerator.movenext(v=vs.110).aspx>
        }
示例#21
0
 void LoadComplete(VoxelBlob loadedBlob)
 {
 }
示例#22
0
    void NormalMenu()
    {
        float yInitial   = (Screen.height - (kButtonHeight + kMargin) * 6) / 2.0f;
        Rect  buttonRect = new Rect((Screen.width - kButtonWidth) / 4.0f,
                                    yInitial, kButtonWidth, kButtonHeight);

        // Left column ////////////////////////////////////////////////////////
        if (GUI.Button(buttonRect, m_workingPrinter.isAwake ? "Sleep" : "Wake"))
        {
            if (!m_workingPrinter.isAwake)
            {
                pc.WakePrinter(m_workingPrinter);
            }
            else
            {
                pc.SleepPrinter(m_workingPrinter);
            }
        }

        buttonRect.y += kButtonHeight + kMargin;
        if (GUI.Button(buttonRect, "Print Test"))
        {
            // Print
            pc.SchedulePrint(VoxelBlob.NewTestDisc());
            HandleMenu = PrintingMenu;
            Dispatcher <float> .AddListener(PrinterController.kOnPrintingProgress, OnPrintingProgress);
        }

        buttonRect.y += kButtonHeight + kMargin;
        if (GUI.Button(buttonRect, @"Print Test Scene"))
        {
            string   filePath;
            string[] extensions     = new string[] { "radiant" };
            string[] extensionNames = new string[] { "Radiant scene" };

            if (FileDialogs.ShowOpenFileDialog(out filePath, extensions, extensionNames))
            {
                System.IO.FileStream stream = new System.IO.FileStream(filePath, System.IO.FileMode.Open);
                VoxelBlob            blob   = VoxelBlob.NewFromFile(stream, false);
                pc.SchedulePrint(blob);
                HandleMenu = PrintingMenu;
                Dispatcher <float> .AddListener(PrinterController.kOnPrintingProgress, OnPrintingProgress);
            }
            else
            {
                Text.Log(@"Aborted opening.");
            }
        }

        /*
         * buttonRect.y += kButtonHeight + kMargin;
         * if (GUI.Button(buttonRect, "Request Token Test")) {
         *      StartCoroutine(OAuth1.GetRequestToken(ExternalSite.ShapeWays, RequestResponse));
         *      HandleMenu = AuthorizationMenu;
         * }
         */

        /*
         * GUI.enabled = !m_isSaved;
         * buttonRect.y += kButtonHeight + kMargin;
         * if (GUI.Button(buttonRect, "Save")) {
         *      string filePath = NativePanels.SaveFileDialog("model.radiant", "radiant");
         *      SaveBlob(filePath);
         *      Text.Log("Saved " + filePath);
         *      m_isSaved = true;
         *      Dispatcher<Sfx>.Broadcast(AudioManager.kPlaySfx, Sfx.Select);
         * }
         *
         * GUI.enabled = true;
         * buttonRect.y += kButtonHeight + kMargin;
         * if (GUI.Button(buttonRect, "Load")) {
         *      //PlayerPrefs.SetString(VoxelBlob.kSerializedKey, serializedBlob);
         *      string filePath = NativePanels.OpenFileDialog(new string[]{"radiant"});
         *      LoadBlob(filePath);
         *      m_isSaved = true;
         *      Dispatcher<Sfx>.Broadcast(AudioManager.kPlaySfx, Sfx.Select);
         * }
         */

        // Right column ///////////////////////////////////////////////////////
        buttonRect.x      = (Screen.width - kButtonWidth) * 0.75f;
        buttonRect.y      = yInitial;
        buttonRect.height = kButtonHeight;
        buttonRect.width  = kButtonWidth / 3.0f;
        buttonRect.x     += buttonRect.width + kMargin;
        if (GUI.Button(buttonRect, "^"))
        {
            pc.BeginMotorChanges(m_workingPrinter);
            pc.MoveVerticallyBy(-10.0f, Change.Execute);
            pc.EndMotorChanges();
        }

        buttonRect.y += kButtonHeight + kMargin;
        buttonRect.x  = buttonRect.x - buttonRect.width - kMargin;
        if (GUI.Button(buttonRect, "<"))
        {
            pc.BeginMotorChanges(m_workingPrinter);
            pc.MoveHorizontallyBy(10.0f, Change.Execute);
            pc.EndMotorChanges();
        }

        buttonRect.x += buttonRect.width + kMargin;
        if (GUI.Button(buttonRect, "v"))
        {
            pc.BeginMotorChanges(m_workingPrinter);
            pc.MoveVerticallyBy(10.0f, Change.Execute);
            pc.EndMotorChanges();
        }

        buttonRect.x += buttonRect.width + kMargin;
        if (GUI.Button(buttonRect, ">"))
        {
            pc.BeginMotorChanges(m_workingPrinter);
            pc.MoveHorizontallyBy(-10.0f, Change.Execute);
            pc.EndMotorChanges();
        }
    }
示例#23
0
 public void SaveStlFromBlob(VoxelBlob blob, string fileName)
 {
     Scheduler.StartCoroutine(GenFacesFromBlob(blob), this);
     Scheduler.StartCoroutine(WriteStlBinary(fileName), this);
 }
示例#24
0
 public void InitFromBlob(VoxelBlob blob)
 {
     Scheduler.StartCoroutine(GenFacesFromBlob(blob), this);
 }
示例#25
0
 byte VoxelAt(int x, int y, int z, VoxelBlob blob)
 {
     return(blob[x + position.x, y + position.y, z + position.z]);
 }
示例#26
0
 public BlobHolder(VoxelBlob blob)
 {
     this.blob = blob;
     unDone    = false;
 }
示例#27
0
 byte VoxelAt(int3 pos, VoxelBlob blob)
 {
     return(VoxelAt(pos.x, pos.y, pos.z, blob));
 }
示例#28
0
    IEnumerator GenFacesFromBlob(VoxelBlob blob)
    {
        float currentProgress = 0;
        float maxProgress     = blob.width * blob.height * blob.depth;

        loadProgress = 0;

        faces = new List <Face>();
        for (int x = 0; x < blob.width; ++x)
        {
            for (int y = 0; y < blob.height; ++y)
            {
                for (int z = 0; z < blob.depth; ++z)
                {
                    if (Scheduler.ShouldYield())
                    {
                        yield return(null);
                    }
                    if (blob[x, y, z] == MeshManager.kVoxelEmpty)
                    {
                        continue;
                    }

                    //figure out if each face is a surface face
                    Vector3 block = new Vector3(x, y, z);
                    for (int dim = 0; dim < 3; ++dim)
                    {
                        for (int dir = -1; dir < 2; dir += 2)
                        {
                            Vector3 neighbor = block;
                            neighbor[dim] += dir;
                            bool onSurface = true;
                            if (blob.IsValidPoint((int)neighbor.x, (int)neighbor.y, (int)neighbor.z) &&
                                blob[(int)neighbor.x, (int)neighbor.y, (int)neighbor.z] != MeshManager.kVoxelEmpty)
                            {
                                onSurface = false;
                            }

                            if (onSurface)
                            {
                                int axis1 = (dir < 0 ? (dim + 2) % 3 : (dim + 1) % 3);
                                int axis2 = (dir < 0 ? (dim + 1) % 3 : (dim + 2) % 3);

                                Vector3 p0;
                                if (dir < 0)
                                {
                                    p0 = block;
                                }
                                else
                                {
                                    p0 = block + Vector3.one;
                                }

                                Vector3 p1 = p0;
                                p1[axis1] -= dir;
                                Vector3 p2 = p0;
                                p2[axis2] -= dir;
                                Face face = new Face(p0, p1, p2);
                                face.Init();
                                faces.Add(face);
                                Vector3 p3 = p1;
                                p3[axis2] -= dir;
                                face       = new Face(p3, p2, p1);
                                face.Init();
                                faces.Add(face);
                            }
                        }
                    }
                }
            }
            currentProgress += blob.height * blob.depth;
            loadProgress     = currentProgress / maxProgress;
        }
        MoveFacesToOrigin();
        m_loaded = true;
    }
示例#29
0
    /// <summary>
    /// Builds the chunk's mesh.
    /// </summary>
    public void RegenerateVisualMesh(float aVoxelScale)
    {
        //float startTime = Time.realtimeSinceStartup;
        VoxelBlob blob     = manager.m_blob;
        int3      blobSize = blob.size;

        if (sm_regenInUse)
        {
            Debug.Log("Somehow calling two regens at the same time");
            //throw new System.Exception("Cannot run two RegenerateVisualMesh at the same time. If needed, make more static RegenData");
            return;
        }
        sm_regenInUse = true;
        sm_regenData.Clear();

        needsRegen = false;

        int chunkSize = manager.chunkSize;

        for (int i = 0; i < 6; ++i)
        {
            m_hasBuild[0][i] = false;
            m_hasWater[i]    = false;
            m_hasPattern[i]  = false;
        }

        m_mesh.Clear();
        m_mesh.subMeshCount = kSubMeshCount;

        int3 currVoxel = new int3();

        bool hasFaces = false;

        int3 maxVals = blobSize - position;

        for (int i = 0; i < 3; ++i)
        {
            maxVals[i] = Mathf.Min(maxVals[i], chunkSize);
        }
        //Debug.Log("Starting main block");
        for (int z = 0; z < maxVals.z && z + position.z < blobSize.z; z += 2)
        {
            for (int y = 0; y < maxVals.y && y + position.y < blobSize.y; y += 2)
            {
                for (int x = 0; x < maxVals.x && x + position.x < blobSize.x; x += 2)
                {
                    currVoxel.x = x;
                    currVoxel.y = y;
                    currVoxel.z = z;

                    int2[][] buildIndex = new int2[kNumBuildMats][];
                    for (int i = 0; i < kNumBuildMats; ++i)
                    {
                        buildIndex[i] = new int2[6];
                    }
                    int2[] waterIndex   = new int2[6];
                    int2[] patternIndex = new int2[6];

                    byte voxel;

                    for (int i = 0; i < 2 && x + i + position.x < blobSize.x; ++i)
                    {
                        for (int j = 0; j < 2 && y + j + position.y < blobSize.y; ++j)
                        {
                            for (int k = 0; k < 2 && z + k + position.z < blobSize.z; ++k)
                            {
                                int3 curr = new int3(currVoxel.x + i, currVoxel.y + j, currVoxel.z + k);
                                voxel = VoxelAt(curr, blob);
                                if (voxel != 0)
                                {
                                    int2[] voxelIndex = null;
                                    switch (voxel)
                                    {
                                    case MeshManager.kVoxelWater:
                                        voxelIndex = waterIndex;
                                        break;

                                    case MeshManager.kVoxelObjectDef:
                                        voxelIndex = patternIndex;
                                        break;

                                    default:
                                        voxelIndex = buildIndex[(int)(voxel - MeshManager.kVoxelFirstMat)];
                                        break;
                                    }
                                    if (curr.x + position.x == 0 || VoxelAt(curr.x - 1, curr.y, curr.z, blob) == 0)
                                    {
                                        voxelIndex[0][i] += (1 << (j * 2 + k));
                                    }
                                    if (curr.x + position.x == blobSize.x - 1 || VoxelAt(curr.x + 1, curr.y, curr.z, blob) == 0)
                                    {
                                        voxelIndex[1][i] += (1 << (j * 2 + k));
                                    }
                                    if (curr.y + position.y == 0 || VoxelAt(curr.x, curr.y - 1, curr.z, blob) == 0)
                                    {
                                        voxelIndex[2][j] += (1 << (k * 2 + i));
                                    }
                                    if (curr.y + position.y == blobSize.y - 1 || VoxelAt(curr.x, curr.y + 1, curr.z, blob) == 0)
                                    {
                                        voxelIndex[3][j] += (1 << (k * 2 + i));
                                    }
                                    if (curr.z + position.z == 0 || VoxelAt(curr.x, curr.y, curr.z - 1, blob) == 0)
                                    {
                                        voxelIndex[4][k] += (1 << (i * 2 + j));
                                    }
                                    if (curr.z + position.z == blobSize.z - 1 || VoxelAt(curr.x, curr.y, curr.z + 1, blob) == 0)
                                    {
                                        voxelIndex[5][k] += (1 << (i * 2 + j));
                                    }
                                }
                            }
                        }
                    }

                    for (int i = 0; i < kNumBuildMats; ++i)
                    {
                        GenNegXFaces(currVoxel, ref hasFaces, m_hasBuild[i], buildIndex[i], m_buildOffsets[i]);
                        GenPosXFaces(currVoxel, ref hasFaces, m_hasBuild[i], buildIndex[i], m_buildOffsets[i]);
                        GenNegYFaces(currVoxel, ref hasFaces, m_hasBuild[i], buildIndex[i], m_buildOffsets[i]);
                        GenPosYFaces(currVoxel, ref hasFaces, m_hasBuild[i], buildIndex[i], m_buildOffsets[i]);
                        GenNegZFaces(currVoxel, ref hasFaces, m_hasBuild[i], buildIndex[i], m_buildOffsets[i]);
                        GenPosZFaces(currVoxel, ref hasFaces, m_hasBuild[i], buildIndex[i], m_buildOffsets[i]);
                    }

                    GenNegXFaces(currVoxel, ref hasFaces, m_hasWater, waterIndex, kWaterOffset);
                    GenNegXFaces(currVoxel, ref hasFaces, m_hasPattern, patternIndex, kPatternOffset);
                    GenPosXFaces(currVoxel, ref hasFaces, m_hasWater, waterIndex, kWaterOffset);
                    GenPosXFaces(currVoxel, ref hasFaces, m_hasPattern, patternIndex, kPatternOffset);

                    GenNegYFaces(currVoxel, ref hasFaces, m_hasWater, waterIndex, kWaterOffset);
                    GenNegYFaces(currVoxel, ref hasFaces, m_hasPattern, patternIndex, kPatternOffset);
                    GenPosYFaces(currVoxel, ref hasFaces, m_hasWater, waterIndex, kWaterOffset);
                    GenPosYFaces(currVoxel, ref hasFaces, m_hasPattern, patternIndex, kPatternOffset);

                    GenNegZFaces(currVoxel, ref hasFaces, m_hasWater, waterIndex, kWaterOffset);
                    GenNegZFaces(currVoxel, ref hasFaces, m_hasPattern, patternIndex, kPatternOffset);
                    GenPosZFaces(currVoxel, ref hasFaces, m_hasWater, waterIndex, kWaterOffset);
                    GenPosZFaces(currVoxel, ref hasFaces, m_hasPattern, patternIndex, kPatternOffset);
                }
            }
        }

        //Debug.Log("Finished main block");

        if (!hasFaces)
        {
            sm_regenInUse = false;
            return;
        }
        m_mesh.name     = "Visual Mesh";
        m_mesh.vertices = sm_regenData.verts.ToArray();
        for (int i = 0; i < kSubMeshCount; ++i)
        {
            if (sm_regenData.tris[i].Count > 0)
            {
                m_mesh.SetTriangles(sm_regenData.tris[i].ToArray(), i);
            }
        }
        if (m_mesh.vertexCount > 0)
        {
            manager.EnableMesh(this);
        }
        else
        {
            manager.DisableMesh(this);
        }

        m_mesh.Optimize();
        sm_regenInUse = false;
    }
示例#30
0
    IEnumerator GenColorFacesFromBlob(VoxelBlob blob)
    {
        float currentProgress = 0;
        float maxProgress     = blob.width * blob.height * blob.depth;

        loadProgress = 0;

        int3 minVals = new int3(0, 0, 0);
        int3 maxVals = new int3(blob.width, blob.height, blob.depth);

        if (blob.minVoxelBounds.x != -1)
        {
            minVals = blob.minVoxelBounds;
            maxVals = blob.maxVoxelBounds;
        }

        multicolorFaces = new List <List <Face> >();

        for (int mat = 1; mat < 5; mat++)
        {
            faces = new List <Face>();
            for (int x = minVals.x; x < maxVals.x; ++x)
            {
                for (int y = minVals.y; y < maxVals.y; ++y)
                {
                    for (int z = minVals.z; z < maxVals.z; ++z)
                    {
                        if (Scheduler.ShouldYield())
                        {
                            yield return(null);
                        }
                        if (blob[x, y, z] != mat)
                        {
                            continue;
                        }

                        //figure out if each face is a surface face
                        Vector3 block = new Vector3(x, y, z);
                        for (int dim = 0; dim < 3; ++dim)
                        {
                            for (int dir = -1; dir < 2; dir += 2)
                            {
                                Vector3 neighbor = block;
                                neighbor[dim] += dir;
                                bool onSurface = true;
                                if (blob.IsValidPoint((int)neighbor.x, (int)neighbor.y, (int)neighbor.z) &&
                                    blob[(int)neighbor.x, (int)neighbor.y, (int)neighbor.z] == mat)
                                {
                                    onSurface = false;
                                }

                                if (onSurface)
                                {
                                    int axis1 = (dir < 0 ? (dim + 2) % 3 : (dim + 1) % 3);
                                    int axis2 = (dir < 0 ? (dim + 1) % 3 : (dim + 2) % 3);

                                    Vector3 p0;
                                    if (dir < 0)
                                    {
                                        p0 = block;
                                    }
                                    else
                                    {
                                        p0 = block + Vector3.one;
                                    }

                                    Vector3 p1 = p0;
                                    p1[axis1] -= dir;
                                    Vector3 p2 = p0;
                                    p2[axis2] -= dir;
                                    Face face = new Face(p0, p1, p2);
                                    face.Init();
                                    faces.Add(face);
                                    Vector3 p3 = p1;
                                    p3[axis2] -= dir;
                                    face       = new Face(p3, p2, p1);
                                    face.Init();
                                    faces.Add(face);
                                }
                            }
                        }
                    }
                }
                currentProgress += blob.height * blob.depth;
                loadProgress     = currentProgress / maxProgress;
            }
            multicolorFaces.Add(faces);
        }

        m_loaded = true;
    }