Gravitation d'un personnage sur une mesh.

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
guerrier001
Messages : 130
Inscription : dim. 11/janv./2009 15:04

Gravitation d'un personnage sur une mesh.

Message par guerrier001 »

Salut tout le monde, j'ai encore un problème qui est a moitié régler. Mon personnage gravite sur une mapheight(terrain vu de haut) et moi je voudrait qu'il gravite sur une mesh. Aidez moi, merci. Voila le code:

Code : Tout sélectionner

;-Include Files
IncludePath "Include\"  :   IncludeFile "dreamotion3d.pbi"

Declare FrameFind( *pframe.D3DXFRAME , *frame.D3DXFRAME)
;-Globales
Global   anglex.f, angley.f, flagXDown.w
Global   mox.f, omx.f, moy.l, omy.l, PlayerSpeed.l
Global   mFar.f, hh.f


  Global   *camera.CEntity
  Global *texture.CTexture
  Global   *font.CFont
  Global Dim *tiny.CAnimX(30)
  Global Quit.b
   Global  i.l, flag.l
  Global  tab.l=0, *tFrame.D3DXFRAME
 
     Structure BULLET
    *mesh.CMesh
    pos.D3DXVECTOR3

  EndStructure
  Global Dim ball.BULLET(128)
  Global num_ball.l=0
 
Procedure MON_JEU()
    DM_InitPhysic()
  ;-Init PB modules
  If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0
    End
  EndIf

  ;-set graphic window 3D
  DM_Graphics3D(800,600, 32,  0, 1)
  ;-load font
  *font = DM_LoadFont( "Tahoma",9 , 0)
  DM_TextColor(*font, 198,198,198,255)
  ;-change directory for media
  SetCurrentDirectory("media/")
 
  ;-Set ambient color
  DM_AmbientLight(250,  250,  250)
  DM_CreateLight(3)

