Implementing two default MFDs in VC on Lua

misha.physics

Well-known member
Joined
Dec 22, 2021
Messages
1,481
Reaction score
2,225
Points
128
Location
Lviv
Preferred Pronouns
he/him
I have an aircraft mesh with two square meshgroups located in XY plane. I would like to use them as displays for two default MFDs in virtual 3D cockpit, that will be synchronized with two ones in generic glass cockpit. There are two vessel examples based on Lua with MFDs in VC, namely Delta-glider and Atlantis. There are far fewer Lua scripts for Atlantis, so I thought it will be easier to take it as an example. It looks like the main "Atlantis.lua" script contains all code for MFDs implementations, maybe the following piece, but I am not sure:
C++:
----------------------------------------------------------------
-- Respond to MFD mode change
----------------------------------------------------------------
function clbk_MFDmode(mfd, mode)
    oapi.VC_trigger_redrawarea(-1, AID_CDR1_BUTTONS + mfd - MFDID.LEFT)
end

----------------------------------------------------------------
-- Load generic glass cockpit mode
----------------------------------------------------------------
function clbk_loadgenericcockpit()
    vi:set_cameraoffset(_V(-0.67, 2.55, 14.4))
    vi:set_cameradefaultdirection(_V(0, 0, 1))
    return true
end

----------------------------------------------------------------
-- register VC buttons for the 2 commander MFDs
-- (accessible from commander position only)
----------------------------------------------------------------
local function registerVC_CdrMFD()
    -- activate MFD function buttons
    oapi.VC_set_areaclickmode_quadrilateral(AID_CDR1_BUTTONS, _V(-0.9239,2.0490,15.0595), _V(-0.7448,2.0490,15.0595),  _V(-0.9239,2.0280,15.0595), _V(-0.7448,2.0280,15.0595))
    oapi.VC_set_areaclickmode_quadrilateral(AID_CDR2_BUTTONS, _V(-0.6546,2.0490,15.0595), _V(-0.4736,2.0490,15.0595),  _V(-0.6546,2.0280,15.0595), _V(-0.4736,2.0280,15.0595))

    -- D. Beachy: register+activate MFD power buttons
    local powerButtonRadius = 0.0075 -- radius of power button on each MFD
    oapi.VC_register_area(AID_CDR1_PWR, PANEL_REDRAW.NEVER, bit.bor(PANEL_MOUSE.LBDOWN, PANEL_MOUSE.ONREPLAY))
    oapi.VC_register_area(AID_CDR2_PWR, PANEL_REDRAW.NEVER, bit.bor(PANEL_MOUSE.LBDOWN, PANEL_MOUSE.ONREPLAY))
    oapi.VC_set_areaclickmode_spherical(AID_CDR1_PWR, _V(-0.950, 2.060, 15.060), powerButtonRadius)
    oapi.VC_set_areaclickmode_spherical(AID_CDR2_PWR, _V(-0.680, 2.060, 15.060), powerButtonRadius)

    -- register+activate MFD brightness buttons
    oapi.VC_register_area(AID_CDR1_BRT, PANEL_REDRAW.NEVER, bit.bor(PANEL_MOUSE.LBDOWN, PANEL_MOUSE.LBPRESSED, PANEL_MOUSE.ONREPLAY))
    oapi.VC_register_area(AID_CDR2_BRT, PANEL_REDRAW.NEVER, bit.bor(PANEL_MOUSE.LBDOWN, PANEL_MOUSE.LBPRESSED, PANEL_MOUSE.ONREPLAY))
    oapi.VC_set_areaclickmode_quadrilateral(AID_CDR1_BRT, _V(-0.729,2.0675,15.060), _V(-0.714,2.0675,15.060), _V(-0.729,2.0525,15.060), _V(-0.714,2.0525,15.060))
    oapi.VC_set_areaclickmode_quadrilateral(AID_CDR2_BRT, _V(-0.459,2.0675,15.060), _V(-0.444,2.0675,15.060), _V(-0.459,2.0525,15.060), _V(-0.444,2.0525,15.060))
end


----------------------------------------------------------------
-- register VC buttons for the 2 pilot MFDs
-- (accessible from pilot position only)
----------------------------------------------------------------
local function registerVC_PltMFD()
    -- activate MFD function buttons
    oapi.VC_set_areaclickmode_quadrilateral(AID_PLT1_BUTTONS, _V(0.4759,2.0490,15.0595), _V(0.6568,2.0490,15.0595),  _V(0.4759,2.0280,15.0595), _V(0.6568,2.0280,15.0595))
    oapi.VC_set_areaclickmode_quadrilateral(AID_PLT2_BUTTONS, _V(0.7461,2.0490,15.0595), _V(0.9271,2.0490,15.0595),  _V(0.7461,2.0280,15.0595), _V(0.9271,2.0280,15.0595))

    -- D. Beachy: register+activate MFD power buttons
    local powerButtonRadius = 0.0075 -- radius of power button on each MFD
    oapi.VC_register_area(AID_PLT1_PWR, PANEL_REDRAW.NEVER, bit.bor(PANEL_MOUSE.LBDOWN, PANEL_MOUSE.ONREPLAY))
    oapi.VC_register_area(AID_PLT2_PWR, PANEL_REDRAW.NEVER, bit.bor(PANEL_MOUSE.LBDOWN, PANEL_MOUSE.ONREPLAY))
    oapi.VC_set_areaclickmode_spherical(AID_PLT1_PWR, _V( 0.450, 2.060, 15.060), powerButtonRadius)
    oapi.VC_set_areaclickmode_spherical(AID_PLT2_PWR, _V( 0.720, 2.060, 15.060), powerButtonRadius)

    -- register+activate MFD brightness buttons
    oapi.VC_register_area(AID_PLT1_BRT, PANEL_REDRAW.NEVER, bit.bor(PANEL_MOUSE.LBDOWN, PANEL_MOUSE.LBPRESSED, PANEL_MOUSE.ONREPLAY))
    oapi.VC_register_area(AID_PLT2_BRT, PANEL_REDRAW.NEVER, bit.bor(PANEL_MOUSE.LBDOWN, PANEL_MOUSE.LBPRESSED, PANEL_MOUSE.ONREPLAY))
    oapi.VC_set_areaclickmode_quadrilateral(AID_PLT1_BRT, _V(0.671,2.0675,15.060), _V(0.686,2.0675,15.060), _V(0.671,2.0525,15.060), _V(0.686,2.0525,15.060))
    oapi.VC_set_areaclickmode_quadrilateral(AID_PLT2_BRT, _V(0.941,2.0675,15.060), _V(0.956,2.0675,15.060), _V(0.941,2.0525,15.060), _V(0.956,2.0525,15.060))
end


----------------------------------------------------------------
-- register VC buttons for the 5 MFDs on the central panel
-- (accessible from commander and pilot positions)
----------------------------------------------------------------
local function registerVC_CntMFD()
    -- activate MFD function buttons
    oapi.VC_set_areaclickmode_quadrilateral(AID_MFD1_BUTTONS, _V(-0.3579,2.1451,15.0863), _V(-0.1770,2.1451,15.0863), _V(-0.3579,2.1241,15.0863), _V(-0.1770,2.1241,15.0863))
    oapi.VC_set_areaclickmode_quadrilateral(AID_MFD2_BUTTONS, _V(-0.3579,1.9143,15.0217), _V(-0.1770,1.9143,15.0217), _V(-0.3579,1.8933,15.0217), _V(-0.1770,1.8933,15.0217))
    oapi.VC_set_areaclickmode_quadrilateral(AID_MFD3_BUTTONS, _V(-0.0888,2.0288,15.0538), _V(0.0922,2.0288,15.0538), _V(-0.0888,2.0078,15.0538), _V(0.0922,2.0078,15.0538))
    oapi.VC_set_areaclickmode_quadrilateral(AID_MFD4_BUTTONS, _V(0.1795,2.1451,15.0863), _V(0.3604,2.1451,15.0863), _V(0.1795,2.1241,15.0863), _V(0.3604,2.1241,15.0863))
    oapi.VC_set_areaclickmode_quadrilateral(AID_MFD5_BUTTONS, _V(0.1795,1.9143,15.0217), _V(0.3604,1.9143,15.0217), _V(0.1795,1.8933,15.0217), _V(0.3604,1.8933,15.0217))

    -- D. Beachy: register+activate MFD power buttons
    local powerButtonRadius = 0.0075 -- radius of power button on each MFD
    oapi.VC_register_area(AID_MFD1_PWR, PANEL_REDRAW.NEVER, bit.bor(PANEL_MOUSE.LBDOWN, PANEL_MOUSE.ONREPLAY))
    oapi.VC_register_area(AID_MFD2_PWR, PANEL_REDRAW.NEVER, bit.bor(PANEL_MOUSE.LBDOWN, PANEL_MOUSE.ONREPLAY))
    oapi.VC_register_area(AID_MFD3_PWR, PANEL_REDRAW.NEVER, bit.bor(PANEL_MOUSE.LBDOWN, PANEL_MOUSE.ONREPLAY))
    oapi.VC_register_area(AID_MFD4_PWR, PANEL_REDRAW.NEVER, bit.bor(PANEL_MOUSE.LBDOWN, PANEL_MOUSE.ONREPLAY))
    oapi.VC_register_area(AID_MFD5_PWR, PANEL_REDRAW.NEVER, bit.bor(PANEL_MOUSE.LBDOWN, PANEL_MOUSE.ONREPLAY))
    oapi.VC_set_areaclickmode_spherical(AID_MFD1_PWR, _V(-0.383, 2.153, 15.090), powerButtonRadius)
    oapi.VC_set_areaclickmode_spherical(AID_MFD2_PWR, _V(-0.383, 1.922, 15.023), powerButtonRadius)
    oapi.VC_set_areaclickmode_spherical(AID_MFD3_PWR, _V(-0.114, 2.037, 15.058), powerButtonRadius)
    oapi.VC_set_areaclickmode_spherical(AID_MFD4_PWR, _V( 0.155, 2.153, 15.090), powerButtonRadius)
    oapi.VC_set_areaclickmode_spherical(AID_MFD5_PWR, _V( 0.155, 1.922, 15.023), powerButtonRadius)

    -- register+activate MFD brightness buttons
    oapi.VC_register_area(AID_MFD1_BRT, PANEL_REDRAW.NEVER, bit.bor(PANEL_MOUSE.LBDOWN, PANEL_MOUSE.LBPRESSED, PANEL_MOUSE.ONREPLAY))
    oapi.VC_register_area(AID_MFD2_BRT, PANEL_REDRAW.NEVER, bit.bor(PANEL_MOUSE.LBDOWN, PANEL_MOUSE.LBPRESSED, PANEL_MOUSE.ONREPLAY))
    oapi.VC_register_area(AID_MFD3_BRT, PANEL_REDRAW.NEVER, bit.bor(PANEL_MOUSE.LBDOWN, PANEL_MOUSE.LBPRESSED, PANEL_MOUSE.ONREPLAY))
    oapi.VC_register_area(AID_MFD4_BRT, PANEL_REDRAW.NEVER, bit.bor(PANEL_MOUSE.LBDOWN, PANEL_MOUSE.LBPRESSED, PANEL_MOUSE.ONREPLAY))
    oapi.VC_register_area(AID_MFD5_BRT, PANEL_REDRAW.NEVER, bit.bor(PANEL_MOUSE.LBDOWN, PANEL_MOUSE.LBPRESSED, PANEL_MOUSE.ONREPLAY))
    oapi.VC_set_areaclickmode_quadrilateral(AID_MFD1_BRT, _V(-0.162,2.1605,15.090), _V(-0.147,2.1605,15.090), _V(-0.162,2.1455,15.090), _V(-0.147,2.1455,15.090))
    oapi.VC_set_areaclickmode_quadrilateral(AID_MFD2_BRT, _V(-0.162,1.9295,15.023), _V(-0.147,1.9295,15.023), _V(-0.162,1.9145,15.023), _V(-0.147,1.9145,15.023))
    oapi.VC_set_areaclickmode_quadrilateral(AID_MFD3_BRT, _V(0.107,2.0445,15.058), _V(0.122,2.0445,15.058), _V(0.107,2.0295,15.058), _V(0.122,2.0295,15.058))
    oapi.VC_set_areaclickmode_quadrilateral(AID_MFD4_BRT, _V(0.376,2.1605,15.090), _V(0.391,2.1605,15.090), _V(0.376,2.1455,15.090), _V(0.391,2.1455,15.090))
    oapi.VC_set_areaclickmode_quadrilateral(AID_MFD5_BRT, _V(0.376,1.9295,15.023), _V(0.391,1.9295,15.023), _V(0.376,1.9145,15.023), _V(0.391,1.9145,15.023))
end

----------------------------------------------------------------
-- register VC buttons for the aft MFD at the starbord panel
-- (accessible from payload control position only)
----------------------------------------------------------------
local function registerVC_AftMFD()
    -- register+activate aft MFD function buttons
    local tex1 = oapi.get_texturehandle(hOrbiterVCMesh, 7)
    oapi.VC_register_area(AID_MFDA_BUTTONS, _R(0,127,255,140), PANEL_REDRAW.USER, bit.bor(PANEL_MOUSE.LBDOWN, PANEL_MOUSE.LBUP, PANEL_MOUSE.LBPRESSED, PANEL_MOUSE.ONREPLAY), PANEL_MAP.BACKGROUND, tex1)
    oapi.VC_set_areaclickmode_quadrilateral(AID_MFDA_BUTTONS, _V(1.3862,2.2570,13.8686), _V(1.3862,2.2570,13.6894), _V(1.3678,2.2452,13.8686), _V(1.3678,2.2452,13.6894))

    -- register+activate MFD power button
    local powerButtonRadius = 0.0075 -- radius of power button on each MFD
    oapi.VC_register_area(AID_MFDA_PWR, PANEL_REDRAW.NEVER, bit.bor(PANEL_MOUSE.LBDOWN, PANEL_MOUSE.ONREPLAY))
    oapi.VC_set_areaclickmode_spherical(AID_MFDA_PWR, _V(1.3929,2.2632,13.8947), powerButtonRadius)

    -- register+activate MFD brightness buttons
    oapi.VC_register_area(AID_MFDA_BRT, PANEL_REDRAW.NEVER, bit.bor(PANEL_MOUSE.LBDOWN, PANEL_MOUSE.LBPRESSED, PANEL_MOUSE.ONREPLAY))
    oapi.VC_set_areaclickmode_quadrilateral(AID_MFDA_BRT, _V(1.4024,2.2675,13.6736), _V(1.4024,2.2675,13.6586), _V(1.3893,2.2590,13.6736), _V(1.3893,2.2590,13.6586))
end


----------------------------------------------------------------
-- Load virtual cockpit mode
----------------------------------------------------------------
function clbk_loadVC(id)
    local huds = {                  -- common HUD specs
        nmesh = mesh_vc,
        ngroup = GRP_VC.VirtualHUD,
        hudcnt = _V(0,0,0),         -- hudcnt (to be filled)
        size = 0.176558
    }
    local mfds = {                -- common MFD specs
        pos = _R(0,0,0,0),
        nmesh = mesh_vc,
        ngroup = 0,                  -- ngroup (to be filled)
        flag = MFD_SHOWMODELABELS,
        nbt1 = 5,
        nbt2 = 0,
        bt_yofs = 512/6,
        bt_ydist = 512/7
    }
    local mfdgrp = {
        GRP_VC.CDR1,GRP_VC.CDR2,GRP_VC.PLT1,GRP_VC.PLT2,
        GRP_VC.MFD1, GRP_VC.MFD2, GRP_VC.MFD3, GRP_VC.MFD4, GRP_VC.MFD5,
        GRP_VC.MFD_aft
    }

    local ok = false

    -- register MFD function buttons
    -- this needs to be done globally, so that the labels are correctly updated from all VC positions
    local tex1 = oapi.get_texturehandle(hOrbiterVCMesh, 7)

    -- commander MFD function buttons
    oapi.VC_register_area(AID_CDR1_BUTTONS, _R(0,1,255,14), PANEL_REDRAW.USER, bit.bor(PANEL_MOUSE.LBDOWN, PANEL_MOUSE.LBUP, PANEL_MOUSE.LBPRESSED, PANEL_MOUSE.ONREPLAY), PANEL_MAP.BACKGROUND, tex1)
    oapi.VC_register_area(AID_CDR2_BUTTONS, _R(0,15,255,28), PANEL_REDRAW.USER, bit.bor(PANEL_MOUSE.LBDOWN, PANEL_MOUSE.LBUP, PANEL_MOUSE.LBPRESSED, PANEL_MOUSE.ONREPLAY), PANEL_MAP.BACKGROUND, tex1)
    -- pilot MFD function buttons
    oapi.VC_register_area(AID_PLT1_BUTTONS, _R(0,29,255,42), PANEL_REDRAW.USER, bit.bor(PANEL_MOUSE.LBDOWN, PANEL_MOUSE.LBUP, PANEL_MOUSE.LBPRESSED, PANEL_MOUSE.ONREPLAY), PANEL_MAP.BACKGROUND, tex1)
    oapi.VC_register_area(AID_PLT2_BUTTONS, _R(0,43,255,56), PANEL_REDRAW.USER, bit.bor(PANEL_MOUSE.LBDOWN, PANEL_MOUSE.LBUP, PANEL_MOUSE.LBPRESSED, PANEL_MOUSE.ONREPLAY), PANEL_MAP.BACKGROUND, tex1)
    -- central console MFD function buttons
    oapi.VC_register_area(AID_MFD1_BUTTONS, _R(0, 57,255, 70), PANEL_REDRAW.USER, bit.bor(PANEL_MOUSE.LBDOWN, PANEL_MOUSE.LBUP, PANEL_MOUSE.LBPRESSED, PANEL_MOUSE.ONREPLAY), PANEL_MAP.BACKGROUND, tex1)
    oapi.VC_register_area(AID_MFD2_BUTTONS, _R(0, 71,255, 84), PANEL_REDRAW.USER, bit.bor(PANEL_MOUSE.LBDOWN, PANEL_MOUSE.LBUP, PANEL_MOUSE.LBPRESSED, PANEL_MOUSE.ONREPLAY), PANEL_MAP.BACKGROUND, tex1)
    oapi.VC_register_area(AID_MFD3_BUTTONS, _R(0, 85,255, 98), PANEL_REDRAW.USER, bit.bor(PANEL_MOUSE.LBDOWN, PANEL_MOUSE.LBUP, PANEL_MOUSE.LBPRESSED, PANEL_MOUSE.ONREPLAY), PANEL_MAP.BACKGROUND, tex1)
    oapi.VC_register_area(AID_MFD4_BUTTONS, _R(0, 99,255,112), PANEL_REDRAW.USER, bit.bor(PANEL_MOUSE.LBDOWN, PANEL_MOUSE.LBUP, PANEL_MOUSE.LBPRESSED, PANEL_MOUSE.ONREPLAY), PANEL_MAP.BACKGROUND, tex1)
    oapi.VC_register_area(AID_MFD5_BUTTONS, _R(0,113,255,126), PANEL_REDRAW.USER, bit.bor(PANEL_MOUSE.LBDOWN, PANEL_MOUSE.LBUP, PANEL_MOUSE.LBPRESSED, PANEL_MOUSE.ONREPLAY), PANEL_MAP.BACKGROUND, tex1)

    if id == 0 then -- commander position
        vi:set_cameraoffset(_V(-0.67,2.55,14.4))
        vi:set_cameradefaultdirection(_V(0,0,1))
        vi:set_cameramovement(_V(0,0,0.3), 0, 0, _V(-0.3,0,0), 75*RAD, -5*RAD, _V(0.3,0,0), -20*RAD, -27*RAD)
        huds.hudcnt = _V(-0.671257, 2.523535, 14.969)
        oapi.VC_set_neighbours(-1, 1, -1, 2)

        registerVC_CdrMFD() -- activate commander MFD controls
        registerVC_CntMFD() -- activate central panel MFD controls

        ok = true
    elseif id == 1 then -- pilot position
        vi:set_cameraoffset(_V(0.67,2.55,14.4))
        vi:set_cameradefaultdirection(_V(0,0,1))
        vi:set_cameramovement(_V(0,0,0.3), 0, 0, _V(-0.3,0,0), 20*RAD, -27*RAD, _V(0.3,0,0), -75*RAD, -5*RAD)
        huds.hudcnt = _V(0.671257, 2.523535, 14.969)
        oapi.VC_set_neighbours(0, -1, -1, 2)

        registerVC_PltMFD() -- activate pilot MFD controls
        registerVC_CntMFD() -- activate central panel MFD controls

        ok = true
    elseif id == 2 then -- payload view position
        vi:set_cameraoffset(_V(0.4,3.15,13.0))
        vi:set_cameradefaultdirection(_V(0,0,-1))
        vi:set_cameramovement(_V(0,-0.1,-0.1), 0, 80.0*RAD, _V(0.3,-0.3,0.15), 60.0*RAD, -50.0*RAD, _V(-0.8,0,0), 0, 0)
        oapi.VC_set_neighbours(1, 0, -1, 0)

        registerVC_AftMFD() -- activate aft MFD controls
        plop.register_VC()  -- register panel R13L interface
        ok = true
    end

    if ok then
        -- register the HUDs (synced)
        oapi.VC_registerHUD(huds)
        -- register all MFD displays
        for i=0, 9 do
            mfds.ngroup = mfdgrp[i + 1]
            oapi.register_mfd(MFDID.LEFT + i, mfds)
        end
        -- update panel R13L
        plop.update_VC()
    end
    return ok
