diff --git a/class/boids/controls/AbsoluteControls.lua b/class/boids/controls/AbsoluteControls.lua index 69cd5cd..373dec2 100644 --- a/class/boids/controls/AbsoluteControls.lua +++ b/class/boids/controls/AbsoluteControls.lua @@ -1,56 +1,58 @@ --[[ * Absolute control scheme Cellulo acts like a mouse ]]-- local global = require "global" local AbsoluteControls = (class "boids.controls.Controls"):subclass("AbsoluteControls") local CELLULO_ABSOLUTE_SPEED = 0.04 local CELLULO_MAX_HAPTIC_FORCE = 20 local CELLULO_HAPTIC_FACTOR = 10 function AbsoluteControls.static:applyMovement(boid, dt) -- move continuously local kidnapped = boid:getCellulo():getKidnapped() if kidnapped then boid.ox, boid.oy, boid.oa = nil, nil, nil end if not kidnapped then if boid.ox and boid.oy and boid.oa then local da = boid:getCellulo():getTheta() - boid.oa da = math.atan2(math.sin(da), math.cos(da)) local angle = boid:getAngle() angle = angle - da -- no need for dt? boid:setAngle(angle) local dx, dy = boid:getCellulo():getX() - boid.ox, boid:getCellulo():getY() - boid.oy local x, y, z = boid:getCollider():getPosition() dx, dy = util.rotateVector(dx, dy, -global.camera:getAngle()) x, z = x + dx * CELLULO_ABSOLUTE_SPEED, z + dy * CELLULO_ABSOLUTE_SPEED boid:setPosition(x, y, z) boid:getCollider():setPosition(x, y, z) end -- set origin boid.ox, boid.oy, boid.oa = boid:getCellulo():getX(), boid:getCellulo():getY(), boid:getCellulo():getTheta() end end function AbsoluteControls.static:applyHapticFeedback(boid, dt, dir) dir:mul(CELLULO_HAPTIC_FACTOR) if dir:length() > CELLULO_MAX_HAPTIC_FORCE then dir:normalize() dir:mul(CELLULO_MAX_HAPTIC_FORCE) end local dx, dy, dz = dir:unpack() dx, dz = util.rotateVector(dx, dz, global.camera:getAngle()) boid:getCellulo():setGoalVelocity(dx, dz, 0) -end \ No newline at end of file +end + +return AbsoluteControls \ No newline at end of file diff --git a/class/boids/controls/Controls.lua b/class/boids/controls/Controls.lua index cd69f87..2db71ca 100644 --- a/class/boids/controls/Controls.lua +++ b/class/boids/controls/Controls.lua @@ -1,5 +1,7 @@ local Controls = lib "class" ("Controls") function Controls.static:applyMovement(boid, dt) end -function Controls.static:applyHapticFeedback(boid, dt) end \ No newline at end of file +function Controls.static:applyHapticFeedback(boid, dt) end + +return Controls \ No newline at end of file diff --git a/class/boids/controls/HybridControls.lua b/class/boids/controls/HybridControls.lua index 449ef3d..e786eea 100644 --- a/class/boids/controls/HybridControls.lua +++ b/class/boids/controls/HybridControls.lua @@ -1,60 +1,62 @@ --[[ * Hybrid control scheme Cellulo acts like a joystick position-wise, and goes back to the center when it's released. Rotation-wise, it acts like the absolute control scheme. ]]-- local global = require "global" local HybridControls = (class "boids.controls.Controls"):subclass("HybridControls") local CELLULO_RELATIVE_SPEED = 5 local CELLULO_RELATIVE_ROTATION_SPEED = 2 local CELLULO_MAX_HAPTIC_FORCE = 20 local CELLULO_HAPTIC_FACTOR = 10 local CELLULO_RELATIVE_TARGET = { x = 0, y = 0 } function HybridControls.static:applyMovement(boid, dt) -- move like the cellulo was a joystick thumb, origin of the paper acting as neutral if not kidnapped then -- relative position local x, y, z = boid:getCollider():getPosition() local dx, dy = boid:getCelluloPlane():normalizedRelative(boid:getCellulo():getX(), boid:getCellulo():getY()) dx, dy = util.rotateVector(dx, dy, -global.camera:getAngle()) x, z = x + dx * CELLULO_RELATIVE_SPEED * dt, z + dy * CELLULO_RELATIVE_SPEED * dt boid:setPosition(x, y, z) boid:getCollider():setPosition(x, y, z) -- absolute rotation local da = boid:getCellulo():getTheta() - boid.oa da = math.atan2(math.sin(da), math.cos(da)) local angle = boid:getAngle() angle = angle - da -- no need for dt? boid:setAngle(angle) -- force cellulo back to center (haptic) local tx, ty = boid:getCelluloPlane():normalizedRelativeToAbsolute(CELLULO_RELATIVE_TARGET.x, CELLULO_RELATIVE_TARGET.y) boid:getCellulo():setGoalPosition(tx, ty, 100) end end function HybridControls.static:applyHapticFeedback(boid, dt, dir) if dir:length() > 1 then dir:mul(CELLULO_HAPTIC_FACTOR) if dir:length() > CELLULO_MAX_HAPTIC_FORCE then dir:normalize() dir:mul(CELLULO_MAX_HAPTIC_FORCE) end dir:div(CELLULO_MAX_HAPTIC_FORCE) local dx, dy, dz = dir:unpack() dx, dz = util.rotateVector(dx, dz, global.camera:getAngle()) dx, dz = dx / 2, dz / 2 dx, dz = boid:getCelluloPlane():normalizedRelativeToAbsolute(dx, dz) boid:getCellulo():setGoalPosition(dx, dz, 100) end -end \ No newline at end of file +end + +return HybridControls \ No newline at end of file diff --git a/class/boids/controls/RelativeControls.lua b/class/boids/controls/RelativeControls.lua index 4fc31ca..aad5f0c 100644 --- a/class/boids/controls/RelativeControls.lua +++ b/class/boids/controls/RelativeControls.lua @@ -1,50 +1,52 @@ --[[ * Relative control scheme Cellulo acts like a joystick ]]-- local global = require "global" local RelativeControls = (class "boids.controls.Controls"):subclass("RelativeControls") local CELLULO_RELATIVE_SPEED = 5 local CELLULO_RELATIVE_ROTATION_SPEED = 2 local CELLULO_MAX_HAPTIC_FORCE = 20 local CELLULO_HAPTIC_FACTOR = 10 function RelativeControls.static:applyMovement(boid, dt) -- move like the cellulo was a joystick thumb, origin of the paper acting as neutral if not kidnapped then local x, y, z = boid:getCollider():getPosition() local dx, dy = boid:getCelluloPlane():normalizedRelative(boid:getCellulo():getX(), boid:getCellulo():getY()) dx, dy = util.rotateVector(dx, dy, -global.camera:getAngle()) x, z = x + dx * CELLULO_RELATIVE_SPEED * dt, z + dy * CELLULO_RELATIVE_SPEED * dt local angle = boid:getAngle() local da = boid:getCellulo():getAngle() if da > math.pi then da = -2*math.pi + da end angle = angle + (-da) * CELLULO_RELATIVE_ROTATION_SPEED * dt boid:setPosition(x, y, z) boid:getCollider():setPosition(x, y, z) boid:setAngle(angle) end end function RelativeControls.static:applyHapticFeedback(boid, dt, dir) if dir:length() > 1 then dir:mul(CELLULO_HAPTIC_FACTOR) if dir:length() > CELLULO_MAX_HAPTIC_FORCE then dir:normalize() dir:mul(CELLULO_MAX_HAPTIC_FORCE) end dir:div(CELLULO_MAX_HAPTIC_FORCE) local dx, dy, dz = dir:unpack() dx, dz = util.rotateVector(dx, dz, global.camera:getAngle()) dx, dz = dx / 2, dz / 2 dx, dz = boid:getCelluloPlane():normalizedRelativeToAbsolute(dx, dz) boid:getCellulo():setGoalPose(dx, dz, 0, 100, 10) end -end \ No newline at end of file +end + +return RelativeControls \ No newline at end of file