Lunatic: make hitscan accept ray as vector, add xmath.kangvec.

Also, add hitscan test to test.lua -- a crosshair-like sprite is spawned
and continuously updated to the position of where the player aims at.

git-svn-id: https://svn.eduke32.com/eduke32@4059 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2013-09-13 20:23:54 +00:00
parent 694975b2f5
commit e94fa7f70f
4 changed files with 47 additions and 20 deletions

View file

@ -512,6 +512,7 @@ end
local xmath = require("xmath") local xmath = require("xmath")
local abs = math.abs local abs = math.abs
local bangvec, kangvec = xmath.bangvec, xmath.kangvec
local dist, ldist = xmath.dist, xmath.ldist local dist, ldist = xmath.dist, xmath.ldist
local vec3, ivec3 = xmath.vec3, xmath.ivec3 local vec3, ivec3 = xmath.vec3, xmath.ivec3
local rotate = xmath.rotate local rotate = xmath.rotate
@ -1345,10 +1346,6 @@ function _awayfromwall(spr, d)
return true return true
end end
local function cossinb(bang)
return xmath.cosb(bang), xmath.sinb(bang)
end
-- TODO: xmath.vec3 'mhlen2' method? -- TODO: xmath.vec3 'mhlen2' method?
local function manhatdist(v1, v2) local function manhatdist(v1, v2)
return abs(v1.x-v2.x) + abs(v1.y-v2.y) return abs(v1.x-v2.x) + abs(v1.y-v2.y)
@ -1364,9 +1361,8 @@ local function A_FurthestVisiblePoint(aci, otherspr)
local j = 0 local j = 0
repeat repeat
local c, s = cossinb(otherspr.ang + j) local ray = kangvec(otherspr.ang + j, 16384-krandand(32767))
local hit = hitscan(otherspr^(16*256), otherspr.sectnum, local hit = hitscan(otherspr^(16*256), otherspr.sectnum, ray, ffiC.CLIPMASK1)
c, s, 16384-krandand(32767), ffiC.CLIPMASK1)
local dother = manhatdist(hit.pos, otherspr) local dother = manhatdist(hit.pos, otherspr)
local dactor = manhatdist(hit.pos, sprite[aci]) local dactor = manhatdist(hit.pos, sprite[aci])
@ -1439,7 +1435,8 @@ end
-- CON "hitscan" command -- CON "hitscan" command
function _hitscan(x, y, z, sectnum, vx, vy, vz, cliptype) function _hitscan(x, y, z, sectnum, vx, vy, vz, cliptype)
local srcv = ivec3(x, y, z) local srcv = ivec3(x, y, z)
local hit = hitscan(srcv, sectnum, vx, vy, vz, cliptype) local ray = ivec3(vx, vy, vz)
local hit = hitscan(srcv, sectnum, ray, cliptype)
return hit.sect, hit.wall, hit.sprite, hit.pos.x, hit.pos.y, hit.pos.z return hit.sect, hit.wall, hit.sprite, hit.pos.x, hit.pos.y, hit.pos.z
end end
@ -1508,15 +1505,12 @@ end
local function A_CheckHitSprite(spr, angadd) local function A_CheckHitSprite(spr, angadd)
local zoff = (spr:isenemy() and 42*256) or (ispic(spr.picnum, "APLAYER") and 39*256) or 0 local zoff = (spr:isenemy() and 42*256) or (ispic(spr.picnum, "APLAYER") and 39*256) or 0
local c, s = cossinb(spr.ang+angadd) local hit = hitscan(spr^zoff, spr.sectnum, kangvec(spr.ang+angadd), ffiC.CLIPMASK1)
local hit = hitscan(spr^zoff, spr.sectnum, c, s, 0, ffiC.CLIPMASK1)
if (hit.wall >= 0 and wall[hit.wall]:ismasked() and spr:isenemy()) then if (hit.wall >= 0 and wall[hit.wall]:ismasked() and spr:isenemy()) then
return -1, nil return -1, nil
end end
local dx = hit.pos.x-spr.x return hit.sprite, ldist(hit.pos, spr)
local dy = hit.pos.y-spr.y
return hit.sprite, math.sqrt(dx*dx+dy*dy) -- TODO: use "ldist" approximation for authenticity
end end
function _canshoottarget(dst, aci) function _canshoottarget(dst, aci)

View file

