Pouze tento týden sleva až 80 % na e-learning týkající se Javy. Zároveň využij akce až 50 % zdarma při nákupu e-learningu - více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
discount 50 + hiring

Diskuze: XNA free look camera

Aktivity
Avatar
Cube
Člen
Avatar
Cube:21.4.2013 0:59

Ahoj mám takový problém s kamerou pro volný pohyb. Když stojím na místě po načtení hry všechno funguje. Jakmile se začnu pohybovat po mapě tak správně funguje jen otáčení doleva a doprava a pohyb dopředu a dozadu, ale pohled nahoru a dolů pořád blbne.

Tady je moje třída Camera:

private Vector3 baseCameraReference = new Vector3(1, 0, 0);

Tady je matice pohledu:

public Matrix View
{
    get
    {
        if (needViewResync)
            cachedViewMatrix = Matrix.CreateLookAt(
                Position,
                lookAt,
                Vector3.Backward);
        return cachedViewMatrix;
    }
}

Tady si přepočítávám novou pozici:

private void UpdateLookAt()
{
    Matrix rotationMatrix = Matrix.CreateFromYawPitchRoll(yaw, 0, roll);
    Vector3 lookAtOffset = Vector3.Transform(
        baseCameraReference,
        rotationMatrix);
    lookAt = position + lookAtOffset;
    needViewResync = true;
}

A tady je ovládání pomocí klávesnice:

if (keyState.IsKeyDown(Keys.Right))
{
    camera.Roll = MathHelper.WrapAngle(
        camera.Roll - (rotateScale * elapsed));
}
if (keyState.IsKeyDown(Keys.Left))
{
    camera.Roll = MathHelper.WrapAngle(
        camera.Roll + (rotateScale * elapsed));
}
if (keyState.IsKeyDown(Keys.Up))
{
    //camera.MoveForward(moveScale * elapsed);
    moveAmount = moveScale * elapsed;
}
if (keyState.IsKeyDown(Keys.Down))
{
    //camera.MoveForward(-moveScale * elapsed);
    moveAmount = -moveScale * elapsed;
}
if (keyState.IsKeyDown(Keys.Q))                 //pohled nahoru
{
    camera.Yaw = MathHelper.WrapAngle(
        camera.Yaw - (rotateScale * elapsed));
}
if (keyState.IsKeyDown(Keys.A))                 //pohled dolu
{
    camera.Yaw = MathHelper.WrapAngle(
        camera.Yaw + (rotateScale * elapsed));
}

