Can voxel volume blocks be solid?

It doesn’t appear that blocks in voxel volumes can be solid in the sense that they interact with the physics engine (i.e. you can’t stand on them).

The attached project may be overkill for demonstrating this (I’m sure @dave1707 could do it in under 90 lines :slight_smile: ) but it was what I had at hand.

The project shows a character either falling onto regular voxel blocks and being supported by them, or falling onto volume blocks and passing right through them; by default it starts with volume blocks, and to switch to regular voxel blocks comment out the line indicated around 42 or 43:


    --comment this out to set voxels without a volume
    if true then return end

Is there a way to make volume blocks solid so you can stand on them?

@UberGoober - if the block as an entity can not be solid is it possible for each side of the box to be treated as solid - as an entity plane?

@UberGoober Not sure if this is anything you can use, I made this long ago when I was playing with Voxels. It’s the Frog moving across some random Voxel terrain.

viewer.mode=FULLSCREEN

function setup()
    cnt,x1,z1=0,0,0
    assert(OrbitViewer, "Please include Cameras as a dependency")    
    scene = craft.scene() 
    v=scene.camera:add(OrbitViewer,vec3(0,20,0),30,0,2000)
    
    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,offsetZ=2,1    
    dirtLevel=80
    grassLevel=50
    waterLevel=7    
    val=400
    m=1/val
    h=craft.noise.perlin()
    for x=1,val do
        for z=1,val do  
            y=math.abs(h:getValue(x*m+offsetX,0,z*m+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
    
    frog = scene:entity()
    local a = frog:add(craft.volume)
    a:load(asset.documents.Craft.Froggy.Player_cvox)
    frog.scale = vec3(1,1,1) * 0.09
end

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

function draw()
    update(DeltaTime)
    scene:draw()
    cnt=cnt+1
    if cnt>60 then
        cnt=0
        x1=x1+1
        z1=40
    end
    y1=math.abs(h:getValue(x1*m+offsetX,0,z1*m+offsetZ))*100//1
    frog.position = vec3(x1,y1+1,z1)  
end

@dave1707 I think in that example you’re using voxels directly and not as part of a volume. I’m specifically talking about voxels in a volume.

@UberGoober I’ll look up volume and see what that’s about. I don’t think I’ve messed with it or else I forgot about it.

I forget where the original of this is, but this project contains many versions of a thing you did with volumes.

@UberGoober I totally forgot about the volume:set when creating those cubes. But I guess it would be the same thing I’m doing with the Frog. I’m recalculating where a Voxel would be and staying just above it. If a block isn’t a solid object then create a table of block positions and use that to position anything around it. Or you could create a physics wall to cover any open voxel edge.

Those seem like good alternate ways of creating solid surfaces.

It’s just odd to me that the base voxel system and the volume system use the exact same block objects, not to mention that (one assumes) the volume system is built on top of the base voxel system, but the blocks are solid in one case and not in the other case.

@John, given that voxel blocks have the properties necessary to be solid in the base voxel system, is there any way of activating those properties when used in volumes—and not for nothing, having solid volume-based blocks would greatly increase their usefulness in games, given that you can independently rotate and position volumes freely, and you can’t do that with the base voxel system.

I’ve been studying block usage for a while, and I’ve noticed that the difference between volume and blocks is that the former only provides the same visual appearance as the latter, but doesn’t store the latter’s behavioral properties. In other words, a volume model does not include physical simulations.

@binaryblues you seem to have done the most in-depth examination of the voxel system, and it’s actually quite heartening that you judged it to be a pretty good system overall.

Since all voxel blocks can be scripted, it seems like it might not be too hard to write a script that automatically attaches a physics body cube to a block, but @John warns in his documentation that scripting should be used only sparingly, because it eats up memory like crazy.

In your experience, would a script that adds rigidbodies to every voxel just figuratively explode Codea?

@UberGoober You get the point. Indeed, the complexity of a custom block can affect the stability of your application. The more complex a block is, the more resource intensive it is and the more likely it is to crash. I just collected some voxel system documentation and experimented with it, and it’s a great visualization tool. But perhaps because of the steep learning curve and the lack of documentation, there aren’t many user-initiated projects. You can see the experimental code I posted earlier on voxel systems. In fact, the rigidbody is the default configuration for each voxel block (except for glass and water, which are two types of blocks that can pass right through, perhaps without attaching to the rigid body) , since each voxel block must be able to be mined, can be an obstacle.

Below is an example, you can change the radius to see the max value


-- ExEzBlocks
-- ?????????

-- viewer.mode = FULLSCREEN_NO_BUTTONS
viewer.mode = FULLSCREEN

function setup()
    scene = craft.scene()
    
    -- ?? OrbitViewer????? voxels ???????????????????????????
    player = scene.camera:add(OrbitViewer, vec3( 40, 20, -10), 80, 1, 900)
    
    -- ?? voxel ????:???????
    scene.voxels:resize(vec3(5,1,5))      
    scene.voxels.coordinates = vec3(0,0,0)    
    
    -- ????? block type
    scene.voxels.blocks:addAssetPack("Blocks")
    
    grass = scene.voxels.blocks:new("myGrass")
    print(type(grass.id))
    grass.setTexture(ALL, "Blocks:Dirt")
    grass.setColor(ALL, color(239, 222, 5))
    
    blinky()
    -- ?? craft.voxels ??????? block type:SOLID
    scene.voxels:fill("myGrass")
    -- ?????? SOLID ????????????????
    scene.voxels:box(0,0,0, 16*8,1,16*8)
    
    -- try set radius to 12,13,14,15,16,17 
    radius = 17
    scene.voxels:fill("Blinky")
    scene.voxels:sphere(40,50,90,radius)
    
    scene.voxels:fill("Blinky")
    scene.voxels:line(10,20,0,10,50,30)
    scene.voxels:block(vec3(30,20,35))
    
    -- ???? block type ??
    scene.voxels:fill("myGrass")
    scene.voxels:block(vec3(40,20,35))
    
    -- ????block
    grass.update = function(entity, dt)
        print("uuuuu")
        entity.y = math.sin(ElapsedTime)
    end
    
    grass.destroyed = function(entity)
        sound(SOUND_POWERUP)
    end
    
    
    craft.scene.main = scene
end

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

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


-- ???????? block type ??
-- ??????block
function blinky()
    local Blinky = scene.voxels.blocks:new("Blinky")
    Blinky.setTexture(ALL, "Blocks:Stone")
    -- Blinky.setColor(ALL, color(239, 222, 5))
    Blinky.geometry = TRANSLUCENT
    Blinky.renderPass = TRANSLUCENT
    Blinky.tinted = true
    Blinky.dynamic = true
    Blinky.scriped = true
    
    -- the internal script
    function Blinky:created()
        -- Schedule an update in one second
        self:schedule(60)
        -- self:blockUpdate(60)
    end
    
    function Blinky:blockUpdate(ticks)
        -- Create a random color
        -- local x,y,z = self:xyz()
        -- print("----")
        local randomColor = color(math.random(128,255), math.random(128,255), math.random(128,255))
        -- Blinky.setColor(ALL, randomColor)
        -- Blinky.setColor(DOWN, randomColor)
        -- set block color and then schedule another update in one second

        -- self:set(vec3(x,y,z),COLOR, randomColor)
        self:set(COLOR, randomColor)
        self:schedule(10)
    end  
end

@binaryblues I feel ignorant of the reason for all the Asian characters in the code…

@binaryblues I don’t remember if you were on the forums when I was also pointing out the dearth of voxel projects—are you aware I made an alternate block library that implemented more blocks than the original?

@UberGoober Don’t worry about the characters, they’re just comments. I went through almost all the voxel-related articles on the forum, including yours, and downloaded and experimented with your projects to learn how to use your resources (make sure you have an info.plist file, for example)
And some interesting volume models, like castles, bears, soldiers with shields, etc. , I don’t know if you created them or someone else did, but they inspired me a lot.

@UberGoober If you double tap on the characters and then highlight them, you’ll get a popup bar that has translate on it. Use that to read them. I use translate for any text I get that’s not English. A lot of discussions will show up here in foreign languages and I select some of the text to translate it before I delete them.

@binaryblues I made those models, I’m glad you liked them! I don’t get what you meant about info.plist…

@binaryblues on my iPhone 8 this is all I see when I run the above code.

@UberGoober The info.plist file is needed in your custom asset folder, at first, I dont know this rule, and my custom block asset cannot take effect, after read your post, I got it.

Pls try to change these line to below:

    -- try set radius to 12,13,14,15,16,17 
    radius = 8
    scene.voxels:fill("Blinky")
    scene.voxels:sphere(40,20,80,radius)

If it still dont show the sphere, make the radius more smaller untill it can show.

In your device, the plane cannot be drawn in one piece? Means we’re running out of memory.

@binaryblues ok it’s working now. But even setting the radius to 9 causes incomplete rendering.

Why did you include a grass.update function and a grass.destroy function—they don’t seem to be called ever?

I have to say it’s a little stunning how fast the memory runs out with scripted blocks—without scripted blocks Codea can render a volume containing a 400x400x400-voxel box without any trouble.