@ -1196,14 +1196,13 @@ end
---=== Engine functions, wrapped for Lua convenience ===--- ---=== Engine functions, wrapped for Lua convenience ===---
-- returns a hitdata_ct -- returns a hitdata_ct
-- TODO: make v[xyz] be passed as one aggregate, too?
-- TODO: make cliptype optional? What should be the default? -- TODO: make cliptype optional? What should be the default?
function hitscan(pos, sectnum, vx,vy,vz, cliptype) function hitscan(pos, sectnum, ray, cliptype)
check_sector_idx(sectnum) check_sector_idx(sectnum)
local vec = vec3_ct(pos.x, pos.y, pos.z) local vec = vec3_ct(pos.x, pos.y, pos.z)
local hitdata = hitdata_ct() local hitdata = hitdata_ct()
ffiC.hitscan(vec, sectnum, vx,vy,vz, hitdata, cliptype) ffiC.hitscan(vec, sectnum, ray.x, ray.y, ray.z, hitdata, cliptype)
return hitdata return hitdata
end end

View file

@ -469,6 +469,35 @@ local TROOPSTRENGTH = 30
local AF = actor.FLAGS local AF = actor.FLAGS
local CS = sprite.CSTAT local CS = sprite.CSTAT
-- Crosshair sprite.
-- NOTE: This ought to be a gamevar -- if a savegame is restored, a new one
-- will be spawned.
local chair
gameactor{ D.APLAYER, AF.chain_end,
function(aci, pli)
if (chair == nil) then
chair = con.spawn(555, aci)
printf("Spawned our crosshair: sprite %d", chair)
local spr = sprite[chair]
-- Set to STAT_MISC because otherwise interpolation goes crazy (old
-- value never updated; dunno why...)
sprite.changestat(chair, actor.STAT.MISC)
spr.xrepeat, spr.yrepeat = 96, 96
spr.cstatbits:set(CS.CENTER)
end
local ps = player[pli]
local ray = xmath.kangvec(ps.ang, -(ps.horiz-100)*2048)
local hit = hitscan(ps.pos, ps.cursectnum, ray, 0)
if (hit.sect >= 0) then
sprite[chair]:setpos(hit.pos)
sprite.changesect(chair, hit.sect)
end
end
}
-- Also test actor code chaining: strength is doubled. -- Also test actor code chaining: strength is doubled.
gameactor gameactor
{ {
@ -483,7 +512,7 @@ gameactor
local spr = sprite[i] local spr = sprite[i]
local t = gv.gethiticks() local t = gv.gethiticks()
local hit = hitscan(spr, spr.sectnum, 10, 10, 0, gv.CLIPMASK0) local hit = hitscan(spr, spr.sectnum, {x=10, y=10, z=0}, gv.CLIPMASK0)
hs:add(1000*(gv.gethiticks()-t)) hs:add(1000*(gv.gethiticks()-t))
@ -534,7 +563,7 @@ gameactor
-- Polymost: only for "ghost" -- Polymost: only for "ghost"
-- Polymer: none -- Polymer: none
local aimv = 256*xmath.bangvec(tspr.ang) local aimv = 256*xmath.bangvec(tspr.ang)
local hit = hitscan(tspr^(16*256), tspr.sectnum, aimv.x, aimv.y, 0, gv.CLIPMASK1) local hit = hitscan(tspr^(16*256), tspr.sectnum, aimv, gv.CLIPMASK1)
if (hit.wall >= 0) then if (hit.wall >= 0) then
local aimtspr = tspr:dup() local aimtspr = tspr:dup()

View file

@ -292,11 +292,16 @@ local vec2, vec3 = vec2, vec3
local intarg = ffi.new("int32_t [1]") local intarg = ffi.new("int32_t [1]")
function bangvec(bang) function bangvec(bang)
intarg[0] = bang -- round towards zero intarg[0] = bang -- round towards zero
return vec3(cosb(intarg[0]), sinb(intarg[0])) return dvec3_t(cosb(intarg[0]), sinb(intarg[0]))
end
function kangvec(bang, z)
intarg[0] = bang -- round towards zero
return ivec3_t(kcos(intarg[0]), ksin(intarg[0]), z or 0)
end end
function angvec(ang) function angvec(ang)
return vec3(cos(ang), sin(ang)) return dvec3_t(cos(ang), sin(ang))
end end