linepick under parent ?

Blitz3D Forums/Blitz3D Beginners Area/linepick under parent ?

Prym(Posted 2016) [#1]
- Is 'LinePick x,y,z,dx,dy,dz' is working
in global ( 000 origin point ) ,
or local ( with a parent entity ) ?
- Can dx , dy , dz be oriented with a parent entity ?
- My question is stupid .
I want to make a gravity on a sphere (planet) .
I think I have to use 'alignToVector' with ... But how ?


RemiD(Posted 2016) [#2]
you can use an entity global position as the start point of the linepick and either use a vector of your choice or a vector which takes into account the entity orientation, for this use TFormVector()

TFormVector(0,-10,0,Entity,0)
LinePick(EntityX(Entity,true),EntityY(Entity,true),EntityZ(Entity,true),TFormedX(),TFormedY(),TFormedZ())

will throw a linepick from the global position of the entity and go -10units along the Yaxis of the entity (taking into account its orientation)


but if you want your linepick to start at the entity global position but to go straight downward along the Yaxis of the world (without taking into account the entity orientation), you would rather write :
LinePick(EntityX(Entity,true),EntityY(Entity,true),EntityZ(Entity,true),0,-10,0)



RemiD(Posted 2016) [#3]
double post


Bobysait(Posted 2016) [#4]
For a planet, "Gravity" is a "dynamic vector" which depends on the position of the object on the planet, but it's easy to compute :

The gravity is the vector going from the player to the planet (normalized, then scaled by the gravity factor)

using vectors will simplify the thing :
- Player -> the position of the player
- Planet -> the position of the planet
- Gravity -> the vector corresponding to the gravity ^^
- GRAVITY_FORCE -> the acceleration factor (*)

(*) you can set the gravity force as a constant value if you have a player on the ground (fit to most games, as the world is planar and always on the ground, or at a really negligible distance from the surface of the planet)
If you really need something more accurate, like for a space opera or else, you need to use kind of newton attractors
-> the farther you are from an attractor, the lower the "attraction"
it works the same for a planet -> the radius is just something required to compute the attraction factor
but anytime you go away from a planet, the attraction goes lower and lower (captain obvious \o/)


; the gravity vector can be defined like this
Gravity = (Player-Planet).Normalized() * GRAVITY_FORCE

Then you can compute the direction of the player related to its previous direction and the gravity applied
PlayerAxisZ is the current Z vector (TFormNormal 0,0,1, Player, 0 -> PlayerAxisZX=TFormedX(), PlayerAxisZY = TFOrmedY() etc ...)
PlayerAxisY is the Gravity vector (or more exactly, its opposite)
PlayerAxisY = -Gravity
PlayerAxisX can be computed using the cross Product of Y*Z
-> PlayerAxisXX = PlayerAxisYY * PlayerAxisZZ - PlayerAxisYZ*PlayerAxisZY
-> PlayerAxisXY = PlayerAxisYZ * PlayerAxisZX - PlayerAxisYX*PlayerAxisZZ
-> PlayerAxisXZ = PlayerAxisYX * PlayerAxisZY - PlayerAxisYY*PlayerAxisZX

Finally, you can get the new Z Axis of the player with the cross product of X and Y
-> PlayerAxisZX = PlayerAxisXY * PlayerAxisYZ - PlayerAxisXZ*PlayerAxisYY
-> PlayerAxisZY = PlayerAxisXZ * PlayerAxisYX - PlayerAxisXX*PlayerAxisYZ
-> PlayerAxisZZ = PlayerAxisXX * PlayerAxisYY - PlayerAxisXY*PlayerAxisYX

You can now align the player along the PlayerAxisZ Axis and PlayerAxisY Axis (at this stage, it will probably require some quaternions...)
problem is that AlignToVector function align the 3 axis anytime you use it ... so if you align Y then align Z, you'll lose the Y alignment and Vice-Versa.

So you need to create a quaternion from the Y and Z vectors and extract eulers angles to use with RotateEntity.
or you can create a matrix which is by the way already fully defined by PlayerAxisX,PlayerAxisY,PlayerAxisZ ^^
And same ... extract the euler angles to rotate the player.


here, you'll find some functions extracted from my personnal maths library that will do the job

-> so you can convert a matrix3 to a quaternion and then the extraction of euler angles




To get the euler angles, it's a bit long but it will work (this maths library was created to mimic blitz3d entities, so it's fully compatible with blitz3d)

; Create before the loop !
Local l_Gravity.Vector = NewVector()

Repeat
	[...]
	
	; align the player and set the gravity vector
	AlignToPlanet(Player, Planet, PlayerHeight, l_Gravity)


Until KeyDown(1)
End

Function AlignToPlanet(Player, Planet, PlayerRadius#, pGravity.Vector)
	
	; Get player position
	Local PlayerPos.Vector = NewVector(EntityX(Player,1),EntityY(Player,1),EntityZ(Player,1))
	Local PlanetPos.Vector = NewVector(EntityX(Planet,1),EntityY(Planet,1),EntityZ(Planet,1))
	Local Dist.Vector = VecSub(PlayerPos,PlanetPos)
	Local GRAVITY_FORCE#= PlanetGravity(VecLength(Dist)*2000.0, EARTH_DENSITY) ; use something more accurate here
	Local AxY.Vector = VecSelfNormalize(Dist)
	Local Gravity.Vector = VecScale(AxY, -GRAVITY_FORCE)
	
	; compute the 3 axis
	TFormNormal(0,0,1, Player, 0)
	Local TempZ.Vector = NewVector (TFormedX(), TFormedY(), TFormedZ())
	Local AxX.Vector = VecCross(AxY,TempZ)
	Delete TempZ
	; rebuild Z to be orthogonal to the gravity
	Local AxZ.Vector = VecCross(AxX,AxY)
	
	; at this stage, you can do your linepick
	LinePick PlayerPos\X,PlayerPos\Y,PlayerPos\Z, Gravity\X,Gravity\Y,Gravity\Z, PlayerRadius
	If (PickedEntity() = Planet)
		Local offset# = PlayerRadius+0.01
		PositionEntity Player, PickedX()+AxY\X*offset, PickedY()+AxY\Y*offset, PickedZ()+AxY\Z*offset, 1
	Else
		TranslateEntity Player, Gravity\X, Gravity\Y, Gravity\Z, 1
	EndIf
	
	; Then it's time to align the player
	; create a matrix from the axis
	Local mat3.Matrix3 = Mat3FromVectors(AxX,AxY,AxZ)
	; release the vectors, they won't be used anymore ^^
	Delete AxX
	Delete AxY
	Delete AxZ
	
	; create a quaternion from the matrix
	Local Quat.Quaternion = QuatFromMat3(mat3)
	; free the matrix, it's not required anymore
	FreeMatrix3(mat3)
	
	; finally extract the euler angles from the quaternion rotation.
	Local Euler.Vector = QuatToEuler(Quat)
	; and don't forget to release the quaternion
	Delete Quat
	
	; you can now rotate the player
	RotateEntity Player, Euler\X,Euler\Y,Euler\Z, 1
	
	VecAssign(pGravity, Gravity)
	
	; and remove the instances of the maths types
	Delete Euler
	
	Delete PlayerPos
	Delete PlanetPos
	Delete Gravity
	
End Function




Prym(Posted 2016) [#5]
Merci RemiD ,
C'est juste ce que je cherchais !
TFormVector(0,-10,0,Entity,0)

Merci aussi à BobbySait ,
Mais votre travail semble
d'un trop haut niveau pour moi .
Je le garde pour l'étudier à l'occasion .

Pour ma part ,
je pense avoir simplifié le nombre de calcul ,
en donnant un pivot supplémentaire , pivorbiplayer ,
à chaque entité , dont le joueur ,
et positionné au centre de la planète .

http://www.blitzbasic.com/codearcs/codearcs.php?code=3289

Exemple :
Le déplacement "Z" se fait
avec la rotation "Pitch" du pivot pivorbiplayer .

Merci à tous .
Content de savoir qu'on est pas seuls .

Toutes mes excuses .
Traduction EN au post suivant ...


Prym(Posted 2016) [#6]
Remid thank you,
It's just what I wanted!
TFormVector (0, -10.0, Entity, 0)

Also thank you to BobbySait,
But your work seems
a too high level for me.
I keep it to study it occasionally.

For my part ,
I think I have simplified the number of calculation,
giving an additional pivot pivorbiplayer,
each entity, the player,
and positioned in the center of the planet.

http://www.blitzbasic.com/codearcs/codearcs.php?code=3289

example:
Moving 'Z' is
with rotation 'Pitch' pivot pivorbiplayer.

Thank you all.
Glad to know we are not alone.

Prym