Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add LOD management functions #3831

Draft
wants to merge 38 commits into
base: master
Choose a base branch
from

Conversation

Fernando-A-Rocha
Copy link
Contributor

@Fernando-A-Rocha Fernando-A-Rocha commented Oct 29, 2024

Important

HLOD = High Level of Detail (normal models the player sees when near)
LLOD = Low Level of Detail (models with less detail the player sees when far)

Details

Adds new clientside model utility & Level-Of-Detail(LOD) management functions

WIP

To be used in conjunction with:

This solves the problem of having to include a Lua LOD_TABLE in every map's script, which has been happening for years (the map editor's LOD table happens to be incomplete as of submitting this PR), providing a simple solution to obtain an object's LLOD model ID in the code.

Related to multitheftauto/mtasa-resources#556

Examples

  • LLOD model of HLOD model ganghous03_LAx (3655) is lodganghous03_lax (3656).

  • Practical code examples:
    WIP

Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.Util.cpp Outdated Show resolved Hide resolved
Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.h Outdated Show resolved Hide resolved
Client/mods/deathmatch/logic/lua/CLuaManager.cpp Outdated Show resolved Hide resolved
Server/mods/deathmatch/logic/luadefs/CLuaFunctionDefs.cpp Outdated Show resolved Hide resolved
Server/mods/deathmatch/logic/luadefs/CLuaFunctionDefs.h Outdated Show resolved Hide resolved
Shared/mods/deathmatch/logic/CLodModels.cpp Outdated Show resolved Hide resolved
Shared/mods/deathmatch/logic/CLodModels.h Outdated Show resolved Hide resolved
Shared/mods/deathmatch/logic/CLodModels.h Outdated Show resolved Hide resolved
@FileEX
Copy link
Contributor

FileEX commented Oct 29, 2024

The lod arrays from the map editor are incomplete, so I assume this function is also incomplete. Therefore, a note should be added on the wiki once this PR is merged

@Fernando-A-Rocha
Copy link
Contributor Author

Fernando-A-Rocha commented Oct 29, 2024

The lod arrays from the map editor are incomplete, so I assume this function is also incomplete. Therefore, a note should be added on the wiki once this PR is merged

No. I completed the table. It's good now.
See the mtasa-resources issue I linked where I explain it.

@Fernando-A-Rocha Fernando-A-Rocha changed the title Add getObjectLODModel(int objectModel) Add getObjectLODModel and getObjectModelOfLOD Oct 30, 2024
@Fernando-A-Rocha Fernando-A-Rocha changed the title Add getObjectLODModel and getObjectModelOfLOD Add getObjectLODOfModel and getObjectModelOfLOD Oct 30, 2024
Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.h Outdated Show resolved Hide resolved
Client/mods/deathmatch/logic/lua/CLuaManager.cpp Outdated Show resolved Hide resolved
Client/mods/deathmatch/logic/luadefs/CLuaObjectDefs.cpp Outdated Show resolved Hide resolved
Server/mods/deathmatch/logic/luadefs/CLuaObjectDefs.cpp Outdated Show resolved Hide resolved
Server/mods/deathmatch/logic/luadefs/CLuaObjectDefs.h Outdated Show resolved Hide resolved
Shared/mods/deathmatch/logic/CLodModels.h Outdated Show resolved Hide resolved
Shared/mods/deathmatch/logic/CLodModels.cpp Outdated Show resolved Hide resolved
Shared/mods/deathmatch/logic/CLodModels.cpp Outdated Show resolved Hide resolved
Shared/mods/deathmatch/logic/CLodModels.h Outdated Show resolved Hide resolved
Client/mods/deathmatch/logic/luadefs/CLuaObjectDefs.cpp Outdated Show resolved Hide resolved
Client/mods/deathmatch/logic/luadefs/CLuaObjectDefs.cpp Outdated Show resolved Hide resolved
Client/mods/deathmatch/logic/luadefs/CLuaObjectDefs.h Outdated Show resolved Hide resolved
Server/mods/deathmatch/logic/luadefs/CLuaObjectDefs.cpp Outdated Show resolved Hide resolved
Server/mods/deathmatch/logic/luadefs/CLuaObjectDefs.cpp Outdated Show resolved Hide resolved
Server/mods/deathmatch/logic/luadefs/CLuaObjectDefs.h Outdated Show resolved Hide resolved
Shared/mods/deathmatch/logic/CLodModels.h Outdated Show resolved Hide resolved
@lotsofs
Copy link