Všechno funguje jenom ten pohled nahoru a dolů jde do té doby než se pohnu z původního místa. Už vážně nevím co s tím... :(

 
Odpovědět
21.4.2013 0:59
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Cube
David Čápka:21.4.2013 9:38

Díval jsi se do tutoriálů od vodacek?

Nahoru Odpovědět
21.4.2013 9:38
One of the most common causes of failure is the habit of quitting when one is overtaken by temporary defeat.
Avatar
Cube
Člen
Avatar
Odpovídá na David Čápka
Cube:21.4.2013 11:55

Do těch tutoriálů jsem se díval a pořád si myslím, že to mám tak, jak to má být. Teda vím, že nemám, jinak by to fungovalo dobře... Když mám pohled nahoru nebo dolů, přičítám nebo odečítám hodnotu yaw a pomocí Matrix.Create­FromYawPitchRo­ll(yaw, 0, roll); přepočítám nové natočení a přidám ho k současné pozici. Roll měním při pohybu do stran.

 
Nahoru Odpovědět
21.4.2013 11:55
Avatar
vodacek
Tvůrce
Avatar
Odpovídá na Cube
vodacek:21.4.2013 12:28

osobně si myslim že chyba je zde:

Matrix rotationMatrix = Matrix.CreateFromYawPitchRoll(yaw, 0, roll);

pořadí které funguje mě to totok:

Matrix rotationMatrix = Matrix.CreateFromYawPitchRoll(yaw, roll,0);

nic jinýho tam nevidim

 
Nahoru Odpovědět
21.4.2013 12:28
Avatar
Cube
Člen
Avatar
Odpovídá na vodacek
Cube:21.4.2013 12:38

Dívám se podél kladné osy X, nahoru je kladná osa Z a doleva tudíž kladná osa Y. Když se chci otáčet doleva a doprava točím se kolem osy Z (měním roll). A když se chci dívat nahoru nebo dolů, točím se kolem Y (měním yaw) ne? Tak přece hodnotu pitch mám nula proto to podle mě musí být takto:

Matrix rotationMatrix = Matrix.CreateFromYawPitchRoll(yaw, 0, roll);

Když to dám tak, jak říkáš přestane fungovat otáčení do stran.

 
Nahoru Odpovědět
21.4.2013 12:38
Avatar
vodacek
Tvůrce
Avatar
Odpovídá na Cube
vodacek:21.4.2013 13:19

nahoru je Y

 
Nahoru Odpovědět
21.4.2013 13:19
Avatar
Cube
Člen
Avatar
Cube:21.4.2013 13:30

ale přece když mám

private Vector3 baseCameraReference = new Vector3(1, 0, 0);

znamená to, že se dívám po kladné ose X

a v matici view mám

Vector3.Backward

což je vektor (0,0,1), který udává natočení kamery, to znamená, že nahoru je osa Z přece.

Kdyby to tak nebylo, tak mi nemůže fungovat ani otáčení doleva a doprava. Jak říkám, když stojím na místě po načtení hry, tak všechno funguje jak má.

Editováno 21.4.2013 13:31
 
Nahoru Odpovědět
21.4.2013 13:30
Avatar
Cube
Člen
Avatar
Odpovídá na vodacek
Cube:21.4.2013 13:31

promiň zapomněl jsem tě označit :-)

 
Nahoru Odpovědět
21.4.2013 13:31
Avatar
vodacek
Tvůrce
Avatar
Odpovídá na Cube
vodacek:21.4.2013 13:51

většinou se dává Y nahoru, ale je to vlastně jedno, co to dělá když se pohneš?

 
Nahoru Odpovědět
21.4.2013 13:51
Avatar
Cube
Člen
Avatar
Odpovídá na vodacek
Cube:21.4.2013 14:02

Dává já vím, ale mám to pro určitou aplikaci, kde to potřebuji právě takhle. Jak jsem říkal, když načtu hru a stojím na místě funguje vše jak má. pohled nahoru a dolů je bez problému. Když se pohybuji po mapě, otáčení doleva a doprava a chůze vpřed a vzad jde taky v pohodě, ale jakmile se chci podívat nahoru nebo dolů pokaždé to dělá něco jiného. jednou to místo pohledu nahoru jde dolů a opačně a jindy to opisuje malinké kružnice. Připadá mi, že se to točí pokaždé jinak, jakoby to nechtělo správně počítat ten úhel yaw.

 
Nahoru Odpovědět
21.4.2013 14:02
Avatar
Cube
Člen
Avatar
Cube:21.4.2013 14:30

Nevím jestli to pomůže ale tady je celá třída mojí kamery:

namespace ProjectX
{
    class Camera
    {
        #region Fields
        private Vector3 position = Vector3.Zero;
        private float yaw;
        private float roll;
        private Vector3 lookAt;
        private Vector3 baseCameraReference = new Vector3(1, 0, 0);
        private bool needViewResync = true;
        private Matrix cachedViewMatrix;
        #endregion

        #region Properties
        public Matrix Projection { get; private set; }
        public Vector3 Position
        {
            get
            {
                return position;
            }
            set
            {
                position = value;
                UpdateLookAt();
            }
        }

        public float Yaw          //osa y
        {
            get
            {
                return yaw;
            }
            set
            {
                yaw = value;
                UpdateLookAt();
            }
        }

        public float Roll        //osa z
        {
            get
            {
                return roll;
            }
            set
            {
                roll = value;
                UpdateLookAt();
            }
        }

        public Matrix View
        {
            get
            {
                if (needViewResync)
                    cachedViewMatrix = Matrix.CreateLookAt(
                        Position,
                        lookAt,
                        Vector3.Backward);
                return cachedViewMatrix;
            }
        }
        #endregion

        #region Constructor
        public Camera(
            Vector3 position,
            float yaw,
            float roll,
            float aspectRatio,
            float nearClip,
            float farClip)
        {
            Projection = Matrix.CreatePerspectiveFieldOfView(
                MathHelper.PiOver4,
                aspectRatio,
                nearClip,
                farClip);
            MoveTo(position, yaw, roll);
        }
        #endregion

        #region Helper Methods
        private void UpdateLookAt()
        {
            Matrix rotationMatrix = Matrix.CreateFromYawPitchRoll(yaw, 0, roll);
            Vector3 lookAtOffset = Vector3.Transform(
                baseCameraReference,
                rotationMatrix);
            lookAt = position + lookAtOffset;
            needViewResync = true;
        }

        public void MoveTo(Vector3 position, float yaw, float roll)
        {
            this.position = position;
            this.yaw = yaw;
            this.roll = roll;
            UpdateLookAt();
        }

        public Vector3 PreviewMove(float scale)
        {
            Matrix rotate = Matrix.CreateFromYawPitchRoll(yaw, 0, roll);
            Vector3 forward = new Vector3(scale, 0, 0);
            forward = Vector3.Transform(forward, rotate);
            return (position + forward);
        }

        public void MoveForward(float scale)
        {
            MoveTo(PreviewMove(scale), yaw, roll);
        }
        #endregion
    }
}
 
Nahoru Odpovědět
21.4.2013 14:30
Avatar
paanoik
Člen
Avatar
Odpovídá na Cube
paanoik:21.4.2013 14:33

Hmm .. a nebude problém v tom, že při tom testování přerazíš úhel? Jakoby ses díval vlastně hore nohama? V fpskách máš vždy ten horní a spodní limit tak, že když se chceš podívat za sebe, tak se musíš otočit podle y osy.

 
Nahoru Odpovědět
21.4.2013 14:33
Avatar
Cube
Člen
Avatar
Odpovídá na paanoik
Cube:21.4.2013 14:38

To jsem moc nepobral... Dělám v tom teprve chvíli. Nešlo by to nějak lidsky vysvětlit? :-)

 
Nahoru Odpovědět
21.4.2013 14:38
Avatar
vodacek
Tvůrce
Avatar
Odpovídá na Cube
vodacek:21.4.2013 15:37

jakej máš důvod k tomu mít Z nahoru?

 
Nahoru Odpovědět
21.4.2013 15:37
Avatar
Cube
Člen
Avatar
Odpovídá na vodacek
Cube:21.4.2013 17:50

Tak už jsem to vyřešil... Důvod byl takový, že jsem měl 3D skener, a používal jsem komponentu, která mi načítala ty data a ukládala do určité struktury a já je zobrazuji a pracuji dál s nima... Tak jsem to už nevydržel a přepsal tu komponentu a můžu vesele používat osu Y nahoru :-) že mě to nenapadlo hned... o_O

 
Nahoru Odpovědět
21.4.2013 17:50
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Cube
David Čápka:21.4.2013 17:52

Jak vypadá 3D scanner? :P

Nahoru Odpovědět
21.4.2013 17:52
One of the most common causes of failure is the habit of quitting when one is overtaken by temporary defeat.
Avatar
Cube
Člen
Avatar
Odpovídá na David Čápka
Cube:21.4.2013 19:51

Jde o 3D proximitní skener, který je na robotu... Robot jezdí a snímá okolí kolem sebe... :)

 
Nahoru Odpovědět
21.4.2013 19:51
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Cube
David Čápka:21.4.2013 20:24

Ukážeš nám robota?

Nahoru Odpovědět
21.4.2013 20:24
One of the most common causes of failure is the habit of quitting when one is overtaken by temporary defeat.
Avatar
Cube
Člen
Avatar
Odpovídá na David Čápka
Cube:21.4.2013 21:01

:D neukážu, protože pracuji jen s jeho pořízenými daty a ne přímo s ním... ;)

 
Nahoru Odpovědět
21.4.2013 21:01
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 19 zpráv z 19.