Ooops
November 29, 2020, 05:20:14 PM

Author Topic: Rotate entity according to terrain?  (Read 2427 times)

Offline Yue

  • Hero Member
  • *****
  • Posts: 579
    • YiHosting Your Hosting Free
Rotate entity according to terrain?
« on: February 03, 2018, 10:29:21 PM »
Any suggestions on how to rotate an entity according to the inclination angle of a terrain. What I need is to put some rocks on the ground.

I appreciate the help.

Offline STEVIE G

  • Sr. Member
  • ****
  • Posts: 498
Re: Rotate entity according to terrain?
« Reply #1 on: February 03, 2018, 11:27:01 PM »
Use Aligntovector on the y axis.  The alignment vector will be the surface normal.

Offline Yue

  • Hero Member
  • *****
  • Posts: 579
    • YiHosting Your Hosting Free
Re: Rotate entity according to terrain?
« Reply #2 on: February 03, 2018, 11:33:29 PM »
Use Aligntovector on the y axis.  The alignment vector will be the surface normal.

Thank you, you have some simple examples of how to use that command.

Online RemiD

  • Hero Member
  • *****
  • Posts: 1077
Re: Rotate entity according to terrain?
« Reply #3 on: February 04, 2018, 11:02:59 AM »
A simple approach is to use linepick from above the terrain to below it (so a vertical linepick), then you will be able to get the picked x,y,z and normalx,normaly,normalz and use this to position your rock and to oriente your rock (using aligntovector)
However, be aware that if you use a (blitz3d) ROAM terrain, linepick sometimes fails on it, so you will have to check for that and redo it with a slight offset on x,z, but if you use a mesh terrain, it should work all the time.

example :
Code: [Select]
;assuming that your terrain relief has heights between 0units and 25.5units
;assuming "Picker" is a pivot that represents the startpoint of the linepick
Positionentity(Picker,x,25.5+10,z,true)
Entitypickmode(Terrain,2)
Tformvector(0,-10-25.5-10,0,picker,0) ;create a 3dvector from picker position to straight below it
Linepick(entityx(Picker,true),entityy(Picker,true),entityz(Picker,true),tformedx(),tformedy(),tformedz()) ;throw a linepick from picker position, in the direction of the created vector, with the length of the created vector
If( PickedEntity <> 0 )
 PositionEntity(Thing,PickedX(),PickedY(),PickedZ(),true) ;position the thing at the picked position
 AlignToVector(Thing,PickedNX(),PickedNY(),PickedNZ(),2,1.0) ;oriente the thing depending on the picked triangle normal, using the thing Yaxis
endif
Entitypickmode(Terrain,0)
DualCore AMD E-450, 1646 MHz - 6 Go DDR3 1333 SDRAM - AMD Radeon HD 6320 Graphics (384 Mo) - Windows 7 Home Premium - DirectX 11.0

Offline Yue

  • Hero Member
  • *****
  • Posts: 579
    • YiHosting Your Hosting Free
Re: Rotate entity according to terrain?
« Reply #4 on: February 04, 2018, 11:08:54 AM »
Okay, thank you very much, I'll see the code at work to try it on. The idea is to put a lot of rocks, in this case for every rock I need a linepick?

Online RemiD

  • Hero Member
  • *****
  • Posts: 1077
Re: Rotate entity according to terrain?
« Reply #5 on: February 04, 2018, 11:15:48 AM »
if you want to oriente your rock depending on the triangle normal, yes.

But if you only want position your rock at the y position at x,z, not necessarily :
->if you use a (blitz3d) ROAM terrain, you can use TerrainY(TerrainROAM,x,0,z) to get the y position at x,z
->if you use a mesh terrain, you will need to use linepick to get each picked y position at x,z
DualCore AMD E-450, 1646 MHz - 6 Go DDR3 1333 SDRAM - AMD Radeon HD 6320 Graphics (384 Mo) - Windows 7 Home Premium - DirectX 11.0

Offline Yue

  • Hero Member
  • *****
  • Posts: 579
    • YiHosting Your Hosting Free
Re: Rotate entity according to terrain?
« Reply #6 on: February 05, 2018, 03:10:13 PM »
I understand the concept, but I can't understand how to position the rocks on the ground, I just get here.  I'll try later.

