A question about sswifts ball physics code.

Blitz3D Forums/Blitz3D Programming/A question about sswifts ball physics code.

D_Town_Tony(Posted 2003) [#1]
I've been looking at the code and it is obviously very helpful when it comes to learning ball physics, I have also looked at hw others have used it. One question is that how do you aim the ball at something as in a pool game of miniature golf. I'm having a lot of trouble getting the ball to move in a desired direction, any help is greatly appreciated.


sswift(Posted 2003) [#2]
Well you know how the velocity is stored each frame in values like vx, vy, vz?

Well to shoot it in a specified direction you need to figure out the normal of the direction and the magnitude of the force which you want to apply.

To make things simple for you, you can use a pivot.

First, make a pivot.

Next, point the pivot in the direction which you want to apply a force to the ball.

Then do this:

TFormVector 0, 0, Speed#, Pivot, 0
Vx# = Vx# + TformedX#()
Vy# = Vy# + TformedY#()
Vz# = Vz# + TformedZ#()

And that's it. Speed# is for example, 10, if you want to add 10 blitz units per second of speed to your ball. In other words, it would move 10 in the world every second.

I use a scale of 1 unit in the world = 1 meter in my games, so I can say that that is 10 meters per second, which is a lot easier to say and conceptulize. :-)


Anyhow, your ball will then be moving at 10 meters per second minus whatever it was moving in any other direction at the time.


D_Town_Tony(Posted 2003) [#3]
you are the god of blitz. I appreciate the help, thanks


D_Town_Tony(Posted 2003) [#4]
sswift- it works except if I put the speed above 100 it doesn't work, and it seems that the max speed is 50 anything above or below is less. Here is my code as it is any idea whats wrong.
[CODE]
Graphics3D 640,480
SetBuffer BackBuffer()

; world vars
Global cam,ball,world,BallRadius#=2,vector_piv,aim,speed#

Const GRAVITY# = .98
Const AIR_FRICTION_CONSTANT# = 0.01
Const GROUND_FRICTION_CONSTANT# =.05

; SETUP COLLISIONS
Const Type_Ball=1,Type_World=2
Collisions Type_Ball,Type_World,2,2

Type ball
Field entity
Field vx#,vy#,vz#
Field oldx#,oldz#,newx#,newz#
End Type

initialize_world()

While Not KeyHit(1)
update_ball()

If KeyHit(5) Then fire_cannon()

UpdateWorld
RenderWorld
getposition()
Flip
Wend
End

Function initialize_world()
AmbientLight 200,225,200

lite=CreateLight()

cam=CreateCamera() ; create a world camera
PositionEntity cam,50,600,-75
MoveEntity cam,0,0,0
CameraClsColor cam,175,225,255

b.ball= New ball
b\entity =CreateSphere(12)
ScaleMesh b\entity,2,2,2
PositionEntity b\entity,5,10,-50
EntityRadius b\entity,3
EntityType b\entity,Type_Ball

aim=CreateCube()
ScaleMesh aim,.25,.25,8
PositionEntity aim,EntityX(b\entity),EntityY(b\entity),EntityZ(b\entity)

vector_piv=CreatePivot()

world=LoadMesh("test.3ds")
ScaleEntity world,.5,.5,.5
EntityType world,Type_World

PointEntity cam,world
End Function

Function update_ball()
For b.ball=Each ball
PositionEntity aim,EntityX(b\entity),EntityY(b\entity),EntityZ(b\entity)
If KeyDown(203) TurnEntity aim,0,1,0
If KeyDown(205) TurnEntity aim,0,-1,0
RotateEntity vector_piv,EntityPitch(aim),EntityYaw(aim),EntityRoll(aim)
If KeyDown(200) speed#=speed#+.5
If KeyDown(208) speed#=speed#-.5

Entity_Hit=EntityCollided(b\entity,Type_World)
;calculate velocity
Velocity# = Sqr(b\Vx#^2 + b\Vy#^2 + b\Vz#^2)
If Velocity# > 0
;Calc dir vector
Direction_X# = b\Vx# / Velocity#
Direction_Y# = b\Vy# / Velocity#
Direction_Z# = b\Vz# / Velocity#
;Air friction
Air_Friction_Force# = AIR_FRICTION_CONSTANT# * Velocity#^2.0
Velocity# = Velocity# - (Air_Friction_Force#)

;ground friction
If entity_hit>0
Velocity# = Velocity# - (GROUND_FRICTION_CONSTANT#)
EndIf
;velocity always > 0
If(Velocity#<0) Then Velocity#=0
; Convert the entity's velocity and direction back into a motion vector.
b\Vx# = Direction_X# * Velocity#
b\Vy# = Direction_Y# * Velocity#
b\Vz# = Direction_Z# * Velocity#
; If the entity collided with the level, make it bounce.
If Entity_Hit > 0
; Calculate bounce:
; Get the normal of the surface which the entity collided with.
Nx# = CollisionNX(b\entity, 1)
Ny# = CollisionNY(b\entity, 1)
Nz# = CollisionNZ(b\entity, 1)
; Compute the dot product of the entity's motion vector and the normal of the surface collided with.
VdotN# = b\Vx#*Nx# + b\Vy#*Ny# + b\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.
b\Vx# = b\Vx# + NFx#
b\Vy# = b\Vy# + NFy#
b\Vz# = b\Vz# + NFz#
; Do not allow the entity to move vertically.
If Vy# > 0 Then Vy# = 0
EndIf
EndIf

;Apply dir thrust
b\Vx# = b\Vx# + (Thrust_X#)
b\Vz# = b\Vz# + (Thrust_Z#)
; Apply gravity:
b\Vy# = b\Vy# - (GRAVITY#)

; Move and rotate the entity:
; We rotate the entity by the actual distance moved and not by the velocity because if we rotate according
; to the velocity then the entity will roll when it's up against a wall and not moving.
b\OldX# = b\NewX#
b\OldZ# = b\NewZ#
TranslateEntity b\entity, b\Vx#, b\Vy#, b\Vz#, True
b\NewX# = EntityX#(b\entity, True)
b\NewZ# = EntityZ#(b\entity, True)
Mx# = (b\NewX# - b\OldX#)
Mz# = (b\NewZ# - b\OldZ#)

; 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 diffrence.
XAngleAdjust# = (Mx# / BallRadius#) * (180.0/Pi)
ZAngleAdjust# = (Mz# / BallRadius#) * (180.0/Pi)
TurnEntity b\entity,ZAngleAdjust#,0,-XAngleAdjust#,True
Next
End Function
;=====================================================================================

Function fire_cannon()
For b.ball = Each ball
TFormVector 0,0,speed#,vector_piv,0
b\vx#=b\vx#+TFormedX#();/8
b\vy#=b\vy#+TFormedY#();/8
b\vz#=b\vz#+TFormedZ#();/8
Next



End Function
;=====================================================================================

[/CODE]


sswift(Posted 2003) [#5]
I think you need to reduce the air friction constant to increase the maximum possible speed. Air friction is expoential. The faster you go, the more air friction you have and there is a certain speed you can't go above with X amount of thrust.

Are you saying that if you put the speed above 200 then your object actually moves at less than 50?