diff --git a/coffee/bot.coffee b/coffee/bot.coffee index 4232422..fff6924 100644 --- a/coffee/bot.coffee +++ b/coffee/bot.coffee @@ -114,10 +114,11 @@ class Bot extends Pushable getDown: -> @orientation.rotate Vector.minusY getUp: -> @orientation.rotate Vector.unitY getDir: -> @orientation.rotate new Vector 0,0,@dir_sgn - - getCurrentDir: -> @current_orientation.rotate(Vector.unitZ).normal() - getCurrentUp: -> @current_orientation.rotate(Vector.unitY).normal() - getCurrentLeft: -> @current_orientation.rotate(Vector.unitX).normal() + + currentPos: -> @current_position.clone() + currentDir: -> @current_orientation.rotate(Vector.unitZ).normal() + currentUp: -> @current_orientation.rotate(Vector.unitY).normal() + currentLeft: -> @current_orientation.rotate(Vector.unitX).normal() # 0000000 000 00000000 # 000 000 000 000 diff --git a/coffee/bullet.coffee b/coffee/bullet.coffee index 9404ad1..9b7a760 100644 --- a/coffee/bullet.coffee +++ b/coffee/bullet.coffee @@ -33,7 +33,7 @@ class Bullet extends Item @shootFromBot: (bot) -> bullet = new Bullet() world.addObject bullet - bullet.direction = bot.getCurrentDir() + bullet.direction = bot.currentDir() bullet.setPosition bot.position.plus bullet.direction.mul 0.8 bullet.src_object = bot bullet.mesh.material.color.set bot.mesh.material.color diff --git a/coffee/camera.coffee b/coffee/camera.coffee new file mode 100644 index 0000000..3e718d0 --- /dev/null +++ b/coffee/camera.coffee @@ -0,0 +1,241 @@ + +# 0000000 0000000 00 00 00000000 00000000 0000000 +# 000 000 000 000 000 000 000 000 000 000 +# 000 000000000 000000000 0000000 0000000 000000000 +# 000 000 000 000 0 000 000 000 000 000 000 +# 0000000 000 000 000 000 00000000 000 000 000 000 +{ +clamp +} = require '/Users/kodi/s/ko/js/tools/tools' +log = require '/Users/kodi/s/ko/js/tools/log' +Matrix = require './lib/matrix' +Vector = require './lib/vector' + +class Camera extends Matrix + + @INSIDE = 0 + @BEHIND = 1 + @FOLLOW = 2 + + constructor: (@player, opt) -> + @fov = opt?.fov ? 90 + @near = opt?.near ? 0.01 + @eye_distance = @near + @far = opt?.far ? 20 + @mode = Camera.BEHIND + @aspect = opt.aspect ? -1 + @dist = 10 + @border = [0,0,0,0] + + super + + @setViewport 0.0, 0.0, 1.0, 1.0 + + @cam = new THREE.PerspectiveCamera @fov, @aspect, @near, @far + @cam.position.z = @dist + + step: (step) -> + + switch @mode + when Camera.INSIDE then @insideProjection() + when Camera.BEHIND then @behindProjection() + when Camera.FOLLOW then @followProjection() + + camPos = @getPosition() + @cam.position.copy camPos + @cam.up.copy @getYVector() + @cam.lookAt camPos.plus @getZVector() + + if @light? + pos = @getPosition().plus @light_offset + @light.setDirection -@getZVector() + @light.setPosition new Vector pos[X], pos[Y], pos[Z], 1.0 # positional light source + + getLookAtPosition: -> @getZVector().mul(-@eye_distance).plus @getPosition() + + updateViewport: -> + ss = world.screenSize + vp = [] + vp[0] = @viewport[0] * ss.w + @border[0] + vp[1] = @viewport[1] * ss.h + @border[1] + vp[2] = @viewport[2] * ss.w - @border[0] - @border[2] + vp[3] = @viewport[3] * ss.h - @border[1] - @border[3] + + setViewportBorder: (l, b, r, t) -> + @border = [l,b,r,t] + @updateViewport() + + setViewport: (l, b, w, h) -> + @viewport = [l,b,w,h] + @updateViewport() + + setFov: (fov) -> @fov = Math.max(2.0, Math.min fov, 175.0) + + # 00000000 00000000 0000000 000 00000000 0000000 000000000 000 0000000 000 000 + # 000 000 000 000 000 000 000 000 000 000 000 000 000 0000 000 + # 00000000 0000000 000 000 000 0000000 000 000 000 000 000 000 0 000 + # 000 000 000 000 000 000 000 000 000 000 000 000 000 000 0000 + # 000 000 000 0000000 0000000 00000000 0000000 000 000 0000000 000 000 + + insideProjection: () -> + + playerPos = @player.currentPos() + playerDir = @player.currentDir() + playerUp = @player.currentUp() + lookAngle = @player.look_angle + + posDelta = world.getSpeed() / 10.0 # smooth camera movement a little bit + camPos = playerPos + if lookAngle < 0 + camPos.add playerUp.mul -2*lookAngle/90 + @setPosition @getPosition().mul(1.0-posDelta).plus camPos.mul posDelta + + if lookAngle # player is looking up or down + @setXVector playerDir.cross(playerUp).normal() + rot = Quaternion.rotationAroundVector lookAngle, @getXVector() + @setYVector rot.rotate playerUp + @setZVector rot.rotate playerDir #.neg() + else + # smooth camera rotation a little bit + lookDelta = (2.0 - @getZVector().dot playerDir) * world.getSpeed() / 50.0 + newLookVector = @getZVector().mul(1.0 - lookDelta).plus playerDir.mul lookDelta + newLookVector.normalize() + @setXVector playerUp.cross(newLookVector).normal() + @setYVector playerUp + @setZVector newLookVector + + @projection + + # 0000000 00000000 000 000 000 000 000 0000000 + # 000 000 000 000 000 000 0000 000 000 000 + # 0000000 0000000 000000000 000 000 0 000 000 000 + # 000 000 000 000 000 000 000 0000 000 000 + # 0000000 00000000 000 000 000 000 000 0000000 + + behindProjection: () -> + playerPos = @player.currentPos() + playerDir = @player.currentDir() + playerUp = @player.currentUp() + lookAngle = @player.look_angle + + # find a valid camera position + botToCamera = playerUp.minus playerDir.mul 2 + min_f = botToCamera.length() + botToCamera.normalize() + + min_f = Math.min world.getWallDistanceForRay(playerPos, botToCamera), min_f + camPos = playerPos.plus botToCamera.mul Math.max(min_f, 0.72) * (1-Math.abs(lookAngle)/90) + if lookAngle < 0 + camPos.add playerUp.mul -2*lookAngle/90 + + camPos = world.getInsideWallPosWithDelta camPos, 0.2 + + # smooth camera movement a little bit + posDelta = 0.2 + @setPosition @getPosition().mul(1.0 - posDelta).plus camPos.mul posDelta + + if lookAngle + # log "look_angle #{lookAngle}" + @setXVector playerDir.cross(playerUp).normal() + rot = Quaternion.rotationAroundVector lookAngle, @getXVector() + @setYVector rot.rotate playerUp + @setZVector rot.rotate playerDir #.neg() + else + # smooth camera rotation a little bit + lookDelta = 0.3 + newLookVector = @getZVector().mul(1.0 - lookDelta).plus (playerDir.minus(playerUp.mul(0.2)).normal()).mul lookDelta + newLookVector.normalize() + + @setZVector newLookVector + @setXVector playerUp.cross(newLookVector).normal() + @setYVector newLookVector.cross(@getXVector()).normal() + + # 00000000 0000000 000 000 0000000 000 000 + # 000 000 000 000 000 000 000 000 0 000 + # 000000 000 000 000 000 000 000 000000000 + # 000 000 000 000 000 000 000 000 000 + # 000 0000000 0000000 0000000 0000000 00 00 + + followProjection: () -> + + camPos = @getPosition() + desiredDistance = 2.0 # desired distance from camera to bot + + playerPos = @player.currentPos() + playerDir = @player.currentDir() + playerUp = @player.currentUp() + playerLeft = @player.currentLeft() + + # first, adjust distance from camera to bot + + botToCamera = camPos.minus playerPos # vector from bot to current pos + cameraBotDistance = botToCamera.length() # distance from camera to bot + + if cameraBotDistance >= desiredDistance + difference = cameraBotDistance - desiredDistance + delta = difference*difference/400.0 # weight for following speed + camPos = camPos.mul(1.0-delta).plus playerPos.mul delta + else + difference = desiredDistance - cameraBotDistance + delta = difference/20.0 # weight for negative following speed + camPos = camPos.mul(1.0-delta).plus (playerPos.plus botToCamera.normal().mul desiredDistance).mul delta + + # second, rotate around bot + + botToCamera = camPos.minus playerPos + botToCameraNormal = botToCamera.normal() + + # rotate camera vertically + verticalAngle = Vector.RAD2DEG Math.acos(clamp(-1.0, 1.0, botToCameraNormal.dot playerUp)) + if verticalAngle > 45 + # log "verticalAngle #{verticalAngle}" + rotQuat = Quaternion.rotationAroundVector(verticalAngle/400.0, botToCameraNormal.cross(playerUp)) + botToCamera = rotQuat.rotate botToCamera + botToCameraNormal = botToCamera.normal() + camPos = playerPos.plus botToCamera + + rotFactor = 1.0 + + wall_distance = world.getWallDistanceForPos camPos + if wall_distance < 0.5 # try avoid piercing walls + if wall_distance < 0.2 + camPos = world.getInsideWallPosWithDelta camPos, 0.2 + botToCamera = camPos.minus playerPos + botToCameraNormal = botToCamera.normal() + rotFactor = 0.5 / (wall_distance-0.2) + + # try view bot from behind + # calculate horizontal angle between bot orientation and vector to camera + mappedToXZ = (botToCamera.minus playerUp.mul(botToCamera.dot playerUp)).normal() + horizontalAngle = Vector.RAD2DEG Math.acos(clamp(-1.0, 1.0, -playerDir.dot mappedToXZ)) + if botToCameraNormal.dot(playerLeft) < 0 + horizontalAngle = -horizontalAngle + rotQuat = Quaternion.rotationAroundVector horizontalAngle/(rotFactor*400.0), playerUp + camPos = playerPos.plus rotQuat.rotate botToCamera + + botToCamera = camPos.minus playerPos + botToCameraNormal = botToCamera.normal() + + @setPosition camPos # finally, set the position + + # slowly adjust look direction by interpolating current and desired directions + lookDelta = @getZVector().dot botToCameraNormal + lookDelta *= lookDelta / 30.0 + newLookVector = @getZVector().mul(1.0-lookDelta).plus botToCameraNormal.neg().mul(lookDelta) + newLookVector.normalize() + + # slowly adjust up vector by interpolating current and desired up vectors + upDelta = 1.5-@getYVector().dot playerUp + upDelta *= upDelta / 100.0 + newUpVector = @getYVector().mul(1.0-upDelta).plus playerUp.mul(upDelta) + newUpVector.normalize() + + newLeftVector = newUpVector.cross newLookVector + + # finished interpolations, update camera matrix + @setXVector newLeftVector + @setYVector newUpVector + @setZVector newLookVector + @projection + +module.exports = Camera \ No newline at end of file diff --git a/coffee/perspective.coffee b/coffee/perspective.coffee deleted file mode 100644 index 12fdc5d..0000000 --- a/coffee/perspective.coffee +++ /dev/null @@ -1,119 +0,0 @@ -# 00000000 00000000 00000000 0000000 00000000 00000000 0000000 000000000 000 000 000 00000000 -# 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 -# 00000000 0000000 0000000 0000000 00000000 0000000 000 000 000 000 000 0000000 -# 000 000 000 000 000 000 000 000 000 000 000 000 -# 000 00000000 000 000 0000000 000 00000000 0000000 000 000 0 00000000 -{ -clamp -} = require '/Users/kodi/s/ko/js/tools/tools' -log = require '/Users/kodi/s/ko/js/tools/log' -Matrix = require './lib/matrix' - -class Perspective extends Matrix - - constructor: (fov,near=0.01,far=1000) -> - @znear = near - @zfar = far - @fov = fov - @aspect_ratio = -1.0 - @eye_distance = @znear - # @eye_distance = 5.0 - @border = [0,0,0,0] - @setViewport 0.0, 0.0, 1.0, 1.0 - super - # log "Perspective #{@fov} #{@znear} #{@zfar}" - - reset: -> - @fov = 60.0 - @eye_distance = @znear - super - @translate 0, 0, @eye_distance - - # rotate: (x,y,z) -> - # savePos = @getLookAtPosition() - # @translate -@getPosition() -# - # up = @getYVector() - # look = @getZVector() -# - # rotxz = Matrix.rotation x, 0.0, z - # roty = Matrix.rotation 0.0, y, 0.0 -# - # yunit = new Vector 0.0, 1.0, 0.0 - # zunit = new Vector 0.0, 0.0, 1.0 -# - # lookperp = @look.perpendicular yunit # y-axis rotation - # if lookperp.length() > 0 - # look = roty.transform lookperp.plus look.parallel(yunit) - # up = roty.transform up.perpendicular(yunit).plus up.parallel(yunit) -# - # # x & z-axis rotation - # transmat = new Matrix up.cross(look), up, look -# - # uprotxz = rotxz.transform yunit - # lookrotxz = rotxz.transform zunit -# - # up = transmat.transform uprotxz - # look = transmat.transform lookrotxz -# - # @.initXYZ up.cross(look), up, look -# - # @setPosition savePos.plus @getZVector().mul @eye_distance - - apply: (camera) -> - camPos = @getPosition() - camera.position.copy camPos - camera.up.copy @getYVector() - camera.lookAt camPos.plus @getZVector() - - if @light? - pos = @getPosition().plus @light_offset - @light.setDirection -@getZVector() - @light.setPosition new Vector pos[X], pos[Y], pos[Z], 1.0 # positional light source - - # setEyeDistance: (distance) -> - # log 'setEyeDistance', distance - # lookAtPos = @getLookAtPosition() - # @eye_distance = Math.min Math.max(@znear, distance), 0.9*@zfar - # @setPosition lookAtPos.plus @getZVector().mul @eye_distance - - # setLookAtPosition: (lookAtPos) -> - # up = @getYVector() - # newLook = lookAtPos.minus(@getPosition()).normal() - # newRight = up.cross(newLook).normal() - # newUp = newLook.cross(newRight).normal() -# - # @setXVector newRight - # @setYVector newUp - # @setZVector newLook - # # log 'setLookAtPosition', @matrix - # @eye_distance = lookAtPos.minus(@getPosition()).length() - - getLookAtPosition: -> @getZVector().mul(-@eye_distance).plus @getPosition() - - updateViewport: -> - ss = world.screenSize - vp = [] - vp[0] = @viewport[0] * ss.w + @border[0] - vp[1] = @viewport[1] * ss.h + @border[1] - vp[2] = @viewport[2] * ss.w - @border[0] - @border[2] - vp[3] = @viewport[3] * ss.h - @border[1] - @border[3] - - getCurrentAspectRatio: -> - vps = @getViewportSize() - @aspect_ratio <= 0.0 and vps.w/vps.h or @aspect_ratio - - getScreenCoordinates: (pos, sx, sy) -> - - setViewportBorder: (l, b, r, t) -> - @border = [l,b,r,t] - @updateViewport() - - setViewport: (l, b, w, h) -> - @viewport = [l,b,w,h] - @updateViewport() - - setFov: (fov) -> @fov = Math.max(2.0, Math.min fov, 175.0) - -module.exports = Perspective - \ No newline at end of file diff --git a/coffee/player.coffee b/coffee/player.coffee index 3fc397c..a79afdb 100644 --- a/coffee/player.coffee +++ b/coffee/player.coffee @@ -12,8 +12,8 @@ Bot = require './bot' Action = require './action' Timer = require './timer' Vector = require './lib/vector' +Camera = require './camera' Quaternion = require './lib/quaternion' -Perspective = require './perspective' class Player extends Bot @@ -33,6 +33,9 @@ class Player extends Bot view: 'c' push: 'shift' + @camera = new Camera @, + aspect: world.view.offsetWidth / world.view.offsetHeight + @look_action = null @look_angle = 0.0 @new_dir_sgn = 1.0 @@ -47,178 +50,8 @@ class Player extends Bot @addEventWithName "landed" - @projection = new Perspective 90.0 - @projection.updateViewport() - bulletHitSound: -> 'BULLET_HIT_PLAYER' - - # 00000000 00000000 0000000 000 00000000 0000000 000000000 000 0000000 000 000 - # 000 000 000 000 000 000 000 000 000 000 000 000 000 0000 000 - # 00000000 0000000 000 000 000 0000000 000 000 000 000 000 000 0 000 - # 000 000 000 000 000 000 000 000 000 000 000 000 000 000 0000 - # 000 000 000 0000000 0000000 00000000 0000000 000 000 0000000 000 000 - - getInsideProjection: () -> - - # smooth camera movement a little bit - posDelta = world.getSpeed() / 10.0 - playerDir = @getCurrentDir() - playerUp = @current_orientation.rotate(new Vector(0,1,0)).normal() - camPos = @current_position.clone() - if @look_angle < 0 - camPos.add playerUp.mul -2*@look_angle/90 - @projection.setPosition @projection.getPosition().mul(1.0-posDelta).plus camPos.mul posDelta - if @look_angle # player is looking up or down - @projection.setXVector playerDir.cross(playerUp).normal() - rot = Quaternion.rotationAroundVector @look_angle, @projection.getXVector() - @projection.setYVector rot.rotate playerUp - @projection.setZVector rot.rotate playerDir #.neg() - else - # smooth camera rotation a little bit - lookDelta = (2.0 - @projection.getZVector().dot playerDir) * world.getSpeed() / 50.0 - newLookVector = @projection.getZVector().mul(1.0 - lookDelta).plus playerDir.mul lookDelta - newLookVector.normalize() - @projection.setXVector playerUp.cross(newLookVector).normal() - @projection.setYVector playerUp - @projection.setZVector newLookVector - - @projection - - # 0000000 00000000 000 000 000 000 000 0000000 - # 000 000 000 000 000 000 0000 000 000 000 - # 0000000 0000000 000000000 000 000 0 000 000 000 - # 000 000 000 000 000 000 000 0000 000 000 - # 0000000 00000000 000 000 000 000 000 0000000 - - getBehindProjection: () -> - - playerDir = @getCurrentDir() - playerUp = @current_orientation.rotate(new Vector(0,1,0)).normal() - - # find a valid camera position - botToCamera = playerUp.minus playerDir.mul 2 - min_f = botToCamera.length() - botToCamera.normalize() - - min_f = Math.min world.getWallDistanceForRay(@current_position, botToCamera), min_f - camPos = @current_position.plus botToCamera.mul Math.max(min_f, 0.72) * (1-Math.abs(@look_angle)/90) - if @look_angle < 0 - camPos.add playerUp.mul -2*@look_angle/90 - - camPos = world.getInsideWallPosWithDelta camPos, 0.2 - - # smooth camera movement a little bit - posDelta = 0.2 - @projection.setPosition @projection.getPosition().mul(1.0 - posDelta).plus camPos.mul posDelta - - if @look_angle - # log "look_angle #{@look_angle}" - @projection.setXVector playerDir.cross(playerUp).normal() - rot = Quaternion.rotationAroundVector @look_angle, @projection.getXVector() - @projection.setYVector rot.rotate playerUp - @projection.setZVector rot.rotate playerDir #.neg() - else - # smooth camera rotation a little bit - lookDelta = 0.3 - newLookVector = @projection.getZVector().mul(1.0 - lookDelta).plus (playerDir.minus(@getCurrentUp().mul(0.2)).normal()).mul lookDelta - newLookVector.normalize() - - @projection.setZVector newLookVector - @projection.setXVector playerUp.cross(newLookVector).normal() - @projection.setYVector newLookVector.cross(@projection.getXVector()).normal() - - # log 'Player.getBehindProjection', @projection.getPosition() - @projection - - # 00000000 0000000 000 000 0000000 000 000 - # 000 000 000 000 000 000 000 000 0 000 - # 000000 000 000 000 000 000 000 000000000 - # 000 000 000 000 000 000 000 000 000 - # 000 0000000 0000000 0000000 0000000 00 00 - - getFollowProjection: () -> - - camPos = @projection.getPosition() - desiredDistance = 2.0 # desired distance from camera to bot - - playerPos = @current_position - playerDir = @getCurrentDir() - playerUp = @getCurrentUp() - playerLeft = @getCurrentLeft() - - # first, adjust distance from camera to bot - - botToCamera = camPos.minus playerPos # vector from bot to current pos - cameraBotDistance = botToCamera.length() # distance from camera to bot - - if cameraBotDistance >= desiredDistance - difference = cameraBotDistance - desiredDistance - delta = difference*difference/400.0 # weight for following speed - camPos = camPos.mul(1.0-delta).plus playerPos.mul delta - else - difference = desiredDistance - cameraBotDistance - delta = difference/20.0 # weight for negative following speed - camPos = camPos.mul(1.0-delta).plus (playerPos.plus botToCamera.normal().mul desiredDistance).mul delta - - # second, rotate around bot - - botToCamera = camPos.minus playerPos - botToCameraNormal = botToCamera.normal() - - # rotate camera vertically - verticalAngle = Vector.RAD2DEG Math.acos(clamp(-1.0, 1.0, botToCameraNormal.dot playerUp)) - if verticalAngle > 45 - # log "verticalAngle #{verticalAngle}" - rotQuat = Quaternion.rotationAroundVector(verticalAngle/400.0, botToCameraNormal.cross(playerUp)) - botToCamera = rotQuat.rotate botToCamera - botToCameraNormal = botToCamera.normal() - camPos = playerPos.plus botToCamera - - rotFactor = 1.0 - - wall_distance = world.getWallDistanceForPos camPos - if wall_distance < 0.5 # try avoid piercing walls - if wall_distance < 0.2 - camPos = world.getInsideWallPosWithDelta camPos, 0.2 - botToCamera = camPos.minus playerPos - botToCameraNormal = botToCamera.normal() - rotFactor = 0.5 / (wall_distance-0.2) - - # try view bot from behind - # calculate horizontal angle between bot orientation and vector to camera - mappedToXZ = (botToCamera.minus playerUp.mul(botToCamera.dot playerUp)).normal() - horizontalAngle = Vector.RAD2DEG Math.acos(clamp(-1.0, 1.0, -playerDir.dot mappedToXZ)) - if botToCameraNormal.dot(playerLeft) < 0 - horizontalAngle = -horizontalAngle - rotQuat = Quaternion.rotationAroundVector horizontalAngle/(rotFactor*400.0), playerUp - camPos = playerPos.plus rotQuat.rotate botToCamera - - botToCamera = camPos.minus playerPos - botToCameraNormal = botToCamera.normal() - - @projection.setPosition camPos # finally, set the position - - # slowly adjust look direction by interpolating current and desired directions - lookDelta = @projection.getZVector().dot botToCameraNormal - lookDelta *= lookDelta / 30.0 - newLookVector = @projection.getZVector().mul(1.0-lookDelta).plus botToCameraNormal.neg().mul(lookDelta) - newLookVector.normalize() - - # slowly adjust up vector by interpolating current and desired up vectors - upDelta = 1.5-@projection.getYVector().dot playerUp - upDelta *= upDelta / 100.0 - newUpVector = @projection.getYVector().mul(1.0-upDelta).plus playerUp.mul(upDelta) - newUpVector.normalize() - - newLeftVector = newUpVector.cross newLookVector - - # finished interpolations, update camera matrix - @projection.setXVector newLeftVector - @projection.setYVector newUpVector - @projection.setZVector newLookVector - @projection - # 0000000 0000000 000000000 000 0000000 000 000 # 000 000 000 000 000 000 000 0000 000 # 000000000 000 000 000 000 000 000 0 000 @@ -419,30 +252,4 @@ class Player extends Bot false - # 0000000 000 0000000 00000000 000 0000000 000 000 - # 000 000 000 000 000 000 000 000 000 000 000 - # 000 000 000 0000000 00000000 000 000000000 00000 - # 000 000 000 000 000 000 000 000 000 - # 0000000 000 0000000 000 0000000 000 000 000 - - step: (step) -> super step - - getBodyColor: () -> - if world.getCameraMode() == world.CAMERA_BEHIND - # static bodyColor - bodyColor = colors[KikiPlayer_base_color] - bodyColor.setAlpha(kMin(0.7, (@projection.getPosition()-@current_position).length()-0.4)) - return bodyColor - - return colors[KikiPlayer_base_color] - - getTireColor: () -> - if world.getCameraMode() == world.CAMERA_BEHIND - # static tireColor - tireColor = colors[KikiPlayer_tire_color] - tireColor.setAlpha(kMin(1.0, (@projection.getPosition()-@current_position).length()-0.4)) - return tireColor - - return colors[KikiPlayer_tire_color] - module.exports = Player diff --git a/coffee/world.coffee b/coffee/world.coffee index f68d0d6..3ed4857 100644 --- a/coffee/world.coffee +++ b/coffee/world.coffee @@ -15,6 +15,7 @@ Pos = require './lib/pos' Size = require './lib/size' Cell = require './cell' Gate = require './gate' +Camera = require './camera' Light = require './light' Levels = require './levels' Player = require './player' @@ -43,10 +44,6 @@ Face} = require './items' world = null class World extends Actor - - @CAMERA_INSIDE = 0 - @CAMERA_BEHIND = 1 - @CAMERA_FOLLOW = 2 @levels = null @@ -63,10 +60,7 @@ class World extends Actor @speed = 6 - @raster_size = 0.05 - # @camera_mode = World.CAMERA_INSIDE - @camera_mode = World.CAMERA_BEHIND - # @camera_mode = World.CAMERA_FOLLOW + @rasterSize = 0.05 super @@ -84,22 +78,7 @@ class World extends Actor @renderer.setClearColor 0x000000 @renderer.setSize @view.offsetWidth, @view.offsetHeight @renderer.shadowMap.type = THREE.PCFSoftShadowMap - - # 0000000 0000000 00 00 00000000 00000000 0000000 - # 000 000 000 000 000 000 000 000 000 000 - # 000 000000000 000000000 0000000 0000000 000000000 - # 000 000 000 000 0 000 000 000 000 000 000 - # 0000000 000 000 000 000 00000000 000 000 000 000 - - @fov = 90 - @near = 0.1 - @far = 20 - @aspect = @view.offsetWidth / @view.offsetHeight - @dist = 10 - - @camera = new THREE.PerspectiveCamera @fov, @aspect, @near, @far - @camera.position.z = @dist - + # 0000000 0000000 00000000 000 000 00000000 # 000 000 000 0000 000 000 # 0000000 000 0000000 000 0 000 0000000 @@ -115,7 +94,7 @@ class World extends Actor # 0000000 000 0000000 000 000 000 @sun = new THREE.PointLight 0xffffff - @sun.position.copy @camera.position + @sun.position.copy @player.camera.getPosition() if @player? @scene.add @sun @ambient = new THREE.AmbientLight 0x111111 @@ -199,11 +178,6 @@ class World extends Actor # else # @setName "noname" - # if @preview - # @getProjection().setViewport(0.0, 0.4, 1.0, 0.6) - # else - # @getProjection().setViewport(0.0, 0.0, 1.0, 1.0) - # ............................................................ escape # escape_event = Controller.getEventWithName ("escape") # escape_event.removeAllActions() @@ -251,7 +225,7 @@ class World extends Actor else if @dict.player.coordinates? @addObjectAtPos @player, new Pos @dict.player.coordinates - @getProjection().setPosition new Vector 0,0,0 + @player.camera.setPosition new Vector 0,0,0 restart: () -> @create @dict @@ -344,10 +318,10 @@ class World extends Actor # calcuate max distance (for position relative sound) @max_distance = Math.max(@size.x, Math.max(@size.y, @size.z)) # heuristic of a heuristic :-) @cage?.del() - @cage = new Cage @size, @raster_size + @cage = new Cage @size, @rasterSize getCellAtPos: (pos) -> return @cells[@posToIndex(pos)] if @isValidPos pos - getBotAtPos: (pos) -> @getObjectOfTypeAtPos KikiBot, new Pos pos + getBotAtPos: (pos) -> @getObjectOfTypeAtPos Bot, new Pos pos posToIndex: (pos) -> p = new Pos pos @@ -477,9 +451,7 @@ class World extends Actor newObject: (object) -> if _.isString object - if object.startsWith 'Kiki' - return new (require "./#{object.slice(4).toLowerCase()}")() - else if object.startsWith 'new' + if object.startsWith 'new' return eval object return new (require "./#{object.toLowerCase()}")() if object instanceof Item @@ -548,9 +520,9 @@ class World extends Actor log "World.getObjectWithName [WARNING] no object with name #{objectName}" null - setCameraMode: (mode) -> @camera_mode = clamp World.CAMERA_INSIDE, World.CAMERA_FOLLOW, mode + setCameraMode: (mode) -> @player.camera.mode = clamp Camera.INSIDE, Camera.FOLLOW, mode - changeCameraMode: -> @camera_mode = (@camera_mode+1) % (World.CAMERA_FOLLOW+1) + changeCameraMode: -> @player.camera.mode = (@player.camera.mode+1) % (Camera.FOLLOW+1) # 0000000 0000000 000 00 00 0000000 000 000 00000000 # 000 000 000 000 000 000 000 000 000 000 000 000 @@ -638,14 +610,6 @@ class World extends Actor else log "world.objectMoved [WARNING] #{movedObject.name} no target cell?" - setObjectColor: (color_name, color) -> - if color_name == 'base' - # KikiWall::setObjectColor "base", color - @colors[0] = color - else if color_name == 'plate' - # KikiWall::setObjectColor "plate", color - @colors[1] = color - # 0000000 000000000 00000000 00000000 # 000 000 000 000 000 # 0000000 000 0000000 00000000 @@ -653,31 +617,27 @@ class World extends Actor # 0000000 000 00000000 000 step: (step) -> + camera = @player.camera.cam if false - quat = @camera.quaternion.clone() + quat = camera.quaternion.clone() quat.multiply new THREE.Quaternion().setFromAxisAngle new THREE.Vector3(1,0,0), step.dsecs*0.2 quat.multiply new THREE.Quaternion().setFromAxisAngle new THREE.Vector3(0,1,0), step.dsecs*0.1 center = @size.div 2 - @camera.position.set(center.x,center.y,center.z+@dist).applyQuaternion quat - @camera.quaternion.copy quat + camera.position.set(center.x,center.y,center.z+@dist).applyQuaternion quat + camera.quaternion.copy quat Timer.event.triggerActions() Timer.event.finishActions() o.step?(step) for o in @objects + @player.camera.step step - switch @camera_mode - when World.CAMERA_INSIDE then @projection = @player.getInsideProjection() - when World.CAMERA_BEHIND then @projection = @player.getBehindProjection() - when World.CAMERA_FOLLOW then @projection = @player.getFollowProjection() - - Sound.setMatrix @projection + Sound.setMatrix @player.camera - # Material.tire.visible = @camera_mode != World.CAMERA_INSIDE - @player.setOpacity clamp 0, 1, @projection.getPosition().minus(@player.current_position).length()-0.4 - @projection.apply @camera - @sun.position.copy @camera.position - @renderer.render @scene, @camera + @player.setOpacity clamp 0, 1, @player.camera.getPosition().minus(@player.current_position).length()-0.4 + + @sun.position.copy camera.position + @renderer.render @scene, camera # 000000000 000 00 00 00000000 # 000 000 000 000 000 @@ -711,8 +671,9 @@ class World extends Actor resized: (w,h) -> @aspect = w/h - @camera?.aspect = @aspect - @camera?.updateProjectionMatrix() + camera = @player.camera.cam + camera?.aspect = @aspect + camera?.updateProjectionMatrix() @renderer?.setSize w,h @screenSize = new Size w,h @@ -819,7 +780,7 @@ class World extends Actor if less_text page.getEventWithName("previous").addAction (i=index-1) => @outro i - resetProjection: -> world.getProjection().setViewport 0.0, 0.0, 1.0, 1.0 + resetProjection: -> @player.camera.setViewport 0.0, 0.0, 1.0, 1.0 # 00000000 0000000 0000000 # 000 000 000 @@ -891,15 +852,7 @@ class World extends Actor displayLights: () -> for light in @lights lignt.display() - - getProjection: () -> - if not @projection - switch @camera_mode - when World.CAMERA_INSIDE then @projection = @player.getInsideProjection() - when World.CAMERA_BEHIND then @projection = @player.getBehindProjection() - when World.CAMERA_FOLLOW then @projection = @player.getFollowProjection() - @projection - + playSound: (sound, pos, time) -> Sound.play sound, pos, time # 000 000 00000000 000 000