Code: BlitzBasic
  1. Global piedras.TRocas = Null
  2.  
  3. Type TRocas
  4.        
  5.        
  6.         Field id%
  7.         Field roca%[100]
  8.         Field x#, y#, z#
  9.         Field pivot%
  10.        
  11.        
  12.        
  13. End Type
  14.  
  15. Function Init_Rocas.TRocas()
  16.        
  17.         Local self.TRocas = New TRocas
  18.  
  19.        
  20.         For r = 1 To 100
  21.                
  22.                
  23.                 self\roca[r] = CreateCube()
  24.                
  25.         Next
  26.  
  27.        
  28.        
  29.         Return ( self.TRocas )
  30.        
  31.        
  32. End Function
  33.  
  34.  

Online RemiD

  • Hero Member
  • *****
  • Posts: 1077
Re: Rotate entity according to terrain?
« Reply #7 on: February 05, 2018, 05:43:03 PM »
i think that your code is weird, unecessarily complicated, and that your custom type has several useless fiels to achieve what i have explained...

i would store the rocks in a custom type list like this :
Code: [Select]
Type TRock
 field RockRenderer ;the normal details mesh for rendering
 field RockLD ;the low details mesh for collisions/linepicks ("LD" for "low details")
end type

or in a dim array like this :
Code: [Select]
global RocksCount%
dim RockRenderer(100)
dim RockLD(100)

imo, you need to learn to simplify your code, else it will be very complicated to debug when it becomes big (with many lines)

i will post an example in the evening, i am not on my computer right now...
DualCore AMD E-450, 1646 MHz - 6 Go DDR3 1333 SDRAM - AMD Radeon HD 6320 Graphics (384 Mo) - Windows 7 Home Premium - DirectX 11.0

Offline Yue

  • Hero Member
  • *****
  • Posts: 579
    • YiHosting Your Hosting Free
Re: Rotate entity according to terrain?
« Reply #8 on: February 05, 2018, 05:52:54 PM »
I appreciate the help. :

Offline peteswansen

  • Jr. Member
  • **
  • Posts: 57
Re: Rotate entity according to terrain?
« Reply #9 on: February 05, 2018, 07:50:06 PM »
Use this code- defines wheel as terrain contact points.................

you will have to provide your own textures- vehicle model, and a blitz terrain...
Enjoy!  It is a lot of fun...  I use it with my tank combat game I am working on..
found on page 2 of 3D graphics-math Blitz code archives
----------------------------------------------------------------------------------

; based on Mad Jack's Car-terrain vehicle code using independent wheels

Graphics3D 800,800,32,2

Global info1$="Driver"

;Include "../start.bb"

Const GRAVITY#=-.01

Const BODY=1,WHEEL=2,SCENE=3

Collisions BODY,SCENE,2,3
Collisions WHEEL,SCENE,2,3

terr=LoadTerrain( "heightmap_256.bmp" )
ScaleEntity terr,1000/TerrainSize(terr),70,1000/TerrainSize(terr)
TerrainDetail terr,6000,True
TerrainShading terr,True
PositionEntity terr,-500,0,-500
tex=LoadTexture( "terrain-1.jpg" )
ScaleTexture tex,3,3
EntityTexture terr,tex
EntityType terr,SCENE

car=LoadMesh( "car.x" )
ScaleMesh car,1,1,-1
FlipMesh car
FitMesh car,-1.5,-1,-3,3,2,6
PositionEntity car,0,70,0
EntityShininess car,1
EntityType car,BODY

Global wheels[4]

cnt=1
For z#=1.5 To -1.5 Step -3
For x#=-1 To 1 Step 2
   wheels[cnt]=CreateSphere( 8,car )
   EntityAlpha wheels[cnt],.5
   ScaleEntity wheels[cnt],.5,.5,.5
   EntityRadius wheels[cnt],.5
   PositionEntity wheels[cnt],x,0,z
   EntityType wheels[cnt],WHEEL
   cnt=cnt+1
Next
Next

light=CreateLight()
TurnEntity light,45,45,0

target=CreatePivot( car )
PositionEntity target,0,5,-12

camera=CreateCamera()
CameraClsColor camera,0,128,255

speed#=0
x_vel#=0:prev_x#=EntityX( car )
y_vel#=0:prev_y#=EntityY( car )
z_vel#=0:prev_z#=EntityZ( car )

