Wikibooks
itwikibooks
https://it.wikibooks.org/wiki/Pagina_principale
MediaWiki 1.47.0-wmf.16
first-letter
Media
Speciale
Discussione
Utente
Discussioni utente
Wikibooks
Discussioni Wikibooks
File
Discussioni file
MediaWiki
Discussioni MediaWiki
Template
Discussioni template
Aiuto
Discussioni aiuto
Categoria
Discussioni categoria
Progetto
Discussioni progetto
Ripiano
Discussioni ripiano
TimedText
TimedText talk
Modulo
Discussioni modulo
Evento
Discussioni evento
Storia della letteratura italiana/Alberto Moravia
0
38277
501041
500209
2026-08-19T17:52:16Z
Hippias
18281
revisione: aggiunti i riferimenti, eliminate le informazioni non verificate
501041
wikitext
text/x-wiki
{{storia della letteratura italiana|sezione=8}}
Tra i più rappresentativi scrittori italiani del secondo dopoguerra, Alberto Moravia è un autore prolifico, animato da passione civile e curiosità culturale. Critico nei confronti della borghesia italiana, classe sociale da cui egli stesso proviene, si fa conoscere già con il suo primo romanzo, pubblicato quando è poco più che ventenne, ''Gli indifferenti''. Nel dopoguerra firma altre opere di successo, molte delle quali sono trasposte al cinema.
== La vita ==
[[File:Paolo Monti - Servizio fotografico - BEIC 6361580.jpg|thumb|left|Alberto Moravia]]
Nasce a Roma, con il nome di Alberto Pincherle, il 28 novembre 1907 in una agiata famiglia borghese. Firma però le sue opere con il cognome della nonna paterna, Moravia. La sua è un'infanzia difficile: malato di tubercolosi ossea, è costretto a letto per lunghi periodi e subisce vari ricoveri in sanatorio. Compie studi irregolari, leggendo per lo più classici e narratori contemporanei. Durante la convalescenza in un albergo di montagna scrive tra il 1925 e il 1928 il suo primo romanzo, ''Gli indifferenti'': pubblicato nel 1929, ottiene immediato successo. Si inserisce attivamente nel mondo intellettuale e letterario italiano: continua a pubblicare racconti e stringe rapporti con Alvaro, Bontempelli e la redazione della rivista ''900''. Viaggia a lungo all'estero: soggiorna a Londra, a Parigi, negli Stati Uniti (ospite di Prezzolini) e persino in Cina.
Intrattiene buoni rapporti con influenti intellettuali fascisti, sebbene il regime guardi con sospetto alla sua produzione letteraria e imponga agli editori di darle scarsa visibilità. Infine nel 1941, con la pubblicazione del romanzo ''La mascherata'', la censura interviene in modo duro e gli proibisce di scrivere sui quotidiani se non dietro pseudonimo. Nello stesso anno sposa la scrittrice [[../Elsa Morante|Elsa Morante]]. Dopo l'8 settembre 1943 la coppia fugge da Roma e ripara a Fondi, per tornare nella capitale solo dopo la Liberazione. Riprende l'attività letteraria e giornalistica, collaborando con ''Il Mondo'', ''L'Europeo'', il ''Corriere della Sera''. Pubblica vari interventi, reportage, riflessioni su argomenti di attualità. La sua attività di scrittore impegnato si intreccia con la partecipazione alla vita mondana.
Nel 1947 il successo del romanzo ''La romana'' lo fa conoscere e apprezzare da un pubblico sempre più ampio. Vari suoi libri si rivelano spunti per riduzioni cinematografiche. Tra i film tratti dalle sue opere si ricordano ''La provinciale'' (1952) di Mario Soldati, ''La romana'' (1954) di Luigi Zampa, ''La ciociara'' (1960) di Vittorio De Sica, ''Agostino o la perdita dell'innocenza'' (1962) di Mauro Bolognini e ''Il conformista'' (1970) di Bernardo Bertolucci. Attivo anche come sceneggiatore, Moravia si avvicina, durante gli anni cinquanta, alla scrittura per il teatro.
Nel 1953 fonda, insieme ad Alberto Carocci, la rivista culturale «Nuovi Argomenti», che dirige fino agli ultimi anni di vita. Nel 1957 inizia a collaborare con ''l'Espresso'', sul quale firma una rubrica di critica cinematografica. Nel 1960 la sua notorietà si amplifica ancora di più dopo il successo del romanzo ''La noia''. Nel 1962 rompe con Elsa Morante e inizia una relazione con la giovane scrittrice [[../Postmoderno#Dacia Maraini|Dacia Maraini]]. Negli anni ottanta il suo impegno politico lo porta a candidarsi alle elezioni europee come indipendente nelle liste del Partito Comunista: eletto, siede al parlamento di Strasburgo dal 1984 al 1989. Muore a Roma il 26 settembre 1990.<ref name="Ferroni1066">{{cita libro | Giulio | Ferroni | Profilo storico della letteratura italiana | 2003 | Einaudi | Torino | p=1066 }}</ref>
== Poetica ==
La passione civile e la curiosità culturale, che hanno accompagnato Moravia per tutta la sua attività letteraria, lo rendono scrittore impegnato. L'opera di Moravia è legata al realismo e indaga le patologie delle classi sociali, specialmente dell'alta e della media borghesia. Il suo è uno stile esclusivamente da narratore che non si compiace di effetti lirici ma si affida esclusivamente allo svolgersi del periodo. Moravia guarda la realtà dall'esterno, lo stile della sua prosa è spoglio e disadorno, sempre regolare e privo di ogni slancio.<ref>{{cita libro | Giulio | Ferroni | Profilo storico della letteratura italiana | 2003 | Einaudi | Torino | p=1068 }}</ref>
== I primi scritti e ''Gli indifferenti'' ==
Moravia inizia a scrivere i suoi primi racconti sulla rivista ''900'' alla quale collabora a partire dal 1927:<ref name="Ferroni1066" /> ''Cortigiana stanca'' (1927), ''Delitto al circolo del tennis'' (1928), ''Il ladro curioso'' e ''Apparizione'' (1929). Il successo ottenuto con il primo romanzo ''Gli indifferenti'' (1929), che viene visto dalla critica come esempio di romanzo esistenzialista e di stampo dostoevskijano,<ref>{{cita pubblicazione|autore=Stefano Guerriero|titolo=«Gli indifferenti» nella storia del romanzo|pubblicazione=Belfagor|vol=63|numero=3|data=31 maggio 2008|p=264|url=https://www.jstor.org/stable/26150663}}</ref> gli permette di proseguire la sua attività di scrittore e gli apre le porte del giornalismo.
Scritto quando l'autore aveva solo 22 anni, il romanzo si presenta come uno dei primi esempi della nuova letteratura che stava nascendo negli anni del [[../Letteratura e fascismo|fascismo]]. L'opera non è il risultato di una riflessione teorica, ma piuttosto da un impulso istintivo che spinge Moravia alla narrazione. Si tratta di una caratteristica tipica del suo stile, che si osserva anche nelle opere successive. Quella descritta negli ''Indifferenti'' è una realtà vuota, in cui i personaggi sono mossi unicamente dal proprio egoismo e non mostrano nessun interesse per la tragedia che si sta consumando. Ne esce un'immagine risentita e violenta della borghesia italiana negli anni del regime.<ref>{{cita libro | Giulio | Ferroni | Profilo storico della letteratura italiana | 2003 | Einaudi | Torino | pp=1068-1069 }}</ref>
Durante il fascismo, che penalizzava la sua origine ebraica da parte del padre, la sua opera viene tenuta sotto controllo e alcuni suoi scritti vietati, come le recensioni a ''Le ambizioni sbagliate'' (1935), o sequestrati, come ''La mascherata'' (1941).<ref name="Ferroni1066" /> In alcuni casi ne viene addirittura impedita la pubblicazione, come avviene per ''Agostino'' (terminato nel 1943). Moravia però non rinuncia alla letteratura e scrive comunque opere di carattere allegorico. Continua inoltre l'attività giornalistica firmando i suoi interventi con uno pseudonimo. Esce in questo periodo la raccolta di racconti ''La bella vita'' (1935), ''L'imbroglio'' (1937) e ''I sogni del pigro'' (1940).<ref name="treccani">{{treccani|alberto-moravia|Moràvia, Alberto}}</ref>
== Gli scritti del dopoguerra: il neorealismo ==
Terminata la seconda guerra mondiale e trascorsi alcuni anni all'estero, Moravia riprende a scrivere e, oltre a dedicarsi al giornalismo, s'interessa di cinema, di teatro e di saggistica. Per il teatro scriverà ''Beatrice Cenci'' (1958), ''Il dio Kurt'' (1968), ''La vita è gioco'' (1969) e come saggista ''L'uomo come fine'' (1963) e l'''Impegno controvoglia'' (1980).<ref name="treccani" />
Nel 1945 lo scrittore pubblica ''Agostino''. Il romanzo segue i turbamenti di un tredicenne, Agostino, che scopre il sesso venendo a sapere di una relazione della madre con un uomo più giovane. Frequentando un gruppo di coetanei disposti a qualsiasi esperienza, il protagonista esce dall'ingenuità, attratto dagli aspetti torbidi della realtà attorno a lui. Tuttavia è frenato nei suoi impulsi dalla sua posizione di bravo ragazzo borghese, che gli impedisce di godere appieno della vitalità a cui possono accedere i ragazzi del popolo. Moravia aggredisce così il mito dell'adolescenza diffuso nella letteratura degli anni trenta, descrivendola come una fase della vita in cui la realtà appare come qualcosa di estraneo e sordido.<ref>{{cita libro | Giulio | Ferroni | Profilo storico della letteratura italiana | 2003 | Einaudi | Torino | p=1069 }}</ref>
[[File:Lollo+moravia la romana 1954.jpg|thumb|Alberto Moravia sul set de ''La romana'' (Zampa) si intrattiene con Gina Lollobrigida]]
Due anni dopo, nel 1947, vede la luce il romanzo ''La romana'', che narra la storia di una giovane prostituta che agisce in un ambiente di polizia fascista e di cospiratori antifascisti. Moravia viene così consacrato come autore [[../Neorealismo|neorealista]]. Seguono, al ritmo di un anno di distanza, ''La disubbidienza'' (1948) e ''L'amore coniugale'' (1949) nei quali lo scrittore fa una critica all'istituzione borghese del matrimonio.
Nel romanzo ''Il conformista'' (1951) racconta la storia di un uomo che diventa una spia dell'OVRA, ispirata all'assassinio dei fratelli Rosselli. Una tra le opere più famose dello scrittore è ''La ciociara'' (1957), storia di una donna del popolo e di sua figlia che vengono mortificate dalla guerra.<ref name="Asor Rosa 406">{{cita libro | autore=Alberto Asor Rosa | titolo=Storia europea della letteratura italiana | editore=Einaudi | città=Torino | anno=2009 | vol=3: ''La letteratura della Nazione'' | p=406 }}</ref> Si annovera anche ''I due amici'', scritto nel 1952 ma rimasto incompiuto e pubblicato da Bompiani nel 2007.
A questa fase sono riconducibili anche i ''Racconti romani'', scritti negli anni cinquanta, e nati dall'osservazione della realtà popolare.<ref name="Asor Rosa 406" />
== Alienazione e crisi esistenziale ==
Nel romanzo ''Il disprezzo'' (1954) e nei successivi, lo scrittore propone le tematiche adeguate alle nuove tendenze letterarie e culturali, come quella dell'alienazione, anche se la linea essenziale che lo guida rimane sempre l'osservazione della realtà. Tra i più noti è ''La noia'' (1960), al quale segue la raccolta di novelle ''L'automa'' (1962), ''L'uomo come fine'' (1964), ''L'attenzione'' (1965), ''Una cosa è una cosa'' (1967).
''La noia'' è, insieme a ''Gli indifferenti'', il romanzo più rappresentativo di Moravia e della sua analisi critica del mondo borghese. Il protagonista Dino è un intellettuale proveniente da una ricca famiglia romana, che fa di sé un'analisi psicologica e morale a partire dal senso di noia che prova. La "noia" non è altro che l'indifferenza di cui parlava il primo romanzo, l'estraneità nei confronti della realtà. Moravia porta avanti un affondo alla borghesia italiana degli anni cinquanta: la noia di Dino è un senso di inadeguatezza della realtà, che non riesce a persuaderlo della sua effettiva esistenza. L'unico modo per uscire da questa incomunicabilità sembra l'esperienza erotica. Anche questa però finisce per far ricadere nella noia, proprio per la sua ansia di possesso.<ref>{{cita libro | Giulio | Ferroni | Profilo storico della letteratura italiana | 2003 | Einaudi | Torino | p=1070 }}</ref>
L'attualità contemporanea rimane un tema centrale anche nei romanzi dei decenni successivi, incentrati sulla sessualità o temi politici, e in specifico quello del terrorismo: ''Il paradiso'' (1970), ''Io e lui'' (1971), ''La vita interiore'' (1978), ''La cosa'' (1983), ''L'uomo che guarda'' (1985), ''Viaggio a Roma'' (1988), ''Palocco'' (1990).
== Note ==
<references />
{{avanzamento|100%|23 settembre 2017}}
[[Categoria:Storia della letteratura italiana|Moravia]]
67wsvr7rt4bw8z2xspjasfwvb6o2mrr
Software e didattica/Video e animazioni
0
39005
501054
444669
2026-08-19T22:09:26Z
~2026-45514-04
54704
/* Video e animazioni */
501054
wikitext
text/x-wiki
<noinclude>{{Software e didattica}}</noinclude>
===Video e animazioni===
Le animazioni e le immagini in movimento sono elementi particolarmente apprezzati da alunni, genitori e insegnanti, ma la loro preparazione (e utilizzazione all'interno di learning objects) non è sempre agevole. La limitata presenza di strumenti freeware e open source per la composizione video costituisce un limite evidente, mentre leggermente migliore è il panorama dei software gratuiti per il trattamento di immagini .gif animate, di files .flv e di filmati .avi a bassa risoluzione. Ci permettiamo di suggerire un inserimento discreto di elementi video nei nostri oggetti di apprendimento, anche per non aumentarne eccessivamente dimensioni e pesantezza. Immediatamente di seguito riporteremo e descriveremo invece alcune applicazioni gratuite che possono risultare utili per preparare animazioni, ma non garantendo per esse in assoluto risultati soddisfacenti in ogni sistema operativo e in qualsiasi condizione e ben sapendo che alcuni software commerciali (come Pinnacle Studio e Nero Vision) sono obiettivamente inarrivabili (e irrinunciabili nel caso si vogliano ottenere risultati professionali).
Peraltro non dobbiamo dimenticare che il mondo del multimediale in Windows è piuttosto complesso e sempre in evoluzione. Per governare i cambiamenti e risultare sempre aggiornati può essere utile considerare un'eccezionale raccolta di codec audio e video, ''K-Lite Codec Pack (Full)'' [http://www.codecguide.com/], con un comodissimo programma di installazione.
==== <u>Windows Movie Maker</u> ====
''Windows Movie Maker'' è stato presente nei sistemi Windows fino alla versione Xp. Il programma non è più nemmeno disponibile dal sito della Microsoft.
==== <u>Synfig Studio</u> ====
''Synfig Studio'' [https://www.synfig.org/] è un programma di animazione vettoriale 2D utilizzabile gratuitamente per Windows, Mac OS X e Linux. Una versione portatile molto comoda è stata preparata dagli esperti di WinPenPack [http://www.winpenpack.com/en/request.php?1275]. Synfig Studio permette di ottenere animazioni fluide senza doverne disegnare individualmente ogni fotogramma. Le tecniche di trasformazione morfologica (passaggio tra due immagini) e di ritaglio (piccole modifiche applicate nel tempo a un'immagine) consentono una facile creazione dei necessari fotogrammi intermedi. In effetti il programma applica effetti avanzati di interpolazione, limitando drasticamente la necessità dell'intervento umano. Occorre comunque una certa pratica per l'utilizzo efficace del programma, certamente non adatto a bambini e adolescenti. E' possibile importare immagini create da GIMP o nel formato .svg, mentre l'esportazione dei lavori può avvenire (ma in certi casi con alcuni artifizi) verso diversi formati di immagini (.bmp, .gif, .jpg, .png) e di video (.dv, .mpg, .flv).
==== <u>Pencil2D</u> ====
Più semplice da usare, pur essendo disponibile solo in lingua inglese, è ''Pencil2D'' [https://www.pencil2d.org/download/], un altro software multipiattaforma per l'animazione grafica 2D (bitmap e vettoriale). Il programma utilizza il formato immagine .ai (Adobe Illustrator Artwork), ma è possibile creare animazioni ed esportare i lavori realizzati in files .swf (Flash) e .mov (quest'ultimo solo per la versione Mac). Pencil gestisce i suoni e i livelli (per cui è possibile disegnare vedendo il resto in trasparenza) e può definire diversi punti di vista per le scene. Un'applicazione ipotizzabile del programma è la realizzazione di cartoni animati o di storie illustrate. Naturalmente i risultati migliori si possono ottenere con una tavoletta grafica di buona qualità.
==== <u>VirtualDub</u> ====
''VirtualDub'' [http://www.virtualdub.org], open source (licenza GNU GPL) per Windows 98/ME/NT4/2000/XP/Vista/7/8/10, disponibile anche in versione portable [http://www.lupopensuite.com/db/virtualdubportable.htm], permette di acquisire ed elaborare contenuti video. Pur non offrendo caratteristiche paragonabili a prodotti professionali come Adobe Premiere, edita i video in modo veloce e lineare e permette di elaborare numerosi formati (ampliabili da filtri forniti da terze parti). Con VirtualDub è possibile: 1) acquisire filmati da TV, telecamere e altre periferiche esterne e comprimerli utilizzando vari formati; 2) importare files .avi anche di grandi dimensioni (oltre la barriera dei 2 GB) e modificarli tramite appositi filtri e/o numerosi parametri; 3) realizzare .gif animate da immagini statiche; 4) importare files .avi, .dvx, .mpg, .mpeg, .gif, .jpg, .png, .tga, .avs e .vdr; 5) esportare i filmati in formato .avi e .dvx; 6) usare funzioni batch per automatizzare le operazioni; 7) ottimizzare l'accesso all'hard disk; 8) ridimensionare e ridurre il rumore in tempo reale; 9) monitorare CPU e spazio libero sul disco; 10) usare scorciatoie per velocizzare le operazioni; 11) operare sulla traccia audio di un video; 12) tagliare, copiare, incollare, unire i filmati. Si può consultare il sito "The filters of Donald Graft" [http://neuron2.net] per prelevare nuovi filtri per il programma.
==== <u>Avisynth</u> ====
''Avisynth'' [http://sourceforge.net/projects/avisynth2], open source (GNU GPL) per Windows, è orientato alla post-produzione e fornisce molti metodi per la modifica dei propri video. Il software funziona grazie a script in formato .avs ed è molto più complesso da usare rispetto a VirtualDub, anche perché non presenta alcuna interfaccia grafica. L'uso in ambienti didattici appare piuttosto problematico, tuttavia la formazione specifica al software di un operatore scolastico permetterebbe la soluzione dei vari problemi di composizione video che si presentano periodicamente nelle scuole.
==== <u>Kdenlive</u> ====
''Kdenlive'' [http://kdenlive.org], acronimo di KDE Non-Linear Video Editor, è un software open source solo per GNU/Linux pensato per l'elaborazione video non lineare. Kdenlive è discretamente stabile e supporta i files QuickTime, .avi, .wmv, .mpeg, .flv, gli standard PAL, NTSC, HD, HDV e i formati 4:3 e 16:9. In output, il programma può scrivere DVD video con menu e capitoli. In fase di elaborazione video è possibile applicare effetti, transizioni, testi e clip di immagini. L'interfaccia grafica (che richiama quella di Adobe Premiere) è gradevole, intuitiva e semplice da capire, quindi, diversamente da Avisynth, Kdenlive, una volta installato in un sistema Linux compatibile, può essere utilizzato anche da insegnanti non particolarmente esperti.
==== <u>Moviesoup</u> ====
Al contrario di Avisynth e Kdenlive, ''Moviesoup'' [http://moviesoup.co.uk] è un software a pagamento, ma si segnala per la semplicità d'uso, che lo rende adatto anche a bambini della scuola primaria.
==== <u>Avidemux e DVDStyler</u> ====
''Avidemux'' [http://sourceforge.net/projects/avidemux/][http://www.winpenpack.com/en/download.php?view.734], open source per Windows (32 e 64 Bit), Linux e Mac OS X, supporta i formati .avi, QuickTime e .mpeg ed è versatile e ricco di opzioni. Il programma in particolare può: 1) modificare, tagliare, unire video; 2) convertire i filmati in tutti i formati più importanti; 3) apporre filtri; 4) lavorare con i sottotitoli; 5) modificare, integrare e sostituire la traccia audio. L'interfaccia è piuttosto intuitiva e basta un po' di pratica per ottenere ottimi contenuti multimediali, anche se non paragonabili a quelli di corrispondenti software commerciali. Rispetto a VirtualDub, Avidemux è molto più curato esteticamente, è più completo ed è più semplice da usare. Avidemux, disponibile anche in italiano, è sicuramente consigliabile quando si devono tagliare alcuni fotogrammi o piccole parti da un video. Sotto l'area di visualizzazione (al centro) si trovano i comandi del player (nell'ordine: Play, Stop, Vai al frame precedente e successivo, Vai al keyframe precedente e successivo, Imposta l'inizio e la fine di un marcatore, Cerca i frames neri, Vai al primo o all'ultimo frame, Vai indietro o avanti di un minuto); ancora più sotto una barra di stato ci fornisce informazioni sull'avanzamento e sui tipi dei fotogrammi; e si può anche scegliere se visualizzare solo le parti eventualmente filtrate. Le configurazioni più complesse si trovano sulla sinistra e comprendono opzioni per il decoder video, l'output video, l'ouput audio, l'output contenitore. Infine nel ricco menù superiore, posto sopra le tre icone per il richiamo e il salvataggio dei files e per la richiesta di informazioni, si trovano sltre funzioni più complesse, come il salvataggio dei fotogrammi come immagini .bmp e .jpg, l'inserimento di un logo persistente, l'applicazione di vari tipi di zoom e la modifica del rumore video (noise), della nitidezza (sharpness) e dei colori. Da segnalare peraltro la presenza di un potente motore di scripting utile per gli utenti più esperti. Nel sito di YouTube, oltre a una guida rapida al programma [http://www.youtube.com/watch?v=fWikDX0g3FE], sono presenti numerosi tutorial sul programma [https://www.youtube.com/results?search_query=avidemux]. All'indirizzo [http://www.pcpercaso.com/video-editing/10-tutorial-dvd-avidemux-dvdstyler.html] troviamo invece una guida per l'uso del programma in combinazione con ''DVDStyler'' [http://www.digital-digest.com/software/download.php?sid=1101&ssid=0&did=30][http://www.winpenpack.com/en/download.php?view.1255] un software per la creazione di menu per DVD. Anche per DVDStyler non mancano tutorial dedicati in YouTube [https://www.youtube.com/results?search_query=dvdstyler].
==== <u>Creazione e modifica di sottotitoli</u> ====
''Subtitle Edit'' [http://www.nikse.dk/SubtitleEdit/][http://www.winpenpack.com/en/download.php?view.1333], freeware per Windows, richiede per il proprio funzionamento .NET Framework e si occupa specificamente dell'inserimento e della modifica di sottotitoli nei video. In modo simile funziona ''Subtitle Creator'' [http://sourceforge.net/projects/subtitlecreator/files/SubtitleCreator/], che si segnala per la facilità d'uso dell'interfaccia WYSIWYG. ''SubRip'' [http://sourceforge.net/projects/subrip/], open source per Windows, all'opposto, estrae dai video i sottotitoli con il loro timing esportandoli in un file di testo; il programma può risultare utile quando si vogliono tradurre dei sottotitoli in lingue diverse.
==== <u>Mpg2Cut2</u> ====
''Mpg2Cut2'' [http://sourceforge.net/projects/mpg2cut2/], sempre gratuito per Windows, è studiato invece per la manipolazione (taglio, unione, divisione) di files video in formato .mpg, .mpv, .m2v, .vob, .m1v, .ts, .evo, .m2t, .pva e .mpeg.
==== <u>VideoLan Movie Creator</u> ====
''VideoLan Movie Creator'' [ftp://ftp.videolan.org/pub/videolan/testing/vlmc/vlmc-0.1.0.exe] è un software open source multipiattaforma semi-professionale per l'editing video basato sul noto ''VLC Media Player'' [http://www.videolan.org/vlc] e [http://www.winpenpack.com/en/download.php?view.36]. Il programma, distribuito con licenza GNU GPL, pur essendo alle prime "releases" (con tutti i problemi di stabilità connessi), promette bene e supporta i formati video PAL<ref>Phase Alternating Line.</ref> e NTCS<ref>National Television System Committee, sistema televisivo usato soprattutto in Nord-America.</ref> con varie risoluzioni (VCD, SVCD,DVD, HDTVi, HDTVp). E' possibile [https://jjtiktok.com/id importare video], ridimensionarli, riprodurli in tempo reale, tagliarne alcune parti e molto altro. Al termine del montaggio video si può caricare il lavoro direttamente su Youtube. Il punto di forza di VideoLan Movie Creator è sicuramente la facilità d'uso, per cui il software è consigliato per ambienti educativi.
==== <u>Animata</u> ====
''Animata'' [http://animata.kibu.hu/index.html] è un programma web particolare (e non molto immediato nell'uso) per la realizzazione di filmati con pupazzi filiformi da far muovere su sfondi animati.
==== <u>Creare filmati da più immagini</u> ====
Infine, per la creazione di filmati a partire da più immagini .jpg sono da segnalare alcuni software gratuiti:
# ''PhotoLapse'' [http://www.softwaredidattico.org/files/photolapse.zip], stand-alone e leggerissimo (solo 152 Kb), è facile da usare, è disponibile per Windows e trasforma le immagini .jpg selezionate in semplici animazioni .avi;
# ''PhotoFilmStrip'' [https://portableapps.com/apps/graphics_pictures/photofilmstrip-portable], open source per Linux e Windows, è disponibile anche in italiano con licenza GPL; PhotoFilmStrip crea, a partire dalle proprie immagini, animazioni e filmati in formato VCD, SVCD, DVD e FULL-HD; il tutto avviene molto facilmente e velocemente attraverso tre semplici passi: 1) selezione delle foto; 2) impostazione delle transizioni; 3) montaggio del video; una guida completa è stata realizzata da Gustavo Barbieri [http://punto-informatico.it/s_3363861/Download/News/photofilmstrip.aspx].
# ''Alternate Pic View ExeSlide'' [http://www.alternate-tools.com/pages/c_exeslide.php?lang=ENG] è un programma versatilissimo: partendo dalle immagini selezionate, si possono creare 4 tipi di eseguibili (.exe), compresi 3 diversi minigiochi, e poi files .scr, .swf, .avi e .gif animate.
==== <u>Servizi web per la produzione video</u> ====
Anche per la produzione video esistono diversi servizi web interessanti, orientati per lo più alla produzione di files Flash .swf:
# ''Domo Animate'' [http://goanimate4schools.com/public_index], adatto a bambini molto piccoli, serve a creare vivaci cartoni animati; si possono realizzare splendide animazioni in un ambiente gradevole che consente l'inserimento nei vari frames di diversi elementi: personaggi animati (con varie azioni e differenti movimenti), fumetti (editabili e personalizzabili nello stile), sfondi vivacissimi, oggetti ridimensionabili e specchiabili, brani musicali, disegni/effetti grafici modificabili; sono disponibili ben 5 librerie di elementi: "Domo", "Cartoon Classics", "Holiday And Seasonal", "Monster Mayhen", "Stick Figure";
# con ''Make Comix Belief'' [http://www.makebeliefscomix.com] si possono realizzare fumetti composti di 2, 3 o 4 vignette; sono disponibili 7 colori di sfondo, oltre 50 personaggi ("characters"), 16 nuvole per colloqui e pensieri, diversi balloons espressivi e numerosi oggetti; tramite i comandi sulla barra a sinistra, gli oggetti posti nelle vignette possono essere spostati, scalati, invertiti (a specchio), cancellati, portati in primo piano o indietro; "Start Over" azzera il fumetto, "Print/Email" lo stampa o manda via e-mail; altri ambienti simili, ma molto meno performanti sono ''Creaza Cartoonist'' [http://www.creazaeducation.com/cartoonist] e ''Pixton'' [http://www.pixton.com]; molto più completo appare invece ''ComicMaster'' [http://www.comicmaster.org.uk], che consente la creazione di bellissimi fumetti e coloratissime strisce; è possibile impostare la distribuzione delle vignette, gli sfondi, i personaggi, le nuvolette (testo parlato e pensato), le caselle di narrazione, gli effetti speciali; il salvataggio del lavoro è permesso solo agli utenti registrati;
# ''Animaps'' [http://www.animaps.com] crea carte geografiche animate utilizzando Google Maps;
# ''TubeChop'' [http://www.tubechop.com] permette (tramite il codice "embed" fornito) la condivisione e l'utilizzo in propri siti di filmati video di YouTube o di loro parti specificate semplicemente indicando l'URL ed agendo sui parametri mostrati ("Start", "End");
# con ''Comment Bubble'' [http://www.commentbubble.com] si possono inserire commenti e note in filmati e video e condividerli on-line nella forma modificata.
==== <u>Convertitori</u> ====
Come convertitore tra formati video appare molto interessante ed efficace ''HandBrake'' [http://sourceforge.net/projects/handbrake], open source (con licenza GPL) per Linux, MacOS X e Windows. Il programma supporta tutti i più comuni formati multimediali, sia video (inclusi BluRay e DVD non protetti) che audio (.aac, .mp3, .flac, .ac3) e permette la modifica di sottotitoli e capitoli e l'inserimento di diversi filtri (Cropping, Scaling, Deblocking, DeInterlace, DeTelecine, ecc.). Oltre a questo programma è consigliabile anche ''TEncoder Video Converter'' [http://sourceforge.net/projects/tencoder], open source disponibile anche come portatile; l'applicazione supporta tutti i formati video considerando separatamente nelle conversioni lingue e sottotitoli degli originali. Con i principali formati video, ma anche audio, lavorano peraltro altri software:
# ''Eusing Free Video Converter'' [http://www.eusing.com/free_video_converter/video_converter.htm] è facile da usare e non richiede codecs esterni;
# ''Any Video Converter Free'' [http://www.anvsoft.com] si segnala sia perché offre numerosi profili di conversione già pronti, sia per le funzioni di editing (ad es. tagli ed unioni di video) e di cattura dei fotogrammi (in fase di setup fare attenzione a non installare i programmi di terze parti eventualmente proposti);
# ''500th Video Converter'' [http://www.glorylogic.com/video-converter.html] è leggerissimo e di facile utilizzo; è possibile, rispetto ai video caricati: convertirli nei formati .avi, .mov, .mkv, .wmv, .vcd, .dvd, .mp4; estrarne l'audio e salvandolo in files .mp3, .wav, .ogg, .flac, .wma; registrarli su CD, DVD e dischi Blue-ray; visualizzarne un'anteprima e salvare fotogrammi singoli; è interessante notare come il software funziona con tutti i sistemi operativi Windows a partire da Windows Xp.
==== <u>Gif animate</u> ====
Molto interessante è anche ''OpenAviToGif'' [http://sourceforge.net/projects/openavitogif], open source per Windows; il programma converte files video .avi, .mkv, .mpg, .mp4, .flv, .mov e .rm in .gif animate sulla base delle impostazioni dell'utente (risoluzione, colori, ritardi tra i frames, iterazioni. ecc.). Simile è ''QGifer'' [http://sourceforge.net/projects/qgifer/], open source per Windows e Linux, disponibile anche portable, utile per la creazione di .gif animate a partire da frames estratti da video in formato .avi e .mp4.
On-line per la creazione di .gif animate a partire dalle proprie immagini sono da segnalare diversi servizi, tutti gratuiti e senza bisogno di registrazione: 1) ''Picasion'' [http://picasion.com], con possibilità di impostare la grandezza (100, 125, 300, 400 pixel o libera fino a 450 pixel) e la velocità (Faster!, Fast, Normal, Slow, Slower, libera fino a 10 secondi) dei files prodotti; 2) ''GifUp'' [http://www.gifup.com], con il controllo della velocità dell'animazione e diverse possibilità di importazione delle immagini necessarie (cattura tramite webcam, upload dal proprio pc, link Internet, prelevamente dagli archivi Flickr); 3) ''GIFMake'' [http://gifmake.com], con caricamento delle immagini (max 1024 kb) da URL Internet o dal proprio hard disk, indicazione del numero di ripetizioni dell'animazione (0 = infinito) ed impostazione delle dimensioni (max 500x500 pixel) delle .gif animate da realizzare; 4) ''MakeAGif'' [http://makeagif.com], con il limite di 1024 kb per le immagini da utilizzare; 5) ''Gickr'' [http://www.gickr.com], con importazione delle immagini (max 10) da indirizzo web o dal proprio computer e praticamente le stesse impostazioni/caratteristiche di Picasion.
TUTTI I COLLEGAMENTI:
# [http://www.softwaredidattico.org/libro/links_3_2_6_1/index.html PARTE 1]
# [http://www.softwaredidattico.org/libro/links_3_2_6_2/index.html PARTE 2]
'''Note'''
[[Categoria:Software e didattica|Video e animazioni]]
{{Avanzamento|100%|13 luglio 2018}}
fod71lo38fv0ccl8ptxn8d9qa1lh55i
501055
501054
2026-08-19T22:12:08Z
~2026-45514-04
54704
i found useful free video tools, so i seem it would be shared with people
501055
wikitext
text/x-wiki
<noinclude>{{Software e didattica}}</noinclude>
===Video e animazioni===
Le animazioni e le immagini in movimento sono elementi particolarmente apprezzati da alunni, genitori e insegnanti, ma la loro preparazione (e utilizzazione all'interno di learning objects) non è sempre agevole. La limitata presenza di strumenti freeware e open source per la composizione video costituisce un limite evidente, mentre leggermente migliore è il panorama dei software gratuiti per il trattamento di immagini .gif animate, di files .flv e di filmati .avi a bassa risoluzione. Ci permettiamo di suggerire un inserimento discreto di elementi video nei nostri oggetti di apprendimento, anche per non aumentarne eccessivamente dimensioni e pesantezza. Immediatamente di seguito riporteremo e descriveremo invece alcune applicazioni gratuite che possono risultare utili per preparare animazioni, ma non garantendo per esse in assoluto risultati soddisfacenti in ogni sistema operativo e in qualsiasi condizione e ben sapendo che alcuni software commerciali (come Pinnacle Studio e Nero Vision) sono obiettivamente inarrivabili (e irrinunciabili nel caso si vogliano ottenere risultati professionali).
Peraltro non dobbiamo dimenticare che il mondo del multimediale in Windows è piuttosto complesso e sempre in evoluzione. Per governare i cambiamenti e risultare sempre aggiornati può essere utile considerare un'eccezionale raccolta di codec audio e video, ''K-Lite Codec Pack (Full)'' [http://www.codecguide.com/], con un comodissimo programma di installazione.
==== <u>Windows Movie Maker</u> ====
''Windows Movie Maker'' è stato presente nei sistemi Windows fino alla versione Xp. Il programma non è più nemmeno disponibile dal sito della Microsoft.
==== <u>Synfig Studio</u> ====
''Synfig Studio'' [https://www.synfig.org/] è un programma di animazione vettoriale 2D utilizzabile gratuitamente per Windows, Mac OS X e Linux. Una versione portatile molto comoda è stata preparata dagli esperti di WinPenPack [http://www.winpenpack.com/en/request.php?1275]. Synfig Studio permette di ottenere animazioni fluide senza doverne disegnare individualmente ogni fotogramma. Le tecniche di trasformazione morfologica (passaggio tra due immagini) e di ritaglio (piccole modifiche applicate nel tempo a un'immagine) consentono una facile creazione dei necessari fotogrammi intermedi. In effetti il programma applica effetti avanzati di interpolazione, limitando drasticamente la necessità dell'intervento umano. Occorre comunque una certa pratica per l'utilizzo efficace del programma, certamente non adatto a bambini e adolescenti. E' possibile importare immagini create da GIMP o nel formato .svg, mentre l'esportazione dei lavori può avvenire (ma in certi casi con alcuni artifizi) verso diversi formati di immagini (.bmp, .gif, .jpg, .png) e di video (.dv, .mpg, .flv).
==== <u>Pencil2D</u> ====
Più semplice da usare, pur essendo disponibile solo in lingua inglese, è ''Pencil2D'' [https://www.pencil2d.org/download/], un altro software multipiattaforma per l'animazione grafica 2D (bitmap e vettoriale). Il programma utilizza il formato immagine .ai (Adobe Illustrator Artwork), ma è possibile creare animazioni ed esportare i lavori realizzati in files .swf (Flash) e .mov (quest'ultimo solo per la versione Mac). Pencil gestisce i suoni e i livelli (per cui è possibile disegnare vedendo il resto in trasparenza) e può definire diversi punti di vista per le scene. Un'applicazione ipotizzabile del programma è la realizzazione di cartoni animati o di storie illustrate. Naturalmente i risultati migliori si possono ottenere con una tavoletta grafica di buona qualità.
==== <u>VirtualDub</u> ====
''VirtualDub'' [http://www.virtualdub.org], open source (licenza GNU GPL) per Windows 98/ME/NT4/2000/XP/Vista/7/8/10, disponibile anche in versione portable [http://www.lupopensuite.com/db/virtualdubportable.htm], permette di acquisire ed elaborare contenuti video. Pur non offrendo caratteristiche paragonabili a prodotti professionali come Adobe Premiere, edita i video in modo veloce e lineare e permette di elaborare numerosi formati (ampliabili da filtri forniti da terze parti). Con VirtualDub è possibile: 1) acquisire filmati da TV, telecamere e altre periferiche esterne e comprimerli utilizzando vari formati; 2) importare files .avi anche di grandi dimensioni (oltre la barriera dei 2 GB) e modificarli tramite appositi filtri e/o numerosi parametri; 3) realizzare .gif animate da immagini statiche; 4) importare files .avi, .dvx, .mpg, .mpeg, .gif, .jpg, .png, .tga, .avs e .vdr; 5) esportare i filmati in formato .avi e .dvx; 6) usare funzioni batch per automatizzare le operazioni; 7) ottimizzare l'accesso all'hard disk; 8) ridimensionare e ridurre il rumore in tempo reale; 9) monitorare CPU e spazio libero sul disco; 10) usare scorciatoie per velocizzare le operazioni; 11) operare sulla traccia audio di un video; 12) tagliare, copiare, incollare, unire i filmati. Si può consultare il sito "The filters of Donald Graft" [http://neuron2.net] per prelevare nuovi filtri per il programma.
==== <u>Avisynth</u> ====
''Avisynth'' [http://sourceforge.net/projects/avisynth2], open source (GNU GPL) per Windows, è orientato alla post-produzione e fornisce molti metodi per la modifica dei propri video. Il software funziona grazie a script in formato .avs ed è molto più complesso da usare rispetto a VirtualDub, anche perché non presenta alcuna interfaccia grafica. L'uso in ambienti didattici appare piuttosto problematico, tuttavia la formazione specifica al software di un operatore scolastico permetterebbe la soluzione dei vari problemi di composizione video che si presentano periodicamente nelle scuole.
==== <u>Kdenlive</u> ====
''Kdenlive'' [http://kdenlive.org], acronimo di KDE Non-Linear Video Editor, è un software open source solo per GNU/Linux pensato per l'elaborazione video non lineare. Kdenlive è discretamente stabile e supporta i files QuickTime, .avi, .wmv, .mpeg, .flv, gli standard PAL, NTSC, HD, HDV e i formati 4:3 e 16:9. In output, il programma può scrivere DVD video con menu e capitoli. In fase di elaborazione video è possibile applicare effetti, transizioni, testi e clip di immagini. L'interfaccia grafica (che richiama quella di Adobe Premiere) è gradevole, intuitiva e semplice da capire, quindi, diversamente da Avisynth, Kdenlive, una volta installato in un sistema Linux compatibile, può essere utilizzato anche da insegnanti non particolarmente esperti.
==== <u>Moviesoup</u> ====
Al contrario di Avisynth e Kdenlive, ''Moviesoup'' [http://moviesoup.co.uk] è un software a pagamento, ma si segnala per la semplicità d'uso, che lo rende adatto anche a bambini della scuola primaria.
==== <u>Avidemux e DVDStyler</u> ====
''Avidemux'' [http://sourceforge.net/projects/avidemux/][http://www.winpenpack.com/en/download.php?view.734], open source per Windows (32 e 64 Bit), Linux e Mac OS X, supporta i formati .avi, QuickTime e .mpeg ed è versatile e ricco di opzioni. Il programma in particolare può: 1) modificare, tagliare, unire video; 2) convertire i filmati in tutti i formati più importanti; 3) apporre filtri; 4) lavorare con i sottotitoli; 5) modificare, integrare e sostituire la traccia audio. L'interfaccia è piuttosto intuitiva e basta un po' di pratica per ottenere ottimi contenuti multimediali, anche se non paragonabili a quelli di corrispondenti software commerciali. Rispetto a VirtualDub, Avidemux è molto più curato esteticamente, è più completo ed è più semplice da usare. Avidemux, disponibile anche in italiano, è sicuramente consigliabile quando si devono tagliare alcuni fotogrammi o piccole parti da un video. Sotto l'area di visualizzazione (al centro) si trovano i comandi del player (nell'ordine: Play, Stop, Vai al frame precedente e successivo, Vai al keyframe precedente e successivo, Imposta l'inizio e la fine di un marcatore, Cerca i frames neri, Vai al primo o all'ultimo frame, Vai indietro o avanti di un minuto); ancora più sotto una barra di stato ci fornisce informazioni sull'avanzamento e sui tipi dei fotogrammi; e si può anche scegliere se visualizzare solo le parti eventualmente filtrate. Le configurazioni più complesse si trovano sulla sinistra e comprendono opzioni per il decoder video, l'output video, l'ouput audio, l'output contenitore. Infine nel ricco menù superiore, posto sopra le tre icone per il richiamo e il salvataggio dei files e per la richiesta di informazioni, si trovano sltre funzioni più complesse, come il salvataggio dei fotogrammi come immagini .bmp e .jpg, l'inserimento di un logo persistente, l'applicazione di vari tipi di zoom e la modifica del rumore video (noise), della nitidezza (sharpness) e dei colori. Da segnalare peraltro la presenza di un potente motore di scripting utile per gli utenti più esperti. Nel sito di YouTube, oltre a una guida rapida al programma [https://www.youtube.com/watch?v=fWikDX0g3FE], sono presenti numerosi tutorial sul programma [https://www.youtube.com/results?search_query=avidemux]. All'indirizzo [http://www.pcpercaso.com/video-editing/10-tutorial-dvd-avidemux-dvdstyler.html] troviamo invece una guida per l'uso del programma in combinazione con ''DVDStyler'' [http://www.digital-digest.com/software/download.php?sid=1101&ssid=0&did=30][http://www.winpenpack.com/en/download.php?view.1255] un software per la creazione di menu per DVD. Anche per DVDStyler non mancano tutorial dedicati in YouTube [https://www.youtube.com/results?search_query=dvdstyler].
==== <u>Creazione e modifica di sottotitoli</u> ====
''Subtitle Edit'' [http://www.nikse.dk/SubtitleEdit/][http://www.winpenpack.com/en/download.php?view.1333], freeware per Windows, richiede per il proprio funzionamento .NET Framework e si occupa specificamente dell'inserimento e della modifica di sottotitoli nei video. In modo simile funziona ''Subtitle Creator'' [http://sourceforge.net/projects/subtitlecreator/files/SubtitleCreator/], che si segnala per la facilità d'uso dell'interfaccia WYSIWYG. ''SubRip'' [http://sourceforge.net/projects/subrip/], open source per Windows, all'opposto, estrae dai video i sottotitoli con il loro timing esportandoli in un file di testo; il programma può risultare utile quando si vogliono tradurre dei sottotitoli in lingue diverse.
==== <u>Mpg2Cut2</u> ====
''Mpg2Cut2'' [http://sourceforge.net/projects/mpg2cut2/], sempre gratuito per Windows, è studiato invece per la manipolazione (taglio, unione, divisione) di files video in formato .mpg, .mpv, .m2v, .vob, .m1v, .ts, .evo, .m2t, .pva e .mpeg.
==== <u>VideoLan Movie Creator</u> ====
''VideoLan Movie Creator'' [ftp://ftp.videolan.org/pub/videolan/testing/vlmc/vlmc-0.1.0.exe] è un software open source multipiattaforma semi-professionale per l'editing video basato sul noto ''VLC Media Player'' [http://www.videolan.org/vlc] e [http://www.winpenpack.com/en/download.php?view.36]. Il programma, distribuito con licenza GNU GPL, pur essendo alle prime "releases" (con tutti i problemi di stabilità connessi), promette bene e supporta i formati video PAL<ref>Phase Alternating Line.</ref> e NTCS<ref>National Television System Committee, sistema televisivo usato soprattutto in Nord-America.</ref> con varie risoluzioni (VCD, SVCD,DVD, HDTVi, HDTVp). E' possibile [https://jjtiktok.com/id importare video], ridimensionarli, riprodurli in tempo reale, tagliarne alcune parti e molto altro. Al termine del montaggio video si può caricare il lavoro direttamente su Youtube. Il punto di forza di VideoLan Movie Creator è sicuramente la facilità d'uso, per cui il software è consigliato per ambienti educativi.
==== <u>Animata</u> ====
''Animata'' [http://animata.kibu.hu/index.html] è un programma web particolare (e non molto immediato nell'uso) per la realizzazione di filmati con pupazzi filiformi da far muovere su sfondi animati.
==== <u>Creare filmati da più immagini</u> ====
Infine, per la creazione di filmati a partire da più immagini .jpg sono da segnalare alcuni software gratuiti:
# ''PhotoLapse'' [http://www.softwaredidattico.org/files/photolapse.zip], stand-alone e leggerissimo (solo 152 Kb), è facile da usare, è disponibile per Windows e trasforma le immagini .jpg selezionate in semplici animazioni .avi;
# ''PhotoFilmStrip'' [https://portableapps.com/apps/graphics_pictures/photofilmstrip-portable], open source per Linux e Windows, è disponibile anche in italiano con licenza GPL; PhotoFilmStrip crea, a partire dalle proprie immagini, animazioni e filmati in formato VCD, SVCD, DVD e FULL-HD; il tutto avviene molto facilmente e velocemente attraverso tre semplici passi: 1) selezione delle foto; 2) impostazione delle transizioni; 3) montaggio del video; una guida completa è stata realizzata da Gustavo Barbieri [http://punto-informatico.it/s_3363861/Download/News/photofilmstrip.aspx].
# ''Alternate Pic View ExeSlide'' [http://www.alternate-tools.com/pages/c_exeslide.php?lang=ENG] è un programma versatilissimo: partendo dalle immagini selezionate, si possono creare 4 tipi di eseguibili (.exe), compresi 3 diversi minigiochi, e poi files .scr, .swf, .avi e .gif animate.
==== <u>Servizi web per la produzione video</u> ====
Anche per la produzione video esistono diversi servizi web interessanti, orientati per lo più alla produzione di files Flash .swf:
# ''Domo Animate'' [http://goanimate4schools.com/public_index], adatto a bambini molto piccoli, serve a creare vivaci cartoni animati; si possono realizzare splendide animazioni in un ambiente gradevole che consente l'inserimento nei vari frames di diversi elementi: personaggi animati (con varie azioni e differenti movimenti), fumetti (editabili e personalizzabili nello stile), sfondi vivacissimi, oggetti ridimensionabili e specchiabili, brani musicali, disegni/effetti grafici modificabili; sono disponibili ben 5 librerie di elementi: "Domo", "Cartoon Classics", "Holiday And Seasonal", "Monster Mayhen", "Stick Figure";
# con ''Make Comix Belief'' [http://www.makebeliefscomix.com] si possono realizzare fumetti composti di 2, 3 o 4 vignette; sono disponibili 7 colori di sfondo, oltre 50 personaggi ("characters"), 16 nuvole per colloqui e pensieri, diversi balloons espressivi e numerosi oggetti; tramite i comandi sulla barra a sinistra, gli oggetti posti nelle vignette possono essere spostati, scalati, invertiti (a specchio), cancellati, portati in primo piano o indietro; "Start Over" azzera il fumetto, "Print/Email" lo stampa o manda via e-mail; altri ambienti simili, ma molto meno performanti sono ''Creaza Cartoonist'' [http://www.creazaeducation.com/cartoonist] e ''Pixton'' [http://www.pixton.com]; molto più completo appare invece ''ComicMaster'' [http://www.comicmaster.org.uk], che consente la creazione di bellissimi fumetti e coloratissime strisce; è possibile impostare la distribuzione delle vignette, gli sfondi, i personaggi, le nuvolette (testo parlato e pensato), le caselle di narrazione, gli effetti speciali; il salvataggio del lavoro è permesso solo agli utenti registrati;
# ''Animaps'' [http://www.animaps.com] crea carte geografiche animate utilizzando Google Maps;
# ''TubeChop'' [http://www.tubechop.com] permette (tramite il codice "embed" fornito) la condivisione e l'utilizzo in propri siti di filmati video di YouTube o di loro parti specificate semplicemente indicando l'URL ed agendo sui parametri mostrati ("Start", "End");
# con ''Comment Bubble'' [http://www.commentbubble.com] si possono inserire commenti e note in filmati e video e condividerli on-line nella forma modificata.
==== <u>Convertitori</u> ====
Come convertitore tra formati video appare molto interessante ed efficace ''HandBrake'' [http://sourceforge.net/projects/handbrake], open source (con licenza GPL) per Linux, MacOS X e Windows. Il programma supporta tutti i più comuni formati multimediali, sia video (inclusi BluRay e DVD non protetti) che audio (.aac, .mp3, .flac, .ac3) e permette la modifica di sottotitoli e capitoli e l'inserimento di diversi filtri (Cropping, Scaling, Deblocking, DeInterlace, DeTelecine, ecc.). Oltre a questo programma è consigliabile anche ''TEncoder Video Converter'' [http://sourceforge.net/projects/tencoder], open source disponibile anche come portatile; l'applicazione supporta tutti i formati video considerando separatamente nelle conversioni lingue e sottotitoli degli originali. Con i principali formati video, ma anche audio, lavorano peraltro altri software:
# ''Eusing Free Video Converter'' [http://www.eusing.com/free_video_converter/video_converter.htm] è facile da usare e non richiede codecs esterni;
# ''Any Video Converter Free'' [http://www.anvsoft.com] si segnala sia perché offre numerosi profili di conversione già pronti, sia per le funzioni di editing (ad es. tagli ed unioni di video) e di cattura dei fotogrammi (in fase di setup fare attenzione a non installare i programmi di terze parti eventualmente proposti);
# ''500th Video Converter'' [http://www.glorylogic.com/video-converter.html] è leggerissimo e di facile utilizzo; è possibile, rispetto ai video caricati: convertirli nei formati .avi, .mov, .mkv, .wmv, .vcd, .dvd, .mp4; estrarne l'audio e salvandolo in files .mp3, .wav, .ogg, .flac, .wma; registrarli su CD, DVD e dischi Blue-ray; visualizzarne un'anteprima e salvare fotogrammi singoli; è interessante notare come il software funziona con tutti i sistemi operativi Windows a partire da Windows Xp.
==== <u>Gif animate</u> ====
Molto interessante è anche ''OpenAviToGif'' [http://sourceforge.net/projects/openavitogif], open source per Windows; il programma converte files video .avi, .mkv, .mpg, .mp4, .flv, .mov e .rm in .gif animate sulla base delle impostazioni dell'utente (risoluzione, colori, ritardi tra i frames, iterazioni. ecc.). Simile è ''QGifer'' [http://sourceforge.net/projects/qgifer/], open source per Windows e Linux, disponibile anche portable, utile per la creazione di .gif animate a partire da frames estratti da video in formato .avi e .mp4.
On-line per la creazione di .gif animate a partire dalle proprie immagini sono da segnalare diversi servizi, tutti gratuiti e senza bisogno di registrazione: 1) ''Picasion'' [http://picasion.com], con possibilità di impostare la grandezza (100, 125, 300, 400 pixel o libera fino a 450 pixel) e la velocità (Faster!, Fast, Normal, Slow, Slower, libera fino a 10 secondi) dei files prodotti; 2) ''GifUp'' [http://www.gifup.com], con il controllo della velocità dell'animazione e diverse possibilità di importazione delle immagini necessarie (cattura tramite webcam, upload dal proprio pc, link Internet, prelevamente dagli archivi Flickr); 3) ''GIFMake'' [http://gifmake.com], con caricamento delle immagini (max 1024 kb) da URL Internet o dal proprio hard disk, indicazione del numero di ripetizioni dell'animazione (0 = infinito) ed impostazione delle dimensioni (max 500x500 pixel) delle .gif animate da realizzare; 4) ''MakeAGif'' [https://makeagif.com], con il limite di 1024 kb per le immagini da utilizzare; 5) ''Gickr'' [http://www.gickr.com], con importazione delle immagini (max 10) da indirizzo web o dal proprio computer e praticamente le stesse impostazioni/caratteristiche di Picasion.
[https://jjtiktok.com/id Video Downloader for Tiktokers]
TUTTI I COLLEGAMENTI:
# [http://www.softwaredidattico.org/libro/links_3_2_6_1/index.html PARTE 1]
# [http://www.softwaredidattico.org/libro/links_3_2_6_2/index.html PARTE 2]
'''Note'''
[[Categoria:Software e didattica|Video e animazioni]]
{{Avanzamento|100%|13 luglio 2018}}
b8y0702yjfxl9dmz6lpqqwghac1a93b
Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa
0
41565
501060
501032
2026-08-19T22:44:24Z
~2026-45474-98
54699
501060
wikitext
text/x-wiki
{{Disposizioni foniche di organi a canne}}
Disposizioni foniche del [[w:Libero consorzio comunale di Siracusa|libero consorzio comunale di Siracusa]] raggruppate per comune:
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Siracusa|Siracusa]]
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Augusta|Augusta]]
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Avola|Avola]]
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Canicattini Bagni|Canicattini Bagni]]
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Carlentini|Carlentini]]
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Buccheri|Buccheri]]
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Buscemi|Buscemi]]
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Floridia|Floridia]]
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Francoforte|Francoforte]]
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Lentini|Lentini]]
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Melilli|Melilli]]
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Noto|Noto]]
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Pachino|Pachino]]
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Palazzolo Acreide|Palazzolo Acreide]]
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Rosolini|Rosolini]]
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Solarino|Solarino]]
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Sortino|Sortino]]
{{Avanzamento|15%|20 novembre 2019}}
[[Categoria:Disposizioni foniche di organi a canne]]
ry2hx0qwzi9uakenwn67qystft6h5w3
Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Siracusa
0
44112
501058
501035
2026-08-19T22:20:41Z
~2026-45474-98
54699
501058
wikitext
text/x-wiki
{{Disposizioni foniche di organi a canne}}
Disposizioni foniche del comune di [[w:Siracusa|Siracusa]] raggruppate per edificio.
== Capoluogo ==
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Siracusa/Siracusa - Cattedrale metropolitana della Natività di Maria Santissima|Cattedrale metropolitana della Natività di Maria Santissima]]
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Siracusa/Siracusa - Chiesa di San Filippo Apostolo|Chiesa di San Filippo Apostolo]]
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Siracusa/Siracusa - Chiesa di San Filippo Neri|Chiesa di San Filippo Neri]]
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Siracusa/Siracusa - Chiesa di San Giuseppe|Chiesa di San Giuseppe]]
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Siracusa/Siracusa - Chiesa di San Martino|Chiesa di San Martino]]
{{Avanzamento|25%|22 ottobre 2019}}
[[Categoria:Disposizioni foniche di organi a canne]]
ji9mqonoduo7gotbte09qylps48ds4x
Wikibooks:GUS2Wiki
4
51801
501043
500858
2026-08-19T19:54:21Z
Alexis Jazz
37143
Updating gadget usage statistics from [[Special:GadgetUsage]] ([[phab:T121049]])
501043
wikitext
text/x-wiki
{{#ifexist:Project:GUS2Wiki/top|{{/top}}|This page provides a historical record of [[Special:GadgetUsage]] through its page history. To get the data in CSV format, see wikitext. To customize this message or add categories, create [[/top]].}}
I dati che seguono sono estratti da una copia ''cache'' del database, il cui ultimo aggiornamento risale al 2026-08-19T07:25:31Z. Un massimo di {{PLURAL:5000|un risultato è disponibile|5000 risultati è disponibile}} in cache.
{| class="sortable wikitable"
! Accessorio !! data-sort-type="number" | Numero di utenti !! data-sort-type="number" | Utenti attivi
|-
|BordiArrotondati || 31 || 0
|-
|CatWatch || 21 || 0
|-
|Chat || 22 || 0
|-
|EDTitle || 18 || 0
|-
|HotCat || 51 || 3
|-
|LinkComplete || 18 || 0
|-
|MassDelete || 2 || 1
|-
|NMS || 11 || 0
|-
|Orologio || 36 || 0
|-
|Popup || 24 || 3
|-
|Purge || 50 || 3
|-
|QuickEdit || 31 || 0
|-
|Ricetta || data-sort-value="Infinity" | Predefinito || data-sort-value="Infinity" | Predefinito
|-
|Spostamento || 23 || 2
|-
|Toolbar || 14 || 2
|-
|Unwatch || 32 || 1
|-
|UserEditCount || 37 || 1
|-
|Wiked || 39 || 0
|-
|canctxt || 10 || 1
|-
|dictionaryLookupHover || 20 || 1
|-
|lastedit || 41 || 0
|-
|nav-aut || 22 || 0
|-
|nav-blocklist || 24 || 1
|-
|nav-bot || 12 || 0
|-
|nav-canc || 25 || 1
|-
|nav-cancimm || 9 || 0
|-
|nav-css || 20 || 0
|-
|nav-js || 17 || 0
|-
|nav-log || 31 || 0
|-
|nav-newpages || 33 || 0
|-
|nav-prob || 23 || 1
|-
|nav-rfa || 30 || 1
|-
|nav-sandbox || 318 || 1
|-
|nav-struadmin || 16 || 0
|-
|nav-vand || 26 || 1
|-
|section0 || 32 || 0
|-
|stru-whois || 21 || 0
|-
|strumentivari || 21 || 1
|-
|tb-aiutare || 52 || 2
|-
|tb-barr || 67 || 1
|-
|tb-case || 75 || 1
|-
|tb-controllare || 48 || 2
|-
|tb-noinclude || 54 || 1
|-
|tb-sott || 88 || 1
|}
* [[Speciale:GadgetUsage]]
* [[m:Meta:GUS2Wiki/Script|GUS2Wiki]]
<!-- data in CSV format:
BordiArrotondati,31,0
CatWatch,21,0
Chat,22,0
EDTitle,18,0
HotCat,51,3
LinkComplete,18,0
MassDelete,2,1
NMS,11,0
Orologio,36,0
Popup,24,3
Purge,50,3
QuickEdit,31,0
Ricetta,default,default
Spostamento,23,2
Toolbar,14,2
Unwatch,32,1
UserEditCount,37,1
Wiked,39,0
canctxt,10,1
dictionaryLookupHover,20,1
lastedit,41,0
nav-aut,22,0
nav-blocklist,24,1
nav-bot,12,0
nav-canc,25,1
nav-cancimm,9,0
nav-css,20,0
nav-js,17,0
nav-log,31,0
nav-newpages,33,0
nav-prob,23,1
nav-rfa,30,1
nav-sandbox,318,1
nav-struadmin,16,0
nav-vand,26,1
section0,32,0
stru-whois,21,0
strumentivari,21,1
tb-aiutare,52,2
tb-barr,67,1
tb-case,75,1
tb-controllare,48,2
tb-noinclude,54,1
tb-sott,88,1
-->
ptqi3hqoah2438u33zbp7fkm8dffa8k
Software libero a scuola/Minetest/Luanti a scuola
0
60667
501039
500182
2026-08-19T15:40:19Z
Mattruffoni
17392
aggiornato la m,opdalità per ottenere un file obj
501039
wikitext
text/x-wiki
{{Software libero a scuola}}
Usare Luanti/Minetest per giocare a conoscere il territorio e, volendo, progettarne gli sviluppi futuri.
== Il Progetto: La scuola come laboratorio di pianificazione territoriale ==
Questo manuale nasce con l'obiettivo di guidare docenti e studenti nell'utilizzo di '''Luanti''' (precedentemente noto come ''Minetest'') come strumento didattico, integrando la tecnologia, la geografia (GIS), la matematica e l'educazione civica.
Il cuore del progetto si articola su tre pilastri fondamentali:
* '''Esplorare e Osservare (La Georeferenziazione):''' Creare un mondo digitale che sia il facsimile esatto del proprio territorio reale. Attraverso l'importazione di dati geografici e altimetrici reali, gli studenti possono muoversi in scala 1:1 in un ambiente virtuale familiare, imparando a leggere la morfologia della propria terra da una prospettiva inedita e immersiva.
* '''Progettare ed Eseguire (La Ricostruzione):''' Permettere agli studenti di ricostruire l'ambiente, i monumenti e i complessi urbani. Questo processo stimola lo sviluppo di competenze geometriche, di calcolo spaziale e di problem-solving strutturale, costringendo il ragazzo a passare dall'osservazione della realtà alla sua astrazione e successiva esecuzione tridimensionale a blocchi.
* '''Partecipare (La Cittadinanza Attiva):''' Dare ai ragazzi la possibilità di utilizzare il server condiviso come un laboratorio democratico per la pianificazione urbana e infrastrutturale collettiva. Gli studenti non si limitano a replicare il presente o il passato, ma possono proporre modifiche, nuove infrastrutture e varianti urbanistiche, imparando il valore del dibattito, della negoziazione e della progettazione comunitaria del bene comune.
Attraverso questo percorso, il mondo voxel di Luanti smette di essere un semplice videogioco e diventa un vero e proprio '''gemello digitale didattico''', un ponte tra la scuola e il territorio in grado di formare cittadini consapevoli e tecnicamente preparati.
== Il Valore del Software Libero e l'Accessibilità ==
L'adozione di software libero come Luanti elimina alla radice l'ostacolo delle licenze commerciali e dei costi per le scuole e le famiglie. Questa libertà tecnologica si traduce in una straordinaria agilità operativa: permette di configurare, personalizzare e pubblicare online un server scolastico in modo immediato. Per gli studenti, l'accesso a questo "gemello digitale" del territorio diventa sicuro e inclusivo: chiunque, da qualsiasi dispositivo a casa o a scuola, può connettersi liberamente e partecipare al progetto collettivo, con l'unico requisito di inserire il proprio nome utente e password personalizzati.
== Flusso di lavoro: Dati GIS, Modellazione 3D e Iniezione in Luanti ==
Questo capitolo documenta passo dopo passo la pipeline tecnologica utilizzata per trasformare i dati geografici e altimetrici reali della Val di Ledro in un mondo 3D interamente calpestabile all'interno del server Luanti (Minetest).
=== Fase 1: Acquisizione dei dati geografici e modellazione in Blender ===
==== 1. Selezione dell'Area di Interesse (OSM) ====
Il progetto ha inizio con la delimitazione della zona geografica. Utilizzando il software di modellazione 3D '''Blender''' combinato con l'add-on '''Blender-GIS''', è stato possibile connettersi direttamente ai server cartografici globali. Tramite l'interfaccia di georeferenziazione, è stato ritagliato il perimetro esatto della Val di Ledro attingendo alla cartografia vettoriale di '''OpenStreetMap (OSM)'''. Questa operazione fissa le coordinate di base (Latitudine/Longitudine) nel sistema di riferimento del progetto.
==== 2. Generazione del Rilievo Altimetrico (SRTM) ====
Una volta ottenuta la mappa bidimensionale, si è passati alla terza dimensione applicando i dati altimetrici reali. Sfruttando la funzione di importazione DEM (Digital Elevation Model) di Blender-GIS, sono stati scaricati i dati '''SRTM (Shuttle Radar Topography Mission)''' forniti dalla NASA. Il plugin ha proiettato questi dati vettoriali sulla mesh piana di Blender, deformandola e generando un modello tridimensionale fedele del rilievo montuoso e della morfologia della valle.
==== 3. Download dei Volumi degli Edifici ====
Per integrare l'elemento antropico, è stato effettuato un download mirato direttamente dal portale ufficiale [https://www.openstreetmap.org openstreetmap.org]. È stato esportato un file con estensione <code>.osm</code>, contenente tutti i metadati e le impronte planimetriche degli edifici (i "volumi" e i poligoni delle case) registrati all'interno della medesima area geografica della valle.
==== 4. Posizionamento e Georeferenziazione delle Case ====
Il file <code>.osm</code> grezzo è stato importato all'interno della scena di Blender, sempre tramite l'ausilio di Blender-GIS. Il plugin, riconoscendo la corrispondenza delle coordinate geografiche condivise, ha posizionato automaticamente e matematicamente i volumi geometrici degli edifici sopra il rilievo 3D precedentemente generato, incollando le fondamenta delle case alle rispettive quote del terreno. Nell'importazione viene scelta l'opzione ''buildings''.
==== 5. Importazione del lago ====
Nello stesso modo, e con lo stesso file .osm, usato per importare gli edifici scegliendo l'opzione ''water'' è stato importato il lago di Ledro. Sul lago si è docvuto applicare un ''modifier'' che ha aggiunto una triangolazione della superficie.
==== 6. Esportazione della Mesh ====
Una volta preparato il file in vblender si è proceduto all'esportazione del modello in un formato di interscambio testuale standard. Il file risultante è stato salvato con il nome di <code>LedroValleCompleta.obj</code>, contenente: l'elenco puro dei vertici tridimensionali del terreno, gli edifici in 3d e la superficie del lago.
Un altra informazione contenuta nei file .osm ad esempio è il nome delle vie e degli edifici, ed anche questo dato è interessante da importare nel mondo virtuale in mod da rendewre i luoghi più riconoscibili.
=== Fase 2: Parsing, Ottimizzazione e Struttura Server ===
=== Il problema tecnologico ===
I metodi tradizionali di scrittura dei nodi in Luanti via API standard (come `minetest.set_node`) mostrano forti limiti quando si gestiscono milioni di coordinate geometriche:
# '''Timeout UDP e Disconnessioni:''' L'elaborazione lineare di file massivi blocca il thread principale del server, causando il congelamento della rete e l'espulsione dei client.
# '''Errore Map::getNodeMetadata (Block not found):''' In ambienti a mappa vuota (es. mapgen `singlenode`), il server fallisce l'accesso ai metadati di blocchi non ancora inizializzati sul database del mondo (`map.sqlite`), generando migliaia di warning e fallendo la scrittura.
# '''Saturazione RAM in Blender:''' L'uso di modificatori come il ''Remesh'' su mesh territoriali molto estese (es. 20x12 km) satura la memoria volatile del sistema operativo, causando il crash del software di modellazione.
=== Architettura della Soluzione ===
La pipeline definitiva si divide in due fasi staccate: un'ottimizzazione matematica dei dati in locale tramite Python e un'iniezione asincrona a basso livello nel server Luanti tramite Lua.
==== Fase 1: Estrazione e Interpolazione dei Dati (Python) ====
Invece di sovraccaricare il motore di gioco o Blender, si utilizza uno script Python esterno sfruttando la libreria '''SciPy''' e l'algoritmo `NearestNDInterpolator` (o `LinearNDInterpolator`).
Lo script esegue le seguenti operazioni:
# Legge i vertici geometrici (`v X Y Z`) dal file `.obj` originale.
# Rileva i confini geografici assoluti della mappa.
# Inizializza un interpolatore spaziale e proietta i dati su una griglia fitta bidimensionale regolare (Heightmap) con un passo stabilito (es. ogni 2 metri).
# Tappa matematicamente i "buchi di cielo" presenti nella mesh rada, assegnando a ogni coordinata vuota l'altezza corretta calcolata sui punti vicini.
# Genera un file di testo ordinato (`ledro_terreno_dati.txt`) in formato `X,Y,Z`.
==== 7. Conversione e Densificazione dei Dati (Python e SciPy) ====
I file <code>.obj</code> nativi presentano una struttura a nuvola di punti (Point Cloud) rada e non ordinata. Con il supporto di '''Gemini''', sono stati sviluppati gli script Python per elaborare i dati:
* <code>estrai_griglia.py</code>: Questo script utilizza la libreria scientifica '''SciPy''' (in particolare l'algoritmo <code>NearestNDInterpolator</code>) per analizzare i 66.481 vertici originali distribuiti su un'area di circa 20x12 km. Python proietta questi punti su una griglia fitta bidimensionale regolare (Heightmap) con un passo costante (es. ogni 2 metri), interpolando matematicamente le altezze nei punti vuoti per "tappare i buchi di cielo" e generando un file coordinato e continuo chiamato <code>ledro_terreno_dati.txt</code> in formato <code>X,Y,Z</code>.<syntaxhighlight lang="python">
import os
import numpy as np
from scipy.interpolate import NearestNDInterpolator
FILE_OBJ = "LedroRilievo.obj"
FILE_OUTPUT = "ledro_terreno_dati.txt"
PASSO = 2 # Un punto ogni 2 metri
print("1. Lettura di tutti i vertici dal file OBJ...")
punti_validi = []
with open(FILE_OBJ, "r") as f:
for line in f:
if line.startswith("v "):
parti = line.split()
if len(parti) >= 4:
try:
punti_validi.append((float(parti[1]), float(parti[2]), float(parti[3])))
except ValueError:
continue
if not punti_validi:
print("ERRORE: Nessun vertice trovato nel file OBJ!")
exit()
# Coordinate separate
x_arr = np.array([p[0] for p in punti_validi])
y_arr = np.array([p[1] for p in punti_validi])
z_arr = np.array([p[2] for p in punti_validi])
min_x, max_x = int(np.min(x_arr)), int(np.max(x_arr))
min_z, max_z = int(np.min(z_arr)), int(np.max(z_arr))
print(f"Confini rilevati -> X: [{min_x} a {max_x}], Z: [{min_z} a {max_z}]")
print("2. Inizializzazione interpolatore geometrico (SciPy)...")
# Creiamo l'interpolatore basato sui punti noti dell'OBJ
interp = NearestNDInterpolator(list(zip(x_arr, z_arr)), y_arr)
print("3. Generazione griglia fitta continua e scrittura...")
# Generiamo gli intervalli regolari basati sul PASSO scelto
intervallo_x = np.arange(round(min_x / PASSO) * PASSO, round(max_x / PASSO) * PASSO + PASSO, PASSO)
intervallo_z = np.arange(round(min_z / PASSO) * PASSO, round(max_z / PASSO) * PASSO + PASSO, PASSO)
punti_totali_scritti = 0
with open(FILE_OUTPUT, "w") as out:
for gx in intervallo_x:
# Calcoliamo l'altezza per l'intera colonna Z in un colpo solo (velocissimo)
gz_array = np.array(list(intervallo_z))
gx_array = np.full_like(gz_array, gx)
# SciPy calcola le altezze interpolate istantaneamente per tutta la riga
altezze_interpolate = interp(gx_array, gz_array)
for i, gz in enumerate(intervallo_z):
gy = round(altezze_interpolate[i])
out.write(f"{gx},{gy},{gz}\n")
punti_totali_scritti += 1
print(f"Operazione completata! Generata griglia solida continua con {punti_totali_scritti} punti complessivi.")
</syntaxhighlight>
* <code>ledro_convertitore_case.py</code>: Estrae le posizioni degli edifici associandole ai rispettivi blocchi di costruzione, generando il file ordinato <code>ledro_case_dati.txt</code><syntaxhighlight lang="python">
import numpy as np
import trimesh
import os
from math import ceil
# ==========================================
# CONFIGURAZIONE COSTANTI
# ==========================================
FILE_OBJ_TERRENO = "LedroRilievo.obj"
FILE_OBJ_CASE = "LedroCase.obj"
NOME_FILE_USCITA = "ledro_case_dati.txt"
# Scala 1.0 per corrispondenza esatta con il terreno a passo 1 metro
FAUTORE_SCALA = 1.0
START_Y = 30
def converti_case_streaming(terreno_input, case_input, file_output):
if not os.path.exists(case_input) or not os.path.exists(terreno_input):
print("Errore: Uno dei file OBJ non esiste nella cartella attuale!")
return
# 1. Calcolo del centro del terreno per l'allineamento perfetto degli assi
print(f"Lettura terreno per allineamento assi: {terreno_input}...")
scena_t = trimesh.load(terreno_input, force='mesh')
mesh_t = trimesh.util.concatenate([g for g in scena_t.geometry.values()]) if isinstance(scena_t, trimesh.Scene) else scena_t
bounds_t = mesh_t.bounds
min_x_t, _, min_z_t = bounds_t[0]
max_x_t, _, max_z_t = bounds_t[1]
centro_x = int((max_x_t - min_x_t) / 2)
centro_z = int((max_z_t - min_z_t) / 2)
# 2. Caricamento e pulizia della mesh degli edifici
print(f"Caricamento edifici da {case_input}...")
scena_c = trimesh.load(case_input, force='mesh')
if isinstance(scena_c, trimesh.Scene):
mesh_unica_case = trimesh.util.concatenate([g for g in scena_c.geometry.values()])
else:
mesh_unica_case = scena_c
print("Pulizia della mesh e fusione dei vertici adiacenti...")
# Valida e salda insieme i poligoni staccati della stessa struttura
mesh_unica_case.process(validate=True)
print("Separazione degli edifici in componenti connesse...")
edifici_grezzi = mesh_unica_case.split(only_watertight=False)
# Filtriamo le bricioline geometriche inferiori a 2mq
edifici = [edf for edf in edifici_grezzi if edf.area > 2.0]
print(f"Trovati {len(edifici)} edifici reali stabili. Generazione geometrie cave...")
# Rimuoviamo il vecchio file se presente
if os.path.exists(file_output):
os.remove(file_output)
# 3. Ciclo di generazione geometrica delle case cave (SOLO SOLIDI)
edifici_scritti = 0
with open(file_output, "w") as f:
for i, edf in enumerate(edifici):
b = edf.bounds
min_x, min_y, min_z = b[0]
max_x, max_y, max_z = b[1]
dim_x = int(ceil(max_x - min_x))
dim_y = int(ceil(max_y - min_y))
dim_z = int(ceil(max_z - min_z))
# FILTRO DI SICUREZZA ANTI-LOOP (ARTEFATTI GIS):
# Se un "edificio" supera le dimensioni di un enorme isolato, è un errore di mesh dell'OBJ.
# Lo saltiamo per evitare che i cicli for successivi congelino la CPU.
if dim_x > 60 or dim_z > 60 or dim_y > 40:
continue
# APPLICAZIONE REGOLE PUNTO 4: Vincoli minimi (5x6x5)
larghezza_x = max(5, dim_x)
lunghezza_z = max(6, dim_z)
altezza_y = max(5, dim_y)
# Calcolo coordinate assolute centrate rispetto al terreno
start_x = int(min_x - min_x_t - centro_x)
start_z = int(min_z - min_z_t - centro_z)
start_y = int(min_y + START_Y)
edifici_scritti += 1
# Rendering dei soli nodi fisici perimetrali
for dx in range(larghezza_x):
for dz in range(lunghezza_z):
for dy in range(altezza_y):
abs_x = start_x + dx
abs_z = start_z + dz
abs_y = start_y + dy
is_muro = (dx == 0 or dx == larghezza_x - 1 or dz == 0 or dz == lunghezza_z - 1)
is_pavimento = (dy == 0)
is_tetto = (dy == altezza_y - 1)
if is_pavimento:
blocco = "default:wood"
elif is_tetto:
blocco = "default:brick"
elif is_muro:
blocco = "default:stone"
else:
# Salta l'aria interna! Risparmia lo spazio su disco
continue
f.write(f"{abs_x},{abs_y},{abs_z},{blocco}\n")
if (i + 1) % 100 == 0 or (i + 1) == len(edifici):
print(f"Progressione: {i + 1}/{len(edifici)} nodi mesh analizzati... ({edifici_scritti} edifici reali scritti)")
print(f"Fatto! File delle case salvato con successo in {file_output}. Scritti {edifici_scritti} edifici.")
# ==========================================
# PUNTO DI INGRESSO DELLO SCRIPT
# ==========================================
if __name__ == "__main__":
converti_case_streaming(FILE_OBJ_TERRENO, FILE_OBJ_CASE, NOME_FILE_USCITA)
</syntaxhighlight>
==== 8. Configurazione dell'Ambiente Virtuale Docker ====
Per ospitare l'infrastruttura di simulazione in modo isolato e replicabile, è stato configurato un container '''Docker''' gestito tramite '''Docker Compose'''. Sulla base di un file <code>docker-compose.yml</code> strutturato ad hoc, la cartella di lavoro del server Luanti/Minetest è stata mappata in locale sul PC dell'utente (tramite i Docker Volumes) per permettere la modifica in tempo reale dei file di gioco. All'interno della configurazione, il mondo è stato battezzato <code>ledro3d</code> e l'utente <code>mattruffoni</code> è stato designato come amministratore di sistema con massimi privilegi energetici.<syntaxhighlight lang="dockerfile">
services:
luanti_engine:
image: lscr.io/linuxserver/luanti:latest
container_name: local_luanti_engine
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Rome
# FORZATURA: Diciamo a Luanti esattamente quale file .conf leggere dentro il container
- CLI_ARGS=--worldname ledro3d --config /config/.minetest/minetest.conf --terminal
volumes:
- ./server_data:/config/.minetest
ports:
- 30000:30000/udp
restart: unless-stopped
</syntaxhighlight>
==== 9. Accessibilità del Server di Gioco ====
Una volta avviato lo stack di Docker tramite terminale (<code>docker compose up -d</code>), il container ha esposto i servizi di rete dedicati. Il server Luanti/Minetest è diventato operativo e raggiungibile in locale dall'indirizzo di loopback '''<code>localhost:30000</code>''', pronto ad accettare le connessioni da parte del client di gioco per l'esplorazione virtuale.
=== Fase 3: Sviluppo della Mod e Generazione del Mondo ===
====Creazione mod '''importatore'''====
Nella cartella ''.../minetest-server/server_data/worlds/ledro3d/worldmods/importatore'' si crea la mod importatore inserendoci il file init.lua, mod.conf e i due file di testo ledro_terreno_dati.txt e ledro_case_dati.txt creati in precedenza.
==== 10. Sviluppo della Mod Lua Asincrona "Importatore" ====
L'iniezione di milioni di nodi all'interno del database del mondo (<code>map.sqlite</code>) presenta forti criticità prestazionali (rischio di timeout UDP e crash per memoria satura). Per ovviare a questo problema, è stata sviluppata una mod personalizzata in linguaggio Lua denominata '''<code>importatore</code>'''. La mod implementa due soluzioni architetturali cruciali:
# '''Il VoxelManip Engine (LVM):''' Invece di posizionare un singolo cubo alla volta, la mod alloca grandi porzioni di mappa direttamente nella memoria volatile del server, scrive i blocchi di erba superficiale (<code>default:dirt_with_grass</code>) e le fondamenta sottostanti (<code>default:stone</code>), e forza la scrittura in blocco sul database, azzerando i warning di blocchi non trovati.
# '''Gestione tramite Co-routine Lua:''' La lettura dei file <code>.txt</code> è inserita in un ciclo asincrono controllato da co-routine. Tramite l'istruzione <code>coroutine.yield()</code>, la mod rilascia il controllo alla CPU del PC host ogni 100 nodi processati, permettendo al server di rimanere fluido, gestire i pacchetti di rete e consentire il movimento del giocatore durante la crescita progressiva della valle.
==== Fase 2: Iniezione Asincrona nella Mappa (Luanti Mod) ====
La mod Luanti (scritta in `init.lua`) riceve il file a griglia regolare e applica due strategie fondamentali per garantire stabilità e performance:
* '''Uso del VoxelManip (LVM):''' Invece di scrivere un blocco alla volta, la mod alloca un'area di memoria temporanea (`minetest.get_voxel_manip()`), manipola l'array dei nodi inserendo la superficie erbosa (`default:dirt_with_grass`) e lo zoccolo di roccia sottostante (`default:stone`), e infine forza la scrittura dell'intero blocco direttamente sul database (`vm:write_to_map()`). Questo bypassa i controlli dei metadati azzerando il warning ''Block not found''.
* '''Gestione Asincrona via Co-routine:''' Il ciclo di lettura del file viene inserito in una co-routine Lua (`coroutine.create`). Tramite l'istruzione `coroutine.yield()`, la mod rilascia il controllo alla CPU ogni 100 nodi processati, permettendo al server Luanti di gestire i pacchetti di rete, l'orario del mondo e il login dei giocatori senza lag.
==== Codice init.lua della mod importatore====
<syntaxhighlight lang="lua">
-- ========================================================
-- 1. PRIVILEGI AUTOMATICI PER MATTRUFFONI (CON SETTIME)
-- ========================================================
minetest.register_on_joinplayer(function(player)
local name = player:get_player_name()
if name == "mattruffoni" then
minetest.after(0.5, function()
local p = minetest.get_player_by_name(name)
if p then
local privs = minetest.get_player_privs(name)
privs.privs = true
privs.fly = true
privs.fast = true
privs.teleport = true
privs.interact = true
privs.shout = true
privs.settime = true -- Aggiunto privilegio per impostare l'ora
privs.time = true -- Aggiunto privilegio per gestire il tempo
minetest.set_player_privs(name, privs)
minetest.chat_send_player(name, "Benvenuto Prof! Privilegi completi (incluso settime) attivati.")
end
end)
end
end)
-- ========================================================
-- 2. PIPELINE DI IMPORTAZIONE A GRIGLIA ORDINATA (LVM)
-- ========================================================
local function avvia_importazione_superficie()
local percorso_terreno = minetest.get_modpath("importatore") .. "/ledro_terreno_dati.txt"
local percorso_case = minetest.get_modpath("importatore") .. "/ledro_case_dati.txt"
local thread = coroutine.create(function()
-- A. TERRENO (Morfologia a celle raccordate)
local file_t = io.open(percorso_terreno, "r")
if file_t then
minetest.log("action", "[Importatore] Scrittura griglia terreno georeferenziato...")
local count = 0
for line in file_t:lines() do
local x, y, z = line:match("([^,]+),([^,]+),([^,]+)")
if x and y and z then
local tx, ty, tz = tonumber(x), tonumber(y), tonumber(z)
-- Raggio 2 crea una piastra 5x5 attorno a ogni punto.
-- Avendo ordinato il file a passo 2, le piastre si fondono perfettamente.
local raggio = 2
-- Allochiamo l'area minima per il manipolatore di voxel
local p_min = {x = tx - raggio, y = ty - 15, z = tz - raggio}
local p_max = {x = tx + raggio, y = ty, z = tz + raggio}
local vm = minetest.get_voxel_manip()
local emin, emax = vm:read_from_map(p_min, p_max)
local data = vm:get_data()
local va = VoxelArea:new{MinEdge = emin, MaxEdge = emax}
local c_grass = minetest.get_content_id("default:dirt_with_grass")
local c_stone = minetest.get_content_id("default:stone")
-- Disegniamo la piastra locale
for dx = -raggio, raggio do
for dz = -raggio, raggio do
local px = tx + dx
local pz = tz + dz
-- Blocco d'erba superficiale
local vi_g = va:index(px, ty, pz)
data[vi_g] = c_grass
-- Zoccolo di pietra sottostante (15 blocchi per saldare i dislivelli)
for dy = 1, 15 do
local vi_s = va:index(px, ty - dy, pz)
data[vi_s] = c_stone
end
end
end
-- Scrittura forzata nel database senza controlli intermedi
vm:set_data(data)
vm:write_to_map()
count = count + 1
-- Rilasciamo la CPU ogni 100 punti della griglia per mantenere stabile il server
if count % 100 == 0 then
minetest.log("action", "[Importatore] Punti griglia terreno consolidati: " .. count)
coroutine.yield()
end
end
end
file_t:close()
end
-- B. CASE (Puntuali sopra il terreno)
local file_c = io.open(percorso_case, "r")
if file_c then
minetest.log("action", "[Importatore] Iniezione volumi edifici...")
local count = 0
for line in file_c:lines() do
local x, y, z, blockname = line:match("([^,]+),([^,]+),([^,]+),([^,]+)")
if x and y and z and blockname then
local pos = {x = tonumber(x), y = tonumber(y), z = tonumber(z)}
blockname = blockname:gsub("%s+", "")
local vm = minetest.get_voxel_manip()
vm:read_from_map(pos, pos)
minetest.set_node(pos, {name = blockname})
count = count + 1
if count % 2000 == 0 then
minetest.log("action", "[Importatore] Blocchi edificio inseriti: " .. count)
coroutine.yield()
end
end
end
file_c:close()
end
minetest.log("action", "[Importatore] PIPELINE COMPLETATA CON SUCCESSO!")
minetest.chat_send_all("[Importatore] PIPELINE COMPLETATA! La Val di Ledro a griglia è pronta.")
end)
local function esegui_passo()
if coroutine.status(thread) ~= "dead" then
coroutine.resume(thread)
minetest.after(0.02, esegui_passo)
end
end
esegui_passo()
end
-- ========================================================
-- 3. ATTIVAZIONE EVENTO AL LOGIN DI MATTRUFFONI
-- ========================================================
local attivato = false
minetest.register_on_joinplayer(function(player)
if player:get_player_name() == "mattruffoni" and not attivato then
attivato = true
minetest.after(3.0, function()
minetest.chat_send_all("[Importatore] Avvio rigenerazione morfologica a griglia fitta...")
avvia_importazione_superficie()
end)
end
end)
</syntaxhighlight>
=====Codice mod.conf=====
<syntaxhighlight lang="lua">
name = importatore
description = Importatore geometrico per la Val di Ledro
</syntaxhighlight>
=== Risultati e Sviluppi Pedagogici ===
L'applicazione di questo flusso permette di generare manti continui di milioni di blocchi mantenendo il server Docker estremamente leggero. Questo ambiente offre uno scenario di apprendimento eccezionale per la didattica laboratoriale (Matematica e Scienze), permettendo agli studenti di esplorare modelli in scala 1:1 del proprio territorio, comprendere l'interazione tra coordinate cartesiane e dati GIS, e interagire con elementi di programmazione e gestione server.
=== Note ===
Ovviamente tutto è stato sviluppato con AI, nello specifico Gemini.
=== Bibliografia ===
=== Collegamenti esterni ===
[[Categoria:Software libero a scuola|Luanti a scuola]]
2k06m5cik3ocea8byw6fq3ttcyj8xb0
501040
501039
2026-08-19T15:40:58Z
Mattruffoni
17392
/* 6. Esportazione della Mesh */
501040
wikitext
text/x-wiki
{{Software libero a scuola}}
Usare Luanti/Minetest per giocare a conoscere il territorio e, volendo, progettarne gli sviluppi futuri.
== Il Progetto: La scuola come laboratorio di pianificazione territoriale ==
Questo manuale nasce con l'obiettivo di guidare docenti e studenti nell'utilizzo di '''Luanti''' (precedentemente noto come ''Minetest'') come strumento didattico, integrando la tecnologia, la geografia (GIS), la matematica e l'educazione civica.
Il cuore del progetto si articola su tre pilastri fondamentali:
* '''Esplorare e Osservare (La Georeferenziazione):''' Creare un mondo digitale che sia il facsimile esatto del proprio territorio reale. Attraverso l'importazione di dati geografici e altimetrici reali, gli studenti possono muoversi in scala 1:1 in un ambiente virtuale familiare, imparando a leggere la morfologia della propria terra da una prospettiva inedita e immersiva.
* '''Progettare ed Eseguire (La Ricostruzione):''' Permettere agli studenti di ricostruire l'ambiente, i monumenti e i complessi urbani. Questo processo stimola lo sviluppo di competenze geometriche, di calcolo spaziale e di problem-solving strutturale, costringendo il ragazzo a passare dall'osservazione della realtà alla sua astrazione e successiva esecuzione tridimensionale a blocchi.
* '''Partecipare (La Cittadinanza Attiva):''' Dare ai ragazzi la possibilità di utilizzare il server condiviso come un laboratorio democratico per la pianificazione urbana e infrastrutturale collettiva. Gli studenti non si limitano a replicare il presente o il passato, ma possono proporre modifiche, nuove infrastrutture e varianti urbanistiche, imparando il valore del dibattito, della negoziazione e della progettazione comunitaria del bene comune.
Attraverso questo percorso, il mondo voxel di Luanti smette di essere un semplice videogioco e diventa un vero e proprio '''gemello digitale didattico''', un ponte tra la scuola e il territorio in grado di formare cittadini consapevoli e tecnicamente preparati.
== Il Valore del Software Libero e l'Accessibilità ==
L'adozione di software libero come Luanti elimina alla radice l'ostacolo delle licenze commerciali e dei costi per le scuole e le famiglie. Questa libertà tecnologica si traduce in una straordinaria agilità operativa: permette di configurare, personalizzare e pubblicare online un server scolastico in modo immediato. Per gli studenti, l'accesso a questo "gemello digitale" del territorio diventa sicuro e inclusivo: chiunque, da qualsiasi dispositivo a casa o a scuola, può connettersi liberamente e partecipare al progetto collettivo, con l'unico requisito di inserire il proprio nome utente e password personalizzati.
== Flusso di lavoro: Dati GIS, Modellazione 3D e Iniezione in Luanti ==
Questo capitolo documenta passo dopo passo la pipeline tecnologica utilizzata per trasformare i dati geografici e altimetrici reali della Val di Ledro in un mondo 3D interamente calpestabile all'interno del server Luanti (Minetest).
=== Fase 1: Acquisizione dei dati geografici e modellazione in Blender ===
==== 1. Selezione dell'Area di Interesse (OSM) ====
Il progetto ha inizio con la delimitazione della zona geografica. Utilizzando il software di modellazione 3D '''Blender''' combinato con l'add-on '''Blender-GIS''', è stato possibile connettersi direttamente ai server cartografici globali. Tramite l'interfaccia di georeferenziazione, è stato ritagliato il perimetro esatto della Val di Ledro attingendo alla cartografia vettoriale di '''OpenStreetMap (OSM)'''. Questa operazione fissa le coordinate di base (Latitudine/Longitudine) nel sistema di riferimento del progetto.
==== 2. Generazione del Rilievo Altimetrico (SRTM) ====
Una volta ottenuta la mappa bidimensionale, si è passati alla terza dimensione applicando i dati altimetrici reali. Sfruttando la funzione di importazione DEM (Digital Elevation Model) di Blender-GIS, sono stati scaricati i dati '''SRTM (Shuttle Radar Topography Mission)''' forniti dalla NASA. Il plugin ha proiettato questi dati vettoriali sulla mesh piana di Blender, deformandola e generando un modello tridimensionale fedele del rilievo montuoso e della morfologia della valle.
==== 3. Download dei Volumi degli Edifici ====
Per integrare l'elemento antropico, è stato effettuato un download mirato direttamente dal portale ufficiale [https://www.openstreetmap.org openstreetmap.org]. È stato esportato un file con estensione <code>.osm</code>, contenente tutti i metadati e le impronte planimetriche degli edifici (i "volumi" e i poligoni delle case) registrati all'interno della medesima area geografica della valle.
==== 4. Posizionamento e Georeferenziazione delle Case ====
Il file <code>.osm</code> grezzo è stato importato all'interno della scena di Blender, sempre tramite l'ausilio di Blender-GIS. Il plugin, riconoscendo la corrispondenza delle coordinate geografiche condivise, ha posizionato automaticamente e matematicamente i volumi geometrici degli edifici sopra il rilievo 3D precedentemente generato, incollando le fondamenta delle case alle rispettive quote del terreno. Nell'importazione viene scelta l'opzione ''buildings''.
==== 5. Importazione del lago ====
Nello stesso modo, e con lo stesso file .osm, usato per importare gli edifici scegliendo l'opzione ''water'' è stato importato il lago di Ledro. Sul lago si è docvuto applicare un ''modifier'' che ha aggiunto una triangolazione della superficie.
==== 6. Esportazione della Mesh ====
Una volta preparato il file in Blender si è proceduto all'esportazione del modello in un formato di interscambio testuale standard. Il file risultante è stato salvato con il nome di <code>LedroValleCompleta.obj</code>, contenente: l'elenco puro dei vertici tridimensionali del terreno, gli edifici in 3d e la superficie del lago.<br/>
Un altra informazione contenuta nei file .osm ad esempio è il nome delle vie e degli edifici, ed anche questo dato è interessante da importare nel mondo virtuale in mod da rendewre i luoghi più riconoscibili.
=== Fase 2: Parsing, Ottimizzazione e Struttura Server ===
=== Il problema tecnologico ===
I metodi tradizionali di scrittura dei nodi in Luanti via API standard (come `minetest.set_node`) mostrano forti limiti quando si gestiscono milioni di coordinate geometriche:
# '''Timeout UDP e Disconnessioni:''' L'elaborazione lineare di file massivi blocca il thread principale del server, causando il congelamento della rete e l'espulsione dei client.
# '''Errore Map::getNodeMetadata (Block not found):''' In ambienti a mappa vuota (es. mapgen `singlenode`), il server fallisce l'accesso ai metadati di blocchi non ancora inizializzati sul database del mondo (`map.sqlite`), generando migliaia di warning e fallendo la scrittura.
# '''Saturazione RAM in Blender:''' L'uso di modificatori come il ''Remesh'' su mesh territoriali molto estese (es. 20x12 km) satura la memoria volatile del sistema operativo, causando il crash del software di modellazione.
=== Architettura della Soluzione ===
La pipeline definitiva si divide in due fasi staccate: un'ottimizzazione matematica dei dati in locale tramite Python e un'iniezione asincrona a basso livello nel server Luanti tramite Lua.
==== Fase 1: Estrazione e Interpolazione dei Dati (Python) ====
Invece di sovraccaricare il motore di gioco o Blender, si utilizza uno script Python esterno sfruttando la libreria '''SciPy''' e l'algoritmo `NearestNDInterpolator` (o `LinearNDInterpolator`).
Lo script esegue le seguenti operazioni:
# Legge i vertici geometrici (`v X Y Z`) dal file `.obj` originale.
# Rileva i confini geografici assoluti della mappa.
# Inizializza un interpolatore spaziale e proietta i dati su una griglia fitta bidimensionale regolare (Heightmap) con un passo stabilito (es. ogni 2 metri).
# Tappa matematicamente i "buchi di cielo" presenti nella mesh rada, assegnando a ogni coordinata vuota l'altezza corretta calcolata sui punti vicini.
# Genera un file di testo ordinato (`ledro_terreno_dati.txt`) in formato `X,Y,Z`.
==== 7. Conversione e Densificazione dei Dati (Python e SciPy) ====
I file <code>.obj</code> nativi presentano una struttura a nuvola di punti (Point Cloud) rada e non ordinata. Con il supporto di '''Gemini''', sono stati sviluppati gli script Python per elaborare i dati:
* <code>estrai_griglia.py</code>: Questo script utilizza la libreria scientifica '''SciPy''' (in particolare l'algoritmo <code>NearestNDInterpolator</code>) per analizzare i 66.481 vertici originali distribuiti su un'area di circa 20x12 km. Python proietta questi punti su una griglia fitta bidimensionale regolare (Heightmap) con un passo costante (es. ogni 2 metri), interpolando matematicamente le altezze nei punti vuoti per "tappare i buchi di cielo" e generando un file coordinato e continuo chiamato <code>ledro_terreno_dati.txt</code> in formato <code>X,Y,Z</code>.<syntaxhighlight lang="python">
import os
import numpy as np
from scipy.interpolate import NearestNDInterpolator
FILE_OBJ = "LedroRilievo.obj"
FILE_OUTPUT = "ledro_terreno_dati.txt"
PASSO = 2 # Un punto ogni 2 metri
print("1. Lettura di tutti i vertici dal file OBJ...")
punti_validi = []
with open(FILE_OBJ, "r") as f:
for line in f:
if line.startswith("v "):
parti = line.split()
if len(parti) >= 4:
try:
punti_validi.append((float(parti[1]), float(parti[2]), float(parti[3])))
except ValueError:
continue
if not punti_validi:
print("ERRORE: Nessun vertice trovato nel file OBJ!")
exit()
# Coordinate separate
x_arr = np.array([p[0] for p in punti_validi])
y_arr = np.array([p[1] for p in punti_validi])
z_arr = np.array([p[2] for p in punti_validi])
min_x, max_x = int(np.min(x_arr)), int(np.max(x_arr))
min_z, max_z = int(np.min(z_arr)), int(np.max(z_arr))
print(f"Confini rilevati -> X: [{min_x} a {max_x}], Z: [{min_z} a {max_z}]")
print("2. Inizializzazione interpolatore geometrico (SciPy)...")
# Creiamo l'interpolatore basato sui punti noti dell'OBJ
interp = NearestNDInterpolator(list(zip(x_arr, z_arr)), y_arr)
print("3. Generazione griglia fitta continua e scrittura...")
# Generiamo gli intervalli regolari basati sul PASSO scelto
intervallo_x = np.arange(round(min_x / PASSO) * PASSO, round(max_x / PASSO) * PASSO + PASSO, PASSO)
intervallo_z = np.arange(round(min_z / PASSO) * PASSO, round(max_z / PASSO) * PASSO + PASSO, PASSO)
punti_totali_scritti = 0
with open(FILE_OUTPUT, "w") as out:
for gx in intervallo_x:
# Calcoliamo l'altezza per l'intera colonna Z in un colpo solo (velocissimo)
gz_array = np.array(list(intervallo_z))
gx_array = np.full_like(gz_array, gx)
# SciPy calcola le altezze interpolate istantaneamente per tutta la riga
altezze_interpolate = interp(gx_array, gz_array)
for i, gz in enumerate(intervallo_z):
gy = round(altezze_interpolate[i])
out.write(f"{gx},{gy},{gz}\n")
punti_totali_scritti += 1
print(f"Operazione completata! Generata griglia solida continua con {punti_totali_scritti} punti complessivi.")
</syntaxhighlight>
* <code>ledro_convertitore_case.py</code>: Estrae le posizioni degli edifici associandole ai rispettivi blocchi di costruzione, generando il file ordinato <code>ledro_case_dati.txt</code><syntaxhighlight lang="python">
import numpy as np
import trimesh
import os
from math import ceil
# ==========================================
# CONFIGURAZIONE COSTANTI
# ==========================================
FILE_OBJ_TERRENO = "LedroRilievo.obj"
FILE_OBJ_CASE = "LedroCase.obj"
NOME_FILE_USCITA = "ledro_case_dati.txt"
# Scala 1.0 per corrispondenza esatta con il terreno a passo 1 metro
FAUTORE_SCALA = 1.0
START_Y = 30
def converti_case_streaming(terreno_input, case_input, file_output):
if not os.path.exists(case_input) or not os.path.exists(terreno_input):
print("Errore: Uno dei file OBJ non esiste nella cartella attuale!")
return
# 1. Calcolo del centro del terreno per l'allineamento perfetto degli assi
print(f"Lettura terreno per allineamento assi: {terreno_input}...")
scena_t = trimesh.load(terreno_input, force='mesh')
mesh_t = trimesh.util.concatenate([g for g in scena_t.geometry.values()]) if isinstance(scena_t, trimesh.Scene) else scena_t
bounds_t = mesh_t.bounds
min_x_t, _, min_z_t = bounds_t[0]
max_x_t, _, max_z_t = bounds_t[1]
centro_x = int((max_x_t - min_x_t) / 2)
centro_z = int((max_z_t - min_z_t) / 2)
# 2. Caricamento e pulizia della mesh degli edifici
print(f"Caricamento edifici da {case_input}...")
scena_c = trimesh.load(case_input, force='mesh')
if isinstance(scena_c, trimesh.Scene):
mesh_unica_case = trimesh.util.concatenate([g for g in scena_c.geometry.values()])
else:
mesh_unica_case = scena_c
print("Pulizia della mesh e fusione dei vertici adiacenti...")
# Valida e salda insieme i poligoni staccati della stessa struttura
mesh_unica_case.process(validate=True)
print("Separazione degli edifici in componenti connesse...")
edifici_grezzi = mesh_unica_case.split(only_watertight=False)
# Filtriamo le bricioline geometriche inferiori a 2mq
edifici = [edf for edf in edifici_grezzi if edf.area > 2.0]
print(f"Trovati {len(edifici)} edifici reali stabili. Generazione geometrie cave...")
# Rimuoviamo il vecchio file se presente
if os.path.exists(file_output):
os.remove(file_output)
# 3. Ciclo di generazione geometrica delle case cave (SOLO SOLIDI)
edifici_scritti = 0
with open(file_output, "w") as f:
for i, edf in enumerate(edifici):
b = edf.bounds
min_x, min_y, min_z = b[0]
max_x, max_y, max_z = b[1]
dim_x = int(ceil(max_x - min_x))
dim_y = int(ceil(max_y - min_y))
dim_z = int(ceil(max_z - min_z))
# FILTRO DI SICUREZZA ANTI-LOOP (ARTEFATTI GIS):
# Se un "edificio" supera le dimensioni di un enorme isolato, è un errore di mesh dell'OBJ.
# Lo saltiamo per evitare che i cicli for successivi congelino la CPU.
if dim_x > 60 or dim_z > 60 or dim_y > 40:
continue
# APPLICAZIONE REGOLE PUNTO 4: Vincoli minimi (5x6x5)
larghezza_x = max(5, dim_x)
lunghezza_z = max(6, dim_z)
altezza_y = max(5, dim_y)
# Calcolo coordinate assolute centrate rispetto al terreno
start_x = int(min_x - min_x_t - centro_x)
start_z = int(min_z - min_z_t - centro_z)
start_y = int(min_y + START_Y)
edifici_scritti += 1
# Rendering dei soli nodi fisici perimetrali
for dx in range(larghezza_x):
for dz in range(lunghezza_z):
for dy in range(altezza_y):
abs_x = start_x + dx
abs_z = start_z + dz
abs_y = start_y + dy
is_muro = (dx == 0 or dx == larghezza_x - 1 or dz == 0 or dz == lunghezza_z - 1)
is_pavimento = (dy == 0)
is_tetto = (dy == altezza_y - 1)
if is_pavimento:
blocco = "default:wood"
elif is_tetto:
blocco = "default:brick"
elif is_muro:
blocco = "default:stone"
else:
# Salta l'aria interna! Risparmia lo spazio su disco
continue
f.write(f"{abs_x},{abs_y},{abs_z},{blocco}\n")
if (i + 1) % 100 == 0 or (i + 1) == len(edifici):
print(f"Progressione: {i + 1}/{len(edifici)} nodi mesh analizzati... ({edifici_scritti} edifici reali scritti)")
print(f"Fatto! File delle case salvato con successo in {file_output}. Scritti {edifici_scritti} edifici.")
# ==========================================
# PUNTO DI INGRESSO DELLO SCRIPT
# ==========================================
if __name__ == "__main__":
converti_case_streaming(FILE_OBJ_TERRENO, FILE_OBJ_CASE, NOME_FILE_USCITA)
</syntaxhighlight>
==== 8. Configurazione dell'Ambiente Virtuale Docker ====
Per ospitare l'infrastruttura di simulazione in modo isolato e replicabile, è stato configurato un container '''Docker''' gestito tramite '''Docker Compose'''. Sulla base di un file <code>docker-compose.yml</code> strutturato ad hoc, la cartella di lavoro del server Luanti/Minetest è stata mappata in locale sul PC dell'utente (tramite i Docker Volumes) per permettere la modifica in tempo reale dei file di gioco. All'interno della configurazione, il mondo è stato battezzato <code>ledro3d</code> e l'utente <code>mattruffoni</code> è stato designato come amministratore di sistema con massimi privilegi energetici.<syntaxhighlight lang="dockerfile">
services:
luanti_engine:
image: lscr.io/linuxserver/luanti:latest
container_name: local_luanti_engine
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Rome
# FORZATURA: Diciamo a Luanti esattamente quale file .conf leggere dentro il container
- CLI_ARGS=--worldname ledro3d --config /config/.minetest/minetest.conf --terminal
volumes:
- ./server_data:/config/.minetest
ports:
- 30000:30000/udp
restart: unless-stopped
</syntaxhighlight>
==== 9. Accessibilità del Server di Gioco ====
Una volta avviato lo stack di Docker tramite terminale (<code>docker compose up -d</code>), il container ha esposto i servizi di rete dedicati. Il server Luanti/Minetest è diventato operativo e raggiungibile in locale dall'indirizzo di loopback '''<code>localhost:30000</code>''', pronto ad accettare le connessioni da parte del client di gioco per l'esplorazione virtuale.
=== Fase 3: Sviluppo della Mod e Generazione del Mondo ===
====Creazione mod '''importatore'''====
Nella cartella ''.../minetest-server/server_data/worlds/ledro3d/worldmods/importatore'' si crea la mod importatore inserendoci il file init.lua, mod.conf e i due file di testo ledro_terreno_dati.txt e ledro_case_dati.txt creati in precedenza.
==== 10. Sviluppo della Mod Lua Asincrona "Importatore" ====
L'iniezione di milioni di nodi all'interno del database del mondo (<code>map.sqlite</code>) presenta forti criticità prestazionali (rischio di timeout UDP e crash per memoria satura). Per ovviare a questo problema, è stata sviluppata una mod personalizzata in linguaggio Lua denominata '''<code>importatore</code>'''. La mod implementa due soluzioni architetturali cruciali:
# '''Il VoxelManip Engine (LVM):''' Invece di posizionare un singolo cubo alla volta, la mod alloca grandi porzioni di mappa direttamente nella memoria volatile del server, scrive i blocchi di erba superficiale (<code>default:dirt_with_grass</code>) e le fondamenta sottostanti (<code>default:stone</code>), e forza la scrittura in blocco sul database, azzerando i warning di blocchi non trovati.
# '''Gestione tramite Co-routine Lua:''' La lettura dei file <code>.txt</code> è inserita in un ciclo asincrono controllato da co-routine. Tramite l'istruzione <code>coroutine.yield()</code>, la mod rilascia il controllo alla CPU del PC host ogni 100 nodi processati, permettendo al server di rimanere fluido, gestire i pacchetti di rete e consentire il movimento del giocatore durante la crescita progressiva della valle.
==== Fase 2: Iniezione Asincrona nella Mappa (Luanti Mod) ====
La mod Luanti (scritta in `init.lua`) riceve il file a griglia regolare e applica due strategie fondamentali per garantire stabilità e performance:
* '''Uso del VoxelManip (LVM):''' Invece di scrivere un blocco alla volta, la mod alloca un'area di memoria temporanea (`minetest.get_voxel_manip()`), manipola l'array dei nodi inserendo la superficie erbosa (`default:dirt_with_grass`) e lo zoccolo di roccia sottostante (`default:stone`), e infine forza la scrittura dell'intero blocco direttamente sul database (`vm:write_to_map()`). Questo bypassa i controlli dei metadati azzerando il warning ''Block not found''.
* '''Gestione Asincrona via Co-routine:''' Il ciclo di lettura del file viene inserito in una co-routine Lua (`coroutine.create`). Tramite l'istruzione `coroutine.yield()`, la mod rilascia il controllo alla CPU ogni 100 nodi processati, permettendo al server Luanti di gestire i pacchetti di rete, l'orario del mondo e il login dei giocatori senza lag.
==== Codice init.lua della mod importatore====
<syntaxhighlight lang="lua">
-- ========================================================
-- 1. PRIVILEGI AUTOMATICI PER MATTRUFFONI (CON SETTIME)
-- ========================================================
minetest.register_on_joinplayer(function(player)
local name = player:get_player_name()
if name == "mattruffoni" then
minetest.after(0.5, function()
local p = minetest.get_player_by_name(name)
if p then
local privs = minetest.get_player_privs(name)
privs.privs = true
privs.fly = true
privs.fast = true
privs.teleport = true
privs.interact = true
privs.shout = true
privs.settime = true -- Aggiunto privilegio per impostare l'ora
privs.time = true -- Aggiunto privilegio per gestire il tempo
minetest.set_player_privs(name, privs)
minetest.chat_send_player(name, "Benvenuto Prof! Privilegi completi (incluso settime) attivati.")
end
end)
end
end)
-- ========================================================
-- 2. PIPELINE DI IMPORTAZIONE A GRIGLIA ORDINATA (LVM)
-- ========================================================
local function avvia_importazione_superficie()
local percorso_terreno = minetest.get_modpath("importatore") .. "/ledro_terreno_dati.txt"
local percorso_case = minetest.get_modpath("importatore") .. "/ledro_case_dati.txt"
local thread = coroutine.create(function()
-- A. TERRENO (Morfologia a celle raccordate)
local file_t = io.open(percorso_terreno, "r")
if file_t then
minetest.log("action", "[Importatore] Scrittura griglia terreno georeferenziato...")
local count = 0
for line in file_t:lines() do
local x, y, z = line:match("([^,]+),([^,]+),([^,]+)")
if x and y and z then
local tx, ty, tz = tonumber(x), tonumber(y), tonumber(z)
-- Raggio 2 crea una piastra 5x5 attorno a ogni punto.
-- Avendo ordinato il file a passo 2, le piastre si fondono perfettamente.
local raggio = 2
-- Allochiamo l'area minima per il manipolatore di voxel
local p_min = {x = tx - raggio, y = ty - 15, z = tz - raggio}
local p_max = {x = tx + raggio, y = ty, z = tz + raggio}
local vm = minetest.get_voxel_manip()
local emin, emax = vm:read_from_map(p_min, p_max)
local data = vm:get_data()
local va = VoxelArea:new{MinEdge = emin, MaxEdge = emax}
local c_grass = minetest.get_content_id("default:dirt_with_grass")
local c_stone = minetest.get_content_id("default:stone")
-- Disegniamo la piastra locale
for dx = -raggio, raggio do
for dz = -raggio, raggio do
local px = tx + dx
local pz = tz + dz
-- Blocco d'erba superficiale
local vi_g = va:index(px, ty, pz)
data[vi_g] = c_grass
-- Zoccolo di pietra sottostante (15 blocchi per saldare i dislivelli)
for dy = 1, 15 do
local vi_s = va:index(px, ty - dy, pz)
data[vi_s] = c_stone
end
end
end
-- Scrittura forzata nel database senza controlli intermedi
vm:set_data(data)
vm:write_to_map()
count = count + 1
-- Rilasciamo la CPU ogni 100 punti della griglia per mantenere stabile il server
if count % 100 == 0 then
minetest.log("action", "[Importatore] Punti griglia terreno consolidati: " .. count)
coroutine.yield()
end
end
end
file_t:close()
end
-- B. CASE (Puntuali sopra il terreno)
local file_c = io.open(percorso_case, "r")
if file_c then
minetest.log("action", "[Importatore] Iniezione volumi edifici...")
local count = 0
for line in file_c:lines() do
local x, y, z, blockname = line:match("([^,]+),([^,]+),([^,]+),([^,]+)")
if x and y and z and blockname then
local pos = {x = tonumber(x), y = tonumber(y), z = tonumber(z)}
blockname = blockname:gsub("%s+", "")
local vm = minetest.get_voxel_manip()
vm:read_from_map(pos, pos)
minetest.set_node(pos, {name = blockname})
count = count + 1
if count % 2000 == 0 then
minetest.log("action", "[Importatore] Blocchi edificio inseriti: " .. count)
coroutine.yield()
end
end
end
file_c:close()
end
minetest.log("action", "[Importatore] PIPELINE COMPLETATA CON SUCCESSO!")
minetest.chat_send_all("[Importatore] PIPELINE COMPLETATA! La Val di Ledro a griglia è pronta.")
end)
local function esegui_passo()
if coroutine.status(thread) ~= "dead" then
coroutine.resume(thread)
minetest.after(0.02, esegui_passo)
end
end
esegui_passo()
end
-- ========================================================
-- 3. ATTIVAZIONE EVENTO AL LOGIN DI MATTRUFFONI
-- ========================================================
local attivato = false
minetest.register_on_joinplayer(function(player)
if player:get_player_name() == "mattruffoni" and not attivato then
attivato = true
minetest.after(3.0, function()
minetest.chat_send_all("[Importatore] Avvio rigenerazione morfologica a griglia fitta...")
avvia_importazione_superficie()
end)
end
end)
</syntaxhighlight>
=====Codice mod.conf=====
<syntaxhighlight lang="lua">
name = importatore
description = Importatore geometrico per la Val di Ledro
</syntaxhighlight>
=== Risultati e Sviluppi Pedagogici ===
L'applicazione di questo flusso permette di generare manti continui di milioni di blocchi mantenendo il server Docker estremamente leggero. Questo ambiente offre uno scenario di apprendimento eccezionale per la didattica laboratoriale (Matematica e Scienze), permettendo agli studenti di esplorare modelli in scala 1:1 del proprio territorio, comprendere l'interazione tra coordinate cartesiane e dati GIS, e interagire con elementi di programmazione e gestione server.
=== Note ===
Ovviamente tutto è stato sviluppato con AI, nello specifico Gemini.
=== Bibliografia ===
=== Collegamenti esterni ===
[[Categoria:Software libero a scuola|Luanti a scuola]]
ip4yswwq2bi7236juwantv06cjcrksz
501061
501040
2026-08-20T08:23:38Z
Mattruffoni
17392
incipit generalizzato
501061
wikitext
text/x-wiki
{{Software libero a scuola}}
'''''[https://www.luanti.org/it/ Luanti] a scuola''''' è una guida pratica rivolta a docenti, educatori e studenti interessati a integrare la didattica laboratoriale e il ''game-based learning'' nei percorsi scolastici attraverso ambienti virtuali 3D.
== Introduzione ==
L'impiego didattico dei mondi a blocchi (*voxel*) vanta un'esperienza consolidata: la videoludica e la formazione convergono da oltre 15 anni nell'istruzione, con [[Minecraft]] promosso in numerosi contesti educativi ed editori di rilievo (come evidenziato nel testo ''A scuola con Minecraft'' di Andrea Benassi, Giunti Scuola, 2021).
Tuttavia, l'adozione di software proprietari all'interno delle istituzioni scolastiche può comportare costi di licenza e vincoli tecnici. In questo scenario si inserisce **Luanti** (storicamente noto come **Minetest**), una piattaforma open source, gratuita, flessibile e altamente scalabile.
== Perché Luanti nella didattica ==
Luanti offre una vasta libreria di mod e contenuti personalizzabili che ne estendono le funzionalità pedagogiche:
* **Circuiti elettrici e logica digitale:** attraverso la simulazione di componenti come relè e porte logiche per comprendere la modellazione di sistemi hardware.
* **Coding e robotica:** mediante l'uso di bot e tartarughe programmabili visualmente o tramite script.
* **Attività multidisciplinari:** dalla ricostruzione storica di monumenti all'esplorazione di strutture molecolari e geografiche.
L'efficacia dell'approccio basato sulla costruzione immersiva trova conferma sul campo: da oltre quattro anni l'utilizzo continuativo di Minetest/Luanti in classe dimostra come il *building* collaborativo favorisca l'acquisizione di competenze trasversali, logico-matematiche e digitali (si veda l'esperienza del progetto [https://www.didasharing.it Didasharing.it]).
== Server della community ed esperienze multiplayer ==
Oltre alle attività in locale o in rete d'istituto, il panorama open source offre significativi esempi di ambienti di rete e server multiplayer:
=== A.E.S. (Alternative Entertainment Server) ===
Sviluppato da Zughy e collaboratori, **A.E.S.** rappresenta uno dei più noti hub di minigiochi multiplayer della community di Luanti. Sfruttando l'architettura dinamica e la leggerezza del motore di gioco C++ (con librerie come `arena_lib`), la piattaforma offre varie modalità interattive (tra cui *Block League*, *Skywars*, *Quikbild* e *ColourJump*). Tali arene mostrano come le logiche competitive e lo sviluppo di mod personalizzate possano essere applicati al gioco di squadra e al problem solving.
=== Framatest e il progetto Libreverse ===
In ambito internazionale ed educativo, un punto di riferimento storico è stato **Framatest**, il server pubblico ospitato dal network francese [[Framasoft]] per promuovere l'uso di Minetest nella scuola e nella società civile. Oggi quella stessa eredità e lo spirito di condivisione proseguono grazie all'infrastruttura di Chalec, il cui server è raggiungibile e ospitato su [https://www.chalec.org/services/libreverse/ Libreverse].
Usare Luanti/Minetest per giocare a conoscere il territorio e, volendo, progettarne gli sviluppi futuri.
== Il Progetto: La scuola come laboratorio di pianificazione territoriale ==
Questo manuale nasce con l'obiettivo di guidare docenti e studenti nell'utilizzo di '''Luanti''' (precedentemente noto come ''Minetest'') come strumento didattico, integrando la tecnologia, la geografia (GIS), la matematica e l'educazione civica.
Il cuore del progetto si articola su tre pilastri fondamentali:
* '''Esplorare e Osservare (La Georeferenziazione):''' Creare un mondo digitale che sia il facsimile esatto del proprio territorio reale. Attraverso l'importazione di dati geografici e altimetrici reali, gli studenti possono muoversi in scala 1:1 in un ambiente virtuale familiare, imparando a leggere la morfologia della propria terra da una prospettiva inedita e immersiva.
* '''Progettare ed Eseguire (La Ricostruzione):''' Permettere agli studenti di ricostruire l'ambiente, i monumenti e i complessi urbani. Questo processo stimola lo sviluppo di competenze geometriche, di calcolo spaziale e di problem-solving strutturale, costringendo il ragazzo a passare dall'osservazione della realtà alla sua astrazione e successiva esecuzione tridimensionale a blocchi.
* '''Partecipare (La Cittadinanza Attiva):''' Dare ai ragazzi la possibilità di utilizzare il server condiviso come un laboratorio democratico per la pianificazione urbana e infrastrutturale collettiva. Gli studenti non si limitano a replicare il presente o il passato, ma possono proporre modifiche, nuove infrastrutture e varianti urbanistiche, imparando il valore del dibattito, della negoziazione e della progettazione comunitaria del bene comune.
Attraverso questo percorso, il mondo voxel di Luanti smette di essere un semplice videogioco e diventa un vero e proprio '''gemello digitale didattico''', un ponte tra la scuola e il territorio in grado di formare cittadini consapevoli e tecnicamente preparati.
== Il Valore del Software Libero e l'Accessibilità ==
L'adozione di software libero come Luanti elimina alla radice l'ostacolo delle licenze commerciali e dei costi per le scuole e le famiglie. Questa libertà tecnologica si traduce in una straordinaria agilità operativa: permette di configurare, personalizzare e pubblicare online un server scolastico in modo immediato. Per gli studenti, l'accesso a questo "gemello digitale" del territorio diventa sicuro e inclusivo: chiunque, da qualsiasi dispositivo a casa o a scuola, può connettersi liberamente e partecipare al progetto collettivo, con l'unico requisito di inserire il proprio nome utente e password personalizzati.
== Flusso di lavoro: Dati GIS, Modellazione 3D e Iniezione in Luanti ==
Questo capitolo documenta passo dopo passo la pipeline tecnologica utilizzata per trasformare i dati geografici e altimetrici reali della Val di Ledro in un mondo 3D interamente calpestabile all'interno del server Luanti (Minetest).
=== Fase 1: Acquisizione dei dati geografici e modellazione in Blender ===
==== 1. Selezione dell'Area di Interesse (OSM) ====
Il progetto ha inizio con la delimitazione della zona geografica. Utilizzando il software di modellazione 3D '''Blender''' combinato con l'add-on '''Blender-GIS''', è stato possibile connettersi direttamente ai server cartografici globali. Tramite l'interfaccia di georeferenziazione, è stato ritagliato il perimetro esatto della Val di Ledro attingendo alla cartografia vettoriale di '''OpenStreetMap (OSM)'''. Questa operazione fissa le coordinate di base (Latitudine/Longitudine) nel sistema di riferimento del progetto.
==== 2. Generazione del Rilievo Altimetrico (SRTM) ====
Una volta ottenuta la mappa bidimensionale, si è passati alla terza dimensione applicando i dati altimetrici reali. Sfruttando la funzione di importazione DEM (Digital Elevation Model) di Blender-GIS, sono stati scaricati i dati '''SRTM (Shuttle Radar Topography Mission)''' forniti dalla NASA. Il plugin ha proiettato questi dati vettoriali sulla mesh piana di Blender, deformandola e generando un modello tridimensionale fedele del rilievo montuoso e della morfologia della valle.
==== 3. Download dei Volumi degli Edifici ====
Per integrare l'elemento antropico, è stato effettuato un download mirato direttamente dal portale ufficiale [https://www.openstreetmap.org openstreetmap.org]. È stato esportato un file con estensione <code>.osm</code>, contenente tutti i metadati e le impronte planimetriche degli edifici (i "volumi" e i poligoni delle case) registrati all'interno della medesima area geografica della valle.
==== 4. Posizionamento e Georeferenziazione delle Case ====
Il file <code>.osm</code> grezzo è stato importato all'interno della scena di Blender, sempre tramite l'ausilio di Blender-GIS. Il plugin, riconoscendo la corrispondenza delle coordinate geografiche condivise, ha posizionato automaticamente e matematicamente i volumi geometrici degli edifici sopra il rilievo 3D precedentemente generato, incollando le fondamenta delle case alle rispettive quote del terreno. Nell'importazione viene scelta l'opzione ''buildings''.
==== 5. Importazione del lago ====
Nello stesso modo, e con lo stesso file .osm, usato per importare gli edifici scegliendo l'opzione ''water'' è stato importato il lago di Ledro. Sul lago si è docvuto applicare un ''modifier'' che ha aggiunto una triangolazione della superficie.
==== 6. Esportazione della Mesh ====
Una volta preparato il file in Blender si è proceduto all'esportazione del modello in un formato di interscambio testuale standard. Il file risultante è stato salvato con il nome di <code>LedroValleCompleta.obj</code>, contenente: l'elenco puro dei vertici tridimensionali del terreno, gli edifici in 3d e la superficie del lago.<br/>
Un altra informazione contenuta nei file .osm ad esempio è il nome delle vie e degli edifici, ed anche questo dato è interessante da importare nel mondo virtuale in mod da rendewre i luoghi più riconoscibili.
=== Fase 2: Parsing, Ottimizzazione e Struttura Server ===
=== Il problema tecnologico ===
I metodi tradizionali di scrittura dei nodi in Luanti via API standard (come `minetest.set_node`) mostrano forti limiti quando si gestiscono milioni di coordinate geometriche:
# '''Timeout UDP e Disconnessioni:''' L'elaborazione lineare di file massivi blocca il thread principale del server, causando il congelamento della rete e l'espulsione dei client.
# '''Errore Map::getNodeMetadata (Block not found):''' In ambienti a mappa vuota (es. mapgen `singlenode`), il server fallisce l'accesso ai metadati di blocchi non ancora inizializzati sul database del mondo (`map.sqlite`), generando migliaia di warning e fallendo la scrittura.
# '''Saturazione RAM in Blender:''' L'uso di modificatori come il ''Remesh'' su mesh territoriali molto estese (es. 20x12 km) satura la memoria volatile del sistema operativo, causando il crash del software di modellazione.
=== Architettura della Soluzione ===
La pipeline definitiva si divide in due fasi staccate: un'ottimizzazione matematica dei dati in locale tramite Python e un'iniezione asincrona a basso livello nel server Luanti tramite Lua.
==== Fase 1: Estrazione e Interpolazione dei Dati (Python) ====
Invece di sovraccaricare il motore di gioco o Blender, si utilizza uno script Python esterno sfruttando la libreria '''SciPy''' e l'algoritmo `NearestNDInterpolator` (o `LinearNDInterpolator`).
Lo script esegue le seguenti operazioni:
# Legge i vertici geometrici (`v X Y Z`) dal file `.obj` originale.
# Rileva i confini geografici assoluti della mappa.
# Inizializza un interpolatore spaziale e proietta i dati su una griglia fitta bidimensionale regolare (Heightmap) con un passo stabilito (es. ogni 2 metri).
# Tappa matematicamente i "buchi di cielo" presenti nella mesh rada, assegnando a ogni coordinata vuota l'altezza corretta calcolata sui punti vicini.
# Genera un file di testo ordinato (`ledro_terreno_dati.txt`) in formato `X,Y,Z`.
==== 7. Conversione e Densificazione dei Dati (Python e SciPy) ====
I file <code>.obj</code> nativi presentano una struttura a nuvola di punti (Point Cloud) rada e non ordinata. Con il supporto di '''Gemini''', sono stati sviluppati gli script Python per elaborare i dati:
* <code>estrai_griglia.py</code>: Questo script utilizza la libreria scientifica '''SciPy''' (in particolare l'algoritmo <code>NearestNDInterpolator</code>) per analizzare i 66.481 vertici originali distribuiti su un'area di circa 20x12 km. Python proietta questi punti su una griglia fitta bidimensionale regolare (Heightmap) con un passo costante (es. ogni 2 metri), interpolando matematicamente le altezze nei punti vuoti per "tappare i buchi di cielo" e generando un file coordinato e continuo chiamato <code>ledro_terreno_dati.txt</code> in formato <code>X,Y,Z</code>.<syntaxhighlight lang="python">
import os
import numpy as np
from scipy.interpolate import NearestNDInterpolator
FILE_OBJ = "LedroRilievo.obj"
FILE_OUTPUT = "ledro_terreno_dati.txt"
PASSO = 2 # Un punto ogni 2 metri
print("1. Lettura di tutti i vertici dal file OBJ...")
punti_validi = []
with open(FILE_OBJ, "r") as f:
for line in f:
if line.startswith("v "):
parti = line.split()
if len(parti) >= 4:
try:
punti_validi.append((float(parti[1]), float(parti[2]), float(parti[3])))
except ValueError:
continue
if not punti_validi:
print("ERRORE: Nessun vertice trovato nel file OBJ!")
exit()
# Coordinate separate
x_arr = np.array([p[0] for p in punti_validi])
y_arr = np.array([p[1] for p in punti_validi])
z_arr = np.array([p[2] for p in punti_validi])
min_x, max_x = int(np.min(x_arr)), int(np.max(x_arr))
min_z, max_z = int(np.min(z_arr)), int(np.max(z_arr))
print(f"Confini rilevati -> X: [{min_x} a {max_x}], Z: [{min_z} a {max_z}]")
print("2. Inizializzazione interpolatore geometrico (SciPy)...")
# Creiamo l'interpolatore basato sui punti noti dell'OBJ
interp = NearestNDInterpolator(list(zip(x_arr, z_arr)), y_arr)
print("3. Generazione griglia fitta continua e scrittura...")
# Generiamo gli intervalli regolari basati sul PASSO scelto
intervallo_x = np.arange(round(min_x / PASSO) * PASSO, round(max_x / PASSO) * PASSO + PASSO, PASSO)
intervallo_z = np.arange(round(min_z / PASSO) * PASSO, round(max_z / PASSO) * PASSO + PASSO, PASSO)
punti_totali_scritti = 0
with open(FILE_OUTPUT, "w") as out:
for gx in intervallo_x:
# Calcoliamo l'altezza per l'intera colonna Z in un colpo solo (velocissimo)
gz_array = np.array(list(intervallo_z))
gx_array = np.full_like(gz_array, gx)
# SciPy calcola le altezze interpolate istantaneamente per tutta la riga
altezze_interpolate = interp(gx_array, gz_array)
for i, gz in enumerate(intervallo_z):
gy = round(altezze_interpolate[i])
out.write(f"{gx},{gy},{gz}\n")
punti_totali_scritti += 1
print(f"Operazione completata! Generata griglia solida continua con {punti_totali_scritti} punti complessivi.")
</syntaxhighlight>
* <code>ledro_convertitore_case.py</code>: Estrae le posizioni degli edifici associandole ai rispettivi blocchi di costruzione, generando il file ordinato <code>ledro_case_dati.txt</code><syntaxhighlight lang="python">
import numpy as np
import trimesh
import os
from math import ceil
# ==========================================
# CONFIGURAZIONE COSTANTI
# ==========================================
FILE_OBJ_TERRENO = "LedroRilievo.obj"
FILE_OBJ_CASE = "LedroCase.obj"
NOME_FILE_USCITA = "ledro_case_dati.txt"
# Scala 1.0 per corrispondenza esatta con il terreno a passo 1 metro
FAUTORE_SCALA = 1.0
START_Y = 30
def converti_case_streaming(terreno_input, case_input, file_output):
if not os.path.exists(case_input) or not os.path.exists(terreno_input):
print("Errore: Uno dei file OBJ non esiste nella cartella attuale!")
return
# 1. Calcolo del centro del terreno per l'allineamento perfetto degli assi
print(f"Lettura terreno per allineamento assi: {terreno_input}...")
scena_t = trimesh.load(terreno_input, force='mesh')
mesh_t = trimesh.util.concatenate([g for g in scena_t.geometry.values()]) if isinstance(scena_t, trimesh.Scene) else scena_t
bounds_t = mesh_t.bounds
min_x_t, _, min_z_t = bounds_t[0]
max_x_t, _, max_z_t = bounds_t[1]
centro_x = int((max_x_t - min_x_t) / 2)
centro_z = int((max_z_t - min_z_t) / 2)
# 2. Caricamento e pulizia della mesh degli edifici
print(f"Caricamento edifici da {case_input}...")
scena_c = trimesh.load(case_input, force='mesh')
if isinstance(scena_c, trimesh.Scene):
mesh_unica_case = trimesh.util.concatenate([g for g in scena_c.geometry.values()])
else:
mesh_unica_case = scena_c
print("Pulizia della mesh e fusione dei vertici adiacenti...")
# Valida e salda insieme i poligoni staccati della stessa struttura
mesh_unica_case.process(validate=True)
print("Separazione degli edifici in componenti connesse...")
edifici_grezzi = mesh_unica_case.split(only_watertight=False)
# Filtriamo le bricioline geometriche inferiori a 2mq
edifici = [edf for edf in edifici_grezzi if edf.area > 2.0]
print(f"Trovati {len(edifici)} edifici reali stabili. Generazione geometrie cave...")
# Rimuoviamo il vecchio file se presente
if os.path.exists(file_output):
os.remove(file_output)
# 3. Ciclo di generazione geometrica delle case cave (SOLO SOLIDI)
edifici_scritti = 0
with open(file_output, "w") as f:
for i, edf in enumerate(edifici):
b = edf.bounds
min_x, min_y, min_z = b[0]
max_x, max_y, max_z = b[1]
dim_x = int(ceil(max_x - min_x))
dim_y = int(ceil(max_y - min_y))
dim_z = int(ceil(max_z - min_z))
# FILTRO DI SICUREZZA ANTI-LOOP (ARTEFATTI GIS):
# Se un "edificio" supera le dimensioni di un enorme isolato, è un errore di mesh dell'OBJ.
# Lo saltiamo per evitare che i cicli for successivi congelino la CPU.
if dim_x > 60 or dim_z > 60 or dim_y > 40:
continue
# APPLICAZIONE REGOLE PUNTO 4: Vincoli minimi (5x6x5)
larghezza_x = max(5, dim_x)
lunghezza_z = max(6, dim_z)
altezza_y = max(5, dim_y)
# Calcolo coordinate assolute centrate rispetto al terreno
start_x = int(min_x - min_x_t - centro_x)
start_z = int(min_z - min_z_t - centro_z)
start_y = int(min_y + START_Y)
edifici_scritti += 1
# Rendering dei soli nodi fisici perimetrali
for dx in range(larghezza_x):
for dz in range(lunghezza_z):
for dy in range(altezza_y):
abs_x = start_x + dx
abs_z = start_z + dz
abs_y = start_y + dy
is_muro = (dx == 0 or dx == larghezza_x - 1 or dz == 0 or dz == lunghezza_z - 1)
is_pavimento = (dy == 0)
is_tetto = (dy == altezza_y - 1)
if is_pavimento:
blocco = "default:wood"
elif is_tetto:
blocco = "default:brick"
elif is_muro:
blocco = "default:stone"
else:
# Salta l'aria interna! Risparmia lo spazio su disco
continue
f.write(f"{abs_x},{abs_y},{abs_z},{blocco}\n")
if (i + 1) % 100 == 0 or (i + 1) == len(edifici):
print(f"Progressione: {i + 1}/{len(edifici)} nodi mesh analizzati... ({edifici_scritti} edifici reali scritti)")
print(f"Fatto! File delle case salvato con successo in {file_output}. Scritti {edifici_scritti} edifici.")
# ==========================================
# PUNTO DI INGRESSO DELLO SCRIPT
# ==========================================
if __name__ == "__main__":
converti_case_streaming(FILE_OBJ_TERRENO, FILE_OBJ_CASE, NOME_FILE_USCITA)
</syntaxhighlight>
==== 8. Configurazione dell'Ambiente Virtuale Docker ====
Per ospitare l'infrastruttura di simulazione in modo isolato e replicabile, è stato configurato un container '''Docker''' gestito tramite '''Docker Compose'''. Sulla base di un file <code>docker-compose.yml</code> strutturato ad hoc, la cartella di lavoro del server Luanti/Minetest è stata mappata in locale sul PC dell'utente (tramite i Docker Volumes) per permettere la modifica in tempo reale dei file di gioco. All'interno della configurazione, il mondo è stato battezzato <code>ledro3d</code> e l'utente <code>mattruffoni</code> è stato designato come amministratore di sistema con massimi privilegi energetici.<syntaxhighlight lang="dockerfile">
services:
luanti_engine:
image: lscr.io/linuxserver/luanti:latest
container_name: local_luanti_engine
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Rome
# FORZATURA: Diciamo a Luanti esattamente quale file .conf leggere dentro il container
- CLI_ARGS=--worldname ledro3d --config /config/.minetest/minetest.conf --terminal
volumes:
- ./server_data:/config/.minetest
ports:
- 30000:30000/udp
restart: unless-stopped
</syntaxhighlight>
==== 9. Accessibilità del Server di Gioco ====
Una volta avviato lo stack di Docker tramite terminale (<code>docker compose up -d</code>), il container ha esposto i servizi di rete dedicati. Il server Luanti/Minetest è diventato operativo e raggiungibile in locale dall'indirizzo di loopback '''<code>localhost:30000</code>''', pronto ad accettare le connessioni da parte del client di gioco per l'esplorazione virtuale.
=== Fase 3: Sviluppo della Mod e Generazione del Mondo ===
====Creazione mod '''importatore'''====
Nella cartella ''.../minetest-server/server_data/worlds/ledro3d/worldmods/importatore'' si crea la mod importatore inserendoci il file init.lua, mod.conf e i due file di testo ledro_terreno_dati.txt e ledro_case_dati.txt creati in precedenza.
==== 10. Sviluppo della Mod Lua Asincrona "Importatore" ====
L'iniezione di milioni di nodi all'interno del database del mondo (<code>map.sqlite</code>) presenta forti criticità prestazionali (rischio di timeout UDP e crash per memoria satura). Per ovviare a questo problema, è stata sviluppata una mod personalizzata in linguaggio Lua denominata '''<code>importatore</code>'''. La mod implementa due soluzioni architetturali cruciali:
# '''Il VoxelManip Engine (LVM):''' Invece di posizionare un singolo cubo alla volta, la mod alloca grandi porzioni di mappa direttamente nella memoria volatile del server, scrive i blocchi di erba superficiale (<code>default:dirt_with_grass</code>) e le fondamenta sottostanti (<code>default:stone</code>), e forza la scrittura in blocco sul database, azzerando i warning di blocchi non trovati.
# '''Gestione tramite Co-routine Lua:''' La lettura dei file <code>.txt</code> è inserita in un ciclo asincrono controllato da co-routine. Tramite l'istruzione <code>coroutine.yield()</code>, la mod rilascia il controllo alla CPU del PC host ogni 100 nodi processati, permettendo al server di rimanere fluido, gestire i pacchetti di rete e consentire il movimento del giocatore durante la crescita progressiva della valle.
==== Fase 2: Iniezione Asincrona nella Mappa (Luanti Mod) ====
La mod Luanti (scritta in `init.lua`) riceve il file a griglia regolare e applica due strategie fondamentali per garantire stabilità e performance:
* '''Uso del VoxelManip (LVM):''' Invece di scrivere un blocco alla volta, la mod alloca un'area di memoria temporanea (`minetest.get_voxel_manip()`), manipola l'array dei nodi inserendo la superficie erbosa (`default:dirt_with_grass`) e lo zoccolo di roccia sottostante (`default:stone`), e infine forza la scrittura dell'intero blocco direttamente sul database (`vm:write_to_map()`). Questo bypassa i controlli dei metadati azzerando il warning ''Block not found''.
* '''Gestione Asincrona via Co-routine:''' Il ciclo di lettura del file viene inserito in una co-routine Lua (`coroutine.create`). Tramite l'istruzione `coroutine.yield()`, la mod rilascia il controllo alla CPU ogni 100 nodi processati, permettendo al server Luanti di gestire i pacchetti di rete, l'orario del mondo e il login dei giocatori senza lag.
==== Codice init.lua della mod importatore====
<syntaxhighlight lang="lua">
-- ========================================================
-- 1. PRIVILEGI AUTOMATICI PER MATTRUFFONI (CON SETTIME)
-- ========================================================
minetest.register_on_joinplayer(function(player)
local name = player:get_player_name()
if name == "mattruffoni" then
minetest.after(0.5, function()
local p = minetest.get_player_by_name(name)
if p then
local privs = minetest.get_player_privs(name)
privs.privs = true
privs.fly = true
privs.fast = true
privs.teleport = true
privs.interact = true
privs.shout = true
privs.settime = true -- Aggiunto privilegio per impostare l'ora
privs.time = true -- Aggiunto privilegio per gestire il tempo
minetest.set_player_privs(name, privs)
minetest.chat_send_player(name, "Benvenuto Prof! Privilegi completi (incluso settime) attivati.")
end
end)
end
end)
-- ========================================================
-- 2. PIPELINE DI IMPORTAZIONE A GRIGLIA ORDINATA (LVM)
-- ========================================================
local function avvia_importazione_superficie()
local percorso_terreno = minetest.get_modpath("importatore") .. "/ledro_terreno_dati.txt"
local percorso_case = minetest.get_modpath("importatore") .. "/ledro_case_dati.txt"
local thread = coroutine.create(function()
-- A. TERRENO (Morfologia a celle raccordate)
local file_t = io.open(percorso_terreno, "r")
if file_t then
minetest.log("action", "[Importatore] Scrittura griglia terreno georeferenziato...")
local count = 0
for line in file_t:lines() do
local x, y, z = line:match("([^,]+),([^,]+),([^,]+)")
if x and y and z then
local tx, ty, tz = tonumber(x), tonumber(y), tonumber(z)
-- Raggio 2 crea una piastra 5x5 attorno a ogni punto.
-- Avendo ordinato il file a passo 2, le piastre si fondono perfettamente.
local raggio = 2
-- Allochiamo l'area minima per il manipolatore di voxel
local p_min = {x = tx - raggio, y = ty - 15, z = tz - raggio}
local p_max = {x = tx + raggio, y = ty, z = tz + raggio}
local vm = minetest.get_voxel_manip()
local emin, emax = vm:read_from_map(p_min, p_max)
local data = vm:get_data()
local va = VoxelArea:new{MinEdge = emin, MaxEdge = emax}
local c_grass = minetest.get_content_id("default:dirt_with_grass")
local c_stone = minetest.get_content_id("default:stone")
-- Disegniamo la piastra locale
for dx = -raggio, raggio do
for dz = -raggio, raggio do
local px = tx + dx
local pz = tz + dz
-- Blocco d'erba superficiale
local vi_g = va:index(px, ty, pz)
data[vi_g] = c_grass
-- Zoccolo di pietra sottostante (15 blocchi per saldare i dislivelli)
for dy = 1, 15 do
local vi_s = va:index(px, ty - dy, pz)
data[vi_s] = c_stone
end
end
end
-- Scrittura forzata nel database senza controlli intermedi
vm:set_data(data)
vm:write_to_map()
count = count + 1
-- Rilasciamo la CPU ogni 100 punti della griglia per mantenere stabile il server
if count % 100 == 0 then
minetest.log("action", "[Importatore] Punti griglia terreno consolidati: " .. count)
coroutine.yield()
end
end
end
file_t:close()
end
-- B. CASE (Puntuali sopra il terreno)
local file_c = io.open(percorso_case, "r")
if file_c then
minetest.log("action", "[Importatore] Iniezione volumi edifici...")
local count = 0
for line in file_c:lines() do
local x, y, z, blockname = line:match("([^,]+),([^,]+),([^,]+),([^,]+)")
if x and y and z and blockname then
local pos = {x = tonumber(x), y = tonumber(y), z = tonumber(z)}
blockname = blockname:gsub("%s+", "")
local vm = minetest.get_voxel_manip()
vm:read_from_map(pos, pos)
minetest.set_node(pos, {name = blockname})
count = count + 1
if count % 2000 == 0 then
minetest.log("action", "[Importatore] Blocchi edificio inseriti: " .. count)
coroutine.yield()
end
end
end
file_c:close()
end
minetest.log("action", "[Importatore] PIPELINE COMPLETATA CON SUCCESSO!")
minetest.chat_send_all("[Importatore] PIPELINE COMPLETATA! La Val di Ledro a griglia è pronta.")
end)
local function esegui_passo()
if coroutine.status(thread) ~= "dead" then
coroutine.resume(thread)
minetest.after(0.02, esegui_passo)
end
end
esegui_passo()
end
-- ========================================================
-- 3. ATTIVAZIONE EVENTO AL LOGIN DI MATTRUFFONI
-- ========================================================
local attivato = false
minetest.register_on_joinplayer(function(player)
if player:get_player_name() == "mattruffoni" and not attivato then
attivato = true
minetest.after(3.0, function()
minetest.chat_send_all("[Importatore] Avvio rigenerazione morfologica a griglia fitta...")
avvia_importazione_superficie()
end)
end
end)
</syntaxhighlight>
=====Codice mod.conf=====
<syntaxhighlight lang="lua">
name = importatore
description = Importatore geometrico per la Val di Ledro
</syntaxhighlight>
=== Risultati e Sviluppi Pedagogici ===
L'applicazione di questo flusso permette di generare manti continui di milioni di blocchi mantenendo il server Docker estremamente leggero. Questo ambiente offre uno scenario di apprendimento eccezionale per la didattica laboratoriale (Matematica e Scienze), permettendo agli studenti di esplorare modelli in scala 1:1 del proprio territorio, comprendere l'interazione tra coordinate cartesiane e dati GIS, e interagire con elementi di programmazione e gestione server.
=== Note ===
Ovviamente tutto è stato sviluppato con AI, nello specifico Gemini.
=== Bibliografia ===
=== Collegamenti esterni ===
[[Categoria:Software libero a scuola|Luanti a scuola]]
guj5i704gmebgd8bouhceutbru173qb
501062
501061
2026-08-20T08:30:06Z
Mattruffoni
17392
link inseriti
501062
wikitext
text/x-wiki
{{Software libero a scuola}}
'''''[https://www.luanti.org/it/ Luanti] a scuola''''' è una guida pratica rivolta a docenti, educatori e studenti interessati a integrare la didattica laboratoriale e il ''game-based learning'' nei percorsi scolastici attraverso ambienti virtuali 3D.
== Introduzione ==
L'impiego didattico dei mondi a blocchi (*voxel*) vanta un'esperienza consolidata: la videoludica e la formazione convergono da oltre 15 anni nell'istruzione, con Minecraft promosso in numerosi contesti educativi ed editori di rilievo (come evidenziato nel testo ''A scuola con Minecraft'' di Andrea Benassi, Giunti Scuola, 2021).
Tuttavia, l'adozione di software proprietari all'interno delle istituzioni scolastiche può comportare costi di licenza e vincoli tecnici. In questo scenario si inserisce [https://www.luanti.org/it/ Luanti] (storicamente noto come ''Minetest''), una piattaforma open source, gratuita, flessibile e altamente scalabile.
== Perché Luanti nella didattica ==
Luanti offre una vasta libreria di mod e contenuti personalizzabili che ne estendono le funzionalità pedagogiche:
* **Circuiti elettrici e logica digitale:** attraverso la simulazione di componenti come relè e porte logiche per comprendere la modellazione di sistemi hardware.
* **Coding e robotica:** mediante l'uso di bot e tartarughe programmabili visualmente o tramite script.
* **Attività multidisciplinari:** dalla ricostruzione storica di monumenti all'esplorazione di strutture molecolari e geografiche.
L'efficacia dell'approccio basato sulla costruzione immersiva trova conferma sul campo: da oltre quattro anni l'utilizzo continuativo di Minetest/Luanti in classe dimostra come il *building* collaborativo favorisca l'acquisizione di competenze trasversali, logico-matematiche e digitali (si veda l'esperienza del progetto [https://www.didasharing.it Didasharing.it]).
== Server della community ed esperienze multiplayer ==
Oltre alle attività in locale o in rete d'istituto, il panorama open source offre significativi esempi di ambienti di rete e server multiplayer:
=== A.E.S. (Alternative Entertainment Server) ===
Sviluppato da Zughy e collaboratori, **A.E.S.** rappresenta uno dei più noti hub di minigiochi multiplayer della community di Luanti. Sfruttando l'architettura dinamica e la leggerezza del motore di gioco C++ (con librerie come `arena_lib`), la piattaforma offre varie modalità interattive (tra cui *Block League*, *Skywars*, *Quikbild* e *ColourJump*). Tali arene mostrano come le logiche competitive e lo sviluppo di mod personalizzate possano essere applicati al gioco di squadra e al problem solving.
=== Framatest e il progetto Libreverse ===
In ambito internazionale ed educativo, un punto di riferimento storico è stato **Framatest**, il server pubblico ospitato dal network francese [[Framasoft]] per promuovere l'uso di Minetest nella scuola e nella società civile. Oggi quella stessa eredità e lo spirito di condivisione proseguono grazie all'infrastruttura di Chalec, il cui server è raggiungibile e ospitato su [https://www.chalec.org/services/libreverse/ Libreverse].
Usare Luanti/Minetest per giocare a conoscere il territorio e, volendo, progettarne gli sviluppi futuri.
== Il Progetto: La scuola come laboratorio di pianificazione territoriale ==
Questo manuale nasce con l'obiettivo di guidare docenti e studenti nell'utilizzo di '''Luanti''' (precedentemente noto come ''Minetest'') come strumento didattico, integrando la tecnologia, la geografia (GIS), la matematica e l'educazione civica.
Il cuore del progetto si articola su tre pilastri fondamentali:
* '''Esplorare e Osservare (La Georeferenziazione):''' Creare un mondo digitale che sia il facsimile esatto del proprio territorio reale. Attraverso l'importazione di dati geografici e altimetrici reali, gli studenti possono muoversi in scala 1:1 in un ambiente virtuale familiare, imparando a leggere la morfologia della propria terra da una prospettiva inedita e immersiva.
* '''Progettare ed Eseguire (La Ricostruzione):''' Permettere agli studenti di ricostruire l'ambiente, i monumenti e i complessi urbani. Questo processo stimola lo sviluppo di competenze geometriche, di calcolo spaziale e di problem-solving strutturale, costringendo il ragazzo a passare dall'osservazione della realtà alla sua astrazione e successiva esecuzione tridimensionale a blocchi.
* '''Partecipare (La Cittadinanza Attiva):''' Dare ai ragazzi la possibilità di utilizzare il server condiviso come un laboratorio democratico per la pianificazione urbana e infrastrutturale collettiva. Gli studenti non si limitano a replicare il presente o il passato, ma possono proporre modifiche, nuove infrastrutture e varianti urbanistiche, imparando il valore del dibattito, della negoziazione e della progettazione comunitaria del bene comune.
Attraverso questo percorso, il mondo voxel di Luanti smette di essere un semplice videogioco e diventa un vero e proprio '''gemello digitale didattico''', un ponte tra la scuola e il territorio in grado di formare cittadini consapevoli e tecnicamente preparati.
== Il Valore del Software Libero e l'Accessibilità ==
L'adozione di software libero come Luanti elimina alla radice l'ostacolo delle licenze commerciali e dei costi per le scuole e le famiglie. Questa libertà tecnologica si traduce in una straordinaria agilità operativa: permette di configurare, personalizzare e pubblicare online un server scolastico in modo immediato. Per gli studenti, l'accesso a questo "gemello digitale" del territorio diventa sicuro e inclusivo: chiunque, da qualsiasi dispositivo a casa o a scuola, può connettersi liberamente e partecipare al progetto collettivo, con l'unico requisito di inserire il proprio nome utente e password personalizzati.
== Flusso di lavoro: Dati GIS, Modellazione 3D e Iniezione in Luanti ==
Questo capitolo documenta passo dopo passo la pipeline tecnologica utilizzata per trasformare i dati geografici e altimetrici reali della Val di Ledro in un mondo 3D interamente calpestabile all'interno del server Luanti (Minetest).
=== Fase 1: Acquisizione dei dati geografici e modellazione in Blender ===
==== 1. Selezione dell'Area di Interesse (OSM) ====
Il progetto ha inizio con la delimitazione della zona geografica. Utilizzando il software di modellazione 3D '''Blender''' combinato con l'add-on '''Blender-GIS''', è stato possibile connettersi direttamente ai server cartografici globali. Tramite l'interfaccia di georeferenziazione, è stato ritagliato il perimetro esatto della Val di Ledro attingendo alla cartografia vettoriale di '''OpenStreetMap (OSM)'''. Questa operazione fissa le coordinate di base (Latitudine/Longitudine) nel sistema di riferimento del progetto.
==== 2. Generazione del Rilievo Altimetrico (SRTM) ====
Una volta ottenuta la mappa bidimensionale, si è passati alla terza dimensione applicando i dati altimetrici reali. Sfruttando la funzione di importazione DEM (Digital Elevation Model) di Blender-GIS, sono stati scaricati i dati '''SRTM (Shuttle Radar Topography Mission)''' forniti dalla NASA. Il plugin ha proiettato questi dati vettoriali sulla mesh piana di Blender, deformandola e generando un modello tridimensionale fedele del rilievo montuoso e della morfologia della valle.
==== 3. Download dei Volumi degli Edifici ====
Per integrare l'elemento antropico, è stato effettuato un download mirato direttamente dal portale ufficiale [https://www.openstreetmap.org openstreetmap.org]. È stato esportato un file con estensione <code>.osm</code>, contenente tutti i metadati e le impronte planimetriche degli edifici (i "volumi" e i poligoni delle case) registrati all'interno della medesima area geografica della valle.
==== 4. Posizionamento e Georeferenziazione delle Case ====
Il file <code>.osm</code> grezzo è stato importato all'interno della scena di Blender, sempre tramite l'ausilio di Blender-GIS. Il plugin, riconoscendo la corrispondenza delle coordinate geografiche condivise, ha posizionato automaticamente e matematicamente i volumi geometrici degli edifici sopra il rilievo 3D precedentemente generato, incollando le fondamenta delle case alle rispettive quote del terreno. Nell'importazione viene scelta l'opzione ''buildings''.
==== 5. Importazione del lago ====
Nello stesso modo, e con lo stesso file .osm, usato per importare gli edifici scegliendo l'opzione ''water'' è stato importato il lago di Ledro. Sul lago si è docvuto applicare un ''modifier'' che ha aggiunto una triangolazione della superficie.
==== 6. Esportazione della Mesh ====
Una volta preparato il file in Blender si è proceduto all'esportazione del modello in un formato di interscambio testuale standard. Il file risultante è stato salvato con il nome di <code>LedroValleCompleta.obj</code>, contenente: l'elenco puro dei vertici tridimensionali del terreno, gli edifici in 3d e la superficie del lago.<br/>
Un altra informazione contenuta nei file .osm ad esempio è il nome delle vie e degli edifici, ed anche questo dato è interessante da importare nel mondo virtuale in mod da rendewre i luoghi più riconoscibili.
=== Fase 2: Parsing, Ottimizzazione e Struttura Server ===
=== Il problema tecnologico ===
I metodi tradizionali di scrittura dei nodi in Luanti via API standard (come `minetest.set_node`) mostrano forti limiti quando si gestiscono milioni di coordinate geometriche:
# '''Timeout UDP e Disconnessioni:''' L'elaborazione lineare di file massivi blocca il thread principale del server, causando il congelamento della rete e l'espulsione dei client.
# '''Errore Map::getNodeMetadata (Block not found):''' In ambienti a mappa vuota (es. mapgen `singlenode`), il server fallisce l'accesso ai metadati di blocchi non ancora inizializzati sul database del mondo (`map.sqlite`), generando migliaia di warning e fallendo la scrittura.
# '''Saturazione RAM in Blender:''' L'uso di modificatori come il ''Remesh'' su mesh territoriali molto estese (es. 20x12 km) satura la memoria volatile del sistema operativo, causando il crash del software di modellazione.
=== Architettura della Soluzione ===
La pipeline definitiva si divide in due fasi staccate: un'ottimizzazione matematica dei dati in locale tramite Python e un'iniezione asincrona a basso livello nel server Luanti tramite Lua.
==== Fase 1: Estrazione e Interpolazione dei Dati (Python) ====
Invece di sovraccaricare il motore di gioco o Blender, si utilizza uno script Python esterno sfruttando la libreria '''SciPy''' e l'algoritmo `NearestNDInterpolator` (o `LinearNDInterpolator`).
Lo script esegue le seguenti operazioni:
# Legge i vertici geometrici (`v X Y Z`) dal file `.obj` originale.
# Rileva i confini geografici assoluti della mappa.
# Inizializza un interpolatore spaziale e proietta i dati su una griglia fitta bidimensionale regolare (Heightmap) con un passo stabilito (es. ogni 2 metri).
# Tappa matematicamente i "buchi di cielo" presenti nella mesh rada, assegnando a ogni coordinata vuota l'altezza corretta calcolata sui punti vicini.
# Genera un file di testo ordinato (`ledro_terreno_dati.txt`) in formato `X,Y,Z`.
==== 7. Conversione e Densificazione dei Dati (Python e SciPy) ====
I file <code>.obj</code> nativi presentano una struttura a nuvola di punti (Point Cloud) rada e non ordinata. Con il supporto di '''Gemini''', sono stati sviluppati gli script Python per elaborare i dati:
* <code>estrai_griglia.py</code>: Questo script utilizza la libreria scientifica '''SciPy''' (in particolare l'algoritmo <code>NearestNDInterpolator</code>) per analizzare i 66.481 vertici originali distribuiti su un'area di circa 20x12 km. Python proietta questi punti su una griglia fitta bidimensionale regolare (Heightmap) con un passo costante (es. ogni 2 metri), interpolando matematicamente le altezze nei punti vuoti per "tappare i buchi di cielo" e generando un file coordinato e continuo chiamato <code>ledro_terreno_dati.txt</code> in formato <code>X,Y,Z</code>.<syntaxhighlight lang="python">
import os
import numpy as np
from scipy.interpolate import NearestNDInterpolator
FILE_OBJ = "LedroRilievo.obj"
FILE_OUTPUT = "ledro_terreno_dati.txt"
PASSO = 2 # Un punto ogni 2 metri
print("1. Lettura di tutti i vertici dal file OBJ...")
punti_validi = []
with open(FILE_OBJ, "r") as f:
for line in f:
if line.startswith("v "):
parti = line.split()
if len(parti) >= 4:
try:
punti_validi.append((float(parti[1]), float(parti[2]), float(parti[3])))
except ValueError:
continue
if not punti_validi:
print("ERRORE: Nessun vertice trovato nel file OBJ!")
exit()
# Coordinate separate
x_arr = np.array([p[0] for p in punti_validi])
y_arr = np.array([p[1] for p in punti_validi])
z_arr = np.array([p[2] for p in punti_validi])
min_x, max_x = int(np.min(x_arr)), int(np.max(x_arr))
min_z, max_z = int(np.min(z_arr)), int(np.max(z_arr))
print(f"Confini rilevati -> X: [{min_x} a {max_x}], Z: [{min_z} a {max_z}]")
print("2. Inizializzazione interpolatore geometrico (SciPy)...")
# Creiamo l'interpolatore basato sui punti noti dell'OBJ
interp = NearestNDInterpolator(list(zip(x_arr, z_arr)), y_arr)
print("3. Generazione griglia fitta continua e scrittura...")
# Generiamo gli intervalli regolari basati sul PASSO scelto
intervallo_x = np.arange(round(min_x / PASSO) * PASSO, round(max_x / PASSO) * PASSO + PASSO, PASSO)
intervallo_z = np.arange(round(min_z / PASSO) * PASSO, round(max_z / PASSO) * PASSO + PASSO, PASSO)
punti_totali_scritti = 0
with open(FILE_OUTPUT, "w") as out:
for gx in intervallo_x:
# Calcoliamo l'altezza per l'intera colonna Z in un colpo solo (velocissimo)
gz_array = np.array(list(intervallo_z))
gx_array = np.full_like(gz_array, gx)
# SciPy calcola le altezze interpolate istantaneamente per tutta la riga
altezze_interpolate = interp(gx_array, gz_array)
for i, gz in enumerate(intervallo_z):
gy = round(altezze_interpolate[i])
out.write(f"{gx},{gy},{gz}\n")
punti_totali_scritti += 1
print(f"Operazione completata! Generata griglia solida continua con {punti_totali_scritti} punti complessivi.")
</syntaxhighlight>
* <code>ledro_convertitore_case.py</code>: Estrae le posizioni degli edifici associandole ai rispettivi blocchi di costruzione, generando il file ordinato <code>ledro_case_dati.txt</code><syntaxhighlight lang="python">
import numpy as np
import trimesh
import os
from math import ceil
# ==========================================
# CONFIGURAZIONE COSTANTI
# ==========================================
FILE_OBJ_TERRENO = "LedroRilievo.obj"
FILE_OBJ_CASE = "LedroCase.obj"
NOME_FILE_USCITA = "ledro_case_dati.txt"
# Scala 1.0 per corrispondenza esatta con il terreno a passo 1 metro
FAUTORE_SCALA = 1.0
START_Y = 30
def converti_case_streaming(terreno_input, case_input, file_output):
if not os.path.exists(case_input) or not os.path.exists(terreno_input):
print("Errore: Uno dei file OBJ non esiste nella cartella attuale!")
return
# 1. Calcolo del centro del terreno per l'allineamento perfetto degli assi
print(f"Lettura terreno per allineamento assi: {terreno_input}...")
scena_t = trimesh.load(terreno_input, force='mesh')
mesh_t = trimesh.util.concatenate([g for g in scena_t.geometry.values()]) if isinstance(scena_t, trimesh.Scene) else scena_t
bounds_t = mesh_t.bounds
min_x_t, _, min_z_t = bounds_t[0]
max_x_t, _, max_z_t = bounds_t[1]
centro_x = int((max_x_t - min_x_t) / 2)
centro_z = int((max_z_t - min_z_t) / 2)
# 2. Caricamento e pulizia della mesh degli edifici
print(f"Caricamento edifici da {case_input}...")
scena_c = trimesh.load(case_input, force='mesh')
if isinstance(scena_c, trimesh.Scene):
mesh_unica_case = trimesh.util.concatenate([g for g in scena_c.geometry.values()])
else:
mesh_unica_case = scena_c
print("Pulizia della mesh e fusione dei vertici adiacenti...")
# Valida e salda insieme i poligoni staccati della stessa struttura
mesh_unica_case.process(validate=True)
print("Separazione degli edifici in componenti connesse...")
edifici_grezzi = mesh_unica_case.split(only_watertight=False)
# Filtriamo le bricioline geometriche inferiori a 2mq
edifici = [edf for edf in edifici_grezzi if edf.area > 2.0]
print(f"Trovati {len(edifici)} edifici reali stabili. Generazione geometrie cave...")
# Rimuoviamo il vecchio file se presente
if os.path.exists(file_output):
os.remove(file_output)
# 3. Ciclo di generazione geometrica delle case cave (SOLO SOLIDI)
edifici_scritti = 0
with open(file_output, "w") as f:
for i, edf in enumerate(edifici):
b = edf.bounds
min_x, min_y, min_z = b[0]
max_x, max_y, max_z = b[1]
dim_x = int(ceil(max_x - min_x))
dim_y = int(ceil(max_y - min_y))
dim_z = int(ceil(max_z - min_z))
# FILTRO DI SICUREZZA ANTI-LOOP (ARTEFATTI GIS):
# Se un "edificio" supera le dimensioni di un enorme isolato, è un errore di mesh dell'OBJ.
# Lo saltiamo per evitare che i cicli for successivi congelino la CPU.
if dim_x > 60 or dim_z > 60 or dim_y > 40:
continue
# APPLICAZIONE REGOLE PUNTO 4: Vincoli minimi (5x6x5)
larghezza_x = max(5, dim_x)
lunghezza_z = max(6, dim_z)
altezza_y = max(5, dim_y)
# Calcolo coordinate assolute centrate rispetto al terreno
start_x = int(min_x - min_x_t - centro_x)
start_z = int(min_z - min_z_t - centro_z)
start_y = int(min_y + START_Y)
edifici_scritti += 1
# Rendering dei soli nodi fisici perimetrali
for dx in range(larghezza_x):
for dz in range(lunghezza_z):
for dy in range(altezza_y):
abs_x = start_x + dx
abs_z = start_z + dz
abs_y = start_y + dy
is_muro = (dx == 0 or dx == larghezza_x - 1 or dz == 0 or dz == lunghezza_z - 1)
is_pavimento = (dy == 0)
is_tetto = (dy == altezza_y - 1)
if is_pavimento:
blocco = "default:wood"
elif is_tetto:
blocco = "default:brick"
elif is_muro:
blocco = "default:stone"
else:
# Salta l'aria interna! Risparmia lo spazio su disco
continue
f.write(f"{abs_x},{abs_y},{abs_z},{blocco}\n")
if (i + 1) % 100 == 0 or (i + 1) == len(edifici):
print(f"Progressione: {i + 1}/{len(edifici)} nodi mesh analizzati... ({edifici_scritti} edifici reali scritti)")
print(f"Fatto! File delle case salvato con successo in {file_output}. Scritti {edifici_scritti} edifici.")
# ==========================================
# PUNTO DI INGRESSO DELLO SCRIPT
# ==========================================
if __name__ == "__main__":
converti_case_streaming(FILE_OBJ_TERRENO, FILE_OBJ_CASE, NOME_FILE_USCITA)
</syntaxhighlight>
==== 8. Configurazione dell'Ambiente Virtuale Docker ====
Per ospitare l'infrastruttura di simulazione in modo isolato e replicabile, è stato configurato un container '''Docker''' gestito tramite '''Docker Compose'''. Sulla base di un file <code>docker-compose.yml</code> strutturato ad hoc, la cartella di lavoro del server Luanti/Minetest è stata mappata in locale sul PC dell'utente (tramite i Docker Volumes) per permettere la modifica in tempo reale dei file di gioco. All'interno della configurazione, il mondo è stato battezzato <code>ledro3d</code> e l'utente <code>mattruffoni</code> è stato designato come amministratore di sistema con massimi privilegi energetici.<syntaxhighlight lang="dockerfile">
services:
luanti_engine:
image: lscr.io/linuxserver/luanti:latest
container_name: local_luanti_engine
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Rome
# FORZATURA: Diciamo a Luanti esattamente quale file .conf leggere dentro il container
- CLI_ARGS=--worldname ledro3d --config /config/.minetest/minetest.conf --terminal
volumes:
- ./server_data:/config/.minetest
ports:
- 30000:30000/udp
restart: unless-stopped
</syntaxhighlight>
==== 9. Accessibilità del Server di Gioco ====
Una volta avviato lo stack di Docker tramite terminale (<code>docker compose up -d</code>), il container ha esposto i servizi di rete dedicati. Il server Luanti/Minetest è diventato operativo e raggiungibile in locale dall'indirizzo di loopback '''<code>localhost:30000</code>''', pronto ad accettare le connessioni da parte del client di gioco per l'esplorazione virtuale.
=== Fase 3: Sviluppo della Mod e Generazione del Mondo ===
====Creazione mod '''importatore'''====
Nella cartella ''.../minetest-server/server_data/worlds/ledro3d/worldmods/importatore'' si crea la mod importatore inserendoci il file init.lua, mod.conf e i due file di testo ledro_terreno_dati.txt e ledro_case_dati.txt creati in precedenza.
==== 10. Sviluppo della Mod Lua Asincrona "Importatore" ====
L'iniezione di milioni di nodi all'interno del database del mondo (<code>map.sqlite</code>) presenta forti criticità prestazionali (rischio di timeout UDP e crash per memoria satura). Per ovviare a questo problema, è stata sviluppata una mod personalizzata in linguaggio Lua denominata '''<code>importatore</code>'''. La mod implementa due soluzioni architetturali cruciali:
# '''Il VoxelManip Engine (LVM):''' Invece di posizionare un singolo cubo alla volta, la mod alloca grandi porzioni di mappa direttamente nella memoria volatile del server, scrive i blocchi di erba superficiale (<code>default:dirt_with_grass</code>) e le fondamenta sottostanti (<code>default:stone</code>), e forza la scrittura in blocco sul database, azzerando i warning di blocchi non trovati.
# '''Gestione tramite Co-routine Lua:''' La lettura dei file <code>.txt</code> è inserita in un ciclo asincrono controllato da co-routine. Tramite l'istruzione <code>coroutine.yield()</code>, la mod rilascia il controllo alla CPU del PC host ogni 100 nodi processati, permettendo al server di rimanere fluido, gestire i pacchetti di rete e consentire il movimento del giocatore durante la crescita progressiva della valle.
==== Fase 2: Iniezione Asincrona nella Mappa (Luanti Mod) ====
La mod Luanti (scritta in `init.lua`) riceve il file a griglia regolare e applica due strategie fondamentali per garantire stabilità e performance:
* '''Uso del VoxelManip (LVM):''' Invece di scrivere un blocco alla volta, la mod alloca un'area di memoria temporanea (`minetest.get_voxel_manip()`), manipola l'array dei nodi inserendo la superficie erbosa (`default:dirt_with_grass`) e lo zoccolo di roccia sottostante (`default:stone`), e infine forza la scrittura dell'intero blocco direttamente sul database (`vm:write_to_map()`). Questo bypassa i controlli dei metadati azzerando il warning ''Block not found''.
* '''Gestione Asincrona via Co-routine:''' Il ciclo di lettura del file viene inserito in una co-routine Lua (`coroutine.create`). Tramite l'istruzione `coroutine.yield()`, la mod rilascia il controllo alla CPU ogni 100 nodi processati, permettendo al server Luanti di gestire i pacchetti di rete, l'orario del mondo e il login dei giocatori senza lag.
==== Codice init.lua della mod importatore====
<syntaxhighlight lang="lua">
-- ========================================================
-- 1. PRIVILEGI AUTOMATICI PER MATTRUFFONI (CON SETTIME)
-- ========================================================
minetest.register_on_joinplayer(function(player)
local name = player:get_player_name()
if name == "mattruffoni" then
minetest.after(0.5, function()
local p = minetest.get_player_by_name(name)
if p then
local privs = minetest.get_player_privs(name)
privs.privs = true
privs.fly = true
privs.fast = true
privs.teleport = true
privs.interact = true
privs.shout = true
privs.settime = true -- Aggiunto privilegio per impostare l'ora
privs.time = true -- Aggiunto privilegio per gestire il tempo
minetest.set_player_privs(name, privs)
minetest.chat_send_player(name, "Benvenuto Prof! Privilegi completi (incluso settime) attivati.")
end
end)
end
end)
-- ========================================================
-- 2. PIPELINE DI IMPORTAZIONE A GRIGLIA ORDINATA (LVM)
-- ========================================================
local function avvia_importazione_superficie()
local percorso_terreno = minetest.get_modpath("importatore") .. "/ledro_terreno_dati.txt"
local percorso_case = minetest.get_modpath("importatore") .. "/ledro_case_dati.txt"
local thread = coroutine.create(function()
-- A. TERRENO (Morfologia a celle raccordate)
local file_t = io.open(percorso_terreno, "r")
if file_t then
minetest.log("action", "[Importatore] Scrittura griglia terreno georeferenziato...")
local count = 0
for line in file_t:lines() do
local x, y, z = line:match("([^,]+),([^,]+),([^,]+)")
if x and y and z then
local tx, ty, tz = tonumber(x), tonumber(y), tonumber(z)
-- Raggio 2 crea una piastra 5x5 attorno a ogni punto.
-- Avendo ordinato il file a passo 2, le piastre si fondono perfettamente.
local raggio = 2
-- Allochiamo l'area minima per il manipolatore di voxel
local p_min = {x = tx - raggio, y = ty - 15, z = tz - raggio}
local p_max = {x = tx + raggio, y = ty, z = tz + raggio}
local vm = minetest.get_voxel_manip()
local emin, emax = vm:read_from_map(p_min, p_max)
local data = vm:get_data()
local va = VoxelArea:new{MinEdge = emin, MaxEdge = emax}
local c_grass = minetest.get_content_id("default:dirt_with_grass")
local c_stone = minetest.get_content_id("default:stone")
-- Disegniamo la piastra locale
for dx = -raggio, raggio do
for dz = -raggio, raggio do
local px = tx + dx
local pz = tz + dz
-- Blocco d'erba superficiale
local vi_g = va:index(px, ty, pz)
data[vi_g] = c_grass
-- Zoccolo di pietra sottostante (15 blocchi per saldare i dislivelli)
for dy = 1, 15 do
local vi_s = va:index(px, ty - dy, pz)
data[vi_s] = c_stone
end
end
end
-- Scrittura forzata nel database senza controlli intermedi
vm:set_data(data)
vm:write_to_map()
count = count + 1
-- Rilasciamo la CPU ogni 100 punti della griglia per mantenere stabile il server
if count % 100 == 0 then
minetest.log("action", "[Importatore] Punti griglia terreno consolidati: " .. count)
coroutine.yield()
end
end
end
file_t:close()
end
-- B. CASE (Puntuali sopra il terreno)
local file_c = io.open(percorso_case, "r")
if file_c then
minetest.log("action", "[Importatore] Iniezione volumi edifici...")
local count = 0
for line in file_c:lines() do
local x, y, z, blockname = line:match("([^,]+),([^,]+),([^,]+),([^,]+)")
if x and y and z and blockname then
local pos = {x = tonumber(x), y = tonumber(y), z = tonumber(z)}
blockname = blockname:gsub("%s+", "")
local vm = minetest.get_voxel_manip()
vm:read_from_map(pos, pos)
minetest.set_node(pos, {name = blockname})
count = count + 1
if count % 2000 == 0 then
minetest.log("action", "[Importatore] Blocchi edificio inseriti: " .. count)
coroutine.yield()
end
end
end
file_c:close()
end
minetest.log("action", "[Importatore] PIPELINE COMPLETATA CON SUCCESSO!")
minetest.chat_send_all("[Importatore] PIPELINE COMPLETATA! La Val di Ledro a griglia è pronta.")
end)
local function esegui_passo()
if coroutine.status(thread) ~= "dead" then
coroutine.resume(thread)
minetest.after(0.02, esegui_passo)
end
end
esegui_passo()
end
-- ========================================================
-- 3. ATTIVAZIONE EVENTO AL LOGIN DI MATTRUFFONI
-- ========================================================
local attivato = false
minetest.register_on_joinplayer(function(player)
if player:get_player_name() == "mattruffoni" and not attivato then
attivato = true
minetest.after(3.0, function()
minetest.chat_send_all("[Importatore] Avvio rigenerazione morfologica a griglia fitta...")
avvia_importazione_superficie()
end)
end
end)
</syntaxhighlight>
=====Codice mod.conf=====
<syntaxhighlight lang="lua">
name = importatore
description = Importatore geometrico per la Val di Ledro
</syntaxhighlight>
=== Risultati e Sviluppi Pedagogici ===
L'applicazione di questo flusso permette di generare manti continui di milioni di blocchi mantenendo il server Docker estremamente leggero. Questo ambiente offre uno scenario di apprendimento eccezionale per la didattica laboratoriale (Matematica e Scienze), permettendo agli studenti di esplorare modelli in scala 1:1 del proprio territorio, comprendere l'interazione tra coordinate cartesiane e dati GIS, e interagire con elementi di programmazione e gestione server.
=== Note ===
Ovviamente tutto è stato sviluppato con AI, nello specifico Gemini.
=== Bibliografia ===
=== Collegamenti esterni ===
[[Categoria:Software libero a scuola|Luanti a scuola]]
91waoqxzrq5kyi9cer4zsn6k21d29do
501063
501062
2026-08-20T08:30:47Z
Mattruffoni
17392
/* Perché Luanti nella didattica */
501063
wikitext
text/x-wiki
{{Software libero a scuola}}
'''''[https://www.luanti.org/it/ Luanti] a scuola''''' è una guida pratica rivolta a docenti, educatori e studenti interessati a integrare la didattica laboratoriale e il ''game-based learning'' nei percorsi scolastici attraverso ambienti virtuali 3D.
== Introduzione ==
L'impiego didattico dei mondi a blocchi (*voxel*) vanta un'esperienza consolidata: la videoludica e la formazione convergono da oltre 15 anni nell'istruzione, con Minecraft promosso in numerosi contesti educativi ed editori di rilievo (come evidenziato nel testo ''A scuola con Minecraft'' di Andrea Benassi, Giunti Scuola, 2021).
Tuttavia, l'adozione di software proprietari all'interno delle istituzioni scolastiche può comportare costi di licenza e vincoli tecnici. In questo scenario si inserisce [https://www.luanti.org/it/ Luanti] (storicamente noto come ''Minetest''), una piattaforma open source, gratuita, flessibile e altamente scalabile.
== Perché Luanti nella didattica ==
Luanti offre una vasta libreria di mod e contenuti personalizzabili che ne estendono le funzionalità pedagogiche:
* '''Circuiti elettrici e logica digitale:''' attraverso la simulazione di componenti come relè e porte logiche per comprendere la modellazione di sistemi hardware.
* '''Coding e robotica:''' mediante l'uso di bot e tartarughe programmabili visualmente o tramite script.
* '''Attività multidisciplinari:''' dalla ricostruzione storica di monumenti all'esplorazione di strutture molecolari e geografiche.
L'efficacia dell'approccio basato sulla costruzione immersiva trova conferma sul campo: da oltre quattro anni l'utilizzo continuativo di Minetest/Luanti in classe dimostra come il *building* collaborativo favorisca l'acquisizione di competenze trasversali, logico-matematiche e digitali (si veda l'esperienza del progetto [https://www.didasharing.it Didasharing.it]).
== Server della community ed esperienze multiplayer ==
Oltre alle attività in locale o in rete d'istituto, il panorama open source offre significativi esempi di ambienti di rete e server multiplayer:
=== A.E.S. (Alternative Entertainment Server) ===
Sviluppato da Zughy e collaboratori, **A.E.S.** rappresenta uno dei più noti hub di minigiochi multiplayer della community di Luanti. Sfruttando l'architettura dinamica e la leggerezza del motore di gioco C++ (con librerie come `arena_lib`), la piattaforma offre varie modalità interattive (tra cui *Block League*, *Skywars*, *Quikbild* e *ColourJump*). Tali arene mostrano come le logiche competitive e lo sviluppo di mod personalizzate possano essere applicati al gioco di squadra e al problem solving.
=== Framatest e il progetto Libreverse ===
In ambito internazionale ed educativo, un punto di riferimento storico è stato **Framatest**, il server pubblico ospitato dal network francese [[Framasoft]] per promuovere l'uso di Minetest nella scuola e nella società civile. Oggi quella stessa eredità e lo spirito di condivisione proseguono grazie all'infrastruttura di Chalec, il cui server è raggiungibile e ospitato su [https://www.chalec.org/services/libreverse/ Libreverse].
Usare Luanti/Minetest per giocare a conoscere il territorio e, volendo, progettarne gli sviluppi futuri.
== Il Progetto: La scuola come laboratorio di pianificazione territoriale ==
Questo manuale nasce con l'obiettivo di guidare docenti e studenti nell'utilizzo di '''Luanti''' (precedentemente noto come ''Minetest'') come strumento didattico, integrando la tecnologia, la geografia (GIS), la matematica e l'educazione civica.
Il cuore del progetto si articola su tre pilastri fondamentali:
* '''Esplorare e Osservare (La Georeferenziazione):''' Creare un mondo digitale che sia il facsimile esatto del proprio territorio reale. Attraverso l'importazione di dati geografici e altimetrici reali, gli studenti possono muoversi in scala 1:1 in un ambiente virtuale familiare, imparando a leggere la morfologia della propria terra da una prospettiva inedita e immersiva.
* '''Progettare ed Eseguire (La Ricostruzione):''' Permettere agli studenti di ricostruire l'ambiente, i monumenti e i complessi urbani. Questo processo stimola lo sviluppo di competenze geometriche, di calcolo spaziale e di problem-solving strutturale, costringendo il ragazzo a passare dall'osservazione della realtà alla sua astrazione e successiva esecuzione tridimensionale a blocchi.
* '''Partecipare (La Cittadinanza Attiva):''' Dare ai ragazzi la possibilità di utilizzare il server condiviso come un laboratorio democratico per la pianificazione urbana e infrastrutturale collettiva. Gli studenti non si limitano a replicare il presente o il passato, ma possono proporre modifiche, nuove infrastrutture e varianti urbanistiche, imparando il valore del dibattito, della negoziazione e della progettazione comunitaria del bene comune.
Attraverso questo percorso, il mondo voxel di Luanti smette di essere un semplice videogioco e diventa un vero e proprio '''gemello digitale didattico''', un ponte tra la scuola e il territorio in grado di formare cittadini consapevoli e tecnicamente preparati.
== Il Valore del Software Libero e l'Accessibilità ==
L'adozione di software libero come Luanti elimina alla radice l'ostacolo delle licenze commerciali e dei costi per le scuole e le famiglie. Questa libertà tecnologica si traduce in una straordinaria agilità operativa: permette di configurare, personalizzare e pubblicare online un server scolastico in modo immediato. Per gli studenti, l'accesso a questo "gemello digitale" del territorio diventa sicuro e inclusivo: chiunque, da qualsiasi dispositivo a casa o a scuola, può connettersi liberamente e partecipare al progetto collettivo, con l'unico requisito di inserire il proprio nome utente e password personalizzati.
== Flusso di lavoro: Dati GIS, Modellazione 3D e Iniezione in Luanti ==
Questo capitolo documenta passo dopo passo la pipeline tecnologica utilizzata per trasformare i dati geografici e altimetrici reali della Val di Ledro in un mondo 3D interamente calpestabile all'interno del server Luanti (Minetest).
=== Fase 1: Acquisizione dei dati geografici e modellazione in Blender ===
==== 1. Selezione dell'Area di Interesse (OSM) ====
Il progetto ha inizio con la delimitazione della zona geografica. Utilizzando il software di modellazione 3D '''Blender''' combinato con l'add-on '''Blender-GIS''', è stato possibile connettersi direttamente ai server cartografici globali. Tramite l'interfaccia di georeferenziazione, è stato ritagliato il perimetro esatto della Val di Ledro attingendo alla cartografia vettoriale di '''OpenStreetMap (OSM)'''. Questa operazione fissa le coordinate di base (Latitudine/Longitudine) nel sistema di riferimento del progetto.
==== 2. Generazione del Rilievo Altimetrico (SRTM) ====
Una volta ottenuta la mappa bidimensionale, si è passati alla terza dimensione applicando i dati altimetrici reali. Sfruttando la funzione di importazione DEM (Digital Elevation Model) di Blender-GIS, sono stati scaricati i dati '''SRTM (Shuttle Radar Topography Mission)''' forniti dalla NASA. Il plugin ha proiettato questi dati vettoriali sulla mesh piana di Blender, deformandola e generando un modello tridimensionale fedele del rilievo montuoso e della morfologia della valle.
==== 3. Download dei Volumi degli Edifici ====
Per integrare l'elemento antropico, è stato effettuato un download mirato direttamente dal portale ufficiale [https://www.openstreetmap.org openstreetmap.org]. È stato esportato un file con estensione <code>.osm</code>, contenente tutti i metadati e le impronte planimetriche degli edifici (i "volumi" e i poligoni delle case) registrati all'interno della medesima area geografica della valle.
==== 4. Posizionamento e Georeferenziazione delle Case ====
Il file <code>.osm</code> grezzo è stato importato all'interno della scena di Blender, sempre tramite l'ausilio di Blender-GIS. Il plugin, riconoscendo la corrispondenza delle coordinate geografiche condivise, ha posizionato automaticamente e matematicamente i volumi geometrici degli edifici sopra il rilievo 3D precedentemente generato, incollando le fondamenta delle case alle rispettive quote del terreno. Nell'importazione viene scelta l'opzione ''buildings''.
==== 5. Importazione del lago ====
Nello stesso modo, e con lo stesso file .osm, usato per importare gli edifici scegliendo l'opzione ''water'' è stato importato il lago di Ledro. Sul lago si è docvuto applicare un ''modifier'' che ha aggiunto una triangolazione della superficie.
==== 6. Esportazione della Mesh ====
Una volta preparato il file in Blender si è proceduto all'esportazione del modello in un formato di interscambio testuale standard. Il file risultante è stato salvato con il nome di <code>LedroValleCompleta.obj</code>, contenente: l'elenco puro dei vertici tridimensionali del terreno, gli edifici in 3d e la superficie del lago.<br/>
Un altra informazione contenuta nei file .osm ad esempio è il nome delle vie e degli edifici, ed anche questo dato è interessante da importare nel mondo virtuale in mod da rendewre i luoghi più riconoscibili.
=== Fase 2: Parsing, Ottimizzazione e Struttura Server ===
=== Il problema tecnologico ===
I metodi tradizionali di scrittura dei nodi in Luanti via API standard (come `minetest.set_node`) mostrano forti limiti quando si gestiscono milioni di coordinate geometriche:
# '''Timeout UDP e Disconnessioni:''' L'elaborazione lineare di file massivi blocca il thread principale del server, causando il congelamento della rete e l'espulsione dei client.
# '''Errore Map::getNodeMetadata (Block not found):''' In ambienti a mappa vuota (es. mapgen `singlenode`), il server fallisce l'accesso ai metadati di blocchi non ancora inizializzati sul database del mondo (`map.sqlite`), generando migliaia di warning e fallendo la scrittura.
# '''Saturazione RAM in Blender:''' L'uso di modificatori come il ''Remesh'' su mesh territoriali molto estese (es. 20x12 km) satura la memoria volatile del sistema operativo, causando il crash del software di modellazione.
=== Architettura della Soluzione ===
La pipeline definitiva si divide in due fasi staccate: un'ottimizzazione matematica dei dati in locale tramite Python e un'iniezione asincrona a basso livello nel server Luanti tramite Lua.
==== Fase 1: Estrazione e Interpolazione dei Dati (Python) ====
Invece di sovraccaricare il motore di gioco o Blender, si utilizza uno script Python esterno sfruttando la libreria '''SciPy''' e l'algoritmo `NearestNDInterpolator` (o `LinearNDInterpolator`).
Lo script esegue le seguenti operazioni:
# Legge i vertici geometrici (`v X Y Z`) dal file `.obj` originale.
# Rileva i confini geografici assoluti della mappa.
# Inizializza un interpolatore spaziale e proietta i dati su una griglia fitta bidimensionale regolare (Heightmap) con un passo stabilito (es. ogni 2 metri).
# Tappa matematicamente i "buchi di cielo" presenti nella mesh rada, assegnando a ogni coordinata vuota l'altezza corretta calcolata sui punti vicini.
# Genera un file di testo ordinato (`ledro_terreno_dati.txt`) in formato `X,Y,Z`.
==== 7. Conversione e Densificazione dei Dati (Python e SciPy) ====
I file <code>.obj</code> nativi presentano una struttura a nuvola di punti (Point Cloud) rada e non ordinata. Con il supporto di '''Gemini''', sono stati sviluppati gli script Python per elaborare i dati:
* <code>estrai_griglia.py</code>: Questo script utilizza la libreria scientifica '''SciPy''' (in particolare l'algoritmo <code>NearestNDInterpolator</code>) per analizzare i 66.481 vertici originali distribuiti su un'area di circa 20x12 km. Python proietta questi punti su una griglia fitta bidimensionale regolare (Heightmap) con un passo costante (es. ogni 2 metri), interpolando matematicamente le altezze nei punti vuoti per "tappare i buchi di cielo" e generando un file coordinato e continuo chiamato <code>ledro_terreno_dati.txt</code> in formato <code>X,Y,Z</code>.<syntaxhighlight lang="python">
import os
import numpy as np
from scipy.interpolate import NearestNDInterpolator
FILE_OBJ = "LedroRilievo.obj"
FILE_OUTPUT = "ledro_terreno_dati.txt"
PASSO = 2 # Un punto ogni 2 metri
print("1. Lettura di tutti i vertici dal file OBJ...")
punti_validi = []
with open(FILE_OBJ, "r") as f:
for line in f:
if line.startswith("v "):
parti = line.split()
if len(parti) >= 4:
try:
punti_validi.append((float(parti[1]), float(parti[2]), float(parti[3])))
except ValueError:
continue
if not punti_validi:
print("ERRORE: Nessun vertice trovato nel file OBJ!")
exit()
# Coordinate separate
x_arr = np.array([p[0] for p in punti_validi])
y_arr = np.array([p[1] for p in punti_validi])
z_arr = np.array([p[2] for p in punti_validi])
min_x, max_x = int(np.min(x_arr)), int(np.max(x_arr))
min_z, max_z = int(np.min(z_arr)), int(np.max(z_arr))
print(f"Confini rilevati -> X: [{min_x} a {max_x}], Z: [{min_z} a {max_z}]")
print("2. Inizializzazione interpolatore geometrico (SciPy)...")
# Creiamo l'interpolatore basato sui punti noti dell'OBJ
interp = NearestNDInterpolator(list(zip(x_arr, z_arr)), y_arr)
print("3. Generazione griglia fitta continua e scrittura...")
# Generiamo gli intervalli regolari basati sul PASSO scelto
intervallo_x = np.arange(round(min_x / PASSO) * PASSO, round(max_x / PASSO) * PASSO + PASSO, PASSO)
intervallo_z = np.arange(round(min_z / PASSO) * PASSO, round(max_z / PASSO) * PASSO + PASSO, PASSO)
punti_totali_scritti = 0
with open(FILE_OUTPUT, "w") as out:
for gx in intervallo_x:
# Calcoliamo l'altezza per l'intera colonna Z in un colpo solo (velocissimo)
gz_array = np.array(list(intervallo_z))
gx_array = np.full_like(gz_array, gx)
# SciPy calcola le altezze interpolate istantaneamente per tutta la riga
altezze_interpolate = interp(gx_array, gz_array)
for i, gz in enumerate(intervallo_z):
gy = round(altezze_interpolate[i])
out.write(f"{gx},{gy},{gz}\n")
punti_totali_scritti += 1
print(f"Operazione completata! Generata griglia solida continua con {punti_totali_scritti} punti complessivi.")
</syntaxhighlight>
* <code>ledro_convertitore_case.py</code>: Estrae le posizioni degli edifici associandole ai rispettivi blocchi di costruzione, generando il file ordinato <code>ledro_case_dati.txt</code><syntaxhighlight lang="python">
import numpy as np
import trimesh
import os
from math import ceil
# ==========================================
# CONFIGURAZIONE COSTANTI
# ==========================================
FILE_OBJ_TERRENO = "LedroRilievo.obj"
FILE_OBJ_CASE = "LedroCase.obj"
NOME_FILE_USCITA = "ledro_case_dati.txt"
# Scala 1.0 per corrispondenza esatta con il terreno a passo 1 metro
FAUTORE_SCALA = 1.0
START_Y = 30
def converti_case_streaming(terreno_input, case_input, file_output):
if not os.path.exists(case_input) or not os.path.exists(terreno_input):
print("Errore: Uno dei file OBJ non esiste nella cartella attuale!")
return
# 1. Calcolo del centro del terreno per l'allineamento perfetto degli assi
print(f"Lettura terreno per allineamento assi: {terreno_input}...")
scena_t = trimesh.load(terreno_input, force='mesh')
mesh_t = trimesh.util.concatenate([g for g in scena_t.geometry.values()]) if isinstance(scena_t, trimesh.Scene) else scena_t
bounds_t = mesh_t.bounds
min_x_t, _, min_z_t = bounds_t[0]
max_x_t, _, max_z_t = bounds_t[1]
centro_x = int((max_x_t - min_x_t) / 2)
centro_z = int((max_z_t - min_z_t) / 2)
# 2. Caricamento e pulizia della mesh degli edifici
print(f"Caricamento edifici da {case_input}...")
scena_c = trimesh.load(case_input, force='mesh')
if isinstance(scena_c, trimesh.Scene):
mesh_unica_case = trimesh.util.concatenate([g for g in scena_c.geometry.values()])
else:
mesh_unica_case = scena_c
print("Pulizia della mesh e fusione dei vertici adiacenti...")
# Valida e salda insieme i poligoni staccati della stessa struttura
mesh_unica_case.process(validate=True)
print("Separazione degli edifici in componenti connesse...")
edifici_grezzi = mesh_unica_case.split(only_watertight=False)
# Filtriamo le bricioline geometriche inferiori a 2mq
edifici = [edf for edf in edifici_grezzi if edf.area > 2.0]
print(f"Trovati {len(edifici)} edifici reali stabili. Generazione geometrie cave...")
# Rimuoviamo il vecchio file se presente
if os.path.exists(file_output):
os.remove(file_output)
# 3. Ciclo di generazione geometrica delle case cave (SOLO SOLIDI)
edifici_scritti = 0
with open(file_output, "w") as f:
for i, edf in enumerate(edifici):
b = edf.bounds
min_x, min_y, min_z = b[0]
max_x, max_y, max_z = b[1]
dim_x = int(ceil(max_x - min_x))
dim_y = int(ceil(max_y - min_y))
dim_z = int(ceil(max_z - min_z))
# FILTRO DI SICUREZZA ANTI-LOOP (ARTEFATTI GIS):
# Se un "edificio" supera le dimensioni di un enorme isolato, è un errore di mesh dell'OBJ.
# Lo saltiamo per evitare che i cicli for successivi congelino la CPU.
if dim_x > 60 or dim_z > 60 or dim_y > 40:
continue
# APPLICAZIONE REGOLE PUNTO 4: Vincoli minimi (5x6x5)
larghezza_x = max(5, dim_x)
lunghezza_z = max(6, dim_z)
altezza_y = max(5, dim_y)
# Calcolo coordinate assolute centrate rispetto al terreno
start_x = int(min_x - min_x_t - centro_x)
start_z = int(min_z - min_z_t - centro_z)
start_y = int(min_y + START_Y)
edifici_scritti += 1
# Rendering dei soli nodi fisici perimetrali
for dx in range(larghezza_x):
for dz in range(lunghezza_z):
for dy in range(altezza_y):
abs_x = start_x + dx
abs_z = start_z + dz
abs_y = start_y + dy
is_muro = (dx == 0 or dx == larghezza_x - 1 or dz == 0 or dz == lunghezza_z - 1)
is_pavimento = (dy == 0)
is_tetto = (dy == altezza_y - 1)
if is_pavimento:
blocco = "default:wood"
elif is_tetto:
blocco = "default:brick"
elif is_muro:
blocco = "default:stone"
else:
# Salta l'aria interna! Risparmia lo spazio su disco
continue
f.write(f"{abs_x},{abs_y},{abs_z},{blocco}\n")
if (i + 1) % 100 == 0 or (i + 1) == len(edifici):
print(f"Progressione: {i + 1}/{len(edifici)} nodi mesh analizzati... ({edifici_scritti} edifici reali scritti)")
print(f"Fatto! File delle case salvato con successo in {file_output}. Scritti {edifici_scritti} edifici.")
# ==========================================
# PUNTO DI INGRESSO DELLO SCRIPT
# ==========================================
if __name__ == "__main__":
converti_case_streaming(FILE_OBJ_TERRENO, FILE_OBJ_CASE, NOME_FILE_USCITA)
</syntaxhighlight>
==== 8. Configurazione dell'Ambiente Virtuale Docker ====
Per ospitare l'infrastruttura di simulazione in modo isolato e replicabile, è stato configurato un container '''Docker''' gestito tramite '''Docker Compose'''. Sulla base di un file <code>docker-compose.yml</code> strutturato ad hoc, la cartella di lavoro del server Luanti/Minetest è stata mappata in locale sul PC dell'utente (tramite i Docker Volumes) per permettere la modifica in tempo reale dei file di gioco. All'interno della configurazione, il mondo è stato battezzato <code>ledro3d</code> e l'utente <code>mattruffoni</code> è stato designato come amministratore di sistema con massimi privilegi energetici.<syntaxhighlight lang="dockerfile">
services:
luanti_engine:
image: lscr.io/linuxserver/luanti:latest
container_name: local_luanti_engine
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Rome
# FORZATURA: Diciamo a Luanti esattamente quale file .conf leggere dentro il container
- CLI_ARGS=--worldname ledro3d --config /config/.minetest/minetest.conf --terminal
volumes:
- ./server_data:/config/.minetest
ports:
- 30000:30000/udp
restart: unless-stopped
</syntaxhighlight>
==== 9. Accessibilità del Server di Gioco ====
Una volta avviato lo stack di Docker tramite terminale (<code>docker compose up -d</code>), il container ha esposto i servizi di rete dedicati. Il server Luanti/Minetest è diventato operativo e raggiungibile in locale dall'indirizzo di loopback '''<code>localhost:30000</code>''', pronto ad accettare le connessioni da parte del client di gioco per l'esplorazione virtuale.
=== Fase 3: Sviluppo della Mod e Generazione del Mondo ===
====Creazione mod '''importatore'''====
Nella cartella ''.../minetest-server/server_data/worlds/ledro3d/worldmods/importatore'' si crea la mod importatore inserendoci il file init.lua, mod.conf e i due file di testo ledro_terreno_dati.txt e ledro_case_dati.txt creati in precedenza.
==== 10. Sviluppo della Mod Lua Asincrona "Importatore" ====
L'iniezione di milioni di nodi all'interno del database del mondo (<code>map.sqlite</code>) presenta forti criticità prestazionali (rischio di timeout UDP e crash per memoria satura). Per ovviare a questo problema, è stata sviluppata una mod personalizzata in linguaggio Lua denominata '''<code>importatore</code>'''. La mod implementa due soluzioni architetturali cruciali:
# '''Il VoxelManip Engine (LVM):''' Invece di posizionare un singolo cubo alla volta, la mod alloca grandi porzioni di mappa direttamente nella memoria volatile del server, scrive i blocchi di erba superficiale (<code>default:dirt_with_grass</code>) e le fondamenta sottostanti (<code>default:stone</code>), e forza la scrittura in blocco sul database, azzerando i warning di blocchi non trovati.
# '''Gestione tramite Co-routine Lua:''' La lettura dei file <code>.txt</code> è inserita in un ciclo asincrono controllato da co-routine. Tramite l'istruzione <code>coroutine.yield()</code>, la mod rilascia il controllo alla CPU del PC host ogni 100 nodi processati, permettendo al server di rimanere fluido, gestire i pacchetti di rete e consentire il movimento del giocatore durante la crescita progressiva della valle.
==== Fase 2: Iniezione Asincrona nella Mappa (Luanti Mod) ====
La mod Luanti (scritta in `init.lua`) riceve il file a griglia regolare e applica due strategie fondamentali per garantire stabilità e performance:
* '''Uso del VoxelManip (LVM):''' Invece di scrivere un blocco alla volta, la mod alloca un'area di memoria temporanea (`minetest.get_voxel_manip()`), manipola l'array dei nodi inserendo la superficie erbosa (`default:dirt_with_grass`) e lo zoccolo di roccia sottostante (`default:stone`), e infine forza la scrittura dell'intero blocco direttamente sul database (`vm:write_to_map()`). Questo bypassa i controlli dei metadati azzerando il warning ''Block not found''.
* '''Gestione Asincrona via Co-routine:''' Il ciclo di lettura del file viene inserito in una co-routine Lua (`coroutine.create`). Tramite l'istruzione `coroutine.yield()`, la mod rilascia il controllo alla CPU ogni 100 nodi processati, permettendo al server Luanti di gestire i pacchetti di rete, l'orario del mondo e il login dei giocatori senza lag.
==== Codice init.lua della mod importatore====
<syntaxhighlight lang="lua">
-- ========================================================
-- 1. PRIVILEGI AUTOMATICI PER MATTRUFFONI (CON SETTIME)
-- ========================================================
minetest.register_on_joinplayer(function(player)
local name = player:get_player_name()
if name == "mattruffoni" then
minetest.after(0.5, function()
local p = minetest.get_player_by_name(name)
if p then
local privs = minetest.get_player_privs(name)
privs.privs = true
privs.fly = true
privs.fast = true
privs.teleport = true
privs.interact = true
privs.shout = true
privs.settime = true -- Aggiunto privilegio per impostare l'ora
privs.time = true -- Aggiunto privilegio per gestire il tempo
minetest.set_player_privs(name, privs)
minetest.chat_send_player(name, "Benvenuto Prof! Privilegi completi (incluso settime) attivati.")
end
end)
end
end)
-- ========================================================
-- 2. PIPELINE DI IMPORTAZIONE A GRIGLIA ORDINATA (LVM)
-- ========================================================
local function avvia_importazione_superficie()
local percorso_terreno = minetest.get_modpath("importatore") .. "/ledro_terreno_dati.txt"
local percorso_case = minetest.get_modpath("importatore") .. "/ledro_case_dati.txt"
local thread = coroutine.create(function()
-- A. TERRENO (Morfologia a celle raccordate)
local file_t = io.open(percorso_terreno, "r")
if file_t then
minetest.log("action", "[Importatore] Scrittura griglia terreno georeferenziato...")
local count = 0
for line in file_t:lines() do
local x, y, z = line:match("([^,]+),([^,]+),([^,]+)")
if x and y and z then
local tx, ty, tz = tonumber(x), tonumber(y), tonumber(z)
-- Raggio 2 crea una piastra 5x5 attorno a ogni punto.
-- Avendo ordinato il file a passo 2, le piastre si fondono perfettamente.
local raggio = 2
-- Allochiamo l'area minima per il manipolatore di voxel
local p_min = {x = tx - raggio, y = ty - 15, z = tz - raggio}
local p_max = {x = tx + raggio, y = ty, z = tz + raggio}
local vm = minetest.get_voxel_manip()
local emin, emax = vm:read_from_map(p_min, p_max)
local data = vm:get_data()
local va = VoxelArea:new{MinEdge = emin, MaxEdge = emax}
local c_grass = minetest.get_content_id("default:dirt_with_grass")
local c_stone = minetest.get_content_id("default:stone")
-- Disegniamo la piastra locale
for dx = -raggio, raggio do
for dz = -raggio, raggio do
local px = tx + dx
local pz = tz + dz
-- Blocco d'erba superficiale
local vi_g = va:index(px, ty, pz)
data[vi_g] = c_grass
-- Zoccolo di pietra sottostante (15 blocchi per saldare i dislivelli)
for dy = 1, 15 do
local vi_s = va:index(px, ty - dy, pz)
data[vi_s] = c_stone
end
end
end
-- Scrittura forzata nel database senza controlli intermedi
vm:set_data(data)
vm:write_to_map()
count = count + 1
-- Rilasciamo la CPU ogni 100 punti della griglia per mantenere stabile il server
if count % 100 == 0 then
minetest.log("action", "[Importatore] Punti griglia terreno consolidati: " .. count)
coroutine.yield()
end
end
end
file_t:close()
end
-- B. CASE (Puntuali sopra il terreno)
local file_c = io.open(percorso_case, "r")
if file_c then
minetest.log("action", "[Importatore] Iniezione volumi edifici...")
local count = 0
for line in file_c:lines() do
local x, y, z, blockname = line:match("([^,]+),([^,]+),([^,]+),([^,]+)")
if x and y and z and blockname then
local pos = {x = tonumber(x), y = tonumber(y), z = tonumber(z)}
blockname = blockname:gsub("%s+", "")
local vm = minetest.get_voxel_manip()
vm:read_from_map(pos, pos)
minetest.set_node(pos, {name = blockname})
count = count + 1
if count % 2000 == 0 then
minetest.log("action", "[Importatore] Blocchi edificio inseriti: " .. count)
coroutine.yield()
end
end
end
file_c:close()
end
minetest.log("action", "[Importatore] PIPELINE COMPLETATA CON SUCCESSO!")
minetest.chat_send_all("[Importatore] PIPELINE COMPLETATA! La Val di Ledro a griglia è pronta.")
end)
local function esegui_passo()
if coroutine.status(thread) ~= "dead" then
coroutine.resume(thread)
minetest.after(0.02, esegui_passo)
end
end
esegui_passo()
end
-- ========================================================
-- 3. ATTIVAZIONE EVENTO AL LOGIN DI MATTRUFFONI
-- ========================================================
local attivato = false
minetest.register_on_joinplayer(function(player)
if player:get_player_name() == "mattruffoni" and not attivato then
attivato = true
minetest.after(3.0, function()
minetest.chat_send_all("[Importatore] Avvio rigenerazione morfologica a griglia fitta...")
avvia_importazione_superficie()
end)
end
end)
</syntaxhighlight>
=====Codice mod.conf=====
<syntaxhighlight lang="lua">
name = importatore
description = Importatore geometrico per la Val di Ledro
</syntaxhighlight>
=== Risultati e Sviluppi Pedagogici ===
L'applicazione di questo flusso permette di generare manti continui di milioni di blocchi mantenendo il server Docker estremamente leggero. Questo ambiente offre uno scenario di apprendimento eccezionale per la didattica laboratoriale (Matematica e Scienze), permettendo agli studenti di esplorare modelli in scala 1:1 del proprio territorio, comprendere l'interazione tra coordinate cartesiane e dati GIS, e interagire con elementi di programmazione e gestione server.
=== Note ===
Ovviamente tutto è stato sviluppato con AI, nello specifico Gemini.
=== Bibliografia ===
=== Collegamenti esterni ===
[[Categoria:Software libero a scuola|Luanti a scuola]]
150cot3vvbt5ig6527c2dubm7sntv3f
Disposizioni foniche di organi a canne/Italia/Abruzzo/Provincia di Chieti/Vasto/Vasto - Chiesa di San Francesco di Paola
0
60960
501042
501038
2026-08-19T19:27:23Z
VoceUmana7
51633
501042
wikitext
text/x-wiki
{{disposizioni foniche di organi a canne}}
* '''Costruttore:''' Fratelli Ciavarelli
* '''Anno:''' prima metà del sec. XIX
* '''Restauri/modifiche:''' anonimo (manutenzione, 1885), R. Palma (installazione dell'elettroventilatore, sec. XX)
* '''Registri:''' 7
* '''Canne:''' ca. 330
* '''Trasmissione:''' meccanica
* '''Consolle:''' a finestra
* '''Tastiere:''' 1 di 50 note con la prima ottava scavezza (''Do<sup>1</sup>''-''Fa<sup>5</sup>'')
* '''Pedaliera:''' scavezza a leggio di 9 note (''Do<sup>1</sup>''-''Do<sup>2</sup>'') costantemente unita alla tastiera
*'''Accessori:''' Tiratutti a pomello
* '''Collocazione:''' a pavimento nel presbiterio
{| border="0" cellspacing="0" cellpadding="20" style="border-collapse:collapse;"
| style="vertical-align:top" |
{| border="0"
| colspan=2 | '''Colonna di sinistra - ''Ripieno'''''
----
|-
|Principale
|-
|Ottava
|-
|Decima quinta
|-
|Decima nona
|-
|Vigesima seconda
|-
|}
| style="vertical-align:top" |
{| border="0"
| colspan=2 | '''Colonna di destra - ''Concerto'''''
----
|-
|Flauto in VIII
|-
|Voce umana<ref>dal ''Do<sup>3</sup>''</ref>
|-
|}
|}
== Note ==
<references/>
{{Avanzamento|100%|18 agosto 2026}}
[[Categoria:Disposizioni foniche di organi a canne]]
qfjlalxb1dtngbczs431d49zaeucbbc
Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Buscemi
0
60963
501044
501022
2026-08-19T21:47:54Z
~2026-45474-98
54699
501044
wikitext
text/x-wiki
{{Disposizioni foniche di organi a canne}}
Disposizioni foniche del comune di [[w:Buscemi|Buscemi]] raggruppate per edificio.
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Buscemi/Buscemi - Chiesa di Sant'Antonio|Chiesa di Sant'Antonio]]
ewwzc4qphtcvy7obgtxcce5dskyar9z
501046
501044
2026-08-19T21:58:00Z
~2026-45474-98
54699
501046
wikitext
text/x-wiki
{{Disposizioni foniche di organi a canne}}
Disposizioni foniche del comune di [[w:Buscemi|Buscemi]] raggruppate per edificio.
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Buscemi/Buscemi - Chiesa di Sant'Antonio|Chiesa di Sant'Antonio]]
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Buscemi/Buscemi - Chiesa Madre - Natività di Maria Santissima|Chiesa Madre - Natività di Maria Santissima]]
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Buscemi/Buscemi - Chiesa di San Sebastiano|Chiesa di San Sebastiano]]
djom83t9bpwzf50u33z0yc7hopclzt3
Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Buscemi/Buscemi - Chiesa di Sant'Antonio
0
60964
501049
501026
2026-08-19T22:00:56Z
~2026-45474-98
54699
501049
wikitext
text/x-wiki
{{disposizioni foniche di organi a canne}}
* '''Costruttore:''' Donato del Piano
* '''Anno:'''
* '''Restauri:'''
* '''Registri:''' 11
* '''Canne:'''
* '''Trasmissione:''' meccanica
* '''Consolle:''' a finestra
* '''Tastiere:''' 1 di 45 tasti (''Do<sup>1</sup>''-''Do<sup>5</sup>''), con prima ottava corta
* '''Pedaliera:''' di 12 note ((''Do<sup>1</sup>''-''Si<sup>1</sup>''))
* '''Collocazione:'''
* '''Accessori:'''
* '''Note:'''
{| border="0" cellspacing="0" cellpadding="20" style="border-collapse:collapse;"
| style="vertical-align:top" |
| style="vertical-align:top" |
{| border="0"
| colspan=2 |
|-
|Principale I
|-
|Principale II
|-
|Ottava
|-
|Decimaquinta
|-
|Decimanona
|-
|Vigesimaseconda
|-
|Vigesimasesta
|-
|Vigesimanona
|-
|
|-
|
|-
|
|-
|}
| style="vertical-align:top" |
{| border="0"
| colspan=2 |
|-
|Voce Umana
|-
|Flauto in ottava
|-
|Flauto in XII
|-
|}
|}
eoxgolm7lbtqgz4wim2a2nv4h1nhtvq
Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Canicattini Bagni/Canicattini Bagni- Chiesa Madre
0
60970
501045
2026-08-19T21:50:48Z
~2026-45474-98
54699
Nuova pagina: {{disposizioni foniche di organi a canne}} * '''Costruttore:''' * '''Anno:''' * '''Restauri:''' * '''Registri:''' * '''Canne:''' * '''Trasmissione:''' * '''Consolle:''' * '''Tastiere:''' 1 di 45 tasti (''Do<sup>1</sup>''-''Do<sup>5</sup>''), con prima ottava corta * '''Pedaliera:''' di 12 note ((''Do<sup>1</sup>''-''Si<sup>1</sup>'')) * '''Collocazione:''' navata centrale destra nell'intercolunnio * '''Accessori:''' * '''Note:'''
501045
wikitext
text/x-wiki
{{disposizioni foniche di organi a canne}}
* '''Costruttore:'''
* '''Anno:'''
* '''Restauri:'''
* '''Registri:'''
* '''Canne:'''
* '''Trasmissione:'''
* '''Consolle:'''
* '''Tastiere:''' 1 di 45 tasti (''Do<sup>1</sup>''-''Do<sup>5</sup>''), con prima ottava corta
* '''Pedaliera:''' di 12 note ((''Do<sup>1</sup>''-''Si<sup>1</sup>''))
* '''Collocazione:''' navata centrale destra nell'intercolunnio
* '''Accessori:'''
* '''Note:'''
cknfhafghzvlhkgy5gq9e5odx3mll30
501050
501045
2026-08-19T22:01:52Z
~2026-45474-98
54699
501050
wikitext
text/x-wiki
{{disposizioni foniche di organi a canne}}
* '''Costruttore:'''
* '''Anno:'''
* '''Restauri:'''
* '''Registri:'''
* '''Canne:'''
* '''Trasmissione:'''
* '''Consolle:'''
* '''Tastiere:''' 1 di 45 tasti (''Do<sup>1</sup>''-''Do<sup>5</sup>''), con prima ottava corta
* '''Pedaliera:''' di 12 note ((''Do<sup>1</sup>''-''Si<sup>1</sup>''))
* '''Collocazione:''' navata centrale nell'intercolunnio destro
* '''Accessori:'''
* '''Note:'''
rkttzeu0tyhz09oimsa4v2uluva8pl3
Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Buscemi/Buscemi - Chiesa Madre - Natività di Maria Santissima
0
60971
501047
2026-08-19T21:59:22Z
~2026-45474-98
54699
Nuova pagina: {{disposizioni foniche di organi a canne}} * '''Costruttore:''' Donato del Piano * '''Anno:''' * '''Restauri:''' * '''Registri:''' * '''Canne:''' * '''Trasmissione:''' * '''Consolle:''' * '''Tastiere:''' 1 di 45 tasti (''Do<sup>1</sup>''-''Do<sup>5</sup>''), con prima ottava corta * '''Pedaliera:''' di 12 note ((''Do<sup>1</sup>''-''Si<sup>1</sup>'')) * '''Collocazione:''' in cantoria in controfacciata * '''Accessori:''' * '''Note:'''
501047
wikitext
text/x-wiki
{{disposizioni foniche di organi a canne}}
* '''Costruttore:''' Donato del Piano
* '''Anno:'''
* '''Restauri:'''
* '''Registri:'''
* '''Canne:'''
* '''Trasmissione:'''
* '''Consolle:'''
* '''Tastiere:''' 1 di 45 tasti (''Do<sup>1</sup>''-''Do<sup>5</sup>''), con prima ottava corta
* '''Pedaliera:''' di 12 note ((''Do<sup>1</sup>''-''Si<sup>1</sup>''))
* '''Collocazione:''' in cantoria in controfacciata
* '''Accessori:'''
* '''Note:'''
g9av4x9j1xbloydqm5w5ixpnvtcggec
501048
501047
2026-08-19T22:00:02Z
~2026-45474-98
54699
501048
wikitext
text/x-wiki
{{disposizioni foniche di organi a canne}}
* '''Costruttore:''' Donato del Piano
* '''Anno:'''
* '''Restauri:'''
* '''Registri:'''
* '''Canne:'''
* '''Trasmissione:'''
* '''Consolle:'''
* '''Tastiere:''' 1 di 45 tasti (''Do<sup>1</sup>''-''Do<sup>5</sup>''), con prima ottava corta
* '''Pedaliera:''' di 12 note ((''Do<sup>1</sup>''-''Si<sup>1</sup>''))
* '''Collocazione:''' in cantoria in controfacciata
* '''Accessori:'''
* '''Note:''' attualmente in fase di restauro
0sri1kw8ieac79i0mt7nk6wl0j94ux8
Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Melilli
0
60972
501051
2026-08-19T22:04:49Z
~2026-45474-98
54699
Nuova pagina: * [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Melilli/Melilli- Basilica di San Sebastiano|Basilica di San Sebastiano]]
501051
wikitext
text/x-wiki
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Melilli/Melilli- Basilica di San Sebastiano|Basilica di San Sebastiano]]
blky3adwch3kuh95dv81l8twcddg7vv
501052
501051
2026-08-19T22:05:59Z
~2026-45474-98
54699
501052
wikitext
text/x-wiki
{{Disposizioni foniche di organi a canne}}
Disposizioni foniche del comune di [[w:Melilli|Melilli]] raggruppate per edificio.
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Melilli/Melilli- Basilica di San Sebastiano|Basilica di San Sebastiano]]
35eewpgeqafoqruot4br5qkercnzzge
Software libero a scuola/Pdf/PDFedit
0
60973
501053
2026-08-19T22:06:27Z
~2026-45514-04
54704
I found this useful pdf tool with 106 free tools
501053
wikitext
text/x-wiki
[https://allpdflove.com/en/ AllPDFLove] is an online PDF platform designed to make everyday document tasks faster and easier. Its collection of tools helps users '''convert, merge, split, compress, edit, and manage PDF files''' directly from a web browser without complicated software. Whether you need to turn a PDF into an editable document, reduce file size, extract pages, or work with different document formats, AllPDFLove brings essential PDF utilities together in one convenient place.
The tools are built for simple, practical workflows, making them suitable for students, professionals, businesses, and anyone who regularly works with digital documents.
7zgy68m19a9gj48tib65lach3fewh1z
Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Floridia
0
60974
501056
2026-08-19T22:13:49Z
~2026-45474-98
54699
Nuova pagina: {{Disposizioni foniche di organi a canne}} Disposizioni foniche del comune di [[w:Floridia|Floridia]] raggruppate per edificio. * [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Floridia/Floridia- Chiesa Madre|Chiesa Madre]] * [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Floridia/Floridia- Chiesa della Madonna del Carmine|Chiesa della Madonna del Carmine]] * Disposizioni foniche d...
501056
wikitext
text/x-wiki
{{Disposizioni foniche di organi a canne}}
Disposizioni foniche del comune di [[w:Floridia|Floridia]] raggruppate per edificio.
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Floridia/Floridia- Chiesa Madre|Chiesa Madre]]
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Floridia/Floridia- Chiesa della Madonna del Carmine|Chiesa della Madonna del Carmine]]
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Floridia/Floridia- Chiesa di Sant'Anna|Chiesa di Sant'Anna]]
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Floridia/Floridia- Chiesa di Sant'Antonio|Chiesa di Sant'Antonio]]
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Floridia/Floridia- Chiesa di San Francesco D'Assisi|Chiesa di San Francesco D'Assisi]]
gw6j1v5it88zs6b2ceh5rb0mbsktmci
Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Sortino
0
60975
501057
2026-08-19T22:18:35Z
~2026-45474-98
54699
Nuova pagina: {{Disposizioni foniche di organi a canne}} Disposizioni foniche del comune di [[w:Sortino|Sortino]] raggruppate per edificio. * [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Sortino/Sortino- Chiesa Madre di San Giovanni Apostolo ed Evangelista|Chiesa Madre di San Giovanni Apostolo ed Evangelista]]
501057
wikitext
text/x-wiki
{{Disposizioni foniche di organi a canne}}
Disposizioni foniche del comune di [[w:Sortino|Sortino]] raggruppate per edificio.
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Sortino/Sortino- Chiesa Madre di San Giovanni Apostolo ed Evangelista|Chiesa Madre di San Giovanni Apostolo ed Evangelista]]
9sim6554li9rkspcka42thz8peutbcs
Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Pachino
0
60976
501059
2026-08-19T22:23:34Z
~2026-45474-98
54699
Nuova pagina: {{Disposizioni foniche di organi a canne}} Disposizioni foniche del comune di [[w:Pachino|Pachino]] raggruppate per edificio. * [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Pachino/Pachino- Chiesa Madre del Santissimo Crocifisso|Chiesa Madre del Santissimo Crocifisso]]
501059
wikitext
text/x-wiki
{{Disposizioni foniche di organi a canne}}
Disposizioni foniche del comune di [[w:Pachino|Pachino]] raggruppate per edificio.
* [[Disposizioni foniche di organi a canne/Italia/Sicilia/Libero consorzio comunale di Siracusa/Pachino/Pachino- Chiesa Madre del Santissimo Crocifisso|Chiesa Madre del Santissimo Crocifisso]]
ebt412k0p4ox52r40p8srt0mx8iyowe