Paramètres Collision ThirdPerson.pb

Généralités sur la programmation 3D
Avatar de l’utilisateur
Cool Dji
Messages : 1126
Inscription : ven. 05/sept./2008 11:42
Localisation : Besançon
Contact :

Paramètres Collision ThirdPerson.pb

Message par Cool Dji »

Hello,

En travaillant sur les collisions 3d d'après divers exemples, il me semble que la source ThirdPerson.pb du repertoire de Demo3d soit la plus précieuse.
Cependant, quelques paramètres sont encore obscurs pour moi.
Il me semble avoir compris que l'enveloppe de l'entity servant aux collisions (ici capsulebody) soit plus grande que le bound de l'entity lui-même (26 unités dans cet exemple avec le robot).

Code : Tout sélectionner

;Robot Body
    CreateEntity(1, MeshID(0), #PB_Material_None, 0, 26, 0)
    HideEntity(1, 1)

Ainsi, une entity invisible est positionnée plus haute que l'entity visible et les collisions se font sur l'entity invisible.
Dans la source, on trouve un "BodyOffsetY" paramétré ici à 43 et il sert à positionner l'entity visible à 43 unités sous l'entity invisible servant aux collisions

Code : Tout sélectionner

With Robot
      \Entity = 0
      \EntityBody = 1
      \BodyOffsetY = 43

Cette valeur 43 est propre à chaque entity.
Si je remplace le mesh du robot par un autre mesh, les collisions ne fonctionnent plus
idem si, en gardant le mesh du robot, on change la valeur de 43 ou si on remplace le capsulebody par un boxbody

Pour conclure, est-ce que quelqu'un sait comment sont calculés les valeurs 26 et 43 par rapport au mesh, à l'entity, au type de Body pour l'EntityPhysicBody ?

Merci d'avance
Only PureBasic makes it possible
comtois
Messages : 5172
Inscription : mer. 21/janv./2004 17:48
Contact :

Re: Paramètres Collision ThirdPerson.pb

Message par comtois »

En tant qu'auteur de cet exemple, je peux te répondre.

De mémoire j'avais utilisé ces valeurs par tâtonnement. Ou alors j'avais exploré le source xml du mesh pour déterminer la taille de l'entity (en relevant la valeur en y de chaque vertex) ?
J'avoue que je ne sais plus, j'utilise les deux méthodes selon mon humeur :)

Les repères du body et du mesh étant différents, j'ai dû utiliser 2 entités.
La première pour créer un body et la seconde pour l'afficher à l'écran. Si tu as un mesh avec un repère centré c'est inutile, une seule entity, ton body sera centré.

Le repère du robot se trouve à ses pieds, donc y=0 quand les pieds touchent le sol (il est construit ainsi).
Le repère de tous les types de body est centré, donc avec y=0, le body est coupé en deux par le sol.

Voila donc tu as besoin de connaitre le repère de ton mesh, s'il est centré, ton body sera centré aussi, sinon il faut faire un décalage et dans ce cas prendre 2 entités comme dans l'exemple.

[EDIT]
La valeur 26 n'est pas importante, elle peut être plus grande, c'était juste pour être au dessus du sol , avec la gravité, le body va toucher le sol, ce qui compte c'est l'offset pour replacer l'entity visible.
Dernière modification par comtois le mar. 03/janv./2012 20:50, modifié 1 fois.
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Avatar de l’utilisateur
Cool Dji
Messages : 1126
Inscription : ven. 05/sept./2008 11:42
Localisation : Besançon
Contact :

Re: Paramètres Collision ThirdPerson.pb

Message par Cool Dji »

Merci Comtois,

Je n'avais pas pensé au repère centré des mesh... je pense toujours (et j'ai donc souvent faux) que la base x,y,z du mesh se trouve en bas à gauche.
Cependant, ce n'était pas uniquement ça. il y a aussi la fonction onGround qui joue un rôle. Je m'étais uniquement focalisé sur le 43 et 26 en cherchant désespérément à comprendre en pensant que la clé était là. Je regarde de plus près pour mieux comprendre...
Only PureBasic makes it possible
comtois
Messages : 5172
Inscription : mer. 21/janv./2004 17:48
Contact :

Re: Paramètres Collision ThirdPerson.pb

Message par comtois »

l y a aussi la fonction onGround qui joue un rôle
A l'origine l'exemple fonctionnait sans cette fonction. Je l'ai ajouté parce que le robot broutait un peu sur le sol (à chaque intersection de triangles) , du fait que je maintenais en permanence la gravité.
Avec cette fonction je lance un rayon au pied du robot pour détecter la présence d'un obstacle, et mettre à zéro la gravité.

C'est aussi pratique pour un terrain en pente (voir l'exemple FPS FirstPerson) , en coupant la gravité on peut rester en place sur une pente. Dans l'exemple FPS FirstPerson il y a aussi des pentes sur lesquelles on glisse, pour ne plus glisser il suffit de lancer un rayon plus long pour détecter plus tôt la présence d'un obstacle.

Ce qu'il manque c'est les coordonnées du point d'intersection, ça permettrait de calculer la pente en lançant 2 rayons ? A voir ...
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Avatar de l’utilisateur
Cool Dji
Messages : 1126
Inscription : ven. 05/sept./2008 11:42
Localisation : Besançon
Contact :

Re: Paramètres Collision ThirdPerson.pb

Message par Cool Dji »

C'est marrant, j'étais sur la source de FPS FirstPerson pendant que tu écrivais ton message !!

Les codes des démos sont peut-être à peine trop complexes (les nodes, les structures) pour être utilisés facilement. Mais bon, on y arrive... et en plus je supporte pas l'include screen3DRequester, c'est toujours compliqué de la virer :mrgreen:

En définitive, la seule fonction qui me manque dans la 4.6 est la possibilité d'accéder aux coordonnées des points et à l'assemblage des triangles du mesh. La connaissance de ces coordonnées permettrait de faire un calcul fin sur les triangles ou de construire une forme englobante simplifiée du mesh.
Cela permettrait de calculer les distances inter-triangles, les angles des pentes et de maitriser les coefficients de frottement en fonction du mesh ou des conditions météo par exemple.
Le fichier xml du mesh devrait me permettre de récupérer toutes les données utiles pour construire un mesh mais c'est dommage de refaire un truc. La fonction loadmesh doit bien stocker quelque part les données du mesh.

En tous les cas, la 4.6 constitue une réelle évolution...
Only PureBasic makes it possible
comtois
Messages : 5172
Inscription : mer. 21/janv./2004 17:48
Contact :

Re: Paramètres Collision ThirdPerson.pb

Message par comtois »

Les codes des démos sont peut-être à peine trop complexes (les nodes, les structures) pour être utilisés facilement.
C'est pour ça que j'ai ajouté un dossier Demos, pour y mettre des codes un peu plus complexe et plus long qu'un exemple qui doit être le plus court possible pour illustrer l'utilisation d'une seule commande si possible.

Pour les nodes vaut mieux t'y habituer, c'est le coeur du moteur, et c'est très pratique, tu n'as pas d'angle à calculer. Dans la première version de tank.pb je calculais tous les angles pour positionner le tir, les rotations, etc. Très très lourd et compliqué inutilement. Avec quelques nodes bien placés, c'est le moteur Ogre qui se charge de calculer les positions nécessaires pour nous.

Et finalement grâce aux nodes on s'aperçoit qu'on a très rarement besoin de connaitre un angle ou d'en calculer un .
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Avatar de l’utilisateur
Cool Dji
Messages : 1126
Inscription : ven. 05/sept./2008 11:42
Localisation : Besançon
Contact :

Re: Paramètres Collision ThirdPerson.pb

Message par Cool Dji »

Ok, merci du conseil. C'est vrai que jusqu'à présent j'ai plutôt évité de travailler avec les nodes...
Je vais commencer par le début :D
Only PureBasic makes it possible
Avatar de l’utilisateur
Cool Dji
Messages : 1126
Inscription : ven. 05/sept./2008 11:42
Localisation : Besançon
Contact :

Re: Paramètres Collision ThirdPerson.pb

Message par Cool Dji »

