Toon posts:

[C# / XNA 4.0] Camera rotation speed

Pagina: 1
Acties:

Onderwerpen


  • Hyperz
  • Registratie: augustus 2009
  • Laatst online: 15-08 09:03
Hey, ik ben me onlangs beginnen verdiepen in 3D programmeren met XNA omdat me dat nogal interessant leek, ondanks het feit dat wiskunde één van mijn zwakke punten is. Nu heb ik al een paar van de basics onder de knie en ben momenteel bezig met een FPS-style camera class te maken aan de hand van deze tutorial.


C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
public class Camera3D
{
    public const float RotationSpeed = 0.5f;
    public const float MoveSpeed = 30.0f;

    private float xRot;
    private float yRot;
    private MouseState initialMouseState;
    private Viewport viewport;

    public Vector3 Position { get; set; }
    public Vector3 LookAt { get; set; }
    public Matrix Rotation { get; set; }
    public Matrix Projection {get; set;}
    public Matrix View { get; set; }

    public Camera3D(GraphicsDevice graphicsDevice, Vector3 position, Vector3 lookAt, float fieldOfView)
    {
        float aspectRatio = (float)graphicsDevice.DisplayMode.Width / (float)graphicsDevice.DisplayMode.Height;
        float fov = MathHelper.ToRadians(fieldOfView);

        this.Position = position;
        this.LookAt = lookAt;
        this.View = Matrix.CreateLookAt(Position, LookAt, Vector3.Up);
        this.Projection = Matrix.CreatePerspectiveFieldOfView(fov, aspectRatio, 0.01f, 10000.0f);
        this.viewport = graphicsDevice.Viewport;

        Mouse.SetPosition(viewport.Width / 2, viewport.Height / 2);

        this.initialMouseState = Mouse.GetState();
        this.xRot = MathHelper.PiOver2;
        this.yRot = -MathHelper.Pi / 10.0f;
    }

    public Camera3D(GraphicsDevice graphicsDevice, float fieldOfView)
        : this(graphicsDevice, Vector3.Zero, Vector3.Zero, fieldOfView)
    {
    }

    public Camera3D(GraphicsDevice graphicsDevice)
        : this(graphicsDevice, Vector3.Zero, Vector3.Zero, 45.0f)
    {
    }

    public void Update(GameTime gameTime)
    {
        var gt = (float)gameTime.ElapsedGameTime.TotalSeconds;
        var ks = Keyboard.GetState();
        var ms = Mouse.GetState();
        var moveVector = Vector3.Zero;

        if (ks.IsKeyDown(Keys.Z)) moveVector += Vector3.Forward;
        if (ks.IsKeyDown(Keys.S)) moveVector += Vector3.Backward;
        if (ks.IsKeyDown(Keys.Q)) moveVector += Vector3.Left;
        if (ks.IsKeyDown(Keys.D)) moveVector += Vector3.Right;
        if (ks.IsKeyDown(Keys.C)) moveVector += Vector3.Down;
        if (ks.IsKeyDown(Keys.Space)) moveVector += Vector3.Up;

        moveVector *= gt;

        if (ms != initialMouseState)
        {
            float xDifference = ms.X - initialMouseState.X;
            float yDifference = ms.Y - initialMouseState.Y;

            this.xRot -= Camera3D.RotationSpeed * xDifference * gt;
            this.yRot -= Camera3D.RotationSpeed * yDifference * gt;

            Mouse.SetPosition(this.viewport.Width / 2, this.viewport.Height / 2);
        }

        Vector3 rotatedVector, originalTarget, originalUpVector, rotatedTarget, rotatedUpVector;

        this.Rotation = Matrix.CreateRotationX(this.yRot) * Matrix.CreateRotationY(this.xRot);
        rotatedVector = Vector3.Transform(moveVector, this.Rotation);
        this.Position += Camera3D.MoveSpeed * rotatedVector;

        originalTarget = new Vector3(0, 0, -1);
        originalUpVector = new Vector3(0, 1, 0);

        rotatedTarget = Vector3.Transform(originalTarget, this.Rotation);
        this.LookAt = this.Position + rotatedTarget;

        rotatedUpVector = Vector3.Transform(originalUpVector, this.Rotation);

        this.View = Matrix.CreateLookAt(this.Position, this.LookAt, rotatedUpVector);
    }

    public override string ToString()
    {
        return String.Format("CAM Pos:{0}\nCAM Pov:{1}\n", this.Position, this.LookAt);
    }
}


Alles lijkt goed te werken, behalve dat bij een lage framerate de camera rotatie sneller/gevoeliger is dan bij een hoge framerate. Nu begrijp ik niet goed waarom. Ik dacht dat dit stukje dit moest verhelpen (* gt):


C#:
1
2
            this.xRot -= Camera3D.RotationSpeed * xDifference * gt;
            this.yRot -= Camera3D.RotationSpeed * yDifference * gt;


Ik heb nog geprobeerd verschillende variables aan te passen aan de gametime maar zonder succes :-( . Iemand die weet waar het probleem zit?

Alvast bedankt.

Asus P8P67 EVO | i5 2500k (4.8 GHz) | Sapphire HD 7970 Vapor-X GHz Ed. | 8 GB DDR3 1600 | 1 TB HDD


  • .oisyn
  • Registratie: september 2000
  • Laatst online: 21:56

.oisyn

Moderator Devschuur® / Cryptocurrencies

Demotivational Speaker

Logisch, je moet niet vermenigvuldigen met de frametijd aangezien de muisbewegingen zelf niet frametijd-afhankelijk zijn :). De muisbewegingen zijn een accumulatie sinds de vorige frame, en dus een relatieve afstand. Niet een snelheid.

[Voor 36% gewijzigd door .oisyn op 13-10-2010 11:13]

You see, killbots have a preset kill limit. Knowing their weakness, I sent wave after wave of my own men at them until they reached their limit and shut down. Kif, show them the medal I won.


  • roy-t
  • Registratie: oktober 2004
  • Laatst online: 22-09 19:19
Je moet bewegingen altijd laten afhangen van gameTime.ElapsedGameTime.TotalSeconds (of TotalMiliSeconds).

Maar ik zie dat dat in jouw geval al geburt. Wel zie ik dat initial mouse state niet geupdate wordt aan het einde van de update methode.

~ Mijn prog blog! ~ @RoyTries


  • .oisyn
  • Registratie: september 2000
  • Laatst online: 21:56

.oisyn

Moderator Devschuur® / Cryptocurrencies

Demotivational Speaker

roy-t schreef op woensdag 13 oktober 2010 @ 11:00:
Je moet bewegingen altijd laten afhangen van gameTime.ElapsedGameTime.TotalSeconds (of TotalMiliSeconds).
Nonsens. Je moet rekening houden met grootheden. Als je te maken hebt met een snelheid dan moet je die inderdaad omzetten naar afstand door te vermenigvuldigen met de tijd (want afstand = snelheid * tijd). Muisinput is geen snelheid, maar afstand. Je zou er wel eerst een snelheid van kunnen maken door te delen door tijd (want snelheid = afstand / tijd), alleen maar om 'm later weer te vermenigvuldigen met tijd om de afstand terug te krijgen. Nutteloos dus.

[Voor 20% gewijzigd door .oisyn op 13-10-2010 11:17]

You see, killbots have a preset kill limit. Knowing their weakness, I sent wave after wave of my own men at them until they reached their limit and shut down. Kif, show them the medal I won.


  • roy-t
  • Registratie: oktober 2004
  • Laatst online: 22-09 19:19
Ah shit je hebt gelijk.

Hmm met diff (beweging van de muis) constant
verandering = diff * spf; geeft dat bij een lager fps het lijkt alsof er meer bewogen is per seconden.

verandering = diff/spf; klopt wel.


Edit: idd niet fps maar seconds per frame

[Voor 11% gewijzigd door roy-t op 13-10-2010 13:08]

~ Mijn prog blog! ~ @RoyTries


  • .oisyn
  • Registratie: september 2000
  • Laatst online: 21:56

.oisyn

Moderator Devschuur® / Cryptocurrencies

Demotivational Speaker

Nee, het is gewoon
verandering = diff

Logisch ook, want die dingen betekenen hetzelfde.

(En ik neem aan dat je met fps eigenlijk spf bedoelt?)

De code wordt dus:
C#:
1
2
            this.xRot -= Camera3D.RotationSpeed * xDifference; 
            this.yRot -= Camera3D.RotationSpeed * yDifference;

[Voor 56% gewijzigd door .oisyn op 13-10-2010 12:18]

You see, killbots have a preset kill limit. Knowing their weakness, I sent wave after wave of my own men at them until they reached their limit and shut down. Kif, show them the medal I won.


  • Hyperz
  • Registratie: augustus 2009
  • Laatst online: 15-08 09:03
En dat lijkt dus perfect te werken. Ik dacht echt dat ik ergens anders een fout gemaakt had aangezien dat stukje code een vrijwel directe copy/paste is van die tutorial. Dus eigenlijk bevat die tutorial dan een fout :?. In ieder geval bedankt voor de oplossing!
roy-t schreef op woensdag 13 oktober 2010 @ 11:00:
Wel zie ik dat initial mouse state niet geupdate wordt aan het einde van de update methode.
Dat hoeft ook niet aangezien ik de cursor terug in het midden plaats. Moest dat stukje niet goed werken zou ik het snel merken wanneer ik de muis beweeg :).

Asus P8P67 EVO | i5 2500k (4.8 GHz) | Sapphire HD 7970 Vapor-X GHz Ed. | 8 GB DDR3 1600 | 1 TB HDD


  • .oisyn
  • Registratie: september 2000
  • Laatst online: 21:56

.oisyn

Moderator Devschuur® / Cryptocurrencies

Demotivational Speaker

Hyperz schreef op woensdag 13 oktober 2010 @ 13:03:
Dus eigenlijk bevat die tutorial dan een fout :?
Klopt, en dat niet alleen, alle users op het forum doen het ook allemaal fout :D. Frappant dat nog niemand iets gemerkt heeft, waarschijnlijk lopen hun framerates allemaal vrij constant. Ik ga eens een account aanmaken :P

.edit: blijkbaar lukt posten niet. 't Is ook niet echt een heel fantastische site. Was riemers trouwens geen gotter?
.edit2: riemerg

[Voor 21% gewijzigd door .oisyn op 13-10-2010 13:42]

You see, killbots have a preset kill limit. Knowing their weakness, I sent wave after wave of my own men at them until they reached their limit and shut down. Kif, show them the medal I won.


  • roy-t
  • Registratie: oktober 2004
  • Laatst online: 22-09 19:19
.oisyn schreef op woensdag 13 oktober 2010 @ 13:13:
[...]

