Students Save 30%! Learn & create with unlimited courses & creative assets Students Save 30%! Save Now
Advertisement
  1. Game Development
  2. Programming
Gamedevelopment

Hoe maak 2D Custom Physics Machine: Wrywing, Scene, en Jump Table

by
Difficulty:IntermediateLength:LongLanguages:
This post is part of a series called How to Create a Custom Physics Engine.
How to Create a Custom 2D Physics Engine: The Core Engine
How to Create a Custom 2D Physics Engine: Oriented Rigid Bodies

Afrikaans (Afrikaans) translation by Meyria (you can also view the original English article)

In die eerste twee tutoriale in hierdie reeks het ek die onderwerp behandel Impulse Resolution en Core Architecture. Nou is dit tyd om te voeg op sommige van die finale aanrakinge aan ons 2D, impulsgebaseerde fisika-enjin.

Die onderwerpe wat ons in hierdie artikel sal sien is:

  • Wrywing
  • Toneel
  • Botsing Spring Tabel

Ek beveel aan om te lees twee vorige artikels in die reeks voordat jou probeer om hierdie een te oorkom. Sommige belangrike inligting in die vorige artikels is op hierdie artikel gebaseer.

Nota: Alhoewel hierdie tutoriaal voldoen aan die woord C skrif, wat jou in dieselfde omgewing gebruik en tegnieke dieselfde tegnieke en konsepte gebruik.


Video Demo

Hier is 'n vinnige demo van waarna ons in hierdie deel werk:


Wrywing

Wrywing is deel van die botsings resolusie. Wrywing is aFriction gebruik altyd krag op voorwerpe in die teenoorgestelde rigting na die beweging waarin hulle reis. deel van die botsingsresolusie.

In die werklike lewe, wrywing is 'n baie komplekse interaksie tussen verskillende stowwe, en om dit te modelleer, word breë aannames en ramings gemaak. Hierdie aannames word in wiskunde geïmpliseer, en gewoonlik kan iets soos "wrywing deur 'n enkele vektor benader word" - soortgelyk aan hoe stewige liggaamsdinamika werklike interaksies simuleer deur 'n liggaam met eenvormige digtheid aan te neem wat nie skadelik kan wees nie.

Kyk gerus na die video-demo van die eerste artikel in hierdie reeks:

Die interaksies tussen die liggame is baie interessant, en die weerkaatsing tydens botsings voel realisties. Maar sodra die voorwerp op 'n soliede platform land, het hulle net so druk gedruk en van die rand van die skerm af gedryf. Dit is as gevolg van 'n gebrek aan wrywing simulasie.

Impulse, weer?

Soos jou moet onthou van the first article in this series, 'n sekere waarde, j, verteenwoordig die hoeveelheid impuls wat benodig word om die twee indringende voorwerpe tydens 'n botsing te skei. Hierdie hoeveelheid kan na verwys word as jnormal of jN omdat dit gebruik word om die spoed te verander langs normale botsings.

Om 'n wrywingrespons in te sluit behels die berekening van 'n ander grootte, waarna verwys word as jtangent of jT. Wrywing sal as 'n impuls gemodelleer word. Hierdie grootte verander die snelheid van 'n voorwerp langs die negatiewe tangentvektor van die botsing, of met ander woorde langs die wrywingvektor. In twee dimensies is die oplos van hierdie wrywingvektor 'n oplosbare probleem, maar in 3D word die probleem baie meer kompleks.

Wrywing is eenvoudig genoeg, en ons kan die vorige vergelyking vir j gebruik, tensy ons alle normale n gevalle met tangentvektor t vervang.

\[ Verg 1: \\
j = \frac{-(1 + e)(V^{B}-V^{A})\cdot n)}
{\frac{1}{mass^A} + \frac{1}{mass^B}}\]

Vervang n met t:

\[ Verg 2: \\
j = \frac{-(1 + e)((V^{B}-V^{A})\cdot t)}
{\frac{1}{mass^A} + \frac{1}{mass^B}}\]

Alhoewel slegs een geval van n in hierdie vergelyking deur t vervang word, word na die rotasie ingevoer, moet nog enkele voorbeelde anders as 'n enkele een in die vergelyking van vergelyking 2 vervang word.

Nou kom die kwessie van hoe om t te bereken. Die raaklynvektor is 'n vektor loodreg op die botsings normaal wat meer na die normale kyk. Dit mag dalk verwarrend wees - moenie bekommerd wees nie, ek het 'n diagram!

Hieronder kan u die raaklynvektor loodreg op die normale sien. Die tangentvektor kan óf na links of regs wys. Aan die linkerkant sou "meer weg" van die relatiewe snelheid wees. Egter, dit word gedefinieer as loodreg op die normale "meer rigting" relatiewe spoed.

Vectors of various types within the timeframe of a collision of rigid bodies.
Vektore van verskillende tipes in die tydsbestek van botsings van voorwerpe sal rigied wees.

Soos vroeër gesê, sal wrywing die vektor wees wat handel oor die raaklynvektor. Dit beteken dat die rigting waarin wrywing toegepas kan word, direk bereken word, aangesien normale vektore tydens botsingsdeteksie aangetref word.

As jou dit weet, is die raaklynvektor (waar n 'n normale botsing is):

\[ V^R = V^{B}-V^{A} \\
t = V^R - (V^R \cdot n) * n \]

Al wat oorbly om te oplos vir jt, die grootte van die wrywing, is om die waarde direk te bereken deur die vergelykings hierbo te gebruik. Daar is 'n paar baie ingewikkelde dele sodra hierdie waarde bereken word wat binnekort bespreek sal word, dit is dus nie die laaste ding wat nodig is in ons botsingsbeslissing nie:

Bogenoemde kode volg direk vergelyking 2. Weereens, is dit belangrik om te besef dat die wrywingvektor in die teenoorgestelde rigting van ons raakvektor dui en dus moet ons 'n negatiewe teken toepas wanneer ons die relatiewe spoed langs die raaklyn draai om die relatiewe snelheid langs die raaklynvektor te voltooi. Hierdie negatiewe teken omkeer die spoed van die raaklyn en skielik wys in die rigting waar wrywing benader moet word.

Coulomb se Wet

Coulomb's law is deel van die wrywing simulasie wat die meeste programmeerders probleme ondervind. Ek moet self leer om die korrekte modellering te vind. Die truuk is dat Coulomb se wet ongelykheid is.

Coulomb wrywingstoestande:

\[Verg 3: \\
F_f <= \mu F_n \]

Met ander woorde, die wrywingskrag is altyd minder as of gelyk aan die normale krag vermenigvuldig met 'n konstante μ (waarvan die waarde afhang van die materiaal van die voorwerp).

Normale styl is net ons groot krag j vermenigvuldig met normale botsing. Dus, as ons jt opgelos word (wat wrywingsterkte verteenwoordig) minder is as μ keer die normale krag, dan kan ons jt grootte as wrywing gebruik. Indien nie, dan moet ons die normale kragtyd μ gebruik. Hierdie "ander" geval is 'n vorm om ons wrywing onder sekere maksimum waarde vas te hou. Maksimum is die normale kragtye μ.

Die kern van Coulomb se wet is om hierdie klemprosedure uit te voer. Hierdie klem blyk die moeilikste deel van 'n wrywing-simulasie te wees vir impulsgebaseerde resolusie om dokumentasie oral te vind - tot nou toe, ten minste! Die meeste witskrifte wat ek oor die onderwerp kan kry, kan nie heeltemal oorskakel nie, of stop kort en onvanpas (of nie-bestaande) klemprosedures toepas. Hopelik het jou nou 'n waardering dat jou verstaan ​​dat dit reg is belangrik.

Laat ons die klem in een slag uitsteek voordat u iets verduidelik. Die volgende kodeblok is 'n voorbeeld van die vorige kode met 'n volledige klemprosedure en 'n gelyktydige impulstoepassing:

Ek het besluit om hierdie formule te gebruik om die wrywingskoëffisiënt tussen twee liggame op te los, gegewe die koëffisiënte vir elke liggaam:

\[Verg 4: \\
Wrywing = \ sqrt [] {Wrywing ^ 2_A + Wrywing ^ 2_B} \]

Ek het eintlik mense gesien wat dit in hul eie fisika masjien gedoen het, en ek het die resultate gehou. Die gemiddelde van die twee waardes sal goed werk om die gebruik van vierkantswortels te voorkom. Inderdaad, enige vorm van seleksie van die wrywingskoëffisiënt sal werk; dit is net wat ek liefhet. Nog 'n opsie is om 'n opsoektabel te gebruik waar elke liggaamsoort as 'n indeks gebruik word in 'n 2D tabel.

Dit is belangrik dat die absolute waarde van jt gebruik word in vergelyking, aangesien die verhouding teoreties die ruwe hoeveelheid onder 'n sekere drempel klamp. Aangesien j altyd positief is, moet dit omgekeer word om die presiese wrywingvektor te verteenwoordig, in die geval dat 'n dinamiese wrywing gebruik word.

Statiese en Dinamiese Wrywing

In die laaste kodeks word statiese en dinamiese wrywing sonder verduideliking bekendgestel! Ek sal hierdie hele afdeling wy om die verskil tussen en die behoeftes van hierdie twee soorte waardes te verduidelik.

Iets interessant gebeur met wrywing: dit benodig 'aktiveringsenergie' sodat dinge kan begin beweeg wanneer hulle heeltemal rus. Wanneer twee voorwerpe interafhanklik is in die werklike lewe, neem dit genoeg energie om een ​​te druk en dit te laat beweeg. Maar sodra jou iets kry om te gly, is dit dikwels makliker om dit te hou van daardie oomblik af.

Dit is as gevolg van die manier waarop wrywing op 'n mikroskopiese vlak werk. Nog 'n beeld help hier:

Microscopic view of what causes energy of activation due to friction.
Mikroskopiese siening van wat veroorsaak dat energie van aktivering as gevolg van wrywing.

Soosjou kan sien, is 'n klein misvorming tussen oppervlaktes regtig die hoofoorsaak wat in die eerste plek wrywing skep. Wanneer een voorwerp berus op die ander, rus die mikroskopiese misvorming tussen voorwerpe, sluit mekaar. Hierdie moet gebreek of geskei word sodat die voorwerpe teen mekaar kan skuif.

Ons het 'n manier nodig om dit in ons masjien te modelleer. Die eenvoudige oplossing is om elke tipe materiaal te voorsien met twee wrywingswaardes: een vir statiese en een vir dinamiese.

Die statiese wrywing word gebruik om ons jt grootte vas te klamp. As die grootte van jt wat opgelos word, laag genoeg is (onder ons drumpel), dan kan ons aanvaar dat die voorwerp rus, of amper soos rus en die hele jt gebruik as 'n hupstoot.

Op die flipkant, as jt opgelos is, is ons bo die drumpel, kan aanvaar word dat die voorwerp 'aktiveringsenergie' geskend het, en in sulke situasies word 'n laer wrywing impuls gebruik, wat deur kleiner wrywingskoëffisiënte verteenwoordig word. en 'n effens ander impulsberekening.


Toneel

Gestel jou het nie enige deel van die Wrywingsafdeling misloop nie, voltooi dit goed! Jou het die moeilikste deel van hierdie hele reeks voltooi (na my mening).

Die Scene klas dien as 'n houer vir alles wat 'n fisika simulasiesituasie behels. Dit noem en gebruik die resultate van 'n breë fase, bevat alle rigiede liggame, hardloop botsings tjeks en oproepe resolusie. Dit integreer ook alle lewende voorwerpe. Tone wissel ook met gebruikers (soos in programmeerders wat fisika masjiene gebruik).

Hier is 'n voorbeeld van 'n toneelstruktuur aansig:

Daar is niks besonder kompleks oor die Scene klas nie. Die idee is om die gebruiker toe te laat om stewige liggame maklik by te voeg en te verwyder. Die BodyDef is 'n struktuur wat alle inligting oor 'n starre liggaam berg, en kan gebruik word om gebruikers toe te laat om waardes as 'n soort konfigurasiestruktuur in te voeg.

Die ander belangrike funksie is Step (). Hierdie funksie voer een ronde botsing, resolusie en integrasie tjeks uit. Dit moet genoem word binne die tydsopname lus uiteengesit in die tweede artikel van hierdie reeks.

Om 'n punt of AABB te vra, behels kontrole om te sien watter voorwerpe werklik bots met 'n wyser of AABB binne die toneel. Dit vergemaklik spelverwante logika om te sien hoe dinge in die wêreld geplaas word.


Jump Table

Ons het 'n maklike manier nodig om die botsingsfunksie te kies wat genoem moet word, gegrond op die tipe twee verskillende voorwerpe.

In C++ is daar twee hoof maniere wat ek ken: dubbele aflewering en 2D springtafels. In my persoonlike toetse het ek die 2D springtafel vir die superieur gevind, so ek gaan meer in detail oor hoe om dit te implementeer. As jou van plan is om 'n ander taal as C of C++ te gebruik, is ek seker dat 'n verskeidenheid funksie of objekfunksies soortgelyk aan 'n funksietabelwyser (wat nog 'n rede is waarom ek verkies het om oor springtafels te praat eerder as ander opsies wat spesifiek vir C++ ).

Die springtafel in C of C++ is 'n wyserfunksietabel. 'N Indeks wat 'n arbitrêre naam of konstante verteenwoordig, word gebruik om in 'n tabel te indekseer en 'n spesifieke funksie te noem. Die gebruik daarvan kan so lyk vir 'n 1D springtafel:

Bogenoemde kode eintlik naboots wat C + + taal self implementeer met virtuele funksie oproepe en oorerwing. Egter, C ++ implementeer slegs 'n enkele dimensionele virtuele oproep. Die 2D tafel kan met die hand gebou word.

Hier is 'n paar psuedokode vir 2D springtafels om botsingsroetines te noem:

En daar het ons dit! Die werklike tipe van elke collider kan gebruik word om te indekseer in 'n 2D-skikking en kies 'n funksie om die botsing te voltooi.

Let egter daarop dat AABBvsCircle en CirclevsAABB amper duplikate is. Dit is baie belangrik! Normale vereistes moet omgekeer word vir een van hierdie twee funksies, en dit is die enigste verskil tussen die twee. Dit maak voorsiening vir konsekwente botsingsresolusie, ongeag die kombinasie van voorwerpe om te voltooi.


Gevolgtrekking

Tans het ons 'n groot aantal onderwerpe behandel om 'n spesiale, stewige liggaamfisika enjin heeltemal van nuuts af op te rig! Crash resolusie, wrywing en masjienargitektuur is al die onderwerpe wat tot dusver bespreek is. 'N Hoogs suksesvolle fisika-enjin wat geskik is vir baie tweedimensionele produksievlakspele kan gebou word met die kennis wat tot dusver in die reeks aangebied word.

Ek sien uit na die toekoms, en ek beplan om nog 'n artikel te skryf wat heeltemal aan 'n hoogs gewilde kenmerk gewy is: rotasie en oriëntasie. Objek georiënteerde is baie interessant om interaksie met mekaar te sien, en is die finale deel wat ons persoonlike fisika enjin vereis.

Rotasie resolusie is redelik eenvoudig, hoewel botsings opsporing baie kompleks is. Sterkte tot volgende keer, en stel asseblief 'n vraag of plaas 'n opmerking hieronder!

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.