Hi, can someone who knows about vector math tell me what I'm doing wrong here.
I've made up a physics demo, using some of Sswift's physics code, which has 100 balls bouncing around inside a cube with gravity applied.
It looks fairly realistic, for the most part, however there seems to be a problem with energy loss when the balls bounce off each other. They go from flying around so fast that they're barely visible, to lying on the floor of the cube barely moving, within a few minutes.
This is with a maximum elasticity value of 1.0. The problem was also present before I factored elasticity into the code. This only shows up if the balls are enabled to bounce off each other. If they're only bouncing off the walls then there's no apparent energy loss. My physics code is below.
Also, how would I go about, mathematically applying thrust to a physics object parellel to the plane of the surface it's standing on, so that it can be properly 'pushed' along an inclined surface (for a game character walking up and down ramps and hills, for example). {edit}I think multiplying the x, y, z, velocity vectors by the respective collision normals to align them to the space of the collision plane, applying the thrust to the x and y vextors, as required, and then multplying the three vectors by the normals calculated from the original velocity vectors to convert them back to global space, would work. I'll have to try it out.{/edit}
--- Physics code
; Note: Delta time has already been applied to the gravity# variable at the start of the main loop.
Function apply_basic_physics( the_entity_data.ENTITY_STRUCT )
the_entity = the_entity_data\entity_handle
vx# = the_entity_data\physics_data\vx#
vy# = the_entity_data\physics_data\vy#
vz# = the_entity_data\physics_data\vz#
;the_mass# = the_entity_data\physics_data\mass#
the_elasticity# = the_entity_data\physics_data\elasticity#
;the_friction# = the_entity_data\physics_data\friction#
For the_collision_index = 1 To CountCollisions ( the_entity )
the_entity_collided_with = CollisionEntity ( the_entity, the_collision_index )
the_target_entitiy_type = GetEntityType ( the_entity_collided_with )
; Get the data structure of the target collision object.
the_target_entity_data.ENTITY_STRUCT = Object.ENTITY_STRUCT( EntityName$ ( the_entity_collided_with ) )
; Get the collision normals.
coll_nx# = CollisionNX# ( the_entity, the_collision_index )
coll_ny# = CollisionNY# ( the_entity, the_collision_index )
coll_nz# = CollisionNZ# ( the_entity, the_collision_index )
; Compute the dot product of the avatars's motion vector and the normal of the surface collided with.
VdotN# = vx# * coll_nx# + vy# * coll_ny# + vz# * coll_nz#
; Check if the target collision object has physics properties.
If the_target_entity_data\physics_data <> Null
; Calculate the normal force to be applied to the source and target objects.
NFx# = -the_elasticity# * coll_nx# * VdotN#
NFy# = -the_elasticity# * coll_ny# * VdotN#
NFz# = -the_elasticity# * coll_nz# * VdotN#
; Apply the positive normal force to the motion vector of the source object.
vx# = vx# + NFx#
vy# = vy# + NFy#
vz# = vz# + NFz#
; Apply the negative normal force to the motion vector of the target object.
the_target_entity_data\physics_data\vx# = the_target_entity_data\physics_data\vx# - NFx#
the_target_entity_data\physics_data\vy# = the_target_entity_data\physics_data\vy# - NFy#
the_target_entity_data\physics_data\vz# = the_target_entity_data\physics_data\vz# - NFz#
Else
; Calculate and add the normal force to the motion vector of the source object.
vx# = vx# + ( -( 1.0 + the_elasticity# ) * coll_nx# * VdotN# )
vy# = vy# + ( -( 1.0 + the_elasticity# ) * coll_ny# * VdotN# )
vz# = vz# + ( -( 1.0 + the_elasticity# ) * coll_nz# * VdotN# )
EndIf
Next
vy# = vy# + gravity#
PositionEntity the_entity, EntityX# ( the_entity ) + ( vx# * Delta_Time# ), EntityY# ( the_entity ) + ( vy# * Delta_Time# ), EntityZ# ( the_entity ) + ( vz# * Delta_Time# )
the_entity_data\physics_data\vx# = vx#
the_entity_data\physics_data\vy# = vy#
the_entity_data\physics_data\vz# = vz#
DBG_total_energy# = DBG_total_energy# + Sqr# ( vx# * vx# + vy# * vy# + vz# * vz# ) ; DEBUG CODE :: Calculate the ball's energy.
End Function
I've made up a physics demo, using some of Sswift's physics code, which has 100 balls bouncing around inside a cube with gravity applied.
It looks fairly realistic, for the most part, however there seems to be a problem with energy loss when the balls bounce off each other. They go from flying around so fast that they're barely visible, to lying on the floor of the cube barely moving, within a few minutes.
This is with a maximum elasticity value of 1.0. The problem was also present before I factored elasticity into the code. This only shows up if the balls are enabled to bounce off each other. If they're only bouncing off the walls then there's no apparent energy loss. My physics code is below.
Also, how would I go about, mathematically applying thrust to a physics object parellel to the plane of the surface it's standing on, so that it can be properly 'pushed' along an inclined surface (for a game character walking up and down ramps and hills, for example). {edit}I think multiplying the x, y, z, velocity vectors by the respective collision normals to align them to the space of the collision plane, applying the thrust to the x and y vextors, as required, and then multplying the three vectors by the normals calculated from the original velocity vectors to convert them back to global space, would work. I'll have to try it out.{/edit}
--- Physics code
; Note: Delta time has already been applied to the gravity# variable at the start of the main loop.
Function apply_basic_physics( the_entity_data.ENTITY_STRUCT )
the_entity = the_entity_data\entity_handle
vx# = the_entity_data\physics_data\vx#
vy# = the_entity_data\physics_data\vy#
vz# = the_entity_data\physics_data\vz#
;the_mass# = the_entity_data\physics_data\mass#
the_elasticity# = the_entity_data\physics_data\elasticity#
;the_friction# = the_entity_data\physics_data\friction#
For the_collision_index = 1 To CountCollisions ( the_entity )
the_entity_collided_with = CollisionEntity ( the_entity, the_collision_index )
the_target_entitiy_type = GetEntityType ( the_entity_collided_with )
; Get the data structure of the target collision object.
the_target_entity_data.ENTITY_STRUCT = Object.ENTITY_STRUCT( EntityName$ ( the_entity_collided_with ) )
; Get the collision normals.
coll_nx# = CollisionNX# ( the_entity, the_collision_index )
coll_ny# = CollisionNY# ( the_entity, the_collision_index )
coll_nz# = CollisionNZ# ( the_entity, the_collision_index )
; Compute the dot product of the avatars's motion vector and the normal of the surface collided with.
VdotN# = vx# * coll_nx# + vy# * coll_ny# + vz# * coll_nz#
; Check if the target collision object has physics properties.
If the_target_entity_data\physics_data <> Null
; Calculate the normal force to be applied to the source and target objects.
NFx# = -the_elasticity# * coll_nx# * VdotN#
NFy# = -the_elasticity# * coll_ny# * VdotN#
NFz# = -the_elasticity# * coll_nz# * VdotN#
; Apply the positive normal force to the motion vector of the source object.
vx# = vx# + NFx#
vy# = vy# + NFy#
vz# = vz# + NFz#
; Apply the negative normal force to the motion vector of the target object.
the_target_entity_data\physics_data\vx# = the_target_entity_data\physics_data\vx# - NFx#
the_target_entity_data\physics_data\vy# = the_target_entity_data\physics_data\vy# - NFy#
the_target_entity_data\physics_data\vz# = the_target_entity_data\physics_data\vz# - NFz#
Else
; Calculate and add the normal force to the motion vector of the source object.
vx# = vx# + ( -( 1.0 + the_elasticity# ) * coll_nx# * VdotN# )
vy# = vy# + ( -( 1.0 + the_elasticity# ) * coll_ny# * VdotN# )
vz# = vz# + ( -( 1.0 + the_elasticity# ) * coll_nz# * VdotN# )
EndIf
Next
vy# = vy# + gravity#
PositionEntity the_entity, EntityX# ( the_entity ) + ( vx# * Delta_Time# ), EntityY# ( the_entity ) + ( vy# * Delta_Time# ), EntityZ# ( the_entity ) + ( vz# * Delta_Time# )
the_entity_data\physics_data\vx# = vx#
the_entity_data\physics_data\vy# = vy#
the_entity_data\physics_data\vz# = vz#
DBG_total_energy# = DBG_total_energy# + Sqr# ( vx# * vx# + vy# * vy# + vz# * vz# ) ; DEBUG CODE :: Calculate the ball's energy.
End Function