Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Request for simple voxel example

in Questions Posts: 520
Tried to read the docs, got confused, but would like to see a small example of using voxels. How do I make a small scene with say two voxels of a solid color? The documentation is a bit confusing, and some examples on the site uses addAssetPack which isnt documented.

But I would like to just add some colored voxels to a volume without texture and try it out a bit :)

I know how to make it with meshes, but not with craft :).

Comments

  • dave1707dave1707 Mod
    Posts: 8,781

    @tnlogy Here’s an example I have that uses voxels.

    viewer.mode=FULLSCREEN
    
    function setup()
        fill(255)
        assert(OrbitViewer, "Please include Cameras (not Camera) as a dependency")
        scene = craft.scene() 
        v=scene.camera:add(OrbitViewer,vec3(50,200,0), 500, 0, 2000)
        v.camera.farPlane=10000
        v.rx=30
        v.ry=30
        scene.voxels.blocks:addAssetPack("Blocks")
        dirtgrass = scene.voxels.blocks:new("DirtGrass")
        dirtgrass.setTexture(ALL, "Blocks:Dirt Grass")
        water = scene.voxels.blocks:new("Water")
        water.setTexture(ALL, "Blocks:Water")
        snow = scene.voxels.blocks:new("Snow")
        snow.setTexture(ALL, "Blocks:Snow")
        grass = scene.voxels.blocks:new("Grass Top")
        grass.setTexture(ALL, "Blocks:Grass Top")
    
        scene.voxels.visibleRadius=30
        scene.voxels:resize(vec3(30,1,30))          
        scene.voxels.coordinates = vec3(100,0,100) 
    
        offsetX=6
        offsetZ=4
    
        dirtLevel=80
        grassLevel=50
        waterLevel=7
    
        val=400
        m=1/val
        h=craft.noise.perlin()
    
        xx,zz=0,0  
        for x=1,val do
            xx=xx+m
            zz=0
            for z=1,val do  
                zz=zz+m
                y=math.abs(h:getValue(xx+offsetX,0,zz+offsetZ))*100//1
                if y>dirtLevel then
                    scene.voxels:fill("Snow")
                    scene.voxels:block(x,y,z)
                elseif y>grassLevel then
                    scene.voxels:fill("DirtGrass")
                    scene.voxels:block(x,y,z)
                elseif y>waterLevel then
                    scene.voxels:fill("Grass Top")
                    scene.voxels:block(x,y,z)
                else
                    scene.voxels:fill("Water")
                    scene.voxels:block(x,waterLevel,z)
                end
            end
        end
    end
    
    function update(dt)
        scene:update(dt)
    end
    
    function draw()
        update(DeltaTime)
        scene:draw()
        text("Use one finger to rotate.",WIDTH/2,HEIGHT-25)
        text("Use two fingers to move or resize.",WIDTH/2,HEIGHT-50)
    end
    
  • Posts: 520
    Thanks for the code, but I wanted to know if you could make voxels of solid color or are only textured supported?
  • edited February 14 Posts: 1,958
    @tnology - have you tried the Craft demos - in one of them you can build your own scene and can build your own blocks, They are then stored in a grid for selection. I think it’s called block library. So if you check out the code you may be able to design your own project.
  • dave1707dave1707 Mod
    Posts: 8,781

    @tnlogy Heres another example that might be closer to what you want if you’re still looking for an example. I tried to keep it as small as possible. It creates a red and blue sprite in the Dropbox folder. Once the sprites are created, you can comment or remove those 2 lines.

    viewer.mode=FULLSCREEN
    
    function setup()
        --create red and blue sprite in Dropbox
        --comment out or remove the next 2 lines after the first run
        createColor("Red",color(255,0,0))
        createColor("Blue",color(0,0,255))
    
        assert(OrbitViewer, "Please include Cameras as a dependency")
    
        scene = craft.scene() 
        scene.camera:add(OrbitViewer,vec3(7,7,0), 20, 0, 10000) 
        scene.voxels.visibleRadius=90
        scene.voxels:resize(vec3(60,1,60))
        scene.voxels.coordinates = vec3(0,0,0)
    
        --add as asset packs    
        scene.voxels.blocks:addAssetPack("Blocks")
        scene.voxels.blocks:addAssetPack("Dropbox")
    
        --define Red and Blue colors       
        temp=scene.voxels.blocks:new("Red")
        temp.setTexture(ALL, "Dropbox:Red") 
    
        temp=scene.voxels.blocks:new("Blue")
        temp.setTexture(ALL, "Dropbox:Blue") 
    
        --draw 6 blocks of each color           
        for z=1,6 do
            scene.voxels:fill("Red")
            scene.voxels:block(7,z*2,0) 
    
            scene.voxels:fill("Blue")
            scene.voxels:block(z*2,7,0)
        end    
    end
    
    function update(dt)
        scene:update(dt)
    end
    
    function draw()
        update(DeltaTime)
        scene:draw()
    end
    
    function createColor(name,col)
        img=image(128,128)
        setContext(img)
        background(col)
        setContext()
        saveImage(asset.documents.Dropbox..name,img)
    end
    
  • edited February 14 Posts: 520
    Thanks! After seeing your example and digging in some example code it made a new version

    ~~~

    viewer.mode=FULLSCREEN

    function setup()
    assert(OrbitViewer, "Please include Cameras as a dependency")

    scene = craft.scene() scene.camera:add(OrbitViewer,vec3(7,7,0), 20, 0, 10000)
    scene.voxels.visibleRadius=90
    scene.voxels:resize(vec3(60,1,60))
    scene.voxels.coordinates = vec3(0,0,0)
    blank = scene.voxels.blocks:new("Blank")
    blank.setTexture(ALL, "Blocks:Blank White")
    blank.tinted = true


    --draw 6 blocks of each color
    for z=1,6 do
    local c = color(255, 0, 106)
    scene.voxels:set(7,z*2,0,"name","Blank","color", c)
    c = color(20, 0, 255)
    scene.voxels:set(z*2,7,0,"name","Blank","color", c)
    end
    end

    function update(dt)
    scene:update(dt)
    end

    function draw()
    update(DeltaTime)
    scene:draw()
    end

    ~~~

    This uses tinted instead. I find the documentation for Craft a bit lacking and confusing compared to the documentation of the other parts of Codea. Thanks a lot for the help in understanding!
  • dave1707dave1707 Mod
    Posts: 8,781

    @tnlogy I like your version. I never used voxels:set, so something new. I agree that the docs sometimes don’t give enough info on how to use things.

  • Posts: 520
    Seems like you can to like this also:

    ~~~

    scene.voxels:fill("name","Blank",
    "color",color(154, 233, 80))
    scene.voxels:block(7,z*2,1)

    ~~~
  • dave1707dave1707 Mod
    edited February 15 Posts: 8,781

    @tnlogy Heres an example of a Sierpinski cube using the voxel color code you used above. Uncomment the color lines near the bottom of the code to see different color schemes.

    viewer.mode=FULLSCREEN
    
    function setup()
        ss=27         -- cube size, powers of 3 only (3, 9, 27, 81)
        fill(255)
        assert(OrbitViewer, "Please include Cameras (not Camera) as a dependency")
        scene = craft.scene() 
        scene.voxels.visibleRadius=90
        scene.voxels:resize(vec3(30,1,30))
        scene.voxels.coordinates = vec3(ss,ss,ss)
        v=scene.camera:add(OrbitViewer,vec3(ss,ss,ss), ss*3, 0, 6000) 
        v.rx=45
        v.ry=45    
        blank = scene.voxels.blocks:new("Blank")
        blank.setTexture(ALL,"Blocks:Blank White")
        blank.tinted=true        
        count=0
        cube(0,0,0,ss)
    end
    
    function update(dt)
        scene:update(dt)
    end
    
    function draw()
        update(DeltaTime)
        scene:draw()
        text("Cube size "..ss.."x"..ss.."x"..ss.." = "..(ss^3).." cubes",WIDTH/2,HEIGHT-25)
        text("Number of cubes drawn "..count,WIDTH/2,HEIGHT-50)
        text("Sierpinski cube",WIDTH/2,HEIGHT-75)
    end
    
    function cube(x,y,z,size)
        local s=size//3
        for x1=-s,s,s do
            for y1=-s,s,s do
                for z1=-s,s,s do
                    if (y1~=0 or z1~=0) and (x1~=0 or z1~=0) and (x1~=0 or y1~=0) then
                        if size~=3 then
                            cube(x1+x,y1+y,z1+z,s)
                        else
                            count=count+1
                            r=255//(x1+s+1)
                            g=255//(y1+s+1)
                            b=255//(z1+s+1)
                            c=color(r,g,b)        
                            --c=color(200,200,200)   
                            --c=color(math.random(255),math.random(255),math.random(255))
                            scene.voxels:set((x1+x+ss),(y1+y+ss),(z1+z+ss),
                                    "name","Blank","color", c)
                        end
                    end
                end
            end
        end
    end
    
  • Posts: 520
    Nice! :)
Sign In or Register to comment.