This just takes advantage of sliding collisions to move the ball, so nothing fancy (other than Marks collision code). As big10p says the ball is parented and moves with and relative to the 'flat'. Any erroneous ball collisions are discarded immediately after movement of the 'flat' (they will be bad because the ball is always in a contact situation with the mesh and the collision system does not deal with sphere to poly collisions if the poly object is moving - penetration will occur). The ball is then translated down true to the world and will slide along the rotated 'flat'. Thanks are due to S. Swift for the nifty ball rotation.
Edit. I have now finished messing with it for the time being. :)
;Graphics Graphics3D 800,600,16,2 SetBuffer BackBuffer() ;Collisions Const COL_BALL=1,COL_LAB=2 Collisions COL_BALL,COL_LAB,2,2 ;sphere-to-polygon, sliding collisions ;Frames per Second Const FPS=30 ;Lab Global lab=CreateCube(), labrotx#, labrotz# EntityAlpha lab,0.5 Const LAB_LENGTH = 30 ScaleMesh lab,LAB_LENGTH,1,LAB_LENGTH EntityColor lab,200,200,100 lab1=CopyEntity(lab,lab) EntityColor lab1,150,150,50 ScaleEntity lab1,1,0.2,0.1 RotateEntity lab1,90,90,0 PositionEntity lab1,-LAB_LENGTH,4,0 lab2=CopyEntity(lab1,lab) PositionEntity lab2,LAB_LENGTH,4,0 lab3=CopyEntity(lab1,lab) RotateEntity lab3,-90,0,0 PositionEntity lab3,0,4,LAB_LENGTH lab4=CopyEntity(lab3,lab) PositionEntity lab4,0,4,-LAB_LENGTH EntityType lab,COL_LAB,True ;Ball Global ball=CreateSphere() ScaleMesh ball,3,3,3 checktex ball,0.25,0.25 ;EntityColor ball,200,100,50 EntityType ball,COL_BALL EntityRadius ball,3 EntityParent ball,lab TranslateEntity ball,0,20,0 ;Camera camera=CreateCamera() PositionEntity camera,0,20,-50 PointEntity camera,lab ;Light light=CreateLight() PositionEntity light,50,50,-150 PointEntity light,lab ;mouse MoveMouse GraphicsWidth()/2,GraphicsHeight()/2 ;------------------------------; ; Main ;------------------------------; period=1000/FPS time=MilliSecs()-period While Not KeyHit(1) If KeyHit(17) wire=Not wire WireFrame wire EndIf Repeat elapsed=MilliSecs()-time Until elapsed ;how many 'frames' have elapsed ticks=elapsed/period ;fractional remainder tween#=Float(elapsed Mod period)/Float(period) For k=1 To ticks time=time+period If k=ticks Then CaptureWorld UpdateLab(0.25,3,40) Next If MouseDown(1) Then MoveMouse GraphicsWidth()/2,GraphicsHeight()/2 RenderWorld tween Flip Wend End ;------------------------------; ; End Main ;------------------------------; Function UpdateLab(rotrate#,ballrate#,rotlimit#=30) ;Store Mouse Movement mxs = MouseXSpeed() mys = MouseYSpeed() oldx#=EntityX(ball) oldz#=EntityZ(ball) If MouseDown(1) ;linke maustaste ;X-Axis labrotx = labrotx - mys * rotrate If Abs(labrotx)>rotlimit Then labrotx = Sgn(labrotx) * rotlimit ;Z-Axis labrotz = labrotz - mxs * rotrate If Abs(labrotz)>rotlimit Then labrotz = Sgn(labrotz) * rotlimit RotateEntity lab,labrotx,0,labrotz,True ;True = relative to 0,0,0 origin ResetEntity ball ; discard any erroneous ball collisions EndIf If MouseDown(2) ;right mouse, reposition ball PositionEntity ball,0,20,0,True End If TranslateEntity ball,0,-ballrate,0,True UpdateWorld rollerball ball,3,oldx,oldz End Function Function checktex(entity,sx#=0.25,sy#=0.25) texture=CreateTexture(128,128) SetBuffer TextureBuffer(texture) Color 128,128,128 Rect 0,0,128,128 Color 128,0,0 Rect 0,0,64,64 Rect 64,64,64,64 SetBuffer BackBuffer() EntityTexture entity,texture ScaleTexture texture,sx,sy Return texture End Function Function rollerball(ball,ballrad#,oldx#,oldz#) ; get distance ball has moved NewX# = EntityX(ball) NewZ# = EntityZ(ball) Mx# = (NewX# - OldX#) Mz# = (NewZ# - OldZ#) ; SSwift rotation code: ; Rotate the entity the right amount for it's radius and the distance it has moved along the X and Z axis. ; This is kinda a hack and only designed for rolling on planes but you won't notice the difference. XAngleAdjust# = (Mx# / ballrad) * (180.0/Pi) ZAngleAdjust# = (Mz# / ballrad) * (180.0/Pi) TurnEntity ball,ZAngleAdjust#,0,-XAngleAdjust#,True End Function
Edit. I have now finished messing with it for the time being. :)