SyntaxBomb - Indie Coders

Languages & Coding => Blitz2D, BlitzPlus, Blitz3D => Topic started by: JBR on June 24, 2019, 19:12:28

Title: Elite style movement help
Post by: JBR on June 24, 2019, 19:12:28
Hi,

Left/Right moves around the z-axis but as soon as you do this the up/down around the x-axis does not look right. i.e. it is not up/down on screen.

Has anyone any ideas on how to get the rotation on screen and always up/down on screen as up/down movement.

I've done a Zarch/Virus game before where I combined rotation around the x-axis and then around z-axis and all worked as expected.

Any pointers?

Thanks, Jim.
Title: Re: Elite style movement help
Post by: Dabz on June 25, 2019, 00:12:46
Wasnt Zarch rotation left/right around the y-axis, bank left/right around the z-axis and up/down on the x-axis?

*I'm playing the game in my head now, lol*

Dabz
Title: Re: Elite style movement help
Post by: Qube on June 25, 2019, 06:00:32
Not quite sure what the issue is here but in 3D space if you're wanting true free 3D movement and rotation then using the common euler angles in many engines will cause a problem and you'll end up with what's known as gimbal lock which results in funky 3D rotations. For truly free 3D movement and rotations the mathematical method to use is via quaternion.

As said I'm not quite sure what your issue is and perhaps a code example demonstrating the problem would be helpful.

Quote*I'm playing the game in my head now, lol*
Blast blast blast, yo!! look at those lovely fat square explosions ;D not that I've ever played it :P
Title: Re: Elite style movement help
Post by: 3DzForMe on June 25, 2019, 16:18:27
Gave up on my 3D space invaders meets asteroids due to funky 3D blips, wondering if gimbal lock was the issue now! :o
Title: Re: Elite style movement help
Post by: JBR on June 25, 2019, 19:02:02
Hi, did a search and found https://www.syntaxbomb.com/index.php/topic,3176.msg4165.html#msg4165

Looks good.

Cheers guys, Jim.
Title: Re: Elite style movement help
Post by: RemiD on June 25, 2019, 20:48:32
if you look at the values returned by entitipitch, entityyaw, entityroll, you will realise that you can't really oriente an entity precisely between -180.0 and +180.0 on all axis, sometimes something is messed up...
so usually i forget about the roll and only use pitch and yaw to oriente on all possible orientations...
Title: Re: Elite style movement help
Post by: JBR on June 26, 2019, 22:17:41
https://www.syntaxbomb.com/index.php/topic,3176.msg4165.html#msg4165

When I try and run this code there are 'funny' characters in it which buggers up compiling.

Most often is b*lip where * is like a square with a question mark.

It is on the actual listing so not my error. Help!

Jim
Title: Re: Elite style movement help
Post by: Dabz on June 27, 2019, 06:21:51
Its not you, copy and pasting buggers the formatting up

Dabz
Title: Re: Elite style movement help
Post by: Krischan on June 28, 2019, 09:51:32
On request here again the working code with executables in the attachment, looks as if something went wrong with the transfer of the code archive (the Blitz3D Types are incorrect).

The original code is still working:
Elite Style Scanner: http://www.mojolabs.nz/codearcs.php?code=2773 (http://www.mojolabs.nz/codearcs.php?code=2773)
Elite Name Generator: http://www.mojolabs.nz/codearcs.php?code=2770 (http://www.mojolabs.nz/codearcs.php?code=2770)

Oh, and for spaceship movement I've written this code years ago:

Code (blitzbasic) Select
AppTitle "Infinite Starfield"

Graphics3D 800,600,32,2

Global SCALEX# = 2.0 ; starfield scale X
Global SCALEY# = 2.0 ; starfield scale Y
Global SCALEZ# = 2.0 ; starfield scale Z

Global TurnSpeed# = 4.0 ; cam turn speed
Global RollSpeed# = 0.5 ; cam roll speed
Global CameraSpeed# = 0.01 ; cam move speed

