From 2acfe785db771cbc4747b85081fdc7ea49c36953 Mon Sep 17 00:00:00 2001 From: monsterkodi Date: Sun, 14 Aug 2016 14:04:02 +0200 Subject: [PATCH] perspective --- coffee/action.coffee | 20 +++++++++++++------- coffee/bot.coffee | 8 ++++---- coffee/lib/pos.coffee | 20 ++++++++++---------- coffee/lib/vector.coffee | 8 ++++++-- coffee/player.coffee | 16 +++++++++++----- coffee/pushable.coffee | 2 ++ coffee/world.coffee | 11 +++-------- 7 files changed, 49 insertions(+), 36 deletions(-) diff --git a/coffee/action.coffee b/coffee/action.coffee index 31ee7d9..7d328cc 100644 --- a/coffee/action.coffee +++ b/coffee/action.coffee @@ -65,14 +65,18 @@ class Action # log "Action.finished #{@name} #{@object?.actionFinished?}" @object.actionFinished @ return if @deleted - if @current == @getDuration() # if keepRest wasn't called -> reset start and current values - @reset() + @reset() + # if @current >= @getDuration() # if keepRest wasn't called -> reset start and current values + # @reset() + # else + # log 'keeping rest', @current reset: () -> - @start = 0 - @rest = 0 - @last = 0 - @current = 0 + log "action.reset #{@name}" + @start = 0 # world time + @rest = 0 + @last = 0 # relative + @current = 0 # relative takeRest: (action) -> @current = action.rest @@ -83,7 +87,9 @@ class Action keepRest: () -> if @rest != 0 @current = @rest - @rest = 0 + @rest = 0 + # @last = 0 + # @current = 0 getRelativeTime: -> @current / @getDuration() getRelativeDelta: -> (@current-@last) / @getDuration() diff --git a/coffee/bot.coffee b/coffee/bot.coffee index 4810e08..f7fde74 100644 --- a/coffee/bot.coffee +++ b/coffee/bot.coffee @@ -155,9 +155,9 @@ class Bot extends Pushable # 000 000 0000000 000 000 0000000 000 000 initAction: (action) -> - # log "initAction #{action.name}" newPos = new Pos @position - + log "initAction #{action.name} pos", newPos + switch action.id when Action.NOOP then return when Action.FORWARD then newPos.add @getDir() @@ -176,8 +176,8 @@ class Bot extends Pushable super action return - if not newPos.eql @position - # log 'bot.initAction', newPos + if not newPos.eql new Pos @position + log 'bot.initAction objectWillMoveToPos:', newPos world.objectWillMoveToPos @, newPos, action.getDuration() # 00000000 00000000 00000000 00000000 0000000 00000000 00 00 diff --git a/coffee/lib/pos.coffee b/coffee/lib/pos.coffee index 709a140..bc915b2 100644 --- a/coffee/lib/pos.coffee +++ b/coffee/lib/pos.coffee @@ -12,10 +12,10 @@ class Pos constructor: (x=0, y=0, z=0) -> - if (x instanceof Vector) or (x instanceof Pos) + if x.x? and x.y? @x = Math.round x.x @y = Math.round x.y - @z = Math.round x.z + @z = Math.round x.z ? 0 else if Array.isArray x @x = Math.round x[0] @y = Math.round x[1] @@ -24,11 +24,11 @@ class Pos @x = Math.round x @y = Math.round y @z = Math.round z - log "Pos #{x} #{y} #{z}", @ + # log "Pos #{@x} #{@y} #{@z}" if Number.isNaN @x throw new Error - vector: () -> new Vector x, y, z + vector: -> new Vector @x, @y, @z minus: (p) -> new Pos @x-p.x, @y-p.y, @z-p.z plus: (p) -> new Pos @x+p.x, @y+p.y, @z+p.z mul: (f) -> new Pos @x*f, @y*f, @z*f @@ -36,15 +36,15 @@ class Pos eql: (p) -> @x==p.x and @y==p.y and @z==p.z add: (p) -> - @x = parseInt @x + p.x - @y = parseInt @y + p.y - @z = parseInt @z + p.z + @x = Math.round @x + p.x + @y = Math.round @y + p.y + @z = Math.round @z + p.z @ sub: (p) -> - @x = parseInt @x - p.x - @y = parseInt @y - p.y - @z = parseInt @z - p.z + @x = Math.round @x - p.x + @y = Math.round @y - p.y + @z = Math.round @z - p.z @ module.exports = Pos diff --git a/coffee/lib/vector.coffee b/coffee/lib/vector.coffee index d562cce..aa73cb2 100644 --- a/coffee/lib/vector.coffee +++ b/coffee/lib/vector.coffee @@ -113,11 +113,15 @@ class Vector @pointMappedToPlane: (point, planePos, planeNormal) -> point.minus(planeNormal).dot point.minus(planePos).dot(planeNormal) - @rayPlaneIntersectionFactor: (rayPos, rayDirection, planePos, planeNormal) -> + @rayPlaneIntersectionFactor: (rayPos, rayDir, planePos, planeNormal) -> # ((planePos - rayPos) * planeNormal) / (rayDirection * planeNormal); - r = planePos.minus(rayPos).dot(planeNormal) / rayDirection.dot(planeNormal) + r = planePos.minus(rayPos).dot(planeNormal) / rayDir.dot(planeNormal) # log 'rayPlaneIntersectionFactor', r if Number.isNaN r + log 'rayPos', rayPos + log 'rayDir', rayDir + log 'planePos', planePos + log 'planeNormal', planeNormal throw new Error r diff --git a/coffee/player.coffee b/coffee/player.coffee index 6eb2a7d..b95b96d 100644 --- a/coffee/player.coffee +++ b/coffee/player.coffee @@ -67,8 +67,9 @@ class Player extends Bot updatePosition: () -> if @move_action - relTime = (world.getTime() - @move_action.start) / @move_action.duration - if relTime <= 1.0 + relTime = (world.getTime()-@move_action.start) / @move_action.duration + # log "updatePosition #{@move_action.id} #{relTime} #{@move_action.start} #{world.getTime()}" + if 0 <= relTime <= 1.0 switch @move_action.id when Action.FORWARD @current_position = @position.plus @getDir().mul relTime @@ -101,7 +102,7 @@ class Player extends Bot 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).minus playerDir.mul lookDelta + newLookVector = @projection.getZVector().mul(1.0 - lookDelta).plus playerDir.mul lookDelta newLookVector.normalize() @projection.setXVector playerUp.cross(newLookVector).normal() @projection.setYVector playerUp @@ -166,7 +167,6 @@ class Player extends Bot @updatePosition() playerPos = @current_position # desired look pos - # log 'getFollowProjection.current_position', @current_position playerDir = @getCurrentDir() playerUp = @current_orientation.rotate new Vector(0,1,0).normal() playerRight = playerDir.cross(playerUp).normal() @@ -177,6 +177,8 @@ class Player extends Bot botToCamera = cameraPos.minus playerPos # vector from bot to current pos cameraBotDistance = botToCamera.length() # distance from camera to bot + # log 'getFollowProjection 1', botToCamera, cameraPos, playerPos + if cameraBotDistance >= desiredDistance difference = cameraBotDistance - desiredDistance delta = difference*difference/400.0 # weight for following speed @@ -186,6 +188,8 @@ class Player extends Bot delta = difference/20.0 # weight for negative following speed cameraPos = cameraPos.mul(1.0-delta).plus (playerPos.plus botToCamera.normal().mul desiredDistance).mul delta + # log 'getFollowProjection 2', botToCamera, cameraPos, playerPos + # ____________________________________________________ refining camera position # second, rotate around bot @@ -201,9 +205,11 @@ class Player extends Bot botToCamera = cameraPos.minus playerPos botToCameraNormal = botToCamera.normal() + + # log 'getFollowProjection 3', botToCamera, cameraPos, playerPos rotFactor = 1.0 - # log "playerPos", playerPos + wall_distance = world.getWallDistanceForPos playerPos.plus botToCamera if wall_distance < 0.5 # ____________________________________________________ piercing walls diff --git a/coffee/pushable.coffee b/coffee/pushable.coffee index 30a2b46..d69f6be 100644 --- a/coffee/pushable.coffee +++ b/coffee/pushable.coffee @@ -4,6 +4,7 @@ # 000 000 000 000 000 000 000 000 000 000 000 000 # 000 0000000 0000000 000 000 000 000 0000000 0000000 00000000 +log = require '/Users/kodi/s/ko/js/tools/log' Item = require './item' Action = require './action' Vector = require './lib/vector' @@ -33,6 +34,7 @@ class Pushable extends Item initAction: (action) -> switch action.id when Action.FALL + log 'fall!' world.objectWillMoveToPos @, @position.plus(@direction), action.getDuration() performAction: (action) -> diff --git a/coffee/world.coffee b/coffee/world.coffee index 32d0a50..134fab3 100644 --- a/coffee/world.coffee +++ b/coffee/world.coffee @@ -384,7 +384,6 @@ class World extends Actor isValidPos: (pos) -> p = new Pos pos - log 'isValidPos', p p.x >= 0 and p.x < @size.x and p.y >= 0 and p.y < @size.y and p.z >= 0 and p.z < @size.z isInvalidPos: (pos) -> not @isValidPos pos @@ -810,7 +809,7 @@ class World extends Actor o.step?(step) for o in @objects switch @camera_mode - when World.CAMERA_INSIDE then @projection = @player.getProjection() + 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.apply @camera @@ -925,7 +924,6 @@ class World extends Actor f = Vector.rayPlaneIntersectionFactor pos, World.normals[w].neg(), planePos, World.normals[w] if f < delta insidePos.add World.normals[w].mul delta-f - # log 'getInsideWallPosWithDelta', insidePos insidePos getWallDistanceForPos: (pos) -> # distance to the next wall (positive or negative) @@ -934,19 +932,16 @@ class World extends Actor planePos = new Vector -0.5, -0.5, -0.5 if w >= 3 then planePos.add @size f = Vector.rayPlaneIntersectionFactor pos, World.normals[w].neg(), planePos, World.normals[w] - # log "getWallDistanceForPos w #{w} min_f #{min_f} f #{f}" min_f = absMin min_f, f - # log "getWallDistanceForPos #{min_f}", pos min_f - getWallDistanceForRay: (rayPos, rayDirection) -> # distance to the next wall in rayDirection + getWallDistanceForRay: (rayPos, rayDir) -> # distance to the next wall in rayDir min_f = 10000 for w in [0..5] planePos = new Vector -0.5, -0.5, -0.5 if w >= 3 then planePos.add @size - f = Vector.rayPlaneIntersectionFactor rayPos, rayDirection, planePos, World.normals[w] + f = Vector.rayPlaneIntersectionFactor rayPos, rayDir, planePos, World.normals[w] min_f = f if f >= 0.0 and f < min_f - # log "getWallDistanceForRay #{min_f}", rayDirection min_f displayLights: () ->