Wednesday, January 16, 2008

Unità di misura 2

Tanti ragionamenti.. tutti sbagliati purtroppo.
DirectX lavora internamente in singola precisione (formato float in C++), e la singola precisione è ahimè insufficiente per riuscire a rappresentare il sistema solare.
Mi spiego: una volta decisa l'origine del nostro ambiente, che avevo scelto coincidente col sole, e scelta come unità di misura 1 = 10.000km, andando a lavorare con dimensioni piccole, tipo 10 metri, (la dimensione di una navicella), i numeri diventano dell'ordine di 0.000001
Ora: se ci troviamo sufficientemente vicini all'origine non c'e' problema usando questa scala, se pero' siamo nei pressi di plutone, che sta a (581000.0,0,0) , il numero "grande" prende il sopravvento e viene "sacrificato" il piccolo, col risultato che si ottengono dei troncamenti che fan si' che la navicella si muova a "balzi" di 1 kilometro od oltre, con un risultato visivo orribile.
La stessa cosa avviene se abbassiamo la scala.. il numeri diventano dell'ordine di 0.1 (per ipotesi), ma la coordinata di plutone diventa una cosa del tipo (5810000000,0,0), e nuovamente entrano in gioco i troncamenti.
Come risolvere? L'idea che ho avuto è quella di:

1) utilizzare un sistema di coordinate in doppia precisione (che però non è compatibile con directX), per rappresentare tutti gli oggetti che fan parte del sistema solare. Dovrebbe garantirmi una precisione sufficiente a rappresentar distanze siderali come distanze nell'ordine dei metri quando due astronavi ad esempio son vicine

2) impostare l'origine non più nel sole ma nella telecamera, così che gli oggetti vicini alla telecamera siano anche prossimi allo zero.. quindi se ho un oggetto vicinissimo, lo converto da double a float ma non perdo precisione. Un oggetto invece molto distante probabilmente, convertito, perderà di risoluzione, ma essendo molto lontano apparirà piccolissimo, probabilmente invisibile. Un errore, da lontano, sembra piccolo, e più lontano è, e più sembrerà microscopico. Come una macchia su una giacca, se la persona sta a 500 metri da voi, non ve ne accorgete.

Speriamo sia la strada giusta. Nel frattempo ho implementato anche la gestione delle mesh create esternamente da altri programmi (es: blender), e questo screenshot è una prova con un'astronave (orribile) trovata assieme al SDK di DirectX. Uso questa per ora come sistema di riferimento, poi col tempo spero di arrivare a disegnare qualcosa di più decente.

2 comments:

Anonymous said...

Potresti anche provare a suddividere il sistema in celle, avendo così n sistemi di riferimento. Tutto la galassia diventa così una matrice di celle in cui i pianeti hanno coordinate riferite alla loro cella di appartenenza.

PdG said...

Grazie per il consiglio, come forse avrai già letto probabilmente (faccio gli scongiuri) ho risolto il problema.
Avere una griglia mi complica comunque la vita quando devo visualizzare tutto, se un oggetto fa parte di una griglia e un altro oggetto fa parte di un'altra, devo convertire le coordinate del primo in quelle del secondo, e sono punto a capo. A meno che non decida di visualizzare solo le coordinate della griglia nella quale mi trovo, ma non va bene perche' se sono vicino al bordo, e un oggetto e' anch'esso vicino al bordo, ma dall'altro lato, io l'oggetto non lo vedo, appena attraverso il confine mi appare di colpo, e non e' di certo una buona cosa.