Codea Craft 2.5 (84) Beta - Updated 8/9/2017

Hi @dave1707 - retired myself and until recently had a reasonable time to play now I have to make the time. As far as Codea Craft goes I’m like you need to get a grounding in the basics.

@John it could be useful for a few of us if you could provide, or point us to, any documentation/code that outlines what is needed in the virtual 3D world involved with Codea Craft (possibly something from Minecraft?)

@Bri_G I’m currently working on a manual and some fairly simple step-by-step example projects to demonstrate the basic 3D features and how they work.

If you want to display a cube on the screen, this would be a simple example project:

-- Make sure to enable Craft in the dependency settings
function setup()  
  cube = craft.entity()
  
  -- Create a basic unit cube mesh
  local cubeMesh = craft.mesh.cube(vec3(1,1,1))
  
  -- Add the renderer component, which will actually draw our mesh
  renderer = cube:add(craft.renderer, cubeMesh)
 
  -- Apply a material to the cube
  renderer.material = craft.material("Materials:Standard")
  -- Use renderer.material.map to apply a texture
  
  -- Move the camera forwards and rotate 180 degrees
  craft.scene.camera.position = vec3(0,0,10)
  craft.scene.camera.rotation = quat.eulerAngles(0,0,180)
end

function update()
  local r = ElapsedTime * 45
  cube.rotation = quat.eulerAngles(r,r,r)
end

function draw()
end

craft.scene gives you access to some basic built-in objects such as camera, sun and sky, which you can use to alter lighting, the camera and the background. Each of those are entities so you have to get components from them which you can then modify (such as making the camera orthographic, changing the sun into a point light or setting the sky color). This will all be in the documentation soon in addition to the manual and some tutorial videos.

@John Thanks for the little demo. I was trying to take one of the examples and chop it down to bare minimum, but l didn’t have any luck. I see that the draw function isn’t needed for Craft. Can’t wait for the manual, documentation, and the tutorials because there seems to be a lot going on that doesn’t make sense.

@John I modified your code a bit to experiment with physics, but I get an error whenever I try to call applyForce on the cube. Is it one of the things that isn’t implemented yet?

Also, I can’t future out the material.map feature, could you explain how it works/is going to work?

Aaand, I’ll answer my own question because I actually read the example code now. To apply force to an object, you’ve got to put the cube rigidbody in a variable and apply force to that variable.

cubep = cube:add(craft.rigidbody, DYNAMIC, 1)
cubep:applyForce(vec3(100,100,0))

And the reason the material.map didn’t work is because the asset I assigned it didn’t exist. Hmm.

@Attila717 Good job. I hope the manual and documentation comes out soon.

Here’s the above program with some changes as I experiment. I changed some of the names to make it easier for me to understand. Hope the manual comes out soon.

-- Make sure to enable Craft in the dependency settings

displayMode(FULLSCREEN)

function setup()  
    c1 = craft.entity()
    c2 = craft.entity()
    
    -- Create a basic unit cube mesh
    local c1Mesh = craft.mesh.cube(vec3(1,12,3))
    local c2Mesh = craft.mesh.cube(vec3(8,2,1))
    
    -- Add the renderer component, which will actually draw our mesh
    local r1 = c1:add(craft.renderer, c1Mesh)
    local r2 = c2:add(craft.renderer, c2Mesh)
    
    -- Apply a material to the cube
    r1.material = craft.material("Materials:Specular")
    r1.material.diffuse = color(0, 19, 255, 255)
    r1.material.specular = color(0, 206, 255, 255)
    
    r2.material = craft.material("Materials:Specular")
    r2.material.diffuse = color(255,0,0)
    r2.material.specular = color(0, 255, 0, 255)
    
    -- Set camera position
    craft.scene.camera.position = vec3(0,0,15)
    craft.scene.camera.rotation = quat.eulerAngles(0,0,180)
end

function update()
    local r = ElapsedTime * 15
    c1.rotation = quat.eulerAngles(r*2,r,r)
    c2.rotation = quat.eulerAngles(r,r*3,-r)
end

I guess I’ll share my code based off this example too. I’ve got most of the basic physics down and a lot of comments to explain what I’ve learned.

-- Make sure to enable Craft in the dependency settings
function setup()  
  -- for fps function
  frame = 0
  etime = 0 
  parameter.watch("fps")
    
  -- positions in space
  cubexyz = vec3(0,5,0)
  platformxyz = vec3(0,-5,0)
    
  -- init two entities, cube and platform
  cube = craft.entity()
  platform = craft.entity()

  -- Create a basic unit cube mesh
  local cubeMesh = craft.mesh.cube(vec3(1,1,1))
  local platformMesh = craft.mesh.cube(vec3(8,1,8))

  -- Add the renderer component, which will actually draw our mesh
  renderer = cube:add(craft.renderer, cubeMesh)
  renderer2 = platform:add(craft.renderer, platformMesh)
    
  -- move cubes to certain positions and rotate the cube a bit
  cube.y = cubexyz.y
  platform.y = platformxyz.y
  local r = 45
  cube.rotation = quat.eulerAngles(r,r,r)
    
  -- add physics collision bodies
  cubep = cube:add(craft.rigidbody, DYNAMIC, 0.5)
  platform:add(craft.rigidbody, STATIC)
    
  -- give a shape to the collision area
  -- for box, first argument is shape, second is dimentions of the bounding box, and third is the offset from your mesh
  cube:add(craft.shape.box, vec3(1,1,1), vec3(0,0,0))
  platform:add(craft.shape.box, vec3(8,1,8), vec3(0,0,0))

  -- Apply a material to the cube
  renderer.material = craft.material("Materials:Standard")
  renderer2.material = craft.material("Materials:Standard")
    
  -- Use renderer.material.map to apply a texture
  renderer.material.map = "Blocks:Greystone"
  renderer2.material.map = "Blocks:Wood Red"
    
  -- bounciness doesn't seem to work yet
  cubep.restitution = 50

  -- Move the camera forwards and rotate 180 degrees
  craft.scene.camera.position = vec3(0,0,15)
  craft.scene.camera.rotation = quat.eulerAngles(0,0,180)
end

function update()
  -- I think this is called every time the physics engine updates
    fpsEval()
end

function fpsEval()
    -- just counting fps
    frame = frame + 1
    etime = etime + DeltaTime
    fps = math.floor(frame/etime+.5)
end

function draw()
    -- Nothing happening here D:
end

function touched(touch)
    if touch.state == BEGAN then
        -- wake up cube every time a touch registers
        cubep.awake = true
        if touch.x > WIDTH/3*2 then
            -- apply force to cube (up and right)
            cubep:applyForce(vec3(75,75,0))
        elseif touch.x < WIDTH/3 then
            -- apply force to cube (up and left)
            cubep:applyForce(vec3(-75,75,0))
        else
            -- apply force to cube (up)
            cubep:applyForce(vec3(0,75,0))
        end
    end
end

@Attila717 Nice job. You’re getting good experience with your coding.

@dave1707 Thanks! I’m always trying to improve

Hey everyone

I’m currently working on the manual for Craft. The current work-in-progress version can be found here:

https://twolivesleft.com/CodeaCraft/Manual

@John The manual is looking great so far! Do you think you could elaborate a bit more on the inner workings of the Generate Terrain tab? It’d be nice to know more about how the split, warp, and hills functions work.

Also, I nocticed a thin line of transparency between blocks in the Block Library, Voxel Player, and Voxel Terrain projects. Is that a bug? A feature? Something that could be turned off?

Still playing with physics…

@Simeon @John Is it possible to assign an icosphere mesh collision shape

sphere:add(craft.shape.mesh, craft.mesh.icoSphere(1,1))

to an icosphere with a rigidbody and still let it rotate on its axis(s) like if I assigned it a sphere collision shape

sphere:add(craft.shape.sphere, 1, vec3(0,0,0))

?

I noticed the word “quaternion” fly by in Codea Craft. I’m going to be exploring that to see how much it can replace my old code.

Just in case it’s of any interest, my Quaternion write-up is now at:

http://loopspace.mathforge.org/HowDidIDoThat/Codea/Quaternions/

@LoopSpace I just did a quick pass of your writeup, looks interesting. I’ll have to spend more time reading it later on.

@dave1707 Any comments for making it clearer would be gratefully received.

@John, I notice that there aren’t many methods available for quat. I have quite an extensive quaternion library for Codea on github (written as an extension of the native vec4). Feel free to steal ideas. As a start, I think that quat() with no arguments should return the quaternion 1 + 0i + 0j + 0k as that corresponds to the identity rotation.

@John @Simeon I’ve found a bug, probably in the 3d physics engine, that crashes Codea. When I run the Planet 3D project with only a minor change and then refresh a number of times, Codea crashes. I’ve been able to recreate this bug three times so I’m pretty sure it’s not a fluke.

(The change was that I uncommented these two lines:

pivot:add(craft.rigidbody, DYNAMIC)
pivot:add(craft.shape.box, bs, vec3(0, bs.y * 0.5, 0))

)

Thanks @Attila717 I have a physics bug fix in the pipeline, hopefully it will address this exact issue:

@LoopSpace I will have a look at your library. Defaulting to the identity is probably a good idea, cheers!

@John Thanks for looking at the bug. I’m still wondering wether the mesh shape can roll and react to being hit like the box and sphere shapes do. When I tried using the mesh shape, it collided well, but stayed frozen in the same rotation. Is this a bug?

@Attila717 mesh shapes should only be used with kinematic or static rigidbodies (this is a bullet limitation).

There is a thing called btGImpactMeshShape which could work for dynamic bodies so I might look into that.

I’m also going to add shape.hull which would allow for optimised dynamic mesh shapes that are convex.