Craft physics example

Here’s a little example showing Craft physics.

supportedOrientations(LANDSCAPE_ANY)

function setup()
    assert(craft, "Please include Craft as a dependency")
    assert(OrbitViewer, "Please include Cameras (not Camera) as a dependency")
    parameter.number("opac",0,.7)
    size=1
    fill(255)
    scene = craft.scene()
    skyMaterial=scene.sky.material
    skyMaterial.sky=color(0, 62, 255, 255)
    skyMaterial.horizon=color(99, 255, 0, 255)
    scene.sun.rotation=quat.eulerAngles(20,45,-30)
    createObjects()
    v=scene.camera:add(OrbitViewer, vec3(0,0,0), 30, 0, 20)
end

function createObjects()
    sphere1=scene:entity()
    s1=sphere1:add(craft.rigidbody,DYNAMIC)
    s1.linearVelocity=vec3(2,2,2)
    s1.restitution=1
    s1.friction=0
    sphere1.position=vec3(-3,3,1)
    sphere1:add(craft.shape.sphere,size)
    sphere1.model = craft.model.icosphere(size,2)
    sphere1.material = craft.material("Materials:Specular")
    sphere1.material.diffuse=color(255,0,0)
    
    sphere2=scene:entity()
    s2=sphere2:add(craft.rigidbody,DYNAMIC)
    s2.linearVelocity=vec3(3,4,3)
    s2.restitution=1
    s2.friction=0
    sphere2.position=vec3(-5,0,3)
    sphere2:add(craft.shape.sphere,size)
    sphere2.model = craft.model.icosphere(size,2)
    sphere2.material = craft.material("Materials:Specular")
    sphere2.material.diffuse=color(0,0,255)

    wall1=createWall(1,vec3(-5,0,0),vec3(.1,10,10),vec3(.1,10,10),"Blocks:Error")
    wall2=createWall(1,vec3(5,0,0),vec3(.1,10,10),vec3(.1,10,10),"Blocks:Dirt Sand")    
    wall3=createWall(1,vec3(0,-5,0),vec3(10,.1,10),vec3(10,.1,10),"Blocks:Cotton Blue")    
    wall4=createWall(1,vec3(0,0,5),vec3(10,10,.1),vec3(10,10,.1),"Blocks:Cactus Side")    
    wall5=createWall(1,vec3(0,0,-5),vec3(10,10,.1),vec3(10,10,.1),"Blocks:Brick Red")
    wall6=createWall(1,vec3(0,5,0),vec3(10,.1,10),vec3(10,.1,10),"Blocks:Brick Grey")
end

function createWall(rest,pos,a,mod,map)
    local ww=scene:entity()
    local w=ww:add(craft.rigidbody,STATIC)
    w.restitution=rest
    ww.position=pos
    ww:add(craft.shape.box,a)
    ww.model = craft.model.cube(mod)
    ww.material = craft.material("Materials:Standard")
    ww.material.map = readImage(map)
    ww.material.blendMode = NORMAL
    return ww
end

function draw()
    update(DeltaTime)
    scene:draw()	
    text("Move the slider to change opacity",WIDTH/2,HEIGHT-50)
    text("Drag your finger on the screen to rotate the cube",WIDTH/2,HEIGHT-100)
end

function update(dt)
    scene:update(dt)
    wall1.material.opacity=opac
    wall2.material.opacity=opac
    wall3.material.opacity=opac
    wall4.material.opacity=opac
    wall5.material.opacity=opac
    wall6.material.opacity=opac
end
--[[
Main:7: attempt to index a nil value (global 'craft')
stack traceback:
	Main:7: in function 'setup'

Main:68: attempt to index a nil value (global 'scene')
stack traceback:
	Main:68: in function 'update'
	Main:61: in function 'draw'
]]

I started the project. This happens.

@TokOut Anytime you use Craft, you have to check Craft as a dependency.

@dave1707 What about OrbitViewer? Am I missing something?

@JhaSeh What are you referring to about OrbitViewer. Not sure what you think you’re missing.

EDIT: Sorry @JhaSeh I forgot that cameras was included as a dependency. I added assert for the cameras in my code above.

@JhaSeh You’ll need to include the Cameras project as a dependency as well (OrbitViewer is just Lua not built into craft).

