The rolling and stopping comes closer to reality. But running the program long enough - you see them still falling off the plane when the slow motion effect is not there.
The slow motion effect is still visible. It seems that WorldGravity(-90) to WorldGravity(-100) comes closest to a more realistic behavior as reading through applePI's Links shows.
What brings us to another point.
ApplePi's idea using #PB_Entity_ConvexHullBody makes the spheres stop. But once they stop, they are released from physics calculations. When you now move the floor they do not start rolling again but hang in the air until they got pushed (get an impulse) again. Toggle ImpulseFlag to view.
See this code I am testing with.
Use [W][A][S][D] to move the Camera; Numpad [8][4][6][2] to tilt the plane; [N] to launch more spheres;
EDITED: Added Stringgadgets for Spheres and Cubes count.
Code: Select all
;
; ------------------------------------------------------------
;
; PureBasic - PointJoint (Bridge)
;
; (c) 2011 - Fantaisie Software
;
; Bridge02.pb
;
; Changes from me And users. See http://www.purebasic.fr/english/posting.php?mode=reply&f=36&t=59735
;
; Use [W][A][S][D] to move the Camera, Numpad [8][4][6][2] to tilt the plane [N] to launch more spheres [I] to toggle ImpulseFlag
; ------------------------------------------------------------
;
IncludeFile "Screen3DRequester.pb"
#CameraSpeed = 1
#NbPlanks = 30
Define.f KeyX, KeyY, MouseX, MouseY
Dim Plank(#NbPlanks)
NewList Spheres.l()
NewList Cubes.l()
ImpulseFlag=1
If InitEngine3D()
Add3DArchive("Data/Textures", #PB_3DArchive_FileSystem)
Add3DArchive("Data/Scripts",#PB_3DArchive_FileSystem)
Add3DArchive("Data/Packs/desert.zip", #PB_3DArchive_Zip)
Add3DArchive("Data/GUI", #PB_3DArchive_FileSystem)
Add3DArchive("Data/fonts", #PB_3DArchive_FileSystem)
Parse3DScripts()
InitSprite()
InitKeyboard()
InitMouse()
If Screen3DRequester()
WorldShadows(#PB_Shadow_Modulative, -1, RGB(127, 127, 127))
EnableWorldPhysics(#True)
WorldGravity(-100)
;Materials
;
Tex_Wood0=LoadTexture(-1, "Wood.jpg")
Mat_Wood0=CreateMaterial(-1, TextureID(Tex_Wood0))
Mat_SphereRustySteel1=GetScriptMaterial(-1, "SphereMap/SphereMappedRustySteel")
Tex_Dirt2=LoadTexture(-1, "Dirt.jpg")
Mat_Dirt2=CreateMaterial(-1, TextureID(Tex_Dirt2))
Mat_GroundBlend3=GetScriptMaterial(-1, "Scene/GroundBlend")
; Ground
;
Plane3=CreatePlane(-1, 500, 500, 5, 5, 20, 20)
Ground3=CreateEntity(-1,MeshID(Plane3),MaterialID(Mat_Dirt2), 0, -50, 0)
EntityRenderMode(Ground3, 0)
EntityPhysicBody(Ground3, #PB_Entity_BoxBody, 0, 0.1, 10)
; Bridge
Cube0=CreateCube(-1, 1.0)
For i = 1 To #NbPlanks
Plank(i)=CreateEntity(#PB_Any, MeshID(Cube0), MaterialID(Mat_Wood0))
ScaleEntity(Plank(i), 2.8, 0.8, 20)
MoveEntity(Plank(i), i * 3, 0, 0, #PB_Absolute)
EntityPhysicBody(Plank(i), #PB_Entity_BoxBody, 10)
Next i
Pas.f = 1.5
PointJoint(#PB_Any, EntityID(Plank(1)), -Pas, 0, -5)
For i= 1 To #NbPlanks-2
Joint=PointJoint(#PB_Any, EntityID(Plank(i+1)), -Pas, 0, -5, EntityID(Plank(i)), Pas, 0, -5)
Next i
PointJoint(#PB_Any, EntityID(Plank(#NbPlanks)), Pas, 0, -5)
PointJoint(#PB_Any, EntityID(Plank(#NbPlanks-1)), Pas, 0, -5, EntityID(Plank(#NbPlanks)), -Pas, 0, -5)
PointJoint(#PB_Any, EntityID(Plank(1)), -Pas, 0, 5)
For i= 1 To #NbPlanks-2
Joint=PointJoint(#PB_Any, EntityID(Plank(i+1)), -Pas, 0, 5, EntityID(Plank(i)), Pas, 0, 5)
Next i
PointJoint(#PB_Any, EntityID(Plank(#NbPlanks)), Pas, 0, 5)
toto=PointJoint(#PB_Any, EntityID(Plank(#NbPlanks-1)), Pas, 0, 5, EntityID(Plank(#NbPlanks)), -Pas, 0, 5)
; Objects
;
Sphere2=CreateSphere(-1, 2, 36, 36)
C = Plank(1)
For i = 1 To #NbPlanks/2
AddElement(Spheres())
Spheres() = CreateEntity(#PB_Any, MeshID(Sphere2), MaterialID(Mat_SphereRustySteel1), EntityX(C) +i * 5, EntityY(C)+ i * 2, EntityZ(C))
EntityPhysicBody(Spheres(), #PB_Entity_ConvexHullBody, 1.5, 0.02, 1.0)
Next i
For i = 1 To #NbPlanks/2
AddElement(Spheres())
Spheres() = CreateEntity(#PB_Any, MeshID(Sphere2), MaterialID(Mat_SphereRustySteel1), EntityX(C) +i * 5, EntityY(C)+ i * 6, EntityZ(C))
EntityPhysicBody(Spheres(), #PB_Entity_ConvexHullBody, 1.5, 0.02, 1.0)
Next i
For i = 1 To #NbPlanks/2
AddElement(Spheres())
Spheres() = CreateEntity(#PB_Any, MeshID(Sphere2), MaterialID(Mat_SphereRustySteel1), EntityX(C) +i * 5, EntityY(C)+ i * 8, EntityZ(C))
EntityPhysicBody(Spheres(), #PB_Entity_ConvexHullBody, 1.5, 0.02, 1.0)
Next i
For i = 1 To #NbPlanks/2
AddElement(Cubes())
Cubes() = CreateEntity(#PB_Any, MeshID(Cube0), MaterialID(Mat_SphereRustySteel1), EntityX(C) +i * 5, EntityY(C)+ i * 4, EntityZ(C))
ScaleEntity(Cubes(), 3, 3, 3)
EntityPhysicBody(Cubes(), #PB_Entity_BoxBody, 1.0)
Next i
; Camera
;
Camera1=CreateCamera(-1, 0, 0, 100, 100)
MoveCamera(Camera1, -20, 30, -40, #PB_Absolute)
CameraLookAt(Camera1, EntityX(C) + 25, EntityY(C) + 10, EntityZ(C))
; Skybox
;
SkyBox("desert07.jpg")
; Light
;
CreateLight(0, RGB(255, 255, 255), 100, 800, -500)
AmbientColor(RGB(20, 20, 20))
;-GUI
RatioX = CameraViewWidth(Camera1) / ScreenWidth()
RatioY = CameraViewHeight(Camera1) / ScreenHeight()
MainWindw1=OpenWindow3D(-1, 0, 0, 280 * RatioX, 150 * RatioY, "FPS-Check")
StFPS1=StringGadget3D(-1 , 10 * RatioX, 10 * RatioY, 240 * RatioX, 30 * RatioY, "FPS")
StCount1=StringGadget3D(-1 , 10 * RatioX, 30+10 * RatioY, 240 * RatioX, 30 * RatioY, "Spheres")
StCount2=StringGadget3D(-1 , 10 * RatioX, 60+10 * RatioY, 240 * RatioX, 30 * RatioY, "Cubes")
ShowGUI(128, 0) ; Display the GUI, semi-transparent and display the mouse cursor
Plank = 1
Repeat
Screen3DEvents()
If ExamineMouse()
MouseX = -MouseDeltaX() * #CameraSpeed * 0.05
MouseY = -MouseDeltaY() * #CameraSpeed * 0.05
EndIf
If ExamineKeyboard()
If KeyboardPushed(#PB_Key_Space)
ApplyEntityImpulse(Plank(#NbPlanks/2), 0, 100, -100)
EndIf
If KeyboardReleased(#PB_Key_Return)
If Plank <= #NbPlanks
DisableEntityBody(Plank(Plank), 0)
FreeEntityJoints(Plank(Plank))
Plank + 1
EndIf
EndIf
If KeyboardReleased(#PB_Key_N)
For i = 1 To #NbPlanks/2
AddElement(Spheres())
Spheres() = CreateEntity(#PB_Any, MeshID(Sphere2), MaterialID(Mat_SphereRustySteel1), EntityX(C) +i * 5, EntityY(C)+ i * 6, EntityZ(C))
EntityPhysicBody(Spheres(), #PB_Entity_ConvexHullBody, 1.5, 0.02, 1.0)
Next i
EndIf
If KeyboardPushed(#PB_Key_A)
KeyX = -#CameraSpeed
ElseIf KeyboardPushed(#PB_Key_D)
KeyX = #CameraSpeed
Else
KeyX = 0
EndIf
If KeyboardPushed(#PB_Key_W)
KeyY = -#CameraSpeed
ElseIf KeyboardPushed(#PB_Key_S)
KeyY = #CameraSpeed
Else
KeyY = 0
EndIf
If KeyboardPushed(#PB_Key_Pad5)
;RotateEntity(Ground3, 0,0,0)
EndIf
If KeyboardPushed(#PB_Key_Pad2)
If ImpulseFlag=1
ForEach Spheres()
ApplyEntityImpulse(Spheres(), 0, 1, 0)
Next
ForEach Cubes()
ApplyEntityImpulse(Cubes(), 0, 0.1, 0)
Next
EndIf
RotateEntity(Ground3, 0, 0, 0.1, #PB_Relative)
EndIf
If KeyboardPushed(#PB_Key_Pad8)
If ImpulseFlag=1
ForEach Spheres()
ApplyEntityImpulse(Spheres(), 0, 1, 0)
Next
ForEach Cubes()
ApplyEntityImpulse(Cubes(), 0, 0.1, 0)
Next
EndIf
RotateEntity(Ground3, 0, 0, -0.1, #PB_Relative)
EndIf
If KeyboardPushed(#PB_Key_Pad4)
If ImpulseFlag=1
ForEach Spheres()
ApplyEntityImpulse(Spheres(), 0, 1, 0)
Next
ForEach Cubes()
ApplyEntityImpulse(Cubes(), 0, 0.1, 0)
Next
EndIf
RotateEntity(Ground3, -0.1, 0, 0, #PB_Relative)
EndIf
If KeyboardPushed(#PB_Key_Pad6)
If ImpulseFlag=1
ForEach Spheres()
ApplyEntityImpulse(Spheres(), 0, 1, 0)
Next
ForEach Cubes()
ApplyEntityImpulse(Cubes(), 0, 0.1, 0)
Next
EndIf
RotateEntity(Ground3, 0.1, 0, 0, #PB_Relative)
EndIf
If KeyboardReleased(#PB_Key_I)
ImpulseFlag=1-ImpulseFlag
EndIf
EndIf
MoveCamera (Camera1, KeyX, 0, KeyY)
RotateCamera(Camera1, MouseY, MouseX, 0, #PB_Relative)
SetGadgetText3D(StFPS1, "FPS=" + Str(Engine3DStatus(#PB_Engine3D_CurrentFPS))+" I="+Str(ImpulseFlag))
SetGadgetText3D(StCount1, "Spheres=" + Str(ListSize(Spheres())))
SetGadgetText3D(StCount2, "Cubes=" + Str(ListSize(Cubes())))
RenderWorld()
Screen3DStats()
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
EndIf
Else
MessageRequester("Error", "The 3D Engine can't be initialized",0)
EndIf
End
It would be interesing to know when the framerate drops on different systems ... on mine the framerate drops below 60 when 105 Spheres + 15 Cubes are launched.
Well, what I do is try and error ... the manual does not explain what really happens behind the scene ...
Next will be using #PB_Entity_SphereBody again and bmon's stop-the-spheres-code.
.