perspective

This commit is contained in:
monsterkodi 2016-08-13 00:54:11 +02:00
parent bec76e00e7
commit b3db929331
8 changed files with 210 additions and 181 deletions

View File

@ -6,6 +6,9 @@
Pushable = require './pushable' Pushable = require './pushable'
Action = require './action' Action = require './action'
Timer = require './timer'
Vector = require './lib/vector'
Quaternion = require './lib/quaternion'
class Bot extends Pushable class Bot extends Pushable
@ -13,6 +16,13 @@ class Bot extends Pushable
super super
@direction = new Quaternion
@orientation = new Quaternion
@current_orientation = new Quaternion
@rotate_orientation = new Quaternion
@climb_orientation = new Quaternion
@rest_orientation = new Quaternion
@geom = new THREE.SphereGeometry 1, 32, 32 @geom = new THREE.SphereGeometry 1, 32, 32
@mat = new THREE.MeshPhongMaterial @mat = new THREE.MeshPhongMaterial
color: 0x0000ff color: 0x0000ff
@ -39,14 +49,13 @@ class Bot extends Pushable
@jump = false @jump = false
@shoot = false @shoot = false
@jump_once = false @jump_once = false
@spiked = false @spiked = false
@died = false @died = false
@move_action = null @move_action = null
@rotate_action = null @rotate_action = null
@dir_sgn = 1.0 @dir_sgn = 1.0
@addAction new Action @, Action.NOOP, "noop", 0 @addAction new Action @, Action.NOOP, "noop", 0
@addAction new Action @, Action.FORWARD, "move forward", 200 @addAction new Action @, Action.FORWARD, "move forward", 200
@ -68,7 +77,7 @@ class Bot extends Pushable
addHealth: (h) -> @health = Math.max @health+h addHealth: (h) -> @health = Math.max @health+h
die: () -> die: () ->
# timer_event.removeActionsOfObject (@) Timer.removeActionsOfObject @
@move = false @move = false
@jump = false @jump = false
@ -378,6 +387,8 @@ class Bot extends Pushable
@move_action.keepRest() # try to make subsequent actions smooth @move_action.keepRest() # try to make subsequent actions smooth
timer_event.addAction @move_action timer_event.addAction @move_action
getCurrentDir: -> @current_orientation.rotate(new Vector(0,0,1)).normal()
render: () -> render: () ->
radius = 0.5 radius = 0.5
tireRadius = 0.15 tireRadius = 0.15

View File

@ -4,9 +4,13 @@
# 000 0 000 000 000 000 000 000 000 000 000 # 000 0 000 000 000 000 000 000 000 000 000
# 000 000 000 000 000 000 000 000 000 000 # 000 000 000 000 000 000 000 000 000 000
Quaternion = require './quaternion'
Vector = require './vector'
class Matrix class Matrix
constructor: (o) -> constructor: (o) ->
@matrix = [] @matrix = []
if o instanceof Matrix if o instanceof Matrix
@ -123,7 +127,7 @@ class Matrix
@matrix[14] += @matrix[2]*v.x+@matrix[6]*v.y+@matrix[10]*v.z @matrix[14] += @matrix[2]*v.x+@matrix[6]*v.y+@matrix[10]*v.z
@matrix[15] += @matrix[3]*v.x+@matrix[7]*v.y+@matrix[11]*v.z @matrix[15] += @matrix[3]*v.x+@matrix[7]*v.y+@matrix[11]*v.z
@rotation (x,y,z) -> new Matrix().rotate x,y,z @rotation: (x,y,z) -> new Matrix().rotate x,y,z
rotate: (x,y,z) -> rotate: (x,y,z) ->
rx = Vector.DEG2RAD x rx = Vector.DEG2RAD x
@ -201,12 +205,9 @@ class Matrix
for k in [0...3] for k in [0...3]
jj[k] = k+1 jj[k] = k+1
fac = m[ii[0]][jj[0]] * (m[ii[1]][jj[1]]*m[ii[2]][jj[2]] fac = m[ii[0]][jj[0]] * (m[ii[1]][jj[1]]*m[ii[2]][jj[2]] - m[ii[1]][jj[2]]*m[ii[2]][jj[1]])
- m[ii[1]][jj[2]]*m[ii[2]][jj[1]]) fac -= m[ii[0]][jj[1]] * (m[ii[1]][jj[0]]*m[ii[2]][jj[2]] - m[ii[1]][jj[2]]*m[ii[2]][jj[0]])
fac -= m[ii[0]][jj[1]] * (m[ii[1]][jj[0]]*m[ii[2]][jj[2]] fac += m[ii[0]][jj[2]] * (m[ii[1]][jj[0]]*m[ii[2]][jj[1]] - m[ii[1]][jj[1]]*m[ii[2]][jj[0]])
- m[ii[1]][jj[2]]*m[ii[2]][jj[0]])
fac += m[ii[0]][jj[2]] * (m[ii[1]][jj[0]]*m[ii[2]][jj[1]]
- m[ii[1]][jj[1]]*m[ii[2]][jj[0]])
k = i+j k = i+j
if k != (k/2)*2 # compute sign if k != (k/2)*2 # compute sign

