Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Toa

Alter Hase

  • »Toa« ist der Autor dieses Themas

Beiträge: 944

Beruf: Research associate

  • Private Nachricht senden

1

21.10.2009, 22:41

Box2D Polygon um einen bestimmten Punkt drehen

Guten abend,

ich möchte mir eine Funktion schreiben die ein Box2D Polygon um einen beliebigen Punkt dreht und nicht immer um dessen Mittelpunkt.
Das Problem, welches ich habe liegt weniger beim Algorithmus sondern es ist eher mehr ein Box2D Problem.

Im Grunde setze ich mein erstellen des Shapes für das Polygon als Userdata die Shapeinformationen damit ich später während des simulieren an die vertices des Polygons komme.

C-/C++-Quelltext

1
2
3
4
5
6
7
b2PolygonDef shapeDef;
shapeDef.vertexCount = iCount;
shapeDef.density = fDensity;
shapeDef.restitution = fRestitution;
shapeDef.friction = fFriction;
shapeDef.userData = &shapeDef;  // Shape Informationen als UserData!

bBody->CreateShape(&shapeDef);


und hier ist meine Rotationsfunktion:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void Game::CGeometry::RotateForms( double fRotation, Core::CVector vPos )
{
    for ( set<CForm *>::iterator it = sForms.begin(); it != sForms.end(); ++it ) {
    
        for ( b2Shape *ShapeList = (*it)->GetBody()->GetShapeList(); ShapeList; ShapeList = ShapeList->GetNext() ) {
            if( ShapeList->GetType() == e_polygonShape ) {
                b2PolygonDef* data = (b2PolygonDef*)ShapeList->GetUserData();

                for( unsigned int i = 0; i < data->vertexCount; i++ ) {
                    data->vertices[i].x -= vPos.X;
                    data->vertices[i].y -= vPos.Y;

                    data->vertices[i].x = data->vertices[i].x * cos( fRotation ) - data->vertices[i].y * sin( fRotation );
                    data->vertices[i].y = data->vertices[i].y * cos( fRotation ) + data->vertices[i].x * sin( fRotation );

                    data->vertices[i].x += vPos.X;
                    data->vertices[i].y += vPos.Y;
                }
            }
        }
    }
}


das Problem ist nun folgende Stelle:

C-/C++-Quelltext

1
    b2PolygonDef* data = (b2PolygonDef*)ShapeList->GetUserData();


Hier möchte ich mir die vorher gespeicherte Userdata (Die Shape informationen holen). Komischerweise stehen als VertexCount Angaben sehr sehr große Werte, beispielsweise 333944.

Kennt sich vielleicht jemand mit Box2D aus und weiß was ich falsch mache?

Grüße Toa

2

21.10.2009, 23:02

ich kenne mich zwar nicht mit physik libs aus, möchte aber mal was fragen:

basiert das hier (http://www.youtube.com/watch?v=4QOTXEpDuU4) auf box2d? wenn dus hinkriegst hier die welt zu rotieren wäre das interessant und meines wissens eine noch nicht da gewesene spielerfahrung. viel erfolg damit ;)

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

3

21.10.2009, 23:13

Zitat von »"fred2507"«

wenn dus hinkriegst hier die welt zu rotieren wäre das interessant und meines wissens eine noch nicht da gewesene spielerfahrung. viel erfolg damit ;)


Ganz noch nie dagewesen nicht gerade. ;)
Es gibt ein iPhone Spiel, bei dem du damit arbeiten musst die Spielwelt zu drehen, respektive das Telefon, wenn du magnetisch an der Decke hängst.. Finde die Idee echt toll und die Umsetzung auf dem iPhone genial. :)

Toa

Alter Hase

  • »Toa« ist der Autor dieses Themas

Beiträge: 944

Beruf: Research associate

  • Private Nachricht senden

4

21.10.2009, 23:21

Ja also alles noch geheim was es wird :D (Aber Steuern wird man das ganze mit der Wiimote^^) . Fehler ist jetzt soweit fixed. ShapeDef war nur lokal und nach verlassen nicht mehr da^^

Nur ich glaube der Algorithmus funktioniert nicht -..- Aber eigentlich müsste es funktionieren. Im Grunde mach ich nichts anderes als:

1. Drepunkt von den Vertices Koordinaten abziehen
2. Drehmatrix anwenden
3. Drehpunkt wieder drauf addieren

