une chenille sur un terrain

Généralités sur la programmation 3D
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

une chenille sur un terrain

Message par comtois »

Une bricole sans intérêt, si ce n'est que j'aime bien balader une chenille sur un terrain :)

Pour tester copiez le code dans le répertoire PureBasic\Examples\3D

Touches [F2]/[F3]/[F4] pour changer le point de vue de la caméra. [F4] est plus efficace quand la chenille grandit.

Code : Tout sélectionner

IncludeFile #PB_Compiler_Home + "Examples/3D/Screen3DRequester.pb"

Enumeration
  #ThirdPersonChase 
  #ThirdPersonFixed
  #TopView
EndEnumeration

#Nb = 100
#Size = 6
#PlayerSpeed = 0.1

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

Structure s_Key
  Left.i
  Right.i
EndStructure

Structure s_Item
  Attached.i
  Entity.i
  MainNode.i     
  SecondNode.i 
  forward.i
EndStructure

Structure s_Head
  Item.s_Item
  LastItem.i
  Key.s_Key
  SightNode.i
  CameraNode.i 
  DirectionNode.i
  Offset.Vector3
EndStructure

Structure s_Camera
  Camera.i
  Mode.i
  Tightness.f
  CameraNode.i
  TargetNode.i
EndStructure   

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

Macro SetVector3(V, xx, yy, zz)
  V\x = xx
  V\y = yy
  V\z = zz
EndMacro

Macro AddVector3(V, V1, V2)
  V\x = V1\x + V2\x
  V\y = V1\y + V2\y
  V\z = V1\z + V2\z
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

