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)
scene.sky.active = false
-- Setup camera and lighting
scene.sun.rotation = quat.eulerAngles(125, 125, 0)
assert(OrbitViewer, "Please include Cameras project as a dependency")
gViewer = scene.camera:add(OrbitViewer, vec3( 0.0, 0.5, 0.5), 8, 1, 400)
gViewer.rx=-45
gViewer.ry=45
myChest1 = Cube(scene:entity())
-- myChest2 = Cube(scene:entity(), vec3(1.8, 0.6, 0.1),vec3(0))
end
function update(dt)
scene:update(dt)
myChest1:update()
-- myChest2:update()
end
-- Called automatically by codea
function draw()
update(DeltaTime)
scene:draw()
sprite(asset.builtin.UI.Blue_Circle,CurrentTouch.x,CurrentTouch.y)
end
Cube = class()
function Cube:init(entity,pos,offset)
self.camera = scene.camera:get(craft.camera)
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)))
self.top = entity
self.top.parent = self.root
self.top.position = pos or vec3(0.1, 0.6, 0.1)
self.top:add(craft.rigidbody, STATIC)
self.top:add(craft.shape.box, vec3(0.8,0.8,0.8), offset or vec3(0.4,0.4,0.4))
local r2 = self.top:add(craft.renderer, 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)
end
function Cube:update(dt)
self.root.rotation = quat.eulerAngles(0, 0, self.angle)
self.top.rotation = quat.eulerAngles(0, 0, self.angle*80)
local a = self.top.worldPosition + vec3(0,0,-1)
local b = self.top.worldPosition + vec3(0,0,1)
scene.debug:line(a, b,color(16, 239, 5))
end
function Cube:interact()
if not self.open then
self.open = true
tween(1.6, self, {angle = 90, y=10}, {easing=tween.easing.backOut,loop = tween.loop.once })
else
self.open = false
tween(1.6, self, {angle = 0, y=0.6}, tween.easing.cubicIn)
end
end
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 = self.camera:screenToRay(vec2(touch.x, touch.y))
-- Do a raycast to check if touch is hitting the bulb
local hit = scene.physics:raycast(origin, dir, 300)
-- print(self.top.position)
if hit and hit.entity == self.top then
self:interact()
self.state = not self.state
print("Touch Began (Captured - "..touch.id..")",origin)
return true
end
elseif touch.state == ENDED and self.state then
print("Touch Ended (Captured - "..touch.id..")")
end
end