PlayerSpeed = 5
  ; ---------------------------------------
  ;-a little skybox, well here a skydome must be define in first
  ;
  ; ---------------------------------------
  *sky.CSkySphere = DM_LoadSkySphere("grassenvmap1024.dds", 50)
  DM_TranslateEntity(*sky, 0,-10,0)



  DM_TextureMipLevel( 0 )
  ; ---------------------------------------
       ;-create terrain with terrain engine
  ;    
  ; ---------------------------------------
  ;-create base terrain with heightmap "map.jpg"
  *terrain = DM_CreateTerrain("Height113.bmp", 1.5, #False)
  *brush = DM_CreateBrush("terrain")
  DM_LoadTexture("sol113.jpg", DM_GetTexture(*brush))
  DM_LoadTexture("detail3.bmp", DM_GetTexture(*brush,1))
  DM_PaintTerrain(*terrain, *brush )
  DM_FreeBrush(*brush)  
  mFar=800.0

*sphere = DM_LoadAnimMesh("tiger.x")
DM_TranslateEntity(*sphere, 0,20,90)

  *tiny  = DM_LoadAnimMesh("bones_all.x")
  DM_ScaleEntity(*tiny, 13,13,13)
  DM_AnimateSpeed(*tiny, 0.01)
  DM_RotateEntity(*tiny, 0,225,0)


 *cube = DM_CreateCube()
 *frame.l = DM_AnimateFindChild(*tiny, "R_hand")
 DM_FrameChild(*tiny, *frame, *cube )


  ; ---------------------------------------
            ;-create camera
  ; ---------------------------------------
  *camera   = DM_CreateCamera(800,600,*tiny)
  DM_MoveEntity(*camera, 0,2,4)
  DM_TurnEntity(*camera, 10,180,0)
  DM_CameraClsColor(*camera, 125, 125, 125)
  DM_CameraProjRatio(*camera, 800,600, mFar)


  ; ---------------------------------------
             ;-main loop
  ; ---------------------------------------
  ;-if fullscreen, must do it for keep mouse cursor
  ;-change_curseur( #IDC_ARROW  )
  Repeat
         ExamineMouse()
        If flagXdown=0

           flagXDown=11
        Else
           moy = MouseDeltaY()/10*PlayerSpeed/2
          
         
           mox = MouseDeltaX()/10*PlayerSpeed/2
          
          
          DM_TurnEntity(*tiny, 0,mox,0)


        EndIf
        
       ExamineKeyboard()

     ;-if Escape Key, exit
     If KeyboardReleased(#PB_Key_Escape) Or WindowEvent()=#PB_Event_CloseWindow
       Quit=1
     EndIf

        If KeyboardReleased(#PB_Key_Space)
    ball(num_ball)\mesh = DM_CreateSphere(32)
    num_ball+1
    DM_PositionEntity( ball(i)\mesh, DM_EntityX(*cube), DM_EntityY(*cube), DM_EntityZ(*cube))
      alpha.f = DM_EntityYaw(*tiny)
      DM_RotateEntity(ball(i)\mesh, 0, alpha, 0)              
  EndIf
  If(num_ball)
     For i=0 To num_ball-1
       DM_MoveEntity( ball(i)\mesh, 0,0,-5)
     Next
  EndIf
(DM

  
      h.f = DM_GetTerrainHeight(*terrain, DM_EntityX(*tiny), DM_EntityZ(*tiny))

    If KeyboardPushed(#PB_Key_Down)
        DM_AnimateIndex(*tiny, 1)
      DM_MoveEntity(*tiny, 0,0,4)
      DM_PositionEntity(*tiny, DM_EntityX(*tiny), h+5, DM_EntityZ(*tiny))
    EndIf
          If KeyboardReleased(#PB_Key_Down)
      DM_AnimateIndex(*tiny, 0)
            DM_MoveEntity(*tiny, 0,0,0)
      DM_PositionEntity(*tiny, DM_EntityX(*tiny), h+5, DM_EntityZ(*tiny))
    EndIf
    If KeyboardPushed(#PB_Key_Up)
        DM_AnimateIndex(*tiny, 1)
      DM_MoveEntity(*tiny, 0,0,-4)
      DM_PositionEntity(*tiny, DM_EntityX(*tiny), h+5, DM_EntityZ(*tiny))
    EndIf
      If KeyboardReleased(#PB_Key_Up)
      DM_AnimateIndex(*tiny, 0)
            DM_MoveEntity(*tiny, 0,0,0)
      DM_PositionEntity(*tiny, DM_EntityX(*tiny), h+5, DM_EntityZ(*tiny))
    EndIf

  If KeyboardPushed(#PB_Key_Right)
    DM_TurnEntity(*tiny, 0,1,0)
  EndIf

  If KeyboardPushed(#PB_Key_Left)
    DM_TurnEntity(*tiny, 0,-1,0)
  EndIf


      h.f = DM_GetTerrainHeight(*terrain, DM_EntityX(*sphere), DM_EntityZ(*sphere))

    If KeyboardPushed(#PB_Key_S)
      DM_MoveEntity(*sphere, 0,0,4)
      DM_PositionEntity(*sphere, DM_EntityX(*sphere), h+5, DM_EntityZ(*sphere))
    EndIf
          If KeyboardReleased(#PB_Key_S)
            DM_MoveEntity(*sphere, 0,0,0)
      DM_PositionEntity(*sphere, DM_EntityX(*sphere), h+5, DM_EntityZ(*sphere))
    EndIf
    If KeyboardPushed(#PB_Key_W)
      DM_MoveEntity(*sphere, 0,0,-4)
      DM_PositionEntity(*sphere, DM_EntityX(*sphere), h+5, DM_EntityZ(*sphere))
    EndIf
      If KeyboardReleased(#PB_Key_W)
            DM_MoveEntity(*sphere, 0,0,0)
      DM_PositionEntity(*sphere, DM_EntityX(*sphere), h+5, DM_EntityZ(*sphere))
    EndIf
    
  If KeyboardPushed(#PB_Key_D)
    DM_TurnEntity(*sphere, 0,1,0)
  EndIf

  If KeyboardPushed(#PB_Key_A)
    DM_TurnEntity(*sphere, 0,-1,0)
  EndIf
     ; ---------------
           ;-Render
     ; ---------------
           If flag=0 : DM_UpdateWorld() : EndIf
     DM_BeginScene()
       DM_RenderWorld(*camera)
        ;-draw some informations
        DM_DrawText(*font, 10, 15, "FPS: "+Str(DM_FPS()))  
     DM_EndScene()
  Until quit=1
  ;-end
  DM_ClearGraphics()
 
EndProcedure
 
  Procedure FrameFind( *pframe.D3DXFRAME , *frame.D3DXFRAME)
  Protected a$
 
  a$=Space(tab)
  Repeat
    *frame = DM_AnimateGetChild(*tiny, *pframe, *frame)
    If *frame
      Debug a$+DM_AnimFrameName(*frame)
      tab+3
      FrameFind(*frame, #Null)
    EndIf
  Until *frame=#Null
  tab-3
 
EndProcedure
Le guerrier avance vers sa destiné!
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

Le problème c'est que vu que tu t'es lancé dans DreamMotion3D, ça restreind le nombre de personnes qui peuvent te filer un coup de main! Et vu que c'est les vacances, je crois même que ça annule momentanément le nombre de personnes qui peuvent te filer un coup de main...
guerrier001
Messages : 130
Inscription : dim. 11/janv./2009 15:04

Message par guerrier001 »

J'attendrais septembre alors ^_^
Le guerrier avance vers sa destiné!
Anonyme

Message par Anonyme »

pas besoin , il te faut quelque notions de Vecteur 3D et connaitre l'utilisation des fonction physique du moteur.

Le principe est simple :

Imagine que tu as une sphère qui represente la planete avec comme vecteur de position 100,200,150

et que tu as un objet à soumettre à la gravité qui se trouve à 250,320,450


Il te faut dans un premier temps , désactivé la gravité de base dans le moteur.
Tu connais ensuite la position ( vecteur3 ) de ton objet qui attire les autres.
La gravité est une sorte de Dégradé , plus t'es loin , moins tu est attiré.
Donc on en déduis que la gravité vaut 1 à la position de l'objet [100,200,150]
Mais combien vaut la gravité à l'objet qui est en [250,320,450] ?
C'est simple , tu calcules la distance entre tes vecteurs :


x = A\x - B\x
y = A\y - B\y
z = A\z - B\z
Distance.f = sqr( (x * x) + (y * y) + (z * z) )

Dans notre cas Distance vaut environ 356.
il y a donc 356 unité qui sépare nos objets.
ensuite tu dois déterminer en fonction de ton choix la force d'attraction de ton objet qui attire les autres, ici on va dire 400.


On connais donc la position de tout les objets , la distance qui les sépare , la force. Vu la distance qui sépare les 2 objets , le second est attiré par l'attraction qui vaut 400 , mais comme l'attraction est progressive , il faut calculé , la force qui est soumis à cet objet.

un simple produit en croix inversé suffit.

donc à 400 unité de distance la gravité vaut 0
à 0 unité de distance la gravité vaut 1
à 200 unité la gravité vaut 0.5
etc...


on inverse :

400 vaut 1
0 vaut 0

notre produit en croix :

400 1
356 ?

356 * 1 / 400 = 0.89

on inverse encore une fois pour avoir la bonne valeur
Force_a_appliquer = 1 - 0.89 = 0.11


Tu connais la force qu'il faut appliqué à l'objet pour l'attirer vers l'autre. mais dans quelle direction ?

Pour connaitre la direction , c'est très simple

Resultat_Vector3 = PointViser_Vector3 - ObjetADiriger_Vector3
Tu normalizes le vecteur resultat , et tu as la direction de l'attraction

Pour avoir la bonne direction il est impératif de soustraire de cette maniere :
Cible - Position



se qui nous donne les valeurs suivantes :

X = -0.42107596993446
Y = -0.33686077594757
Z = -0.84215193986893



ensuite tu multiplie ton vecteur normalizé par la Force_a_appliquer
en gros , tu scales ton vecteur 3d par la force. se qui donne :

X = -0.046318356692790622
Y = -0.037054685354232723
Z = -0.092636713385582298


Tu récupères la position de ton objet , et tu additionne le resultat :

X = 250 + -0.046318356692790622
Y = 320 + -0.037054685354232723
Z = 450 + -0.092636713385582298

Maintenant :

X = 249.95368164330722
Y = 319.96294531464576
Z = 449.90736328661444

Ton objet se rapproche ! tu repetes l'opération tout le temps , car plus il se rapproche , plus il est soumis à la force d'attraction !
pour les collisions , tu laisses la main au moteur physique !

si le moteur physique te le permet , tu peut directement ajouté une force à l'objet , plus besoin donc de soustraire le resultat à la position.

je sais que tu n'a pas de notion de vecteur , néanmoins , je t'ai donné les pistes pour que tu cherches sur le net les opérations sur les vecteurs 3d
normalisation , echelle ( scale ) , addition , etc...
une fois que tu auras saisi le concept , plus rien ne t'échappera en 3D !
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

@Cpl.Bator

Ah... Moi, je croyais qu'il voulait tout ce qui touche les collisions conséquentes à l'attraction entre deux objets, et là c'est une belle galère.

Juste une toute petite correction pour le calcul de la force :
F = K * (M1 * M2) / (D * D)

K : c'est une constante
M1 : c'est la masse de l'un des deux objets
M2 : c'est la masse de l'autre objet
D : c'est la distance entre les deux objets

C'est Isaac Newton qui s'en est aperçu en se prenant une pomme en pleine poire.
Et Albert Einstein a remplacé la constante K par une autre équation bien trash en fonction des masses et de la distance aussi, mais comme je doute que Guerrier001 ne soit en train de modéliser des galaxies, des étoiles et des trous noirs, ça sert à rien que j'aille trop loin.

En tout cas, bien vu Cpl, j'allais le laisser galérer encore deux semaines!

Ollivier
Anonyme

Message par Anonyme »

c'est ce que j'allais répondre , il n'a pas parlé d'orbite ^^ je suppose que les vecteur 3d l'on envoyé sur l'orbite de pluton :D

Sinon , si tu veut appliqué la formule de newton , K ( je l'aurais appeler G ) vaut 9.8 pour la gravité terrestre.

Tu peut aussi utilisé la technique décrite plus haut pour faire des explosions , ta juste a inversé la force.
guerrier001
Messages : 130
Inscription : dim. 11/janv./2009 15:04

Message par guerrier001 »

tu allais me laisser galerer pendant 2 semaine? tu veux mamort c'est ca ? bon merci cpl.bator je vais l'essayer demain. ollivier, la prochaine fois je t'envoie directent un mp. :lol: :lol:
Le guerrier avance vers sa destiné!
tmyke
Messages : 1554
Inscription : lun. 24/juil./2006 6:44
Localisation : vosges (France) 47°54'39.06"N 6°20'06.39"E

Message par tmyke »

[APARTé]
Si je puis me permettre, tu aurais un certains intérêt de lacher DM3D (qui n'est plus maintenu pour PB),
et passer à N3xtD, la syntaxe générale ne te déroutera pas (très proche de celle de DM3D), et tu partiras sur un moteur 3D
mis à jour, plus complet et doté d'une certaine pérennité. ;)
[/APARTé]
Force et sagesse...
guerrier001
Messages : 130
Inscription : dim. 11/janv./2009 15:04

Message par guerrier001 »

Ok je vais l'essayer
Le guerrier avance vers sa destiné!
Anonyme

Message par Anonyme »

Voila avec n3xtd un code brut :

Code : Tout sélectionner

IncludePath "includes"   :   IncludeFile "n3xtD_PB.pbi"


Global NewList Dynamic_body()
ExamineDesktops()
iSetAntiAlias(#True)
*app=iCreateGraphics3D(DesktopWidth(0),DesktopHeight(0),DesktopDepth(0), 0, #True, #EDT_OPENGL)
If *app= #Null
  End
EndIf

SetCurrentDirectory("media/") 

WSize = 10000
iSetWorldSize(-WSize,-WSize,-WSize,WSize,WSize,WSize)
iGravityForce(0,0,0)


*light = iCreateLight($FFFFFF,5000)
iPositionNode(*light,1000,500,500)
iAttenuationLight(*light, 1, 1.0/5000, 0)


*Cam = iCreateCamera()
iPositionNode(*Cam,150,150,150)
iPointTargetNode(*Cam,0,0,0)



Magnetic = iCreateSphere(100,60)
iSetCollideForm(#SPHERE_PRIMITIVE)
*body_Magnetic = iCreateBody(Magnetic,#False)





Procedure new_dynamic_body(x,y,z)
Mesh = iCreateSphere(5,10)
iPositionNode(Mesh,x,y,z)
	iSetCollideForm(#SPHERE_PRIMITIVE)
		*body_Magnetic = iCreateBody(Mesh)
		AddElement(Dynamic_body())
			Dynamic_body() = *body_Magnetic

EndProcedure





For i = 0 To 499
	new_dynamic_body(-Random(1000)+Random(1000),-Random(1000)+Random(1000),-Random(1000)+Random(1000))
Next



; iAddFilePostProcessingXEffect("XShaders/BlurVP")
; iAddFilePostProcessingXEffect("XShaders/BlurHP")

G = 9.8
Mult = 50
Repeat



iPointTargetNode(*Cam,0,0,0)


; Camera Orbitale ^^
Nx.f = 150 * Cos(ElapsedMilliseconds()/2500)
Ny.f = (100 + 100 * Cos(ElapsedMilliseconds()/2000))+150
Nz.f = 150 * Sin(ElapsedMilliseconds()/5000)
iPositionNode(*Cam,Nx,Ny,Nz)



  If iGetMouseEvent(#MOUSE_BUTTON_LEFT)
  		If flagXDown=0
  			omx = iGetMouseX()
  			omy = iGetMouseY()
  			flagXDown=11
  		Else
  			moy = iGetMouseY()-omy
  			angley=(moy/10.0)
  			omy= iGetMouseY()
  			mox = iGetMouseX()-omx
  			anglex=(mox/10.0)
  			omx= iGetMouseX()
  			iTurnNode(*cam, angley, anglex,0)
  		EndIf
  Else
  	 		flagXDown=0
  EndIf


	; if Escape Key, exit	
  If iGetKeyDown(#KEY_ESCAPE)
    Quit=1
  EndIf

	If iGetKeyDown(#KEY_ARROW_UP) And KeyFlag = 0
	 KeyFlag = 1
    Mult = -1*Mult
  EndIf

	If Not iGetKeyDown(#KEY_Space) And KeyFlag = 1
	 KeyFlag = 0
  EndIf


ForEach Dynamic_body()

A.VECTOR3 
VECTOR3_(A,iBodyX(Dynamic_body()),iBodyY(Dynamic_body()),iBodyZ(Dynamic_body()))

B.VECTOR3 
VECTOR3_(B,iBodyX(*body_Magnetic),iBodyY(*body_Magnetic),iBodyZ(*body_Magnetic))


Distance.f = Vec3_GetDistanceFrom(@A,@B)
Force.q = G*(10000000000000000*0.001)/(Distance*Distance)

Direction.VECTOR3
Impulse.VECTOR3
Vec3_Sub(@Direction,B,A)
Vec3_Normalize(@Direction)
Vec3_MulF(@Impulse,@Direction,@Force)
Vec3_Normalize(@Impulse)


iForceBody(Dynamic_body(),Impulse\x*Mult,Impulse\y*Mult,Impulse\z*Mult)

Next 






  	; ---------------
  	;      Render
  	; ---------------
  iBeginScene()
     iDrawScene()
  iEndScene()



Until Quit=1
; end
iFreeEngine()
guerrier001
Messages : 130
Inscription : dim. 11/janv./2009 15:04

Message par guerrier001 »

Comment on fait si c'est animé car quand l'entité est animé il traverse la mesh.
Le guerrier avance vers sa destiné!
tmyke
Messages : 1554
Inscription : lun. 24/juil./2006 6:44
Localisation : vosges (France) 47°54'39.06"N 6°20'06.39"E

Message par tmyke »

Heu, peux tu être plus précis ?
Force et sagesse...
guerrier001
Messages : 130
Inscription : dim. 11/janv./2009 15:04

Message par guerrier001 »

quand on initialise l'entité je met qu'elle est animmesh elle travers n'importe quelle terrain mais quand je ne la met pas en animmesh elle fait ce que je lui demande c'est a dire de ne pas bouger quand elle se cogne sur le terrain
Le guerrier avance vers sa destiné!
Anonyme

Message par Anonyme »

arf , as tu vu ton orthographe , même si moi je fait des fotes , toi tu abuses.
ton landeau à pris feu quand tu était petit et ton père l'a éteint à coup de pioche ?
guerrier001
Messages : 130
Inscription : dim. 11/janv./2009 15:04

Message par guerrier001 »

un quoi ?(désoler pour les fautes d'orthographe j'écris trops vite sur le clavier et je ne revérifie pas)
Le guerrier avance vers sa destiné!
Répondre