align an entity to a terrian?

Blitz3D Forums/Blitz3D Beginners Area/align an entity to a terrian?

Cubed Inc.(Posted 2010) [#1]
For my little game, I'm trying to make it so that character "aligns" to the terrian. It sounds kind of confusing,but think of a racing game, when the car is on a bumpy terrain. The car "bumps" with the terrain, rather than just staying still. can someone help me out with this? please reply.later.


Charrua(Posted 2010) [#2]
Hi, try something like:
(this is a fragment of code)

;set graphics mode, camera, light, etc..
;load a terrain.. Terr = loadterrain(....)
;give it a pickmode 

EntityPickMode Terr,2


Temp=CreateCube()


While Not(KeyHit(1))

	RenderWorld
	
	x=MouseX()
	y=MouseY()
	Line x-5,y-5,x+5,y+5
	Line x-5,y+5,x+5,y-5
	
	CameraPick(Camera,MouseX(),MouseY())
	If PickedEntity() Then
		PositionEntity Temp,PickedX#(),PickedY#(),PickedZ#(),1
		AlignToVector Temp,PickedNX#(),PickedNY#(),PickedNZ#(),2
	End If
		
	Flip

Wend


there are other picking commands you may use.

hope that help

Juan


Oiduts Studios(Posted 2010) [#3]
Well if your talking about aligning with blitz terrains (height-map terrains) then you can use the TerrainY command. Or if you are using mesh terrains then you can use the Linepick command and point the pick downwards so you can get y-coordinate under the players feat and position the player there.


Matty(Posted 2010) [#4]
The "driver" sample in the "mak" folder of your samples directory that came with blitz3d should help with this, there are also some code archives such as:

http://blitzbasic.com/codearcs/codearcs.php?code=67


Cubed Inc.(Posted 2010) [#5]
Charrua
It's a nice code, put the alignment works with the mouse and it gets VERY glitchy.
Here's the code if you want to know what I mean better.
;Lego Island Rescue;
Graphics3D 1366,768,32,1
SetBuffer BackBuffer ()

Const GRAVITY#=-1.5

Const TYPE_PLAYER=1,TYPE_TARGET=3,TYPE_WATER=3
Const TYPE_SCENERY=10,TYPE_TERRAIN=11

Collisions TYPE_PLAYER,TYPE_TERRAIN,2,3
Collisions TYPE_PLAYER,TYPE_SCENERY,2,2
Collisions TYPE_TARGET,TYPE_TERRAIN,2,2
Collisions TYPE_TARGET,TYPE_SCENERY,2,2

;Lego Island;
island=LoadMesh("media/tower.b3d")
islandtex=LoadTexture("media/Untitled2.png",256)
PositionEntity island,0,-150,60
ScaleEntity island,4,4,4
EntityFX island,0
EntityType island,TYPE_TERRAIN

;Lego Island;
island2=LoadMesh("media/tower.b3d")
islandtex2=LoadTexture("media/Untitled2.png",256)
PositionEntity island2,0,-150,5360
ScaleEntity island2,4,4,4
EntityFX island2,0
EntityType island2,TYPE_TERRAIN

;player;
player=CreateCube()
PositionEntity player,0,100,0
ScaleEntity player,4,4,4
EntityType player,TYPE_PLAYER

;water;
water = CreatePlane ()
h20 = LoadTexture ("media/water_tex.jpg",256)
ScaleTexture h20, 200, 200
EntityTexture water, h20
EntityAlpha water, 0.4
PositionEntity water,0,-140,60
EntityFX water,1
EntityType water,TYPE_TERRAIN

;light;
light=CreateLight()

;camera (AKA the player);
camera=CreateCamera(target)
EntityRadius camera,30
PositionEntity camera,0,100,-50
MoveEntity camera,0,3,-50
EntityType camera,TYPE_TARGET

;target;
target=CreatePivot( player )
MoveEntity Target,0,3,-50

;sky/fog/range;
CameraFogMode camera,1
CameraFogColor camera,200, 220, 255
CameraRange camera, 1,5500
CameraFogRange camera,1,2500-10
CameraClsColor camera,200,220,255

EntityPickMode island,2


;move camera;
While Not KeyDown(1)

x=MouseX()
y=MouseY()
Line x-5,y-5,x+5,y+5
Line x-5,y+5,x+5,y-5


If PickedEntity() Then
PositionEntity player,PickedX#(),PickedY#(),PickedZ#(),1
AlignToVector player,PickedNX#(),PickedNY#(),PickedNZ#(),2
End If


TranslateEntity player,0,GRAVITY,0
TranslateEntity camera,0,GRAVITY,0
If KeyDown(200)
MoveEntity player,0,0,2
EndIf
If KeyDown(208)
MoveEntity player,0,0,-2
EndIf
If KeyDown(203)
TurnEntity player,0,3,0
EndIf
If KeyDown(205)
TurnEntity player,0,-3,0
EndIf
If Not KeyDown(1)
dx#=EntityX( target,True )-EntityX( camera )
dy#=EntityY( target,True )-EntityY( camera )
dz#=EntityZ( target,True )-EntityZ( camera )
TranslateEntity camera,dx*.2,dy*.1,dz*.2
EndIf
PointEntity camera,player



UpdateWorld
RenderWorld
Flip
Wend
End


Charrua(Posted 2010) [#6]
as other sugested, you can do a line pick, the thing is, that if you do some pick (mouse with camera pick is easy to implement) then you get the x,y,z and the normal of the surface picked on that point. The yaw should be corrected, because a normal is that, a perpendicular to the surface but, probably not correctly oriented. I sugest the driver demo pointed above too, i dont remembered that one.

btw, enclose the code with: (code) .... (/code)
wiht square brackets (see forum codes)

Juan


Cubed Inc.(Posted 2010) [#7]
I actually am trying to make my own code. This is it so far, but it says that the index is out of range! I know that it probably won't do anything to help my problem, but can someone help me out with my code?

;Lego Island Rescue;
Graphics3D 1366,768,32,1
SetBuffer BackBuffer ()

Const GRAVITY#=-1.5

Const TYPE_PLAYER=1,TYPE_TARGET=3,TYPE_WATER=3
Const TYPE_SCENERY=10,TYPE_TERRAIN=11

Collisions TYPE_PLAYER,TYPE_TERRAIN,2,3
Collisions TYPE_PLAYER,TYPE_SCENERY,2,2
Collisions TYPE_TARGET,TYPE_TERRAIN,2,2
Collisions TYPE_TARGET,TYPE_SCENERY,2,2

;Lego Island;
island=LoadMesh("media/tower.b3d")
islandtex=LoadTexture("media/Untitled2.png",256)
PositionEntity island,0,-150,60
ScaleEntity island,4,4,4
EntityFX island,0
EntityType island,TYPE_TERRAIN

;Lego Island;
island2=LoadMesh("media/tower.b3d")
islandtex2=LoadTexture("media/Untitled2.png",256)
PositionEntity island2,0,-150,5360
ScaleEntity island2,4,4,4
EntityFX island2,0
EntityType island2,TYPE_TERRAIN

;player;
player=CreateCube()
PositionEntity player,0,100,0
ScaleEntity player,4,4,4
EntityType player,TYPE_PLAYER

;water;
water = CreatePlane ()
h20 = LoadTexture ("media/water_tex.jpg",256)
ScaleTexture h20, 200, 200
EntityTexture water, h20
EntityAlpha water, 0.4
PositionEntity water,0,-140,60
EntityFX water,1
EntityType water,TYPE_TERRAIN

;light;
light=CreateLight()

;camera (AKA the player);
camera=CreateCamera(target)
EntityRadius camera,30
PositionEntity camera,0,100,-50
MoveEntity camera,0,3,-50
EntityType camera,TYPE_TARGET

;target;
target=CreatePivot( player )
MoveEntity Target,0,3,-50

;sky/fog/range;
CameraFogMode camera,1
CameraFogColor camera,200, 220, 255
CameraRange camera, 1,5500
CameraFogRange camera,1,2500-10
CameraClsColor camera,200,220,255

;my failed alignment code;
islandx=CollisionX( island,1 )
islandy=CollisionY( island,1 )
islandz=CollisionZ( island,1 )



;move camera;
While Not KeyDown(1)
;====where the failed alignment happens=======;
AlignToVector player,islandx,islandy,islandz,2
;=============================================;
TranslateEntity player,0,GRAVITY,0

TranslateEntity camera,0,GRAVITY,0
If KeyDown(200)
MoveEntity player,0,0,2
EndIf
If KeyDown(208)
MoveEntity player,0,0,-2
EndIf
If KeyDown(203)
TurnEntity player,0,3,0
EndIf
If KeyDown(205)
TurnEntity player,0,-3,0
EndIf
If Not KeyDown(1)
dx#=EntityX( target,True )-EntityX( camera )
dy#=EntityY( target,True )-EntityY( camera )
dz#=EntityZ( target,True )-EntityZ( camera )
TranslateEntity camera,dx*.2,dy*.1,dz*.2
EndIf
PointEntity camera,player



UpdateWorld
RenderWorld
Flip
Wend
End


Charrua(Posted 2010) [#8]
hi

CollisionX, Y and Z are 3d cords, and should be used to position an entity.
If you want to align to a vector, you should use CollisionNX, NY, NZ, these are quantities from 0.. to 1 and they are used for vetors.

CollisisonX, Y and Z tells the world coords of the collision.
CollisisonNX, NY and NZ tells the normal (a perpendicular to) the surface collided. They are different thigs.

The normal may be used to know the direction for a bouncing ball or in your case the direction of a stand up player in the terrain.

Remember that, the terrain seems to be smooth but it isn't and from one Surface (triangle) to the next, the diference in orientation should be noticeable if you align to the normal. I supose you may have to smooth the transitions from one vector to the next in some way.

Juan


Cubed Inc.(Posted 2010) [#9]
Charrua
Thanks for the explaination, it really cleared things up, but when I try to run my code, no matter what integer or floating integer I use, it says that the index was out of range. I checked the Blitz3d manual ( both on the website and in real life )and it never really me anything. Can you help me out?


Charrua(Posted 2010) [#10]
hi

you place your player and your terrain, but you don't know if their collided. You asume that and call CollisionX(entity,index) if there are no collisions, index surely will be out of range. You have to CountCollisions

say, let Gravity do their job, Count for collisions (one day the player will land) and in this moment you can get CollisionX, Y and Z
from the help!:

"CollisionX# ( entity,index )
Parameters
entity - entity handle
index - index of collision

Description
Returns the world x coordinate of a particular collision.

Index should be in the range 1...CountCollisions( entity ) inclusive.
"

in your mai loop test: if CountCollisions(island)<> 0 then

and if it's true, get CollisionX, Y, Z, do whatever, but remember that x,y,z are for position, use CollisionNX, NY, NZ for vetor alignement.


Juan


Cubed Inc.(Posted 2010) [#11]
Charrua
The code doesn't get that annoying out of range message anymore, but the player still doesn't align with the island. Do you think that my code was pretty much useless from the start? Heres the fixed but still failed version of my code:
;Lego Island Rescue;
Graphics3D 1366,768,32,1
SetBuffer BackBuffer ()

Const GRAVITY#=-1.5

Const TYPE_PLAYER=1,TYPE_TARGET=3,TYPE_WATER=3
Const TYPE_SCENERY=10,TYPE_TERRAIN=11

Collisions TYPE_PLAYER,TYPE_TERRAIN,2,3
Collisions TYPE_PLAYER,TYPE_SCENERY,2,2
Collisions TYPE_TARGET,TYPE_TERRAIN,2,2
Collisions TYPE_TARGET,TYPE_SCENERY,2,2

;Lego Island;
island=LoadMesh("media/tower.b3d")
islandtex=LoadTexture("media/Untitled2.png",256)
PositionEntity island,0,-150,60
ScaleEntity island,4,4,4
EntityFX island,0
EntityType island,TYPE_TERRAIN

;Lego Island;
island2=LoadMesh("media/tower.b3d")
islandtex2=LoadTexture("media/Untitled2.png",256)
PositionEntity island2,0,-150,5360
ScaleEntity island2,4,4,4
EntityFX island2,0
EntityType island2,TYPE_TERRAIN

;player;
player=CreateCube()
PositionEntity player,0,100,0
ScaleEntity player,4,4,4
EntityType player,TYPE_PLAYER

;water;
water = CreatePlane ()
h20 = LoadTexture ("media/water_tex.jpg",256)
ScaleTexture h20, 200, 200
EntityTexture water, h20
EntityAlpha water, 0.4
PositionEntity water,0,-140,60
EntityFX water,1
EntityType water,TYPE_TERRAIN

;light;
light=CreateLight()

;camera (AKA the player);
camera=CreateCamera(target)
EntityRadius camera,30
PositionEntity camera,0,100,-50
MoveEntity camera,0,3,-50
EntityType camera,TYPE_TARGET

;target;
target=CreatePivot( player )
MoveEntity Target,0,3,-50

;sky/fog/range;
CameraFogMode camera,1
CameraFogColor camera,200, 220, 255
CameraRange camera, 1,5500
CameraFogRange camera,1,2500-10
CameraClsColor camera,200,220,255

If CountCollisions(island)<> 0 Then
;my failed alignment code;
islandx=CollisionNX( island,1 )
islandy=CollisionNY( island,1 )
islandz=CollisionNZ( island,1 )
EndIf

;move camera;
While Not KeyDown(1)
;====where the failed alignment happens=======;
AlignToVector player,islandx,islandy,islandz,2
;=============================================;

TranslateEntity player,0,GRAVITY,0
TranslateEntity camera,0,GRAVITY,0
If KeyDown(200)
MoveEntity player,0,0,2
EndIf
If KeyDown(208)
MoveEntity player,0,0,-2
EndIf
If KeyDown(203)
TurnEntity player,0,3,0
EndIf
If KeyDown(205)
TurnEntity player,0,-3,0
EndIf
If Not KeyDown(1)
dx#=EntityX( target,True )-EntityX( camera )
dy#=EntityY( target,True )-EntityY( camera )
dz#=EntityZ( target,True )-EntityZ( camera )
TranslateEntity camera,dx*.2,dy*.1,dz*.2
EndIf
PointEntity camera,player



UpdateWorld
RenderWorld
Flip
Wend
End


Charrua(Posted 2010) [#12]
i didn't test it, but, let me explain better.

Gravity pull's the player down a little each While... EnWhile main loop.

before entering, there will be no collisions (if the player is high enough from the terrain). Inside the main loop, some day ( many frames ahead in time) the player will land.
You have to test, each loop for Player - Island collision, and use the collision information: CollisionNX, NY, NZ to do the allignement part.

i don't thing that it's uselees, we start from an idea, test it and if it works, it's OK. Its better a small idea working that some better ones not coded, isn't it?

Juan


Charrua(Posted 2010) [#13]
again

first, you define the camera as child of target, but you define target before.

try this in the main loop, and be carefull wiht the player-pivot-camera relationships. I think you have to start with a non moveable camera seen the centre, till you are sure that the cube alignement work.

While Not KeyDown(1)
	If CountCollisions(island)<> 0 Then
		islandx=CollisionNX( island,1 )
		islandy=CollisionNY( island,1 )
		islandz=CollisionNZ( island,1 )
		AlignToVector player,islandx,islandy,islandz,2
	EndIf
	
	;rest of you code
	UpdateWorld

	RenderWorld

	Flip

Wend


juan


Cubed Inc.(Posted 2010) [#14]
Charrua
well, I guess it is a good start, but I don't think that I know enough about this kind of stuff to actually make satisfactional results. You seem to know more about this than I do. In your opinion, what would be the easiest way of doing this alignment tecniuque?


Cubed Inc.(Posted 2010) [#15]
Charrua
Ignore what I wrote above this. I guess that we posted at the same time and my post got on the forums before your's did:) It actually works! But I have just one last question. How do I make it so that when the player isn't colliding with the island, it stays flat?


Charrua(Posted 2010) [#16]
last?
don't belive you, are you planning to stop programming?

align the player with a fixed vector, pointing to where you want.
Do as if it where colliding wiht a horizontalplane.
AlingnToVector Player, 0, 1, 0, 2

try the last and ommited parameter of this alignment command, to smooth transitions.


something like:
smooth=True

While Not( KeyHit(1))
	
	If KeyHit(57) Then smooth = Not(smooth)	;press space to turn on/off smooth
	
	If CountCollisions(island)<> 0 Then
		;my failed alignment code;
		islandx=CollisionNX( island,1 )
		islandy=CollisionNY( island,1 )
		islandz=CollisionNZ( island,1 )
		If smooth Then
			AlignToVector player,islandx,islandy,islandz,2,0.1	;last parameter = .1
		Else
			AlignToVector player,islandx,islandy,islandz,2	;last parameter ommited: Default=1 = no smooth
		End If
	Else
		;if not colliding, then align to a vertical vector: 0,1,0
		If smooth Then
			AlignToVector player, 0, 1, 0, 2, 0.1
		Else
			AlignToVector  player, 0, 1, 0, 2
		End If
	EndIf

	;rest of your code

	RenderWorld

	Flip

Wend


Juan


Cubed Inc.(Posted 2010) [#17]
Charrua
Stop programming? I just started programming! Why would I stop? This is my last post on THIS topic:) The code works like a charm. thanks.