View File

@ -16,7 +16,9 @@ class Pos
@y = parseInt x.y @y = parseInt x.y
@z = parseInt x.z @z = parseInt x.z
else if Array.isArray x else if Array.isArray x
[@x, @y, @z] = x @x = parseInt x[0]
@y = parseInt x[1]
@z = parseInt x[2]
else else
@x = parseInt x @x = parseInt x
@y = parseInt y @y = parseInt y

View File

@ -78,8 +78,6 @@ class Quaternion
length: -> Math.sqrt @w*@w + @x*@x + @y*@y + @z*@z length: -> Math.sqrt @w*@w + @x*@x + @y*@y + @z*@z
eql: (q) -> @w==q.w and @x=q.x and @y==q.y and @z==q.z eql: (q) -> @w==q.w and @x=q.x and @y==q.y and @z==q.z
# glRotate () const { KMatrix(*this).glMultMatrix(); }
# Quaternion & operator += ( float f ) { w += f; return(*this); } # Quaternion & operator += ( float f ) { w += f; return(*this); }
# Quaternion & operator -= ( float f ) { w -= f; return(*this); } # Quaternion & operator -= ( float f ) { w -= f; return(*this); }
# Quaternion & operator *= ( float f ) { w *= f; x *= f; y *= f; z *= f; return(*this); } # Quaternion & operator *= ( float f ) { w *= f; x *= f; y *= f; z *= f; return(*this); }
@ -88,18 +86,18 @@ class Quaternion
mul: (quatOrScalar) -> mul: (quatOrScalar) ->
if quatOrScalar instanceof Quaternion if quatOrScalar instanceof Quaternion
quat = quatOrScalar quat = quatOrScalar
A = (@w + @x)*(quat.w + quat.x) A = (@w + @x) * (quat.w + quat.x)
B = (@z - @y)*(quat.y - quat.z) B = (@z - @y) * (quat.y - quat.z)
C = (@w - @x)*(quat.y + quat.z) C = (@w - @x) * (quat.y + quat.z)
D = (@y + @z)*(quat.w - quat.x) D = (@y + @z) * (quat.w - quat.x)
E = (@x + @z)*(quat.x + quat.y) E = (@x + @z) * (quat.x + quat.y)
F = (@x - @z)*(quat.x - quat.y) F = (@x - @z) * (quat.x - quat.y)
G = (@w + @y)*(quat.w - quat.z) G = (@w + @y) * (quat.w - quat.z)
H = (@w - @y)*(quat.w + quat.z) H = (@w - @y) * (quat.w + quat.z)
new Quaternion B +(-E - F + G + H)/2, new Quaternion B + (-E - F + G + H)/2,
A - (E + F + G + H)/2, A - (E + F + G + H)/2,
C + (E - F + G - H)/2, C + (E - F + G - H)/2,
D + (E - F - G + H)/2 D + (E - F - G + H)/2
else else
new Quaternion @w*f, @x*f, @y*f, z*f new Quaternion @w*f, @x*f, @y*f, z*f

View File

@ -4,7 +4,8 @@
# 000 000 000 000 000 000 000 000 000 000 000 000 # 000 000 000 000 000 000 000 000 000 000 000 000
# 000 00000000 000 000 0000000 000 00000000 0000000 000 000 0 00000000 # 000 00000000 000 000 0000000 000 00000000 0000000 000 000 0 00000000
Matrix = require './matrix' log = require '/Users/kodi/s/ko/js/tools/log'
Matrix = require './lib/matrix'
class Perspective extends Matrix class Perspective extends Matrix
@ -58,15 +59,18 @@ class Perspective extends Matrix
initProjection: -> @apply() initProjection: -> @apply()
apply: -> apply: (camera) ->
# glViewport(vp[0], vp[1], vp[2], vp[3]);
# gluPerspective (fov, getCurrentAspectRatio(), znear, zfar); camPos = @getPosition()
# glMatrixMode(GL_MODELVIEW); up = @getYVector()
# glLoadIdentity(); lookAt = @getLookAtPosition()
# KVector lookAt = getLookAtPosition();
# gluLookAt( matrix[TX], matrix[TY], matrix[TZ], log "Perspective.apply", camPos, up, lookAt
# lookAt[X], lookAt[Y], lookAt[Z],
# matrix[4], matrix[5], matrix[6]); camera.position.clone camPos #set camPos.x, camPos.y, camPos.z
camera.up.clone up #new THREE.Vector3 up.x, up.y, up.z
camera.lookAt new THREE.Vector3 lookAt.x, lookAt.y, lookAt.z
if @light? if @light?
pos = @getPosition().plus @light_offset pos = @getPosition().plus @light_offset
@light.setDirection -@getZVector() @light.setDirection -@getZVector()
@ -94,11 +98,12 @@ class Perspective extends Matrix
getLookAtPosition: -> @getZVector().mul(-@eye_distance).plus @getPosition() getLookAtPosition: -> @getZVector().mul(-@eye_distance).plus @getPosition()
updateViewport: -> updateViewport: ->
ss = @world.screenSize() ss = world.screenSize
vp = []
vp[0] = @viewport[0] * ss.w + @border[0] vp[0] = @viewport[0] * ss.w + @border[0]
vp[1] = @viewport[1] * ss.h + @border[1] vp[1] = @viewport[1] * ss.h + @border[1]
vp[2] = @viewport[2] * ss.w - (@border[0]+@border[2]) vp[2] = @viewport[2] * ss.w - @border[0] - @border[2]
vp[3] = @viewport[3] * ss.h - (@border[1]+@border[3]) vp[3] = @viewport[3] * ss.h - @border[1] - @border[3]
getCurrentAspectRatio: -> getCurrentAspectRatio: ->
vps = @getViewportSize() vps = @getViewportSize()
@ -111,7 +116,7 @@ class Perspective extends Matrix
@updateViewport(); @updateViewport();
setViewport: (l, b, w, h) -> setViewport: (l, b, w, h) ->
@viewport[0] = [l,b,w,h] @viewport = [l,b,w,h]
@updateViewport() @updateViewport()
setFov: (fov) -> @fov = Math.max(2.0, Math.min fov, 175.0) setFov: (fov) -> @fov = Math.max(2.0, Math.min fov, 175.0)