sieht jemand nen Fehler? http://nopaste.com/p/avLLFydQT

Eventuell kann man die Werte von den Vertices auch während der simulation nicht verändern das wäre schlecht

ChrisJ

Alter Hase

Beiträge: 487

Wohnort: Schweich

Beruf: Schüler

  • Private Nachricht senden

5

22.10.2009, 10:46

Re: Box2D Polygon um einen bestimmten Punkt drehen

wenn ich nicht völlig falsch liege, sollte die rotation ungefähr so aussehen:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
vec2 pivot;
float rot;
for(int i = 0; i < num_vertices; ++i) {
vec2 diff = vertices[i].pos - pivot;
vec2 len = sqrt(diff.x * diff.x + diff.y * diff.y;
vertices[i].pos.x += cos(rot) * len;
vertices[i].pos.y += sin(rot) * len;
}
"Don't trust your eyes: They are a hell of a lot smarter than you are"

Toa

Alter Hase

  • »Toa« ist der Autor dieses Themas

Beiträge: 944

Beruf: Research associate

  • Private Nachricht senden

6

22.10.2009, 12:21

Im Grunde habe ich die Formeln für die Drehmatrix genommen:
http://de.wikipedia.org/wiki/Drehmatrix

Aber ich glaube solangsam man kann während der simulation in Box2D nichts an den vertices der Bodies machen :/ D.h keine Drehung um einen anderen Punkt, d.h Problem noch nicht gelöst.

Deshalb habe ich mal einen anderen Ansatz gewählt. Box2D bietet nämlich die Funktion SetXForm( Pos, angle ), welche eine statische Form während der Simulation drehen (Um ihren Mittelpunkt -.- ) und Verschieben kann.

Da eine Drehung um enen anderen Punkt nichts anderes ist als eine Drehung um den Mittelpunkt + eine Verschiebung, sieht ein Code nun so aus:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void Game::CGeometry::RotateForms( double fRotation, b2Vec2 vPos )
{
    for ( set<CForm *>::iterator it = sForms.begin(); it != sForms.end(); ++it ) {
        
        //Abstand vom Mittelpunkt zum Verschiebungspunkt

        b2Vec2 vdistance( (*it)->GetPosition().X - vPos.x, (*it)->GetPosition().Y - vPos.y );

        b2Vec2 vNewPos( cos( fRotation ) * vdistance.x - sin( fRotation ) * vdistance.y , sin( fRotation ) * vdistance.x + cos( fRotation ) * vdistance.y );

        //Verschiebung

        vNewPos += vPos;

        //In Box2D Koordinaten umrechnen

        vNewPos *= Game::COORDFACTOR;

        (*it)->GetBody()->SetXForm( vNewPos  , fRotation );
    }
}


Aber funktionieren tut es noch nicht, beispielweise wenn ich eine Rotation von 0 habe verschiebt er trotzdem sehr seltsam...

Hier hab ich mal die Drehung um 400|300 getestet, um welches sich auch der Hintergrund dreht, und eigentlich bei gleichem Drehsinn müssten die Formen ja richtig übereinander liegen,... aber seht selbst:
http://www.youtube.com/watch?v=4UnMe38_C78

idontknow

unregistriert

7

22.10.2009, 18:03

kannst du nicht um den Mittelpunkt drehen und dann in Richtung von deinem eigentlichen Rotationspunkt verschieben sodass es passt quasi das ganze nur simulieren?
Wäre nur ne Idee!

8

22.10.2009, 18:33

nutzt du vertexquads auf die du texturen legst? dann könntest du du doch einfach die projektionsmatrix rotieren und die gravitation ändern. so hast du an den eigentlichen objektpoligonen nichts verändert aber die spielwelt gedreht.

Toa

Alter Hase

  • »Toa« ist der Autor dieses Themas

Beiträge: 944

Beruf: Research associate

  • Private Nachricht senden

9

22.10.2009, 19:29

@ idontknow: Genau den Ansatz wähle ich doch nun^^ (siehe zwei Posts drüber)

@fred: Das ganze ist ja Tilebased, und ich erzeuge ein rendertarget d.h ich rendere die Texturen der Sprites die momentan zu sehen sind auf ein großes Sprite und drehe das

Werbeanzeige