While Not KeyHit(1)

   ;align car to wheels
   zx#=(EntityX( wheels[2],True )+EntityX( wheels[4],True ))/2
   zx=zx-(EntityX( wheels[1],True )+EntityX( wheels[3],True ))/2
   zy#=(EntityY( wheels[2],True )+EntityY( wheels[4],True ))/2
   zy=zy-(EntityY( wheels[1],True )+EntityY( wheels[3],True ))/2
   zz#=(EntityZ( wheels[2],True )+EntityZ( wheels[4],True ))/2
   zz=zz-(EntityZ( wheels[1],True )+EntityZ( wheels[3],True ))/2
   AlignToVector car,zx,zy,zz,1
   
   zx#=(EntityX( wheels[1],True )+EntityX( wheels[2],True ))/2
   zx=zx-(EntityX( wheels[3],True )+EntityX( wheels[4],True ))/2
   zy#=(EntityY( wheels[1],True )+EntityY( wheels[2],True ))/2
   zy=zy-(EntityY( wheels[3],True )+EntityY( wheels[4],True ))/2
   zz#=(EntityZ( wheels[1],True )+EntityZ( wheels[2],True ))/2
   zz=zz-(EntityZ( wheels[3],True )+EntityZ( wheels[4],True ))/2
   AlignToVector car,zx,zy,zz,3
   
   ;calculate car velocities   
   cx#=EntityX( car ):x_vel=cx-prev_x:prev_x=cx
   cy#=EntityY( car ):y_vel=cy-prev_y:prev_y=cy
   cz#=EntityZ( car ):z_vel=cz-prev_z:prev_z=cz
   
   ;resposition wheels
   cnt=1
   For z=1.5 To -1.5 Step -3
   For x=-1 To 1 Step 2
;      PositionEntity wheels[cnt],0,0,0
;      ResetEntity wheels[cnt]
      PositionEntity wheels[cnt],x,-1,z
      cnt=cnt+1
   Next
   Next

   ;move car
   If KeyDown(203) TurnEntity car,0,3,0
   If KeyDown(205) TurnEntity car,0,-3,0
   If EntityCollided( car,SCENE )
      If KeyDown(200)
         speed=speed+.02
         If speed>.7 speed=.7
      Else If KeyDown(208)
         speed=speed-.02
         If speed<-.5 speed=-.5
      Else
         speed=speed*.9
      EndIf
      MoveEntity car,0,0,speed
      TranslateEntity car,0,GRAVITY,0
   Else
      TranslateEntity car,x_vel,y_vel+GRAVITY,z_vel
   EndIf

   ;update camera
   If speed>=0   
      dx#=EntityX( target,True )-EntityX( camera )
      dy#=EntityY( target,True )-EntityY( camera )
      dz#=EntityZ( target,True )-EntityZ( camera )
      TranslateEntity camera,dx*.1,dy*.1,dz*.1
   EndIf
   PointEntity camera,car
   
   UpdateWorld
   RenderWorld
   Flip
Wend

End

Offline Yue

  • Hero Member
  • *****
  • Posts: 579
    • YiHosting Your Hosting Free
Re: Rotate entity according to terrain?
« Reply #10 on: February 05, 2018, 08:10:04 PM »
I have managed to put the rocks in their correct position on the ground, I suppose that alignment will no longer be a problem for me.

This is my code. 

Code: BlitzBasic
  1. ; type Rocks.
  2. ; ---------------------------------------------
  3. ; Proyecto              : TestPace X.
  4. ; Programador   : Yue Rexie.
  5. ; Sitio Web             : http://www.iris3dgames.ga
  6. ; fichero               : TRocas.bb
  7. ; ---------------------------------------------
  8. ; Nota                  : Tipo TRocas
  9. ;                                 Objeto Rocas.
  10. ; ---------------------------------------------
  11.  
  12. Global piedras.TRocas = Null
  13.  
  14.  
  15.  
  16. Type TRocas
  17.        
  18.        
  19.         Field id%
  20.         Field roca%[100]
  21.        
  22.        
  23.        
  24.        
  25. End Type
  26.  
  27.  
  28. Function Init_Rocas.TRocas()
  29.        
  30.         Local self.TRocas = New TRocas
  31.        
  32.        
  33.        
  34.         For r = 1 To 100
  35.                
  36.                
  37.                 self\roca[r] = CreateCube()
  38.                
  39.                
  40.         Next
  41.        
  42.        
  43.        
  44.         Return ( self.TRocas )
  45.        
  46.        
  47. End Function
  48.  
  49. Global tx%
  50. Function SetPositionStones()
  51.        
  52.        
  53.         If tx = False Then
  54.                
  55.                
  56.                 For r = 1 To 100
  57.                        
  58.                        
  59.                         PositionEntity ( piedras\roca[r],Rnd(-100,100), 10,Rnd(-100,100), True  )
  60.                        
  61.                         h = LinePick(EntityX(piedras\roca[r], True),EntityY(piedras\roca[r], True), EntityZ(piedras\roca[r], True), EntityX(piedras\roca[r], False),EntityY(piedras\roca[r], False)-150, EntityZ(piedras\roca[r], False)  )
  62.                        
  63.                        
  64.                         If h  Then
  65.                                
  66.                                 PositionEntity ( piedras\roca[r], EntityX(piedras\roca[r],False ) , PickedY(), EntityZ(piedras\roca[r],False ), True )  
  67.                                
  68.                         End If
  69.                                        
  70.                 Next
  71.                
  72.                        
  73.                 tx = True
  74.                
  75.         End If
  76.  
  77.        
  78. End Function
  79.  
  80.  

