Skip to content

Add client-side function to retrieve world models from memory pools (getStreamedWorldModels) - #5318

Open
iManGaaX wants to merge 8 commits into
multitheftauto:masterfrom
iManGaaX:feature/get-streamed-world-models
Open

Add client-side function to retrieve world models from memory pools (getStreamedWorldModels)#5318
iManGaaX wants to merge 8 commits into
multitheftauto:masterfrom
iManGaaX:feature/get-streamed-world-models

Conversation

@iManGaaX

@iManGaaX iManGaaX commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a new client-side Lua function (getStreamedWorldModels) to query and retrieve world buildings and objects directly from the game's internal pools, filtering out MTA-managed entities and un-streamed RenderWare objects.

Function API Reference

  • Syntax: table getStreamedWorldModels ( void )
  • Returns: A Lua table containing an array of tables for each valid world building/object currently loaded in memory. Each entry represents an object with the following keys:
    • type (string): The entity category ("building" or "object").
    • model (number): The model ID of the world object.
    • x, y, z (number): The 3D world coordinates of the object.
    • rx, ry, rz (number): The rotation angles (Euler angles in degrees) of the object.
    • interior (number): The interior/area code of the object.
    • ipl (number): The IPL file index.
    • lodModel (number): The model ID of the associated LOD variant (or 0 if none).
    • lod (boolean): Flag indicating whether the entity has an LOD pointer (m_pLod != nullptr).
    • collisions (boolean): Flag indicating if the object uses collision.
    • isStatic (boolean): Flag indicating if the object is static.
    • visible (boolean): Flag indicating if the object is visible.
    • Object-specific keys (only present when type == "object"):
      • health (number): The health value of the object.
      • scale (number): The scale factor of the object.

Motivation

Provides developers with a reliable and efficient way to interact with original GTA:SA world models for custom tool development, map editors, or specialized interaction frameworks without conflicting with existing MTA elements.

Test plan

  1. Compile the client changes with the new pool scanning implementation.
  2. Load into a server and execute the test command to call the function.
  3. Verify that world buildings and objects are correctly retrieved with accurate positions, rotations, and model IDs without causing performance drops or memory leaks.

2026-09-04.18-30-02.mp4

Test Script:
The following Lua script was used to verify the functionality, filter out LOD models, spawn test objects locally within a 100-meter radius, and render accurate transformation-based bounding boxes for video demonstration:

local createdTestObjects = {}

addCommandHandler("testworldobjs", function()
	for _, objData in ipairs(createdTestObjects) do
		if isElement(objData.element) then
			destroyElement(objData.element)
		end
	end
	createdTestObjects = {}

	local worldObjects = getStreamedWorldModels()

	local px, py, pz = getElementPosition(localPlayer)
	local maxDistance = 100
	local nearbyObjects = {}

	for _, obj in ipairs(worldObjects) do
		local modelName = engineGetModelNameFromID(obj.model)
		local isLodModel = modelName and string.find(string.lower(modelName), "lod")

		if not isLodModel and not obj.lod then
			local distance = getDistanceBetweenPoints3D(px, py, pz, obj.x, obj.y, obj.z)
			if distance <= maxDistance then
				table.insert(nearbyObjects, obj)
			end
		end
	end

	for _, obj in ipairs(nearbyObjects) do
		local objectElement = createObject(obj.model, obj.x, obj.y, obj.z, obj.rx or 0, obj.ry or 0, obj.rz or 0)

		if objectElement then
			table.insert(createdTestObjects, { element = objectElement })
		end
	end
end)

function drawBoundingBox(obj)
	if not isElement(obj) then return end

	local minX, minY, minZ, maxX, maxY, maxZ = getElementBoundingBox(obj)
	if not minX then return end

	local matrix = getElementMatrix(obj)
	if not matrix then return end

	local function getPoint(lx, ly, lz)
		local x = lx * matrix[1][1] + ly * matrix[2][1] + lz * matrix[3][1] + matrix[4][1]
		local y = lx * matrix[1][2] + ly * matrix[2][2] + lz * matrix[3][2] + matrix[4][2]
		local z = lx * matrix[1][3] + ly * matrix[2][3] + lz * matrix[3][3] + matrix[4][3]
		return x, y, z
	end

	local corners = {
		{getPoint(minX, minY, minZ)},
		{getPoint(maxX, minY, minZ)},
		{getPoint(maxX, maxY, minZ)},
		{getPoint(minX, maxY, minZ)},
		{getPoint(minX, minY, maxZ)},
		{getPoint(maxX, minY, maxZ)},
		{getPoint(maxX, maxY, maxZ)},
		{getPoint(minX, maxY, maxZ)},
	}

	local lines = {
		{1,2}, {2,3}, {3,4}, {4,1},
		{5,6}, {6,7}, {7,8}, {8,5},
		{1,5}, {2,6}, {3,7}, {4,8}
	}

	for _, line in ipairs(lines) do
		local a = corners[line[1]]
		local b = corners[line[2]]

		dxDrawLine3D(a[1], a[2], a[3], b[1], b[2], b[3], tocolor(255, 0, 0, 255), 2)
	end
end

addEventHandler("onClientRender", root, function()
	for _, objData in ipairs(createdTestObjects) do
		if isElement(objData.element) then
			drawBoundingBox(objData.element)
		end
	end
end)

Checklist

  • Your code should follow the coding guidelines.
  • Smaller pull requests are easier to review. If your pull request is beefy, your pull request should be reviewable commit-by-commit.

Added GetStreamedWorldModels function to retrieve world model data.
Removed GetStreamedWorldModels function and its implementation.
Removed declaration for GetStreamedWorldModels.
Added GetStreamedWorldModels function to retrieve world model data and populate Lua table.
@FileEX FileEX added the enhancement New feature or request label Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants