[C++/Direct3D] Rotatie met world-matrix

Pagina: 1
Acties:

  • MisterData
  • Registratie: September 2001
  • Laatst online: 09-04 12:07
Ik heb een simpel programma gemaakt met Direct3D in C++. Ik heb nu een kubus-mesh en een theepot-mesh, beide gemaakt met standaardfuncties in D3DX. Daarnaast heb ik natuurlijk m'n View, Projection en World-matrices goed ingesteld. Het probleem is echter dat zodra ik de world-matrix ga roteren, alle objecten 'los' roteren (dat valt alleen op als ze getranslate zijn, in de andere gevallen zie je het niet omdat ze allemaal rond (0,0,0) roteren). Hoe zorg ik ervoor dat niet de objecten apart maar zegmaar het geheel van objecten, de hele scene dus, roteert?

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 15-04 22:07

NMe

Quia Ego Sic Dico.

Misschien door de camera om een vast punt heen te draaien in plaats van de objecten zelf te roteren? Mijn 3D-kunsten zijn wat roestig, dus verder zou ik het ook niet weten. :P

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 20:17

Janoz

Moderator Devschuur®

!litemod

Het lijkt erop dat je je vermenigvuldiging in de verkeerde volgorde doet. Ik weet niet exact welke orientatie directX gebruikt, maar als je nu je world met de rotatie vermenigvuldigd moet je eens proberen de rotatie met de world te vermenigvuldigen

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21:33

.oisyn

Moderator Devschuur®

Demotivational Speaker

Direct3D gebruikt een left-handed coordinatensysteem waarbij vectoren row-matrices zijn (je doet dus v · M)

MisterData: je world matrix is de transformatie van object space naar world, je view matrix de transformation van world space naar view. Het ligt er een beetje aan wat je wilt. Als je daadwerkelijk je wereld wilt draaien, zul je een extra rotatiematrix moeten maken die je postmultipliet met je world matrix (world' = R * world) voor al je objecten. Als je niet wilt dat de world draait maar eigenlijk dat de camera in tegengestelde richting draait, kun je de rotatiematrix simpelweg premultiplien met je view matrix (view' = R * view).

Voor dit soort dingen is het trouwens wel handig om een scenegraph systeem te makenn met hierarchische transformaties.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

.oisyn schreef op donderdag 01 september 2005 @ 10:44:
Direct3D gebruikt een left-handed coordinatensysteem waarbij vectoren row-matrices zijn (je doet dus v · M)
offtopic:
Tsja.... wie dat ooit heeft bedacht ;) OpenGL doet het wel 'goed' :P

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21:33

.oisyn

Moderator Devschuur®

Demotivational Speaker

wat is 'goed'? Ik prefereer zelf ook left-handed én row-matrices. Ik bedoel, wie heeft nou bedacht dat positief z naar achteren gaat ipv naar voren 8)7. En je muls in omgekeerde volgorde moeten specificeren dan dat je de transformaties doet gaat er bij mij ook niet in :P

(Daarnaast slaat opengl z'n matrices ook nog eens een keer op als row-major ipv column-major, dat druist ook een beetje tegen de gangbare manier in)

[ Voor 22% gewijzigd door .oisyn op 01-09-2005 14:15 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • MisterData
  • Registratie: September 2001
  • Laatst online: 09-04 12:07
.oisyn schreef op donderdag 01 september 2005 @ 10:44:
Direct3D gebruikt een left-handed coordinatensysteem waarbij vectoren row-matrices zijn (je doet dus v · M)

MisterData: je world matrix is de transformatie van object space naar world, je view matrix de transformation van world space naar view. Het ligt er een beetje aan wat je wilt. Als je daadwerkelijk je wereld wilt draaien, zul je een extra rotatiematrix moeten maken die je postmultipliet met je world matrix (world' = R * world) voor al je objecten. Als je niet wilt dat de world draait maar eigenlijk dat de camera in tegengestelde richting draait, kun je de rotatiematrix simpelweg premultiplien met je view matrix (view' = R * view).
Dus ik zou in feite in m'n Scene-class (die een lijst van objecten heeft) nog een extra matrix moeten zetten waarmee ik de matrices van alle objecten moet vermenigvuldigen tijdens het renderen?
Voor dit soort dingen is het trouwens wel handig om een scenegraph systeem te makenn met hierarchische transformaties.
Zoiets heb ik nu, een class DObject die een metode Render heeft (en nog een paar). Zo'n DObject kan een verzameling van meerdere objecten of een losse DMesh zijn :)

  • MisterData
  • Registratie: September 2001
  • Laatst online: 09-04 12:07
Het volgende was de oplossing:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    vector< ref<DObject> >::iterator it = _objects.begin();
    while(it!=_objects.end()) {
        DMatrix temp;

// deze regel:

        D3DXMatrixMultiply(temp.GetMatrix(), (*it)->GetMatrix()->GetMatrix(), _world.GetMatrix());

// en dat was eerst:

        D3DXMatrixMultiply(temp.GetMatrix(),_world.GetMatrix(), (*it)->GetMatrix()->GetMatrix(), );


        device->SetTransform(D3DTS_WORLD,temp.GetMatrix());
        ref<DMaterial> cmat = (*it)->GetMaterial();
        if(cmat) {
            device->SetMaterial(cmat->GetMaterial());
        }

        (*it)->Render(dev);
        it++;
    }

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21:33

.oisyn

Moderator Devschuur®

Demotivational Speaker

MisterData schreef op donderdag 01 september 2005 @ 14:20:
Zoiets heb ik nu, een class DObject die een metode Render heeft (en nog een paar). Zo'n DObject kan een verzameling van meerdere objecten of een losse DMesh zijn :)
Ik bedoel meer dat je een boomstructuur hebt, waarbij elke node een transformatiematrix heeft. Objecten hangen op een bepaalde plek in de boom en hebben dus een totale transformatie van alle matrices van z'n parents met elkaar vermenigvuldigd. Dit is bijvoorbeeld heel handig om dingen als zonnestelsels te modeleren, waarbij elk object een eigen transformatie heeft ten opzichte van z'n parent object. De zon is dan de root, de aarde is een child van de zon met als matrix de rotatie die hij om de zon maakt, en de maan is weer een child van de aarde met een matrix die de baan om een (voor hem stilstaande) aarde beschrijft.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • MisterData
  • Registratie: September 2001
  • Laatst online: 09-04 12:07
.oisyn schreef op donderdag 01 september 2005 @ 14:47:
[...]


Ik bedoel meer dat je een boomstructuur hebt, waarbij elke node een transformatiematrix heeft. Objecten hangen op een bepaalde plek in de boom en hebben dus een totale transformatie van alle matrices van z'n parents met elkaar vermenigvuldigd. Dit is bijvoorbeeld heel handig om dingen als zonnestelsels te modeleren, waarbij elk object een eigen transformatie heeft ten opzichte van z'n parent object. De zon is dan de root, de aarde is een child van de zon met als matrix de rotatie die hij om de zon maakt, en de maan is weer een child van de aarde met een matrix die de baan om een (voor hem stilstaande) aarde beschrijft.
Jaja, wat ik heb is ongeveer hetzelfde denk ik.. .ik zou dan zegmaar een object 'Auto' hebben die een eigen matrix heeft om de auto in zijn geheel te roteren etc., en dat auto-object zou dan weer 'subobjecten' hebben als frame, interieur, etc.. die eventueel ook eigen sub-objecten kunnen hebben?

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

.oisyn schreef op donderdag 01 september 2005 @ 14:13:
wat is 'goed'? Ik prefereer zelf ook left-handed én row-matrices. Ik bedoel, wie heeft nou bedacht dat positief z naar achteren gaat ipv naar voren 8)7. En je muls in omgekeerde volgorde moeten specificeren dan dat je de transformaties doet gaat er bij mij ook niet in :P

(Daarnaast slaat opengl z'n matrices ook nog eens een keer op als row-major ipv column-major, dat druist ook een beetje tegen de gangbare manier in)
Wiskundig is het zo als opengl het doet, daar is een vector eigenlijk altijd een kolom vector. Een matrix is een lineaire operatie, eigenlijk een functie representatie, en het is gebruikelijk om die vooraan te zetten. Dus niet (x)f maar f(x). Column order volgt eigenlijk uit hetzelfde als roworder voor directx; je basis vectoren, of assen, staan nu contiguous in geheugen.

(z+ is eigenlijk omhoog, sommige systemen doen dat ook. y- is dan je scherm in. Maar dat is wel verwarrend geef ik toe, het is makkelijker om z voor diepte te houden, ook standaard eigenlijk tegenwoordig. Anyway ik verveelde me, het was bijna een flamebait ;) )

[ Voor 14% gewijzigd door Zoijar op 01-09-2005 15:59 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21:33

.oisyn

Moderator Devschuur®

Demotivational Speaker

Zoijar schreef op donderdag 01 september 2005 @ 15:56:
Wiskundig is het zo als opengl het doet, daar is een vector eigenlijk altijd een kolom vector.
Je bedoelt dat academici vaak de opengl manier gebruiken (geen toeval ;)). Wiskundig zijn beiden natuurlijk even correct.
z+ is eigenlijk omhoog, sommige systemen doen dat ook. y- is dan je scherm in.
Nogmaals, dat zijn afspraken, geen enkel systeem is "correcter" dan de ander.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

.oisyn schreef op donderdag 01 september 2005 @ 16:19:
Je bedoelt dat academici vaak de opengl manier gebruiken (geen toeval ;)). Wiskundig zijn beiden natuurlijk even correct.
Nou meer dat eigenlijk in elk artikel over bv. lineaire algebra of vector waardige analyse etc. er met kolom vectoren wordt navermenigvuldigd. Dat komt vanwege het verband met operatoren, Fx ipv xF. Voorvermenigvuldigen met rij vectoren is net zoiets als 3- schrijven voor min drie... Maar je hebt gelijk dat het wiskundig wel kan natuurlijk, en ook soms gebeurt indien noodzakelijk.
Nogmaals, dat zijn afspraken, geen enkel systeem is "correcter" dan de ander.
Natuurlijk. Maar ik snap eigenlijk niet waarom dx is afgeweken van wiskundige conventie. Elke matrix voor bv rotatie die je in een boek over openGL of wiskunde iha vindt, zal je moeten transponeren om in dx te gebruiken. Dus als je een ingewikkelde text leest waar uiteindelijk een lastige matrix uitkomt, moet je niet vergeten die nog even te transponeren. Zo is in dx de laatste rij van een 4x4 matrix de translatie component, maar in bv. een standaard boek als 'computer gfx: principles&practice' is het de laatste kolom. Dit zorgt er vaak voor dat mensen rotaties verkeerd om doen in dx.

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 20:17

Janoz

Moderator Devschuur®

!litemod

MisterData schreef op donderdag 01 september 2005 @ 15:48:
[...]


Jaja, wat ik heb is ongeveer hetzelfde denk ik.. .ik zou dan zegmaar een object 'Auto' hebben die een eigen matrix heeft om de auto in zijn geheel te roteren etc., en dat auto-object zou dan weer 'subobjecten' hebben als frame, interieur, etc.. die eventueel ook eigen sub-objecten kunnen hebben?
Nou, meer wiel, deur en aantenne. Het gaat vooral om objecten die bewegen ten opzichte van hun parrent. Frame en interieur zijn statisch tov het object auto en zouden daarom niet een appart object hoeven zijn.

Wanneer je een mannetje hebt dan zou de heup de root kunnen zijn met als kinderen de romp en de bovenbenen. De bovenbenen hebben dan weer de onderbenen als kinderen.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'

Pagina: 1