Blitz3D bug with EntityPitch/Yaw/Roll() after using ALignToVector()

Started by TomToad, September 17, 2019, 12:27:34

Previous topic - Next topic

TomToad

Blitz3D bug with EntityPitch/Yaw/Roll() after using ALignToVector()

There seems to be a bug after using AlignToVector() on an entity, EntityPitch/Yaw/Roll() commands sometimes give wrong values.  Now I do know that EntityPitch, etc.. will return different values than used in RotateEntity, but those values are equivalent to each other and still orientates the objects properly.  This is different.  Object orientation is wrong.

The example provided shows the error.  The left box is aligned to a random axis.  The right box is orientated to the position of the left by using ENtityPitch()... Most of the time, the boxes align just fine.  Every now and then, the right box is aligned wrong.  I am aligning to the y axis as that seems to produce the problem more often, but it happens on the x and z as well.

I figured out that AlignToVector does not align to an absolute orientation, but rather relative to the entity's previous orientation.  This is understandable as this will allow smooth alignment when using the rate parameter.  Apparently transforming from certain orientations to others causes EntityPitch etc... to mess up.  By orientating the entity to 0,0,0 prior to using AlignToVector seems to remove the problem.
------------------------------------------------
8 rabbits equals 1 rabbyte.

STEVIE G

The test looks ok to me after watching it for a few minutes?

My understanding is that Aligntovector uses quarternions for rotation, as does turnentity, but rotateentity uses euler angles and each axis is performed in a specific order.   Maybe the dodgy result is where the pitch is exactly +- 90 so your getting some gymbal lock where the roll and yaw cannot be properly defined?

Sorry - just some thought - not much help!

Stevie


RemiD

@TomToad>>quick look at your code, and i see that you always align your entity with the Y axis, why ?

RemiD

aligntovector seems to work as expected for me, see :

Graphics3D(640,480,32,2)

Origine = CreatePivot()

Xaxis = CreateArrow() : RotateMesh(Xaxis,0,-90,0) ;Xaxis is red
EntityColor(Xaxis,255,000,000) : EntityFX(Xaxis,1)

Yaxis = CreateArrow() : RotateMesh(Yaxis,-90,0,0) ;Yaxis is green
EntityColor(Yaxis,000,255,000) : EntityFX(Yaxis,1)

Zaxis = CreateArrow() : RotateMesh(Zaxis,0,0,0) ;Zaxis is blue
EntityColor(Zaxis,000,000,255) : EntityFX(Zaxis,1)

Direction = CreateArrow()
EntityColor(Direction,255,255,000) : EntityFX(Direction,1)

Thing = CreateCube()
ScaleMesh(Thing,0.5/2,1.75/2,0.25/2)
PositionMesh(Thing,0,1.75/2,0)

NX# = Rnd(-1.0,+1.0) : NY# = Rnd(-1.0,+1.0) : NZ# = Rnd(-1.0,+1.0)
RotateEntity(Direction,0,0,0,True) ;the fix by TomToad
AlignToVector(Direction,NX,NY,NZ,3,1.0)
RotateEntity(Thing,EntityPitch(Direction,True),EntityYaw(Direction,True),EntityRoll(Direction,True),True)

Camera = CreateCamera()
CameraRange(Camera,0.15,150)

PositionEntity(Camera,3,3,-3,True)
PointEntity(Camera,Origine,0)

Repeat

If( KeyHit(57)=1 )
  C% = Rand(1,6)
  If( C = 1 ) : NX# = +1 : NY# = 0 : NZ# = 0
  Else If( C = 2 ) : NX# = -1 : NY# = 0 : NZ# = 0
  Else If( C = 3 ) : NX# = 0 : NY# = +1 : NZ# = 0
  Else If( C = 4 ) : NX# = 0 : NY# = -1 : NZ# = 0
  Else If( C = 5 ) : NX# = 0 : NY# = 0 : NZ# = +1
  Else If( C = 6 ) : NX# = 0 : NY# = 0 : NZ# = -1
  EndIf
  ;NX# = Rnd(-1.0,+1.0) : NY# = Rnd(-1.0,+1.0) : NZ# = Rnd(-1.0,+1.0)
  RotateEntity(Direction,0,0,0,True) ;the fix by TomToad
  AlignToVector(Direction,NX,NY,NZ,3,1.0)
  RotateEntity(Thing,EntityPitch(Direction,True),EntityYaw(Direction,True),EntityRoll(Direction,True),True)
EndIf

RenderWorld()

Color(255,255,255)
Text(0,0,"Xaxis is red, Yaxis is green, Zaxis is blue, Direction is yellow")
Text(0,16,NX+","+NY+","+NZ)
Text(0,32,RoundFloat(EntityPitch(Direction,True))+","+RoundFloat(EntityYaw(Direction,True))+","+RoundFloat(EntityRoll(Direction,True)))

Flip(1)

Until( KeyDown(1)=1 )

End()

Function RoundFloat#(F#)

FInt% = Int(F*1000)
FRounded# = Float(FInt)/1000
Return FRounded

End Function

Function CreateArrow()

TMesh = CreateMesh()

TPart = CreateCube()
ScaleMesh(TPart,0.03/2,0.03/2,2.0/2)
AddMesh(TPart,TMesh) : FreeEntity(TPart)

TPart = CreateCone(4)
ScaleMesh(TPart,0.2/2,0.2/2,0.2/2) : RotateMesh(TPart,90,0,0) : PositionMesh(TPart,0,0,1.0)
AddMesh(TPart,TMesh) : FreeEntity(TPart)

Return TMesh

End Function

press the space key to choose another main normal / direction ( align towards +X, -X, +Y, -Y, +Z, -Z )

but as you say, the entity pitch, yaw, roll, values looks weird (incorrect)
and if i rotate an entity ("thing") using the pitch, yaw, roll values of the other entity ("direction"), the orientation seems correct except that there seems to be an unwanted rotation (roll) around the Zaxis...

TomToad

I just realized I forgot to remark line 39 out.  That line was the workaround.  You can see the bug if you remark the line.
      ;RotateEntity cube,0,0,0
Quote from: RemiD on October 06, 2019, 07:58:16
@TomToad>>quick look at your code, and i see that you always align your entity with the Y axis, why ?
As you can see from my original post, the bug occurs more often when aligning the y axis, but happens when aligning the x and z axis as well.


------------------------------------------------
8 rabbits equals 1 rabbyte.

RemiD

i have just added

RotateEntity(Direction,0,0,0,True) ;the fix by TomToad

before aligntovector(), as you suggested, and yes it works well too, even in my code... (i have edited it, you can copy paste)


well it works yes and no, if you align an entity towards a direction (along a vector), one orientation is always arbitrary.