Macro NodeOnTerrain(p, Node)
  p\x = NodeX(Node)
  p\z = NodeZ(Node)
  p\y = TerrainHeight(0, p\x, p\z) + #Size
  MoveNode(Node, p\x, p\y, p\z, #PB_Absolute)
EndMacro

Define camera.s_Camera
Define p.Vector3
Define Head.s_Head
Global Dim Item.s_Item(#Nb)
Global NewList Chenille.i() ; Stock l'index du tableau
Global Speed.f


#CameraSpeed = 1
#TerrainMiniX = 0
#TerrainMiniY = 0
#TerrainMaxiX = 0
#TerrainMaxiY = 0

;-Declare
Declare HandleEntity(*Head.s_Head)
Declare CameraMode(*Camera.s_Camera, *Head.s_Head)
Declare CameraTrack(*Camera.s_Camera, *Head.s_Head)
Declare CameraInstantUpdate(*Camera.s_Camera, *CameraPosition.Vector3, *TargetPosition.Vector3)
Declare CameraUpdate(*Camera.s_Camera, *CameraPosition.Vector3, *TargetPosition.Vector3)
Declare.f Distance(*v1.Vector3, *v2.Vector3)
Declare MoveItem()
Declare TestItem(*Head.s_Head)

Declare InitBlendMaps()
Declare Clamp(*var.float, min.f, max.f)

; OpenGL needs to have CG enabled to work (Linux and OS X have OpenGL by default)
;
CompilerIf #PB_Compiler_OS <> #PB_OS_Windows Or Subsystem("OpenGL")
  Flags = #PB_Engine3D_EnableCG
CompilerEndIf

If InitEngine3D(3)
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
  If Screen3DRequester()
    
    Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Textures", #PB_3DArchive_FileSystem)
    Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Scripts",#PB_3DArchive_FileSystem)
    Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Textures/nvidia", #PB_3DArchive_FileSystem)
    Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/GUI", #PB_3DArchive_FileSystem)
    Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Packs/desert.zip", #PB_3DArchive_Zip)    
    Parse3DScripts()
    
    WorldShadows(#PB_Shadow_Modulative, -1, RGB(127, 127, 127))
    
    ;- Light
    ;
    
    light = CreateLight(#PB_Any ,RGB(185, 185, 185), 4000, 1200, 1000, #PB_Light_Directional)
    SetLightColor(light, #PB_Light_SpecularColor, RGB(255, 255,255))
    LightDirection(light ,0.55, -0.3, -0.75)
    AmbientColor(RGB(5, 5,5))
    
    ;----------------------------------
    ; terrain definition
    SetupTerrains(LightID(Light), 3000, #PB_Terrain_NormalMapping)
    ; initialize terrain
    CreateTerrain(0, 513, 12000, 600, 3, "Terrain04", "Dat")
    ; set all texture will be use when terrrain will be constructed
    AddTerrainTexture(0,  0, 100, "dirt_grayrocky_diffusespecular.jpg",  "dirt_grayrocky_normalheight.jpg")
    AddTerrainTexture(0,  1,  30, "grass_green-01_diffusespecular.jpg", "grass_green-01_normalheight.jpg")
    AddTerrainTexture(0,  2, 200, "growth_weirdfungus-03_diffusespecular.jpg", "growth_weirdfungus-03_normalheight.jpg")
    
    ;- define terrains
    For ty = #TerrainMiniY To #TerrainMaxiY
      For tx = #TerrainMiniX To #TerrainMaxiX
        imported = DefineTerrainTile(0, tx, ty, "terrain513.png", ty % 2, tx % 2) 
      Next
    Next 
    BuildTerrain(0) 
    
    If imported = #True
      InitBlendMaps()
      UpdateTerrain(0)
      ;SaveTerrain(0, #False)
    EndIf 
    
    ; SkyBox
    ;
    SkyBox("desert07.jpg")
    
    ;- Materials
    ;
    CreateMaterial(0, LoadTexture(0, "Wood.jpg"))
    GetScriptMaterial(1, "SphereMap/SphereMappedRustySteel")
    CreateMaterial(2, LoadTexture(2, "Dirt.jpg"))
    GetScriptMaterial(3, "Scene/GroundBlend")
    ;- Head
    ;
    CreateSphere(1, #Size)
    
    With Head
      \Item\Entity = CreateEntity(#PB_Any, MeshID(1), MaterialID(1))
      \Key\Left  = #PB_Key_Left
      \Key\Right = #PB_Key_Right
      \Offset\x = 0
      \Offset\y = 50 ; Offset could be needed for FirstPerson
      \Offset\z = 130 
      ; Entity use 5 nodes 
      \Item\MainNode=CreateNode(#PB_Any, 0, #Size, 0) ; Entity position
      \Item\SecondNode=CreateNode(#PB_Any, 0, 0, 2 * #Size)
      \DirectionNode=CreateNode(#PB_Any, 0, 0, -1) ; Direction normalized
      
      \SightNode=CreateNode(#PB_Any, 0, 20, -120) ; For cameraLookAt
      \CameraNode=CreateNode(#PB_Any, 0, 100, 140) ; Camera position
      
      CopyStructure(Head\Item, Item(0), s_Item)
      \LastItem = 0
      
      AttachNodeObject(\Item\MainNode, NodeID(\SightNode))
      AttachNodeObject(\Item\MainNode, NodeID(\CameraNode))   
      AttachNodeObject(\Item\MainNode, NodeID(\DirectionNode))
      AttachNodeObject(\Item\MainNode, NodeID(\Item\SecondNode))
      AttachNodeObject(\Item\MainNode, EntityID(\Item\Entity))
      
      NodeOnTerrain(p, \Item\MainNode)
    EndWith
    
    
    ;- Item
    ;
    For i=1 To #Nb
      With Item(i)
        \Entity = CreateEntity(#PB_Any, MeshID(1), MaterialID(1))
        ; Entity use 2 nodes   
        \MainNode=CreateNode(#PB_Any, Random(6000)-3000, #Size, Random(6000)-3000) ; Entity position
        \SecondNode=CreateNode(#PB_Any, 0, 0, 2 * #Size) ; Direction normalized
        AttachNodeObject(\MainNode, NodeID(\SecondNode))
        AttachNodeObject(\MainNode, EntityID(\Entity))
        
        NodeOnTerrain(p, \MainNode)
      EndWith
    Next 
    
    ;- Camera
    ;
    CreateCamera(0, 0, 0, 100, 100)
    With Camera 
      \Camera = 0
      \Mode = -1
      \Tightness = 0.01
      ; Camera use 2 nodes
      \CameraNode = CreateNode(#PB_Any, -3000, 700, 0) ; Camera position
      \TargetNode = CreateNode(#PB_Any) ; For cameraLookAt
      AttachNodeObject(\CameraNode, CameraID(\Camera))
    EndWith 
    
    Repeat
      Screen3DEvents()
      
      If ExamineKeyboard()
        CameraMode(@Camera, @Head)     
        HandleEntity(@Head)
      EndIf
      TestItem(@Head)
      MoveItem()
      
      CameraTrack(@Camera, @Head)
      
      Speed.f = RenderWorld() * #PlayerSpeed
      
      Screen3DStats()
      FlipBuffers()
      
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
    
    End
    
  EndIf
Else
  MessageRequester("Error","Can't initialize engine3D")
EndIf

Procedure InitBlendMaps()
  minHeight1.f = 70
  fadeDist1.f = 40
  minHeight2.f = 70
  fadeDist2.f = 15   
  For ty = #TerrainMiniY To #TerrainMaxiY
    For tx = #TerrainMiniX To #TerrainMaxiX
      Size = TerrainTileLayerMapSize(0, tx, ty)
      For y = 0 To Size-1
        For x = 0 To Size-1
          Height.f = TerrainTileHeightAtPosition(0, tx, ty, 1, x, y)
          
          val.f = (Height - minHeight1) / fadeDist1
          Clamp(@val, 0, 1)
          SetTerrainTileLayerBlend(0, tx, ty, 1, x, y, val)
          
          val.f = (Height - minHeight2) / fadeDist2
          Clamp(@val, 0, 1)
          SetTerrainTileLayerBlend(0, tx, ty, 2, x, y, val)
        Next
      Next
      UpdateTerrainTileLayerBlend(0, tx, ty, 1)
      UpdateTerrainTileLayerBlend(0, tx, ty, 2)
    Next
  Next 
EndProcedure 

Procedure Clamp(*var.float, min.f, max.f)
  If *var\f < min
    *var\f = min
  ElseIf *var\f > max
    *var\f = max
  EndIf
EndProcedure


Procedure.f Distance(*v1.Vector3, *v2.Vector3)
  ProcedureReturn Sqr((*v1\x-*v2\x)*(*v1\x-*v2\x)+(*v1\y-*v2\y)*(*v1\y-*v2\y)+(*v1\z-*v2\z)*(*v1\z-*v2\z))
EndProcedure

Procedure MoveItem()
  Protected.Vector3  d, p, v1, v2
  Protected Dist.f
  ForEach Chenille()
    item = Chenille()
    forward = Item(item)\forward
    
    GetNodePosition(v1, Item(item)\MainNode)
    GetNodePosition(d, Item(forward)\MainNode)
    Dist = (1.8 * #Size) - Distance(@v1, @d)
    
    NodeLookAt(Item(item)\MainNode, d\x, d\y, d\z)
    MoveNode(Item(item)\MainNode, 0, 0, Dist, #PB_Local)
    
    NodeOnTerrain(p, Item(item)\MainNode)
  Next
EndProcedure

Procedure TestItem(*Head.s_Head)
  Protected.Vector3 v1, v2, d, p
  
  For i = 1 To #Nb
    If Not Item(i)\Attached
      GetNodePosition(v1, *Head\Item\MainNode)
      GetNodePosition(v2, Item(i)\MainNode)
      If Distance(@v1, @v2) < 2 * #Size
        AddElement(Chenille())
        Chenille() = i
        
        Item(i)\forward = *Head\LastItem
        
        GetNodePosition(p, Item(*Head\LastItem)\SecondNode)
        GetNodePosition(d, Item(*Head\LastItem)\MainNode)
        MoveNode(Item(i)\MainNode, p\x, p\y, p\z, #PB_Absolute)
        NodeLookAt(Item(i)\MainNode, d\x, d\y, d\z)
        
        *Head\LastItem    = i
        Item(i)\Attached = #True
      EndIf 
    EndIf 
  Next 
EndProcedure

Procedure HandleEntity( *Head.s_Head)
  Protected.Vector3 PosMain, PosDir , p
  Protected Node
  
  With *Head
    
    MoveNode(\Item\MainNode, 0, 0, -Speed, #PB_Local)
    NodeOnTerrain(p, \Item\MainNode)
    
    If KeyboardPushed(\Key\Left)
      RotateNode(\Item\MainNode, 0,Speed, 0, #PB_Relative)
    ElseIf KeyboardPushed(\Key\Right)
      RotateNode(\Item\MainNode, 0, -Speed, 0, #PB_Relative)
    EndIf
  EndWith   
EndProcedure

Procedure CameraMode(*Camera.s_Camera, *Head.s_Head)
  Protected.Vector3 CameraPosition, TargetPosition, Temp
  
  If KeyboardReleased(#PB_Key_F2)  Or *Camera\Mode = -1
    *Camera\Mode = #ThirdPersonChase
    HideEntity(*Head\Item\Entity, #False)
    GetNodePosition(CameraPosition, *Head\CameraNode)
    GetNodePosition(TargetPosition, *Head\SightNode)
    CameraInstantUpdate(*Camera, @CameraPosition, @TargetPosition)
    *Camera\Tightness = 0.01
    
  ElseIf KeyboardReleased(#PB_Key_F3)
    *Camera\Mode = #ThirdPersonFixed
    HideEntity(*Head\Item\Entity, #False)
    SetVector3(CameraPosition, 0, TerrainHeight(0, 0, 0) + 200, 0)
    GetNodePosition(TargetPosition, *Head\SightNode)
    CameraInstantUpdate(*Camera, @CameraPosition, @TargetPosition)
    *Camera\Tightness = 0.01
    
  ElseIf KeyboardReleased(#PB_Key_F4) 
    *Camera\Mode = #TopView
    HideEntity(*Head\Item\Entity, #True)
    GetNodePosition(CameraPosition, Item(*Head\LastItem)\MainNode)
    CameraPosition\y + 200
    GetNodePosition(TargetPosition, *Head\SightNode)
    CameraInstantUpdate(*Camera, @CameraPosition, @TargetPosition)
    *Camera\Tightness = 1   
    
  EndIf
EndProcedure

Procedure CameraTrack(*Camera.s_Camera, *Head.s_Head)
  Protected.Vector3 CameraPosition, TargetPosition, Temp
  
  Select *Camera\Mode
    Case #ThirdPersonChase
      GetNodePosition(CameraPosition, *Head\CameraNode)
      GetNodePosition(TargetPosition, *Head\SightNode)
      CameraUpDate(*Camera, @CameraPosition, @TargetPosition)
      
    Case #ThirdPersonFixed
      SetVector3(CameraPosition, 0,  TerrainHeight(0, 0, 0) + 200, 0)
      GetNodePosition(TargetPosition, *Head\SightNode)
      CameraUpDate(*Camera, @CameraPosition, @TargetPosition)
      
    Case #TopView
      GetNodePosition(CameraPosition, Item(*Head\LastItem)\MainNode)
      CameraPosition\y + 200
      GetNodePosition(TargetPosition, *Head\Item\MainNode)
      CameraUpDate(*Camera, @CameraPosition, @TargetPosition)
      
  EndSelect
EndProcedure

Procedure CameraInstantUpdate(*Camera.s_Camera, *CameraPosition.Vector3, *TargetPosition.Vector3)
  Protected V1.Vector3, V2.Vector3
  
  MoveNode(*Camera\CameraNode, *CameraPosition\x, *CameraPosition\y, *CameraPosition\z, #PB_Absolute)
  
  MoveNode(*Camera\TargetNode, *TargetPosition\x, *TargetPosition\y, *TargetPosition\z, #PB_Absolute)
  
  CameraLookAt(*Camera\Camera, NodeX(*Camera\TargetNode), NodeY(*Camera\TargetNode), NodeZ(*Camera\TargetNode))
EndProcedure

Procedure CameraUpdate(*Camera.s_Camera, *CameraPosition.Vector3, *TargetPosition.Vector3)
  Protected V1.Vector3, V2.Vector3
  
  V1\x = (*CameraPosition\x - NodeX(*Camera\CameraNode)) *  *Camera\Tightness
  V1\y = (*CameraPosition\y - NodeY(*Camera\CameraNode)) *  *Camera\Tightness
  v1\z = (*CameraPosition\z - NodeZ(*Camera\CameraNode)) *  *Camera\Tightness
  MoveNode(*Camera\CameraNode, V1\x, V1\y, V1\z)
  
  V2\x = (*TargetPosition\x - NodeX(*Camera\TargetNode)) *  *Camera\Tightness
  V2\y = (*TargetPosition\y - NodeY(*Camera\TargetNode)) *  *Camera\Tightness
  V2\z = (*TargetPosition\z - NodeZ(*Camera\TargetNode)) *  *Camera\Tightness
  MoveNode(*Camera\TargetNode, V2\x, V2\y, V2\z)
  
  CameraLookAt(*Camera\Camera, NodeX(*Camera\TargetNode), NodeY(*Camera\TargetNode), NodeZ(*Camera\TargetNode))
EndProcedure
Dernière modification par comtois le jeu. 01/mai/2014 18:35, 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.
Fred
Site Admin
Messages : 2807
Inscription : mer. 21/janv./2004 11:03

Re: une chenille sur un terrain

Message par Fred »

Excellent la chenille :D
Avatar de l’utilisateur
graph100
Messages : 1318
Inscription : sam. 21/mai/2005 17:50

Re: une chenille sur un terrain

Message par graph100 »

c'est sympa, et c'est un bon exemple de l'utilisation des nodes.

J'vais le regarder de plus près :D

Merci Comtois

j'avoue que quand j'ai vu le titre du post, j'ai pensé à une chenille qui avance en marchant (avec son bout avant et son bout arrière)
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Re: une chenille sur un terrain

Message par comtois »

graph100 a écrit :j'avoue que quand j'ai vu le titre du post, j'ai pensé à une chenille qui avance en marchant (avec son bout avant et son bout arrière)
Exact, c'est plutôt un 'snake'.
c'est sympa, et c'est un bon exemple de l'utilisation des nodes.

J'vais le regarder de plus près :D
les nodes sont la base de tout :)
Il suffit d'attacher un node pour indiquer où doit se placer la caméra, et c'est tout, la caméra se débrouille pour suivre ce node, pas besoin de faire des calculs d'angle.
Dans l'exemple ci-dessus, j'avais ajouté un node pour indiquer où placer l'élément suivant, mais finalement je l'ai supprimé, et voici le code simplifié :

Code : Tout sélectionner

IncludeFile "Screen3DRequester.pb"

Enumeration 
  #ThirdPersonChase  
  #ThirdPersonFixed
  #TopView
EndEnumeration

Enumeration
  #Object_Entity
  #Object_Node
  #Object_Last
EndEnumeration

#Nb = 100
#Size = 6
#Ecart = 1.5 * #Size
#PlayerSpeed = 0.15

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

Structure s_Key
  Left.i
  Right.i
EndStructure

Structure s_Item
  Entity.i
  forward.i 
EndStructure

Structure s_Head
  Entity.i
  LastItem.i
  Key.s_Key
  MainNode.i
  SightNode.i
  CameraNode.i  
  Offset.Vector3 
EndStructure

Structure s_Camera
  Camera.i
  Mode.i
  Tightness.f
  CameraNode.i 
  TargetNode.i
EndStructure    
Structure s_Object
  Position.i
  Locate.i
  Move.i
EndStructure

Macro GetObjectPosition(Position, Object, type)
  If Type = #Object_Node
    Position\x = NodeX(Object)  
    Position\y = NodeY(Object)  
    Position\z = NodeZ(Object)  
  ElseIf Type = #Object_Entity
    Position\x = EntityX(Object)  
    Position\y = EntityY(Object)  
    Position\z = EntityZ(Object)  
  EndIf
  
EndMacro

Macro SetVector3(V, xx, yy, zz)
  V\x = xx
  V\y = yy
  V\z = zz
EndMacro

Macro AddVector3(V, V1, V2)
  V\x = V1\x + V2\x
  V\y = V1\y + V2\y
  V\z = V1\z + V2\z
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

Macro ObjectOnTerrain(p, Object, Type)
  If Type = #Object_Node
    p\x = NodeX(Object)
    p\z = NodeZ(Object)
    p\y = TerrainHeight(0, p\x, p\z) + #Size    
    NodeLocate(Object, p\x, p\y, p\z)
  ElseIf Type = #Object_Entity
    p\x = EntityX(Object)
    p\z = EntityZ(Object)
    p\y = TerrainHeight(0, p\x, p\z) + #Size
    EntityLocate(Object, p\x, p\y, p\z)
  EndIf  
EndMacro

Define camera.s_Camera
Define p.Vector3
Define Head.s_Head
Prototype.f PositionX(Object)
Global NewList Item.s_Item()
Global NewList Chenille.s_Item() 
Global Speed.f 


#CameraSpeed = 1
#TerrainMiniX = 0
#TerrainMiniY = 0
#TerrainMaxiX = 0
#TerrainMaxiY = 0

;-Declare
Declare HandleEntity(*Head.s_Head)
Declare CameraMode(*Camera.s_Camera, *Head.s_Head)
Declare CameraTrack(*Camera.s_Camera, *Head.s_Head)
Declare CameraInstantUpdate(*Camera.s_Camera, *CameraPosition.Vector3, *TargetPosition.Vector3)
Declare CameraUpdate(*Camera.s_Camera, *CameraPosition.Vector3, *TargetPosition.Vector3)
Declare.f Distance(*v1.Vector3, *v2.Vector3)
Declare MoveItem()
Declare TestItem(*Head.s_Head)

Declare InitBlendMaps()
Declare Clamp(*var.float, min.f, max.f)

; OpenGL needs to have CG enabled to work (Linux and OS X have OpenGL by default)
;
CompilerIf #PB_Compiler_OS <> #PB_OS_Windows Or Subsystem("OpenGL")
  Flags = #PB_Engine3D_EnableCG
CompilerEndIf

If InitEngine3D(Flags)
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
  If Screen3DRequester()
    Add3DArchive("Data/Textures/", #PB_3DArchive_FileSystem)
    Add3DArchive("Data/Scripts",#PB_3DArchive_FileSystem)
    Add3DArchive("Data/Textures/nvidia", #PB_3DArchive_FileSystem)
    Add3DArchive("Data/GUI", #PB_3DArchive_FileSystem) 
    Add3DArchive("Data/Packs/desert.zip", #PB_3DArchive_Zip)
    Parse3DScripts()
    
    WorldShadows(#PB_Shadow_Modulative, -1, RGB(127, 127, 127))
    
    ;- Light
    ; 
    light = CreateLight(#PB_Any ,RGB(185, 185, 185), 4000, 1200, 1000, #PB_Light_Directional)
    LightColor(light, RGB(255*0.4, 255*0.4,255*0.4), #PB_Light_SpecularColor) 
    LightDirection(light ,0.55, -0.3, -0.75) 
    AmbientColor(RGB(5, 5, 5))
    
    ; terrain definition
    SetupTerrains(LightID(Light), 3000, #PB_Terrain_NormalMapping)
    ; initialize terrain 
    CreateTerrain(0, 513, 12000, 600, 3, "Terrain04", "Dat")
    ; set all texture will be use when terrrain will be constructed 
    AddTerrainTexture(0,  0, 100, "dirt_grayrocky_diffusespecular.dds",  "dirt_grayrocky_normalheight.dds")
    AddTerrainTexture(0,  1,  30, "grass_green-01_diffusespecular.dds", "grass_green-01_normalheight.dds")
    AddTerrainTexture(0,  2, 200, "growth_weirdfungus-03_diffusespecular.dds", "growth_weirdfungus-03_normalheight.dds")
    
    ;- define terrains
    For ty = #TerrainMiniY To #TerrainMaxiY
      For tx = #TerrainMiniX To #TerrainMaxiX
        imported = DefineTerrainTile(0, tx, ty, "terrain513.png", ty % 2, tx % 2)  
      Next
    Next  
    BuildTerrain(0)  
    
    If imported = #True
      InitBlendMaps() 
      UpdateTerrain(0)
      SaveTerrain(0, #False)
    EndIf  
    
    ; SkyBox
    ;
    SkyBox("desert07.jpg")
    
    ;- Materials
    ;
    CreateMaterial(0, LoadTexture(0, "Wood.jpg"))
    GetScriptMaterial(1, "SphereMap/SphereMappedRustySteel")
    CreateMaterial(2, LoadTexture(2, "Dirt.jpg"))
    GetScriptMaterial(3, "Scene/GroundBlend")
    
    ;- Head
    ;
    CreateSphere(1, #Size)
    
    With Head
      \Entity = CreateEntity(#PB_Any, MeshID(1), MaterialID(1))
      \Key\Left  = #PB_Key_Left
      \Key\Right = #PB_Key_Right
      \Offset\x = 0
      \Offset\y = 50 ; Offset could be needed for FirstPerson
      \Offset\z = 130  
      ; Entity use 3 nodes  
      \MainNode=CreateNode(#PB_Any, 0, #Size, 0) ; Entity position
      \SightNode=CreateNode(#PB_Any, 0, 20, -120) ; For cameraLookAt 
      \CameraNode=CreateNode(#PB_Any, 0, 100, 140) ; Camera position
      
      \LastItem = \Entity
      
      AttachNodeObject(\MainNode, NodeID(\SightNode))
      AttachNodeObject(\MainNode, NodeID(\CameraNode))   
      AttachNodeObject(\MainNode, EntityID(\Entity))
      
      ObjectOnTerrain(p, \MainNode, #Object_Node)
    EndWith
    
    
    ;- Item 
    ;
    For i=1 To #Nb
      AddElement(Item())
      Item()\Entity = CreateEntity(#PB_Any, MeshID(1), MaterialID(1), Random(6000)-3000, #Size, Random(6000)-3000)
      ObjectOnTerrain(p, Item()\Entity, #Object_Entity)
    Next  
    
    ;- Camera
    ;
    CreateCamera(0, 0, 0, 100, 100)
    With Camera  
      \Camera = 0
      \Mode = -1
      \Tightness = 0.01
      ; Camera use 2 nodes
      \CameraNode = CreateNode(#PB_Any, -3000, 700, 0) ; Camera position
      \TargetNode = CreateNode(#PB_Any) ; For cameraLookAt 
      AttachNodeObject(\CameraNode, CameraID(\Camera))
    EndWith  
    
    ;- --- Main loop ----
    Repeat
      Screen3DEvents()
      
      If ExamineKeyboard()
        CameraMode(@Camera, @Head)     
        HandleEntity(@Head)
      EndIf
      
      TestItem(@Head)
      MoveItem()
      
      CameraTrack(@Camera, @Head)
      
      Speed.f = RenderWorld() * #PlayerSpeed 
      
      Screen3DStats()
      FlipBuffers()
      
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
    
    End 
    
  EndIf 
Else
  MessageRequester("Error","Can't initialize engine3D")
EndIf 

Procedure InitBlendMaps()
  minHeight1.f = 70
  fadeDist1.f = 40
  minHeight2.f = 70
  fadeDist2.f = 15    
  For ty = #TerrainMiniY To #TerrainMaxiY
    For tx = #TerrainMiniX To #TerrainMaxiX
      Size = TerrainTileLayerMapSize(0, tx, ty)
      For y = 0 To Size-1
        For x = 0 To Size-1
          Height.f = TerrainTileHeightAtPosition(0, tx, ty, 1, x, y)
          
          val.f = (Height - minHeight1) / fadeDist1
          Clamp(@val, 0, 1)
          SetTerrainTileLayerBlend(0, tx, ty, 1, x, y, val)
          
          val.f = (Height - minHeight2) / fadeDist2
          Clamp(@val, 0, 1)
          SetTerrainTileLayerBlend(0, tx, ty, 2, x, y, val)
        Next
      Next
      UpdateTerrainTileLayerBlend(0, tx, ty, 1)
      UpdateTerrainTileLayerBlend(0, tx, ty, 2)
    Next
  Next  
EndProcedure  

Procedure Clamp(*var.float, min.f, max.f)
  If *var\f < min
    *var\f = min
  ElseIf *var\f > max
    *var\f = max
  EndIf
EndProcedure 


Procedure.f Distance(*v1.Vector3, *v2.Vector3)
  ProcedureReturn Sqr((*v1\x-*v2\x)*(*v1\x-*v2\x)+(*v1\y-*v2\y)*(*v1\y-*v2\y)+(*v1\z-*v2\z)*(*v1\z-*v2\z))
EndProcedure

Procedure TestItem(*Head.s_Head)
  Protected.Vector3 v1, v2, d, p
  
  ForEach Item() 
    
    GetObjectPosition(v1, *Head\Entity, #Object_Entity)
    GetObjectPosition(v2, Item()\Entity, #Object_Entity)
    
    If Distance(@v1, @v2) < 2 * #Size
      AddElement(Chenille())
      Chenille()\Entity = Item()\Entity
      Chenille()\forward = *Head\LastItem 
      *Head\LastItem    = Item()\Entity
      DeleteElement(Item())
    EndIf
    
  Next  
EndProcedure

Procedure MoveItem()
  Protected.Vector3  d, p, v1, v2
  Protected Dist.f
  ForEach Chenille()
    
    GetObjectPosition(v1, Chenille()\Entity, #Object_Entity)
    GetObjectPosition(d, Chenille()\Forward, #Object_Entity)
    Dist = #Ecart - Distance(@v1, @d)  
    
    EntityLookAt(Chenille()\Entity, d\x, d\y, d\z)
    MoveEntity(Chenille()\Entity, 0, 0, Dist, #PB_Local)
    
    ObjectOnTerrain(p, Chenille()\Entity, #Object_Entity)
  Next 
EndProcedure

Procedure HandleEntity( *Head.s_Head)
  Protected.Vector3 PosMain, PosDir , p
  Protected Node
  
  With *Head
    If KeyboardPushed(\Key\Left)
      RotateNode(\MainNode, 0,Speed, 0, #PB_Relative)
    ElseIf KeyboardPushed(\Key\Right)
      RotateNode(\MainNode, 0, -Speed, 0, #PB_Relative)
    EndIf 
    
    MoveNode(\MainNode, 0, 0, -Speed, #PB_Local)
    ObjectOnTerrain(p, \MainNode, #Object_Node)
    
  EndWith   
EndProcedure

Procedure CameraMode(*Camera.s_Camera, *Head.s_Head)
  Protected.Vector3 CameraPosition, TargetPosition, Temp
  
  If KeyboardReleased(#PB_Key_F2)  Or *Camera\Mode = -1
    *Camera\Mode = #ThirdPersonChase
    HideEntity(*Head\Entity, #False)
    GetObjectPosition(CameraPosition, *Head\CameraNode, #Object_Node)
    GetObjectPosition(TargetPosition, *Head\SightNode, #Object_Node)
    CameraInstantUpdate(*Camera, @CameraPosition, @TargetPosition)
    *Camera\Tightness = 0.01
    
  ElseIf KeyboardReleased(#PB_Key_F3)
    *Camera\Mode = #ThirdPersonFixed
    HideEntity(*Head\Entity, #False)
    SetVector3(CameraPosition, 0, TerrainHeight(0, 0, 0) + 200, 0)
    GetObjectPosition(TargetPosition, *Head\SightNode, #Object_Node)
    CameraInstantUpdate(*Camera, @CameraPosition, @TargetPosition)
    *Camera\Tightness = 0.01
    
  ElseIf KeyboardReleased(#PB_Key_F4)  
    *Camera\Mode = #TopView
    HideEntity(*Head\Entity, #True)
    GetObjectPosition(CameraPosition, *Head\LastItem, #Object_Entity)
    CameraPosition\y + 400
    GetObjectPosition(TargetPosition, *Head\SightNode, #Object_Node)
    CameraInstantUpdate(*Camera, @CameraPosition, @TargetPosition)
    *Camera\Tightness = 1   
    
  EndIf 
EndProcedure

Procedure CameraTrack(*Camera.s_Camera, *Head.s_Head)
  Protected.Vector3 CameraPosition, TargetPosition, Temp
  
  Select *Camera\Mode
    Case #ThirdPersonChase
      GetObjectPosition(CameraPosition, *Head\CameraNode, #Object_Node)
      GetObjectPosition(TargetPosition, *Head\SightNode, #Object_Node)
      CameraUpDate(*Camera, @CameraPosition, @TargetPosition)
      
    Case #ThirdPersonFixed
      SetVector3(CameraPosition, 0,  TerrainHeight(0, 0, 0) + 200, 0)
      GetObjectPosition(TargetPosition, *Head\SightNode, #Object_Node)
      CameraUpDate(*Camera, @CameraPosition, @TargetPosition)
      
    Case #TopView
      GetObjectPosition(CameraPosition, *Head\LastItem, #Object_Entity)
      CameraPosition\y + 400
      GetObjectPosition(TargetPosition, *Head\MainNode, #Object_Node)
      CameraUpDate(*Camera, @CameraPosition, @TargetPosition)
      
  EndSelect
EndProcedure

Procedure CameraInstantUpdate(*Camera.s_Camera, *CameraPosition.Vector3, *TargetPosition.Vector3)
  Protected V1.Vector3, V2.Vector3
  
  NodeLocate(*Camera\CameraNode, *CameraPosition\x, *CameraPosition\y, *CameraPosition\z)
  
  NodeLocate(*Camera\TargetNode, *TargetPosition\x, *TargetPosition\y, *TargetPosition\z)
  
  CameraLookAt(*Camera\Camera, NodeX(*Camera\TargetNode), NodeY(*Camera\TargetNode), NodeZ(*Camera\TargetNode)) 
EndProcedure

Procedure CameraUpdate(*Camera.s_Camera, *CameraPosition.Vector3, *TargetPosition.Vector3)
  Protected.Vector3 V1, V2, p 
  
  V1\x = (*CameraPosition\x - NodeX(*Camera\CameraNode)) *  *Camera\Tightness
  V1\y = (*CameraPosition\y - NodeY(*Camera\CameraNode)) *  *Camera\Tightness
  v1\z = (*CameraPosition\z - NodeZ(*Camera\CameraNode)) *  *Camera\Tightness
  MoveNode(*Camera\CameraNode, V1\x, V1\y, V1\z)
  
  If NodeY(*Camera\CameraNode) < TerrainHeight(0, NodeX(*Camera\CameraNode), NodeZ(*Camera\CameraNode)) + #Size
    ObjectOnTerrain(p, *Camera\CameraNode, #Object_Node)
  EndIf  
  
  V2\x = (*TargetPosition\x - NodeX(*Camera\TargetNode)) *  *Camera\Tightness
  V2\y = (*TargetPosition\y - NodeY(*Camera\TargetNode)) *  *Camera\Tightness
  V2\z = (*TargetPosition\z - NodeZ(*Camera\TargetNode)) *  *Camera\Tightness
  MoveNode(*Camera\TargetNode, V2\x, V2\y, V2\z)
  
  CameraLookAt(*Camera\Camera, NodeX(*Camera\TargetNode), NodeY(*Camera\TargetNode), NodeZ(*Camera\TargetNode)) 
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
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: une chenille sur un terrain

Message par djes »

C'est beau :o
Avatar de l’utilisateur
venom
Messages : 3136
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Re: une chenille sur un terrain

Message par venom »

Bonjour,

j'aurais voulu savoir, a chaque foi que je lance ce type de code, PureBasic ne trouve pas "Screen3DRequester.pb" dans le fichier temporaire. (il n'est pas dedans et je souhaiterais éviter si possible.)Je doit toujours lui montrer le chemin. Il y a pas une option dans purebasic pour lui indiquer ou il est ?

Et pareil dans le fichier "Screen3DRequester.pb" il me renvoie une erreur a la ligne : 49 il me dit "Sources\PureBasic3DLogo.png" Hors je n'est pas ce type de fichier j'ai juste 2 .BMP du nom de "PureBasicLogo" Est-ce normale aussi ça ?

D'avance merci






@++
Windows 10 x64, PureBasic 5.73 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Re: une chenille sur un terrain

Message par comtois »

venom a écrit :Bonjour,

j'aurais voulu savoir, a chaque foi que je lance ce type de code, PureBasic ne trouve pas "Screen3DRequester.pb" dans le fichier temporaire. (il n'est pas dedans et je souhaiterais éviter si possible.)Je doit toujours lui montrer le chemin. Il y a pas une option dans purebasic pour lui indiquer ou il est ?

Et pareil dans le fichier "Screen3DRequester.pb" il me renvoie une erreur a la ligne : 49 il me dit "Sources\PureBasic3DLogo.png" Hors je n'est pas ce type de fichier j'ai juste 2 .BMP du nom de "PureBasicLogo" Est-ce normale aussi ça ?

D'avance merci@++
Tu as copié le code dans ton répertoire PureBasic\Examples\3D ?
J'utilise les médias et le fichier Screen3DRequester.pb déjà présents. Et il faut utiliser la version 5.00.
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
venom
Messages : 3136
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Re: une chenille sur un terrain

Message par venom »

comtois a écrit :Tu as copié le code dans ton répertoire PureBasic\Examples\3D ?
En effet ça tourne impeccable. :oops: En faite comme j'utilise l'addon de RX14 pour copier du code il créer un code dans le dossier temporaire d'ou ce message.
Merci c'est pas mal en effet.






@++
Windows 10 x64, PureBasic 5.73 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
Avatar de l’utilisateur
GallyHC
Messages : 1708
Inscription : lun. 17/déc./2007 12:44

Re: une chenille sur un terrain

Message par GallyHC »

Bonjour comtois,

Vraiment sympa ce petit code, me suis bien amusé.

Cordialement,
GallyHC
Configuration : Tower: Windows 10 (Processeur: i7 "x64") (Mémoire: 16Go) (GeForce GTX 760 - 2Go) - PureBasic 5.72 (x86 et x64)
Avatar de l’utilisateur
graph100
Messages : 1318
Inscription : sam. 21/mai/2005 17:50

Re: une chenille sur un terrain

Message par graph100 »

je suis bien embêté parce que sur l'ordi que j'utilise je ne peux pas compiler les exemples 3D (dans la 4.61 non plus).

J'ai un message disant que d3dx9_42.dll manque sur mon pc. J'ai déjà réinstallé DirectX9.c mais bon, dxdiag me dit que j'ai la version 11...
Je vais essayer de trouver un direct X depuis internet.. A priori Purebasic utilise la version 9 c'est ça ?
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Re: une chenille sur un terrain

Message par comtois »

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
graph100
Messages : 1318
Inscription : sam. 21/mai/2005 17:50

Re: une chenille sur un terrain

Message par graph100 »

ça te met à jour toutes les versions ?
parce que j'ai des jeux qui tournent déjà sur mon pc !

[edit] it works. merci comtois
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))
Avatar de l’utilisateur
Ar-S
Messages : 9540
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: une chenille sur un terrain

Message par Ar-S »

Yeah ultra fluide, :) ça poutre :mrgreen:
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
Atlante
Messages : 337
Inscription : mer. 29/juin/2011 18:35
Localisation : Paris

Re: une chenille sur un terrain

Message par Atlante »

Hello,

Pas mal du tout ;)
Par contre je ne sais pas si c'est propre à Pure Basic mais quand je bouge la fenêtre avec le jeu de lancer sur mon deuxième écran alors là c'est le drame : Ecran noir et plantage ensuite.
Modérateur
Config : Intel I5 4670K, Nvidia Geforce GTX 1060, 16go RAM, SSD 256go, DD 2000go
Répondre