Global WIDTH% = GraphicsWidth() ; grab screen width
Global HEIGHT% = GraphicsHeight() ; grab screen height
Global TIMER% = CreateTimer(60) ; timer

Type star

Field col%
Field x#,y#,z#

End Type

; camera
Global cam=CreateCamera()
CameraRange cam,0.01,10
PositionEntity cam,0,0,0

; starfield mesh
Global starfield=CreateMesh()
Global surf=CreateSurface(starfield)
Global star=CreateQuad()
EntityTexture starfield,CreateStarTexture()
EntityFX starfield,1+2+32
EntityBlend starfield,3

; add stars to starfield
AddStars(20000,0.001,0.005)

MoveMouse WIDTH/2,HEIGHT/2

; main loop
While Not KeyHit(1)

; camera movement
Movement(cam)

; update stars
UpdateStarfield(cam,2,1)

RenderWorld()

WaitTimer TIMER

Flip 0

Wend

End

; create a simple star texture
Function CreateStarTexture(size%=256,flags%=3)

Local tex%=CreateTexture(size,size,flags)
Local tb%=TextureBuffer(tex)

Local i#,j%,col%,rgb%

SetBuffer tb
LockBuffer tb

For j=0 To 255

col=255-j
If col>255 Then col=255
rgb=col*$1000000+col*$10000+col*$100+col

For i=0 To 360 Step 0.1

WritePixelFast (size/2)+(Sin(i)*(j*size/512)),(size/2)+(Cos(i)*(j*size/512)),rgb,tb

Next

Next

UnlockBuffer tb
SetBuffer BackBuffer()

Return tex

End Function