end

----------------------------------------------------------------
-- Respond to virtual cockpit mouse event
----------------------------------------------------------------
VCME_sel_counting = false
VCME_sel_t0 = 0.0

function clbk_VCmouseevent(id, event, p)
    -- handle MFD selection buttons
    local case_selection = {
      [AID_CDR1_BUTTONS] = true,
      [AID_CDR2_BUTTONS] = true,
      [AID_PLT1_BUTTONS] = true,
      [AID_PLT2_BUTTONS] = true,
      [AID_MFD1_BUTTONS] = true,
      [AID_MFD2_BUTTONS] = true,
      [AID_MFD3_BUTTONS] = true,
      [AID_MFD4_BUTTONS] = true,
      [AID_MFD5_BUTTONS] = true,
      [AID_MFDA_BUTTONS] = true
    }
    if case_selection[id] then
        local mfd = id - AID_CDR1_BUTTONS + MFDID.LEFT
        local bt = p.x * 5.99
        if bt < 5 then
            oapi.process_mfdbutton(mfd, bt, event)
        else
            if bit.allset(event, PANEL_MOUSE.LBDOWN) then
                VCME_sel_t0 = oapi.get_systime()
                VCME_sel_counting = true
            elseif bit.allset(event, PANEL_MOUSE.LBUP) and VCME_sel_counting then
                oapi.send_mfdkey(mfd, OAPI_KEY.F2)
                VCME_sel_counting = false
            elseif bit.allset(event, PANEL_MOUSE.LBPRESSED) and VCME_sel_counting and (oapi.get_systime() - VCME_sel_t0 >= 1.0) then
                oapi.send_mfdkey(mfd, OAPI_KEY.F1)
                VCME_sel_counting = false
            end
        end
        return true
    end

    -- D. Beachy: handle power buttons
    local case_pwr = {
     [AID_CDR1_PWR] = true,
     [AID_CDR2_PWR] = true,
     [AID_PLT1_PWR] = true,
     [AID_PLT2_PWR] = true,
     [AID_MFD1_PWR] = true,
     [AID_MFD2_PWR] = true,
     [AID_MFD3_PWR] = true,
     [AID_MFD4_PWR] = true,
     [AID_MFD5_PWR] = true,
     [AID_MFDA_PWR] = true
    }
    if case_pwr[id] then
        local mfd = id - AID_CDR1_PWR + MFDID.LEFT
        oapi.send_mfdkey(mfd, OAPI_KEY.ESCAPE)
        return true
    end
    -- handle MFD brightness buttons
    local case_brt = {
     [AID_CDR1_BRT] = true,
     [AID_CDR2_BRT] = true,
     [AID_PLT1_BRT] = true,
     [AID_PLT2_BRT] = true,
     [AID_MFD1_BRT] = true,
     [AID_MFD2_BRT] = true,
     [AID_MFD3_BRT] = true,
     [AID_MFD4_BRT] = true,
     [AID_MFD5_BRT] = true,
     [AID_MFDA_BRT] = true
    }
    if case_brt[id] then
        local mfd = id - AID_CDR1_BRT
        if bit.allset(event, PANEL_MOUSE.LBDOWN) then
            brt_up = (p.x >= 0.5)
            brt_t0 = oapi.get_systime()
            brt_brt0 = mfdbright[mfd]
        elseif bit.allset(event, PANEL_MOUSE.LBPRESSED) then
            local dt = oapi.get_systime() - brt_t0
            local brt
            local dbrt = dt * 0.2
            if brt_up then
                brt = math.min(1.0, brt_brt0 + dbrt)
            else
                brt = math.max(0.25, brt_brt0 - dbrt)
            end
            mfdbright[mfd] = brt
            if vis then
                local hMesh = vi:get_devmesh(vis, mesh_vc)
                local mat = {
                    diffuse  = _COLOUR4(0,0,0,0),
                    ambient  = _COLOUR4(0,0,0,0),
                    specular = _COLOUR4(0,0,0,0),
                    emissive = _COLOUR4(brt,brt,brt,1.0),
                    power   = 0
                }
                oapi.set_material(hMesh, 10 + mfd, mat)
            end
        end
        return false
    end
    -- handle panel R13L events (payload bay operations)
    if id == AID_R13L then
        return plop.VC_mouse_event(id, event, p)
    end
    return false
end


----------------------------------------------------------------
-- Respond to virtual cockpit area redraw request
----------------------------------------------------------------
function clbk_VCredrawevent(id, event, surf)
    local case_selection = {
      [AID_CDR1_BUTTONS] = true,
      [AID_CDR2_BUTTONS] = true,
      [AID_PLT1_BUTTONS] = true,
      [AID_PLT2_BUTTONS] = true,
      [AID_MFD1_BUTTONS] = true,
      [AID_MFD2_BUTTONS] = true,
      [AID_MFD3_BUTTONS] = true,
      [AID_MFD4_BUTTONS] = true,
      [AID_MFD5_BUTTONS] = true,
      [AID_MFDA_BUTTONS] = true
    }
    if case_selection[id] then
        local mfd = id - AID_CDR1_BUTTONS + MFDID.LEFT
        redraw_panel_MFD_button(surf, mfd)
        return true
    else
        if id >= AID_R13L_MIN and id <= AID_R13L_MAX then
            return plop.VC_redraw_event(id, event, surf)
        end
    end
    return false
end
So, maybe anyone could help me somehow to implement two default MFDs for my mesh (two square meshgroups for MFD displays)? I hope this will be a good example for future vessels based on Lua.
 
I'm afraid I can't figure this out myself. There may be a lot of misunderstandings. I'm trying to add the only left default MFD into my VC (maybe the right MFD should exist too). I'm not sure if I should assign a texture for my MFD rectangle meshgroup. Atlantis example has many features like MFD brightess and so on, I really need the simplest example. Probably, it would be much easier to implement MFDs using the VesselBuilder, but I'd like to do it on Lua... So, if anyone has dealt with MFD (not necessarily on Lua), then I will be very grateful for any help.
 
I'm afraid I can't figure this out myself. There may be a lot of misunderstandings. I'm trying to add the only left default MFD into my VC (maybe the right MFD should exist too). I'm not sure if I should assign a texture for my MFD rectangle meshgroup. Atlantis example has many features like MFD brightess and so on, I really need the simplest example. Probably, it would be much easier to implement MFDs using the VesselBuilder, but I'd like to do it on Lua... So, if anyone has dealt with MFD (not necessarily on Lua), then I will be very grateful for any help.
From the Atlantis.lua file I guess the important parts are :
local mfds = { -- common MFD specs
pos = _R(0,0,0,0),
nmesh = mesh_vc,
ngroup = 0, -- ngroup (to be filled)
flag = MFD_SHOWMODELABELS,
nbt1 = 5,
nbt2 = 0,
bt_yofs = 512/6,
bt_ydist = 512/7
}
local mfdgrp = {
GRP_VC.CDR1,GRP_VC.CDR2,GRP_VC.PLT1,GRP_VC.PLT2,
GRP_VC.MFD1, GRP_VC.MFD2, GRP_VC.MFD3, GRP_VC.MFD4, GRP_VC.MFD5,
GRP_VC.MFD_aft
}
and
-- register all MFD displays
for i=0, 9 do
mfds.ngroup = mfdgrp[i + 1]
oapi.register_mfd(MFDID.LEFT + i, mfds)
end
 
