Question Getting Error when attempting to access mesh vertex data, but code works?

Thunder Chicken

Resident Lua Script Rabble-Rouser
Donator
Joined
Mar 22, 2008
Messages
5,847
Reaction score
5,509
Points
188
Location
Massachusetts
I am getting the following error in console and in the Orbiter log

============================ ERROR: ===========================
Config/Vessels/J3Script/set_anim.lua:157: attempt to index global 'ges' (a nil value)
stack traceback:
Config/Vessels/J3Script/set_anim.lua:157: in function 'Autocoordinate'
Config/Vessels/J3Script/J3Script.lua:192: in function <Config/Vessels/J3Script/J3Script.lua:175>
[ScriptVessel::LuaCall | D:\a\orbiter\orbiter\Src\Vessel\ScriptVessel\ScriptVessel.cpp | 259]
===============================================================

Screenshot at 2024-11-16 18-19-11.png

I get this error either at Line 148 or Line 157 in a function that switches the instrument mesh UV coordinates to show a switch throw, depending on the status of the boolean coordinate_hold at the start of the session:

Code:
function set_anim.Autocoordinate()

    --shift UV coordinates of instrument panel texture to toggle switch

    if coordinate_hold == true then

        ges.Vtx[1].tv = 1.0         --this is line 148
        ges.Vtx[2].tv = 1.0
        ges.Vtx[3].tv = 0.5
        ges.Vtx[4].tv = 0.5

        oapi.edit_meshgroup(hdevmesh, 23, ges)

    elseif coordinate_hold == false then

        ges.Vtx[1].tv = 0.5            --this is line 157  
        ges.Vtx[2].tv = 0.5
        ges.Vtx[3].tv = 0.0
        ges.Vtx[4].tv = 0.0

        oapi.edit_meshgroup(hdevmesh, 23, ges)

    end

end

ges is a structure that contains the mesh vertex data:

Code:
function clbk_visualcreated(vis, refcount)

    hdevmesh = vi:get_devmesh(vis,0)

    nvtx = 4
    vtx = oapi.create_ntvertexarray(nvtx)
    vidx = oapi.create_indexarray({0,1,2,3})

    ges = {}
    ges.flags = GRPEDIT.VTXTEXV
    ges.Vtx = vtx
    ges.VIdx = vidx

end

coordinate_hold is initialized to false in the script, and is read in if it is available in the scenario file using clbk_loadstateex.

This had been working previously, but I realized that I had to edit the code as I initially had the texture shift done inside of a keypress callback which didn't register the boolean if it was read from the scenario file at the start of the session. It is showing the correct texture map according to the boolean in the scenario file at the start of the session, the coordinate_hold boolean and the texture switches correctly during the session. There are no other errors, even after toggling back and forth several times.
 
Maybe your Autocoordinate method is called before clbk_visualcreated ? Once clbk_visualcreated is called, ges is instanciated and the animation gets to work.
You should add a guard (if ges ~= nil then xxx).
Also ges should be reset to nil on clbk_visualdestroyed. Actually I just noticed a typo in the VesselScript where it looks for "clbk_visualdestroyes" instead of clbk_visualdestroyed... I'll push a fix tomorrow.
 
Maybe your Autocoordinate method is called before clbk_visualcreated ? Once clbk_visualcreated is called, ges is instanciated and the animation gets to work.
The autocoordinate function is called in clbk_poststep. I've tried it in clbk_prestep and it makes no difference. I'm not sure how Orbiter calls them, but clbk_visualcreated is before clbk_poststep in the script, if that matters.
You should add a guard (if ges ~= nil then xxx).
OK, but why would it be nil?
Also ges should be reset to nil on clbk_visualdestroyed.
Why is this? The texture should be displayed continuously. Is clbk_visualdestroyed called at the end of the session?
Actually I just noticed a typo in the VesselScript where it looks for "clbk_visualdestroyes" instead of clbk_visualdestroyed... I'll push a fix tomorrow.
Progress! Thanks for your help.
 
Are global variables global over multiple script files? Is ges set to nil at any point or by accident?
 
You should add a guard (if ges ~= nil then xxx).
This seems to resolve the error, but I'm not sure why it was necessary?
Are global variables global over multiple script files? Is ges set to nil at any point or by accident?
No. It's only created in clbk_visualcreated and is only referenced in the calling function.

I do need to clean up my globals though. But they're so easy! :)
 
The autocoordinate function is called in clbk_poststep. I've tried it in clbk_prestep and it makes no difference. I'm not sure how Orbiter calls them, but clbk_visualcreated is before clbk_poststep in the script, if that matters.
clbk_visualcreated is called when the vessel is deemed close enough to the camera to be displayed. Before that the mesh for the vessel does not exist and Orbiter only performs physical actions on the vessel.
clbk_visualdestroyed is called (once I fix the ScriptVessel) when the vessel is out of visual range.
They are not called every frame but only when the visual state changes.

I don't know exactly the order in which the callbacks are executed during startup and if it's possible that clbk_prestep is called before clbk_visualcreated but you should make your code robust to it since it will happen if you have for example one vessel on earth and another on the moon. Both won't be rendered at the same time so clbk_visualcreated will only be called for one of them at startup.
OK, but why would it be nil?
ges will be nil as long as clbk_visualcreated has not been called once. For symmetry you should reset it to nil when the visual is destroyed.
Why is this? The texture should be displayed continuously. Is clbk_visualdestroyed called at the end of the session?
No, the texture should not be displayed when the focus is on another ship, yet clbk_prestep/poststep will be called for this vessel.
 
This seems to resolve the error, but I'm not sure why it was necessary?

Most likely because at the time of execution, ges was still unknown to the interpreter.
 
Most likely because at the time of execution, ges was still unknown to the interpreter.
Exactly, Lua makes no difference between an undefined variable and one which has been assigned the nil value.
There is a StrictMode option that can be specified which will generate errors when trying to access undefined globals from functions but I would not advise using it if you're not already well versed in Lua.
 
I just made a pull request for the fix but there is something fishy going on with the github builds.
Also taking a look at the Orbiter code, seems like the current behavior is not the same as documented. Visuals are not destroyed when going outside of visual range, at least not with the D3D GCs. As a result the callback is only called when the session is closed.
 
Back
Top