; rebuild starfield mesh
Function UpdateStarfield(parent%,maxdist#=2.0,fade%=False)

Local s.star,px#,py#,pz#,d#,a#

ClearSurface(surf)

For s.star = Each star

; calc star position
px=EntityX(parent)-s\x
py=EntityY(parent)-s\y
pz=EntityZ(parent)-s\z

; check if star must be moved
If px<-SCALEX Then s\x=s\x-(SCALEX*2)
If px>+SCALEX Then s\x=s\x+(SCALEX*2)
If py<-SCALEY Then s\y=s\y-(SCALEY*2)
If py>+SCALEY Then s\y=s\y+(SCALEY*2)
If pz<-SCALEZ Then s\z=s\z-(SCALEZ*2)
If pz>+SCALEZ Then s\z=s\z+(SCALEZ*2)

; reposition star
PositionEntity star,s\x,s\y,s\z

; star is visible?
If EntityInView(star,cam) Then

; get distance
d=EntityDistance(star,cam)

; check if not to far away
If d<maxdist Then

; align star to cam
PointEntity star,cam

; add alpha
a=1.0 : If fade Then a=Normalize(d,maxdist*0.5,maxdist,1,0)

; add star to starfield again
AddToSurface(star,surf,starfield,s\col,s\col,s\col,a)

EndIf

EndIf

Next

End Function

; add stars to starfield mesh
Function AddStars(amount%=1,min#=0.01,max#=0.02)

Local i%,s.star,size#

For i=1 To amount

s.star = New star

size#=Rnd(min,max)

s\col=Rand(64,255)
s\x=Rnd(-SCALEX,SCALEX)
s\y=Rnd(-SCALEY,SCALEY)
s\z=Rnd(-SCALEZ,SCALEZ)

PositionEntity(star,s\x,s\y,s\z,1)
ScaleEntity star,size,size,size
AddToSurface(star,surf,starfield,255,255,255,1)

Next

End Function

; simple spaceship freeflight
Function Movement(cam%,sensitivity#=1.0)

Local roll#,cx#,cz#,tx#,ty#

cx=(KeyDown(205)-KeyDown(203))*CameraSpeed
cz=(KeyDown(200)-KeyDown(208))*CameraSpeed
roll=(MouseDown(2)-MouseDown(1))*RollSpeed

tx=Normalize(MouseX(),0,WIDTH , 1,-1)
ty=Normalize(MouseY(),0,HEIGHT,-1, 1)

If ty<0 Then ty=(Abs(ty)^sensitivity)*-1 Else ty=ty^sensitivity
If tx<0 Then tx=(Abs(tx)^sensitivity)*-1 Else tx=tx^sensitivity

TurnEntity cam,ty*TurnSpeed,tx*TurnSpeed,roll*TurnSpeed
MoveEntity cam,cx,0,cz

End Function

; normalize a value
Function Normalize#(value#=128.0,value_min#=0.0,value_max#=255.0,norm_min#=0.0,norm_max#=1.0)

Return ((value-value_min)/(value_max-value_min))*(norm_max-norm_min)+norm_min

End Function

; add a mesh to another mesh's surface
Function AddToSurface(mesh,surf,singlesurfaceentity,r%,g%,b%,a#)

Local vert%[2],vr%[2],vg%[2],vb%[2],va#[2]
Local surface%,oldvert%,i%,i2%

surface = GetSurface(mesh,1)

For i = 0 To CountTriangles(surface)-1

For i2 = 0 To 2

oldvert = TriangleVertex(surface,i,i2)

vr[i2]=r
vg[i2]=g
vb[i2]=b
va[i2]=a

TFormPoint VertexX(surface,oldvert),VertexY(surface,oldvert),VertexZ(surface,oldvert), mesh,singlesurfaceentity
vert[i2] = AddVertex(surf,TFormedX(),TFormedY(),TFormedZ(),VertexU(surface,oldvert),VertexV(surface,oldvert))
VertexColor surf,vert[i2],r,g,b,a

Next

AddTriangle(surf,vert[0],vert[1],vert[2])

Next

End Function

; create a quad
Function CreateQuad(r%=255,g%=255,b%=255,a#=1.0)

Local mesh%,surf%,v1%,v2%,v3%,v4%

mesh=CreateMesh()
surf=CreateSurface(mesh)

v1=AddVertex(surf,-1,1,0,1,0)
v2=AddVertex(surf,1,1,0,0,0)
v3=AddVertex(surf,-1,-1,0,1,1)
v4=AddVertex(surf,1,-1,0,0,1)

VertexColor surf,v1,r,g,b,a
VertexColor surf,v3,r,g,b,a
VertexColor surf,v2,r,g,b,a
VertexColor surf,v4,r,g,b,a

AddTriangle(surf,0,1,2)
AddTriangle(surf,3,2,1)

FlipMesh mesh

Return mesh

End Function
Title: Re: Elite style movement help
Post by: JBR on June 28, 2019, 19:23:55
Thankyou Krischan you are a diamond.

Jim.

Title: Re: Elite style movement help
Post by: 3DzForMe on June 28, 2019, 21:29:00
Krishan, very generous what a star  ;D. I should be packing to go on holiday tomorrow, I can feel a go at Blitz3D coming on though....
Title: Re: Elite style movement help
Post by: JBR on June 28, 2019, 22:17:19
I tried just the basic movement code with BMax and miniB3D and it performs not as expected.

I think they handle TurnEntity different.

Jim
Title: Re: Elite style movement help
Post by: Krischan on June 28, 2019, 22:21:07
Try the first Code (MiniB3D) in this thread in Blitzmax+MiniB3D, this is my latest spacegame movement code with Quaternion rotation. But I'm still not sure what you're looking for.

https://www.syntaxbomb.com/index.php/topic,5159.0.html (https://www.syntaxbomb.com/index.php/topic,5159.0.html)
Title: Re: Elite style movement help
Post by: JBR on June 29, 2019, 20:27:04
Hi Krischan,

Thanks again.

I think I'll be able to use a lot of your code, if that's ok.

TGlobal.EnableStates() in the End2D() gives the error Duplicate identifier 'tglobal' found in module 'm_minib3d' and module 'brl.reflection'.

I've just edited it out and everything works great. Not up on my GL stuff so hopefully no harm done.

My intention is to write an Elite style game, hopefully!

Jim.