Visualizzazione Stampabile
-
domanda su XNA (c#)
Vi chiedo cortesemente di spiegarmi il significato dei metodi Matrix.CreateFromYawPitchRoll e Vector3.Transform.
Ho provato a creare una camera in prima persona ma non capisco perchè non funziona con la semplice somma dei Vector3.
Perchè si devono creare le matrici? Non bastano i Vector3? :nono:
-
Riferimento: domanda su XNA (c#)
Qua un link che spiega come operare sulle matrici base (rotazione, scaling, traslazione per i modelli, projection e view per visualizzare a schermo)
http://www.toymaker.info/Games/XNA/html/xna_matrix.html
Matrix.CreateFromYawPitchRoll crea una rotazione rispettivamente sull'asse Y,X,Z, i valori devono essere in radians.
Vector3.Transform non l'ho mai usato, quindi non so esattamente a cosa serva
-
Riferimento: domanda su XNA (c#)
sì ma non ho capito perchè bisogna usare le matrici. Non bisogna usare un vettore con 3 elementi?
Volevo ruotare orizzontalmente la mia telecamera in prima persona con la pressione del tasto A. Il codice è questo:
if(KeyState.IsKeyDown(Key.A))
{
punto_focalizzazione.X += secondi_passati * speed;
}
però ruota soltanto di 90° e non oltre!!!
Vi prego rispondetemi, sto impazzendo! :stress:
-
Riferimento: domanda su XNA (c#)
Mio pensiero, premetto che non ci capisco molto di grafica ma mi interesso :uhm:
Questo non accade perché ti stai spostando solo sull'asse X?
Matematicamente, andando all'infinito su X non girerai mai il campo visivo oltre i 90°, ma bensì sposti il punto focale all'infinito sull'asse X.
Per girare oltre devi entrare nell'ottica della Z.
Almeno penso :uhm: altrimenti ammetto la mia ignoranza.
-
Riferimento: domanda su XNA (c#)
Citazione:
Originariamente Scritto da
Toty_
sì ma non ho capito perchè bisogna usare le matrici. Non bisogna usare un vettore con 3 elementi?
Volevo ruotare orizzontalmente la mia telecamera in prima persona con la pressione del tasto A. Il codice è questo:
if(KeyState.IsKeyDown(Key.A))
{
punto_focalizzazione.X += secondi_passati * speed;
}
però ruota soltanto di 90° e non oltre!!!
Vi prego rispondetemi, sto impazzendo! :stress:
Non è obbligatorio usare le matrici, puoi usare il sin e il cos per avere la posizione del "punto_focale", per fare questo si agisce sugli assi X e Z, io per esempio uso questo codice
Citazione:
camera.lookAt.X = camera.position.X;
camera.lookAt.Z = camera.position.Z;
camera.lookAt.X += (float)Math.Sin(radianYaw) * 2;
camera.lookAt.Z += (float)Math.Cos(radianYaw) * 2;
-
Riferimento: domanda su XNA (c#)
Ok, sono riuscito a ruotare di 360° la telecamera orizzontalmente. Ma non ho usato ne matrici ne strane formule di trigonometria.
Nel metodo Update controllo se è stato premuto il tasto Left (spostamento verso sinistra) o il tasto Right della tastiera (spostamento verso destra).
Però, stranamente, se tengo premuto per un po' di tempo uno di questi due tasti, la rotazione diventa sempre più lenta!!! :???:
Ecco il codice ("focalizza" è di tipo Vector3 ed è il punto focalizzato dalla telecamera):
if (keyState.IsKeyDown(Keys.Left))
{
if (focalizza.Z >= 0.01f && focalizza.X <= 0.01f)
{ //1° quadrante
focalizza.Z += speed * secondi_passati;
focalizza.X += speed * secondi_passati;
}
if (focalizza.Z >= 0.01f && focalizza.X >= 0.01f)
{ //2° quadrante
focalizza.Z -= speed * secondi_passati;
focalizza.X += speed * secondi_passati;
}
if (focalizza.Z <= 0.01f && focalizza.X >= 0.01f)
{ //3° quadrante
focalizza.Z -= speed * secondi_passati;
focalizza.X -= speed * secondi_passati;
}
if (focalizza.Z <= 0.01f && focalizza.X <= 0.01f)
{ //4° quadrante
focalizza.Z += speed * secondi_passati;
focalizza.X -= speed * secondi_passati;
}
}
if (keyState.IsKeyDown(Keys.Right))
{
if (focalizza.Z >= 0.01f && focalizza.X <= 0.01f)
{ //1° quadrante
focalizza.Z -= speed * elapsedSec;
focalizza.X -= speed * elapsedSec;
}
if (focalizza.Z >= 0.01f && focalizza.X >= 0.01f)
{ //2° quadrante
focalizza.Z += speed * elapsedSec;
focalizza.X -= speed * elapsedSec;
}
if (focalizza.Z <= 0.01f && focalizza.X >= 0.01f)
{ //3° quadrante
focalizza.Z += speed * elapsedSec;
focalizza.X += speed * elapsedSec;
}
if (focalizza.Z <= 0.01f && focalizza.X <= 0.01f)
{ //4° quadrante
focalizza.Z -= speed * elapsedSec;
focalizza.X += speed * elapsedSec;
}
}
Ho diviso gli assi in 4 quadranti. Secondo voi perchè la rotazione rallenta costantemente se tengo premuto uno dei due tasti?
-
Riferimento: domanda su XNA (c#)
Potete dirmi quale specifico argomento di trigonometria dovrei studiare per poter creare dei cerchi (rotazioni) perfetti sugli assi?
Vorrei poter creare le rotazioni con del codice creato da me e non con i metodi (incomprensibili) messi a disposizione da xna (come ad esempio, la classe Matrix).
Vi prego rispondetemi! :sad:
-
Riferimento: domanda su XNA (c#)
Sono metodi ottimizzati per fare quello che devono. Non reinventarti la ruota, usali.
-
Riferimento: domanda su XNA (c#)
Sì ma non ho proprio capito cosa significa "creare un matrice di rotazione" con il metodo Matrix.CreateFromYawPitchRoll.
Se non so cosa fanno questi metodi, potrò soltanto fare il copia e incolla. :nono:
-
Riferimento: domanda su XNA (c#)
non so una seha di xna, ma debuggando bene posso pensare che scoprirai che non è la telecamera che rallenta ma il valore numerico che imposti alla rotazione che aumenta troppo velocemente.
Se, come penso ma non sono sicuro, la rotazione della telecamera è misurata in radianti, il tuo valore di rotazione (speed * elapsedSec) ad un certo punto diventa così alto che ad ogni frame la telecamera viene mossa di un giro più un po'.
nel senso che il valore di rotazione diventa si alto, ma la telecamera viene mossa solo del delta rispetto al punto del frame precedente.
Insomma, non so spiegarmi meglio, non conosco XNA e probabilmente questo post si basa su considerazioni irreali.
-
Riferimento: domanda su XNA (c#)
Citazione:
Originariamente Scritto da
Toty_
Sì ma non ho proprio capito cosa significa "creare un matrice di rotazione" con il metodo Matrix.CreateFromYawPitchRoll.
Se non so cosa fanno questi metodi, potrò soltanto fare il copia e incolla. :nono:
La guida di Direct3D spiega chiaramente a cosa servono le matrici di rototraslazione e che tipo di operazioni occorrono per impostare le matrici di proiezione e di view. Suppongo anche la guida di XNA spieghi queste cose, devi leggere lì. :sisi:
-
Riferimento: domanda su XNA (c#)
Sto creando una rotazione orizzontale con le formule Cos e Sin (trigonometria) però c'è un problema: con Cos-1
ho trovato di quanti gradi ha ruotato il punto (focalizzato) in base alla posizione della telecamera (che sarebbe il centro dell'ipotetico cerchio di rotazione). Però, pare che questa formula funzioni fino ai 180°. Infatti, se i gradi fossero 200, questa formula restituirebbe 160, ecc...
Sapete dirmi perchè?
Se riuscite a trovarmi questa soluzione, forse il problema è risolto! :sisi:
-
Riferimento: domanda su XNA (c#)
Citazione:
Originariamente Scritto da
Toty_
Sto creando una rotazione orizzontale con le formule Cos e Sin (trigonometria) però c'è un problema: con Cos-1
ho trovato di quanti gradi ha ruotato il punto (focalizzato) in base alla posizione della telecamera (che sarebbe il centro dell'ipotetico cerchio di rotazione). Però, pare che questa formula funzioni fino ai 180°. Infatti, se i gradi fossero 200, questa formula restituirebbe 160, ecc...
Sapete dirmi perchè?
Se riuscite a trovarmi questa soluzione, forse il problema è risolto! :sisi:
Se per Cos-1 intendi l'arcocoseno, considera che la funzione arcocoseno è definita solo tra -1 ed 1 ed il suo codominio è tra 0 e pi greco ( = 180° )
-
Riferimento: domanda su XNA (c#)
Con il seguente codice sono finalmente riuscito a ruotare la telecamera verso sinistra (quindi in senso antiorario). Prima di tutto controllo (con arcocoseno) il n° di gradi del punto inizialmente focalizzato, poi gli aggiungo 1° grado per poterlo ruotare effettivamente.
Però se invece di 1° alla volta mettessi 180°, la rotazione non avviene. A 90° alla volta la rotazione è un pò strana, e a 359° comincia a ruotare nel senso opposto (orario).
Ecco il codice: :rotolul:
void Ruota_Sinistra()
{
double gradi_start = Math.Acos((focalizza.X - camera_posizione.X) / (-50)) * (180 / Math.PI);
if (focalizza.Z < camera_posizione.Z) gradi_start = 180 + (180 - gradi_start);
gradi_start += 1; //aumento di 1° alla volta
if (gradi_start > 360) gradi_start -= 360;
focalizza.X = (float)((Math.Cos((gradi_start) / (180 / Math.PI)) * (-50) + camera_posizione.X));
focalizza.Z = (float)((Math.Sin((gradi_start) / (180 / Math.PI)) * 50 + camera_posizione.Z));
}
Sapete dirmi perchè?
Secondo voi le if rallentano l'esecuzione?
Forse ci siamo quasi.
-
Riferimento: domanda su XNA (c#)
-
Riferimento: domanda su XNA (c#)
mi dite almeno se questo metodo rende l'esecuzione meno fluida rispetto all'uso delle matrici? :|
-
Riferimento: domanda su XNA (c#)
Sicuramente l'uso delle matrici è più efficente, per vari motivi di semplificazione di calcolo e di simulazione.
Tra l'altro se sull'msdn (e su tutti i portali di programmazione 3d) dicono di usare le matrici per le rotazioni e per gli spostamenti rispetto alla matrice universo, un motivo ci sarà
-
Riferimento: domanda su XNA (c#)
Allora sono spacciato, dato che non riesco a capire come creare delle matrici (non voglio usare quelle di XNA senza capirci niente) per ruotare o traslare. Ad esempio, in una guida, viene usata una matrice per ruotare la telecamera mediante il mouse. Tale telecamera può anche essere spostata con la pressione dei tasti A, S, D, W:
protected override void Initialize()
{
//...
camera_posizione = new Vector3(0.0f, 100.0f, 0.0f);//<-- Posizione iniziale
camera_rotazione = 0f; //<-- Rotazione destra-sinistra (rotazione).
camera_beccheggio = 0f; //<-- Rotazione alto-basso (beccheggio).
camera_rollio = 0.0f; //<-- Rotazione rollio.
}
protected override void Update(GameTime gameTime)
{
// Secondi trascorsi dall'ultimo frame
float elapsedSec = (float)gameTime.ElapsedGameTime.TotalSeconds;
KeyboardState keyState = Keyboard.GetState();
MouseState mouseState = Mouse.GetState(); camera_rotazione -= (float)(mouseState.X - graphics.PreferredBackBufferWidth / 2) * elapsedSec;
camera_beccheggio += (float)(mouseState.Y - graphics.PreferredBackBufferHeight / 2) * elapsedSec;
Mouse.SetPosition(graphics.PreferredBackBufferWidth / 2, graphics.PreferredBackBufferHeight / 2);
// Crea una matrice di rotazione secondo i vari angoli di rotazione
Matrix rot = Matrix.CreateFromYawPitchRoll(camera_rotazione, camera_beccheggio, camera_rollio);
// Calcola i vettori per la matrice di rotazione corrente.
Vector3 camUp = Vector3.Transform(Vector3.UnitY, rot);
Vector3 camLook = Vector3.Transform(Vector3.UnitZ, rot);
Vector3 camLeft = Vector3.Cross(camUp, camLook);
//...
Mie_variabili.View = Matrix.CreateLookAt(camera_posizione, camera_posizione + camLook, camUp);
}
Se sapeste dirmi cosa contiene la matrice creata da Matrix.CreateFromYawPitchRoll, forse capirei qualcosa.
Vi prego rispondetemi! :tremo:
-
Riferimento: domanda su XNA (c#)
Almeno toglietemi una curiosità: le matrici CreateRotationX, CreateRotationY, ecc.. sono 3x3 o 4x4? :???:
-
Riferimento: domanda su XNA (c#)
-
Riferimento: domanda su XNA (c#)
Citazione:
Originariamente Scritto da
Cherno
4x4
Grazie Cherno. :)
Ma che senso ha fare una matrice 4x4, non basta una 3x3? Qual'è lo scopo?
Inoltre, vorrei fare una domanda importante: sapete dirmi (o indirizzarmi a qualche sito che ne parla) come creare un rotazione obliqua (servirà per ruotare la visuale in un gioco fps)?
-
Riferimento: domanda su XNA (c#)
Devi studiare un pò di matematica discreta :sisi:
Però io insisto: tutti questi concetti anche se non li conosci a fondo, sono affrontati in almeno due milioni di tutorial e la guida di direct3d. Quindi continuo a non comprendere perchè non usi i metodi che ti fornisce l'API, che sono molto molto meglio di quelli che tu potrai sperare di scrivere...
-
Riferimento: domanda su XNA (c#)
Citazione:
Originariamente Scritto da
Cherno
Devi studiare un pò di matematica discreta :sisi:
Però io insisto: tutti questi concetti anche se non li conosci a fondo, sono affrontati in almeno due milioni di tutorial e la guida di direct3d. Quindi continuo a non comprendere perchè non usi i metodi che ti fornisce l'API, che sono molto molto meglio di quelli che tu potrai sperare di scrivere...
Infatti è per questo che voglio imparare di più sulle matrici. All'inizio volevo ricorrere ad altri metodi ma ora mi sono convinto che è meglio usare le matrici (basta moltiplicarle tra loro per ottenere rotazioni, traslazioni, ecc.. in una sola volta).
Però è necessario, prima di usare i metodi di XNA, capire qualcosina di più sulle matrici.
Tra poco vi invierò una soluzione (con matrici, seno e coseno) per ruotare la telecamera attorno all'asse y. Soltanto per capire un po' di più (non mi piacciono i copia e incolla). :sisi:
-
Riferimento: domanda su XNA (c#)
Ecco fatto! :celafa:
E stavolta ho usato le matrici!!!
Con la pressione del tasto Left viene eseguito il metodo Ruota_Sinistra() che ruota la telecamera in senso antiorario attorno all'asse y.
Prima di tutto, creo una matrice identità chiamata "prova":
protected override void Initialize()
{
//...
prova = Matrix.Identity;
}
poi, nel metodo Update richiamo Ruota_Sinistra() se viene premuto l'apposito tasto. Tale metodo è il seguente:
void Ruota_Sinistra()
{
prova.Up = focalizza; //focalizza è il punto focalizzato
Matrix Mtot = prova * Matrix.CreateTranslation(camera_posizione.X, camera_posizione.Y, camera_posizione.Z) * Matrix.CreateRotationY(0.01745f);
focalizza = Mtot.Up;
}
Secondo voi fa troppi calcoli?
In effetti, ho dovuto creare una matrice 4x4 per contenere soltanto le coordinate di "focalizza", sarebbe bastato un Vector3.
Il problema è che il compilatore mi da errore se moltiplico una matrice per un Vector3 o Vector4. Come posso fare? Datemi un consiglio, vi scongiuro. :boh:
-
Riferimento: domanda su XNA (c#)
Ma per caso Matrix.CreateFromYawPitchRoll è il risultato di CreateRotationX * CreateRotationY * CreateRotationZ?
Vector3.Transform cos'è?
Perchè con questo metodo (Transform) vengono creati tre vettori (solitamente chiamati "up", "left", "look")?
Vi prego rispondete! :look:
-
Riferimento: domanda su XNA (c#)
Nessuno sa cosa fa il metodo Vector3.Transform(Vector3 a, Matrix b) ?
-
Riferimento: domanda su XNA (c#)
moltiplicazione vettore matrice. Se cerchi su google le operazioni delle matrici, ti spiegano bene i vari passaggi.
-
Riferimento: domanda su XNA (c#)
E' impossibile moltiplicare un Vector3 per una Matrix! :nono:
Un Vector3 è una matrice 1x3 mentre la Matrix è una 4x4, due matrici possono moltiplicarsi solo se la prima ha tante colonne quante sono le righe delle seconda (quindi una 1x3 non può moltiplicare una 4x4 e viceversa!!!)
Ma allora cos'è questo Vector3.Transform? :look:
Mi basterebbe sapere questo per capirci un po' di più.
Conosco le operazioni e le regole sulle matrici e, ultimamente, ho anche studiato come creare matrici di trasformazione, ma in un esempio ho trovato questo metodo che nessuno sa dirmi cos'è.
-
Riferimento: domanda su XNA (c#)
i vector3 sono sempre considerati a 4 componenti, dove la w dovrebbe essere ad 1.
Aggiungo: http://social.msdn.microsoft.com/For...a-4e8b3e5492af
-
Riferimento: domanda su XNA (c#)
Citazione:
Originariamente Scritto da
Cherno
i vector3 sono sempre considerati a 4 componenti, dove la w dovrebbe essere ad 1.
Allora come mai il compilatore mi segnala errore se tento di moltiplicare un Vector3 per una Matrix? :boh2:
Se fosse come dici tu, la moltiplicazione dovrebbe essere lecita.
-
Riferimento: domanda su XNA (c#)
Al compilatore non gliene frega un ***** delle regole della matematica, probabilmente sbagli a passargli qualcosa alla funzione transform, oppure l'oggetto che la utilizza non è valido.
-
Riferimento: domanda su XNA (c#)
Citazione:
Originariamente Scritto da
Cherno
Al compilatore non gliene frega un ***** delle regole della matematica, probabilmente sbagli a passargli qualcosa alla funzione transform, oppure l'oggetto che la utilizza non è valido.
Ok calmati, non c'è motivo di scaldarsi! :furboni:
Allora, visto che Transform moltiplica un Vector3 per una Matrix, questo codice per muovere la telecamera cosa fa esattamente?
// Crea una matrice di rotazione secondo i vari angoli di rotazione
Matrix rot = Matrix.CreateFromYawPitchRoll(camera_rotazione, camera_beccheggio, camera_rollio);
// Calcola i vettori per la matrice di rotazione corrente.
Vector3 camUp = Vector3.Transform(Vector3.UnitY, rot); //moltiplica (0,1,0) per la matrice di rotazione rot
Vector3 camLook = Vector3.Transform(Vector3.UnitZ, rot); //moltiplica (0,0,1) per rot
Vector3 camLeft = Vector3.Cross(camUp, camLook); //equivale a (1,0,0) per rot
//...
Mie_variabili.View = Matrix.CreateLookAt(camera_posizione, camera_posizione + camLook, camUp);
E' inutile che ti inca**i, Cherno. Cosa dovrei dire io allora, visto che sono mesi che su internet trovo solo informazioni ambigue e incomplete?
-
Riferimento: domanda su XNA (c#)
tanto per cominciare, il fatto che il compilatore ti dia un errore non vuole dire molto.
Postare il testo dell'eccezione magari ci aiuta ad aiutarti.
In secondo luogo io spero che per moltiplicare due matrici tu usi il metodo Matrix.Multiply(Matrix, Matrix) e non l'operatore di moltiplicazione liscio.
-
Riferimento: domanda su XNA (c#)
Citazione:
Originariamente Scritto da
Toty_
Ok calmati, non c'è motivo di scaldarsi! :furboni:
Allora, visto che Transform moltiplica un Vector3 per una Matrix, questo codice per muovere la telecamera cosa fa esattamente?
// Crea una matrice di rotazione secondo i vari angoli di rotazione
Matrix rot = Matrix.CreateFromYawPitchRoll(camera_rotazione, camera_beccheggio, camera_rollio);
// Calcola i vettori per la matrice di rotazione corrente.
Vector3 camUp = Vector3.Transform(Vector3.UnitY, rot); //moltiplica (0,1,0) per la matrice di rotazione rot
Vector3 camLook = Vector3.Transform(Vector3.UnitZ, rot); //moltiplica (0,0,1) per rot
Vector3 camLeft = Vector3.Cross(camUp, camLook); //equivale a (1,0,0) per rot
//...
Mie_variabili.View = Matrix.CreateLookAt(camera_posizione, camera_posizione + camLook, camUp);
E' inutile che ti inca**i, Cherno. Cosa dovrei dire io allora, visto che sono mesi che su internet trovo solo informazioni ambigue e incomplete?
Mica mi incazzo, anzi se vuoi te lo ripeto: al compilatore non gliene frega una gran ceppa delle regole della matematica.
:asd:
la matrice lookAt è definita da 3 vettori: eye, look ed up.
eye indica la posizione della camera,
look indica la direzione verso la quale guarda
up indica il vettore che ci dice su quale asse sta l'asse verticale.
una volta forniti questi tre vettori, la tua camera è bella e funzionante, stai solo attento a non mettere eye e look a zero, altrimenti sfasa tutto.
Quindi tu operando sui valori di qye e look, permetti alla tua camera di girare. Ora capisco che tu sia già in difficoltà per fatti tuoi, però scrivi su google "openGL camera" e troverai informazioni più dettagliate su una cameraLookAt con un sacco di codice.
-
Riferimento: domanda su XNA (c#)
Citazione:
Originariamente Scritto da
Cherno
Ora capisco che tu sia già in difficoltà per fatti tuoi, però scrivi su google "openGL camera" e troverai informazioni più dettagliate su una cameraLookAt con un sacco di codice.
Ok, grazie. :)
Cercherò su google "openGL camera" e vi farò sapere il prima possibile.
-
Riferimento: domanda su XNA (c#)
So cos'è la matrice lookAt. Il problema è riuscire a far ruotare la visuale come un gioco fps.
Ho studiato molto in questi giorni (in questo periodo ho tempo da perdere) e sono riuscito a capire qualcosa sulle matrici di trasformazione. :sisi:
Ora il problema è la rotazione obliqua. Credo che l'unico modo per ottenerla sia quello di moltiplicare le matrici di rotazioni di tutti e tre gli assi (proprio come fa CreateFromYawPitchRoll, se non sbaglio).
Questo è il maledetto codice (preso da un sito) che mi sta facendo impazzire da due settimane. Con queste poche righe è possibile far ruotare la visuale e spostare la telecamera:
Matrix rot = Matrix.CreateFromYawPitchRoll(camera_rotazione, camera_beccheggio, camera_rollio);
// Calcola i vettori per la matrice di rotazione corrente.
Vector3 camUp = Vector3.Transform(Vector3.UnitY, rot);
Vector3 camLook = Vector3.Transform(Vector3.UnitZ, rot);
Vector3 camLeft = Vector3.Cross(camUp, camLook);
//...
if (keyState.IsKeyDown(Keys.A))
camera_posizione += speed * elapsedSec * camLeft;
if (keyState.IsKeyDown(Keys.D))
camera_posizione -= speed * elapsedSec * camLeft;
if (keyState.IsKeyDown(Keys.W))
camera_posizione += speed * elapsedSec * camLook;
if (keyState.IsKeyDown(Keys.S))
camera_posizione -= speed * elapsedSec * camLook;
//...
Mie_variabili.View = Matrix.CreateLookAt(camera_posizione, camera_posizione + camLook, camUp);
-------------
Vi imploro di osservare un attimo questo codice e di rispondermi a due domande:
-1. ognuno dei tre vettori (camUp, ecc..) rappresenta una riga della matrice rot. Per caso, ogni riga è il punto di rotazione attorno ad un asse?
-2. nell'ultima riga di codice, perchè il punto da focalizzare è dato dalla somma tra la posizione della camera e la terza riga di rot (camLook)?
-
Riferimento: domanda su XNA (c#)
guarda io di xna e di c# non so proprio niente.
però tu hai bisogno di un libro che parli di algebra matriciale e geometria, non di un tutorial di programmazione (in verità, ne avrei bisogno anche io, ma provo ad aiutarti lo stesso).
in sintesi, se poniamo che lo spazio fisico sia rappresentabile come uno spazio a 3 dimensioni, possiamo rappresentare matematicamente i cambi di vista (che corrispondono a rotazioni della terna degli assi geometrici) con delle matrici: per ruotare un sistema di riferimento da una posizione ad un altra, moltiplico la matrice degli assi (scusa se non entro nel merito di termini come versori e basi ortogonali, occorre aver studiato la materia geometria e algebra, e io non ho nemmeno ricordi tanto freschi) del primo con la matrice di rotazione, per ottenere quella del secondo
createfromyawpitchroll crea una matrice di rotazione a partire da 3 valori di rotazione angolare lungo ciascuno dei tre assi (yaw pitch e roll sono appunto i nomi inglesi di rollio, beccheggio e imbardata, termini il cui significato facilmente troverai spiegato su internet).
vector3.transform prende un vettore e lo trasforma in base alla matrice (nel caso specifico applica la matrice rot a delle coordinate, ovvero trasforma dei vettori coordinata da un sistema di riferimento ad un altro). perciò i tre vettori NON rappresentano righe della matrice rot: essendo il risultato del prodotto tra matrice di rotazione e vettore riga, il risultato è una colonna di rot, che corrisponde al versore della base originale espresso nel nuovo riferimento (ovvero, il versore del nuovo asse x-y-z a seconda della colonna che prendiamo).
unitY e unitZ sono le basi (i versori degli assi Y e Z), cioè sono i vettori (0,1,0) e (0,0,1): essi vengono convertiti negli assi del riferimento ruotato, trasformandoli con la matrice rot.
vector3.cross realizza il prodotto vettoriale tra i due vettori di cui sopra (e cioè crea il versore perpendicolare, visto che i moduli sono unitari, ovvero l'asse X del riferimento ruotato)
camera_posizione è una matrice che rappresenta la posizione della telecamera, a seconda dei tasti premuti essa viene incrementata di speed*elapsedSec (cioè dello spostamento) o lungo la direzione di camleft (=lungo l'asse X) o lungo camlook (=lungo l'asse Y). ciò corrisponde allo spostare la vista in orizzontale/verticale SENZA ruotarla.
a questo punto nell'ultima istruzione viene detto al compilatore di creare una vista in cui la camera si trova nella posizione camera_posizione (=la posizione traslata, senza rotazione), l'asse verticale è orientato in direzione camUp (l'avevo calcolato prima, infatti, è la nuova orientazione dell'asse Y) e il punto dove la telecamera punta è dato dalla somma di camera posizione e camlook.
il "bersaglio" risulta quello, quindi, perchè con camUP io imposto la rotazione dell'asse Y (imposto la direzione che per la camera è verticale), quindi mi resta solo da effettuare una seconda rotazione (quella dell'asse Z), per posizionare il "fuoco".
ma questa rotazione dell'asse Z (relativa alla nuova posizione, e che quindi parte da camera_posizione) guardacaso è data da camlook (che avevo appositamente calcolato partendo dal versore Z e ruotandolo)
-
Riferimento: domanda su XNA (c#)
Citazione:
Originariamente Scritto da
Ronin
perciò i tre vettori NON rappresentano righe della matrice rot: essendo il risultato del prodotto tra matrice di rotazione e vettore riga, il risultato è una colonna di rot, che corrisponde al versore della base originale espresso nel nuovo riferimento (ovvero, il versore del nuovo asse x-y-z a seconda della colonna che prendiamo).
E' strano, perchè Vector3.Transform moltiplica un Vector3 per una matrix (dando l'elemento w=1 al Vector3 per poter effettuare il prodotto). Moltiplicando Vector3.UnitY e Vector3.UnitZ per rot, ottengo le righe di rot.
E comunque, CampUp non rientra nel punto focalizzato perchè quest'ultimo viene indicato come secondo parametro (e non terzo) di Matrix.CreateLookAt. Quindi, pare che il punto focalizzato tenga conto solo di camLook (camera_posizione+Camlook), come mai? :???:
-
Riferimento: domanda su XNA (c#)
sulle righe o colonne non metto la mano sul fuoco, perchè non so bene se vector3.unity/z restituiscono un vettore riga o colonna; cmq il senso è quello: righe o colonne che siano, rappresentano i versori degli assi nel riferimento ruotato (transform dovrebbe corrispondere alla moltiplicazione di rot per il vettore, e non del vettore per rot; in tal modo si dovrebbero ottenere le colonne di rot). più di tanto non posso aiutarti perchè io ragiono con le matrici 3x3 della geometria analitica, quindi non ho idea di che cosa XNA memorizzi nella quarta riga/colonna.
camup è il terzo parametro di createlookat, ma come ti ho spiegato la funzione "separa" le informazioni necessarie in due argomenti separati: richiede una direzione in cui puntare (che è camera_posizione+Camlook) e una direzione in cui orientare l'asse Y, ruotandolo intorno alla direzione precedente (che è camUP).
fai conto che prima punta il fucile verso camera_posizione+Camlook (che è dove effettivamente deve puntare), poi ruota il fucile su se stesso fino a che il mirino del fucile si trova in alto (direzione di camUP) e il grilletto in basso...
-
Riferimento: domanda su XNA (c#)
Citazione:
Originariamente Scritto da
Ronin
sulle righe o colonne non metto la mano sul fuoco, perchè non so bene se vector3.unity/z restituiscono un vettore riga o colonna; cmq il senso è quello: righe o colonne che siano, rappresentano i versori degli assi nel riferimento ruotato (transform dovrebbe corrispondere alla moltiplicazione di rot per il vettore, e non del vettore per rot; in tal modo si dovrebbero ottenere le colonne di rot). più di tanto non posso aiutarti perchè io ragiono con le matrici 3x3 della geometria analitica, quindi non ho idea di che cosa XNA memorizzi nella quarta riga/colonna.
Scusami Ronin ma, dato che mi dici di non conoscere c#, devo metterti al corrente di alcune cose prima di continuare la discussione (molto interessante, a mio parere) che valgono per tutti quelli che stanno leggendo: :sisi:
- Con XNA i Vector3 sono matrici 1x4 (e non 4x1) e le matrici Matrix sono 4x4. Quindi il prodotto (seguendo le regole sulle matrici) deve essere per forza Vector3 * Matrix e non viceversa. Quindi, Vector3.unitY * rot (ad esempio) restituirà per forza la seconda riga di rot (e non una colonna).
- La parte che mi preoccupa è il secondo parametro di Matrix.CreateLookAt: il mirino della camera. La sua rotazione, precisamente.
Il tutto sembre funzionare ma non capisco perchè. Sembra una magia senza una spiegazione.
Perchè sommiamo camera_posizione per camLook (terza riga di rot)? Che senso ha?
Infine, vorrei chiederti di usare un linguaggio un po' più comprensibile (troppo difficile per me) e di spiegarmi il significato di versore.
Aiutatemi, sono disperato. Pensavo di aver capito e invece....:cattivo: