Jump to content
  • Advertisement
Sign in to follow this  
Auxiusvorg

Beginner 2D Physics Engine Help

This topic is 2691 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I have been attempting for some time now to program a 2d Physics engine from which i will make a 3d engine. But Iv finally gotten some collision detection in along with pointmass physics like particles and such.

Im using Blitz 3D as the language and I understand it is not the most efficient but i would rather learn with something simple like blitz before i move to a c++ engine.
I have ran into a few problems
for one after about 300 pointmasses are on screen doing collision checking along with simple verlet-euler integration and after more than 300 are spawned it begins to slow down, and objects at the bottom of a stack of objects get shoved into eachother.

Honestly im sure there are quite a few things i need help with and i dont exactly know what they all are but here is the code in my engine file. The vector type and functions are in a seperate file and if anyone would like to see it i can post that also

Include "Vectors.bb"

Graphics 800,600,32,2
SetBuffer BackBuffer()

FPStimer= CreateTimer(60)

Global dt#=.5
Global pointmasscount = 0


Global G.Vector = New Vector ;Vector for Gravity
G\x=0
G\y=100



;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;
;Pointmass Type;

Type Pointmass

Field P.Vector ;Current Position Vector
Field V.Vector ;Velocity Vector
Field A.Vector ;Acceleration Vector
Field F.Vector ;Force Vector
Field imass#
Field mousedrag#
End Type

;;;;;;;;;;;;;;;;;;;;;;;;;
;Create Some Pointmasses;



;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;
;Main Loop;

While Not KeyHit(1)

WaitTimer FPStimer
Cls
Text 0,0,pointmasscount

CheckMouse()
CheckKeyboard()
CollisionsCheck()
UpdatePointmasses()
DrawPointmasses()

;DrawPointmassVector(P1,P1\F)

Flip

Wend

;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;
;Pointmass Functions;

Function CreatePointmass.Pointmass(x#,y#,fx#,fy#,imass#)
pointmasscount=pointmasscount+1
N.Pointmass = New Pointmass

n\P=New Vector
n\V=New Vector
n\A=New Vector
n\F=New Vector


N\P\x=x
N\P\y=y

N\F\x=fx
N\F\y=fy

N\imass=imass
N\mousedrag=False
Return N

End Function

Function UpdatePointmasses()

For n.Pointmass = Each Pointmass


G=VScalarmultiply(G,GetMassPointmass(n))

If Not n\imass = 0
n\F=Vadd(n\F,G)
EndIf

R.Vector = New Vector

R=n\A
R=Vadd(R,VScalarmultiply(n\F,n\imass))



n\V=Vadd(n\V,VScalarmultiply(R,dt))
n\V=VScalarmultiply(n\V,.94^dt)


n\F=VScalarmultiply(n\F,0)

n\P=Vadd(n\P,VScalarmultiply(n\V,dt))
Text 0,40,n\V\x
Text 0,50,n\V\y
Next

End Function

Function GetMassPointmass(F.Pointmass)

mass#=F\imass*(1/F\imass)

Return mass
End Function

Function DrawPointmasses()

For n.Pointmass = Each Pointmass
Color 255,0,0
Oval n\P\x-15,n\P\y-15,30,30
Color 255,255,255
Oval n\P\x-16,n\P\y-16,31,31,0
Next

End Function

Function ApplyForce(P.Pointmass,magnitude#,angle#)

Tf.Vector = New Vector ;Temporary force vector
Tf\x = magnitude*Cos(angle)
Tf\y = magnitude*Sin(angle)

P\F = Vadd(P\F,Tf)

End Function

;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;
;Collision Checking;

Function CollisionsCheck()


For n.Pointmass = Each Pointmass

For p.Pointmass = Each pointmass
If Not p=n

R.Vector = New Vector
R\x=p\P\x-n\P\x
R\y=p\P\y-n\P\y

If Vmagnitude(R)<50
If Vmagnitude(R)<31

;Vinvert(p\V)
;Vinvert(n\V)

p\V=VScalarmultiply(n\V,.1)

OverlapDist#=32-Vmagnitude(R)
EachOverlapDist#=OverlapDist/2

p\P\x=p\P\x-EachOverlapDist*Cos(Vangle(R))
p\P\y=p\P\y-EachOverlapDist*Sin(Vangle(R))

n\P\x=n\P\x+EachOverlapDist*Cos(Vangle(R))
n\P\y=n\P\y+EachOverlapDist*Sin(Vangle(R))

EndIf
EndIf

EndIf
Next

If n\P\x <= 10

Vinvert(n\V)
n\P\x = 10+1
EndIf

If n\P\x >= GraphicsWidth()-10

Vinvert(n\V)
n\P\x = GraphicsWidth()-10-1

EndIf

If n\P\y <= 10

Vinvert(n\V)
n\P\y = 10+1

EndIf

If n\P\y >= GraphicsHeight()-14

Vinvert(n\V)
n\P\y = GraphicsHeight()-14-1

EndIf

Next

End Function

;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;
;Input Functions;

Function CheckMouse()

If MouseHit(1)
For n.Pointmass = Each Pointmass
If MouseX()>n\P\x-20 And MouseX()<n\P\x+20
If MouseY()>n\P\y-20 And MouseY()<n\P\y+20

If n\mousedrag=0
n\mousedrag=1
EndIf


EndIf
EndIf


Next

EndIf

If MouseHit(2)
For n.Pointmass = Each Pointmass
If MouseX()>n\P\x-20 And MouseX()<n\P\x+20
If MouseY()>n\P\y-20 And MouseY()<n\P\y+20

n\F=VScalarmultiply(n\F,0)

EndIf
EndIf
Next

EndIf

For n.Pointmass = Each Pointmass
If n\mousedrag = 1
If Not MouseDown(1)
n\mousedrag = 0
EndIf

R.Vector = New Vector
R\x=MouseX()-n\P\x
R\y=MouseY()-n\P\y
ApplyForce(n,-Vmagnitude(R)*2,Vangle(R))
EndIf
Next
End Function
Function CheckKeyboard()

If KeyDown(31)
CreatePointmass(MouseX(),MouseY(),Rand(-900,900),-2000,.05)
EndIf

If KeyHit(32)
Vinvert(G)
EndIf
End Function

;;;;;;;;;;;;;;;;;;;;;;;;;;
;Vector Drawing Functions;

Function DrawPointmassVector(R.Pointmass,F.Vector)

N.Vector = New Vector
N = Vadd(R\P,F)

Line R\P\x,R\P\y,N\x,N\y

End Function

Function DrawOriginVector(F.Vector)

Line 0,0,F\x,F\y

End Function

;;;;;;;;;;;;;;;;;;;;;;;;;;

Share this post


Link to post
Share on other sites
Advertisement
Are you testing collisions for every object against all other objects? If so you could try splitting your world into areas like a quadtree. And only test objects against objects within the same grid, or if close enough to another grid... that one as well. Or if you don't need perfect collision, you don't have to check collisions every frame, you could just check them every other frame.

Share this post


Link to post
Share on other sites
I am checking them all against eachother, But only if they are within a certain range of any other object. not exactly using a grid but each object has a radius that is checked and once another object intersects it begins to check for collisions

Share this post


Link to post
Share on other sites

I am checking them all against eachother, But only if they are within a certain range of any other object. not exactly using a grid but each object has a radius that is checked and once another object intersects it begins to check for collisions


Using the quadtree, would also eliminate the radius check, which is basically check every object against every object... also have you profiled the app?

I'm not familiar with blitz, It would help me and maybe others if you could explain in short what your doing. ie
- loop through object
- loop through possible objects checking if they are in range
- test collision...
etc.

oh and one other thing, once you've checked an object against all others, you never have to check that object again. So when you go to test the next object, don't test against the previous one... hopefully that made sense.

Share this post


Link to post
Share on other sites
ok so collisions go like this
some crazy pseudocode



for n= each pointmass
for p= each pointmass

make a vector between the two

if the magnitude of the vector is
less than both the radii of the pointmass objects combined

there is a collision
correct the pointmasses preventing overlapping
swap velocities of pointmasses
next
next

hopefully that makes sense!


EDIT: And no i havent profiled it. I will work on that

Share this post


Link to post
Share on other sites

ok so collisions go like this
some crazy pseudocode



for n= each pointmass
for p= each pointmass

make a vector between the two

if the magnitude of the vector is
less than both the radii of the pointmass objects combined

there is a collision
correct the pointmasses preventing overlapping
swap velocities of pointmasses
next
next

hopefully that makes sense!


EDIT: And no i havent profiled it. I will work on that


well for starters, instead of doing " for p= each pointmass", you could make it so it starts at n+1. Once again I'm not familiar with blitz syntax, but here is a psuedo C loop to show what I'm talking about.


for (n = 0 to maxObjects-1)
{
for (p = n+1 to maxObjects)
{

}
}


This way you're not having to every object over and over again, even though you've dealt with it's collision already.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!