;Ball rolling physics example by Jeppe Nielsen 2003
Const gravity#=-0.04;-0.02 ;gravity constant
Graphics3D 800,600,16,1
Const ball_col=1
Const world_col=2
Collisions ball_col,world_col,2,2
Global texture
texture=CreateTexture(16,16)
SetBuffer TextureBuffer(texture)
Color 255,255,255
Rect 0,0,16,16,1
Color 255,0,0
Rect 0,0,8,8,1
Rect 8,8,8,8,1
ScaleTexture texture,0.1,0.1
Global groundtexture=CreateTexture(32,32,1+8)
SetBuffer TextureBuffer(groundtexture)
Color 0,0,0
Rect 0,0,32,32,1
Color 0,0,255
Rect 0,0,32,32,0
ScaleTexture groundtexture,2,2
SetBuffer BackBuffer()
Color 255,255,255
plane=CreatePlane()
EntityTexture plane,groundtexture
EntityType plane,world_col
EntityAlpha plane,0.5
mirror=CreateMirror()
light=CreateLight(1)
RotateEntity light,30,20,0
obj=CreateCube()
EntityType obj,world_col
PositionEntity obj,0,0,0
ScaleEntity obj,10,10,10
RotateEntity obj,45,0,0
camera=CreateCamera()
CameraClsColor camera,0,0,255
ball.ball=ballnew(0,4,-120,2,0.8)
zoom#=14
Repeat
zoom#=zoom#-MouseZSpeed()
ballcamera(camera,ball,0,zoom#,-zoom#,0,5,0)
ballcontrol()
ballupdate()
RenderWorld()
Text 10,10,"Arrow keys to control ball"
Text 10,30,"Scroll on mouse to zoom"
Flip
Until KeyDown(1)
End
Type ball
Field e ;entity
Field sphere
Field pivot
Field x#,y#,z# ; position in 3d-space
Field vx#,vy#,vz# ; velocity
Field ax#,ay#,az# ; acceleration
Field size#
Field bounce# ; bounce factor
Field vel#
Field vx2#,vy2#,vz2# ; temp velocity
End Type
Function ballnew.ball(x#,y#,z#,size#=1,bounce#=0.9)
c.ball=New ball
c\x#=x#
c\y#=y#
c\z#=z#
c\size=size
c\bounce#=bounce#
c\e=CreatePivot()
c\sphere=CreateSphere(64)
c\pivot=CreatePivot()
EntityType c\e,ball_col
EntityRadius c\e,c\size
PositionEntity c\e,c\x,c\y,c\z
ScaleEntity c\sphere,c\size,c\size,c\size
EntityTexture c\sphere,texture
Return c
End Function
Function ballupdate()
For c.ball=Each ball
c\vy#=c\vy#+gravity#
c\vx#=c\vx#+c\ax#
c\vy#=c\vy#+c\ay#
c\vz#=c\vz#+c\az#
c\x#=EntityX(c\e)
c\y#=EntityY(c\e)
c\z#=EntityZ(c\e)
TranslateEntity c\e,c\vx,c\vy,c\vz
Next
UpdateWorld()
For c.ball=Each ball
;correct velocity if collided
c\vx2=(EntityX(c\e)-c\x)
c\vy2=(EntityY(c\e)-c\y)
c\vz2=(EntityZ(c\e)-c\z)
c\x#=EntityX(c\e)
c\y#=EntityY(c\e)
c\z#=EntityZ(c\e)
PositionEntity c\sphere,c\x,c\y,c\z
PositionEntity c\pivot,c\x,c\y,c\z
If EntityCollided(c\e,world_col)
For i = 1 To CountCollisions(c\e)
; Get the normal of the surface which the entity collided with.
Nx# = CollisionNX(c\e, i)
Ny# = CollisionNY(c\e, i)
Nz# = CollisionNZ(c\e, i)
; Compute the dot product of the entity's motion vector and the normal of the surface collided with.
VdotN# = c\vx#*Nx# + c\vy#*Ny# + c\vz#*Nz#
; Calculate the normal force.
NFx# = -2.0 * Nx# * VdotN#
NFy# = -2.0 * Ny# * VdotN#
NFz# = -2.0 * Nz# * VdotN#
; Add the normal force to the direction vector.
c\vx# = c\vx# + NFx# * c\bounce#
c\vy# = c\vy# + NFy# * c\bounce#
c\vz# = c\vz# + NFz# * c\bounce#
avx#=EntityPitch(c\sphere)
avy#=EntityYaw(c\sphere)
avz#=EntityRoll(c\sphere)
;Rotate stuff
;Get vector from center to collision
dx1#=(CollisionX(c\e,i)-c\x)
dy1#=(CollisionY(c\e,i)-c\y)
dz1#=(CollisionZ(c\e,i)-c\z)
dx2#=c\vx
dy2#=c\vy
dz2#=c\vz
;Cross product
cx# = ( dy1 * dz2 ) - ( dz1 * dy2 )
cy# = ( dz1 * dx2 ) - ( dx1 * dz2 )
cz# = ( dx1 * dy2 ) - ( dy1 * dx2 )
AlignToVector c\pivot,cx,cy,cz,1
Next
Nx# = CollisionNX(c\e, 1)
Ny# = CollisionNY(c\e, 1)
Nz# = CollisionNZ(c\e, 1)
AlignToVector c\e,Nx#,Ny#,Nz#,2,0.5
c\vel#=Sqr(c\vx2*c\vx2+c\vy2*c\vy2+c\vz2*c\vz2)
;slow down due to friction
c\vx#=c\vx*0.98
c\vy#=c\vy*0.98
c\vz#=c\vz*0.98
EndIf
EntityParent c\sphere,c\pivot
TurnEntity c\pivot,-c\vel#*(180/Pi)/c\size#,0,0
EntityParent c\sphere,0
c\ax#=0
c\ay#=0
c\az#=0
Next
End Function
Function ballcontrol()
For c.ball=Each ball
If KeyDown(200)
TFormVector 0,0,0.03,c\e,0
c\ax#=TFormedX()
c\ay#=TFormedY()
c\az#=TFormedZ()
EndIf
If KeyDown(208)
c\vx=c\vx*0.94
c\vy=c\vy*0.94
c\vz=c\vz*0.94
EndIf
If KeyDown(57)
TFormVector 0,0.05,0,c\e,0
c\ax#=c\ax+TFormedX()
c\ay#=c\ay+TFormedY()
c\az#=c\az+TFormedZ()
EndIf
If KeyDown(203)
TurnEntity c\e,0,2,0
EndIf
If KeyDown(205)
TurnEntity c\e,0,-2,0
EndIf
Next
End Function
Function ballcamera(camera,b.ball,camx#,camy#,camz#,aimx#=0,aimy#=0,aimz#=0,smoothcam#=0.1,roll#=0)
TFormPoint camx#,camy#,camz#,b\e,0
dx#=(TFormedX()-EntityX(camera))*smoothcam#
dy#=(TFormedY()-EntityY(camera))*smoothcam#
dz#=(TFormedZ()-EntityZ(camera))*smoothcam#
TranslateEntity camera,dx,dy,dz
TFormPoint aimx#,aimy#,aimz#,b\e,0
dx# = EntityX(camera)-TFormedX()
dy# = EntityY(camera)-TFormedY()
dz# = EntityZ(camera)-TFormedZ()
dist#=Sqr#((dx#*dx#)+(dz#*dz#))
pitch#=ATan2(dy#,dist#)
yaw#=ATan2(dx#,-dz#)
RotateEntity camera,pitch#,yaw#,roll#
End Function |