Avatar
Cube
Člen
Avatar
Cube:

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:

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

Nahoru Odpovědět 21.4.2013 9:38
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Cube
Člen
Avatar
Odpovídá na David Čápka
Cube:

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
Redaktor
Avatar
Odpovídá na Cube
vodacek:

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:

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
Redaktor
Avatar
 
Nahoru Odpovědět 21.4.2013 13:19
Avatar
Cube
Člen
Avatar
Cube:

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:

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

 
Nahoru Odpovědět 21.4.2013 13:31
Avatar
vodacek
Redaktor
Avatar
Odpovídá na Cube
vodacek:

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:

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:

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:

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:

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
Redaktor
Avatar
Odpovídá na Cube
vodacek:

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:

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  +1 21.4.2013 17:50
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Cube
David Čápka:

Jak vypadá 3D scanner? :P

Nahoru Odpovědět  +1 21.4.2013 17:52
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Cube
Člen
Avatar
Odpovídá na David Čápka
Cube:

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
Nahoru Odpovědět 21.4.2013 20:24
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Cube
Člen
Avatar
Odpovídá na David Čápka
Cube:

: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.