November 29, 2020, 05:20:14 PM

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

#### Yue

• Hero Member
• Posts: 579
##### 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.

#### 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.

#### Yue

• Hero Member
• Posts: 579
##### 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.

#### 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 linepickPositionentity(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 itLinepick(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 vectorIf( 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 YaxisendifEntitypickmode(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

#### Yue

• Hero Member
• Posts: 579
##### 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?

#### 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

#### Yue

• Hero Member
• Posts: 579
##### 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.

#### 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

#### Yue

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

#### 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

#### Yue

• Hero Member
• Posts: 579
##### 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.

#### 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

#### Yue

• Hero Member
• Posts: 579
##### 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