155 lines
4.7 KiB
Lua
155 lines
4.7 KiB
Lua
local sincos = require("glm").sincos
|
|
local rad = require("glm").rad
|
|
local abs = math.abs
|
|
|
|
local getCamCoords = GetFinalRenderedCamCoord
|
|
local getCamRot = GetFinalRenderedCamRot
|
|
local getEntityCoords = GetEntityCoords
|
|
local disableControls = DisableAllControlActions
|
|
local drawLine = DrawLine
|
|
local getCamMatrix = GetCamMatrix
|
|
local createCamera = Utils.CreateCamera
|
|
local handleFlyCam = Utils.HandleFlyCam
|
|
local drawScaleform = Utils.DrawScaleform
|
|
|
|
raycast = {
|
|
cameraOptions = {
|
|
controls = { "up", "right", "forward" }
|
|
}
|
|
}
|
|
|
|
function raycast.getForwardVector(self)
|
|
local camRot = getCamRot(2)
|
|
local sinResult, cosResult = sincos(rad(camRot))
|
|
return vec3(
|
|
-sinResult.z * abs(cosResult.x),
|
|
cosResult.z * abs(cosResult.x),
|
|
sinResult.x
|
|
)
|
|
end
|
|
|
|
function raycast.gameplayCamera(self, callback, options, flags)
|
|
assert(type(callback) == "function", "raycast:gameplayCamera ::: fn must be a function")
|
|
|
|
options = options or {}
|
|
self.controls = Utils.GetControls(options)
|
|
self.scaleform = Utils.CreateInstructional(self.controls)
|
|
self.active = true
|
|
|
|
if not flags then flags = 17 end
|
|
|
|
while self.active do
|
|
DisablePlayerFiring(cache.playerId, true)
|
|
|
|
local camPos = getCamCoords()
|
|
local forward = self:getForwardVector() * 50.0
|
|
local endPos = camPos + forward
|
|
|
|
local rayHandle = StartExpensiveSynchronousShapeTestLosProbe(
|
|
camPos.x, camPos.y, camPos.z,
|
|
endPos.x, endPos.y, endPos.z,
|
|
flags, cache.ped, 4
|
|
)
|
|
|
|
local pedPos = getEntityCoords(cache.ped)
|
|
local _, hitResult, hitCoords, _, hitEntity = GetShapeTestResultIncludingMaterial(rayHandle)
|
|
|
|
self.coords = hitCoords
|
|
self.entity = (hitEntity ~= 0 and hitEntity) or nil
|
|
self.hit = (hitResult == 1)
|
|
|
|
if self.hit then
|
|
DrawMarker(28,
|
|
self.coords.x, self.coords.y, self.coords.z,
|
|
0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
|
0.2, 0.2, 0.2, 255, 42, 24, 100,
|
|
false, false, 0, true, false, false, false
|
|
)
|
|
drawLine(
|
|
pedPos.x, pedPos.y, pedPos.z,
|
|
self.coords.x, self.coords.y, self.coords.z,
|
|
255, 42, 24, 100
|
|
)
|
|
end
|
|
|
|
callback(self)
|
|
drawScaleform(self.scaleform)
|
|
self.lastCoords = self.coords
|
|
Wait(0)
|
|
end
|
|
end
|
|
|
|
function raycast.freeCamera(self, callback, extraControls)
|
|
assert(type(callback) == "function", "raycast:camera ::: fn must be a function")
|
|
|
|
local _, forward, _, origin = GetEntityMatrix(cache.ped)
|
|
local camPos = origin + forward * 2
|
|
local camRot = GetEntityRotation(cache.ped)
|
|
|
|
self.camRot = camRot
|
|
self.camPos = camPos
|
|
self.camera = createCamera("DEFAULT_SCRIPTED_CAMERA", camPos, camRot, true)
|
|
self.active = true
|
|
|
|
SetPlayerControl(cache.playerId, false, 0)
|
|
|
|
local allControls = table.deepclone(self.cameraOptions.controls)
|
|
if extraControls then
|
|
for _, ctrl in pairs(extraControls) do
|
|
allControls[#allControls + 1] = ctrl
|
|
end
|
|
end
|
|
|
|
self.controls = Utils.GetControls(allControls)
|
|
self.scaleform = Utils.CreateInstructional(self.controls)
|
|
|
|
while self.active do
|
|
disableControls(0)
|
|
|
|
self.camPos, self.camRot = handleFlyCam(self.camera)
|
|
|
|
local _, rightVec, _, _ = getCamMatrix(self.camera)
|
|
local endPos = vec3(
|
|
self.camPos.x + rightVec.x * 100.0,
|
|
self.camPos.y + rightVec.y * 100.0,
|
|
self.camPos.z + rightVec.z * 100.0
|
|
)
|
|
|
|
local rayHandle = StartExpensiveSynchronousShapeTestLosProbe(
|
|
self.camPos.x, self.camPos.y, self.camPos.z,
|
|
endPos.x, endPos.y, endPos.z,
|
|
17, cache.ped, 4
|
|
)
|
|
|
|
local _, _, hitCoords, _, hitEntity = GetShapeTestResultIncludingMaterial(rayHandle)
|
|
|
|
self.coords = hitCoords
|
|
self.entity = hitEntity
|
|
self.hit = (hitResult == 1)
|
|
|
|
local cx, cy, cz = self.coords.x, self.coords.y, self.coords.z
|
|
drawLine(cx - 0.3, cy, cz, cx + 0.3, cy, cz, 255, 0, 0, 255)
|
|
drawLine(cx, cy, cz, cx, cy, cz + 0.3, 255, 0, 0, 255)
|
|
drawLine(cx, cy - 0.3, cz, cx, cy + 0.3, cz, 255, 0, 0, 255)
|
|
|
|
drawScaleform(self.scaleform)
|
|
callback(self)
|
|
Wait(0)
|
|
end
|
|
end
|
|
|
|
function raycast.destroy(self)
|
|
self.active = false
|
|
if self.camera then
|
|
Utils.DestroyFlyCam(self.camera, 1000)
|
|
self.camera = nil
|
|
SetPlayerControl(cache.playerId, true, 0)
|
|
end
|
|
end
|
|
|
|
AddEventHandler("onResourceStop", function(resourceName)
|
|
if resourceName == GetCurrentResourceName() then
|
|
raycast:destroy()
|
|
end
|
|
end)
|