| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- -- Move speed (m/s)
- MOVE_SPEED_NORMAL = 1
- MOVE_SPEED_FAST = 5
- -- Move flags
- MOVE_FORWARD = 1
- MOVE_BACKWARD = 2
- MOVE_RIGHT = 3
- MOVE_LEFT = 4
- _useScriptCamera = false
- _forwardSpeed = 0
- _sideSpeed = 0
- _touch = Vector2.new()
- _delta = Vector2.new()
- _move = Vector2.new()
- _moveFlags = { false, false, false, false }
- _yaw = 0
- _pitch = 0
- _moveFast = false
- function camera_setActive(flag)
- _useScriptCamera = flag
- if _useScriptCamera then
- Game.getInstance():setMultiTouch(true)
-
- _scene = Scene.getScene()
- _cameraNode = _scene:getActiveCamera():getNode()
- -- Set initial camera angles
- local eulers = camera_quatToEuler(_cameraNode:getRotation())
- _yaw = eulers:y()
- _pitch = eulers:x()
- else
- -- Release scene and camera
- _scene = nil
- _cameraNode = nil
- end
- end
- function camera_setSpeed(normal, fast)
- MOVE_SPEED_NORMAL = normal
- MOVE_SPEED_FAST = fast
- end
- function camera_update(elapsedTime)
-
- if not _useScriptCamera then
- return
- end
- if USE_PHYSICS_CHARACTER then
- local char = _scene:findNode("camera"):getCollisionObject():asCharacter()
- local speed = MOVE_SPEED_NORMAL
- if _moveFast then
- speed = MOVE_SPEED_FAST
- end
- -- Forward motion
- if _moveFlags[MOVE_FORWARD] then
- char:setForwardVelocity(speed)
- elseif _moveFlags[MOVE_BACKWARD] then
- char:setForwardVelocity(-speed)
- else
- char:setForwardVelocity(0)
- end
- -- Strafing
- if _moveFlags[MOVE_LEFT] then
- char:setRightVelocity(-speed)
- elseif _moveFlags[MOVE_RIGHT] then
- char:setRightVelocity(speed)
- else
- char:setRightVelocity(0)
- end
- else
- -- Manual camera movement
- local secs = elapsedTime / 1000.0
- _move:set(0,0)
- -- Forward motion
- if _moveFlags[MOVE_FORWARD] then
- _move:y(1)
- elseif _moveFlags[MOVE_BACKWARD] then
- _move:y(-1)
- end
- -- Strafing
- if _moveFlags[MOVE_LEFT] then
- _move:x(-1)
- elseif _moveFlags[MOVE_RIGHT] then
- _move:x(1)
- end
- if not _move:isZero() then
- local speed = MOVE_SPEED_NORMAL
- if _moveFast then
- speed = MOVE_SPEED_FAST
- end
- _move:normalize():scale(secs * speed)
- camera_moveForward(_move:y());
- camera_moveRight(_move:x());
- end
- end
- end
- function camera_keyEvent(evt, key)
- if not _useScriptCamera then
- return
- end
- if evt == Keyboard.KEY_PRESS then
- if key == Keyboard.KEY_W or key == Keyboard.KEY_CAPITAL_W then
- _moveFlags[MOVE_FORWARD] = true
- elseif key == Keyboard.KEY_S or key == Keyboard.KEY_CAPITAL_S then
- _moveFlags[MOVE_BACKWARD] = true
- elseif key == Keyboard.KEY_A or key == Keyboard.KEY_CAPITAL_A then
- _moveFlags[MOVE_LEFT] = true
- elseif key == Keyboard.KEY_D or key == Keyboard.KEY_CAPITAL_D then
- _moveFlags[MOVE_RIGHT] = true
- elseif key == Keyboard.KEY_SHIFT then
- _moveFast = true
- end
- elseif evt == Keyboard.KEY_RELEASE then
- if key == Keyboard.KEY_W or key == Keyboard.KEY_CAPITAL_W then
- _moveFlags[MOVE_FORWARD] = false
- elseif key == Keyboard.KEY_S or key == Keyboard.KEY_CAPITAL_S then
- _moveFlags[MOVE_BACKWARD] = false
- elseif key == Keyboard.KEY_A or key == Keyboard.KEY_CAPITAL_A then
- _moveFlags[MOVE_LEFT] = false
- elseif key == Keyboard.KEY_D or key == Keyboard.KEY_CAPITAL_D then
- _moveFlags[MOVE_RIGHT] = false
- elseif key == Keyboard.KEY_SHIFT then
- _moveFast = false
- end
- end
- end
- function camera_touchEvent(evt, x, y, contactIndex)
- if not _useScriptCamera then
- return
- end
- if evt == Touch.TOUCH_PRESS then
- if contactIndex == 0 then
- _touch:set(x, y)
- elseif contactIndex == 1 then
- _moveFlags[MOVE_FORWARD] = true
- elseif contactIndex == 2 then
- _moveFast = true
- end
- elseif evt == Touch.TOUCH_RELEASE then
- if contactIndex == 1 then
- _moveFlags[MOVE_FORWARD] = false
- elseif contactIndex == 2 then
- _moveFast = false
- end
- elseif evt == Touch.TOUCH_MOVE then
- if contactIndex == 0 then
- _delta:set(x - _touch:x(), y - _touch:y())
- _touch:set(x, y)
- _pitch = _pitch - math.rad(_delta:y() * 0.5)
- _yaw = _yaw - math.rad(_delta:x() * 0.5)
- _cameraNode:setRotation(Quaternion.identity())
- _cameraNode:rotateY(_yaw)
- _cameraNode:rotateX(_pitch)
- end
- end
- end
- function camera_moveForward(by)
- local v = _cameraNode:getForwardVector()
- v:normalize():scale(by)
- _cameraNode:translate(v)
- end
- function camera_moveRight(by)
- local v = _cameraNode:getRightVector()
- v:normalize():scale(by)
- _cameraNode:translate(v)
- end
- function camera_quatToEuler(quat)
- local qx = quat:x()
- local qy = quat:y()
- local qz = quat:z()
- local qw = quat:w()
- local qx2 = qx * qx
- local qy2 = qy * qy
- local qz2 = qz * qz
- local qw2 = qw * qw
- local rotx = 0
- local roty = 0
- local rotz = 0
- if (qx*qy + qz*qw) == 0.5 then
- rotx = 0
- roty = 2 * math.atan2(qx, qw)
- elseif (qx*qy + qz*qw) == -0.5 then
- rotx = 0
- roty = -2 * math.atan2(qx, qw)
- else
- rotx = math.atan2(2*qx*qw-2*qy*qz , 1 - 2*qx2 - 2*qz2)
- roty = math.atan2(2*qy*qw-2*qx*qz , 1 - 2*qy2 - 2*qz2)
- end
- rotz = math.asin(2*qx*qy + 2*qz*qw)
- return Vector3.new(rotx, roty, rotz)
- end
|