C172P in dotazione ha volantino (va be', ha due volantini, ma in sostanza è uno mostrato due volte) con un bel pulsante (sembrerebbe).
 |
bel pulsante, nero e "morto" |
Ma quel pulsante non fa niente, il puntatore al passaggio non cambia, non è un elemento attivo. Allora vado indagare: trovo nella cartella
$FGFS_HOME/Aircraft/c172p/Models/Yoke i file
yoke.xml,
yoke.ac e
yoke.png. Il primo è la definizione del volantino, il secondo è suo modello in formato AC3D e il terzo la sua "pelle", textura usata per colorare la superfice. Importando il file
yoke.ac nel Blender ho visto, che modello è fatto solo di due pezzi,
Yoke e
YokeMount. Ho lasciato da parte la montatura e ho modificato il pezzo
Yoke.
 |
pezzo Yoke originale |
Prima ho schiacciato la parte superiore del finto "bottone", ho creato così un buco.
 |
buco pronto ospitare il bottone vero |
e lì ho aggiunto nuovo elemento di tipo "cilindro", un po' prolungato, un po' deformato (ha la sezione ovale, non è cerchio), un po' inclinato.
 |
nuovo bottone pronto per uso |
Colorato di rosso, con grande invenzione chiamato Button. Ho salvato tutto in formato Blender (per eventuali future modifiche) e anche esportato in formato AC3D nel file
yoke_new.ac.
Modifico ancora il file
yoke.xml, al posto di
<path>yoke.ac</path>
scrivo
<path>yoke_new.ac</path>
e vado a guardarlo.
Bello, nuovo di zecca, colorato -- e stupido! Non fa ancora niente, addirittura sta impalato su un punto e non si muove insieme con volantino.
 |
non si muove |
 |
e non si nasconde neanche |
|
Infatti, perché nel file
yoke.xml è definito comportamento del oggetto
Yoke, ma non c'è neanche mezza parola di che cosa deve fare l'oggetto
Button. Come prima cosa, per i movimenti e nascondi/mostra devo fare di
Yoke e
Button un'insieme munito di nome, scrivo al inizio di questo file, subito dopo
path yoke_new.ac
<animation>
<!-- make unique corpus from Yoke and Button (for movements) -->
<name>YokeGroup</name>
<object-name>Yoke</object-name>
<object-name>Button</object-name>
</animation>
e poi nelle 3 seguenti animazioni (rotazione, traslazione e selezione) al posto di
object-name Yoke uso
object-name YokeGroup. OK, modificato, salvato, nel fgfs menu
Debug - Reload Aircraft Model e voilà - il bottone è solidale con resto del volantino.
Ma ancora non fa niente. Per questo devo aggiungere altro pezzo nel file
yoke.xml, definizione del oggetto
Button come parte attiva.
Prima ho guardato il file
$FGFS_HOME/Aircraft/Instruments-3d/kap140/KAP140TwoAxisAlt.xml e lì ho scoperto che il pulsante AP del KAP140 quando clicato chiama la procedura Nasal
kap140.apButton(). Faccio lo stesso, alla fine del file
yoke.xml aggiungo nuova animazione
<animation>
<type>pick</type>
<object-name>Button</object-name>
<visible>true</visible>
<action>
<button>0</button>
<repeatable>false</repeatable>
<binding>
<command>nasal</command>
<script>
kap140.apButton();
</script>
</binding>
</action>
</animation>
e scopro che non va bene. Se AP è inserito, il pulsante lo disinserisce, ma se è disinserito, lo inserisce pure. E che altro dovrebbe fare, se l'ho definito come copia spudorata di pulsante AP? Vado guardare che cosa fa la procedura
apButton() nel file
$FGFS_HOME/Aircraft/Generic/kap140.nas e lì trovo un bel esempio di programmazione (funzione apButton) - scrivo qui in pseudocodice abbreviato:
if (non c'è corrente) { return }
if (rollModes == OFF and pitchModes == OFF) // in breve se è tutto spento
{ risveglialo in modo ROL }
elseif (rollModes != OFF or pitchModes != OFF) // se qualcosa è acceso
{ spegnilo }
Boh, prima di tutto, non capisco quel
elseif. Se uno stato è "tutto spento", lo stato oposto "qualcosa acceso" è complemento automatico, con semplice
else funziona lo stesso (lo stato "tutto acceso" è solo un caso particolare dello stato "qualcosa acceso") Ma ch'è, un yoke di Schrödinger?
if (non c'è corrente) { return }
if (rollModes == OFF and pitchModes == OFF) // in breve se è tutto spento
{ risveglialo in modo ROL }
else // nessun test, che qualcosa è acceso è sicuro,
// terza possibilità non c'è
{ spegnilo }
Modificato questo e verificato che funziona, devo ancora scorporare la parte dello spegnimento, fare di lui una funzione separata, vediamo a breve perché. Il risultato finale sarà
offButton { // azione di spegnimento messa da parte
if (non c'è corrente) { return }
if (rollModes != OFF or pitchModes != OFF) // se qualcosa è acceso
{ spegnilo }
}
apButton {
if (non c'è corrente) { return }
if (rollModes == OFF and pitchModes == OFF) // in breve se è tutto spento
{ risveglialo in modo ROL }
else // se qualcosa è acceso
{ offButton() } // chiama offButton, che lo spegne
}
Perché tutto questo? Adesso posso quel bel bottone rosso far chiamare solo la procedura di spegnimento - funzionerà veramente come spegnimento AP d'emergenza. E perché mo' la funzione
offButton() può essere chiamata separatamente, il test "è qualcosa acceso?" deve stare lì, altrimenti si potrebbe dal volantino spegnere più volte in fila.
<animation>
<type>pick</type>
<object-name>Button</object-name>
<visible>true</visible>
<action>
<button>0</button>
<repeatable>false</repeatable>
<binding>
<command>nasal</command>
<script>
kap140.offButton();
</script>
</binding>
</action>
</animation>
Alla fine, per chi non vuole fare copia/incolla (oggi è un po complicato), i file da scaricare: nuovo modello di volantino
yoke_new.ac, suo nuovo file d'impostazioni
yoke.xml e nasal script di KAP140 modificato
kap140.nas. Potete anche scaricarli tutti e tre insieme - il file
yoke_button.zip.
Alla prossima :)
E chi mi chiederà come si fa quel lavoro con Blender, che ho descritto qui in tre immagini e poche righe di testo? Semplice, procuratevi il manuale e cominciate a studiare, come l'ho fatto io ;)