Come passare da una dinette rotta ad una “funzionale”

Partiamo con la foto della mia dinette prima della modifica:

dinette rotta
dinette rotta

purtroppo chi prima di me aveva utilizzato il camper non era stato molto attento e con qualche pedata di troppo il sottile strato di legno ha ceduto, creando un bel buco; siccome per altri motivi mi trovavo con una presa da accendisigari + 2 usb, ho pensato di inserirla proprio in quello spazio

spessore per presa usb
spessore per presa usb

Con un po’ di legno ho creato degli spessori da utilizzare per far mantenere le viti della presa, dato che è davvero sottile e non resistente se lasciato così com’è.

primo test dopo il montaggio
primo test dopo il montaggio

Fortunatamente sono riuscito a coprire completamente il buco creatosi nella dinette, senza lasciare traccia di quello che c’era! Il cablaggio è stato molto semplice, sia l’accendisigari che le 2 prese USB hanno bisogno di due cavi provenienti dai due poli della batteria, nient’altro.

cablaggio interno
cablaggio interno

I cavi che si vedono sono stati fissati lato adattatore con 4 morsetti e dall’altra parte fissati con un mammut su un cavo sotto tensione solo quando viene azionato il pulsante nella “centralina” luci del camper, in questo modo quando spengo le luci interne sono sicuro di aver spento tutto, anche la luce blu del led delle 2 prese USB.

luce blue del LED
luce blue del LED

Alla prossima.

Oscuranti in PVC – parte 2

Eccoci qui, ormai è stato montato già da un po’ ed ho avuto modo di testarlo per bene; funziona! Qui sotto una foto dopo aver cucito col nylon la parte inferiore dove è presente un’asta inserita in una piccola asola ed averlo inserito nella parte metallica della base

oscurante pvc stampa latex

Qui invece una foto a montaggio finito, l’effetto è veramente carino e probabilmente meglio di come me lo immaginavo! La parte posteriore, come si può vedere dal primo post, non ha la parte riflettente argentata, ma per ora sembra non dare particolari problemi questa differenza.

portal window pvc

Alla prossima.

Oscuranti in PVC per gli oblò del camper

Questo è un post un po’ insolito ma ormai mi sono fatto prendere dal mio camper e sto iniziando a “fixare” le cose che mi capitano a tiro, in questo caso si tratta degli oscuranti degli oblò che, logorati dopo tanti anni di onorato servizio, hanno deciso di smettere di funzionare, aprendosi solo fino a metà.

Il primo passo per sistemarli è stato quello di smontarli, ovviamente.

oscurante oblo camper

Il materiale utilizzato è un semplice PVC e sul retro ha una pellicola riflettente. Lavorando in un’azienda di stampa digitale (multigrafica.net) trovare il materiale necessario è stato facile, la parte difficile è stata decidere se sostituire la stampa con un pezzo bianco oppure farci stampare sopra qualcosa… Ad un certo punto l’illuminazione! Creare qualcosa a tema su Portal! Trovata l’immagine e sistemata per creare un file adatto alla stampa con le mie rudimentali conoscenze di Photoshop sono sceso a vedere il risultato…

portal sign

Grazie alla stampa latex ho potuto toccare subito con mano e vedere il risultato; non male come inizio! Ed ecco una foto con la stampa completata e pronta per essere rifilata, cucita e montata!

stampa su latex portal

Come direbbe GLaDOS: “I’m making a note here: HUGE SUCCESS

Nel prossimo post vedremo la parte relativa al montaggio.

Alla prossima.

Window Functions e partizione dei dati

Una delle caratteristiche più utili e che ho scoperto solo poco tempo fa di PostgreSQL è la capacità di effettuare query di aggregazione su una partizione del set di ritorno, evitando la limitazione di ritornare un solo valore per volta.

Con una classica query di media dello stipendio ordinata per dipartimento, ad esempio, il dato ritornato sarebbe univoco, dettato dalla clausola di group by. Utilizzando una window function (anche detta impropriamente over function per via della sintassi utilizzata nella query) è possibile avere una situazione dove:

  depname  | empno | salary |          avg          
-----------+-------+--------+-----------------------
 develop   |    11 |   5200 | 5020.0000000000000000
 develop   |     7 |   4200 | 5020.0000000000000000
 develop   |     9 |   4500 | 5020.0000000000000000
 develop   |     8 |   6000 | 5020.0000000000000000
 develop   |    10 |   5200 | 5020.0000000000000000
 personnel |     5 |   3500 | 3700.0000000000000000
 personnel |     2 |   3900 | 3700.0000000000000000
 sales     |     3 |   4800 | 4866.6666666666666667
 sales     |     1 |   5000 | 4866.6666666666666667
 sales     |     4 |   4800 | 4866.6666666666666667
(10 rows)

la colonna avg è una funzione di aggregazione che in questo caso ritorna la media per dipartimento dello stipendio, ma vediamo come lavora:

SELECT depname, empno, salary, avg(salary) OVER (PARTITION BY depname) FROM empsalary;