Klopt, en dat niet alleen, alle users op het forum doen het ook allemaal fout :D. Frappant dat nog niemand iets gemerkt heeft, waarschijnlijk lopen hun framerates allemaal vrij constant. Ik ga eens een account aanmaken :P

.edit: blijkbaar lukt posten niet. 't Is ook niet echt een heel fantastische site. Was riemers trouwens geen gotter?
.edit2: riemerg
Standaard loopt XNA in fixed time step modus, waardoor je (totdat je te veel gaat tekenen) inderdaad een constante framerate hebt.

Verder staan er meer subtiele foutjes op Riemer's website, maar zijn boek schijnt wel erg goed te zijn.

~ Mijn prog blog! ~ @RoyTries

Pagina: 1


Nintendo Switch (OLED model) Apple iPhone 13 LG G1 Google Pixel 6 Call of Duty: Vanguard Samsung Galaxy S21 5G Apple iPad Pro (2021) 11" Wi-Fi, 8GB ram Nintendo Switch Lite

Tweakers vormt samen met Hardware Info, AutoTrack, Gaspedaal.nl, Nationale Vacaturebank, Intermediair en Independer DPG Online Services B.V.
Alle rechten voorbehouden © 1998 - 2021 Hosting door True

Tweakers maakt gebruik van cookies

Bij het bezoeken van het forum plaatst Tweakers alleen functionele en analytische cookies voor optimalisatie en analyse om de website-ervaring te verbeteren. Op het forum worden geen trackingcookies geplaatst. Voor het bekijken van video's en grafieken van derden vragen we je toestemming, we gebruiken daarvoor externe tooling die mogelijk cookies kunnen plaatsen.

Meer informatie vind je in ons cookiebeleid.

Sluiten

Forum cookie-instellingen

Bekijk de onderstaande instellingen en maak je keuze. Meer informatie vind je in ons cookiebeleid.

Functionele en analytische cookies

Deze cookies helpen de website zijn functies uit te voeren en zijn verplicht. Meer details

janee

    Cookies van derden

    Deze cookies kunnen geplaatst worden door derde partijen via ingesloten content en om de gebruikerservaring van de website te verbeteren. Meer details

    janee