Seite 1 von 1

Bullet Rigidbody innerhalb anderen Collider

Verfasst: 13.02.2024, 20:18
von Andy90
Hallo,

ich bin gerade dabei mein eigenes 2D physics system auf bullet umzustellen, da ich bullet auch für 3D Physik nutze. Das lustige ist jedoch, dass es für 3D super funktioniert und für 2D Probleme macht.

Es ist nämlich so, dass wenn ich ein Rigedbody auf einen anderen (mit einer masse 0) fallen lasse, das dieser manchmal in den andere herein fällt und es dazu kommt, das er auch durch den anderen hindurch fällt. Ich habe bereits den Linear und Angular factor angepasst.

Code: Alles auswählen

public Vec3 LinearFactor { get; set; } = new Vec3(1, 1, 0);
public Vec3 AngularFactor { get; set; } = new Vec3(0, 1, 0);
Beste Grüße

Andy

Re: Bullet Rigidbody innerhalb anderen Collider

Verfasst: 15.02.2024, 08:59
von Jonathan
Naja, Physik ist kompliziert und du lieferst nicht gerade viele Informationen. Das Standardvorgehen wäre wohl, das Problem erstmal reproduzierbar zu machen, d.h. Spielobjekte so zu initialisieren dass das Problem jedes mal Auftritt. Dann wäre z.B. ein Screenshot unmittelbar vor und nach der Kollision (oder nicht-Kollision) nützlich um zu sehen, was eigentlich passiert.

Aber was Simulationen generell stabil macht: Die Schrittweite (das Time-Delta pro simulierten Frame), die Geschwindigkeiten der Objekte, und deren Größe müssen aufeinander abgestimmt sein. Time Delta mal Geschwindigkeit ergibt die Schrittweite im Raum pro Frame, und wenn diese zu groß im Verhältnis zur Objektgröße ist, kriegst du Probleme. Dementsprechend sind auch sehr dünne Objekte kritisch.

Re: Bullet Rigidbody innerhalb anderen Collider

Verfasst: 17.02.2024, 07:54
von gombolo
ja ist schwer was zu sagen...irgendwie stört mich der Wert 0 bei der Masse von eines dieser Objekte. Ändere diesen mal...keine Ahnung auf 0.001 oder so. Schau mal was passiert.

Re: Bullet Rigidbody innerhalb anderen Collider

Verfasst: 17.02.2024, 08:44
von Jonathan
Normalerweise setzt man die Masse auf 0 um zu signalisieren, dass das Objekt unendlich schwer ist und sich nicht bewegen soll (so spart man sich einfach eine extra Variable, und eine Masse von 0 würde ja eh alles immer direkt explodieren lassen und daher muss man den Test vermutlich eh machen, oder halt Hoffen, dass der User keinen Quatsch macht.). Bin mir halbwegs sicher, dass das auch für Bullet gilt.

Re: Bullet Rigidbody innerhalb anderen Collider

Verfasst: 17.02.2024, 22:17
von Andy90
Hallo, ja mit der Schrittweite und der Subticks habe ich es hinbekommen, dass die Figur schneller fällt und dabei nicht in das neue Objekt herein fällt. Ich bin aber dennoch weiter an der Sache dran.

Wenn ich die Masse ändere, ist das Objekt nicht mehr Statisch und würde auch von der Gravitation angezogen. Wenn die Masse auf 0 gesetzt wird, wird das Objekt unendlich schwer, habe ich auch so verstanden. Es gibt wohl auch eine Funktion um Fehler zu beheben in der Simulation, da muss ich mich noch etwas besser informieren.

Re: Bullet Rigidbody innerhalb anderen Collider

Verfasst: 17.02.2024, 23:38
von Chromanoid
Ich würde mir gut überlegen für diesen Fall Box2D zu nehmen. Du musst da glaube ich recht viel umkonfigurieren damit das gut geht und dann ist es vermutlich immer noch nicht so gut wie eine auf 2D optimierte Engine. Wenn es trotzdem. Bullet sein soll, hast du Dir das hier angeschaut? https://github.com/AndresTraks/BulletSh ... x2DDemo.cs

Re: Bullet Rigidbody innerhalb anderen Collider

Verfasst: 18.02.2024, 14:03
von Jonathan
Andy90 hat geschrieben: 17.02.2024, 22:17Es gibt wohl auch eine Funktion um Fehler zu beheben in der Simulation, da muss ich mich noch etwas besser informieren.
Aber erwarte kein "ich stell es richtig ein und dann funktioniert es immer perfekt". Numerische Simulationen funktionieren immer nur in einem gewissen Parameterintervall, du musst also eine ungefähre Vorstellung von deiner Szene haben und Dinge wie Schrittweite etc. entsprechend so setzen, das es mit den Größen / Geschwindigkeiten die du erwartest immer funktioniert (Plus etwas Sicherheitsspielraum). Du kannst zwar fast immer Rechenzeit oder Speicherverbrauch für zusätzliche Stabilität und Robustheit opfern, aber willst das halt so wenig wie möglich tun, weil man mit Rechenzeit und Speicherplatz auch so viele andere schöne Dinge machen kann ;)

Re: Bullet Rigidbody innerhalb anderen Collider