The material needs to be flagged as dynamic.
Do you know where that flag can be seen? It's not presented in a mesh file.
From the Atlantis.lua file I guess the important parts are :

and
I experimented with Atlantis.lua script and noticed that the following code is enough for displaying the left and right default MFDs in VC:
C++:
function clbk_loadVC(id)
    local mfds =
    {             
        pos = _R(0,0,0,0),
        nmesh = mesh_vc,
        ngroup = 0,                 
        flag = 1,
        nbt1 = 6,
        nbt2 = 6,
        bt_yofs = 1024/6,
        bt_ydist = 1024/7
    }
    local mfdgrp = {33,34}
    


    if id == 0
        vi:set_cameraoffset(_V(-0.67,2.55,14.4))
        oapi.VC_set_neighbours(-1, 1, -1, -1)
    elseif id == 1
        vi:set_cameraoffset(_V(0.67,2.55,14.4))
        oapi.VC_set_neighbours(0, -1, -1, -1)
    end
        
    for i=0, 1 do
        mfds.ngroup = mfdgrp[i + 1]
        oapi.register_mfd(MFDID.LEFT + i, mfds)
    end
    
    return true
end
I changed some parameters here and I commented the rest of code between line 1752 and line 2182. The MFDs in Atlantis VC are displayed correctly and they are synchronized with MFDs in glass cockpit (MFD buttons are not interactive yet (I commented it)).

So, I'm using the following part of Lua code for my plane:
C++:
function clbk_loadVC(id)
    local mfds =
    {
        pos = _R(0,0,0,0),
        nmesh = 0,
        ngroup = 0,
        flag = 1,
        nbt1 = 6,
        nbt2 = 6,
        bt_yofs = 1024/6,
        bt_ydist = 1024/7
    }
    local mfdgrp = {17,18}

      if id == 0 then
           vi:set_cameraoffset({x=-0.49644,y=0.60708,z=1})
           oapi.VC_set_neighbours(-1, 1, -1, 2)
        elseif id == 1 then
           vi:set_cameraoffset({x=0.49644,y=0.60708,z=1})
           oapi.VC_set_neighbours(0, -1, -1, 2)
        elseif id == 2 then
           vi:set_cameraoffset({x=0,y=0.45,z=-1})
           oapi.VC_set_neighbours(-1, -1, 0, -1)
      end

    for i=0, 1 do
        mfds.ngroup = mfdgrp[i + 1]
        oapi.register_mfd(MFDID.LEFT + i, mfds)
    end
    
    return true
end
A have two square planes in my mesh for two test MFDs, but they don't show anything:

Без імені.png

These two square planes don't use a texture and have the material properties in the mesh file the same like for the Atlantis one.

Any suggestions for the issue detection and any help help are very welcome 🙏
 
Your mesh is defined as 0, is it OK?
BTW, you can use the meshc tool to generate a Lua table for your mesh group names
 
Last edited:
Your mesh is defined as 0, is it OK?
I suppose yes, since "nmesh" is the mesh index, and I have the only one mesh, so I am using "0" for it. Maybe I should define the mesh for MFD additionally, I don't know. I can post the whole script (I am using a single script) if it could help?
 
I just ported the vessel so I'm not exactly 100% sure of what everything does but do you set the visibility mode of your mesh? cf vi:set_mesh_visibility_mode :
Code:
function load_meshes()
    -- Retrieve mesh handles
    hOrbiterMesh        = oapi.load_meshglobal("Atlantis/Atlantis")
    hOrbiterCockpitMesh = oapi.load_meshglobal("Atlantis/AtlantisCockpit")
    hOrbiterVCMesh      = oapi.load_meshglobal("Atlantis/AtlantisVC")
    
    -- Load meshes
    mesh_cockpit = vi:add_mesh(hOrbiterCockpitMesh)
    vi:set_mesh_visibility_mode(mesh_cockpit, MESHVIS.EXTERNAL)

    mesh_orbiter = vi:add_mesh(hOrbiterMesh)
    vi:set_mesh_visibility_mode(mesh_orbiter,  bit.bor(MESHVIS.EXTERNAL, MESHVIS.VC, MESHVIS.EXTPASS))

    mesh_vc = vi:add_mesh(hOrbiterVCMesh)
    vi:set_mesh_visibility_mode(mesh_vc, MESHVIS.VC)

    -- Optional meshes
    mesh_cargo      = nil
    mesh_platform   = nil

    -- Visual handle
    vis             = nil
end
 
Sorry! WRONG information. It's the textures that need flagging with a "D" and only for instruments that need updating (had to check the last MFD that I made).
The meshgrp is a simple square with UVs no tex. and a black material.

LABEL mfdpanel1
MATERIAL 5
TEXTURE 0
FLAG 1
GEOM 4 2
-0.0344 0.4142 2.5898 0.0000 0.3420 -0.9397 1.0000 1.0000
-0.0344 0.6058 2.6595 0.0000 0.3420 -0.9397 1.0000 0.0000
-0.2383 0.4142 2.5898 0.0000 0.3420 -0.9397 0.0000 1.0000
-0.2383 0.6058 2.6595 0.0000 0.3420 -0.9397 0.0000 0.0000
1 0 3
2 3 0



MATERIAL instrumentmfd
0.000 0.000 0.000 1.000
0.000 0.000 0.000 1.000
0.700 0.700 0.700 1.000 100.000
1.000 1.000 1.000 1.000
 
Do your square planes have UV coordinates?
I thought about it, too. It's something strange I don't understand. The AtlantisVC.msh file contains "CDR1" meshgroup for the left MFD. A texture isn't assigned for this meshgroup (it's "0"):
Code:
LABEL CDR1
MATERIAL 11
TEXTURE 0
GEOM 4 2
-0.924821 2.23843 15.1108 0 0.269137 -0.963102 0 0
-0.743866 2.23843 15.1108 0 0.269137 -0.963102 1 0
-0.924821 2.06416 15.0621 0 0.269137 -0.963102 0 1
-0.743866 2.06416 15.0621 0 0.269137 -0.963102 1 1
1 2 0
2 1 3
But it has vertex texture coordinates, namely UV coordinates, I suppose (7 and 8 columns above). Are UV coordinates needed if a texture for a meshgroup isn't used? (I tried to add the UV coordinates into the mesh file like for Atlantis, but it didn't help).
I just ported the vessel so I'm not exactly 100% sure of what everything does but do you set the visibility mode of your mesh? cf vi:set_mesh_visibility_mode :
No problem, I hope we can understand it. I'm using:
Code:
vi:add_mesh('Cirrus-SR22/Cirrus-SR22')
vi:set_mesh_visibility_mode(0,bit.bor(MESHVIS.EXTERNAL,MESHVIS.VC))
I attach full code below. But I don't use oapi.load_meshglobal(). Could it be the reason?
It's the textures that need flagging with a "D" and only for instruments that need updating (had to check the last MFD that I made).
Your meshgroup has the flag "1". Does it mean "D" (dynamic) flag?
The meshgrp is a simple square with UVs no tex. and a black material.
The same question. Are UV coordinates needed even if a texture doesn't used (set to "0")? Here's my left MFD meshgroup (I added the UV coordinates into the mesh file like for Atlantis, but it didn't help):
Code:
LABEL Plane
MATERIAL 8
TEXTURE 0
FLAG 0
GEOM 4 2
-0.4803 0.1723 1.8043 0.0000 0.0000 -1.0000 0 0
-0.1838 0.1723 1.8043 0.0000 0.0000 -1.0000 1 0
-0.4803 0.4688 1.8043 0.0000 0.0000 -1.0000 0 1
-0.1838 0.4688 1.8043 0.0000 0.0000 -1.0000 1 1
0 3 1
0 2 3
And its material:
Code:
MATERIAL Plane
0.000 0.000 0.000 1.000
0.000 0.000 0.000 1.000
0.700 0.700 0.700 1.000 100.000
1.000 1.000 1.000 1.000
Also, I set flag "1", but it didn't help.

Here's my full single script:
C++:
-- Main parameters
-- Touchdown points
-- Main thruster parameters
-- Vertical airfoil function
-- Horizontal airfoil function
-- Left yoke roll animation
-- Right yoke roll animation
-- Yoke pitch animation
-- Propeller animation
-- Throttle animation
-- Gauge animations
-- Sound

      -- CLBK SETCLASSCAPS FUNCTION
      -- Main parameters
      -- Touchdown points
      -- Mesh
      -- Propellant
      -- Main thrusters
      -- Airfoils
      -- Yoke animations
      -- Propeller animation parameters
      -- Throttle animation
      -- Gauge animations

-- Keys for propeller animation
-- Function for propeller animation and sound, throttle animation, gauge animations
-- Inner views
-- VC camera positions and default MFDs

--[[
ClassName = Cirrus-SR22
Module = ScriptVessel
Script = Cirrus-SR22/Cirrus-SR22.cfg
END_PARSE
--]]

-- Main parameters

parameters =
{
  size = 8.27,                                  -- mean radius
  mass = 1000,                                  -- empty mass
  pmi = {x=15.5,y=22.1,z=7.7},                  -- principal moments of inertia
  cs = {x=5.3,y=18.69,z=2.59},                  -- cross sections
  rd = {x=0.30,y=0.39,z=0.12},                  -- rotation drag coefficients
  fuel = 500                                    -- fuel mass
}

-- Touchdown points

gears =
{
  {pos = {x=0,y=-2.15,z=2.3713}, stiffness = 9e4, damping = 9e3, mu = 1.6, mu_lng = 0.1},           -- front
  {pos = {x=-3.5,y=-2.1,z=-3.0957}, stiffness = 9e4, damping = 9e3, mu = 3.0, mu_lng = 0.2},       -- left
  {pos = {x=3.5,y=-2.1,z=-3.0957}, stiffness = 9e4, damping = 9e3, mu = 3.0, mu_lng = 0.2}         -- right
}

-- Main thruster parameters

main_thruster =
{
  pos = {x=0,y=0,z=3.34},             -- thrust attack point
  dir = {x=0,y=0,z=1},                -- thrust direction
  maxth0 = 9e3,                       -- max. vacuum thrust
  isp0 = 5e5                          -- vacuum ISP (fuel-specific impulse)
}

-- Vertical airfoil function

function VerticalLift(hVessel,aoa,M,Re)
  local quantity = 9
    local AOA = {-180*RAD,-60*RAD,-30*RAD,-2*RAD,15*RAD,20*RAD,25*RAD,60*RAD,180*RAD}
    local CL  = {       0,      0,   -0.4,     0,   0.7,     1,   0.8,     0,      0}
    local CM  = {       0,      0,  0.014,0.0039,-0.006,-0.008,-0.010,     0,      0}

    local i = 1
    while AOA[i+1] < aoa and i < quantity do
      i = i + 1
    end

    local cl, cm, cd
    if i < quantity then
        local step = (aoa - AOA[i]) / (AOA[i + 1] - AOA[i])
        cl = CL[i] + (CL[i + 1] - CL[i]) * step
        cm = CM[i] + (CM[i + 1] - CM[i]) * step
    else
        cl = CL[quantity]
        cm = CM[quantity]
    end
    local saoa = math.sin(aoa)
    local pd = 0.015 + 0.4*saoa*saoa
    cd = pd + oapi.get_induceddrag (cl, 1.5, 0.7) + oapi.get_wavedrag (M, 0.75, 1.0, 1.1, 0.04)
    return cl, cm, cd
end

-- Horizontal airfoil function

function HorizontalLift(hVessel,beta,M,Re)
    local quantity = 8
    local BETA = {-180*RAD,-135*RAD,-90*RAD,-45*RAD,45*RAD,90*RAD,135*RAD,180*RAD}
    local CL   = {       0,     0.3,      0,   -0.3,   0.3,     0,   -0.3,      0}

    local i = 1
    while BETA[i+1] < beta and i < quantity do
        i = i + 1
    end

    local cl, cd
    if i < quantity then
        cl = CL[i] + (CL[i + 1] - CL[i]) * (beta - BETA[i]) / (BETA[i + 1] - BETA[i])
    else
        cl = CL[quantity]
    end
    cd = 0.015 + oapi.get_induceddrag (cl, 1.5, 0.6) + oapi.get_wavedrag (M, 0.75, 1.0, 1.1, 0.04);
    return cl, 0, cd
end

-- Front yoke roll animation

LeftYokeRoll =
{
  type = 'rotation',
  mesh = 0,
  grp = {0,1,2,3,4,5},
  ref = {x=-0.82617,y=-0.00874,z=1.6092},
  axis = {x=0,y=0,z=-1},
  angle = 30*RAD
}

-- Rear yoke roll animation

RightYokeRoll =
{
  type = 'rotation',
  mesh = 0,
  grp = {6,7,8},
  ref = {x=0.78357,y=-0.00688,z=1.6092},
  axis = {x=0,y=0,z=-1},
  angle = 30*RAD
}

-- Yoke pitch animation

YokePitch =
{
  type = 'translation',
  mesh = 0,
  grp = {0,1,2,3,4,5,6,7,8},
  shift = {x=0,y=0,z=-0.1}
}

-- Propeller animation

propeller =
{
    type = 'rotation',
    mesh = 0,
    grp = {9,10},
    ref = {x=0, y=0, z=3.78448},
    axis = {x=0, y=0, z=1},
    angle = 2*PI
}

-- Throttle animation

Throttle =
{
    type = 'rotation',
    mesh = 0,
    grp = {11,12},
    ref = {x=0.04544, y=-0.39561, z=1.40630},
    axis = {x=1, y=0, z=0},
    angle = PI/4+PI/20
}

-- Gauge animations

ArrowSpeed =
{
    type = 'rotation',
    mesh = 0,
    grp = 13,
    ref = {x=-0.59937, y=0.00239, z=1.78973},
    axis = {x=0, y=0.329427, z=-0.944181},
    angle = 320*RAD
}

DialHeading =
{
    type = 'rotation',
    mesh = 0,
    grp = 14,
    ref = {x=-0.33202, y=0.00311, z=1.78964},
    axis = {x=0, y=0.329427, z=-0.944181},
    angle = -360*RAD
}

ArrowAltitudeLong =
{
    type = 'rotation',
    mesh = 0,
    grp = 15,
    ref = {x=-0.46286, y=0.00233, z=1.78973},
    axis = {x=0, y=0.329427, z=-0.944181},
    angle = 360*RAD
}

ArrowAltitudeShort =
{
    type = 'rotation',
    mesh = 0,
    grp = 16,
    ref = {x=-0.46286, y=0.00233, z=1.78973},
    axis = {x=0, y=0.329427, z=-0.944181},
    angle = 360*RAD
}

-- Sound

local Sound

function clbk_postcreation()
  Sound = xrsound.create_instance(vi)
  Sound:load_wav(1, "XRSound/Cirrus-SR22/Engine.wav", PlaybackType.BothViewClose)

  for id = 10000, 10045 do
    if id ~= 10001 and id ~= 10034 then
      Sound:set_defaultsoundenabled(id, false)
    end
  end

  for id = 11000, 11005 do
    Sound:set_defaultsoundenabled(id, false)
  end

end

-- CLBK SETCLASSCAPS FUNCTION

function clbk_setclasscaps(cfg)

  -- Main parameters

  vi:set_size(parameters.size)
  vi:set_emptymass(parameters.mass)
  vi:set_pmi(parameters.pmi)
  vi:set_crosssections(parameters.cs)
  vi:set_rotdrag(parameters.rd)

  -- Touchdown points

  vi:set_touchdownpoints(gears)
 
  -- Mesh

  vi:add_mesh('Cirrus-SR22/Cirrus-SR22')
  vi:set_mesh_visibility_mode(0,bit.bor(MESHVIS.EXTERNAL,MESHVIS.VC))

  -- Propellant

  propellant = vi:create_propellantresource(parameters.fuel)

  -- Main thrusters

  main_thruster.hprop = propellant

  main_engine = nil
  main_engine_group = nil
  StoredThrottle = 0

  -- Airfoils

  vi:create_airfoil(LIFT.VERTICAL,{x=0,y=0,z=-0.3},'VerticalLift',5,90,1.5)
  vi:create_airfoil(LIFT.HORIZONTAL,{x=0,y=0,z=-4},'HorizontalLift',5,15,1.5)

  -- Yoke animations

  LeftYokeRollAnimationComponent = oapi.create_animationcomponent(LeftYokeRoll)
  RightYokeRollAnimationComponent = oapi.create_animationcomponent(RightYokeRoll)
  YokePitchAnimationComponent = oapi.create_animationcomponent(YokePitch)

  LeftAileronAnimation = vi:create_animation(0.5)
  ElevatorAnimation = vi:create_animation(0.5)

  vi:add_animationcomponent(LeftAileronAnimation,0,1,LeftYokeRollAnimationComponent)
  vi:add_animationcomponent(LeftAileronAnimation,0,1,RightYokeRollAnimationComponent)
  vi:add_animationcomponent(ElevatorAnimation,0,1,YokePitchAnimationComponent)

  vi:create_controlsurface(AIRCTRL.AILERON, 0.3, 1.7, {x=-7.5,y=0,z=-7.2}, AIRCTRL_AXIS.XNEG, 1, LeftAileronAnimation)
  vi:create_controlsurface(AIRCTRL.AILERON, 0.3, 1.7, {x=7.5,y=0,z=-7.2}, AIRCTRL_AXIS.XPOS, 1)
  vi:create_controlsurface(AIRCTRL.ELEVATOR, 1.4, 1.7, {x=0,y=0,z=-7.2}, AIRCTRL_AXIS.XPOS, 1, ElevatorAnimation)
  vi:create_controlsurface(AIRCTRL.RUDDER, 0.8, 1.7, {x=0,y=0,z=-7.2}, AIRCTRL_AXIS.YPOS, 1)
  vi:create_controlsurface(AIRCTRL.ELEVATORTRIM, 0.3, 1.7, {x=0,y=0,z=-7.2}, AIRCTRL_AXIS.XPOS, 1)

  -- Propeller animation parameters
 
  T = 0.33333
  PropellerOn = false

  create_anim_propeller = oapi.create_animationcomponent(propeller)
  anim_propeller = vi:create_animation(0)
  vi:add_animationcomponent(anim_propeller, 0, 1, create_anim_propeller)

  -- Throttle animation

  ThrottleAnimationComponent = oapi.create_animationcomponent(Throttle)
  ThrottleAnimation = vi:create_animation(0)
  vi:add_animationcomponent(ThrottleAnimation, 0, 1, ThrottleAnimationComponent)

  -- Gauge animations

  ArrowSpeedAnimationComponent = oapi.create_animationcomponent(ArrowSpeed)
  ArrowSpeedAnimation = vi:create_animation(0)
  vi:add_animationcomponent(ArrowSpeedAnimation, 0, 1, ArrowSpeedAnimationComponent)

  DialHeadingAnimationComponent = oapi.create_animationcomponent(DialHeading)
  DialHeadingAnimation = vi:create_animation(0)
  vi:add_animationcomponent(DialHeadingAnimation, 0, 1, DialHeadingAnimationComponent)

  ArrowAltitudeLongAnimationComponent = oapi.create_animationcomponent(ArrowAltitudeLong)
  ArrowAltitudeLongAnimation = vi:create_animation(0)
  vi:add_animationcomponent(ArrowAltitudeLongAnimation, 0, 1, ArrowAltitudeLongAnimationComponent)
  ArrowAltitudeShortAnimationComponent = oapi.create_animationcomponent(ArrowAltitudeShort)
  ArrowAltitudeShortAnimation = vi:create_animation(0)
  vi:add_animationcomponent(ArrowAltitudeShortAnimation, 0, 1, ArrowAltitudeShortAnimationComponent)

end

-- Keys for propeller animation

function clbk_consumebufferedkey(key, down, kstate)

  if oapi.keydown(kstate, OAPI_KEY.E) then
    
    if not PropellerOn then
      if main_engine == nil then
        main_engine = vi:create_thruster(main_thruster)
        main_engine_group = vi:create_thrustergroup({main_engine}, THGROUP.MAIN)
        vi:set_thrustergrouplevel(THGROUP.MAIN, StoredThrottle or 0)
      end
      PropellerOn = true

    else
    
      if main_engine_group then
        StoredThrottle = vi:get_thrustergrouplevel(THGROUP.MAIN)
        vi:del_thrustergroup(THGROUP.MAIN)
        vi:del_thruster(main_engine)
        main_engine = nil
        main_engine_group = nil
      end
      PropellerOn = false
    end

  end

end

-- Function for propeller animation and sound, throttle animation, gauge animations

function clbk_poststep(simt,simdt)
  if PropellerOn then
    anim_propeller_level = (simt/T) % 1
    vi:set_animation(anim_propeller, anim_propeller_level)

    ThrottleLevel = vi:get_thrustergrouplevel(THGROUP.MAIN)
    vi:set_animation(ThrottleAnimation, ThrottleLevel)

    local volume = 0.2 + 0.8 * ThrottleLevel
    Sound:play_wav(1, true, volume)
  else
    vi:set_animation(anim_propeller, 0)
    vi:set_animation(ThrottleAnimation, StoredThrottle or 0)
    Sound:stop_wav(1)
  end

  -- Speed

  local SpeedVector = vi:get_airspeedvector(REFFRAME.LOCAL)
  local Speed = vec.length(SpeedVector)
  local SpeedKnots = Speed * 1.94384
  local SpeedState = math.min(SpeedKnots / 120, 1.0)
  vi:set_animation(ArrowSpeedAnimation, SpeedState)

  -- Heading

  local Heading = vi:get_yaw() * DEG
  local HeadingState = Heading / 360
  vi:set_animation(DialHeadingAnimation, HeadingState)

  -- Altitude

  local Altitude = vi:get_altitude(ALTMODE.MEANRAD) / 0.3048

  if Altitude > 10000 then
    Altitude = 10000
  end

  local AltitudeStateLong = (Altitude % 1000) / 1000
  vi:set_animation(ArrowAltitudeLongAnimation, AltitudeStateLong)
  local AltitudeStateShort = (Altitude % 10000) / 10000
  vi:set_animation(ArrowAltitudeShortAnimation, AltitudeStateShort)

end

-- Inner views

function clbk_loadgenericcockpit()
  return true
end

function clbk_loadpanel2D()
  return false
end

-- VC camera positions and default MFDs

function clbk_loadVC(id)

    local mfds =
    {
        pos = _R(0,0,0,0),
        nmesh = 0,
        ngroup = 0,
        flag = 1,
        nbt1 = 6,
        nbt2 = 6,
        bt_yofs = 1024/6,
        bt_ydist = 1024/7
    }
 
    local mfdgrp = {17,18}

  if id == 0 then
    vi:set_cameraoffset({x=-0.49644,y=0.60708,z=1})
    oapi.VC_set_neighbours(-1, 1, -1, 2)
  elseif id == 1 then
    vi:set_cameraoffset({x=0.49644,y=0.60708,z=1})
    oapi.VC_set_neighbours(0, -1, -1, 2)
  elseif id == 2 then
    vi:set_cameraoffset({x=0,y=0.45,z=-1})
    oapi.VC_set_neighbours(-1, -1, 0, -1)
  end

    for i=0, 1 do
        mfds.ngroup = mfdgrp[i + 1]
        oapi.register_mfd(MFDID.LEFT + i, mfds)
    end

  return true
end
 
Yes, you need UV coordinates for an MFD.
Give your MFD group a UV mapped texture, but in the mesh don't use the texture, label it 0.

Code:
MATERIAL 14
TEXTURE 0
LABEL lftmfd
GEOM 6 2
-0.13044 0.30923 0.22779 0 0.22495 -0.97437 -0 -1
-0.28044 0.30923 0.22779 0 0.22495 -0.97437 -1 -1
-0.13044 0.16308 0.19405 0 0.22495 -0.97437 0 0
-0.13044 0.16308 0.19405 -0 0.22495 -0.97437 0 0
-0.28044 0.30923 0.22779 -0 0.22495 -0.97437 -1 -1
-0.28044 0.16308 0.19405 -0 0.22495 -0.97437 -1 0
0 2 1
3 5 4
 
Last edited:
Your meshgroup has the flag "1". Does it mean "D" (dynamic) flag?
No, flag 1 is for no shadows (advisable)

The dynamic flag is for textures that need updating and would look like this:
Code:
BuckRogers\buck_VC1.dds D
at the end of the mesh file.
The same question. Are UV coordinates needed even if a texture doesn't used (set to "0")?
Yes!
Here's my left MFD meshgroup (I added the UV coordinates into the mesh file like for Atlantis, but it didn't help):
This looks ok
0 3 1
0 2 3
This is the UV bit, did you create it in Blender? (another problem I remember was mirroring, had to flip the meshes).
Code:
function clbk_loadVC(id) local mfds = { pos = _R(0,0,0,0), nmesh = 0, ngroup = 0, flag = 1, nbt1 = 6, nbt2 = 6, bt_yofs = 1024/6, bt_ydist = 1024/7 } local mfdgrp = {17,18} if id == 0 then vi:set_cameraoffset({x=-0.49644,y=0.60708,z=1}) oapi.VC_set_neighbours(-1, 1, -1, 2) elseif id == 1 then vi:set_cameraoffset({x=0.49644,y=0.60708,z=1}) oapi.VC_set_neighbours(0, -1, -1, 2) elseif id == 2 then vi:set_cameraoffset({x=0,y=0.45,z=-1}) oapi.VC_set_neighbours(-1, -1, 0, -1) end for i=0, 1 do mfds.ngroup = mfdgrp[i + 1] oapi.register_mfd(MFDID.LEFT + i, mfds) end return true end
I think there's something missing, there are variables for flags and other stuff but I don't see them being referenced? But it's probably better when someone else comments on the code.:)
 
The dynamic flag is for textures that need updating and would look like this:
BuckRogers\buck_VC1.dds D
I'm a little confused. If we don't use a texture for the MFD meshgroup (we wriete TEXTURE 0), then why should we use a DDS texture (with "D" flag) for the MFD meshgroup?
This is the UV bit, did you create it in Blender? (another problem I remember was mirroring, had to flip the meshes).
Yes, I built my mesh in Blender using "Blender Orbiter Mesh Tools". Both square planes that I'm using for two MFDs have correct normals in Blender and game, otherwise they would be invisible.
I think there's something missing, there are variables for flags and other stuff but I don't see them being referenced?
What the variable do you consider undefined?
 
I'm a little confused. If we don't use a texture for the MFD meshgroup (we wriete TEXTURE 0), then why should we use a DDS texture (with "D" flag) for the MFD meshgroup?
You don't. @Buck Rogers was just giving an example of the "D" flag if it were being used for a dynamic texture.
 
I'm a little confused. If we don't use a texture for the MFD meshgroup (we wriete TEXTURE 0), then why should we use a DDS texture (with "D" flag) for the MFD meshgroup?
Apologies again for the confusion
The texture flag is NOT needed for the MFD.
My mistake, it's only needed for other instruments.
Yes, I built my mesh in Blender using "Blender Orbiter Mesh Tools". Both square planes that I'm using for two MFDs have correct normals in Blender and game, otherwise they would be invisible.
I was wondering if you had "unwrapped" in Blender or just copy/pasted the UVs.
What the variable do you consider undefined?
The variables are being initialised. But as said I'm no coder, have to take a more holistic approach.
Have you tried adding your MFD meshes to your modified (working) Atlantis code?
You could also just export the MFD mesh and make a simple Vesselbuilder .cfg to see if the mesh is at fault?
 
Last edited:
Thank you all.
I was wondering if you had "unwrapped" in Blender or just copy/pasted the UVs.
I tried both ways.
Have you tried adding your MFD meshes to your modified (working) Atlantis code?
Do you mean me to edit the Atlantis VC mesh to add two square planes for two test MFDs? Or just using my mesh with the Atlantis Lua script? Not yet, but it's interesting. I should try it.
You could also just export the MFD mesh and make a simple Vesselbuilder .cfg to see if the mesh is at fault?
Not yet, but I should really try it.

Thanks! I need some free time to try it all.
 
Back
Top