Page 1 sur 1

Voir une liaison entres deux nodes.

Publié : dim. 19/mars/2023 21:46
par falsam
J'ai fait un module de conception d'objet ou d'avatar animé.

Le principe est de créer des joints les uns aux autres et pour chaque joint créer une animation.

Une idée simpliste avec cette image.
Image

Si vous souhaitez faire un test ça se passe ici : viewtopic.php?t=18894

:arrow: Pour concevoir un skeleton plus complexe j'aurais besoin de voir les liaisons entre chaque joint.
Actuellement j'utilise la fonction CreateLine3D() pour tracer une ligne entres les joins. Mais c'est trop fin.

:arrow: J'aimerais donc pouvoir mettre un cylindre fin entre les différentes liaisons mais ça dépasse mes compétences. Si vous savez faire je suis preneur. D'avance merci.

Un code dans lequel je met en place deux nodes représentés par deux entité.
Flèches gauche et droite pour voir sur différents cotés.

Code : Tout sélectionner

EnableExplicit

; DPI Résolution
Define drx.f, dry.f, depX.f

Declare Distance3D(Node0, Node1)

drx = DesktopResolutionX()
dry = DesktopResolutionY()

InitEngine3D(#PB_Engine3D_DebugLog) : InitSprite() : InitKeyboard() : InitMouse()

ExamineDesktops()
OpenWindow(0, 0,0, DesktopWidth(0)*0.5,DesktopHeight(0)*0.5, "Test - [Esc] quit",#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0)*drx, WindowHeight(0)*dry, 0, 0, 0)

CreateCamera(0, 0, 0, 100, 100) : MoveCamera(0, 0,1,-4) : CameraLookAt(0, 0,1,0)
CreateLight(0,$ffffff, -10000, 10000, 0)
AmbientColor($111111*3)
CameraBackColor(0,$444488)

; Création de deux nodes
CreateNode(0, 0,0,0)
CreateNode(1, 1,1,1)

; Création de deux petits cubes pour visualiser les nodes
CreateEntity(0, MeshID(CreateCube(#PB_Any, 0.1)), #PB_Material_None)
CreateEntity(1, MeshID(CreateCube(#PB_Any, 0.1)), #PB_Material_None)

; Attacher chaque entité sur leurs Nodes respectifs
AttachNodeObject(0, EntityID(0))
AttachNodeObject(1, EntityID(1))

; Puis j'attache le node 1 sur le node 2
AttachNodeObject(0, NodeID(1))

Repeat
  While WindowEvent() : Wend
  ExamineKeyboard() 
  depx=(-Bool(KeyboardPushed(#PB_Key_Left))+Bool(KeyboardPushed(#PB_Key_Right)))*0.5
  RotateNode(0, 0, depx, 0, #PB_Relative)
  RenderWorld()
  FlipBuffers()    
Until KeyboardReleased(#PB_Key_Escape)

Re: Voir une liaison entres deux nodes.

Publié : dim. 19/mars/2023 23:41
par Guillot
j'ai un peu changer ton code
(j'aime pas trop les nodes, mais bon, tu verras c'est pareil)

tu définis le nombre de liaison
puis tu appelle la procedure liaison dans la boucle de rendu

Code : Tout sélectionner

EnableExplicit

; DPI Résolution
Define drx.f, dry.f, depX.f

Declare Distance3D(Node0, Node1)

drx = DesktopResolutionX()
dry = DesktopResolutionY()

InitEngine3D(#PB_Engine3D_DebugLog) : InitSprite() : InitKeyboard() : InitMouse()

ExamineDesktops()
OpenWindow(0, 0,0, DesktopWidth(0)*0.5,DesktopHeight(0)*0.5, "Test - [Esc] quit",#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0)*drx, WindowHeight(0)*dry, 0, 0, 0)

CreateCamera(0, 0, 0, 100, 100) : MoveCamera(0, 0,1,-4) : CameraLookAt(0, 0,1,0)
CreateLight(0,$ffffff, -10000, 10000, 0)
AmbientColor($111111*3)
CameraBackColor(0,$444488)

CreateEntity(0, MeshID(CreateCube(#PB_Any, 0.1)), #PB_Material_None)
CreateEntity(1, MeshID(CreateCube(#PB_Any, 0.1)), #PB_Material_None,1,1,1)
CreateEntity(2, MeshID(CreateCube(#PB_Any, 0.1)), #PB_Material_None,0,1,0)

; lier les entités entre elles, leur position devient alors position relative à leur parent
AttachEntityObject(0,"",EntityID(1))
AttachEntityObject(1,"",EntityID(2))

;================================================================================================
; liaison
Define nbliaison,mat,mesh,i
nbliaison=2
mat=CreateMaterial(-1,0,$ff)
mesh=CreateCylinder(-1,0.5,1):TransformMesh(mesh,0,0.5,0,1,1,1,0,0,0)
Global Dim entityliaison(nbliaison)
For i=1 To nbliaison
  entityliaison(i)=CreateEntity(-1,MeshID(Mesh),MaterialID(mat))
Next

Procedure liaison(liaison,entity1,entity2,ray.f)
  Protected.f l,dx,dy,dz,   el.i=entityliaison(liaison)
  dx=EntityX(entity2)-EntityX(entity1)
  dy=EntityY(entity2)-EntityY(entity1)
  dz=EntityZ(entity2)-EntityZ(entity1)
  l=Sqr(dx*dx+dy*dy+dz*dz)
  MoveEntity(el,EntityX(entity1),EntityY(entity1),EntityZ(entity1),#PB_Absolute)
  ScaleEntity(el,ray,l,ray,#PB_Absolute)
  EntityLookAt(el,EntityX(entity2),EntityY(entity2),EntityZ(entity2),0,1,0)
EndProcedure
;================================================================================================

Repeat
  While WindowEvent() : Wend
  ExamineKeyboard() 
  depx=(-Bool(KeyboardPushed(#PB_Key_Left))+Bool(KeyboardPushed(#PB_Key_Right)))*0.5*10
  RotateEntity(0, 0, depx, 0, #PB_Relative)
  
  liaison(1,    0,1,0.1) ; <========= 
  liaison(2,    1,2,0.1) ; <========= 
  
  RenderWorld()
  FlipBuffers()    
Until KeyboardReleased(#PB_Key_Escape)

Re: Voir une liaison entres deux nodes.

Publié : lun. 20/mars/2023 1:58
par nemerod
voila c'est fais, dans une procedure comme demande depuis discord le tous avec les ID des 2 node et la coloration des grosse ligne, les extrémité sont démarqué pour les mettre en évidence
mode d'emplois, utilisé les bouton

ATTENTION
j'ai volontairement fais mon propre système pour la demo sans passé par les LIB Mouse & Keyboard
j'utilise aussi 2 fonction API systeme pour des raison pratique

ZQSD pour vous déplacé
la souri pour changé l'angle de vue
espace pour monté
shift pour descendre
faite le bouton entré pour recrée de nouvelle ligne :)
faite échappe pour affiché la souri et gardé la vue fix


la procedure en question s'appel FatNodeLinkView
la couleur est personnalisable et la taille aussi

Code : Tout sélectionner

Global *key:*key=AllocateMemory($400);vieu truc sans_titre.pb
Global TPX.d=0;pos X
Global TPY.d=0;pos Y
Global TPZ.d=0;pos Z
Global TPA.f=0;rotation camera
Global TPP.f=0;rotation camera
Global TPS.f=0;vitesse déplacement depuis delta time qui l'aime de trop
Global TT0.f=0;
Global TT1.f=0;
InitEngine3D():InitSprite()
Procedure KeyPushed(       a):ProcedureReturn PeekA(*key+( a&$ff)     )  :EndProcedure
Procedure KeyReleased(     a):ProcedureReturn PeekA(*key+( a&$ff)     )!1:EndProcedure

Procedure FatNodeLinkView(IDNode1,IDNode2,IDdebug,radius.d=1.0,color=$ffffff)
  fx0.d=NodeX(IDNode1):fx1.d=NodeX(IDNode2);pos X des 2 node
  fy0.d=NodeY(IDNode1):fx1.d=NodeY(IDNode2);Y
  fz0.d=NodeZ(IDNode1):fx1.d=NodeZ(IDNode2);Z
  CreateTexture(IDNode1,       1,1):StartDrawing(TextureOutput(IDNode1)):Plot(0,0,color|$ff101020):StopDrawing():CreateMaterial(IDNode1,TextureID(IDNode1));material source 
  CreateTexture(IDNode2,       1,1):StartDrawing(TextureOutput(IDNode2)):Plot(0,0,color|$ff102010):StopDrawing():CreateMaterial(IDNode2,TextureID(IDNode2));material destination
  CreateTexture(IDdebug,       1,1):StartDrawing(TextureOutput(IDdebug)):Plot(0,0,color          ):StopDrawing():CreateMaterial(IDdebug,TextureID(IDdebug));material central
  CreateSphere( IDNode1,radius+0.1):CreateEntity(IDNode1,MeshID(IDNode1),MaterialID(IDNode1),fx0 ,fy0 ,fz0 );mesh et entité source
  CreateSphere( IDNode2,radius+0.1):CreateEntity(IDNode2,MeshID(IDNode2),MaterialID(IDNode2),fx1 ,fy1 ,fz1 );mesh et entité destination
  tx.d=(fx0+fx1)/2:fx0-fx1:fx0*fx0;creation de la position central et pré-calcule distance
  ty.d=(fy0+fy1)/2:fy0-fy1:fy0*fy0;voir explication ici pour detail 
  tz.d=(fz0+fz1)/2:fz0-fz1:fz0*fz0;https://discord.com/channels/567000183209066496/567004582765527041/1087103348014059630
  tl.d=Sqr(fx0+fy0+fz0);distance
  CreateCylinder(IDdebug,radius,tl,8,1,0):CreateEntity(IDdebug,MeshID(IDdebug),MaterialID(IDdebug),tx  ,ty  ,tz  ):EntityLookAt(IDdebug,fx1 ,fy1 ,fz1 ,0,1,0);parti central
  AttachNodeObject(IDNode1, EntityID(IDNode1));attache des entité sur le node source
  AttachNodeObject(IDNode1, EntityID(IDNode2));
  AttachNodeObject(IDNode1, EntityID(IDdebug));
  ProcedureReturn 
EndProcedure

Procedure recreateline();demo avec ligne random depuis fake node test
  For r = 0 To 200 Step 3
    CreateNode(r  ,Random(201)-100,Random(201)-100,Random(201)-100);creation du node fictive 1
    CreateNode(r+1,Random(201)-100,Random(201)-100,Random(201)-100);creation du node fictive 2
    FatNodeLinkView(r,r+1,r+2,1,Random($ffffff));big line
  Next
EndProcedure
OpenWindow(0,0,0,800,600,"demo de mise en page demande par falsam depuis discord",#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0),0,0,800,600):ShowCursor_(0):CreateCamera(0,0,0,100,100)
recreateline()
Repeat:eee=WindowEvent()
  gmx=(DesktopMouseX()-WindowX(0,1))
  gmy=(DesktopMouseY()-WindowY(0,1))
  Select eee
    Case 0
      If GetWindowState(0)<>#PB_Window_Minimize And GetActiveWindow()=>0
        If flag=0
          SetCursorPos_(WindowX(0,#PB_Window_InnerCoordinate)+400,WindowY(0,#PB_Window_InnerCoordinate)+300)
          tpa-((gmy-300)*0.1)
          tpp-((gmx-400)*0.1)
          If tpa<-90:tpa=-90:EndIf
          If tpa> 90:tpa= 90:EndIf
          tpp=Mod(tpp,360)
          RotateCamera(0,tpa,tpp,#PB_Absolute)
        EndIf
        If KeyPushed(#VK_Q    ):tt0-tps:EndIf
        If KeyPushed(#VK_D    ):tt0+tps:EndIf
        If KeyPushed(#VK_SHIFT):tpy-tps:EndIf
        If KeyPushed(#VK_SPACE):tpy+tps:EndIf
        If KeyPushed(#VK_Z    ):tt1-tps:EndIf
        If KeyPushed(#VK_S    ):tt1+tps:EndIf
        tpx+((Sin(Radian(tpp+90))*tt0)+(Sin(Radian(tpp))*tt1))
        tpz+((Cos(Radian(tpp+90))*tt0)+(Cos(Radian(tpp))*tt1))
        tt0=0:tt1=0
        MoveCamera(0,tpx,tpy,tpz,#PB_Absolute)
        ;CameraLookAt(0,0,0,0)
        For a = 0 To 200
          If IsNode(a)
            Select (a/3)%3
              Case 0:RotateNode(a,1  ,0  ,0  ,#PB_Relative)
              Case 1:RotateNode(a,0  ,0.1,0  ,#PB_Relative)
              Case 2:RotateNode(a,0  ,0  ,1.2,#PB_Relative)
            EndSelect
          EndIf
        Next
        tps=RenderWorld()*0.1
        FlipBuffers()
      Else:Delay(13)
      EndIf
    Case $101:temp=EventwParam():PokeA(*key+temp+$200,1):PokeA(*key+temp+$300,1):PokeA(*key+temp,0):
    Case $100:temp=EventwParam():PokeA(*key+temp+$100,1):PokeA(*key+temp+$300,1):PokeA(*key+temp,1)
      Select temp
        Case #VK_ESCAPE;escap, release cursor or grab
          flag!1
          ShowCursor_(flag)
        Case #VK_RETURN;replacement de la vue
          tpx=0:tpy=0:tpz=100:tpa=0:tpp=0
          MoveCamera(0,tpx,tpy,tpz,#PB_Absolute)
        Case #VK_NUMPAD0;NUMPAD_0; create multi line with random color
          recreateline()
        Default:Debug temp
      EndSelect
  EndSelect
Until eee=#PB_Event_CloseWindow
Image

Re: Voir une liaison entres deux nodes.

Publié : lun. 20/mars/2023 8:58
par Guillot
@ nemerod
pour faire une couleur t'as plus besoin de texture
CreateMaterial(..., 0 , couleur)
t'es sur window 95 ?

Re: Voir une liaison entres deux nodes.

Publié : lun. 20/mars/2023 9:21
par falsam
Me voila avec plusieurs solutions que je vais essayer de comprendre et à intégrer dans mon module de conception d'objets animés. Merci beaucoup pour votre investissement. J'aime beaucoup.

Re: Voir une liaison entres deux nodes.

Publié : lun. 20/mars/2023 15:25
par nemerod
Guillot a écrit : lun. 20/mars/2023 8:58 @ nemerod
pour faire une couleur t'as plus besoin de texture
CreateMaterial(..., 0 , couleur)
dans un sense j'utilise pas souvent les fonction 3D et prendre pas le temps de voir les nouvelle fonction
du moment que cela marche pour moi :)
Guillot a écrit : lun. 20/mars/2023 8:58 t'es sur window 95 ?
non, je suis pas sur win95, j'ai juste demandé au PC d'avoir le skin car je suis beaucoup plus familier avec se visuel que la dernier version