come si può facilmente intuire, avg(salary) è la nostra funzione, ma non viene eseguita su tutto il set di ritorno, ma solo sulla sua partizione per dipartimento.

La mia necessità di una window function nasce da un mio progetto, in cui salvo, catalogati per data e dominio i link che trovo e la loro posizione nel motore di ricerca a seconda di alcune parole chiave (una sorta di log dell’indicizzazione). Nel mio caso specifico, mi sono trovato con più link nello stesso giorno/dominio, ma ero interessato solo al link con la posizione più bassa (indicizzato meglio).

SELECT *
FROM (SELECT data, dominio, 
url, posizione, 
ROW_NUMBER() OVER (PARTITION BY dominio,data ORDER BY posizione)
FROM t_data
WHERE id_keyword='ID') AS tmp
WHERE tmp.row_number='1'

Come si può vedere, per poter utilizzare la colonna row_number bisogna usare una sub-query e viene effettuata la selezione dei primi risultati del set, ordinati secondo la ORDER BY della sub-query stessa.

Alla prossima.

Filtro Kuwahara howto

Mentre ero alla ricerca di un filtro cel shading per poter trasformare il cube engine in qualcosa di divertente mi sono imbattuto in questo articolo:

https://code.google.com/archive/p/gpuakf/

Si tratta di un semplice effetto, ma più che cel shading genera una distorsione simil-quadro (ora molto di moda, grazie prisma!)

Nonostante non sia quello che cercavo, è stato divertente adattarlo al sorgente e sperimentare. Il codice del cube engine modificato con il supporto agli shader è presente sul mio GitHub, la parte dedicata al filtro Kuwahara si trova qui.

Alla prossima.

Back buffer e shader in opengl

Nel mio ultimo progetto, Adolfish, ho avuto la necessità di utilizzare degli shader per poter creare alcuni livelli, dando un effetto “penombra” al piccolo piranha.

Semplice ed utile allo scopo, ma vediamo come realizzarlo. Ogni texture, quando viene disegnata, subisce l’effetto di uno shader, il più semplice è RGB.frag che non fa altro che copiare il contenuto del singolo pixel della texture nel buffer video.

// RGB.frag
varying vec4 v_color;
varying vec2 v_texCoord;
uniform sampler2D tex0;

void main() {
    gl_FragColor = texture2D(tex0, v_texCoord) * v_color;
}

Per poter realizzare l’effetto che vedete nell’immagine qui sopra ho utilizzato invece tre buffer; due “back buffer” e lo schermo come terzo.

Per prima cosa ho disegnato il background, i nemici, gli effetti particellari ed il nostro caro Adolf sul backbuffer1. Il secondo passo è stato applicare l’effetto dello shader sul backbuffer1 e disegnare sul backbuffer2. Fatto questo, l’ultimo passo è stato disegnare la UI, che non subiva lo shader, ma andava su un livello superiore.

Come funziona? Lo shader in questione è molto semplice, basa la sua logica sulla distanza del pixel da disegnare, dalla posizione di Adolf, in modo da andare ad applicare, se la distaza è inferiore ad un raggio r da noi stabilito, una dissolvenza ad un pixel generato da noi. Passiamo al codice!

Per prima cosa genero un pixel completamente nero.

vec4 shadow = vec4(0.0, 0.0, 0.0, 1.0);

Poi effettuo il calcolo della distanza del pixel che devo disegnare dalla posizione di Adolf.

float dist_pl = distance(gl_FragCoord.xy, vec2(pos_pl_x,pos_pl_y));

Ovviamente i parametri pos_pl_x e pos_pl_y vengono passati come uniform dal programma allo shader. Una volta effettuato il calcolo della distanza, applichiamo la logica di disegno dello shader.

if (dist_pl > r) {
    gl_FragColor = shadow;
} else {
    float dist_pn = dist_pl / r;

    vec4 t = texture(tex0, uv.xy);
    vec4 s = shadow;

    gl_FragColor = (t * (1.0 – dist_pn)) + (shadow * dist_pn);
}

Nel primo ramo del controllo, ci assicuriamo di essere fuori dal raggio, in tal caso basta disegnare un pixel nero, se invece fossimo all’interno del raggio, prima di tutto ci calcoliamo dist_pn che serve a capire con che intensità il pixel nero verrà mescolato al pixel della scena. L’ultima assegnazione, quella effettuata su gl_FragColor, permette il disegno del nostro shader così come lo vediamo nell’immagine.

Cos’è quella formula? Si tratta semplicemente dell’equazione di blending utilizzata anche da opengl nella sua fixed pipeline quando si utilizza

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

In pratica permette, dato un valore di alpha (dist_pn in questo caso), di gestire come due pixel vengono sommati tra loro; nel nostro caso maggiore è la distanza del pixel dal nostro personaggio, più sarà visibile solo il pixel shadow, al contrario più ci si avvicina al centro, più sarà visibile solo il pixel della texture.

Un link interessante per capire meglio l’equazione è presente qui: Alpha Compositing.

Alla prossima.