lotsofs commented Nov 1, 2024

The provided LOD model list not only is incomplete, it also contains plain incorrections. Examples are the LLODs for HLOD models 10428, 10369, 10439.

@Fernando-A-Rocha
Copy link
Contributor Author

The provided LOD model list not only is incomplete, it also contains plain incorrections. Examples are the LLODs for HLOD models 10428, 10369, 10439.

I'm surprised, I thought the list was generated from the game files not missing anything.

Will you suggest a fix for the array?

@derxgbb
Copy link

derxgbb commented Nov 1, 2024

I'm surprised, I thought the list was generated from the game files not missing anything.

Will you suggest a fix for the array?

Just a note:
Even the game .ipl files are different in other ports (ps2, xbox etc). For example the lanterns and special objects around four dragon casino is only persistent on ps2/xbox. https://imgur.com/MV61hvH
The objects does exist but never used in game.
I don't know if .ide files are different, they shouldn't but who knows.

@Fernando-A-Rocha
Copy link
Contributor Author

Fernando-A-Rocha commented Nov 2, 2024

I'm gonna investigate the HLOD => LLOD array. @lotsofs @spooky-spook

I'm surprised, I thought the list was generated from the game files not missing anything.
Will you suggest a fix for the array?

Just a note: Even the game .ipl files are different in other ports (ps2, xbox etc). For example the lanterns and special objects around four dragon casino is only persistent on ps2/xbox. https://imgur.com/MV61hvH The objects does exist but never used in game. I don't know if .ide files are different, they shouldn't but who knows.

It's interesting that PS2 and XBOX versions of the games have different world mapping, but I think this is out of the scope of this LLOD-improvements PR.

https://tcrf.net/Grand_Theft_Auto:_San_Andreas/Version_and_Platform_Differences
There are a large number of objects in Las Venturas missing from the PC version, mainly outside the Four Dragons Casino and The Visage. This seems to be a simple omission from the map as they are still in the game.

@TheNormalnij
Copy link
Member

TheNormalnij commented Nov 21, 2024

Opinions?

I would prefer a simple solution with createObjectWithLod and createBuildingWithLod.
And i don't recommend using createObject instead of createBuilding for world models with LODs.
Objects doesn't have lod support in GTA. MTA uses dirty LOD support for objects

#include "CLodModels.h"

constexpr std::size_t OBJ_LOD_MODELS_COUNT = 4289;
constexpr std::pair<std::uint32_t, std::uint32_t> OBJ_LOD_MODELS_ARRAY[] = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need this array. Just define a hashmap

@Fernando-A-Rocha
Copy link
Contributor Author

Fernando-A-Rocha commented Nov 21, 2024

I would prefer a simple solution with createObjectWithLod and createBuildingWithLod. And i don't recommend using createObject instead of createBuilding for world models with LODs. Objects doesn't have lod support in GTA. MTA uses dirty LOD support for objects

createObjectWithLod and createBuildingWithLod sound good!

I am still in favor of implementing the new LOD ID management functions described the main post. They are useful for getting the LLOD id of an HLOD id, and also setting custom LLOD ids for custom systems.

Also, what do you think about making setObjectCustomLowLODModel(hlod, llod) automatically update the models of the game's LLOD landscape/world "buildings"/"objects" ? @TheNormalnij

@Kinimel
Copy link

Kinimel commented Nov 21, 2024

I can also make setObjectCustomLowLODModel(hlod, llod) automatically the models of the game's LLOD landscape/world "buildings"(objects).

It'd be useful for projects that a lot of LLOD models to objects that don't have LOD in GTA SA, giving the game a new look and feel.

E.g. https://www.mixmods.com.br/2021/12/lod-vegetation-distant-trees/

Opinions?