@John Is there anyway thru code to include a project without having to manually check it in the dependency list.

Dependencies are stored in the project’s Info.plist file. If you edit it, the dependency list will automatically change.

@em2 I’ve used the info.plist long ago for dependencies, but it would be nice to be able to add a line of code to include a dependency instead of requiring a user to go thru a list and check one when they don’t realize that they need to.

@dave1707 good point. Especially with Craft being dependency heavy, it’d be good to have this feature.

Thanks @dave1707 there you have it - the skybox I’ve been wanting to set up plus an old demo I’ve been wanting to imitate for a while, that will keep me busy for some time.

Hi @dave1707 , playing with your Craft demo and found something intriguing. If you place an image in the wall. Looking from the centre of the cube the image is in one orientation. From outside the cube the image is not reversed. Turning through 180 deg the external cube face remains unchanged. It looks like the system prints the same image when it gets past 90 deg.

This makes setting up a sky box a little more difficult, I find matching the external faces easier (dependent on content) from outside the cube.

@Bri_G I noticed that on the wall with the letter E when I first wrote the code. I forgot about it, but I thought someone else mentioned a similar problem.

@dave1707 noticed this whilst trying to set up a skybox in Craft. I have a normal Codea skybox which operates as expected image reversed on outside of box. Looks a bit like the Gimbal lock problem with rotation, I thought Euler angles resolved that.

If you only need a solid box viewed from the outside or a skybox viewed from inside then there is no issue, but developers are always looking for something new to visually impress. Your transparent box shows this up perfectly.

Here’s another Craft Physics Example. @Simeon @John Can you explain a problem I’m having with this example. If you rotate the image so you’re looking straight on at the high angled side, the sphere bounces off the side a little towards the right instead of straight out. If I change the starting position of the sphere ( line commented near bottom ) from -9 to -8, the sphere bounces off the high angled side straight out. Just wondering what I don’t understand that’s happening with it.

displayMode(FULLSCREEN)

function setup()
    assert(craft, "Please include Craft as a dependency")
    assert(OrbitViewer, "Please include Cameras (not Camera) as a dependency")
    fill(255)
    scene = craft.scene()
    skyMaterial=scene.sky.material
    skyMaterial.sky=color(0, 62, 255, 255)
    skyMaterial.horizon=color(99, 255, 0, 255)
    scene.sun.rotation=quat.eulerAngles(20,45,-30)
    v=scene.camera:add(OrbitViewer, vec3(0,0,0), 100, 0, 200)
    v.rx,v.ry=20,20
    createRect()
    createSphere()
end

function draw()
    update(DeltaTime)
    scene:draw()    
    text("Drag your finger on the screen to rotate the cube",WIDTH/2,HEIGHT-100)
    if sphere1.position.y<-80 then
        createSphere()
    end
end

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

function createRect() 
    diff=8
    c1=scene:entity()
    w=c1:add(craft.rigidbody,STATIC)
    w.restitution=.8
    c1.position=vec3(0,0,0)
    c1.model = craft.model.cube(vec3(25,10,10))
    c1.model:position(5,-5,diff,5)
    c1.model:position(18,-5,diff,5)
    c1.model:position(10,-5,diff,5)
    c1.model:position(9,-5,diff,-5)
    c1.model:position(14,-5,diff,-5)
    c1.model:position(19,-5,diff,-5) 
    c1:add(craft.shape.model,c1.model)
    c1.material = craft.material("Materials:Standard")
    c1.material.map = readImage("Blocks:Trunk White Top")
end

function createSphere()
    if sphere1 then
        sphere1:destroy()
    end
    sphere1=scene:entity()
    s1=sphere1:add(craft.rigidbody,DYNAMIC)
    s1.linearVelocity=vec3(0,0,0)
    s1.restitution=.8
    nxt=not nxt
    if nxt then
        sphere1.position=vec3(-4.8,10,0)
    else
        sphere1.position=vec3(-9,20,0)      -- change the -9 to -8
    end
    sphere1.model = craft.model.icosphere(.5,5)
    sphere1:add(craft.shape.sphere,.5)
    sphere1.material = craft.material("Materials:Specular")
    sphere1.material.diffuse=color(255,0,0)
end