MaxPhysics Community Project : Main
BlitzMax Forums/BlitzMax Programming/MaxPhysics Community Project : Main
| ||
M A X P H Y S I C S MaxPhysics will be a public module to BlitzMax that will add advanced 2D Collision detection and Collision Response; Physics and Mechanics. Including but not limited to: Polygons, Lines, Circle Shapes that can slide and bounce against eachother. PhysicsObjects that incorporates shapes for collision and gives you advanced collision response in the form of bounce, slide and rotation with such things as mass points taken into account. We may even include ragdoll physics with contrants. Read All About it here: The Official MaxPhysics Main Page. Here you will find the latest information and code relating to the MaxPhysics Project. Note that anyone can change and add stuff here! |
| ||
Old Project Threads The topic that lead to the creation of the project |
| ||
(See the MaxPhysics page instead ) |
| ||
Oh please, use only one thread! I get confused, when I search for the complete module. (I hate cycled links in posts). I can't find a realy start, but it's a good idea, so thumbs up! cu olli |
| ||
The latest and completed source code can be found in the Wiki from now on. |
| ||
Oh please, use only one thread! I get confused, when I search for the complete module. (I hate cycled links in posts). I can't find a realy start, but it's a good idea, so thumbs up! Me too. A big thumbs up, but one topic only please. |
| ||
You need to have a motivation for one topic, right now I see none except chaos, and chaos is not that fun in the long run. (Get's messy and hard to follow) Anyhow I will stay open to any arguments or motivations considering having one topic. Note that there should be at max one codebox per post. Consider we have seven types we have 7 starting posts for just the finnished code. Add to that 3-4 examples and we have at bare minimum 13 posts full with loads of code. And don't forget we want everyone to be able to suggest their view on the project and code additions and tweaks and changes to those additions. So add a couple of posts every day. It's a lot of posts for one topic. That's my motivation for having 4 topics. Now let me hear yours, and I don't think your personal vandetta against links is enought motivation for me ;) |
| ||
I checked out the Wiki. It would be great, we could even then create one page for each file, with both discussion and code and it saves the history and everyone can edit! But there is one major setback. There is no codeboxes! Seems like you have to manually add a space on every line of all files, and that is not going to happen ( any volunteer? ). Or perhaps there is another way? Does anyone know? If anyone wish to help with setting up work in the Wiki then go here: http://www.blitzwiki.org/index.php/MaxPhysics/Line2D http://www.blitzwiki.org/index.php/MaxPhysics |
| ||
There is no codeboxes! You can use <pre></pre> instead. But a real codebox with scrollbars would be the best. |
| ||
Thanks, that solves it. |
| ||
ok - dont think you have this link yet - its a cool physics thing ChronoDoll |
| ||
http://www.christianherta.de/index_physics.html http://www.cs.unc.edu/~ehmann/RigidTutorial/ I see, you have specified at collision detection, but I think a rigid body system is very important. Just start with this: Type TAtom Field Position : TVector2 Field Velocity : TVector2 Field Acceleration : TVector2 Field Mass : Float Method Update() Self.Acceleration = Self.SumForces().Divide(Self.Mass) Self.Velocity = Self.Velocity.VectorAdd(Self.Acceleration) Self.Position = Self.Position.VectorAdd(Self.Velocity) End Method Method SumForces:TVector3() ' like gravity ... End Method End Type cu olli |
| ||
Yea, that would be very cool. Building a rigid body system ontop of our current Vector2D seems like a great addition. I'm unsure but how integrated does a rigid body system need to be? Can we simply add a RigidBody.bmx which uses Vector2D or do you think we need to add methods to Line2d/Cricle2D and so on? I'll update those links to. |
| ||
For 2D stuff you might want to consider verlet integration and mass spring system. Verlet mass-spring system is not the fastest (using rigid bodies only), but when organized in fast and flexible library, would be the most simple and flexible, yet quite powerfull system in many ways. There's lot's of verlet stuff floating around the forums if you want to search for it... I might clean-up and port my 2d physics engine to max, when I get my B3D game ready... |
| ||
I might clean-up and port my 2d physics engine to max, when I get my B3D game ready... And when you do please use our public community Vector2D. As any additions you do can benifit all and you can take benifit of everyone else's great work.The more who use it, the faster it is going to get completed and improved upon. |
| ||
Vertex and Peter I think you where right. One topic is probably better. Now that we have the code in the WIKI, so that everyone can update. I mean nothing beats that. So I'm moving the things back here. One thread from now on. When it's to long I'll make a new one instead. For 2D stuff you might want to consider verlet integration and mass spring system. That would be cool to have an an option. I'm new to it, do you have any links? The system( technique ) we are using now is called projection, I think. |
| ||
You can use projection with it. That's what Jakobsen proposes in his paper. Anywho, this is the one to read: http://www.gotoandplay.it/_articles/2005/08/advCharPhysics.php |
| ||
Good links http://www.peroxide.dk/download/tutorials/tut10/pxdtut10.html www.three14.demon.nl/sweptellipsoid/SweptEllipsoid.pdf http://www.fluidstudios.com/pub/FluidStudios/CollisionDetection/Fluid_Studios_Generic_Collision_Detection_for_Games_Using_Ellipsoids.pdf |
| ||
By far the best game physics system for 2D I have ever seen is the one in Torque 2D. Everything is a convex hull list of points - even a sphere. This for starters introduces SANITY into the equation. There are seperate box and circle commands but these merely WRAP the convex hull primitive. It uses swept collisions to determine collisions between two convex hulls. You can add one object to another via joints for complex systems. It's really the best on the net, but you have to use it or play with the examples to see what I mean. |
| ||
Is it free, is it for BMax, written in BMax? |
| ||
Nope Torque is not free, its a commercial jobbie. |
| ||
The problem that I see right now in this Community Mod it's that it's not a community Mod. What I mean : None helping , None cares. This community looks like that it's filled with 3d programmers , a lot of artists and golden free time people. I can't understand where is the problem to share knowledge? |
| ||
I'm willing to help really I am, I just need more time. I have been reading every thread. |
| ||
Just seen this thread. Vertex is spot on. That's the same method I use for my physics stuffs. a=F/m vel = vel + a * dt pos = pos + vel * dt Just gotta rememer to put the delta time (dt) in there. |
| ||
You mean his TAtom type? I still don't see how it would fit into the system. Is a object built from several atoms then? How do we handle rotations and such with atoms? I would assume the total mass of an object consisting of atmos is the atmos combined mass. But for velocity how would this work? They will always share the same velocity , acceleration and force if they are rigid and if they are in springs then we need some functions to deal with that. Or is our MaxPhysicsObject the same thing with another name? Please post an example with code, I would love to see it and see it I can help add this! |
| ||
No not the TAtom type, just the forces, velocity, and position stuff. |
| ||
Another vote for Verlet integration. It's fast and far more stable than the Euler method. |
| ||
Start working then ;) Before you dig to deep, put up a TO DO list in the Wiki so everyone can follow the progress and come with ideas. Also add a page for code for this. |
| ||
Start working then ;) http://blitzbasic.com/logs/userlog.php?user=8095&log=413 :) |
| ||
http://www.flipcode.com/articles/index.shtml For those how don't know this is a great site with great articles. At last I found a well documented (book) about Geometry and Vectors to the 3D Geometry Primer siries. Nessesary knowledge for evryone how wands to create a game. teamonkey : Nice Link you have in your Worklog. Thanks for pointing it out. |
| ||
Wow, that is amazing for less than 200 lines of code! I really think you should add this to the Max Physics Project. If you have any questions, just ask. |
| ||
teamonkey : As you all ready know this think needs to have a collision engine to work. Unless you wand something like that : http://www.blitzmax.com/Community/posts.php?topic=50079&hl=physics You will see that the guy it's from the document.(Hitman) |
| ||
I was wondering, with all these new modules coming out by everyone. does BRL have any plans on Including them into the Max release ? I mean if I hit Sync mods will it ever sync the added or possibly BRL supported modules ? If this already happens Ignore me pls, if not tho, then I think BRL should support special mods, this being one of those id like to see come with Max when you buy it or when you click Sync mods. Just Wonderin ... |
| ||
When we are done I'll probably send BRL a mail and ask, but before we have something "complete" which can be used "out-of-the-box" for physics I'm going to wait. The Vector Library and A lot of the collisions already work (Line, Circle) but not Polygons yet. If you want to use the Vector2D library, check the WIKI and copy/paste. |
| ||
I don't really know if this mod is good or ideal for being an official mod mainly because I heard mark planned to do his own / use ode for physics in the up coming 3d module. I don't know if I want delta time in my physics to begin with, but I applaud you on the valiant efforts you've all achieved so far. |
| ||
I don't know if I want delta time in my physics to begin with That is a very strange comment. You almost make it sounds like we force the use of Delta Time in the library, which we don't. We haven't even make one single example where we use delta time yet. I don't really know if this mod is good or ideal for being an official mod mainly because I heard mark planned to do his own / use ode for physics in the up coming 3d module. An even bigger reason for Mark to actually help us with this module so it will be compatible with his plans for 3D. And if he already have a physics module of his own I don't see why he does not share it or combine it into this project. If he or anyone else improves BlitzMax, BRL is the one who gains on it, by making BMax a better language. |
| ||
Wave... After some thinking and some looking to the mirror I realized that I am not a person with the ability and knowledge to work in this project. I also feel ashamed with my actions to the project. It look like that I had destroyed the begining of this project. Please make new topics for the newcomers without all of my posts to be clearer for the people how may work for this project. See you around... |
| ||
It look like that I had destroyed the begining of this project. I can't agree. You did your part and you did it good. We woudn't have come this far without your efforts. |
| ||
I just wana say that as one of probably many, watching this project I can only hope that you persist in it.. What I would love is fully working 2D Physics. cos I'm sure Mark said at some point in the past that he was working on 3D Physics.. Also cant contrubite its never been my strong point which is why im watching your progress.. Keep up the good work. |
| ||
Another vote for Verlet integration. It's fast and far more stable than the Euler method. I also would highly reccomend the verlet method. If you don't know what verlet is, read this. Verlet is far better than the "standard" method (like Chroma's): a=F/m vel = vel + a * dt pos = pos + vel * dt It's more stable, accurate, and very fast. By far the best game physics system for 2D I have ever seen is the one in Torque 2D. Everything is a convex hull list of points - even a sphere. This for starters introduces SANITY into the equation. These "points" are the basis of verlet rigid body physics. If I'm not mistaken, the points don't even need to be convex. |
| ||
Here: And here's an example to test it: This is a quick and simple 2D physics engine I made last night. It still lacks collision other than the bounding box of the world, but as it is it's kindof fun to play with anyway. Click+drag to move a physics object around the screen. It runs at well over 500 FPS on my machine (3 Ghz) with 200 iterations and debug off (for non-benchmarking use, you would normally use ~5 iterations, which means a possible 20,000 FPS not including render time :) ). And the code I posted isn't even optimized! Verlet is simple and fast. |
| ||
Very impressive, you sure know what you are doing. We must use this. I have just tested the demo. I'll take a closer look at the code and see if I get more clever. Hopefully we can use this with what we already have, and the complete package is done. I want to know more: Not how it works, I want to know what it can do, the end result: How do you use this? I mean how am I supposed to build stuff with this, I mean don't we need an editor or similar? What can it be used for? Destructable Buildings? Can you set a break-point on the constraints? So if you pull a rope with more and more force it eventually breaks? In your example, How would I: Make the robe more elastic? Change the shape of the box, or ho wwould I do to replace it with a more complex shape? Can you make it a star or a sphere for example? |
| ||
And the collision detection, how would we deal with collisions between constraints? Or perhaps that is never required? Or perhaps it is as simple as testing each constraint against each shape (those we already have working in MaxPhysics) such as circles and lines? |
| ||
Unfortunately, you're circle collision isn't going to be very useful with Verlet. A Verlet system would be based completely on "constraints", which would be tested for collision with your line collision algorithm. how am I supposed to build stuff with this, I mean don't we need an editor or similar? An editor is not necessary, but would help alot. You could outline an object which would be used to set up collisions and physics. What can it be used for? Destructable Buildings? Can you set a break-point on the constraints? Yes! I have successfully added breaking points to the rope in the example I posted where it will break at a specified stress limit. How would I: An elastic system could be implimented by updating constraints gradually. If you lower the iterations to 5 an effect like this will happen, also.Make the robe more elastic? Change the shape of the box, or ho wwould I do to replace it with a more complex shape? Can you make it a star or a sphere for example? Yes, very easily. Each "VerletParticle" is used to outline the shape of an object. The VerletParticles are then linked together with constraints to form a shape. As you can see, there are also criss-cross supports inside the shape in the example so it doesn't flop shapelessly. This won't be necessary if a angular constraint system is implimented, which would also allow for ragdoll physics as well. Unfortunately, I don't think the current line collision algorithm will be adequate for verlet physics. In this tutorial, figure 4a and 4b shows what collision info the collision engine needs to provide. I'm not sure how this would be done (I know next to nothing about actual collision algorithms). For speed, there are several optimizations that could be applied to the collision and verlet engine. One important optimization would be a simple bounding box check between multiple collision entities before calculating each constraint's collision status. But all this will come later. Or perhaps it is as simple as testing each constraint against each shape That would work, but it would probably be much simpler to create shapes out of lines only. |
| ||
John J. Bravo. About collisions I haven't done anything. I tried to convert the famous PolyColly code for Blitz Max. I am stucked one step before the collision we wand for this Physics lib or maybe we can use what we have already I don't really know. Look at the last codebox that I had posted to the MaxPhysics Community Project: In Progress (Tweaks) topic in the BlitzMax Module Tweaks forum. Run the demo and see what it's doing. This gives the MTD, or minimum translation distance that a poly needs to be separated from the other poly. This is maybe what we need. But I am not sure. Any other suggestions? |
| ||
The Collition detection with a Line If you put in the above John's example those two functions At the begining of the example import "Vector2d.Bmx" And before the flip 1 Test(Physics.Constraints) You have a visual of a basic collision detection Also the collide function returns a TList with all the intersection points. IMPORTANT : This is not coming from a tutorial so the whole idea may become a failure. If you have any suggestion pls post Also If anyone ever worked with collision stuff pls post |
| ||
John J : I cutted the tail from the Rigid Body of you example and if I drag it to one of the corners then the body have many chances to get out from the box. |
| ||
The Module doesn't support Poly-Poly-Collision yet, does it? I've found this free B3D-Library somewhere in the internet, I don't know who wrote it but I think it could help. Edit: Oh... there it is. It's by Nuloen ^^ ; nPoly - Polygonal Collision Library ; By Jocelyn 'GoSsE' Perreault, http://www.nuloen.com/ ; Last Updated: July 8 2004 ; Version: 1.0.0 ; This source code is copyrighted (c) to Jocelyn Perreault. ; It is FreeWare. You have no limitiations in regard to ; applications/games that you release/create with it, either ; they be freeware or commercial. However, you cannot release ; this source code under another name or release a similar ; library with it. It cannot be redistributed. The code may be ; modified to be tweaked but you cannot distribute it. If you ; made a modification that you think the community would ; benifit, please let me know. ; If you make tons of money with a commercial project, ; a free copy wouldn't hurt ;) ; I would love to have an e-mail and a place in the credits ; of your projects, but it is up to you. ; Thanks, ; Jocelyn "GoSsE Korupted" Perreault ; gosse@... ; Nuclear Loaded Entertainment ; http://www.nuloen.com/ ; ====================================================================== ; Globals and Constants ; ====================================================================== Const nP_MAX = 32 ; Maximum number of vertices for a poly ; ====================================================================== ; Different objects ; ====================================================================== ; Polygon Type nP_Poly Field iX[nP_MAX] ; Vertices X position Field iY[nP_MAX] ; Vertices Y position Field fX#[nP_MAX] ; Scaled and rotated X position Field fY#[nP_MAX] ; Scaled and rotated Y position Field iVertexCount ; Number of vertices Field fScaleX# ; X-Scale Field fScaleY# ; Y-Scale Field fAngle# ; Angle rotation Field iMinX ; Bounding box Field iMinY ; Bounding box Field iMaxX ; Bounding box Field iMaxY ; Bounding box End Type ; ====================================================================== ; Functions ; ====================================================================== ; Creates a new empty polygon Function nP_CreatePoly() Local nPoly.nP_Poly = New nP_Poly nPoly\fScaleX = 1 nPoly\fScaleY = 1 Return Handle(nPoly) End Function ; ---------------------------------------------------------------------- ; Adds a vertex to a polygon Function nP_AddVertex(poly, x, y, bUpdate = True) Local nPoly.nP_Poly = Object.nP_Poly(poly) If nPoly\iVertexCount > nP_MAX Then RuntimeError "Cannot add one more vertex to polygon!" Else nPoly\iX[nPoly\iVertexCount] = x nPoly\iY[nPoly\iVertexCount] = y nPoly\iVertexCount = nPoly\iVertexCount + 1 If bUpdate Then nP_UpdatePoly(poly) End If End If End Function ; ---------------------------------------------------------------------- ; Checks if 2 polygons overlap each other Function nP_PolyOverlap(poly1, x1, y1, poly2, x2, y2, bCheckBounding = True) ; Polygons Local nPoly1.nP_Poly = Object.nP_Poly(poly1) Local nPoly2.nP_Poly = Object.nP_Poly(poly2) ; Temp positions Local tx1#, ty1#, tx2#, ty2#, tx3#, ty3#, tx4#, ty4# ; Delta calculations Local dSqr#, d1#, d2#, dx#, dy# ; Last vertex Local lx1#, ly1#, lx2#, ly2# ; Counters Local i, j ; Checks bounding box first (if specified) If bCheckBounding Then tx1 = X1 + nPoly1\iMinX ty1 = Y1 + nPoly1\iMinY tx2 = X1 + nPoly1\iMaxX ty2 = Y1 + nPoly1\iMaxY tx3 = X2 + nPoly2\iMinX ty3 = Y2 + nPoly2\iMinY tx4 = X2 + nPoly2\iMaxX ty4 = Y2 + nPoly2\iMaxX If Not (tx3 > tx1 And ty3 > ty1 And tx3 < tx2 And ty3 < ty2) Then If Not (tx4 > tx1 And ty4 > ty1 And tx4 < tx2 And ty4 < ty2) Then If Not (tx3 > tx1 And ty4 > ty1 And tx3 < tx2 And ty4 < ty2) Then If Not (tx4 > tx1 And ty3 > ty1 And tx4 < tx2 And ty3 < ty2) Then Return False End If End If End If End If End If ; Store the last vertex lx1 = nPoly1\fX#[0] + X1 ly1 = nPoly1\fY#[0] + Y1 lx2 = nPoly2\fX#[0] + X2 ly2 = nPoly2\fY#[0] + Y2 ; Cycle through all other vertices For i = 1 To nPoly1\iVertexCount - 1 For j = 1 To nPoly2\iVertexCount - 1 ; Store vertices tx1 = nPoly1\fX#[i] + X1 ty1 = nPoly1\fY#[i] + Y1 tx3 = nPoly2\fX#[j] + X2 ty3 = nPoly2\fY#[j] + Y2 tx2 = lX1 ty2 = lY1 tx4 = lX2 ty4 = lY2 ; Calculate deltas dSqr = (ty4-ty3)*(tx2-tx1)-(tx4-tx3)*(ty2-ty1) d1 = (ty1-ty3) d2 = (tx1-tx3) dX = ((tx2-tx1)*d1-(ty2-ty1)*d2) dY = ((tx4-tx3)*d1-(ty4-ty3)*d2) ; Parallel If dSqr = 0 Then ; Coincident If dX = 0 And dY = 0 Then Return True End If Else ; Otherwise d1 = dX / dSqr d2 = dY / dSqr If (d1 >= 0 And d1 <= 1) And (d2 >= 0 And d2 <= 1) Then Return True End If End If ; Store last vertex lX2 = tx3 lY2 = ty3 Next ; Store last vertex lX1 = tx1 lY1 = ty1 Next Return False End Function ; ---------------------------------------------------------------------- Function nP_PolyOverlapsCircle(poly, X, Y, iCircleX, iCircleY, iCircleRadius, bCheckBounding = True) Local nPoly.nP_Poly = Object.nP_Poly(poly) ; Temp positions Local tx1#, ty1#, tx2#, ty2#, tx3#, ty3#, tx4#, ty4# Local CX1#, CY1#, CX2#, CY2#, pX1#, pY1#, pX2#, pY2#, pXT#, pYT# ; Delta calculations Local d1#, d2#, dX#, dY#, dSqr# ; Checks bounding box first (if specified) If bCheckBounding Then tx1 = X + nPoly\iMinX ty1 = Y + nPoly\iMinY tx2 = X + nPoly\iMaxX ty2 = Y + nPoly\iMaxY tx3 = iCircleX - iCircleRadius ty3 = iCircleY - iCircleRadius tx4 = iCircleX + iCircleRadius ty4 = iCircleY + iCircleRadius If Not (tx3 > tx1 And ty3 > ty1 And tx3 < tx2 And ty3 < ty2) Then If Not (tx4 > tx1 And ty4 > ty1 And tx4 < tx2 And ty4 < ty2) Then If Not (tx3 > tx1 And ty4 > ty1 And tx3 < tx2 And ty4 < ty2) Then If Not (tx4 > tx1 And ty3 > ty1 And tx4 < tx2 And ty3 < ty2) Then Return False End If End If End If End If End If ; Store the last vertex & circle lx = nPoly\fX#[0] + X ly = nPoly\fY#[0] + Y CX2# = iCircleX CY2# = iCircleY ; Cycle through all other vertices For i = 1 To nPoly\iVertexCount - 1 CX1# = nPoly\fX#[i] + X CY1# = nPoly\fY#[i] + Y pX1 = lX - CX1 pY1 = lY - CY1 pX2 = CX2 - CX1 pY2 = CY2 - CY1 d1 = pX1 * pX2 + pY1 * pY2 If d1 <= 0 Then dX# = CX2 - CX1 dY# = CY2 - CY1 dSqr# = dX * dX + dY * dY Else d2 = pX1 * pX1 + pY1 * pY1 If (d2 <= d1) Then dX# = CX2 - lX dY# = CY2 - lY dSqr# = dX * dX + dY * dY Else d1 = d1 / d2 pXT# = CX1 + d1 * pX1 pYT# = CY1 + d1 * pY1 dX# = CX2 - pXT dY# = CY2 - PYT dSqr# = dX * dX + dY * dY End If End If If dSqr# < iCircleRadius * iCircleRadius Then Return True End If lx = CX1 ly = CY1 Next Return False End Function ; ---------------------------------------------------------------------- ; Returns true if both circles overlap Function nP_CirclesOverlap(x1, y1, rad1, x2, y2, rad2) Local dx# = x2 - x1 Local dy# = y2 - y1 Local rsqr = rad1 + rad2 rsqr = rsqr*rsqr Return (dx*dx+dy*dy < rsqr) End Function ; ---------------------------------------------------------------------- ; Scales the polygon by the specified scale Function nP_ScalePoly(poly, sx#, sy#, bUpdate = True) Local nPoly.nP_Poly = Object.nP_Poly(poly) nPoly\fScaleX# = nPoly\fScaleX# * sx# nPoly\fScaleY# = nPoly\fScaleY# * sy# If bUpdate Then nP_UpdatePoly(poly) End If End Function ; ---------------------------------------------------------------------- ; Resizes the polygon to the specieid scale Function nP_ResizePoly(poly, sx#, sy#, bUpdate = True) Local nPoly.nP_Poly = Object.nP_Poly(poly) nPoly\fScaleX# = sx# nPoly\fScaleY# = sy# If bUpdate Then nP_UpdatePoly(poly) End If End Function ; ---------------------------------------------------------------------- ; Rotates the polygon by the specified rotation angle Function nP_RotatePoly(poly, fRot#, bUpdate = True) Local nPoly.nP_Poly = Object.nP_Poly(poly) nPoly\fAngle# = nPoly\fAngle# + fRot# If bUpdate Then nP_UpdatePoly(poly) End If End Function ; ---------------------------------------------------------------------- ; Turns the polygon to the specified angle Function nP_FreeRotatePoly(poly, fAngle#, bUpdate = True) Local nPoly.nP_Poly = Object.nP_Poly(poly) nPoly\fAngle# = fAngle# If bUpdate Then nP_UpdatePoly(poly) End If End Function ; ---------------------------------------------------------------------- ; Updates the polygon according to scale and rotation Function nP_UpdatePoly(poly) Local nPoly.nP_Poly = Object.nP_Poly(poly) Local fX#, fY#, f1#, f2# Local i ; Set up big extremums nPoly\iMinX = 9999999 nPoly\iMinY = 9999999 nPoly\iMaxX = -9999999 nPoly\iMaxY = -9999999 ; Find a valid collision setting For i = 0 To nPoly\iVertexCount - 1 ; Standard data fX = nPoly\iX[i] fY = nPoly\iY[i] ; Scale fX = fX * nPoly\fScaleX fY = fY * nPoly\fScaleY ; Rotation If nPoly\fAngle# <> 0 Then f1 = Cos(nPoly\fAngle#) * fX - Sin(nPoly\fAngle#) * fY f2 = Sin(nPoly\fAngle#) * fX + Cos(nPoly\fAngle#) * fY fX = f1 fY = f2 End If ; Final Values nPoly\fX#[i] = fX nPoly\fY#[i] = fY ; Check for bounding box If fX < nPoly\iMinX Then nPoly\iMinX = fX End If If fY < nPoly\iMinY Then nPoly\iMinY = fY End If If fX > nPoly\iMaxX Then nPoly\iMaxX = fX End If If fY > nPoly\iMaxY Then nPoly\iMaxY = fY End If Next End Function ; ---------------------------------------------------------------------- ; Draws the polygon on screen at the specified location Function nP_DrawPoly(poly, x, y, r=255, g=255, b=255, bDrawBoundingBox=True, br=255, bg=255, bb=255) Local nPoly.nP_Poly = Object.nP_Poly(poly) Local i, lx, ly ; Draw bounding box (if specified) If bDrawBoundingBox Then Color br, bg, bb Rect nPoly\iMinX + x, nPoly\iMinY + y, nPoly\iMaxX - nPoly\iMinX + 1, nPoly\iMaxY - nPoly\iMinY + 1, False End If ; Draw all the lines Color r, g, b lx = nPoly\fX[0] + x ly = nPoly\fY[0] + y For i = 1 To nPoly\iVertexCount - 1 Line lx, ly, nPoly\fX[i] + x, nPoly\fY[i] + y lx = nPoly\fX[i] + x ly = nPoly\fY[i] + y Next End Function ; ---------------------------------------------------------------------- ; Copies a polygon and return the newly created poly Function nP_CopyPoly(poly) Local nPoly.nP_Poly = Object.nP_Poly(poly) Local newPoly.nP_Poly = New nP_Poly Local i ; Copy point data For i = 0 To nPoly\iVertexCount - 1 newPoly\iX[i] = nPoly\iX[i] newPoly\iY[i] = nPoly\iY[i] newPoly\fX#[i] = nPoly\fX#[i] newPoly\fY#[i] = nPoly\fY#[i] Next ; Copy all data newPoly\iVertexCount = nPoly\iVertexCount newPoly\fScaleX# = nPoly\fScaleX# newPoly\fScaleY# = nPoly\fScaleY# newPoly\fAngle# = nPoly\fAngle# newPoly\iMinX = nPoly\iMinX newPoly\iMinY = nPoly\iMinY newPoly\iMaxX = nPoly\iMaxX newPoly\iMaxY = nPoly\iMaxY Return Handle(newPoly) End Function ; ---------------------------------------------------------------------- ; Deletes the polygon from memory Function nP_FreePoly(poly) Local nPoly.nP_Poly = Object.nP_Poly(poly) Delete nPoly End Function |
| ||
John J : I cutted the tail from the Rigid Body of you example and if I drag it to one of the corners then the body have many chances to get out from the box. I'm not quite sure what you're describing here. Do you mean that the box collision is faulty? Fetze: That looks perfect! It looks like it'll be fast, too, since it uses bounding boxes to cull out unneeded collision checking. With that code by Nuloen I can complete the verlet physics engine I made and MaxPhysics will be complete. However, I'm going to re-write my current verlet engine for better speed and ease-of-use, first. = My current plan is: Each physics object will be a list of vertices, which forms a convex (or non-convex) polygon with Nuloen's poly code. Each vertex is also a Verlet particle, which are all linked together with Verlet constraints. From a MaxPhysics user's point of view, a MaxPhysics object will basically consist of a list of vertices, which are tied to a 2D image which is displayed to the screen. Functions will be availible that apply forces, torque, and other effects to their 2D physics objects. The use of bones and joints will also be possible by adding an extra link between Verlet particles for each physics object. A physics editor would also be a nice addition to MaxPhysics, when it is complete. In the editor, the user could load their image, and define it's collision polygon by creating vertices that define it's shape. With Verlet, each vertex can even have it's own mass, which means you can accurately reproduce an object's center of gravity, inertial reactions, etc. I also plan on implimenting some sort of joint breaking point system. This way, you could make all your physics objects breakable (an airplane's wings could break off, buildings could collapse, vehicles could lose wheels, robot enemies could lose limbs, etc. etc.) The possibilities are just endless. |
| ||
Yeah, that sounds GREAT ^^ But it would be _very_ nice, if there was some sort of "external physics" support: Functions for collisioncheck and response which aren't connected to the physics-classes. The "problem" I have is, that I use my own small physics for my game and I want to keep it as it's perfectly balanced. Also, the only thing I need is collision-poly-poly-check and very simple response. |
| ||
Well... About nPoly we allready know it. A very good polygon functions but it's working for slow objects. Plus for poly poly collisions we need a collision system that will return some values and not just have the collision responce build in the Overlap function. Also when I checked the nPoly I found out that it's not really returns the if a poly overlaps poly. Just make the simple test. Make a poly big enought to overlap the other poly without colliding any of the edges. You will see that the overlap function does not work as you may expecting. this means that a fast moving object will penetray the other polygons. Also about Verlet. It's looks promising but I cannot find any way to handle collision. Also I found some people around the net saying that you must add some extra particles to handle rotation and some other stuff. Well anythink that I have tried so far does not work. I have a question. When I am finding the particle that overlaps a poly what I have to do is to move it and then sutisfie the constrains? |
| ||
This is great. John, keep us updated on the progress. @Fetze, Don't worry. You can use all collision rutines for collision checking( poly/poly circle/line, line/ line..) without using the collision response. If you use the the "response" rutines you simply get a series of variables that you can change to alter the physics of the collision. If you want to make that part built-in-game-specific, I don't see any limitations. From a MaxPhysics user's point of view, a MaxPhysics object will basically consist of a list of vertices, Yes I agree. However, I would still want it to be possible to use a circle, or a polygon, out-of-the-box, for collisions. In these parts, it might be two engines tied together. I'm not sure how good we can match the two, yet the more options people have, the better. @Haramanai, How fast does the object really have to travel before it is noticable? Try to increse the FPS instead of the speed of the object. I mean at 75fps, you need to move very fast if you are to pass through an (even a small) box v box collision, where the only thing you do is reset to lastX,lastY. Do perhaps have an example for the polygon case? However, I'm not sure how to do any collision response if the polygon rutine does not return a "reflect vector" of sorts.. And to everyone involved: Keep the good work up! |
| ||
An example of the poly overlap Haramanai mentioned would be a small ship flying inside the level. If in one frame it passes from not-touching outside the poly, to not-touching inside, it wont be detected, right? Increasing FPS is not a decent option - better would be to extrude the polygon between its last and new position. Then if the system stutters the game-speed can remain constant and a collision can be resolved anyway. John J - your post sounds great! I would want my physics objects not tied to images, though. |
| ||
Will : Intresting. But we have another problem here. Rotation. Without rotation this may work but with rotation the trick will not work. Or you know something more? |
| ||
Okey, I see. Annoying math ;) What about our line functions, can they not be used in polygon too? or would that be to slow? Or perhaps they can be used as an option when super-effective collison detection is required, at the cost of speed? |
| ||
No I don't Believe that the Line intersection code can help. John was right. You know?... the PolyColly must be translated even we are going to use Verlet integretion or Euler. |
| ||
Sorry I haven't been able to put much time into MaxPhysics - I'm spending most of my free time on my game for a programming competition. However, I would still want it to be possible to use a circle, or a polygon, out-of-the-box, for collisions. In these parts, it might be two engines tied together. I'm not sure how good we can match the two, yet the more options people have, the better. Adding circle-poly, poly-poly, etc. collisions to the engine would be fine, except the physics engine could use only poly-poly or line-poly because that is what verlet is based on. But I think things should be kept simple; MaxPhysics should handle physics, while you could have another module, such as MaxCollision to handle collisions with circles, polygons, boxes, or whatever. However, there's no reason why MaxPhysics can't have commands like AddPoly(), AddCircle(), AddBox(), etc. because MaxPhysics could automatically convert them into verlet-compatible polygonal structure. But we have another problem here. Rotation. If you've seen my verlet demo, I'm sure you noticed the rotation, torque, and even center of gravity effects on the physics object in there. Verlet handles all these almost automatically, so rotation is no problem. If you're reffering to how to rotate an image which represents a physics object, you would simply need to take the position of a few (2-3) vertices in a verlet rigid body, and use simple triginometry to calculate the angle. The position would also be calculated similarly, by finding the average position of all of a rigid body's vertices. I would want my physics objects not tied to images, though. That would be completely optional, if it's implimented at all. |
| ||
But we have another problem here. Rotation. I am not saing that the problem it's inside the Verlet Physics Engine but in the way that Collision must be handled. |
| ||
That would be simple also. Just give the collision engine the current coordinates of all the vertices and there shouldn't be any problem. |
| ||
Would it be possible for a vertice to have a radius? I mean so it can be larger than whatever it is as default? |
| ||
I found a trick like this in the main olivier_rebellion's directory http://uk.geocities.com/olivier_rebellion/ Under the : verlet integration rigid body you have to download and the glut and copy the files of the zip to the directory to run the example. He have much code source in there . |
| ||
Do you guys still need a starter collision library? I'll post mine here(written in BB) if any expansions/alterations will be done in the BB and BMax code so both comunities can benefit. Here's the starter version, I don't know what you need, but wait a few days to really dig into it as I'll be posting a new version soon. Theres LOTS of room for optimisation that I just havn't had time for yet. [edit]Keep in mind I only spent a couple hours on it, so the state it's in right now is a good point to learn from(for those who havn't done anything like this before). I dunno what you already have, so if someone can fill me in, I might be able to help. I still have to add rotated collision hull support, and a few other things before it's really at a release stage, but here it is regardless. Post comments and ideas, I don't have blitzmax so I can't help as much as I'd like to. Anyone wanna buy me a liscense? ;) |
| ||
Just noticed someone had posted nPoly's code here. I started what I posted above because I didn't see an easy way to get collision info from intersection tests(at least nothing I wanted to have to do ;)). |
| ||
I'm implementing rotation into my collision library right now, it will be using my Matrix library for transforming vertices around a local origin. so when I post a new version it will be with the matrix lib included. |
| ||
Rotated collisions are done, will upload the updated col lib and my matrix lib soon. I'm going to be working on a physics library, I've been getting advice on that end for a bit and I feel confident I can do it. If you guys don't have anything else I can simply post my results on that end here as well..? |
| ||
Yes sure, that would be great, ask if you need help. I would like to see a runnable tech-demo, I have B3d, so you can post in that too. Or perhaps you can upload an exe? And I really recommend you to get BMax. You don't know what you are missing. |
| ||
I've only now added the actual collision info returns from the intersection testing functions(which is kind of the whole point of these things ;)). The physics library will be a bit off yet... I'm trying to decide how to work it into my 2d in 3d engine without sacraficing the ability for it to work standalone. I am planning to release the engine as well, but it's going to take time to get it to where I feel comfortable releasing it. Will post an update asap. As for a tech demo, I'll see what I can do. Might be a few days to a week before anything new comes up, I've got a few ideas I want to work on before posting anything. |
| ||
Dev: Impressive. |
| ||
Not sure if this will be useful or not, but I just found a link to a dynamics engine written in flash. Perhaps it could be converted. http://sourceforge.net/projects/flade/ Also this link includes source as well for a library written in c++ and some interesting demos http://www.aidspan.org/alec/physical/downloads.htm |
| ||
Lemme know if you guys have any real direction in what you're doing. I still havn't been filled in on your status so I don't know if I should continue posting my work or not :). Lemme know. |
| ||
Well. Dev. The direction of the project right now is a litle bit separated. What I mean. John J. as you can see implementing Verlet physics system. Wave working on Circles and physics momentus for them he also created the Vector2d type. We are not in an real direction right now. We just trying to find the right one. The basic problem as I can tell is the collision detection. We don't have any codes for collision detection. Just a simple code for Line vs Line Intersection and a simple one for circles. As you can see polygons are not yet in. Last from my point of view first priority is the polygon collision detection and I believe this is the mai nreason that the project is stucked. |
| ||
Well my system takes care of that... I have circle->polygon, polygon->polygon, ray->polygon, etc working right now on my local version for intersection. I have circle->Polygon and soon to be polygon->polygon working with collision response here as well. If all can wait for a week or so I'll try my hardest to get everything working/optimised AND get some basic physics going. I need someone to get in touch with me to work on porting the code over to blitzmax, I'd rather do that then post my BlitzBasic code and have everyone take their own pick at porting it, as it can just be unified this way. I'm also going to be implementing prechecks to keep objects from going through one another when they're moving fast. Any takers on helping me with the porting? |
| ||
I haven't used Blitz Plus but from the codes I have seen so far I believe that the convertion it's not so dificult. Also if I am not wrong Blitz Plus graphics system it's the same with Max2d. Also I have to say that I am new in the programming world and I have no expirience but I have the will to learn and create. So I will do my best to help porting. A good idea I think it's to use some space in the wiki for this work. Wave what you say about all this? |
| ||
The code is not related to blitzplus/2d/3d, it was written in the b3d IDE but it's simply the generalized syntax that guides it. So it could be compiled by any of them(just to clarify). It's just maths, there are no graphics dependant functions involved. |
| ||
I said about graphics thinking about the origin. Because in the openGL code I found the origin at the bottom left corner but in Max2d and Blitz Plus it's to the upper left so the y in openGL goes up but in the others goes down. It will be well apreciated if you can tell what return values we will get from the collision detection. Also what do you think If we take a space in the BlitzWiki for this? |
| ||
As far as what it returns, everything you need(obviously so since I said I had collision response running on this end :D) Anywho, it returns: Collision coordinates(X, Y) Collision normals Penetration depth and the collision bodies involved(in case the data is to be shuffled around). As for as a section in the wiki, not much point until it's running in blitzmax eh? After that, I can write documentation for someone else to put in the wiki but I'm not going to actively maintain anything.(I might get into updating the wiki but right now I just don't have time) [edit] Things are going a bit slowly right now as I seem to have caused myself some insomnia, tis enough work sorting that out :) |
| ||
I'm working on a simply hull editor(for building polygons) when I finish it I'll get back at expanding the collision system, and when both are ready I'll release it. [Edit] Forget the hull editor, I have to buy xlnt to release anything using it. |
| ||
Anywho, I've decided the most efficient method of collision between arbitrary collision hulls is to project vertices along the vector of travel and detect collisions then. The system currently will detect all line segment intersections between collision hulls, but this gives no mechanism for finding collision point/penentration depth etc. Sure seems like this thread is dead and I'm talking to thin air. |
| ||
I am reading evrything you are writing. I just don't post if I don't have anything to say. About that new idea. What you will do. Drawbacks to find the right position of the objects? This may overkill the overall system... Or it will stay like the Max2D's collision system.e.g. There is a collision and nothing more. |
| ||
I don't understand quite what you're asking. At any rate, the solution to what I had stated in my last post is to project vertices who are potential candidates for collision(in order for one line segment to intersect another, an endpoint of one must penetrate the other, so if I detect that, then the collision point/normals can be found.) I'm going to try to get it done tommorow. You'll see then. *be warned* I havn't had time to optimize or clean anything up, so if I release code tommorow, it will be messy. I might wait till it's been finalized(since someone has to port this) |
| ||
I didn't really read what you guys have at this point although I have been interested in the project. Anyway, I can't exactly help you on collision as I havn't done anything pertaining to that. However, I did just write a simple verlet integration system. It includes basic particles and constraints. While I know it's not quite finished yet it's in pretty good working order. Unfortunately, I didnt know about your Vector type so I didnt use it, but just observing they look very compatable. Anyway, I'll post both up here if they're any use. Vector Type: Strict Import BRL.Basic Type TVector 'VARIABLES Field _x:Double, _y:Double 'METHODS Method New() _x = 0 _y = 0 End Method Method Set(x:Double,y:Double) _x=x _y=y End Method Method Get(x:Double Var, y:Double Var) x = _x y = _y End Method Method Multiply:TVector(factor:Double) _x:*factor _y:*factor Return Self End Method Method Add:TVector(v:TVector,bself=False) If bself = False Return TVector.Create(_x+v._x,_y+v._y) Else _x:+v._x _y:+v._y Return Self EndIf End Method Method Subtract:TVector(v:TVector,bself=False) If bself = False Return TVector.Create(_x-v._x,_y-v._y) Else _x:-v._x _y:-v._y Return Self EndIf End Method Method Copy:TVector() Return Create(_x,_y) End Method Method DotProduct:Double(v:TVector) Return _x*v._x+_y*v._y End Method Method AngleBetween:Double(v:TVector) Return ACos(DotProduct(v)/(Magnitude()*v.Magnitude())) EndMethod Method SetAngle(angle:Double) Local mag:Double = Magnitude() _x = Cos(angle)*mag _y = -Sin(angle)*mag End Method Method GetAngle:Double() Return ATan2(-_y,_x) End Method Method SetMagnitude(mag:Double) Normalise() _x:*mag _y:*mag End Method Method Magnitude:Double() Return Sqr(_x^2+_y^2) End Method Method MagSquared:Double() Return _x^2+_y^2 End Method Method Normalise:TVector(bself=True) Local m:Double = Magnitude() If bself = False Return TVector.Create(_x/m,_y/m) Else _x:/m _y:/m EndIf End Method Method PrintVector() Print "(" + _x + "," + _y + ")" End Method Method Draw(xoff,yoff) DrawLine xoff,yoff,xoff+_x,yoff+_y End Method 'FUNCTIONS Function Create:TVector(x:Double,y:Double) Local o:TVector = New TVector o._x=x o._y=y Return o End Function Function FromTo:TVector(v1:TVector,v2:TVector) Return Create(v2._x-v1._x,v2._y-v2._x) End Function End Type Verlet Physics System: Strict Framework BRL.Max2D Import BRL.D3D7Max2D Import BRL.Basic Import BRL.System Import BRL.Timer Import BRL.LinkedList Import "vector.bmx" Type TParticle Global list:TList Global bHidden=False Field oldposition:TVector Field position:TVector Field acceleration:TVector Field mass# Field bLocked Method New() If Not list Then list = CreateList() ListAddLast(list,Self) position = TVector.Create(0,0) oldposition = TVector.Create(0,0) acceleration = TVector.Create(0,0) mass# = 1 bLocked = False End Method Method Push(Fx#,Fy#) acceleration.Add(TVector.Create(Fx/mass,Fy/mass),True) End Method Method Update() If bLocked = False Then VerletIntegrator() acceleration.set(0,0) End Method Method VerletIntegrator:TVector(update = True) If update = True Local p:TVector = position.Copy() Local op:TVector = oldposition.Copy() Local accel:TVector = acceleration.Copy() p.Multiply(2-TPhysicsEngine.Resistance) op.Multiply(1-TPhysicsEngine.Resistance) p.Subtract(op,True) accel.Multiply(TPhysicsEngine.DeltaTime()^2) p.Add(accel,True) oldposition = position.Copy() position = p.Copy() Return Null Else Local p:TVector = position.Copy() Local op:TVector = oldposition.Copy() Local accel:TVector = acceleration.Copy() p.Multiply(2-TPhysicsEngine.Resistance) p.Subtract(op.Multiply(1-TPhysicsEngine.Resistance),True) p.Add(accel.Multiply(TPhysicsEngine.DeltaTime()^2)) Return p EndIf End Method Method Lock() bLocked = True End Method Method Unlock() blocked = False End Method Method GetVelocity:TVector() Local v:TVector = VerletIntegrator(False).Subtract(oldposition) v.Multiply(1/Float(2*TPhysicsEngine.DeltaTime())) Return v End Method Method SetPosition(x#,y#) position._x=x position._y=y oldposition = position.Copy() End Method Method GetMomentumX:Float() Return GetVelocity()._x*mass End Method Method GetMomentumY:Float() Return GetVelocity()._y*mass End Method Method Render() DrawRect position._x-5,position._y-5,10,10 End Method Function Create:TParticle(x#,y#,mass#=1,vx#=0,vy#=0) Local o:TParticle = New TParticle o.SetPosition(x,y) o.mass = mass o.acceleration.set(vx,vy) Return o End Function Function DoFrame() For Local o:TParticle = EachIn(list) o.Update() If bHidden = False Then o.Render() Next End Function End Type Type TConstraint Global list:TList Global bHidden=False Field _distance:Float Field _p1:TParticle = Null Field _p2:TParticle = Null Method New() If Not list Then list = CreateList() list.addlast(Self) EndMethod Method Update() Local vdistance:TVector Local ndistance# Local difference# Local invmass1# = 1.0/_p1.mass Local invmass2# = 1.0/_p2.mass vdistance = _p1.position.Subtract(_p2.position) ndistance = vdistance.Magnitude() difference = (ndistance-_distance)/(ndistance*(invmass1+invmass2)) If _p1.bLocked = False _p1.position._x=_p1.position._x-vdistance._x*invmass1*difference _p1.position._y=_p1.position._y-vdistance._y*invmass1*difference EndIf If _p2.bLocked = False _p2.position._x=_p2.position._x+vdistance._x*invmass2*difference _p2.position._y=_p2.position._y+vdistance._y*invmass2*difference EndIf End Method Method Render() DrawLine _p1.position._x,_p1.position._y,_p2.position._x,_p2.position._y End Method Function Create:TConstraint(p1:TParticle,p2:TParticle,dist:Float = 0) Local c:TConstraint = New TConstraint c._p1 = p1 c._p2 = p2 If dist = 0 c._distance = Sqr((p1.position._x-p2.position._x)^2+(p1.position._y-p2.position._y)^2) Else c._distance = dist EndIf Return c End Function Function DoFrame() For Local o:TConstraint = EachIn(list) o.Update() If bHidden = False Then o.Render() Next End Function End Type Type TPhysicsEngine Global Gravity:Float = 0.0 Global Resistance:Float = 0.0 Global LastTime = 0 Global ThisTime = 0 Function DoFrame() If ThisTime = 0 And LastTime = 0 ThisTime = MilliSecs() LastTime = MilliSecs() EndIf ThisTime = MilliSecs() If TParticle.list For Local p:TParticle = EachIn(TParticle.list) p.acceleration._y:+Gravity p.Update() p.Render() Next EndIf If TConstraint.list For Local c:TConstraint = EachIn(TConstraint.list) c.Render() c.Update() Next EndIf LastTime = ThisTime End Function Function DeltaTime#() Return Float(ThisTime-LastTime)/1000.0 End Function End Type Example: Graphics 640,480,0 Local p:TParticle = TParticle.Create(640/2,480/2) Local p2:TParticle = TParticle.Create(640/2,480/2+50) Local p3:TParticle = TParticle.Create(640/2,480/2+100) Local p4:TParticle = TParticle.Create(640/2,480/2+150) Local p5:TParticle = TParticle.Create(640/2,480/2+200) Local p6:TParticle = TParticle.Create(640/2-25,480/2+225) Local p7:TParticle = TParticle.Create(640/2+25,480/2+225) TConstraint.Create(p,p2) TConstraint.Create(p2,p3) TConstraint.Create(p3,p4) TConstraint.Create(p4,p5) TConstraint.Create(p5,p6) TConstraint.Create(p6,p7) TConstraint.Create(p5,p7) p.Lock() Local x# =640/2 Local y# =480/2 TPhysicsEngine.Gravity = 70 TPhysicsEngine.Resistance = 0.005 While Not KeyDown(KEY_ESCAPE) Cls If MouseDown(1) Then p5.SetPosition(MouseX(),MouseY()) TPhysicsEngine.DoFrame() Flip Wend |
| ||
Someone try that and tell me what they think, I was going to write a rigid body solution but if that get's the job done, I'll just focus on making collisions work. |
| ||
SSS and I have partnered up to build you folks a physics solution, aren't we nice? ;) Someone better buy me a copy of blitzmax already! And you better buy SSS a popcicle just so he doesn't feel left out. ^_^ |
| ||
I'm having some troubles with the Collision hulls properly responding to interpenetration... it's not easy to get this right, I forsaw it and now I've gotta deal with it. I'm trying a variety of things to hopefully I will have a solution soon. |
| ||
SSS : Nice one SSS and well organized. I hope to see some more when we have some collisions. Mike Con : Collisions it's really dificult task. Also BMax it's not so expensive and you will have the MaxGui free as you have Blitz Plus. I am going to try some elipsoid vs pollygon collision detection and responce just for characters on a terrain. It will be just a work around the document <Generic Collision Detection for Games using Ellipsoids> by Paul Nettle. I have tried it before but I gived up. But now I beleive I can make it so I will try. |
| ||
Hey you guys.. thanks for the praise Haramanai! I got angular constraints working (i think.. dunno exactly how their supposed to act.) The creation is through the function TAngularConstraint.Create(p1,p2,p3,angle) where p1 is the pivot and p2, and p3 are the two particles that you want to separate by a certain angle. The angle is only needed if you dont want them at their rest angle but some other artificial angle. Anyway, without further adue here is the code: Type TAngularConstraint Global list:TList Field _angle:Float Field _p1:TParticle = Null Field _p2:TParticle = Null Field _p3:TParticle = Null Method New() If Not list Then list = CreateList() list.addlast(Self) EndMethod Method Update() Local t1:TVector = _p3.Position.Subtract(_p1.Position) Local t2:TVector = _p2.Position.Subtract(_p1.Position) Local Angle:Double = t1.AngleBetween(t2) If Angle<_angle Local da:Double = (_angle-Angle)/(2*(1.0/_p2.mass+1.0/_p3.mass)) If t1.GetAngle()>t2.GetAngle() t1.SetAngle(t1.GetAngle() + da/_p3.mass) t2.SetAngle(t2.GetAngle() - da/_p2.mass) Else t1.SetAngle(t1.GetAngle() - da/_p3.mass) t2.SetAngle(t2.GetAngle() + da/_p2.mass) EndIf t1.Add(_p1.Position,True) t2.Add(_p1.Position,True) If _p3.bLocked = False _p3.Position = t1 EndIf If _p2.bLocked = False _p2.Position = t2 EndIf EndIf End Method Method CalculateAngle:Double() Local t1:TVector = _p3.Position.Subtract(_p1.Position) Local t2:TVector = _p2.Position.Subtract(_p1.Position) Return t1.AngleBetween(t2) End Method Function Create:TAngularConstraint (p1:TParticle,p2:TParticle,p3:TParticle,angle:Float = 0) Local c:TAngularConstraint = New TAngularConstraint c._p1 = p1 c._p2 = p2 c._p3 = p3 If angle = 0 c._angle = c.CalculateAngle() Else c._angle = angle EndIf Return c End Function Function DoFrame() For Local o:TAngularConstraint = EachIn(list) o.Update() Next End Function End Type and an example Graphics 640,480,0 Local p:TParticle = TParticle.Create(640/2,480/2) Local p2:TParticle = TParticle.Create(640/2+25,480/2+50) Local p3:TParticle = TParticle.Create(640/2-25,480/2+50) TConstraint.Create(p,p2) TConstraint.Create(p,p3) p2.mass = 2 Local l:TAngularConstraint = TAngularConstraint.Create(p,p2,p3) p.Lock() Local x# =640/2 Local y# =480/2 TPhysicsEngine.Gravity = 70 TPhysicsEngine.Resistance = 0.005 While Not KeyDown(KEY_ESCAPE) Cls DrawText l.CalculateAngle(),10,10 If MouseDown(1) Then p2.SetPosition(MouseX(),MouseY()) TPhysicsEngine.DoFrame() Flip Wend |
| ||
SSS : Looks like you know what you are doing... I also started to use your TVector type. Somewhere I readed that one team had added an extra parammeter angle in the Verlet Engine for collisions. Sadly I cannot find the site. I have managed to pass some of the code that I said I will work on. I have Two functions closestPointOnTriangle and closestPointOnLine. You may start playing with collisions with those two but I am not sure If it is the right way to do things. Maybe we have just to wait for Mike Con's Collision Lib. But anyway I post it here with an example. Have a look. |
| ||
Is anyone still working? I still trying to make the Ellipsoid to work but I have some problems with it. I made it and a topic about it : http://www.blitzmax.com/Community/posts.php?topic=55480 Be sure to check it's a hight level stuff. Also... Wave were are you? MikeCon how it's going? SSS I felt in love with your Vector type. I hope you still working with your Verlet engine. |
| ||
Hey! I'm glad you like my vector type. There is one mistake in the TVector.FromTo function... if you look at the creation code it should be Return Create(v2._x-v1._x,v2._y-v1._y) instead of whatever is there. I'm right in the middle of exam week so i havnt had much time. I have, however, managed to add breakable constraints when there is to much tension. Once again, I didn't follow an article, just used my own knowledge so it might not be strictly 'correct'. Anyway, here's the codeType TConstraint Global list:TList Global bHidden=False Field _distance:Float Field _stress:Float = 0 Field _p1:TParticle = Null Field _p2:TParticle = Null Method New() If Not list Then list = CreateList() list.addlast(Self) EndMethod Method Update() Local vdistance:TVector Local ndistance# Local difference# Local invmass1# = 1.0/_p1.mass Local invmass2# = 1.0/_p2.mass vdistance = _p1.position.Subtract(_p2.position) ndistance = vdistance.Magnitude() difference = (ndistance-_distance)/(ndistance*(invmass1+invmass2)) If _stress>0 If Stress()>_stress Then list.remove(Self) EndIf If _p1.bLocked = False _p1.position._x=_p1.position._x-vdistance._x*invmass1*difference _p1.position._y=_p1.position._y-vdistance._y*invmass1*difference EndIf If _p2.bLocked = False _p2.position._x=_p2.position._x+vdistance._x*invmass2*difference _p2.position._y=_p2.position._y+vdistance._y*invmass2*difference EndIf End Method Method Stress:Float() Local tofrom:TVector = TVector.FromTo(_p1.position,_p2.position) Local acceleration1:TVector = TVector.FromTo(_p1.oldposition,_p1.position) Local acceleration2:TVector = TVector.FromTo(_p2.oldposition,_p2.position) acceleration1.Multiply(_p1.mass) acceleration2.Multiply(_p2.mass) Local angle:Float = 180.0-acceleration1.AngleBetween(tofrom) Local Force1:Float = acceleration1.Magnitude()*Cos(angle) angle:Float = 180.0-acceleration2.AngleBetween(tofrom) Local Force2:Float = acceleration2.Magnitude()*Cos(angle) Force1:+Force2 Return Force1 End Method Method Breakable(stress:Float) _stress = stress End Method Method Unbreakable() _stress = 0 End Method Method Render() DrawLine _p1.position._x,_p1.position._y,_p2.position._x,_p2.position._y End Method Function Create:TConstraint(p1:TParticle,p2:TParticle,dist:Float = 0) Local c:TConstraint = New TConstraint c._p1 = p1 c._p2 = p2 If dist = 0 c._distance = Sqr((p1.position._x-p2.position._x)^2+(p1.position._y-p2.position._y)^2) Else c._distance = dist EndIf Return c End Function Function DoFrame() For Local o:TConstraint = EachIn(list) o.Update() If bHidden = False Then o.Render() Next End Function End Type Here's an example, Graphics 640,480,0 Local p:TParticle = TParticle.Create(640/2,480/2) Local p2:TParticle = TParticle.Create(640/2,480/2+50) Local p3:TParticle = TParticle.Create(640/2,480/2+100) Local p4:TParticle = TParticle.Create(640/2,480/2+150) Local p5:TParticle = TParticle.Create(640/2,480/2+200) Local p6:TParticle = TParticle.Create(640/2-25,480/2+225) Local p7:TParticle = TParticle.Create(640/2+25,480/2+225) TConstraint.Create(p,p2) Local c:TConstraint = TConstraint.Create(p2,p3) c.Breakable(7) TConstraint.Create(p3,p4) TConstraint.Create(p4,p5) TConstraint.Create(p5,p6) TConstraint.Create(p6,p7) TConstraint.Create(p5,p7) p.Lock() Local x# =640/2 Local y# =480/2 TPhysicsEngine.Gravity = 70 TPhysicsEngine.Resistance = 0.005 Local pu# = 0 While Not KeyDown(KEY_ESCAPE) Cls If p5.position._y>=300 Then p5.Push(pu,0) If KeyDown(KEY_UP) Then pu#:-50 TPhysicsEngine.DoFrame() Flip Wend hold the upkey to make the thing go around faster until it breaks. I think it's quite cool. |
| ||
The bSelf:Byte is a perfect Idea. Also the I think we must add some more Method like this. I was in really need of this method. |
| ||
I havn't had time to work on the collision code in the last week. SSS was busy with mid-terms anywho, so I suppose it's not great loss. Be back at it soon(I hope), but I am preparing for a move in a week or two so my time availability is patchy. |
| ||
It's Ok Mike. I finished or made the first big step for the Ellipsoid that I said I will try out. Here is the topic I created The Topic This may be good for characters. |
| ||
Don't give up on this project! I check it every day for updates! |
| ||
I agree. I have no idea how I could code something like this myself and I'm really interested in a 2D-Physics module. It would be a waste of a really cool project if no-one continued this. |
| ||
For anyone's that interested, I ported Flade to bmx to have a bit of a play, you can get it here http://www.doozey.com/downloads/flade_06a_bmx.zip |
| ||
dooz : Really impresive. Well done. At last there is something finished! dooz if you don't mind it will be good for the rest of the comunity to make a new thread and show the convertion to the rest as this thread became to large and many people don't bother to read it. Well done. |
| ||
Nice work dooz. |
| ||
Very Very nice :) I haven't really been through the code yet, but is there an easy way to assign correctly orientated images to the physical objects? |
| ||
Has anyone converted this to bmax? http://www.aidspan.org/alec/physical/downloads.htm |
| ||
Dooz, excelent port...very cool stuff. Tested out the demos and they run much faster in Blitz than Flash, of course. Just one question. Since it's released under GPL does that mean that games we make using it must also be GPL, or just any changes and additions we do to Flade need to be GPL. I wish the MaxPhysics project would continue. I'm a Blitz noob so a ready made module would come in very handy as I wouldn't know how to code it myself. Ragnar |
| ||
@gellyware: "atom"-based physics seem very interesting. However rigid body physics are at the moment much more common in game programming. I suppose there are tons of tutorials about it in the web. I'd suggest not to spend to much time on such innovative concepts, but instead focusing on the most widespread concept (rigid-body newtonian). It's quite sad there hasn't been any progress in the last 2 months and the "Progress"-page in the BlitzWiki gives no clue what would be next to do either.. |
| ||
Stefenk I have to tell you that : yes the progress of this module had stucked and the date is not 2 months... if I remember well it must be 4 or 5 months. The reasons are that we were been only two persons working on this. I personaly wasn't so good for this kind of stuff also the main goal for me was to make a proper collision detection. Another reason was the behaviur of many users over the community. What I mean. People were coming and giving promisses that never kept. For example some where saying that there going to create a verlet engine or convex collision detection and responce. Those actions was like bummerang because we were trusting them and we were expecting them to keep promisses but ofcurse this never hapend and the production or the reading were kept behind. Day by day the reading for this project was becoming all the way more difficult and reallity hitted the door to me and said you don't have the knowledge to keep it up so I quit with the hope that someone better will come. Sometimes I fill like I destroyed this project and I fill shame for this. The truth is that there is no MaxPhysics Community Project. You see people with the knowledge and the expirience will never work for free. They will sell you every crap that they will create. They are allready some of those out there in the community and there going to be more. Looks like the spirit is not to sell games but to sell code. |
| ||
The last days I went back and checked on my "MaxPhysics folder" I started messing around some. I looked at what we had and I built my own Polygon and upgraded the Vector2D type (removed a lot of stuff mostly). In my eyes the point,vector, circle, vertex, line and poly structure is very solid now and if anyone have great use of poly collisions I'm willing to share the source for free. There is still some things to do here and there. My basic idea seems to work. So I agree that the project may be over, and Haramanai it was not your fault, more mine. I got stuck in the programming and did not have any engery to keep struggeling with the math and collision algorithms. This combined with errors and bugs I had with Blitzmax itself (those have been fixed in the latest versions - thanks BRL). However If someone want to take this project to the next level with rigid body physics and all that fancy stuff that people would like to see. I'm very willing to share what I currently have. The verlet and contraints system looks promising. |
| ||
I would love the polygon collision source, I've been trying something but I'm not really happy with the result so far. Thanks! |
| ||
Mail me, I'll mail you back |
| ||
Wave or Haramania, I am doing some personal research in game physics. And I don't like buying any libraries. I like to make my own libraries gradually. I am sure I can handle the math part as I have background and mathematicians all around. Also, I get your vector2D very well. But I have a question. Your example codes, like circle2D related ones, tells me that to convert a regular game element to a mechanical (game physics) element, each kenetic object of the game must be redefined and some characteritics must be a vector, like gravity, mass, friction etc. Is that the way it must be develop in real production? My problem is less in math and mechanics, but is more in simulation and implementation. It seems to me once we begin to implement the objects of the game, we need to define all object's characteristics, at least those kenetic ones, as vector, and manipulate them according to physics laws. Am I right? Am I in right direction? See, some people have this kind of problem. You answer is appreciated. |
| ||
It seems that Internal physical entities needs their vectors defined inside the class of the object, and external physical entities needs their vectors to be defined as simply local vectors. For example, gravity is external, while velocity is internal. There are some factors which are scalar, not vector: like mass or friction. |
| ||
Hi Medi, if you mail me I can send you what I have. I developed this a little further (and the wiki code is down)but I never finished it off. The idea with this library (If I remeber correct) was that the library itself creates a physics-object for each object in your game that you want to simulate physics on. For example it could be your racing cars, or your 18 space ships. Each physics object have a position,velocity,acceleration and so on. You can then "sync" your ship with the appropriate physics object by using a function like: Type TAttackShip field x,y, and so on.. field physics:TMaxPhysicsObject ... Endtype To update your attackships in a method of TAttackShip: For Ship:TAttackShip = Eachin AttackshipList Ship.physics.update( x, y, and so on... ) Or if you use vectors you go: Ship.physics.update( Position, Velocity, Acceleration ) Next I still think the idea itself is nice, to bad the physics and maths was so complex. There was also a function to check for collision in different layers and another to act on those collisions depending on the elasticy of the object, something was wrong with the math so the colliding object did not behave as expected, yet the system itself worked to some degree. For example you may add all ships to one layer, all shots to another. Then you check ship-layer against itself, and against shot-layer. That's how simple your entire collision code will be! You can get a return on each object that collide so you can act acordingly, while the physicslibrary handle the actual displacement by the collision, the change in position, velocity and acceleration, all depending on the parameters of the physics-object. Adding gravity to all ships, or all shots should be trival. Something like: Loop all objects.. someObject.physicsObject.add( GravityVector ) or if you do not use vector2D.. someObject.physicsObject.addXY( GravityX, GravityY ) Next If you have time and are good at math and programming, then perhaps you could help get it done :) Or at least to wake this project from its deep sleep. |
| ||
Hi wave, A month ago I was very serious about going into 2d physics as a stage toward 3d physics. I studied the way you try to handle it and actually learned some key ideas. However, I discovered ODE and that put me in different world. Some game engines already use it. ODE seems to follow a particular design or methodology in applying physics for games. I am still studying it and don't know if that has any limitation yet. Now about your method, I faced a cross road. Your methodology above is either in the same line with ODE - if evolved, or is different. If it is the same in core, then all we need to do is to learn every bit of ODE , I mean ODE methods and codes which is on base of physics laws and numerical methods and etc. If not, then, I need to find weakness in ODE method in order to try to understand the advantage of your method. Or you may express it yourself like: this is the limitation with ODE method of applying physics and mine has this advantage. My passion of having my own small non-wrapper physics library for BlitzMAX has not died. But, realistically, by ODE, I feel i am in a different world and that need to be explored before having any personal effort. This is like PhD degree; you need to read all papers before forming your own thesis. Am I off the subject? Is any thing that I don't know and is making me to give too much credit to ODE? Please let me know. And thanks for your reply. |
| ||
MaxPhysics could just as well be used as a wrapper to The Open Dynamics Engine (ODE). I don't have much knowledge of ODE so correct me if I'm wrong, here is some points I see. Things that I see differ from MaxPhysics: -- ODE seems to me be built for 3D, so to use it in 2D I assume you need to have that in mind. -- MaxPhysics does not require any knowledge of Physics, or any knowledge of any other language than bmax. In MaxPhysics you model after the feeling (change some parameters). -- ODE is more complex, yet it also offers more features, it works, it is stable, it is faster, and tested, it is easier to use and quicker to implement in a game? -- ODE is not for blitzmax, so I assume it needs to be wrapped or similar? However if MaxPhysics would use ODE, it seems like we will have a very powerful physics library that will work in both 2D and 3D. Would that not be the optimal solution? For example in ODE-Spaces is a similar idea to Layers in MaxPhysics. To be able to add kick-ass physics to a project with just a few lines of code is pretty cool, which is what maxphysics can do. If the underlying math comes from ODE or is self-programmed should not be of any importance to the end user...if it works :P My way is not based on ODE, or any other physics engine, it is based on what I needed to have for functionality in a game. Adding Joints or more parameters so that the resulting physics can be controlled more is great, it is not limited by design (I fail to see than anyway). While my design is not the same as the ODE, it can, at least for the most part, be intergrated into it. I hope that answers your questions :) |
| ||
Where can i find the code for this project? The wiki page is a bit dead. Thanks. |
| ||
Yes, it seems like an incredibly confused thing that actually has no working code? No offense, just wondering why its sticky with no visible results... |
| ||
I'd really like to find code for this project if it's available... |
| ||
just wondering why its sticky with no visible results... Good point -- I've un-stickied it. It can always be stickied again if things pick up! |
| ||
Link Down :( |
| ||
Can we revive this community project? Tibit are you still around? I wish I had been into physics back then as I am now. I could have definitely contributed to this. I say let's finish it. |
| ||
I'm sure we could, but don't forget about the Chipmunk Physics wrapper of Brucey's. I have been using it, and has most of the features any one would need. |
| ||
has most of the features any one would need. And it's fast... |
| ||
Chipmunk Physics wrapper of Brucey's Is it 2d or 3d? Where is a link? I was thinking of writing a wrapper for box2d but it looked like a PITA and most likely overkill for what I am trying to do. |
| ||
http://www.blitzbasic.com/Community/posts.php?topic=72980 |