The new LLOD ID management functions are a big step towards a more robust and adaptable system. The possibility of customizing LLOD IDs for specific systems offers a high degree of control. The setObjectCustomLowLODModel function is particularly interesting. By automatically updating LLOD models, it not only simplifies development, but also helps to avoid visual inconsistencies in the game.

@PlatinMTA
Copy link
Contributor

I can also make setObjectCustomLowLODModel(hlod, llod) automatically the models of the game's LLOD landscape/world "buildings"(objects).

yes that would be nice... although im guessing that function is also useful for custom models. My request was surely really specific so I'm not sure everyone would like that... maybe we could have a third argument that if its true then we can make that function behave like described (changing all lods?).

I'm down to test that change if needed because i think it would be pretty cool. Otherwise the only way to implement loads of LLODs to existing world buildings would be to delete them all (reading IPL files, parsing those) and create new ones. Second option seems to be too problematic/not worth it.

Out of the scope of this PR but maybe we should have a way to retrieve all world objects in some way. Right now if you want to find a world object you need to use processLineOfSight or similar, unless something was added and I didn't notice it. Otherwise you can get your IPL files and parse them yourself.

@Fernando-A-Rocha
Copy link
Contributor Author

I can also make setObjectCustomLowLODModel(hlod, llod) automatically the models of the game's LLOD landscape/world "buildings"(objects).

yes that would be nice... although im guessing that function is also useful for custom models. My request was surely really specific so I'm not sure everyone would like that... maybe we could have a third argument that if its true then we can make that function behave like described (changing all lods?).

I'm down to test that change if needed because i think it would be pretty cool. Otherwise the only way to implement loads of LLODs to existing world buildings would be to delete them all (reading IPL files, parsing those) and create new ones. Second option seems to be too problematic/not worth it.

Out of the scope of this PR but maybe we should have a way to retrieve all world objects in some way. Right now if you want to find a world object you need to use processLineOfSight or similar, unless something was added and I didn't notice it. Otherwise you can get your IPL files and parse them yourself.

Sure, I'd like to add the feature to automatically update world object LLODs.

For finding all world objects, I have parsed all of the game IPLs. This is enough tbh, and you can easily use Lua scripts for your needs.

I put everything here, including the binary ipls I converted to text. https://github.com/Fernando-A-Rocha/mta-binary-ipl-to-text

@Fernando-A-Rocha Fernando-A-Rocha marked this pull request as draft November 25, 2024 14:57
@Fernando-A-Rocha Fernando-A-Rocha changed the title Add object LOD management functions Add LOD management functions Nov 25, 2024
@Fernando-A-Rocha
Copy link
Contributor Author

Fernando-A-Rocha commented Nov 26, 2024

Check it out so far, ive redone some functions. Moved things to model related files. Added isValidModel (general purpose func)

@TheNormalnij I added model id checks, and also made it reset in engineFreeModel and when model manager is unloaded. Is this ok?

CLuaCFunctions::AddFunction(name, func);
}

bool CLuaModelDefs::IsValidModel(std::string modelPurpose, std::uint32_t id)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about an enum instead of string?


bool CLuaModelDefs::SetModelLOD(std::string modelPurpose, std::uint32_t hLODModel, std::uint32_t lLODModel)
{
if (!(modelPurpose == "object" || modelPurpose == "building"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if(modelPurpose != "object" && modelPurpose != "building")


constexpr std::size_t OBJ_LOD_MODELS_COUNT = 4289;
constexpr std::pair<std::uint32_t, std::uint32_t> OBJ_LOD_MODELS_ARRAY[] = {
{694, 784}, // sm_redwoodgrp => lod_redwoodgrp (countryS)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe too much spacing before the comment?
{X, Y}, // comment
instead of
{X, Y}, // comment

Comment on lines 3521 to 4320
{13804, 13808}, // cuntelandf4 => lodcuntelandf4 (LAhills)
{13805, 13807}, // celalandbiv => lodcelalandbiv (LAhills)
{13809, 13811}, // ce_grndpalcst02 => lodcepalcst02 (LAhills)
{13810, 13812}, // ce_grndpalcst05 => lodce_grndpalcst05 (LAhills)
{13813, 13815}, // cegraveblok03e => lodcegraveblok03e (LAhills)
{13814, 13787}, // ceroadn => lodceroadn (LAhills)
{13816, 13877}, // ce_safeground => ce_s
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we really need that?

@lynconsix
Copy link

Any other news? This PR is interesting!

@ds1-e
Copy link
Contributor

ds1-e commented Dec 14, 2024

These functions should be shared, like setLowLODElement is. e.g: if you would like to create object on server-side, and get it's LOD model directly.

@lynconsix
Copy link

What is missing for this PR to be completed?

@Nico8340
Copy link
Contributor

Any updates on this? @Fernando-A-Rocha

@Fernando-A-Rocha
Copy link
Contributor Author

I'll get back to this PR soon.

There are several ways to approach the problem of LODs. We certainly need something that is both clientside and serverside due to createObject, createBuilding (soon available serverside) and setLowLodElement being shared functions...

@lotsofs
Copy link

lotsofs commented Jan 6, 2025

I am back with my manually built list of HLOD vs LLODs, using the removeWorldObject feature from the editor on every object in the map, and where that failed finding a manual match using the IDE list on the wiki or similar.
MTASA Maps - Sheet17.csv

Here are my conclusions, and more importantly, things that I think should be changed in the big table in CLodModels.cpp:

Missing entries
These are all objects that gave me trouble deleting them in the editor, their LLOD would still show after deletion, and I had to manually find their LLODs in the IDE list. They are also missing from the table in CLodModels.cpp

    {10289, 10156},            // tempsf_3_sfe => LODA27 (???)
    {10561, 10681},            // bbgroundbitc_SFS => LODroundbitc_SFS (???)
    {10933, 11275},            // traintrax01_SFS => LOD_trax_SFSe07 (???)
    {10973, 11025},            // mall_03_SFS => LOD_sfs014 (???)
    {11228, 11277},            // traintrax01b_SFS => LOD_trax_SFSe08 (???)
    {11231, 11273},            // traintrax03b_SFS => LOD_trax_SFSe01 (???)
    {11232, 11274},            // traintrax03c_SFS => LOD_trax_SFSe06 (???)
    {11409, 11347},            // roadsSFSE34 => LODroadsSFSE34 (???)
    {17614, 17843},            // Lae2_landHUB02 => LODLae2_lndHUB02 (???)
    {4826, 4987},              // grifftop2 => LODfftop03 (???)
    {7498, 7843},              // vegaswrailroad01 => lodaswrailroad01 (???)
    {7582, 7951},              // miragebuild04 => lodagebuild04 (???)
    {7625, 7957},              // vgnhseing129 => lodhseing129 (???)
    {7878, 7879},              // vegasNroad242 => hubst4alpha (???)
    {8386, 8387},              // vgsSspagjun09b => lodSspagjun09b (???)
    {8388, 8389},              // vegasSedge29b => lodasSedge29b (???)
    {9310, 9390},              // chapel_SFN => LODpel_SFN (???)
    {9889, 9890},              // park3a_sfw => lod_park3a_sfw (???)
    {9239, 9405},              // track01_SFN => LODck01_SFN (???)
    {9240, 9404},              // track02_SFN => LODck02_SFN (???)

HLODs using the same LLOD
These objects all use LLOD 17749, in addition to the already included HLOD 17559:

    {17556, 17749},            // MStorCP1_LAe2 => LOD1MStorCP_LAe (???)
    {17557, 17749},            // MStorCP2_LAe2 => LOD1MStorCP_LAe (???)
    {17558, 17749},            // MStorCP4_LAe2 => LOD1MStorCP_LAe (???)

multiple LLODs belonging to the same HLOD
These objects all appear the same HLOD, but have different LLODs for some reason:
Inclusion recommended if it is desired that a user can request a HLOD belonging to a specific LLOD.
(not including entry oilderricklod01 that is already in the table)

    {3427, 16274},             // derrick01 => oilderricklod02 (???)
    {3427, 16275},             // derrick01 => oilderricklod03 (???)
    {3427, 16276},             // derrick01 => oilderricklod04 (???)
    {3427, 16277},             // derrick01 => oilderricklod05 (???)
    {3427, 16278},             // derrick01 => oilderricklod06 (???)
    {3427, 16279},             // derrick01 => oilderricklod07 (???)

Furthermore there is this entry: but it has other issues (read below)

    {3724, 5352},              // laxrf_cargotop => LODcargoshp03f (???)

LLODs that cover multiple HLODs
Existing entry:
{7243, 6996}, // vgncircus1b => lodcircus1 (vegasN)
is correct, but LLOD 6996 covers both HLODs 6994 and 7243 combined. The former is an entire casino building, and the latter is only the hedges surrounding its parking lot. A second opinion might be needed on what to do with this, but I'd heavily recommend changing the line to
{6994, 6996}, // vgncircus1b => lodcircus1 (vegasN)
as it makes much more sense after a visual inspectation.

Existing entry:
{9504, 9634}, // sboxbld4_sfw73 => lodxbld4_sfw73 (SFw)
is correct, but LLOD 9634 covers both HLODs 9504 and 9505 combined. The former is a big hill with houses on top, the latter is only the grass textures of the tiny gardens belonging to these houses. The line is fine as it is, but in the interest of completeness I thought it worth mentioning here.

Incorrect entries
Existing entry:
{3412, 3413}, // cunterb03 => lodcunterb07 (countrye)
is incorrect. HLOD 3412 is only the orange upper parts of a bridge, whereas HLOD 3411 is the entire bridge, including yet even more orange upper parts. LLOD 3413 matches HLOD 3412 much more closely
{3411, 3413}, // cunteRB01 => lodcunterb07 (countrye)

Existing entry:
{5786, 5945}, // shutters01_lawn => lodblok08_lawn (LaWn)
is incorrect. HLOD 5786 comprises just a set of door that go on entire building HLOD 5784 that LLOD 5945 matches much more closely.
{5784, 5945}, // MelBlok08_LAwN => lodblok08_lawn (LaWn)
However, the LLOD seems to be rotated 180 degrees compared to the HLOD 5784. Someone else besides me should look at this and make a judgement call.

Actually upon second thought, these are probably yet another cases of LLODs that cover multiple HLODs, but I already marked them as plainly incorrect and I can't be bothered rewriting.

LLOD to a LLOD
Existing entries:
{7174, 7366}, // lod_corpbuild31 => sham_superlod (vegasN)
{6971, 7174}, // vgn_corpbuild31 => lod_corpbuild31 (vegasN)
7174 is the LLOD for HLOD 6971, with 7366 in turn being a LLOD (SuperLOD) to 7174. Odd case. both cases are already in the list, so no action is needed I guess, but I had this in my notes and maybe someone has opinions.

Oddities that require subjective review
Non exhaustive list of objects that might give issues:

Existing entry
{3724, 5164}, // laxrf_cargotop => lodcargoshp03d (LAs2)
is correct, but the LLOD is rotated 90 degrees compared to its HLOD counterpart. This might give unwanted behavior. This also applies to the LODcargoshp03f I mentioned above, it is also rotated 90 degrees.

I dont have time to write the last entry, so here's my raw notes:
HLOD 9690, LLOD 9686
HLOD 9694, LLOD 9692
This concerns the pillars of Gant bridge. The HLOD 9690 and 9694 are each half a pillar (one the southern, one the northern), placed twice with one rotated 180 degrees so it connects. LLOD 9686 and 9692 is a single model representing an entire pillar. A subjective judgement call is needed for this. Furthermore: Deleting the pillar in the map editor reveals yet another model, which looks somewhat like a skeletal structure of like a character model. Someone should look at what the hell is going on here.

I'd submit my suggested changes myself, but I have no idea how to do a pull request to a pull request.

@Fernando-A-Rocha
Copy link
Contributor Author

Wow thank you for your detailed review @lotsofs
I'll definitely take a deeper look
I've added you to my repository Fernando-A-Rocha/mtasa-blue so you can contribute to this branch directly!! 😃

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.