GE Lua Documentation

Press F to search!

spawnBoundaryMarkers

Definition


-- @/lua/ge/extensions/gameplay/crawl/boundary.lua:172

-- Utility function to spawn flag markers along crawl boundary
local function spawnBoundaryMarkers(boundary, spacing)
  if not boundary or not boundary.vertices or #boundary.vertices < 3 then
    log('W', logTag, 'Invalid boundary for spawning markers')
    return
  end

  spacing = spacing or 2.0 -- Default spacing of 2 meters

  -- Clean up existing boundary markers
  if spawnedBoundaryMarkersId then
    local group = scenetree.findObjectById(spawnedBoundaryMarkersId)
    if group then
      group:delete()
    end
    spawnedBoundaryMarkersId = nil
  end

  -- Reset boundary objects tracking
  resetBoundaryObjects()

  -- Create a new group for boundary markers
  local markerGroup = createObject("SimGroup")
  markerGroup:registerObject(Sim.getUniqueName("BoundaryMarkers"))
  scenetree.MissionGroup:addObject(markerGroup)
  spawnedBoundaryMarkersId = markerGroup:getId()

  local flagMeshPath = "/art/shapes/race/flagMarker.dae"
  local points = {}

  -- Generate points along the boundary perimeter
  for i, vertex in ipairs(boundary.vertices) do
    local nextIdx = vertex.next or (i == #boundary.vertices and 1 or i + 1)
    local nextVertex = boundary.vertices[nextIdx]

    local startPos = vertex.pos
    local endPos = nextVertex.pos
    local segmentLength = startPos:distance(endPos)

    local numMarkers = math.floor(segmentLength / spacing)
    if numMarkers < 1 then numMarkers = 1 end

    for j = 0, numMarkers - 1 do
      local t = j / numMarkers
      local pos = lerp(startPos, endPos, t)

      if core_terrain then
        pos.z = core_terrain.getTerrainHeight(pos) or pos.z
      else
        pos.z = be:getSurfaceHeightBelow(pos + vec3(0, 0, 1)) + 0.1
      end

      local terrainNormal = vec3(0, 0, 1)
      if core_terrain then
        terrainNormal = core_terrain.getTerrainSmoothNormal(pos) or vec3(0, 0, 1)
      else
        terrainNormal = map.surfaceNormal(pos, 1) or vec3(0, 0, 1)
      end

      local worldUp = vec3(0, 0, 1)
      local terrainUpDot = terrainNormal:dot(worldUp)

      if terrainUpDot >= 0.5 then
        local dirVec = (endPos - startPos):normalized()
        local rot = quatFromDir(dirVec, worldUp)
        table.insert(points, {pos = pos, rot = rot})
      end
    end
  end

  for i, point in ipairs(points) do
    local name = Sim.getUniqueName("BoundaryFlag_" .. i)
    local marker = createObject('TSStatic')
    marker:setField('shapeName', 0, flagMeshPath)
    marker.scale = vec3(1, 1, 1)
    marker.useInstanceRenderData = true
    marker:setField('instanceColor', 0, '1 1 1 1')
    marker:setInternalName('boundaryMarker')
    marker.canSave = false
    marker:registerObject(name)

    local objectId = marker:getId()
    boundaryObjects[objectId] = {
      finalPosition = vec3(point.pos),
      animationState = "hidden",
      animationTimer = 0,
      lastVisible = false
    }

    marker:setPosRot(point.pos.x, point.pos.y, point.pos.z, point.rot.x, point.rot.y, point.rot.z, point.rot.w)
    marker:setScale(vec3(minScale, minScale, minScale))
    marker:setField('instanceColor', 0, '1 1 1 0')
    marker:updateInstanceRenderData()

    markerGroup:addObject(marker)
  end

  buildBoundaryQuadtree()

  log('D', logTag, string.format('Spawned %d boundary markers along crawl boundary', #points))
  return spawnedBoundaryMarkersId
end

Callers

@/lua/ge/extensions/gameplay/crawl/utils.lua
  if gameplay_crawl_general.activeTrail and gameplay_crawl_general.activeTrail.boundary then
    gameplay_crawl_boundary.spawnBoundaryMarkers(gameplay_crawl_general.activeTrail.boundary, 5.0)
  end