Code: BlitzBasic
  1. ; Main File.
  2. piedras.TRocas  = Init_Rocas() ; Init 100 stones.
  3. Repeat
  4.  
  5.         Repeat  :  elapsed = MilliSecs() - time  :  Until elapsed
  6.         ticks = elapsed / period
  7.         tween# = Float(elapsed Mod period) / Float(period)
  8.         For k=1 To ticks
  9.                 time = time + period
  10.                 If k = ticks Then CaptureWorld
  11.                
  12.                         SetPositionStones() ; << Start Position on terrain.
  13.  
  14.  
      


Online RemiD

  • Hero Member
  • *****
  • Posts: 1077
Re: Rotate entity according to terrain?
« Reply #11 on: February 05, 2018, 08:25:54 PM »
Well done, that's the idea, however if you just want to position the rock on the terrain Y at X,Z, and if you use a ROAM terrain (with loadterrain or createterrain), you can use TerrainY(TerrainROAM,X,0,Z), it is faster and more reliable than linepick...

Also in your example you don't rotate the rock depending on the triangle normal of the terrain (using aligntovector), but this is not necessary to do that to position rocks...

DualCore AMD E-450, 1646 MHz - 6 Go DDR3 1333 SDRAM - AMD Radeon HD 6320 Graphics (384 Mo) - Windows 7 Home Premium - DirectX 11.0

Offline Yue

  • Hero Member
  • *****
  • Posts: 579
    • YiHosting Your Hosting Free
Re: Rotate entity according to terrain?
« Reply #12 on: February 05, 2018, 08:40:38 PM »
Okay, I've learned something new. ;) 
In my case I'm going to use LinePick, this is because I have a LoadTerrain and I have a plane that crosses that terrain which is the flat areas of my terrain.



Code: BlitzBasic
  1. Function SetPositionStones()
  2.        
  3.        
  4.         If tx = False Then
  5.                
  6.                
  7.                 For r = 1 To 1000
  8.                        
  9.                        
  10.                         PositionEntity ( piedras\roca[r],Rand(-200,200), 10,Rand(-200,200), True  )
  11.                        
  12. ;                       h = LinePick(EntityX(piedras\roca[r], True),EntityY(piedras\roca[r], True), EntityZ(piedras\roca[r], True), EntityX(piedras\roca[r], False),EntityY(piedras\roca[r], False)-150, EntityZ(piedras\roca[r], False)  )
  13.                         RotateEntity   ( piedras\roca[r], Rand( -45, 45), Rand( -45, 45), Rand( -45, 45) )  
  14.                         ScaleMesh   ( piedras\roca[r], 0.3, 0.3 ,0.3  )
  15.                        
  16.                        
  17.                         terraY = TerrainY(colinas\ente, EntityX(piedras\roca[r], True),EntityY(piedras\roca[r], True), EntityZ(piedras\roca[r], True))
  18.                        
  19. ;                       If h  Then
  20.                                
  21.                         PositionEntity ( piedras\roca[r], EntityX(piedras\roca[r],False ) , terraY, EntityZ(piedras\roca[r],False ), True )
  22.                                
  23. ;                       End If
  24.                        
  25.                        
  26.                        
  27.                 Next
  28.                
  29.                
  30.                
  31.                 tx = True
  32.                
  33.         End If
  34.        
  35.        
  36. End Function
  37.  

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal