Lua Voxel Manipulators - Italian translation added

This commit is contained in:
Marco 2020-07-11 17:20:02 +02:00 committed by rubenwardy
parent 90787e574a
commit 39d9777bb6

181
_it/advmap/lvm.md Normal file → Executable file
View File

@ -1,77 +1,67 @@
--- ---
title: Lua Voxel Manipulators title: Manipolatori di voxel Lua
layout: default layout: default
root: ../.. root: ../..
idx: 6.2 idx: 6.2
description: Learn how to use LVMs to speed up map operations. description: Impara come usare gli LVM per accelerare le operazioni nella mappa.
redirect_from: redirect_from:
- /en/chapters/lvm.html - /it/chapters/lvm.html
- /en/map/lvm.html - /it/map/lvm.html
mapgen_object: mapgen_object:
level: warning level: warning
title: LVMs and Mapgen title: LVM e generatore mappa
message: Don't use `minetest.get_voxel_manip()` with mapgen, as it can cause glitches. message: Non usare `minetest.get_voxel_manip()` con il generatore mappa, in quanto può causare glitch.
Use `minetest.get_mapgen_object("voxelmanip")` instead. Usa invece `minetest.get_mapgen_object("voxelmanip")`.
--- ---
## Introduction <!-- omit in toc --> ## Introduzione <!-- omit in toc -->
The functions outlined in the [Basic Map Operations](environment.html) chapter Le funzioni introdotte nel capitolo [Mappa: operazioni base](environment.html) sono comode e facili da usare, ma per le grandi aree non sono efficienti.
are convenient and easy to use, but for large areas they are inefficient. Ogni volta che `set_node` e `get_node` vengono chiamati da una mod, la mod deve comunicare con il motore di gioco.
Every time you call `set_node` or `get_node`, your mod needs to communicate with Ciò risulta in una costante copia individuale dei singoli nodi, che è lenta e abbasserà notevolmente le performance del gioco.
the engine. This results in constant individual copying operations between the Usare un Manipolatore di Voxel Lua (*Lua Voxel Manipulator*, da qui LVM) può essere un'alternativa migliore.
engine and your mod, which is slow and will quickly decrease the performance of - [Concetti](#concetti)
your game. Using a Lua Voxel Manipulator (LVM) can be a better alternative. - [Lettura negli LVM](#lettura-negli-lvm)
- [Lettura dei nodi](#lettura-dei-nodi)
- [Scrittura dei nodi](#scrittura-dei-nodi)
- [Esempio](#esempio)
- [Il tuo turno](#il-tuo-turno)
- [Concepts](#concepts) ## Concetti
- [Reading into the LVM](#reading-into-the-lvm)
- [Reading Nodes](#reading-nodes)
- [Writing Nodes](#writing-nodes)
- [Example](#example)
- [Your Turn](#your-turn)
## Concepts Un LVM permette di caricare grandi pezzi di mappa nella memoria della mod che ne ha bisogno.
Da lì si possono leggere e modificare i dati immagazzinati senza dover interagire ulteriormente col motore di gioco, e senza eseguire callback; in altre parole, l'operazione risulta molto più veloce.
Una volta fatto ciò, si può passare l'area modificata al motore di gioco ed eseguire eventuali calcoli riguardo la luce.
An LVM allows you to load large areas of the map into your mod's memory. ## Lettura negli LVM
You can then read and write this data without further interaction with the
engine and without running any callbacks, which means that these
operations are very fast. Once done, you can then write the area back into
the engine and run any lighting calculations.
## Reading into the LVM Si possono caricare solamente aree cubiche negli LVM, quindi devi capire da te quali sono le posizioni minime e massime che ti servono per l'area da modificare.
Fatto ciò, puoi creare l'LVM:
You can only load a cubic area into an LVM, so you need to work out the minimum
and maximum positions that you need to modify. Then you can create and read into
an LVM. For example:
```lua ```lua
local vm = minetest.get_voxel_manip() local vm = minetest.get_voxel_manip()
local emin, emax = vm:read_from_map(pos1, pos2) local emin, emax = vm:read_from_map(pos1, pos2)
``` ```
For performance reasons, an LVM will almost never read the exact area you tell it to. Per questioni di performance, un LVM non leggerà quasi mai l'area esatta che gli è stata passata.
Instead, it will likely read a larger area. The larger area is given by `emin` and `emax`, Al contrario, è molto probabile che ne leggerà una maggiore. Quest'ultima è data da `emin` ed `emax`, che stanno per posizione minima/massima emersa (*emerged min/max pos*).
which stand for *emerged min pos* and *emerged max pos*. An LVM will load the area Inoltre, un LVM caricherà in automatico l'area passatagli - che sia da memoria, da disco o dal generatore di mappa.
it contains for you - whether that involves loading from memory, from disk, or
calling the map generator.
{% include notice.html notice=page.mapgen_object %} {% include notice.html notice=page.mapgen_object %}
## Reading Nodes ## Lettura dei nodi
To read the types of nodes at particular positions, you'll need to use `get_data()`. Per leggere il tipo dei nodi in posizioni specifiche, avrai bisogno di usare `get_data()`.
This returns a flat array where each entry represents the type of a Questo metodo ritorna un array monodimensionale dove ogni voce rappresenta il tipo.
particular node.
```lua ```lua
local data = vm:get_data() local data = vm:get_data()
``` ```
You can get param2 and lighting data using the methods `get_light_data()` and `get_param2_data()`. Si possono ottenere param2 e i dati della luce usando i metodi `get_light_data()` e `get_param2_data()`.
You'll need to use `emin` and `emax` to work out where a node is in the flat arrays Avrai bisogno di usare `emin` e `emax` per capire dove si trova un nodo nei metodi sopraelencati.
given by the above methods. There's a helper class called `VoxelArea` which handles C'è una classe di supporto per queste cose chiamate `VoxelArea` che gestisce i calcoli al posto tuo.
the calculation for you.
```lua ```lua
local a = VoxelArea:new{ local a = VoxelArea:new{
@ -79,103 +69,91 @@ local a = VoxelArea:new{
MaxEdge = emax MaxEdge = emax
} }
-- Get node's index -- Ottiene l'indice del nodo
local idx = a:index(x, y, z) local idx = a:index(x, y, z)
-- Read node -- Legge il nodo
print(data[idx]) print(data[idx])
``` ```
When you run this, you'll notice that `data[vi]` is an integer. This is because All'eseguire ciò, si noterà che `data[idx]` è un intero.
the engine doesn't store nodes using strings, for performance reasons. Questo perché il motore di gioco non salva i nodi come stringhe per motivi di performance; al contrario, usa un intero chiamato "ID di contenuto" (*content ID*).
Instead, the engine uses an integer called a content ID. Per scoprire qual è l'ID assegnato a un tipo di nodo, si usa `get_content_id()`.
You can find out the content ID for a particular type of node with Per esempio:
`get_content_id()`. For example:
```lua ```lua
local c_stone = minetest.get_content_id("default:stone") local c_pietra = minetest.get_content_id("default:stone")
``` ```
You can then check whether the node is stone: Si può ora controllare se un nodo è effettivamente di pietra:
```lua ```lua
local idx = a:index(x, y, z) local idx = a:index(x, y, z)
if data[idx] == c_stone then if data[idx] == c_pietra then
print("is stone!") print("è pietra!")
end end
``` ```
It is recommended that you find and store the content IDs of nodes types Si consiglia di ottenere e salvare (in una variabile locale) gli ID di contenuto al caricare della mod in quanto questi non possono cambiare.
at load time because the IDs of a node type will never change. Make sure to store
the IDs in a local variable for performance reasons.
Nodes in an LVM data array are stored in reverse co-ordinate order, so you should Le coordinate dei nodi nell'array di un LVM sono salvate in ordine inverso (`z, y, x`), quindi se le si vuole iterare, si tenga presente che si inizierà dalla Z:
always iterate in the order `z, y, x`. For example:
```lua ```lua
for z = min.z, max.z do for z = min.z, max.z do
for y = min.y, max.y do for y = min.y, max.y do
for x = min.x, max.x do for x = min.x, max.x do
-- vi, voxel index, is a common variable name here local idx = a:index(x, y, z)
local vi = a:index(x, y, z) if data[idx] == c_pietra then
if data[vi] == c_stone then print("è pietra!")
print("is stone!")
end end
end end
end end
end end
``` ```
The reason for this touches on the topic of computer architecture. Reading from RAM is rather Per capire la ragione di tale iterazione, bisogna parlare un attimo di architettura dei computer: leggere dalla RAM - la memoria principale - è alquanto dispendioso, quindi i processori hanno molteplici livelli di memoria a breve termine (la *cache*).
costly, so CPUs have multiple levels of caching. If the data that a process requests Se i dati richiesti da un processo sono in quest'ultima memoria, si possono ottenere velocemente.
is in the cache, it can very quickly retrieve it. If the data is not in the cache, Al contrario, se i dati lì non ci sono, verranno pescati dalla RAM *e* inseriti in quella a breve termine, nel caso dovessero servire di nuovo.
then a cache miss occurs and it will fetch the data it needs from RAM. Any data Questo significa che una buona regola per l'ottimizzazione è quella di iterare in modo che i dati vengano letti in sequenza, evitando di arrivare fino alla RAM ogni volta (*cache thrashing*).
surrounding the requested data is also fetched and then replaces the data in the cache. This is
because it's quite likely that the process will ask for data near that location again. This means
a good rule of optimisation is to iterate in a way that you read data one after
another, and avoid *cache thrashing*.
## Writing Nodes ## Scrittura dei nodi
First, you need to set the new content ID in the data array: Prima di tutto, bisogna impostare il nuovo ID nell'array:
```lua ```lua
for z = min.z, max.z do for z = min.z, max.z do
for y = min.y, max.y do for y = min.y, max.y do
for x = min.x, max.x do for x = min.x, max.x do
local vi = a:index(x, y, z) local idx = a:index(x, y, z)
if data[vi] == c_stone then if data[idx] == c_pietra then
data[vi] = c_air data[idx] = c_aria
end end
end end
end end
end end
``` ```
When you finish setting nodes in the LVM, you then need to upload the data Una volta finito con le operazioni nell'LVM, bisogna passare l'array al motore di gioco:
array to the engine:
```lua ```lua
vm:set_data(data) vm:set_data(data)
vm:write_to_map(true) vm:write_to_map(true)
``` ```
For setting lighting and param2 data, use the appropriately named Per la luce e param2, invece si usano `set_light_data()` e `set_param2_data()`.
`set_light_data()` and `set_param2_data()` methods.
`write_to_map()` takes a Boolean which is true if you want lighting to be `write_to_map()` richiede un booleano che è `true` se si vuole che venga calcolata anche la luce.
calculated. If you pass false, you need to recalculate lighting at a future Se si passa `false` invece, ci sarà bisogno di ricalcolarla in un secondo tempo usando `minetest.fix_light`.
time using `minetest.fix_light`.
## Example ## Esempio
```lua ```lua
-- Get content IDs during load time, and store into a local -- ottiene l'ID di contenuto al caricare della mod, salvandolo in variabili locali
local c_dirt = minetest.get_content_id("default:dirt") local c_terra = minetest.get_content_id("default:dirt")
local c_grass = minetest.get_content_id("default:dirt_with_grass") local c_erba = minetest.get_content_id("default:dirt_with_grass")
local function grass_to_dirt(pos1, pos2) local function da_erba_a_terra(pos1, pos2)
-- Read data into LVM -- legge i dati nella LVM
local vm = minetest.get_voxel_manip() local vm = minetest.get_voxel_manip()
local emin, emax = vm:read_from_map(pos1, pos2) local emin, emax = vm:read_from_map(pos1, pos2)
local a = VoxelArea:new{ local a = VoxelArea:new{
@ -184,30 +162,27 @@ local function grass_to_dirt(pos1, pos2)
} }
local data = vm:get_data() local data = vm:get_data()
-- Modify data -- modifica i dati
for z = pos1.z, pos2.z do for z = pos1.z, pos2.z do
for y = pos1.y, pos2.y do for y = pos1.y, pos2.y do
for x = pos1.x, pos2.x do for x = pos1.x, pos2.x do
local vi = a:index(x, y, z) local idx = a:index(x, y, z)
if data[vi] == c_grass then if data[idx] == c_erba then
data[vi] = c_dirt data[idx] = c_terra
end end
end end
end end
end end
-- Write data -- scrive i dati
vm:set_data(data) vm:set_data(data)
vm:write_to_map(true) vm:write_to_map(true)
end end
``` ```
## Your Turn ## Il tuo turno
* Create `replace_in_area(from, to, pos1, pos2)`, which replaces all instances of * Crea una funzione `rimpiazza_in_area(da, a, pos1, pos2)`, che sostituisce tutte le istanze di `da` con `a` nell'area data, dove `da` e `a` sono i nomi dei nodi;
`from` with `to` in the area given, where `from` and `to` are node names. * Crea una funzione che ruota tutte le casse di 90&deg;;
* Make a function which rotates all chest nodes by 90&deg;. * Crea una funzione che usa un LVM per far espandere i nodi di muschio sui nodi di pietra e pietrisco confinanti.
* Make a function which uses an LVM to cause mossy cobble to spread to nearby La tua implementazione fa espandere il muschio di più di un blocco alla volta? Se sì, come puoi prevenire ciò?
stone and cobble nodes.
Does your implementation cause mossy cobble to spread more than a distance of one node each
time? If so, how could you stop this?