I have modified my ball code to feature a wheel instead. Hope you can use it :)
;wheel rolling physics example by Jeppe Nielsen 2003
Const gravity#=-0.04;-0.02 ;gravity constant
Graphics3D 800,600,16,2
Const wheel_col=1
Const world_col=2
Collisions wheel_col,world_col,2,3
;create old amiga texture :-)
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
light=CreateLight(1)
RotateEntity light,30,20,0
obj=CreateCube()
EntityType obj,world_col
PositionEntity obj,0,0,0
ScaleEntity obj,40,40,40
RotateEntity obj,45,0,0
EntityTexture obj,texture
camera=CreateCamera()
CameraClsColor camera,0,0,255
wheel.wheel=wheelnew(0,4,-120,2,0.8)
zoom#=14
Repeat
zoom#=zoom#-MouseZSpeed()
wheelcamera(camera,wheel,0,zoom#,-zoom#,0,5,0)
wheelcontrol()
wheelupdate()
RenderWorld()
Color 255,255,255
Text 10,10,"Arrow keys to control wheel"
Text 10,20,"Space to lift wheel"
Text 10,30,"Scroll on mouse to zoom"
Flip
Until KeyDown(1)
End
Type wheel
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 wheelnew.wheel(x#,y#,z#,size#=1,bounce#=0.9)
c.wheel=New wheel
c\x#=x#
c\y#=y#
c\z#=z#
c\size=size
c\bounce#=bounce#
c\e=CreatePivot();CreateCylinder(64)
c\sphere=CreateCylinder(64) ;CreateSphere(64)
RotateMesh c\sphere,0,0,90
c\pivot=CreatePivot()
EntityType c\e,wheel_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 wheelupdate()
For c.wheel=Each wheel
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.wheel=Each wheel
;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
TFormVector 1,0,0,c\e,0
AlignToVector c\sphere,TFormedX(),TFormedY(),TFormedZ(),1
If EntityCollided(c\e,world_col)
avnx#=0
avny#=0
avnz#=0
count=CountCollisions(c\e)
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)
avnx#=avnx+Nx
avny#=avny+Ny
avnz#=avnz+Nz
; 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#
Next
If count>0
;average collision normals
avnx#=avnx/count
avny#=avny/count
avnz#=avnz/count
;align controlpivot to averaged collision normals
AlignToVector c\e,avnx,avny,avnz,2
;calculate length of motion vector, or total velocity.
l#=Sqr(c\vx*c\vx+c\vy*c\vy+c\vz*c\vz)
;get normalized direction of motion, the vector will have a length of one.
;the +0.00001 is there to aviod NaN (not a number) numbers. This happens
;if the length of the vector is 0.
TFormNormal c\vx,c\vy+0.00001,c\vz,0,0
vx#=TFormedX()
vy#=TFormedY()
vz#=TFormedZ()
;get direction of wheel
TFormNormal 0,0,1,c\e,0
;calculate a dot product, a number between -1 and 1 to determine angle
;calculate angle like this: angle#=Acos(dot#)
dot#=TFormedX()*vx+TFormedY()*vy+TFormedZ()*vz
;correct velocities, by multiplying the controlpivotīs direction with
;the dot product, followed by the original velocity vector length:
c\vx=TFormedX()*dot*l
c\vy=TFormedY()*dot*l
c\vz=TFormedZ()*dot*l
TFormVector -1,0,0,c\sphere,0
AlignToVector c\pivot,TFormedX(),TFormedY(),TFormedZ(),1
EndIf
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
;reset acceleration
c\ax#=0
c\ay#=0
c\az#=0
Next
End Function
Function wheelcontrol()
For c.wheel=Each wheel
If KeyDown(200)
TFormVector 0,0,0.05,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)
c\ay#=c\ay+0.05
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 wheelcamera(camera,b.wheel,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
|