Howdy, Stranger!

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

When an object rotates around an axis not ve3(0,0,0), the craft.physics miscalculates its position

edited January 5 in Bugs Posts: 298

I just found a bug in the craft.physics, using the craft.model.cube, setting the offset to vec3(0.4,0.4,0.4) and rotating, the craft.physics calculated the wrong position, and could not handle the collision correctly, the Blue Dot in the video is the click position, after rotating click object invalid, click next to it in the white space, will trigger.

Simply put, if the offset is not zero, the craft.physics calculation will go wrong after the rotation

The test code:


function setup()
    -- Create a new craft scene
    scene = craft.scene()
    scene.ambientColor = color(218, 158, 79) = false

    -- Setup camera and lighting
    scene.sun.rotation = quat.eulerAngles(125, 125, 0)

    assert(OrbitViewer, "Please include Cameras project as a dependency")
    gViewer =, vec3( 0.0,  0.5,  0.5), 8, 1, 400)

    myChest1 = Cube(scene:entity())   
    -- myChest2 = Cube(scene:entity(), vec3(1.8, 0.6, 0.1),vec3(0)) 

function update(dt)
    -- myChest2:update()

-- Called automatically by codea 
function draw()

Cube = class()

function Cube:init(entity,pos,offset) =
    self.state = true
    self.root = scene:entity()
    self.root.position = vec3(x,y,z) or vec3(1.5, 0.3, 0.5)
    local r0 = self.root:add(craft.renderer, craft.model.cube(vec3(0.8,0.2,0.8),vec3(0.3,0.1,0.4))) = entity = self.root = pos or vec3(0.1, 0.6, 0.1), STATIC), vec3(0.8,0.8,0.8), offset or vec3(0.4,0.4,0.4))
    local r2 =, craft.model.cube(vec3(0.8,0.8,0.8),offset or vec3(0.4,0.4,0.4)))
    r2.material = craft.material(asset.builtin.Materials.Specular)
    r2.material.diffuse = color(135, 178, 28)
    self.angle = 0
    self.y = 0.6

    touches.addHandler(self, -1, false)

function Cube:update(dt)
    self.root.rotation = quat.eulerAngles(0,  0, self.angle) = quat.eulerAngles(0,  0, self.angle*80)

    local a = + vec3(0,0,-1)
    local b = + vec3(0,0,1)
    scene.debug:line(a, b,color(16, 239, 5))    

function Cube:interact()
    if not then = true
        tween(1.6, self, {angle = 90, y=10}, {easing=tween.easing.backOut,loop = tween.loop.once })
    else = false
        tween(1.6, self, {angle = 0, y=0.6}, tween.easing.cubicIn)

function Cube:touched(touch)
    if touch.state == BEGAN then

        -- Returning true will capture this touch and prevent other handlers from getting it
        local origin, dir =, touch.y))

        -- Do a raycast to check if touch is hitting the bulb
        local hit = scene.physics:raycast(origin, dir, 300)
        -- print(
        if hit and hit.entity == then
            self.state = not self.state
            print("Touch Began (Captured - "")",origin)
            return true
    elseif touch.state == ENDED and self.state then
        print("Touch Ended (Captured - "")")


  • dave1707dave1707 Mod
    Posts: 10,049

    @binaryblues Modified a program I have using a parent and it looks like I got the same results.

    Ignore my other post I deleted if you saw it.

  • Posts: 298

    @dave1707 Thank you so much for the extension, and I did exactly what you said. Inspired by you, I wonder if scale has the same problem. After all, they are all calculated by the same matrix. I will do a test on scale later.
    Btw. That’s the only response I saw.

  • dave1707dave1707 Mod
    Posts: 10,049

    @Simeon @binaryblues Here’s another example that shows the problem with rotation around a parent object. Run the code and slide the blue parameter all the way left. The blue box tilts and the ball bounces to the left. Do the same for the other 2 sliders. The balls bounce left as they should.

    Run the code again but this time slide the green parameter. The green and blue boxes tilt and the green box ball bounces left but the blue one doesn’t.

    Run the code again and slide the red parameter. All the boxes tilt but only the red box ball bounces correctly.

    The children don’t seem to work correctly when a parent is moved.

    I guess that’s just the way kids are, they never want to do what their parents want.

    function setup() parameter.number("red",-10,0,0) parameter.number("green",-10,0,0) parameter.number("blue",-10,0,0) scene = craft.scene() = false = -30 s1=createSphere(vec3(0,8,0),DYNAMIC) s2=createSphere(vec3(-4,8,4),DYNAMIC) s3=createSphere(vec3(-8,7,8),DYNAMIC) c1=scene:entity() w1=c1:add(craft.rigidbody,STATIC) w1.restitution=1 c1.position=vec3(0,-4,0) c1.model = craft.model.cube(vec3(3,1,3)) c1:add(craft.shape.model,c1.model) c1.material = craft.material(asset.builtin.Materials.Standard) c1.material.diffuse = color(255,0,0) c2=scene:entity() w2=c2:add(craft.rigidbody,STATIC) w2.restitution=1 c2.position=vec3(-4,2,4) c2.model = craft.model.cube(vec3(3,1,3)) c2:add(craft.shape.model,c1.model) c2.material = craft.material(asset.builtin.Materials.Standard) c2.material.diffuse = color(0,255,0) c3=scene:entity() w3=c3:add(craft.rigidbody,STATIC) w3.restitution=1 c3.position=vec3(-4,2,4) c3.model = craft.model.cube(vec3(3,1,3)) c3:add(craft.shape.model,c1.model) c3.material = craft.material(asset.builtin.Materials.Standard) c3.material.diffuse = color(0,0,255) c2.parent=c1 c3.parent=c2 end function update(dt) c1.eulerAngles=vec3(0,0,red) c2.eulerAngles=vec3(0,0,green) c3.eulerAngles=vec3(0,0,blue) scene:update(dt) end function draw() update(DeltaTime) scene:draw() end function createSphere(pos,typ) local sphere1=scene:entity() local s1=sphere1:add(craft.rigidbody,typ) s1.restitution=1 sphere1.position=pos sphere1.model = craft.model.icosphere(.5,1) sphere1:add(craft.shape.sphere,.5) sphere1.material = craft.material(asset.builtin.Materials.Specular) sphere1.material.diffuse=color(255) return sphere1 end
  • Posts: 298

    @dave1707 Perfect example! You dug deeper and brilliant metaphor. I think all the parents feel the same way. Thanks a lot.

    I recorded it, it’s the demo video:

Sign In or Register to comment.