View File

@ -7,6 +7,9 @@
Bot = require './bot' Bot = require './bot'
Action = require './action' Action = require './action'
Timer = require './timer'
Vector = require './lib/vector'
Perspective = require './perspective'
forward_key = "UP" forward_key = "UP"
backward_key = "DOWN" backward_key = "DOWN"
@ -19,8 +22,6 @@ look_up_key = "HOME"
look_down_key = "END" look_down_key = "END"
view_key = "PAGEDOWN" view_key = "PAGEDOWN"
# KikiActionKey actionKeyMapping[] =
class Player extends Bot class Player extends Bot
constructor: -> constructor: ->
@ -35,8 +36,6 @@ class Player extends Bot
@recorder = null @recorder = null
@playback = null @playback = null
# @flags[KDL_KEYHANDLER_FLAG_HANDLES_RELEASE] = true
@addAction new Action @, Action.LOOK_UP, "look up", 220 @addAction new Action @, Action.LOOK_UP, "look up", 220
@addAction new Action @, Action.LOOK_DOWN, "look down", 220 @addAction new Action @, Action.LOOK_DOWN, "look down", 220
@addAction new Action @, Action.LOOK_RESET, "look reset", 60 @addAction new Action @, Action.LOOK_RESET, "look reset", 60
@ -45,13 +44,11 @@ class Player extends Bot
@addEventWithName "keyset failed" @addEventWithName "keyset failed"
@addEventWithName "landed" @addEventWithName "landed"
# @projection = new KLightingProjection (90.0) @projection = new Perspective 90.0
# @projection.updateViewport() @projection.updateViewport()
# @projection.getLight().setCutoff (90.0) # @projection.getLight().setCutoff 90.0
# @projection.getLight().setAttenuation (1.0, 0.0, 0.05) # @projection.getLight().setAttenuation 1.0, 0.0, 0.05
# Controller.player_status->setStatus status
getActionForKey: (keyName) -> getActionForKey: (keyName) ->
index = 0 index = 0
while actionKeyMapping[index].actionName while actionKeyMapping[index].actionName
@ -92,7 +89,7 @@ class Player extends Bot
updatePosition: () -> updatePosition: () ->
if @move_action if @move_action
relTime = (Controller.getTime() - @move_action.getStart()) / @move_action.getDuration() relTime = (world.getTime() - @move_action.getStart()) / @move_action.getDuration()
if relTime <= 1.0 if relTime <= 1.0
switch @move_action.id switch @move_action.id
when Action.FORWARD when Action.FORWARD
@ -110,30 +107,30 @@ class Player extends Bot
@projection.setPosition ((1.0 - posDelta) * @projection.getPosition() + posDelta * @current_position) @projection.setPosition ((1.0 - posDelta) * @projection.getPosition() + posDelta * @current_position)
playerDir = @getCurrentDir() playerDir = @getCurrentDir()
playerUp = @current_orientation.rotate(new KVector(0,1,0)).normal() playerUp = @current_orientation.rotate(new Vector(0,1,0)).normal()
if @look_angle # player is looking up or down if @look_angle # player is looking up or down
projection.setXVector playerUp.cross(@playerDir).normal() @projection.setXVector playerUp.cross(playerDir).normal()
@look_rot = KQuaternion.rotationAroundVector @look_angle, projection.getXVector() @look_rot = Quaternion.rotationAroundVector @look_angle, @projection.getXVector()
projection.setYVector @look_rot.rotate @playerUp @projection.setYVector @look_rot.rotate playerUp
projection.setZVector @look_rot.rotate -@playerDir @projection.setZVector @look_rot.rotate -playerDir
else else
# smooth camera rotation a little bit # smooth camera rotation a little bit
lookDelta = (2.0 - projection.getZVector() * @playerDir) * world.getSpeed() / 50.0 lookDelta = (2.0 - @projection.getZVector().dot playerDir) * world.getSpeed() / 50.0
newLookVector = (1.0 - lookDelta) * projection.getZVector() - lookDelta * @playerDir newLookVector = @projection.getZVector().mul(1.0 - lookDelta).minus playerDir.mul lookDelta
newLookVector.normalize() newLookVector.normalize()
projection.setXVector playerUp.cross(newLookVector).normal() @projection.setXVector playerUp.cross(newLookVector).normal()
projection.setYVector playerUp @projection.setYVector playerUp
projection.setZVector newLookVector @projection.setZVector newLookVector
return projection @projection
getBehindProjection: () -> getBehindProjection: () ->
@updatePosition() @updatePosition()
@playerDir = getCurrentDir() @playerDir = getCurrentDir()
@playerUp = current_orientation.rotate(KVector(0,1,0)).normal() @playerUp = @current_orientation.rotate(new Vector(0,1,0)).normal()
# find a valid camera position # find a valid camera position
botToCamera = (playerUp - 2 * playerDir) botToCamera = (playerUp - 2 * playerDir)
@ -156,7 +153,7 @@ class Player extends Bot
else else
# smooth camera rotation a little bit # smooth camera rotation a little bit
lookDelta = 0.3 lookDelta = 0.3
KVector newLookVector =(1.0 - lookDelta) * @projection.getZVector() - lookDelta * playerDir newLookVector = @projection.getZVector().mul((1.0 - lookDelta)).minus @playerDir.mul lookDelta
newLookVector.normalize() newLookVector.normalize()
@projection.setZVector(newLookVector) @projection.setZVector(newLookVector)
@ -169,86 +166,85 @@ class Player extends Bot
cameraPos = @projection.getPosition() # current camera position cameraPos = @projection.getPosition() # current camera position
desiredDistance = 2.0 # desired distance from camera to bot desiredDistance = 2.0 # desired distance from camera to bot
updatePosition() @updatePosition()
playerPos = @current_position # desired look pos playerPos = @current_position # desired look pos
playerDir = getCurrentDir() playerDir = @getCurrentDir()
playerUp = current_orientation.rotate(KVector(0,1,0)).normal() playerUp = current_orientation.rotate(new Vector(0,1,0)).normal()
playerRight = playerDir.cross(playerUp).normal() playerRight = playerDir.cross(playerUp).normal()
# .................................................................. camera follows bot # ____________________________________________________ camera follows bot
# first, adjust distance from camera to bot # first, adjust distance from camera to bot
botToCamera = cameraPos - playerPos # vector from bot to current pos botToCamera = cameraPos.minus playerPos # vector from bot to current pos
cameraBotDistance = botToCamera.length() # distance from camera to bot cameraBotDistance = botToCamera.length() # distance from camera to bot
if cameraBotDistance >= desiredDistance if cameraBotDistance >= desiredDistance
difference = cameraBotDistance - desiredDistance difference = cameraBotDistance - desiredDistance
delta = (difference*difference)/400.0 # weight for following speed delta = difference*difference/400.0 # weight for following speed
cameraPos = (1.0 - delta) * cameraPos + delta * playerPos cameraPos = cameraPos.mul(1.0 - delta).plus playerPos.mul delta
else else
difference = desiredDistance - cameraBotDistance difference = desiredDistance - cameraBotDistance
delta = difference/20.0 # weight for negative following speed delta = difference/20.0 # weight for negative following speed
cameraPos = (1.0 - delta) * cameraPos + delta * (playerPos + desiredDistance * botToCamera.normal()) cameraPos = cameraPos.mul(1.0 - delta).plus (playerPos.plus botToCamera.normal().mul desiredDistance).mul delta
# .................................................................. refining camera position # ____________________________________________________ refining camera position
# second, rotate around bot # second, rotate around bot
botToCamera = cameraPos - playerPos botToCamera = cameraPos.minus playerPos
KVector botToCameraNormal = botToCamera.normal() botToCameraNormal = botToCamera.normal()
# .................................................................. try view bot from above # ____________________________________________________ try view bot from above
# if camera below bot, rotate up # if camera below bot, rotate up
if (botToCameraNormal * playerUp < 0) if botToCameraNormal.dot(playerUp) < 0
# calculate angle between player to camera vector and player up vector # calculate angle between player to camera vector and player up vector
verticalAngle = RAD2DEG (Math.acos(kMinMax(-1.0, 1.0, botToCameraNormal * playerUp))) - 90.0 verticalAngle = Vector.RAD2DEG Math.acos(kMinMax(-1.0, 1.0, botToCameraNormal.dot playerUp)) - 90.0
cameraPos = playerPos + KQuaternion.rotationAroundVector(verticalAngle/40.0, botToCameraNormal.cross(playerUp)).rotate(botToCamera) cameraPos = playerPos.plus Quaternion.rotationAroundVector(verticalAngle/40.0, botToCameraNormal.cross(playerUp)).rotate botToCamera
botToCamera = cameraPos - playerPos botToCamera = cameraPos.minus playerPos
botToCameraNormal = (cameraPos - playerPos).normal() botToCameraNormal = botToCamera.normal()
rot_factor = 1.0 rot_factor = 1.0
wall_distance = world.getWallDistanceForPos (playerPos + botToCamera) wall_distance = world.getWallDistanceForPos (playerPos + botToCamera)
if wall_distance < 0.5 if wall_distance < 0.5
# .................................................................. apiercing walls # ____________________________________________________ apiercing walls
if (wall_distance < 0.2) if (wall_distance < 0.2)
cameraPos = world.getInsideWallPosWithDelta cameraPos, 0.2 cameraPos = world.getInsideWallPosWithDelta cameraPos, 0.2
botToCamera = cameraPos - playerPos botToCamera = cameraPos.minus playerPos
botToCameraNormal = (cameraPos - playerPos).normal() botToCameraNormal = botToCamera.normal()
rot_factor = 0.5 / (wall_distance-0.2) rot_factor = 0.5 / (wall_distance-0.2)
# .................................................................. try view bot from behind # ____________________________________________________ try view bot from behind
# calculate horizontal angle between bot orientation and vector to camera # calculate horizontal angle between bot orientation and vector to camera
mappedToXZ ((botToCamera - playerUp * (botToCamera * playerUp)).normal()) mappedToXZ = (botToCamera.minus playerUp.mul(botToCamera.dot playerUp)).normal()
horizontalAngle = RAD2DEG (Math.acos(kMinMax(-1.0, 1.0, -playerDir * mappedToXZ))) horizontalAngle = Vector.RAD2DEG Math.acos(kMinMax(-1.0, 1.0, -playerDir.dot mappedToXZ))
if botToCameraNormal * playerRight > 0 if botToCameraNormal.dot(playerRight) > 0
horizontalAngle = -horizontalAngle horizontalAngle = -horizontalAngle
cameraPos = playerPos + KQuaternion.rotationAroundVector(horizontalAngle / (rot_factor * 400.0), playerUp).rotate botToCamera cameraPos = playerPos.plus Quaternion.rotationAroundVector(horizontalAngle / (rot_factor * 400.0), playerUp).rotate botToCamera
botToCamera = cameraPos - playerPos botToCamera = cameraPos.minus playerPos
botToCameraNormal = botToCamera.normal() botToCameraNormal = botToCamera.normal()
# .................................................................. finally, set the position # ____________________________________________________ finally, set the position
@projection.setPosition cameraPos @projection.setPosition cameraPos
# .................................................................. refining camera orientation # ____________________________________________________ refining camera orientation
# slowly adjust look direction by interpolating current and desired directions # slowly adjust look direction by interpolating current and desired directions
lookDelta = 2.0 - @projection.getZVector() * botToCameraNormal lookDelta = 2.0 - @projection.getZVector().dot botToCameraNormal
lookDelta *= lookDelta / 30.0 lookDelta *= lookDelta / 30.0
KVector newLookVector = (1.0 - lookDelta) * @projection.getZVector() + lookDelta * botToCameraNormal newLookVector = @projection.getZVector().mul(1.0 - lookDelta).plus botToCameraNormal.mul(lookDelta)
newLookVector.normalize() newLookVector.normalize()
# slowly adjust up vector by interpolating current and desired up vectors # slowly adjust up vector by interpolating current and desired up vectors
upDelta = 2.0 - @projection.getYVector() * playerUp upDelta = 2.0 - @projection.getYVector().dot playerUp
upDelta *= upDelta / 100.0 upDelta *= upDelta / 100.0
KVector newRightVector = ((1.0 - upDelta) * @projection.getYVector() + upDelta * playerUp).cross(newLookVector) KVector newRightVector = (@projection.getYVector().mul(1.0 - upDelta).plus playerUp.mul(upDelta)).cross newLookVector
newRightVector.normalize() newRightVector.normalize()
KVector newUpVector = newLookVector.cross(newRightVector).normal() newUpVector = newLookVector.cross(newRightVector).normal()
# finished interpolations, update camera matrix # finished interpolations, update camera matrix
@projection.setZVector newLookVector @projection.setZVector newLookVector
@ -263,12 +259,12 @@ class Player extends Bot
when Action.CLIMB_DOWN, Action.FORWARD when Action.CLIMB_DOWN, Action.FORWARD
@status.addMoves 1 @status.addMoves 1
when Action.TURN_LEFT, Action.TURN_RIGHT when Action.TURN_LEFT, Action.TURN_RIGHT
Controller.sound.playSound KikiSound.BOT_MOVE sound.playSound KikiSound.BOT_MOVE
when Action.JUMP, Action.JUMP_FORWARD when Action.JUMP, Action.JUMP_FORWARD
@status.addMoves actionId == Action.JUMP and 1 or 2 @status.addMoves actionId == Action.JUMP and 1 or 2
Controller.sound.playSound KikiSound.BOT_JUMP sound.playSound KikiSound.BOT_JUMP
KikiBot.initAction(action) super action
performAction: (action) -> performAction: (action) ->
relTime = action.getRelativeTime() relTime = action.getRelativeTime()
@ -288,7 +284,7 @@ class Player extends Bot
else else
@look_angle = Math.max @look_angle, (1.0-relTime) * -90.0 @look_angle = Math.max @look_angle, (1.0-relTime) * -90.0
else else
KikiBot.performAction action super action
finishAction: (action) -> finishAction: (action) ->
actionId = action.id actionId = action.id
@ -307,22 +303,22 @@ class Player extends Bot
if rotate if rotate
rotate_action = getActionWithId rotate rotate_action = getActionWithId rotate
rotate_action.reset() rotate_action.reset()
Controller.timer_event.addAction rotate_action Timer.addAction rotate_action
die: () -> die: () ->
# Controller.removeKeyHandler @ # Controller.removeKeyHandler @
super super
# Controller.displayText "game over" # Controller.displayText "game over"
# Controller.sound.playSound KikiSound.BOT_DEATH # sound.playSound KikiSound.BOT_DEATH
world.setCameraMode world.CAMERA_FOLLOW world.setCameraMode world.CAMERA_FOLLOW
reborn: () -> reborn: () ->
Controller.addKeyHandler @ # Controller.addKeyHandler @
died = false died = false
reset: () -> reset: () ->
KikiBot.reset() KikiBot.reset()
Controller.timer_event.removeActionsOfObject @ Timer.removeActionsOfObject @
@look_action = null @look_action = null
@look_angle = 0.0 @look_angle = 0.0
@ -364,9 +360,9 @@ class Player extends Bot
if keyName == turn_left_key or keyName == turn_right_key if keyName == turn_left_key or keyName == turn_right_key
rotate = (keyName == turn_left_key) and Action.TURN_LEFT or Action.TURN_RIGHT rotate = (keyName == turn_left_key) and Action.TURN_LEFT or Action.TURN_RIGHT
if (rotate_action == null and spiked == false) # player is not performing a rotation and unspiked if (@rotate_action == null and spiked == false) # player is not performing a rotation and unspiked
rotate_action = getActionWithId rotate @rotate_action = getActionWithId rotate
Controller.timer_event.addAction rotate_action Timer.addAction @rotate_action
return keyHandled() return keyHandled()
@ -382,7 +378,7 @@ class Player extends Bot
if keyName == shoot_key if keyName == shoot_key
if not shoot if not shoot
shoot = true shoot = true
Controller.timer_event.addAction @getActionWithId Action.SHOOT Timer.addAction @getActionWithId Action.SHOOT
return keyHandled() return keyHandled()
@ -390,7 +386,7 @@ class Player extends Bot
if not @look_action if not @look_action
@look_action = @getActionWithId (key.name == look_up_key) and Action.LOOK_UP or Action.LOOK_DOWN @look_action = @getActionWithId (key.name == look_up_key) and Action.LOOK_UP or Action.LOOK_DOWN
@look_action.reset() @look_action.reset()
Controller.timer_event.addAction @look_action Timer.addAction @look_action
return keyHandled() return keyHandled()
if keyName == view_key if keyName == view_key
@ -406,7 +402,7 @@ class Player extends Bot
true true
if keyName == shoot_key if keyName == shoot_key
Controller.timer_event.removeAction getActionWithId Action.SHOOT Timer.removeAction @getActionWithId Action.SHOOT
shoot = false shoot = false
return releaseHandled() return releaseHandled()
@ -420,8 +416,8 @@ class Player extends Bot
if @move_action == null and world.isUnoccupiedPos position.plus @getUp() if @move_action == null and world.isUnoccupiedPos position.plus @getUp()
jump_once = false jump_once = false
@move_action = getActionWithId Action.JUMP @move_action = getActionWithId Action.JUMP
Controller.sound.playSound KikiSound.BOT_JUMP sound.playSound KikiSound.BOT_JUMP
Controller.timer_event.addAction @move_action Timer.addAction @move_action
return releaseHandled() return releaseHandled()
if keyName == turn_left_key or keyName == turn_right_key if keyName == turn_left_key or keyName == turn_right_key
@ -434,9 +430,9 @@ class Player extends Bot
if keyName == look_down_key or keyName == look_up_key if keyName == look_down_key or keyName == look_up_key
if @look_action and @look_action.id != Action.LOOK_RESET if @look_action and @look_action.id != Action.LOOK_RESET
Controller.timer_event.removeAction @look_action Timer.removeAction @look_action
@look_action = getActionWithId Action.LOOK_RESET @look_action = getActionWithId Action.LOOK_RESET
Controller.timer_event.addAction @look_action Timer.addAction @look_action
return releaseHandled() return releaseHandled()
if keyName == view_key if keyName == view_key
@ -467,8 +463,8 @@ class Player extends Bot
return colors[KikiPlayer_tire_color] return colors[KikiPlayer_tire_color]
finishRotateAction: () -> finishRotateAction: () ->
if rotate_action if rotate_action
rotate = false @rotate = false
finishAction(rotate_action) @finishAction rotate_action
module.exports = Player module.exports = Player

