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: