Collision and large world.
Blitz3D Forums/Blitz3D Programming/Collision and large world.
| ||
| 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! |
| ||
| I'm sorry, but i cannot reproduce your error :S |
| ||
| 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. |
| ||
| One thing i can think of trying, is to reduce the camera range. This might be causing the world to be inaccurate. |
| ||
| 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. |