J'ai enlevé le décor 3D livré avec la démo pour mettre un sol tout simple (Mesh issu de Deled).
Les collisions fonctionnent bien (même si je n'arrive pas à faire fonctionner en remplaçant le mesh du robot par un createcube).

Sinon, j'ai une barre noire en fond de décor
Image

J'ai éclairci le codeFPSthirdpersonn pour y voir plus clair et j'ai toujours cette barre noire en fond d'écran qui se déplace en fonction de la souris.

http://xdji.free.fr/Telechargement/Base3D.zip

Est-ce que vous avez aussi ça ? ça vient peut-être de ma configuration...
Only PureBasic makes it possible
comtois
Messages : 5172
Inscription : mer. 21/janv./2004 17:48
Contact :

Re: Paramètres Collision ThirdPerson.pb

Message par comtois »

ça vient du CameraRange() avec la SkyBox(). Soit tu supprimes la SkyBox() , mais j'imagine que tu veux une SkyBox() dans ce cas, il faut élargir le CameraRange(0, 0.08, 10000)
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
comtois
Messages : 5172
Inscription : mer. 21/janv./2004 17:48
Contact :

Re: Paramètres Collision ThirdPerson.pb

Message par comtois »

exemple avec une sphère , comme l'entité et le body ont leur repère au centre \BodyOffsetY = 0
Et comme la sphère a un rayon de 30 j'ai placé le rayon dans OnGround() entre -29 et -31, histoire d'être à cheval sur la périphérie de la sphère.
Et j'ai pris un body sphérique #PB_Entity_SphereBody.

Code : Tout sélectionner

Global ScreenWidth, ScreenHeight

#PlayerSpeed = 80
#CameraSpeed = 10

Structure Vector3
  x.f
  y.f
  z.f
EndStructure

Structure s_Key
  Up.i
  Down.i
  Left.i
  Right.i
  Jump.i
EndStructure

Structure s_Entity
  EntityBody.i
  BodyOffsetY.f 
  elapsedTime.f
  Fov.f
  Key.s_Key
  MainNode.i  
  CameraNode.i  
  HandNode.i
  ForwardNode.i
  StrafeNode.i
EndStructure

Macro GetNodePosition(Position, Node)
  Position\x = NodeX(Node)  
  Position\y = NodeY(Node)  
  Position\z = NodeZ(Node)  
EndMacro

Macro SubVector3(V, V1, V2)
  V\x = V1\x - V2\x
  V\y = V1\y - V2\y
  V\z = V1\z - V2\z
EndMacro

;-Declare
Declare HandleEntity(*Entity.s_Entity)
Declare OnGround(*Entity.s_Entity)

Define Robot.s_Entity

If InitEngine3D()
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
  ;If Screen3DRequester()
    
ExamineDesktops()
OpenScreen(DesktopWidth(0), DesktopHeight(0), DesktopDepth(0), "char")

    ;- AddArchive
    Add3DArchive("Data/"            , #PB_3DArchive_FileSystem)
    Add3DArchive("Data/Desert.zip", #PB_3DArchive_Zip)
    Parse3DScripts()
    
    ;- Robot Body
    CreateSphere(0,30)
    CreateEntity(0, MeshID(0), #PB_Material_None, 0, 60, 0)
    HideEntity(0, 1)
    
    LoadMesh   (1, "sol.mesh")
    CreateEntity(1, MeshID(1), #PB_Material_None, 0, 0, 0)
       
     ;Body
    EntityPhysicBody(0, #PB_Entity_SphereBody, 0.45, 0, 0) 
    EntityPhysicBody(1, #PB_Entity_StaticBody)
    
    With Robot
      \Fov = 50
      \EntityBody = 0
      \BodyOffsetY = 0
      \Key\Down  = #PB_Key_Down
      \Key\Left  = #PB_Key_Left
      \Key\Right = #PB_Key_Right
      \Key\Up    = #PB_Key_Up
      \Key\Jump  = #PB_Key_Space
    
      \MainNode   = CreateNode(#PB_Any) ; Entity position
      \CameraNode = CreateNode(#PB_Any,  0, 60,  0) ; Camera position
      \ForwardNode= CreateNode(#PB_Any,  0,  0, -1) ; Direction normalized 
      \StrafeNode = CreateNode(#PB_Any, -1,  0,  0) ; Direction normalized
      
      AttachNodeObject(\MainNode  , NodeID(\CameraNode) , #PB_Node_Node)   
      AttachNodeObject(\MainNode  , NodeID(\ForwardNode), #PB_Node_Node)
      AttachNodeObject(\MainNode  , NodeID(\StrafeNode) , #PB_Node_Node)
    EndWith
    
    ;- Camera
    CreateCamera(0, 0, 0, 100, 100)
    CameraBackColor(0, $56778)
    CameraRange(0, 0.08, 10000) 
    AttachNodeObject(Robot\CameraNode, CameraID(0), #PB_Node_Camera)
    CameraLookAt(0, NodeX(Robot\ForwardNode) * 100, NodeY(Robot\CameraNode), NodeZ(Robot\ForwardNode) * 100) 
    
    ;- Skybox
    SkyBox("desert07.jpg")
   
    
    ;- *** Main loop ***
    Repeat
      If Engine3DFrameRate(#PB_Engine3D_Current)
        Robot\elapsedTime = 40/Engine3DFrameRate(#PB_Engine3D_Current)
      EndIf  
 
      HandleEntity(@Robot)
      RenderWorld(60)
      FlipBuffers()
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
  
Else
  MessageRequester("Error", "The 3D Engine can't be initialized",0)
EndIf

End

Procedure OnGround(*Entity.s_Entity)
  ProcedureReturn RayCollide(NodeX(*Entity\MainNode),  NodeY(*Entity\MainNode)-29, NodeZ(*Entity\MainNode), NodeX(*Entity\MainNode), NodeY(*Entity\MainNode)-31,  NodeZ(*Entity\MainNode)) 
EndProcedure

Procedure HandleEntity(*Entity.s_Entity)
  Protected.Vector3 Forward, Strafe, PosMain, PosDir, PosStrafe
  Protected.f Speed, Speed2, SpeedShoot, x, y
  Protected.f MouseX, MouseY
  Static Jump.f, MemJump.i, Rot.Vector3, Trans.Vector3, Clic
  
  
  With *Entity
    GetNodePosition(PosMain, \MainNode)
    GetNodePosition(PosDir, \ForwardNode)
    GetNodePosition(PosStrafe, \StrafeNode)
    SubVector3(Forward, PosDir, PosMain)
    SubVector3(Strafe, PosStrafe, PosMain)
    
    Speed = #PlayerSpeed * \elapsedTime
    Speed2 = Speed / 2
    SpeedShoot = Speed * 9
    
    If ExamineKeyboard()
      
      If KeyboardPushed(\Key\Jump) And OnGround(*Entity)
        Jump = 30
        MemJump = 1
      EndIf 
      
      Rot\x * 0.30
      Rot\y * 0.30
      Rot\z * 0.30
      Trans\x * 0.80
      Trans\y = Jump
      Trans\z * 0.80
      
      If KeyboardPushed(\Key\Up)
        Trans\x = Forward\x * Speed
        Trans\z = Forward\z * Speed
      ElseIf KeyboardPushed(\Key\Down)
        Trans\x = Forward\x * -Speed2
        Trans\z = Forward\z * -Speed2
      EndIf
      
      If KeyboardPushed(\Key\Left)
        Trans\x = Strafe\x * Speed
        Trans\z = Strafe\z * Speed
      ElseIf KeyboardPushed(\Key\Right)
        Trans\x = Strafe\x * -Speed
        Trans\z = Strafe\z * -Speed
      EndIf 
      
      MoveEntity(\EntityBody, Trans\x, Trans\y, Trans\z)
      
      If OnGround(*Entity)
        Jump = 0
      ElseIf MemJump  
        Jump + 30
        If Jump > 60 
          MemJump = 0
        EndIf  
      Else  
        Jump - 4 * \elapsedTime
      EndIf  
    EndIf
    
    
    If ExamineMouse()
      MouseX = -(MouseDeltaX()/200) * \Fov * \elapsedTime
      MouseY = -(MouseDeltaY()/200) * \Fov * \elapsedTime
      Rot\z = 0
      Rot\y + MouseX
      If NodePitch(\CameraNode) < 80 And MouseY > 0
        Rot\x + MouseY
      ElseIf NodePitch(\CameraNode) > -80 And MouseY < 0 
        Rot\x + MouseY
      EndIf  
     
      
      If MouseButton(#PB_MouseButton_Right)
        If \Fov > 20
          \Fov - 2 * \elapsedTime
        EndIf  
      Else
        If \Fov < 50
          \Fov + 2 * \elapsedTime
        EndIf  
      EndIf
      
    EndIf
    
    CameraFOV(0, \Fov)  
       
    RotateEntity(\EntityBody,     0, Rot\y, 0, #PB_Relative)
    RotateNode(\CameraNode  , Rot\x,     0, 0, #PB_Relative)
    
    NodeLocate(\MainNode, EntityX(\EntityBody), EntityY(\EntityBody) - \BodyOffsetY, EntityZ(\EntityBody)) 
    RotateNode(\MainNode, 0, EntityYaw(\EntityBody), 0) 
    
  EndWith   
EndProcedure
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Avatar de l’utilisateur
Cool Dji
Messages : 1126
Inscription : ven. 05/sept./2008 11:42
Localisation : Besançon
Contact :

Re: Paramètres Collision ThirdPerson.pb

Message par Cool Dji »

Yes, merci Comtois pour les param camera et le onground() ; c'était logique, j'aurais du trouver mais le soir, c'est trop hard pour réfléchir.
J'ai tout pour bien avancer, wait and see
Only PureBasic makes it possible
Répondre