17
coffee/timer.coffee Normal file
View File

@ -0,0 +1,17 @@
# 000000000 000 00 00 00000000 00000000
# 000 000 000 000 000 000 000
# 000 000 000000000 0000000 0000000
# 000 000 000 0 000 000 000 000
# 000 000 000 000 00000000 000 000
log = require '/Users/kodi/s/ko/js/tools/log'
class Timer
constructor: () ->
removeActionsOfObject: (o) -> log "removeActionsOfObject", o
addAction: (a) -> log "addAction", a
removeAction: (a) -> log "removeAction", a
module.exports = Timer

View File

@ -9,6 +9,7 @@ first,
last} = require "/Users/kodi/s/ko/js/tools/tools" last} = require "/Users/kodi/s/ko/js/tools/tools"
log = require "/Users/kodi/s/ko/js/tools/log" log = require "/Users/kodi/s/ko/js/tools/log"
Pos = require './lib/pos' Pos = require './lib/pos'
Size = require './lib/size'
Cell = require './cell' Cell = require './cell'
Light = require './light' Light = require './light'
Player = require './player' Player = require './player'
@ -30,6 +31,9 @@ class World
constructor: (@view) -> constructor: (@view) ->
@screenSize = new Size @view.clientWidth, @view.clientHeight
log "view @screenSize #{@screenSize}"
@renderer = new THREE.WebGLRenderer @renderer = new THREE.WebGLRenderer
antialias: true antialias: true
logarithmicDepthBuffer: true logarithmicDepthBuffer: true
@ -60,7 +64,6 @@ class World
# 0000000 0000000 00000000 000 000 00000000 # 0000000 0000000 00000000 000 000 00000000
@scene = new THREE.Scene() @scene = new THREE.Scene()
@geom = new THREE.BoxGeometry 10, 10, 10
# 000 000 0000000 000 000 000000000 # 000 000 0000000 000 000 000000000
# 000 000 000 000 000 000 # 000 000 000 000 000 000
@ -74,10 +77,8 @@ class World
@ambient = new THREE.AmbientLight 0x444444 @ambient = new THREE.AmbientLight 0x444444
@scene.add @ambient @scene.add @ambient
#
@preview = false @preview = false
@display_list = 0
@objects = [] @objects = []
@lights = [] @lights = []
@moved_objects = [] @moved_objects = []
@ -86,12 +87,36 @@ class World
@depth = -Number.MAX_SAFE_INTEGER @depth = -Number.MAX_SAFE_INTEGER
@camera_mode = World.CAMERA_BEHIND @camera_mode = World.CAMERA_BEHIND
@edit_projection = null @edit_projection = null
@edit_mode = false
@debug_camera = false
@debug_cells = false
@raster_size = 0.1 @raster_size = 0.1
# 0000000 0000000 0000000 00000000
# 000 000 000 000 000
# 000 000000000 000 0000 0000000
# 000 000 000 000 000 000
# 0000000 000 000 0000000 00000000
initCage: ->
log "initCage size:", @size
mat = new THREE.MeshPhongMaterial
color: 0x440000
side: THREE.BackSide
shading: THREE.SmoothShading
transparent: true
opacity: 0.5
shininess: 0.99
geom = new THREE.BoxGeometry @size.x, @size.y, @size.z
@cage = new THREE.Mesh geom, mat
@cage.translateX @size.x/2-0.5
@cage.translateY @size.y/2-0.5
@cage.translateZ @size.z/2-0.5
@scene.add @cage
# glDisable(GL_BLEND);
# glDisable(GL_DEPTH_TEST);
# glDisable(GL_ALPHA_TEST);
# glDisable(GL_NORMALIZE);
#
# # colors[World_plate_color].glColor();
#
@init: (view) -> @init: (view) ->
return if world? return if world?
@ -245,26 +270,24 @@ class World
# ............................................................ player # ............................................................ player
player = new Player @player = new Player
# player_dict = @dict.player
# player_dict = @dict["player"] log "player_dict", player_dict
# if player_dict.orientation?
# if "orientation" in player_dict @player.setOrientation player_dict.orientation
# player.setOrientation (player_dict["orientation"]) else
# else @player.setOrientation roty90
# player.setOrientation (roty90)
#
# if "position" in player_dict
# @addObjectAtPos player, @decenter(player_dict["position"])
# else if "coordinates" in player_dict
# pos = player_dict["coordinates"]
# @addObjectAtPos player, Pos(pos[0], pos[1], pos[2])
# if "nostatus" in player_dict if player_dict.position?
# if player_dict["nostatus"] or @preview @addObjectAtPos @player, @decenter player_dict.position
# Controller.player_status.hide() else if player_dict.coordinates?
@addObjectAtPos @player, new Pos player_dict.coordinates
# if player_dict.nostatus?
# if player_dict.nostatus or @preview
# @player_status.hide()
# else # else
# Controller.player_status.show() # @player_status.show()
# else # else
# if @preview # if @preview
# Controller.player_status.hide() # Controller.player_status.hide()
@ -273,8 +296,8 @@ class World
# #
# @getProjection().setPosition(KVector()) # @getProjection().setPosition(KVector())
# Controller.player.getStatus().setMinMoves (highscore.levelParMoves (@level_name)) # @player.getStatus().setMinMoves (highscore.levelParMoves (@level_name))
# Controller.player.getStatus().setMoves (0) # @player.getStatus().setMoves (0)
# ............................................................ init # ............................................................ init
# @init() # tell the world that we are finished # @init() # tell the world that we are finished
@ -471,13 +494,13 @@ class World
menu.addItem(Controller.getLocalizedString("quit"), once(Controller.quit)) menu.addItem(Controller.getLocalizedString("quit"), once(Controller.quit))
setSize: (size) -> setSize: (size) ->
log 'World.setSize!', size
@deleteAllObjects() @deleteAllObjects()
@cells = [] @cells = []
@size = new Pos size @size = new Pos size
# calcuate max distance (for position relative sound) # calcuate max distance (for position relative sound)
@max_distance = Math.max(@size.x, Math.max(@size.y, @size.z)) # heuristic of a heuristic :-) @max_distance = Math.max(@size.x, Math.max(@size.y, @size.z)) # heuristic of a heuristic :-)
@initCage()
getCellAtPos: (pos) -> return @cells[@posToIndex(pos)] if @isValidPos pos getCellAtPos: (pos) -> return @cells[@posToIndex(pos)] if @isValidPos pos
getBotAtPos: (pos) -> @getObjectOfTypeAtPos KikiBot, pos getBotAtPos: (pos) -> @getObjectOfTypeAtPos KikiBot, pos
@ -698,14 +721,17 @@ class World
# 0000000 000 00000000 000 # 0000000 000 00000000 000
step: (step) -> step: (step) ->
if true 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(1,0,0), step.dsecs*0.2)
quat.multiply (new THREE.Quaternion).setFromAxisAngle(new THREE.Vector3(0,1,0), step.dsecs*0.1) quat.multiply (new THREE.Quaternion).setFromAxisAngle(new THREE.Vector3(0,1,0), step.dsecs*0.1)
center = @decenter 0,0,0 # center = @decenter 0,0,0
center = @size.div 2
log center
@camera.position.set(center.x,center.y,center.z+@dist).applyQuaternion quat @camera.position.set(center.x,center.y,center.z+@dist).applyQuaternion quat
@camera.quaternion.copy quat @camera.quaternion.copy quat
@player.getProjection().apply @camera
@sun.position.copy @camera.position @sun.position.copy @camera.position
@renderer.render @scene, @camera @renderer.render @scene, @camera
@ -733,6 +759,7 @@ class World
@camera?.aspect = @aspect @camera?.aspect = @aspect
@camera?.updateProjectionMatrix() @camera?.updateProjectionMatrix()
@renderer?.setSize w,h @renderer?.setSize w,h
@screenSize = new Size w,h
getNearestValidPos: (pos) -> getNearestValidPos: (pos) ->
new KikiPos Math.min(size.x-1, Math.max(pos.x, 0)), new KikiPos Math.min(size.x-1, Math.max(pos.x, 0)),
@ -854,32 +881,4 @@ class World
@projection.initProjection() @projection.initProjection()
# glDisable(GL_BLEND);
# glDisable(GL_DEPTH_TEST);
# glDisable(GL_ALPHA_TEST);
# glDisable(GL_NORMALIZE);
#
# # colors[World_plate_color].glColor();
#
# glTranslatef(-0.5, -0.5, -0.5);
#
# displayWall(size.x, size.y); # xy+z
# glRotatef(180.0, 0.0, 1.0, 0.0);
# glTranslatef(-size.x, 0.0, -size.z);
# displayWall(size.x, size.y); # xy-z
#
# glRotatef(90.0, 1.0, 0.0, 0.0); # xz-y
# glTranslatef(0.0, 0.0, -size.y);
# displayWall(size.x, size.z);
# glRotatef(180.0, 0.0, 1.0, 0.0); # xz+y
# glTranslatef(-size.x, 0.0, -size.y);
# displayWall(size.x, size.z);
#
# glRotatef(-90.0, 0.0, 1.0, 0.0); # yz+x
# glTranslatef(0.0, 0.0, -size.x);
# displayWall(size.y, size.z);
# glRotatef(180.0, 1.0, 0.0, 0.0); # yz-x
# glTranslatef(0.0, -size.z, -size.x);
# displayWall(size.y, size.z);
module.exports = World module.exports = World