Verfasst: 19.02.2024, 16:54
von Andy90
Ich habe nun gemerkt, dass auch in meiner 3D Physic mit Bullet es zu einem Problem kommt. Es ist nämlich so, dass die Rotation nicht mit der Rotation von glm überein stimmt. Solange ich nur 1 Achse Rotiere, gibt es kein Problem. Sobald ich aber eine 2 dazu nehme, kommt es zu gravierenden abweichungen.

Hier ist meine GLM Rotation und die MVP Matrix dazu

Code: Alles auswählen

        public static mat4 GetModelRotation(GameElement element)
        {
            Vec3 rotation = Utils.GetElementWorldRotation(element);
            return mat4.RotateX(rotation.X) * mat4.RotateY(rotation.Y) * mat4.RotateZ(rotation.Z);
        }
        
        //// Dann im Renderen
        
        mat4 mt_mat = Utils.GetModelTransformation(element);
	mat4 mr_mat = Utils.GetModelRotation(element);
	mat4 ms_mat = Utils.GetModelScale(element);
	mat4 m_mat = mt_mat * mr_mat * ms_mat;
	mat4 mvp = p_mat * v_mat * m_mat;
und hier der Bullet Code. Transformation und Scale Passsen, nur die Rotation mach Problemme

Code: Alles auswählen

        public void UpdateRigidBody()
        {
            Vec3 location = Utils.GetElementWorldLocation(Parent);
            Vec3 rotation = Utils.GetElementWorldRotation(Parent);

            BulletSharp.Math.Matrix transform = BulletSharp.Math.Matrix.Translation(location.X, location.Y, location.Z);
            BulletSharp.Math.Matrix rotMat = BulletSharp.Math.Matrix.RotationYawPitchRoll(rotation.Y, rotation.X, rotation.Z);/* BulletSharp.Math.Matrix.RotationX(rotation.X) * BulletSharp.Math.Matrix.RotationY(rotation.Y) * BulletSharp.Math.Matrix.RotationZ(rotation.Z);*/
            this.RigidBody.MotionState = new DefaultMotionState(transform * rotMat);

            Vec3 scale = Utils.GetElementWorldScale(this.Parent);
            this.RigidBody.CollisionShape.LocalScaling = new Vector3(scale.X, scale.Y, scale.Z);
        }
und hier der Fehler, es schaut so aus, als wäre die Rotation gespiegelt.
Fehler.png

Re: Bullet Rigidbody innerhalb anderen Collider

Verfasst: 19.02.2024, 17:27
von Jonathan
Rotationen in 3D sind halt leider kompliziert. Die Darstellung mit "Winkel um die 3 Hauptachsen" sieht zwar zunächst einfach aus, hat aber letztendlich eine ganze Reihe an Problemen. Es gibt kein eindeutiges richtig oder falsch, eher viele unterschiedliche Konventionen. Mit etwas Glück sind die in der Dokumentation beschrieben, ansonsten hilft nur systematisches Durchprobieren und testen.

Ein paar Ideen:
- In welcher Reihenfolge werden die Rotationen um die Achsen durchgeführt?
- verwenden beide links- bzw. rechtshändige Koordinatensysteme?
- in welcher Reihenfolge musst du die Matrizen multiplizieren?
- Zeilen- oder Spaltenbastiere Matrizen?

Re: Bullet Rigidbody innerhalb anderen Collider

Verfasst: 19.02.2024, 18:40
von Andy90
Ja, versucht habe ich schon alles. Was auch immer ich mache, bei mehr als einer Rotation, kommen diese gespiegelten Ergebnisse raus.

Re: Bullet Rigidbody innerhalb anderen Collider

Verfasst: 19.02.2024, 20:38
von Andy90
Ich habe jetzt heraus gefunden, dass es immer nur eine achse ist, welche die Problemme verursacht. Sobald diese dazu kommt, verschiebt es sich.

Re: Bullet Rigidbody innerhalb anderen Collider

Verfasst: 19.02.2024, 20:46
von Alexander Kornrumpf
Schonmal die Händigkeit der beiden Koordinatensysteme verglichen?

Re: Bullet Rigidbody innerhalb anderen Collider

Verfasst: 19.02.2024, 20:52
von Andy90
Ich hab es eben gelöst bekommen. Zwar etwas unschön aber es geht wohl so

Code: Alles auswählen

        public void UpdateRigidBody()
        {
            Vec3 location = Utils.GetElementWorldLocation(Parent);
            Vec3 rotation = Utils.GetElementWorldRotation(Parent);

            quat quat = new quat(new vec3(Utils.ToRadians(rotation.X), Utils.ToRadians(rotation.Y), Utils.ToRadians(rotation.Z)));
            mat4 rotMat = new mat4(quat);

            BulletSharp.Math.Matrix transform = BulletSharp.Math.Matrix.Translation(location.X, location.Y, location.Z);
            BulletSharp.Math.Matrix btrotMat = new Matrix(rotMat.ToArray());
            this.RigidBody.MotionState = new DefaultMotionState(transform * btrotMat);

            Vec3 scale = Utils.GetElementWorldScale(this.Parent);
            this.RigidBody.CollisionShape.LocalScaling = new Vector3(scale.X, scale.Y, scale.Z);
        }
was ich mache, ist die rotations matrix mit glm erstellen und dann mit den daten als Array eine bullet matrix erstellen, für die Transformation. @Alexander, ich glaube das es daran liegen könnte. Vor allem weil es mit dieser umstellung funktioniert.
working.png