Collision and large world.

Blitz3D Forums/Blitz3D Programming/Collision and large world.

Extron(Posted 2003) [#1]
Hi!

I have some problems whith the collisions and the entity position. (great distance)
If my entity is below 2000 units compared to the origin of the world, i don't have any problem. But if it is beyond this distance sometimes the collisions miss.
This error appears only on the triangles of the meshs which do not have one of their vector components equal to 1.
In other words not parralel or perpendicular to the plan X, Y or Z.

Here i post a code to demonstrate this strange thing and some explanation after this one.

; INFOS GENERALES (GENERAL INFO)
; Marche (Walk) = 1.38889 m/s (5Km/h) / Course (Run) = 9.72222 m/s (35Km/h)
;
; CONSTANTES TOUCHES DU CLAVIER (KEY CONSTANT)
Const Gauche=203
Const Droite=205
Const Avance=200
Const Recul=208
;  CONSTANTES COLLISIONS (COLLISION CONSTANT)
Const Camera_Col=1
Const Static_Col=2
; VARIABLES GLOBALES (GLOBAL VAR)
Global cammonde
Global sw=640 , sh=480 , depth=32
; WIREFRAME ON/OFF
wir = 1
; CHOIX DE LA RESOLUTION (RESOLUTION CHOICE)
result=InitDisplay()
If result=0 Then End
;
; INITIALISATION MODE GRAPHIQUE (INIT GRAPHIC MODE)
Graphics3D sw,sh,depth,1
SetBuffer BackBuffer()
;
;*****************************************************************
; INITIALISATION DU MONDE (INIT WORLD)
;*****************************************************************
;
; INIT LUMIERE AMBIENTE (AMBIENT LIGHT)
AmbientLight 255,255,255
; INIT CAMERA DU MONDE ET SON PIVOT (INIT CAMERA AND PIVOT)
Global root_camera=CreatePivot()
EntityType root_camera,Camera_Col
PositionEntity root_camera,0,50,0
Global pivot_cammonde=CreatePivot(root_camera)
PositionEntity pivot_cammonde,0,64,0
cammonde=CreateCamera(pivot_cammonde)
PositionEntity cammonde,0,0,-200
CameraRange cammonde,1,16384
CameraViewport cammonde,0,0,sw,sh

Sph=CreateSphere(20,root_camera)
;
; INITIALISATION POINTEUR SOURIS (INIT MOUSE POINTER)
MoveMouse sw/2,sh/2 : mxs#=sw/2 : mys#=sh/2 : HidePointer
;
; INITIALISATION VITESSE DU JOUEUR (marche) (INIT PLAYER SPEED : WALK)
MultVitesseJoueur#=1.38889
; INITIALISATION GESTION TEMPS/FRAMERATE (INITIALIZATION TIME/FRAMERATE) 
TempsActuel#=MilliSecs()
;
sol=CreatePlane()
PositionEntity sol,0,0,0
EntityColor sol,100,0,0

Dim objet(4)
For t=0 To 3
	objet(t)=CreateCone(32,1)
	ScaleEntity objet(t),1000,2000,1000
	EntityColor objet(t),0,100,100
	EntityType objet(t),Static_Col
Next

PositionEntity objet(0),-2000,2000,2000
PositionEntity objet(1),2000,2000,2000
PositionEntity objet(2),-2000,2000,-2000
PositionEntity objet(3),2000,2000,-2000

;PositionEntity objet(0),-4000,2000,4000
;PositionEntity objet(1),4000,2000,4000
;PositionEntity objet(2),-4000,2000,-4000
;PositionEntity objet(3),4000,2000,-4000

Collisions Camera_Col,Static_Col,2,2
;*****************************************************************
; DANS LE MONDE VIRTUEL (IN THE WORLD)
;*****************************************************************
;
While Not KeyDown(1)

TempsPasser#=MilliSecs()-TempsActuel#
TempsActuel#=MilliSecs()

mxs#=-(Float(MouseX())-Float(sw/2))/15
TurnEntity root_camera,0,mxs#,0
mys#=-(Float(MouseY())-Float(sh/2))/15
If EntityPitch#(cammonde,1)+mys#>=90 Then mys#=0
If EntityPitch#(cammonde,1)+mys#<=-90 Then mys#=0
TurnEntity cammonde,mys#,0,0
MoveMouse sw/2,sh/2

VitesseJoueurX#=0 : VitesseJoueurY#=0 : VitesseJoueurZ#=0
If KeyHit(31) Then			;S enclenché
	If MultVitesseJoueur#=1.38889 Then
		MultVitesseJoueur#=9.72222
	Else
		MultVitesseJoueur#=1.38889
	EndIf
EndIf
; AVANCE
If KeyDown(Avance) Then
	VitesseJoueurZ#=(MultVitesseJoueur#*0.1)*TempsPasser#
EndIf
; RECUL
If KeyDown(Recul) Then
	VitesseJoueurZ#=(-MultVitesseJoueur#*0.1)*TempsPasser#
EndIf
; DROITE
If KeyDown(Droite) Then
		VitesseJoueurX#=(MultVitesseJoueur#*0.1)*TempsPasser#
EndIf
; GAUCHE
If KeyDown(Gauche) Then
	VitesseJoueurX#=(-MultVitesseJoueur#*0.1)*TempsPasser#
EndIf
;
MoveEntity root_camera,VitesseJoueurX#,0,VitesseJoueurZ#
PositionEntity root_camera,EntityX(root_camera),50,EntityZ(root_camera)
;
; WIREFRAME ON/OFF
If KeyHit(44) Then
	wir=-wir
	If wir=-1 Then
		WireFrame 0
	Else
		WireFrame 1
	EndIf
EndIf
;
UpdateWorld
If EntityCollided(root_camera,Static_Col) Then
	mmmx#=CollisionNX(root_camera,1)
	mmmy#=CollisionNY(root_camera,1)
	mmmz#=CollisionNZ(root_camera,1)
EndIf
RenderWorld

Color 255,255,255
;Framecounter--------------------------------------------
Framecounter_counter=Framecounter_counter+1
If Framecounter_time=0 Then Framecounter_time=MilliSecs()
If Framecounter_time+1001 <MilliSecs() Then
Framecounter_framerate=Framecounter_counter
Framecounter_counter=0
Framecounter_time=MilliSecs()
EndIf
Text sw-90,sh-40,"FPS: "+Framecounter_framerate
;--------------------------------------------------------
;
Text 10,22,"X :"+EntityX(root_camera)
Text 10,34,"Y :"+EntityY(root_camera)
Text 10,46,"Z :"+EntityZ(root_camera)
Text 10,70,"CollisionNX :"+mmmx#
Text 10,82,"CollisionNY :"+mmmy#
Text 10,94,"CollisionNZ :"+mmmz#

Flip 0
Wend
ClearWorld
End
;
;*****************************************************************
;*****************************************************************
;
Function InitDisplay()
	l=640 : h=480
	Graphics3D l,h,32,2
	font=LoadFont("Arial",30)
	SetFont font
	SetBuffer BackBuffer()

	Text (l/2)-100,(h/2)-90,"   RESOLUTION",0,1

	Text (l/2)-100,(h/2)-60,"1 - 640 x 480 x 32",0,1
	Text (l/2)-100,(h/2)-30,"2 - 800 x 600 x 32",0,1
	Text (l/2)-100,(h/2),   "3 - 1024 x 768 x 32",0,1
	Text (l/2)-100,(h/2)+30,"4 - 1280 x 1024 x 32",0,1
	Flip 0
	While Not KeyDown(1)
	If KeyHit(79) Or KeyHit(2) Then
		sw=640 : sh=480 : depth=32
		FreeFont font
		Return 1 
	EndIf
	If KeyHit(80) Or KeyHit(3) Then
		sw=800 : sh=600 : depth=32
		FreeFont font
		Return 1
	EndIf
	If KeyHit(81) Or KeyHit(4) Then
		sw=1024 : sh=768 : depth=32
		FreeFont font
		Return 1
	EndIf
	If KeyHit(75) Or KeyHit(5) Then
		sw=1280 : sh=1024 : depth=32
		FreeFont font
		Return 1
	EndIf
	Wend
	FreeFont font
	Return 0
End Function
;
;*****************************************************************
;*****************************************************************


I'll explain some things.
I placed four cones at a certain distance of the origin.
Leave the values of 2000/-2000 and test, you will never pass through meshes.
Comment this line and uncomment the line whith the values of 4000/-4000 and if you insist, you will pass through the meshes.
Larger the distance compared to the origin of the world, more the collisions miss.

Now you can test whith cube.
Replace this code :
For t=0 To 3
	objet(t)=CreateCone(32,1)
	ScaleEntity objet(t),1000,2000,1000
	EntityColor objet(t),0,100,100
	EntityType objet(t),Static_Col
Next

by this one
For t=0 To 3
	objet(t)=CreateCube()
	ScaleEntity objet(t),1000,2000,1000
	EntityColor objet(t),0,100,100
	EntityType objet(t),Static_Col
Next


No collision error will occur and this at any distance.
All the faces of the cubes have one of their vector component equal to 1.

Now add this code in the loop after the cube creation :
RotateEntity objet(t),0,45,0

Errors of collision occur according to the distance from the objects to the origin of the world.

I don't see why! Precision error, i don't know.

I have develloped a large world, in fact it can be infinite, but with these stranges errors I cannot count on these tests of collisions.
This leaves me annoyed.
Would somebody have some information on this subject or it would have encountered this problem and find a solution of replacement?

Do not pay attention to the code, it's just for the example. :)
Thank for the future advice!


Ross C(Posted 2003) [#2]
I'm sorry, but i cannot reproduce your error :S


Extron(Posted 2003) [#3]
Hummm.... bizarre.
Have you try great distance, 8000 or more?

Can you replace "PositionEntity root_camera,0,50,0" by "PositionEntity root_camera,-18000,50,18000" and set distance of the cones to -20000/20000.
At this distance the error has more effect.


Ross C(Posted 2003) [#4]
One thing i can think of trying, is to reduce the camera range. This might be causing the world to be inaccurate.


Extron(Posted 2003) [#5]
I tried this and no change.
In another configuration, P4 1.7 386Mo RDRAM and Gforce4 TI4600, i have the same problem. The only identical specifications are WinXP Pro and Directx 9.0b on the 2 computers.
But what I don't understand, is why at a distance of 2000 I do not have any error of collision.

I suspect DX9.0b but i'm not sure.