|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Feb 2006
Messaggi: 1304
|
[Vari/C++/lowlevel] Bitwise Operations e Bitmasks, non ci capisco una ceppa!
Salve,
ho bisogno di creare uno sparo che colpisca tutto tranne i soldati del mio team. In concreto, uso PhysX e questo si può fare assegnando ad ogni Forma una Mask/Group, e quindi filtrando questi ShapeGroup tramite una bitwise Mask apposita. La Shape Mask è definita come unsigned short e va da 0 a 31; la bitwise mask è un unsigned int. In teoria, ogni team ha una specifica Shape Mask; quindi lancio un Ray che attraversa la scena, configurato per escludere tutte le mask diverse da quelle del mio team. In pratica essendo completamente a digiuno di operazioni bitwise, non ho idea di come creare un raggio che colpisca tutti i gruppi (0, 30) ma non quello del mio team (31) e viceversa per il nemico (0,31)(30) Per ora usavo la maschera ottenuta dal codice (trovato in giro ):Codice:
unsigned short teamMask = 0x1f; //31 unsigned int mask = ~(1<< teamMask ); Mi serve l'aiuto di qualche lowlevel pro
|
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Ciao Tommo,
se la mask di un Ray deve "escludere" tutte le mask diverse dal tuo team, significa che, viceversa, deve "includere" solo la mask del tuo team. Se il ragionamento è corretto presumo che l'operazione che avviene tra la ray_mask e tutte le group_mask intersecate dal ray sia un semplice & (AND) tra la group_mask da testare e il valore della ray_mask negata (NOT ~). Se il risultato di questa operazione è diverso da zero (almeno un bit è rimasto a 1) allora la group_mask testata è "esclusa" (cioè colpita dal ray). Codice:
// per ogni team_mask intersecata dal Ray
result_mask = team_mask & (~ray_mask);
if (result_mask != 0) {
// colpito-escluso
}
Per rendere la cosa un attimo più visiva: Codice:
myteam_mask = [1][1][1][1][1][1] // vale 31 myray_mask = [1][1][1][1][1][1] ~myray_mask -->[0][0][0][0][0][0] myteam_mask & (~myray_mask) --> [1][1][1][1][1][1] & [0][0][0][0][0][0] --> 0 Tutti i falg a zero, cioè "non colpito". Qualsiasi altra mask produrrebbe almeno un flag di vlaore 1, "cioè colpito".
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) Ultima modifica di banryu79 : 22-10-2009 alle 13:17. |
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Feb 2006
Messaggi: 1304
|
Allora,
intanto grazie per la risposta la cosa è molto contorta e le evidenze sperimentali ancora di più ![]() -le mask numero pari non trovano il gruppo 0. -la maschera che passi dice cosa NON toccare, cioè se mask & shapeMask != 0 allora non viene visto. Ad esempio assegnando al p1 e al p2 i numeri 1 e 3, si ha che ray( ..., 1 & 3,... ) ignora tutto tranne il suolo. Siam riusciti ad ottenere quello che serve (cioè che lo sparo colpisce 0 e gruppo_nemico) usando l'arcana formula ~(1<<teamGroup) Comunque non ne vedo ancora il verso ![]() PS: sapendo questo, come faccio a creare una mask che vede unicamente 0? Teoricamente sarebbe NOT 0 ma praticamente non va
Ultima modifica di Tommo : 22-10-2009 alle 15:26. |
|
|
|
|
|
#4 | |||
|
Senior Member
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
|
Premessa: quando hai a che fare con bitmask, non pensare tanto ai valori dei numeri quanto ai bit che sono a 1.
Non conosco Physix, ma il fatto che la shape mask abbia valori solo tra 0 e 31 mi fa supporre che funzioni nel modo seguente: Al numero di shape mask N viene associata la bitmask ( 1 << N ) (ovvero l'N-esimo bit a 1) Se tu vuoi una mask che non abbia dentro il gruppo 30, devi mettere a uno tutti i bit tranne il 30-esimo, come spiegato nel post precedente. Poi sei stato un po' avaro di dettagli, ma faro' le seguenti ipotesi: * Le bitmask di solito di costruiscono con un | non con un &. * Tipicamente le bitmask indicano quel che si vuole tenere, non togliere * Devi shiftare tu opportunamente i bit per fare la maschera (ovvero gruppo 0 -> (1<<0) == 1 ) Se non e' cosi' devi adattare la spiegazione che segue. Se voglio una maschera che tenga i gruppi 1 e 3, allora devo fare ( 1<<1 ) | (1 << 3) ovvero 0010 | 1000 == 1010 In quest'ottica i tuoi dubbi si spiegano facilmente Una mask "numero pari", non e' altro che un maschera con l'ultimo bit a zero, ovvero una che non fara' mai passare il bit piu' basso. Quindi sia che tu usi 0 che (1<<0) il gruppo non passera' mai, perche' in OR con la bitmask dara' sempre zero. Quote:
0001 | 0100 = 0101 ray( ..., (1<<0) | (1<<2),... ) Quote:
~ (1 << 3) == ~(00001000) == (11110111) Ovvero tutto (anche lo zero, nell'ipotesi che sia 1<<0 ) tranne il tuo team. Quote:
In teoria dovrebbe essere semplicemente 1.
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele |
|||
|
|
|
|
|
#5 | ||
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Ciao marco.r,
scusa ma all'inizio (cioè prima di postare una risp a Tommo) pensavo anch'io esattamente la stessa cosa che hai spiegato. C'è solo un dettaglio che non mi torna: Quote:
Codice:
An unsigned short can hold all the values between 0 and USHRT_MAX inclusive. USHRT_MAX must be at least 65535. The short types must contain at least 16 bits to hold the required range of values. Quote:
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) Ultima modifica di banryu79 : 23-10-2009 alle 13:40. |
||
|
|
|
|
|
#6 | |
|
Senior Member
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
|
Quote:
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele |
|
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Non ci avevo pensato ma avevo immaginato che fosse il tipo documentato come input dalla libreria.
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) |
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Feb 2006
Messaggi: 1304
|
Ha completamente ragione marco.r
Cmq siamo riusciti a risolvere portando finalmente tutto terra terra E' vero, la bitmask indica quello che si vuole tenere, ed ad esempio ray( 1<<gruppo ) vede solo quel gruppo. 1<<0 vede solo il terreno, 1<<1 solo il player 1 etc... combinandoli ed invertendoli vien fuori tutto quello che serve lo sparo è quindi risolto come ray( ~(1<<myTeam ) ). Grazie dell'aiuto PS: la bitmask era NxU32, cioè unsigned int 32 su tutte le piattaforme... scusate se era ambiguo! |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 09:40.










):









