Newton question and timeline update
BlitzMax Forums/MiniB3D Module/Newton question and timeline update
| ||
So, I think it is time to give a close overview about my progress on extending minib3d: First the good news: Maybe some of you could remember the Shaderbased PostFX code/demo of Anthony. So I have succesfully integrated it to my extended Version without the restriction of Anthonys Version (it was only usable with squared resolutions). Also the newton implementation comes along nicely. I'm currently working on the material system. And ther I need some help, but this will come later. Here is a small demo (win32 only) : Minimum requirement is a shader 2.0 gfx card http://klepto2.kl.funpic.de/DL/NewtonPostFX.rar Controls: Enter --> Spawn new random boxes F1/F2 --> Change Default Elasticity F3/F4 --> Change Default Friction F5/F6 --> Change Default Softness F7/F8 --> Change the bullets mass (boxes have a random mass) Keys 0-3 --> Apply PostFX (you can combine all) Space --> Turn Vsync off (don't move mouse hard because you may leave the window ) Left Mousebutton: Fire bullet Right MouseButton : Apply random Force to a picked body Also here is a small (30 sec.) video: http://www.myvideo.de/watch/772486 Now I have a problem with the materials: My plan was/is to create a mainly abstract layer to the newton engine. And to achieve that I planned a material type in which you could create different materials. But to simplifiy things I want to add an automated function which will apply the different values to each other available material. But to do this I have to know how to calculate (if this this possible) the friction between 2 different materials. EG: mat a has a friction of 0.8, mat b has friction of 0.3 . So what is the friction when both interact? Btw: You could also override the material settings by yourself. So the automated thing is just a simplification (5 materials already have a minimum of 25 different combinations). If someone already has some experience with newton and know how to calculate this, I would be really happy. thx klepto2 PS: @Chris: sorry I had some problems with my email account (so I'dont know if my answer has arrived): I think you have to change the Rotations to euler based rotations and then simply rotateEntity(). The code how it is currently down in my wrapper: and the corrosponding functions: Also as soon the material system works properly I will send you the code to create a (hopefully working) linux version. |
| ||
Good news klepto2 and amazing demo like always... |
| ||
as far as materials are concerned, theres no real way to accurately calculate material/material interactions (you can do it for friction but where there are multiple property types it gets more complex) I implemented something in ode once, where each object was assigned an material ID, and there was a behaviors table so material ID x and material ID y would have particular friction, restitution etc properties |
| ||
thx Chris, I have just read some theories about the material system, and I think i will apply them to my material system. As far as I now know there are different ways to apply the friction of to materials. 1. Min based : the lowest friction indicates the resulting friction 2. Max based : the same as 1 but this time the max friction 3. Average based: the average is builded between the 2 materials 4. Priority based: that means you have to assign a priority value to each material, if both prios are the same, then the average is build, else the friction with the most priority is used. I think I will implement it this way because the manual overriding of material pair settings is already possible and so whoe needs could modify the rules by his needs. |
| ||
Again, excellent stuff: With VSync on I got a smooth 60 FPS regardless what effects turned on, combined, etc. With VSync off I got: No Effects: 487 FPS Effect 0: 110 FPS Effect 1: 258 FPS Effect 2: 93 FPS Effect 3: 320 FPS Eff. 0+1: 106 FPS Eff. 0+2: 75 FPS Eff. 0+3: 105 FPS Eff. 1+2: 80 FPS Eff. 1+3: 205 FPS Eff. 2+3: 84 FPS 0+ 1+ 2: 68 FPS 0+ 1+ 3: 106 FPS 0+ 2+ 3: 71 FPS 1+ 2+ 3: 74 FPS 0+1+2+3: 63 FPS Intel CoreDuo 1.8 GHz, 1 GB RAM, ATi Radeon x1600 But I think the bloom shader is somewhat over the top :-D ![]() |
| ||
On the multiple friction problem: I would have used the physical way. Frictions are defined against a "opposite material friction" of 0, so as if the other side does not have any friction. What happens when two different materials with friction > 0 are used, is that they push each other up (so from that point of view, any of the 4 possibilities is just wrong. It won't land in between in normal cases. You know that most likely from experience in reality. Tires against Tires is much higher friction than Tires against Ice ^^) I've seen different approaches to that (there is no generic one as in physics, the actual surface structure makes a diff), but basically you have max(fric1, fric2) + a*fric1*fric2 where a bases on the surface structure of the 2 in relation to each other. |
| ||
I know that friction is not really material based, instead is is system based (temp, preasure, etc. is effecting the result). But to be honest I don't understand your last formula in relation to your first explanation. To explain what I mean I will use your example with Ice and a tire of rubber. Ice has a very low friction, lets say 0.015. the rubber tire has a very high friction of around 0.8 : (Values are fantasy based). normally you stated that the friction is much lower because of the ice friction. but with your last stated formula the friction always will be bigger than 0.8 . So the average value would be the most accurate in this case or did I understand you wrong? |
| ||
Ice is something that I assume to have ~0 friction, but you are right, the explanation was not really clear on how handle the whole thing mathematically as the point of where it will become larger is not at 0. For game usage of physics, I think average would be a good solution I think. An alternative idea could be weight based combination. With weight based I mean that you define a "friction" which is assumed to be the "0 impact" friction, so if one of the 2 materials has that friction, the combined friction would be the friction of the other material. If it is below then the combined is lower than the other and if the materials friction is higher than that value, the combined would be larger than the other materials friction. Most likely a not that understandable explanation so here a mathematical version :) combinedFric = maxFric + (minFric - zeroImpactFric) * maxFric = maxFric * (1 + minFric - zeroImpactFric) As an example (pure fantasy) Tire: 0.8 Polished Metal: 0.5 (zeroImpact) Ice: 0.1 Now if the tire is on ice this would mean: combinedFric = 0.8 * (1 + 0.1 - 0.5) = 0.8 * 0.6 = 0.48 Average in this case would be 0.45 The difference isn't really present. So for regular cases, using that assumption would work. Did you have a look at the NewtonPlayGround on how they handle this kind of stuff? PS: Main problem behind this whole ideas of mine and perhaps others is that friction as such is defined as a force factor that specifies the brake force between 2 different materials. It is not an attribute of a single material. For that reason, in above weight-based idea I better should have called it surfaceFactor and the "combinedFric" is actually the friction between those 2 materials. |
| ||
I have been keeping an eye on all this miniB3D malarky with a view to maxing out at some point - and I must say this is all really awesome. Excellent work Klepto2, very very impressive demo. |
| ||
Excellent Work Klepto! Demo is awesome. |
| ||
Nice work klepto. What 3d engine are you using for this demo and how do you load those shaders? |
| ||
short and simple : minib3d (my extended Version)????? |
| ||
Well, because of the release of version 0.41 I have decided not to release my new version yet. This is because there are alot of bufixes in 0.41 which should all be build in my extended Version. But to give you something I will give you a short statusreport about the newton implemntation: I have get it to work on Win32,Linux and MacOS so it is directly passing the no. 1 rule of minib3d ;). Also I'm very proud to the materialsystem I have build around the Newton Lib. As for a PhysicsEngine noob like me I think it is very easy to understand. here is small codesample how to setup a materials (currently everthing is OOP) : Framework sidesign.minib3d Import BRL.FreeAudioAudio Import BRL.WAVLoader Import BRL.Random Import BRL.StandardIO Import BRL.System Strict Local width=800,height=600,depth=32,mode=2 Global EmitterList:TList = New TList Graphics3D width,height,depth,mode Global Boing:TSound = LoadSound("boing.wav") Global spark:Tsprite = LoadSprite("bluspark.bmp") HideEntity spark Global cam:TCamera=CreateCamera() PositionEntity cam,0,30,0 Local light:TLight=CreateLight(,cam) RotateEntity light,45,0,0 ' used by camera code Local mxs#=0 Local mys#=0 Local move#=0.5 MouseXSpeed() ' flush MouseYSpeed() ' flush ' used by fps code Local old_ms=MilliSecs() Local renders Local fps Local Physic:TPhysic = InitPhysic() 'Will disapear to the inernals Physic.SetPhysicModel(0,0) Local Wood:TPhysicMaterial = TPhysicMaterial.Create("Wood") wood.SetFriction(0.6,0.5) wood.SetSoftness(1.0) wood.SetElasticity(0.4) Local Metal:TPhysicMaterial = TPhysicMaterial.Create("Metal") Metal.SetFriction(0.5,0.4) Metal.SetSoftness(1.0) Metal.SetElasticity(.1) Physic.AddMaterial(Metal) Physic.AddMaterial(Wood) Physic.BuildMaterialLibraries() Physic.SetCollisionMode(Metal,Wood,PHYS_CONTINUES_COLLISION) TPhysic.ContactEnd = ContactEndhandle TPhysic.ContactProcess = ContactProcessHandle SeedRnd(MilliSecs()) Global plane:TMesh=LoadMesh("media/test.b3d") ScaleMesh plane,10,10,10 PositionEntity(Plane,0,0,0) EntityPickMode Plane,2 Plane.UpdateBuffer() CreateOctree(plane,20,5) ' set camera entity type to 1 EntityType cam,1 EntityRadius cam,4 EntityType plane,2 Collisions 1,2,4,2 Local NPlane:TNewtonObject = TNewtonObject.Create(Plane,PHYS_MESHCOMPLEX_HULL) NPlane.SetMass(0.0) ' Set it solid Physic.AddObject(NPlane) 'Give it to the Physic engine Physic.SetBodyMaterial(NPlane,"Metal") SetWorldSize(Physic,NPlane.AABB[0],NPlane.AABB[1]) For Local X:Int = 0 To 15 For Local Y:Int = 0 To 5 Local cube:TMesh=CreateCube() 'ScaleEntity(cube,5,5,5) EntityRadius cube,2 EntityPickMode cube,2 PositionEntity cube,Rand(NPlane.AABB[0].X/2,NPlane.AABB[1].X/2),Rand(NPlane.AABB[0].Y,NPlane.AABB[1].Y),Rand(NPlane.AABB[0].Z,NPlane.AABB[1].Z) EntityColor(cube,Rand(255),Rand(255),Rand(255)) Local NCube:TNewtonObject = TNewtonObject.Create(cube,PHYS_BOX_HULL) 'Create the Collision Hull (Parameters are set automatically) NCube.SetMass(Rnd(1.0,100.0)) ' Make it movable and a accurate ball Physic.AddObject(NCube) 'Give it to the Physic engine Physic.ApplyImpulse(cube,0.0,0.0,0.0,0.0,0.0,0.0) Physic.SetBodyMaterial(NCube,"Metal") Next Next Local Timestep:Int = MilliSecs() Local EValue:Float = 0.5 Local FValue:Float = 0.5 Local SValue:Float = 0.5 Local Mass:Float = 1.0 Global blurpass:Int = 5.0 Global multiply:Float = .02 Global pick:TEntity While Not KeyDown(KEY_ESCAPE) Pick = Null Local Pitch:Float = EntityPitch(Cam) Local Yaw:Float = EntityYaw(Cam) Local Roll:Float = EntityRoll(Cam) Local TempX:Float = EntityX(Cam) Local TempY:Float = EntityY(Cam) Local TempZ:Float = EntityZ(Cam) ' control camera ' mouse look mxs#=mxs#+(MouseXSpeed()/5.0) mys#=mys#+(MouseYSpeed()/5.0) RotateEntity cam,mys#,-mxs#,0 If KeyDown(KEY_SPACE)=False MoveMouse width/2,height/2 MouseXSpeed() ' flush MouseYSpeed() ' flush EndIf ' move camera forwards/backwards/left/right with cursor keys If KeyDown(KEY_UP)=True Then MoveEntity cam,0,0,move# ' move camera forward If KeyDown(KEY_DOWN)=True Then MoveEntity cam,0,0,-move# ' move camera back If KeyDown(KEY_LEFT)=True Then MoveEntity cam,-move#,0,0 ' move camera left If KeyDown(KEY_RIGHT)=True Then MoveEntity cam,move#,0,0 ' move camera right ' if mousehit then perform camerapick If MouseHit(2) pick=CameraPick(cam,MouseX(),MouseY()) If pick<>Null Local XP:Float = Rnd(-25.0,25.0) Local YP:Float = Rnd(-25.0,25.0) Local ZP:Float = Rnd(-25.0,25.0) ' Apply a random impulse to the picked ball Physic.ApplyImpulse(pick,PickedX(),PickedY(),PickedZ(),XP,YP,ZP) EndIf EndIf If MouseHit(1) CameraPick(Cam,MouseX(),MouseY()) Local Bullet:TMesh = CreateSphere(8) ScaleMesh(Bullet,3,3,3) PositionEntity(Bullet,EntityX(Cam),EntityY(Cam),EntityZ(Cam)) EntityColor bullet,255-Mass,0,0 bullet.setrenderpass(1) Local NBullet:TNewtonObject = TNewtonObject.Create(Bullet,PHYS_SPHERE_HULL) NBullet.SetMass(MAss) ' Set it solid NBullet.SetCollisionMode(PHYS_CONTINUES_COLLISION) Physic.AddObject(NBullet) 'Give it to the Physic engine Physic.SetBodyMaterial(NBullet,"Wood") Local V1:TVector = TVector.Create(PickedX(),PickedY(),PickedZ()) Local V2:TVector = TVector.Create(EntityX(Cam),EntityY(Cam),EntityZ(Cam)) Local V3:TVector = V1.Subtract(V2).Multiply(2) Physic.ApplyImpulse(Bullet,EntityX(Bullet),EntityY(Bullet),EntityZ(Bullet),V3.X,V3.Y,V3.Z) EndIf If KeyDown(KEY_ENTER) Local cube:TMesh=CreateCube() EntityRadius cube,2 EntityPickMode cube,2 PositionEntity cube,Rand(NPlane.AABB[0].X/2,NPlane.AABB[1].X/2),Rand(NPlane.AABB[0].Y,NPlane.AABB[1].Y),Rand(NPlane.AABB[0].Z,NPlane.AABB[1].Z) EntityColor(cube,Rand(255),Rand(255),Rand(255)) Local NCube:TNewtonObject = TNewtonObject.Create(cube,PHYS_BOX_HULL) 'Create the Collision Hull (Parameters are set automatically) NCube.SetMass(Rnd(1.0,100.0)) ' Make it movable and a accurate ball Physic.AddObject(NCube) 'Give it to the Physic engine Physic.ApplyImpulse(cube,0.0,0.0,0.0,0.0,0.0,0.0) EndIf If KeyDown(KEY_F1) Then EValue:+0.001 Physic.SetDefaultElasticity(Evalue) EndIf If KeyDown(KEY_F2) Then EValue:-0.001 Physic.SetDefaultElasticity(Evalue) EndIf If KeyDown(KEY_F3) Then FValue:+0.001 Physic.SetDefaultFriction(Fvalue,Fvalue-0.10) EndIf If KeyDown(KEY_F4) Then FValue:-0.001 Physic.SetDefaultFriction(Fvalue,Fvalue-0.10) EndIf If KeyDown(KEY_F5) Then SValue:+0.001 Physic.SetDefaultSoftiness(Svalue) EndIf If KeyDown(KEY_F6) Then SValue:-0.001 Physic.SetDefaultSoftiness(Svalue) EndIf If KeyDown(KEY_F7) Then Mass:+0.1 'Physic.SetDefaultSoftiness(Svalue) EndIf If KeyDown(KEY_F8) Then Mass:-0.1 'Physic.SetDefaultSoftiness(Svalue) EndIf For Local E:TEmitter = EachIn EmitterList E.Update() If MilliSecs()-E.StartTime>E.LifeTime Then If ListIsEmpty(E.Particles) = True Then ListRemove(Emitterlist,E) EndIf EndIf Next Physic.Update() UpdateWorld() RenderWorld() renders=renders+1 ' Update the physics (Update time is automatically calculated and passed as Deltatime within the engine) If MilliSecs()-old_ms>=1000 old_ms=MilliSecs() fps=renders renders=0 EndIf SetBlend AlphaBlend DrawText "FPS: "+String(fps),0,0 Text 0,20,"Elasticity : " + EValue Text 0,40,"Friction : " + FValue + " - " + (FValue - 0.10) Text 0,60,"Softiness : " + SValue Text 0,80,"TimeStep : " + Physic.GetPhysicTime() Text 0,100,"Active Bodies: " + Physic.GetActiveBodyCount() Text 0,120,"InActive Bodies: " + Physic.GetUnActiveBodyCount() Text 0,140,"Bullet MAss: " + Mass Text 0,160,"Position : " + EntityX(Cam) + "/" + EntityY(Cam) + "/" + EntityZ(Cam) Text 0,180,"Emitters : " + Emitterlist.Count() If KeyDown(KEY_Space) Flip 0 Else Flip EndIf Wend End Function ContactProcesshandle(Info:TContactInfo) Local mat1:String = Info.body1.material.name Local mat2:String = Info.body2.material.name If (mat1 = "Wood" And mat2 = "Metal") Or (mat2 = "Wood" And mat1 = "Metal") If Abs(Info.Body2.GetVelocity().Length()/25.0) > 0.9 Local C:TChannel = AllocChannel() SetChannelVolume(C,.6 - Clamp(VectorDistance(Cam,Info.ContactPosition)/300.0,0,.6) ) PlaySound(boing,c) Local E:TEmitter = New TEmitter E.Position = Info.ContactPosition EmitterList.Addlast(E) EndIf EndIf End Function Function ContactEndhandle(Info:TContactInfo) End Function Function Clamp:Float(value:Float,_Min:Float,_Max:Float) Local Back:Float = Min(value,_Max) Return Max(Back,_Min) End Function Type TEmitter Field Position:TVector Field LifeTime:Int = 40 Field Partperloop:Int = 25 Field StartTime:Int = MilliSecs() Field Particles:TList = New TList Method Update() If MilliSecs()-StartTime<LifeTime Then For Local I:Int = 0 To PartPerLoop Local P:TParticle = New TParticle P.Sprite = TSprite(CopyEntity(Spark))'CreateSprite() ScaleSprite P.Sprite,0.2,0.2 'EntityTexture P.Sprite,Texture ' EntityBlend(P.sprite,1) 'EntityFX(P.Sprite,32) EntityColor(P.Sprite,200,20,40) PositionEntity P.Sprite,Position.X,Position.Y,Position.Z P.Position = Position P.Velocity = New TVector P.Velocity.X = Rnd(-.1,.1) P.Velocity.Y = Rnd(-.1,.1) P.Velocity.Z = Rnd(-.1,.1) ShowEntity P.Sprite Particles.Addlast(P) Next EndIf For Local PT:TParticle = EachIn Particles PT.Update() If MilliSecs()-PT.Starttime > PT.Life Then FreeEntity PT.Sprite ListRemove(Particles,PT) EndIf Next End Method End Type Type TParticle Field Sprite:TSprite = New TSprite Field Position:TVector Field Velocity:TVector Field Life:Int = 300 Field Starttime:Int = MilliSecs() Method Update() EntityAlpha Sprite,1.0-(1.0/Life)*(MilliSecs()-Starttime) MoveEntity Sprite,Velocity.x,Velocity.y,Velocity.z End Method End Type Maybe you see the ContactProcessCallback here, This a Funcion Pointer which is called from the Physicimplemtation everytime Newton Processes a contact. The Contactinfo(bodies,materials,ContactPoint etc) is gathered directly internally and you could use it in this callback to emit sounds or particles or change the material reaction. |
| ||
can friction etc settings be over ridden in the callback? |
| ||
That code ROCKS. It's like... ROCK... ing... thing! Anyway, it really is cool. When can we expect that module? |
| ||
Yes, the settings could be overridden, as they are called with the corrosponding original Callback. And I hope to get finished (yesterday I have succesfully integrated some joint functions) this week. |
| ||
Yes! :D |
| ||
So, it is not long till the first release: so here is small video with some added features: Newton Dynamics A Newton Joint Rope Newton Collision Debug View and a new command I have called EntityRenderStyle() this command let you decide per entity in which way it will be rendered. (Full,Wireframe or points) Sorry for the fat 'demo' watermark: http://www.myvideo.de/watch/843471 |
| ||
video looks great. |
| ||
Great, will it run on Mac, too? =) |
| ||
yes, it will run on win,mac and linux (all tested) I'm just making the finishing touches (procedural interface, first simple docs) so the release date isn't far away now. PS: the first release will not have: -Vehicle -custom joints and rigid bodies (I will firstly release what I have) -not all callback functions (eg: material manipulation) aren't fully implemented yet, but will be in further versions. |
| ||
Looks excellent. The fact that you've got Newton working on all platforms is good news indeed, I may have to start using your module :) |
| ||
As I see it, Simonh, Klepto2 and Chris C have all been working very hard to create a cross-platform, inherently usable 3D solution for BlitzMax as well as smashing a few bugs along the way. All of you deserve to be proud of your accomlishments. I fro one am very grateful for your hard work. I am actually working on a game using this system right now. I'll post a screenshot as soon as there is something reasonably tolerable to look at :) Thanks again fellas! |
| ||
well i wouldnt say *I've* been working that hard! I would however urge anyone to post code on this forum to help improve and where needed fix stuff as people find it. That way simon can continue to maintain his nice creation and people who want to develop it in different directions like klepto are free to do so. The more people post code, ideas/suggestion, fix's the better for ALL |
| ||
Sorry for the delay with the new Version, but I have a good reason for this. it is maybe hard to describe but here you have the reason why the update is related: http://www.myvideo.de/watch/898684 Look the video and you will understand ;) I hope for a beta release this weekend. cheers klepto2 [PS: I have just forgotten to mention the progress with newton. Well my mod /integration now doesn't need the newton.dll on win32 instead newton is linked static. ] |
| ||
wow phisic + shadows!! shadows is a stencil or you use a stencil +shaders? thanks mongia |
| ||
Wow, excellent |
| ||
Most exciting! |
| ||
What sort of shadows are you using? Carmacks reverse? |
| ||
Yeah it is Carmacks Reverse and currently it has 3 Rendermodes: the first is to render the scene(full),Render the shadows to the stencil, then a black transparent quad is rendered over the viewport. the second is to render the scene(only ambient),Render the shadows to the stencil, Render the whole scene again with full light on. the third is just the debug mode and shows the shadowvolumes. the second pass enables you to have more blended shadows, so the shadow is not seen in very dark areas or 'hides' when coming to more or same dark areas. Currently I'm currently trying to solve the inverting shadow bug when the cam is inside a shadovolume. (Normally this should be done automatically with carmacks reverse, but this only works when using a infinite clip plane. And at the moment my approaches to enable this in opengl simply fails) If someone could show me how to implemnt an infinte clip plane in Opengl and minib3ds camera system, or could point me to the right direction I would be very happy :) . Oh, for the stencil shadows a lot of thanks has to go to 'devils child' who gave me the allowence to use his volume generation code in minib3d. [Correction] The current Algo doesn't use carmacks reverse(zFail), It currently uses ZPass and thats the reason for the inverted shadow bug. I have tried to implemnt carmacks reverse but without success. The code should be compatible (shadowVolume Creation) but I will let it currently this way. And maybe someone else will have more luck to get it working with zfail after I have released the source. Maybe Leadwerks or other Engine Writers (Pointing to Mark Sibly) may have look then i try it ;) . [/Correction] |
| ||
great work, indeed. |
| ||
Superb, can't wait to test it on my iMac. @klepto2: If you want to release some testapps to test your new module revision and want to have a Mac OS X version as well, then send me all the stuff and I will compile a MacTel executable for you. |