Collisions get sticky at certain angles.

Blitz3D Forums/Blitz3D Programming/Collisions get sticky at certain angles.

callahan614(Posted 2005) [#1]
//----- EDIT -----//
I didn't allow the bounce to occur because the condition was 'if the dot product does not equal zero', which should have been 'if the dot product is greater than zero'. I still have an issue, though - using mouselook from a third person perspective to control the orientation of the character without the mere rotation setting off the bounce function. What would be the condition for that? CollisionNY? If so, what value? Thanks.
//--- END EDIT ----//


Hey all,
I've been working on a prototype of a 3D platformer in which the only form of locomotion is a mouselook/click/drag/release combo. It's sort of a Crash Bandicoot/Spyro meets Pinball with Megaman abilities. In any case, the main character is a little blob who lives in a petri dish. The level design is incredibly organic. My level designer created single-sided walls, all normals face in as they should. One particular obstacle, though, causes my character to get stuck upon colliding with it. This may be due to over-zealous collision detection on my part. (Note: Blitz3D's sliding collisions are out, as the curves of the level cause infinite sliding) Why would this obstacle (a poly model that is part of the same mesh as the entire level) cause sticking? Here is the code for the bounce function:

;---------------------------------------------
Function SZ_bounce.VECTOR(player.VECTOR,Index)

norm\Vx# = CollisionNX(player\root,Index)
norm\Vy# = CollisionNY(player\root,Index)
norm\Vz# = CollisionNZ(player\root,Index)

norm = normalize(norm)
player = normalize(player)
two_ndoti = 2 * (norm\Vx# * player\Vx# + norm\Vy# * player\Vy# +norm\Vz# * player\Vz#)
player\Vx# = two_ndoti * norm\Vx# - player\Vx#;
player\Vy# = two_ndoti * norm\Vy# - player\Vy#;
player\Vz# = two_ndoti * norm\Vz# - player\Vz#;
player\Vx# = (player\Magnitude# - (player\Magnitude# * .1)) * (player\Vx#)
player\Vy# = (player\Magnitude# - (player\Magnitude# * .1)) * (player\Vy#)
player\Vz# = (player\Magnitude# - (player\Magnitude# * .1)) * (player\Vz#)

Return player.VECTOR

End Function
;---------------------------------------------

This is used within a For...Next based on the value of CountCollisions for that frame. Let me know what code would be most helpful in figuring this out. It really ties into a larger issue: diminishing secondary bounces without causing an NaN, giving a realistic effect of landing. I can also make an executable available if you want to get a feel for the mechanics. Thanks in advance, guys.

P.S. - I'd be really honored if sswift made an appearance.


Stevie G(Posted 2005) [#2]
Assume your using stop collisions? To avoid sticking you need to slightly offset the collided entity by the collision normals within our bounce routine ...

e.g. Translateentity Entity , .01 * norm\vx , .01*norm\vy, .01*norm\vz

Also, to determine whether the object has hit the ground rather than a wall then you should set a flag if norm\vy > 0.

I'm not entirely sure whether your reflection code is implemented correctly so I think more code would help.

Stevie

I use this ... where Vx, Vy etc.. are the velocities.

For i = 1 To CountCollisions( p\Pivot )
	Nx# = CollisionNX( p\Pivot , i )
	Ny# = CollisionNY( p\Pivot , i )
	Nz# = CollisionNZ( p\Pivot , i )
	TranslateEntity p\Pivot , Nx*.01, Ny*.01 , Nz*.01
	VdotN# = Vx * Nx + Vy * Ny + Vz * Nz
	NFx# = -2.0 * Nx * VdotN
	NFy# = -2.0 * Ny * VdotN
	NFz# = -2.0 * Nz * VdotN
	Vx = Vx + Nfx
	Vy = Vy + Nfy
                Vz = Vz + Nfz
	If Ny > 0 p\OnGround = 1
Next
TranslateEntity p\Pivot , Vx , Vy , Vz