Physics - Airplane

Everything related to 3D programming
User avatar
pf shadoko
Enthusiast
Enthusiast
Posts: 280
Joined: Thu Jul 09, 2015 9:07 am

Physics - Airplane

Post by pf shadoko »

In the "low-cost simulator" series, the airplane

Code: Select all

;Physics - airplane - Pf Shadoko - 2019

EnableExplicit

Structure Vector3
  x.f
  y.f
  z.f
EndStructure

Structure PB_MeshVertexV  
  p.vector3
  n.vector3
  t.vector3
  u.f
  v.f
  color.l
EndStructure

Macro vec3d(v,vx,vy,vz)
  v\x=vx
  v\y=vy
  v\z=vz
EndMacro

Macro sub3D(p,p1,p2)
  p\x=p1\x-p2\x
  p\y=p1\y-p2\y
  p\z=p1\z-p2\z
EndMacro

Macro mul3d(p1,v)
  p1\x*(v)
  p1\y*(v)
  p1\z*(v)
EndMacro

Procedure.f lng3D(*v.Vector3)
  ProcedureReturn Sqr(*V\x * *V\x + *V\y * *V\y + *V\z * *V\z)
EndProcedure

Procedure.f Pscalaire3d(*p.vector3,*q.vector3)
  ProcedureReturn *p\x * *q\x + *p\y * *q\y + *p\z * *q\z 
EndProcedure

Macro getv(p)
  p\x = GetX()
  p\y = GetY()
  p\z = GetZ()
EndMacro

Procedure localtoworld(oid.l ,*p.vector3)
  ConvertLocalToWorldPosition(oid,*p\x,*p\y,*p\z)
  getv(*p)
EndProcedure

Procedure.f POM(v.f)
  ProcedureReturn (Random(v*1000)-v*500)/500
EndProcedure

Procedure perlinarray2d(Array pa.f(2),rnd,periode,amplitude.f=1)
  Protected i,ii,dx=ArraySize(pa(),1),ddx=dx/periode,
            j,jj,dy=ArraySize(pa(),2),ddy=dy/periode
  Protected.f x,y,y0,y1,wx,wy
  
  RandomSeed(rnd)
  Dim t.f(ddx+1,ddy+1)
  For i=0 To ddx:For j=0 To ddy:t(i,j)=pom(amplitude):Next:Next
  For i=0 To ddx+1:t(i,ddy+1)=t(i,0):Next
  For j=0 To ddy+1:t(ddx+1,j)=t(0,j):Next
  
  For jj=0 To ddy
    For ii=0 To ddx
      For i=0 To periode-1
        x=i/periode
        wx=x*x*(3-2*x)
        For j=0 To periode-1
          y0=t(ii+1,jj  )*wx+t(ii,jj  )*(1-wx)
          y1=t(ii+1,jj+1)*wx+t(ii,jj+1)*(1-wx)
          y=j/periode
          wy=y*y*(3-2*y)
          pa(ii*periode+i,jj*periode+j)=y1*wy+y0*(1-wy)
        Next
      Next
    Next
  Next
EndProcedure

Procedure matiere(num,dx,dy,c1,c2, brillance=$888888,alpha=0,scale.f=1)
  CreateTexture(num,dx,dy)
  StartDrawing(TextureOutput(num))
  If alpha:DrawingMode(#PB_2DDrawing_AllChannels):EndIf
  Box(0,0,dx,dy,c2)
  Box(2,2,dx-4,dy-4,c1) 
  StopDrawing()
  CreateMaterial(num, TextureID(num))
  MaterialFilteringMode(num,#PB_Material_Anisotropic,4)
  ScaleMaterial(num,scale,scale)
  If brillance:SetMaterialColor(num, #PB_Material_SpecularColor, brillance):MaterialShininess(num, 40):EndIf
  If alpha:MaterialBlendingMode(num,#PB_Material_AlphaBlend):EndIf
EndProcedure

Procedure AddMesh(mesho,Mesh,mat, NewX.f=0 , NewY.f=0, NewZ.f=0, ScaleX.f=1, ScaleY.f=1, ScaleZ.f=1, RotateX.f=0, RotateY.f=0, RotateZ.f=0)
  Protected Dim MeshDataV.PB_MeshVertex(0)
  Protected Dim MeshDataF.PB_MeshFace(0)
  Protected i,meshc
  
  meshc=CopyMesh(mesh,-1)
  TransformMesh(Meshc, NewX,NewY,NewZ, ScaleX,ScaleY,ScaleZ, RotateX,RotateY,RotateZ)
  GetMeshData(Meshc,0, MeshDataV(), #PB_Mesh_Vertex |#PB_Mesh_Color | #PB_Mesh_UVCoordinate| #PB_Mesh_Normal, 0, MeshVertexCount(Meshc, 0)-1)
  GetMeshData(Meshc,0, MeshDataF(), #PB_Mesh_Face, 0, MeshIndexCount(Meshc, 0)-1)
  FreeMesh(meshc) 
  
  AddSubMesh()
  For i=0 To ArraySize(MeshDataV())
    With MeshDatav(i)
      MeshVertex(\x,\y,\z,\u,\v,$ffffff,\NormalX,\NormalY,\NormalZ)
    EndWith
  Next     
  For i=0 To ArraySize(MeshDataF()) Step 3
    MeshFace(MeshDataF(i)\Index, MeshDataF(i+1)\Index,MeshDataF(i+2)\Index)
  Next
  If mat>=0:SetMeshMaterial(mesho, MaterialID(mat), SubMeshCount(mesho)-1):EndIf
EndProcedure

;##########################################################################################################################################################
Global ex,ey,h.f

Procedure mesh_terrain(mesh,n) 
  Protected.f h, vx, vy
  Protected i,j,dt=4,n2=n/2
  Dim pa.f(n-1,n-1)
  
  perlinarray2d(pa(),0,16,16*4)
  
  Dim t.PB_MeshVertexV(n,n)
  RandomSeed(0)
  For j=0 To n
    For i=0 To n
      With t(i,j)  
        \p\x=(i-n2)*10
        \p\z=(j-n2)*10
        \p\y=pa(i & (n-1),j & (n-1)):If \p\y<0:\p\y=0:EndIf
        \u=i
        \v=j
        \color=$ffffff
      EndWith 
    Next
  Next
  CreateDataMesh(mesh,t())
  NormalizeMesh(mesh);UpdateMeshBoundingBox(mesh);BuildMeshShadowVolume(mesh)
EndProcedure

Procedure Init()
  Protected i
  InitEngine3D():InitSprite():InitKeyboard():InitMouse()
  
  OpenWindow(0, 0, 0, 800,600, "",#PB_Window_Maximize|#PB_Window_BorderLess)
  ex=WindowWidth (0,#PB_Window_InnerCoordinate)
  ey=WindowHeight(0,#PB_Window_InnerCoordinate)
  OpenWindowedScreen(WindowID(0), 0, 0, ex, ey, 0, 0, 0)
  LoadFont(0,"arial",11)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem):Parse3DScripts()
  
  EnableWorldPhysics(#True)
  EnableWorldCollisions(#True)
  WorldGravity(-10)
  
  CreateCamera(0, 0, 0, 100, 100):MoveCamera(0,0,10,-20)
  CameraBackColor(0,$ff8888) 
  
  CreateLight(0,$888888, 500,1000,0):SetLightColor(0, #PB_Light_SpecularColor, $ffffff)
  AmbientColor($444444)  
  
  ; -------------------- terrain
  matiere(0,256,256,$ff448888,$ff88cccc,0)
  mesh_terrain(100,256)
  CreateEntity(100,MeshID(100),MaterialID(0)):CreateEntityBody(100,#PB_Entity_StaticBody,1,0,1)
  EntityRenderMode(100,0)
  matiere(1,256,256,$aaaaaa,$ffffff,0):ScaleMaterial(1,0.1,0.1/6)
  CreateCube(101,1):TransformMesh(101,0,0,0,20,0.4,240,0,0,0):UpdateMeshBoundingBox(101)
  CreateEntity(101,MeshID(101),MaterialID(1)):CreateEntityBody(101,#PB_Entity_StaticBody,1,0,0.5)
  
  ; -------------------- plane
  CreateMesh(0)
  matiere(10,256,256,$88444444,$88444444,$ffffff,1)
  CreateSphere(1,0.3):AddMesh(0,1,10,0,0.3,-0.3, 1,1,1.9)
  matiere(11,256,256,$ff0000ff,$0000ff,$ffffff,0,4)
  CreateCapsule(1,0.4,0.6):AddMesh(0,1,11,0,0,0.5,1,1,1,-90,0,0)
  CreateCone(1,0.4,3,16,1):AddMesh(0,1,11,0,0,-1.3,1,1,1,-90,0,0)
  CreateCapsule(1, 0.3,0):AddMesh(0,1,11,0,0.2,-2.5,0.1,1.5,1,0,0,0)
  CreateCapsule(1, 0.3,0):AddMesh(0,1,11,0,0,-2.5,3,0.1,1,0,0,0)
  CreateCapsule(1, 0.5,5):AddMesh(0,1,11,0,0,0,1,1,0.2,90,0,90)  
  matiere(12,256,256,$444444,$000000,0)
  CreateCylinder(1,0.2,0.1):AddMesh(0,1,12,0.6,-0.6,0.5,1,1,1,0,0,90):AddMesh(0,1,12,-0.6,-0.6,0.5,1,1,1,0,0,90)
  FinishMesh(1):NormalizeMesh(0);UpdateMeshBoundingBox(0);BuildMeshShadowVolume(0)
  CreateEntity(0, MeshID(0), #PB_Material_None,0,0.8+0.2,0):CreateEntityBody(0, #PB_Entity_ConvexHullBody ,100, 0.0,0.2);EntityRenderMode(0, 0)
  SetEntityAttribute(0,#PB_Entity_LinearSleeping,0)
  
  ; helice
  matiere(13,256,256,$444444,$444444)
  CreateCapsule(2,0.1,0.5):TransformMesh(2,0,0,0,0.2,2,1,0,90,0):NormalizeMesh(2):UpdateMeshBoundingBox(2);:BuildMeshShadowVolume(2)
  CreateEntity(2, MeshID(2), MaterialID(13),0,0,1.3) 
  AttachEntityObject(0,"",EntityID(2))
  
  ; smoke
  LoadTexture(20, "smoke2.png")
  CreateMaterial(20, TextureID(20))
  DisableMaterialLighting(20, 1)
  MaterialBlendingMode   (20, #PB_Material_AlphaBlend)
  SetMaterialAttribute(20,#PB_Material_TAM,#PB_Material_ClampTAM)
  CreateParticleEmitter(0, 0.25,0,0,0,0,0,-2)
  ParticleMaterial    (0, MaterialID(20))
  ParticleSize        (0, 0.5,0.5)
  ParticleEmissionRate(0, 25)
  ParticleTimeToLive  (0, 1,1)
  ParticleScaleRate(0,2)
  ParticleAngle(0,-180,180,-90,90)
  ParticleColorFader(0,0,0,0,-1)
  DisableParticleEmitter(0,1)
  AttachEntityObject(0,"",ParticleEmitterID(0))
  
  RenderWorld(10000)
  WorldShadows(#PB_Shadow_Additive)
  ;WorldDebug(#PB_World_DebugEntity)
EndProcedure

Procedure stabilise(entity,f.f)
  Protected.f x,y,z
  x=GetEntityAttribute(entity,#PB_Entity_AngularVelocityX)
  y=GetEntityAttribute(entity,#PB_Entity_AngularVelocityY)
  z=GetEntityAttribute(entity,#PB_Entity_AngularVelocityZ)
  ApplyEntityTorque(entity,-x*f,-y*f,-z*f,#PB_World )
EndProcedure

Procedure menu()
  Protected p=4
  Macro DT(t1,t2="")
    DrawText(8,p,t1)
    DrawText(160,p,t2)
    p+20
  EndMacro
  CreateSprite(0,240,188,#PB_Sprite_AlphaBlending)
  StartDrawing(SpriteOutput(0))
  DrawingMode(#PB_2DDrawing_AllChannels)
  DrawingFont(FontID(0))
  Box(0,0,OutputWidth(),OutputHeight(),$44000000)
  DrawingMode(#PB_2DDrawing_AllChannels|#PB_2DDrawing_Outlined)
  Box(0,0,OutputWidth(),OutputHeight(),$44ffffff)
  BackColor($44000000)
  FrontColor($ffffffff)
  dt("[Arrow keys] / Mouse", "Yoke / Stick")
  dt("[Pad 2-1] / LMB-RMB","Rudder")
  dt("[Pad 0-1] / Wheel","Engine")
  dt("[F1]","Camera")
  dt("[F2]","Smoke")
  dt("[Esc]","Quit")
  dt("        Engine %")
  dt("        Altitude")
  dt("        Velocity")
  StopDrawing()
EndProcedure

Procedure affiche3d()
  Protected.f      cx=0.05,       cz=2.5,   czp=100,      alt=0.8+0.2
  Protected.f rotp,decx,decy,decz,poussee,fpoussee,fportance,v,vd,vp
  Protected.vector3 apos,pos,vit,dir,per,ftrainee,p,p0
  Protected i,ii,j,c,l,dis=0,vdis=1<<dis,smoke,shadows
  
  Macro KBdep(k1,k2):(Bool(KeyboardPushed(k1))-Bool(KeyboardPushed(k2))) :EndMacro
  
  menu()
  MouseLocate(ex/2,ey/2)
  vec3d(pos,EntityX(0),EntityY(0),EntityZ(0))
  Repeat 
    WindowEvent()
    ExamineMouse()
    ExamineKeyboard()
    If KeyboardReleased(#PB_Key_F1):dis=(dis+1)%3:vdis=1<<dis:EndIf
    If KeyboardReleased(#PB_Key_F2):smoke=1-smoke:vdis=4:DisableParticleEmitter(0,1-smoke):EndIf 
    
    vec3d(dir,-EntityDirectionX(0),-EntityDirectionY(0),-EntityDirectionZ(0))
    vec3d(p,0,-1,0)
    vec3d(p0,0,0,0)
    localtoworld(EntityID(0),p)
    localtoworld(EntityID(0),p0)
    sub3d(per,p,p0)
    apos=pos:vec3d(pos,EntityX(0),EntityY(0),EntityZ(0))
    sub3d(vit,pos,apos)
    mul3d(vit,60)
    v=lng3d(vit)
    vd=Pscalaire3d(vit,dir)
    vp=Pscalaire3d(vit,per)
    
    ; commandes
    decx-KBdep(#PB_Key_Left,#PB_Key_Right)*0.4+MouseDeltaX()*0.02:decx*0.8
    decz+KBdep(#PB_Key_Down,#PB_Key_Up   )*0.4+MouseDeltaY()*0.01:decz*0.8
    decy+KBdep(#PB_Key_Pad2,#PB_Key_Pad3 )*0.4+(MouseButton(1)-MouseButton(2))*0.4:decy*0.8
    poussee+KBdep(#PB_Key_Pad1,#PB_Key_Pad0)*1+MouseWheel()*10:If poussee<0:poussee=0:ElseIf poussee>100:poussee=100:EndIf
    
    ; portance    
    fportance=vd*vd*cz + vp*czp
    ApplyEntityForce(0, 0,fportance,0,decx*1,1,-0.15,#PB_Local )
    
    ; poussée
    fpoussee=poussee*10
    ApplyEntityForce(0, 0,0,fpoussee,0,0,1,#PB_Local)
    
    ; trainée
    ftrainee=vit:mul3d(ftrainee,-v*v*cx)
    vec3d(p,decy,decz,-2)
    vec3d(p0,0,0,0)
    localtoworld(EntityID(0),p)
    localtoworld(EntityID(0),p0)
    sub3d(p,p,p0)
    ApplyEntityForce(0,ftrainee\x,ftrainee\y,ftrainee\z,p\x,p\y,p\z,#PB_World )
    
    stabilise(0,800)
    
    rotp=poussee:RotateEntity(2,0,0,rotp,#PB_Relative)
    
    CameraFollow(0, EntityID(0), -180,EntityY(0)+vdis, 6*vdis, 0.02, 0.5)
    
    RenderWorld(16)
    StartDrawing(SpriteOutput(0)):DrawingFont(FontID(0)):DrawText(160,124,Str(poussee)+"  "):DrawText(160,144,StrF(pos\y,1)+"  "):DrawText(160,164,StrF(v,1)+"  "):StopDrawing()
    DisplayTransparentSprite(0,8,8)
    FlipBuffers()  
  Until KeyboardPushed(#PB_Key_Escape)
EndProcedure

init()
affiche3d()
BarryG
Addict
Addict
Posts: 3292
Joined: Thu Apr 18, 2019 8:17 am

Re: Physics - Airplane

Post by BarryG »

Can't run because it crashes with illegal memory access for me. Not what you wanted to hear, I know.
User avatar
Bisonte
Addict
Addict
Posts: 1226
Joined: Tue Oct 09, 2007 2:15 am

Re: Physics - Airplane

Post by Bisonte »

BarryG wrote:Can't run because it crashes with illegal memory access for me. Not what you wanted to hear, I know.
With PB5.70 (x64) on Win10 (x64) it run without problems.
PureBasic 6.04 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
English is not my native language... (I often use DeepL to translate my texts.)
User avatar
VB6_to_PBx
Enthusiast
Enthusiast
Posts: 617
Joined: Mon May 09, 2011 9:36 am

Re: Physics - Airplane

Post by VB6_to_PBx »

awesome !

works great on Win 8.0 64-Bit Computer , with PB5.70LTS ( 32-Bit compiler version X86 )
 
PureBasic .... making tiny electrons do what you want !

"With every mistake we must surely be learning" - George Harrison
User avatar
oreopa
Enthusiast
Enthusiast
Posts: 281
Joined: Sat Jun 24, 2006 3:29 am
Location: Edinburgh, Scotland.

Re: Physics - Airplane

Post by oreopa »

Runs perfect here. Another incredible demo. Great work.

W7 x64 / PB 5.71beta1 x86
Proud supporter of PB! * Musician * C64/6502 Freak
firace
Addict
Addict
Posts: 899
Joined: Wed Nov 09, 2011 8:58 am

Re: Physics - Airplane

Post by firace »

BarryG wrote:Can't run because it crashes with illegal memory access for me. Not what you wanted to hear, I know.
Same here, but I've found that the IMA can be fixed / avoided either by switching the subsystem to opengl, or just commenting line 224: WorldShadows(#PB_Shadow_Additive)

Great demo!
User avatar
pf shadoko
Enthusiast
Enthusiast
Posts: 280
Joined: Thu Jul 09, 2015 9:07 am

Re: Physics - Airplane

Post by pf shadoko »

Hi,
in terms of crashes, with 3d there are 2 common causes; shadows and sprites:

1) shadows:
line 224
- try replacing PB_Shadow_Additive with PB_Shadow_Modulative (I don't really believe in it...)
- disable them (comment the line)

2) sprites:
comment on the lines
224: menu()

325 : StartDrawing....
326: DisplayTransparentSprite....
Hi-Toro
Enthusiast
Enthusiast
Posts: 265
Joined: Sat Apr 26, 2003 3:23 pm

Re: Physics - Airplane

Post by Hi-Toro »

Thanks for posting this, and your other demos! I'm currently struggling with aircraft physics so will study this!

Really cool stuff.
James Boyd
http://www.hi-toro.com/
Death to the Pixies!
User avatar
Psychophanta
Addict
Addict
Posts: 4969
Joined: Wed Jun 11, 2003 9:33 pm
Location: Lípetsk, Russian Federation
Contact:

Re: Physics - Airplane

Post by Psychophanta »

This is specially nice to me, because its smootness and reality. Also because the small code needed.
Really interesting.
Many thanks to post it. :)
http://www.zeitgeistmovie.com

While world=business:world+mafia:Wend
Will never leave this forum until the absolute bugfree PB :mrgreen:
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: Physics - Airplane

Post by Mijikai »

Nice :)

OpenGL works but DirectX crashes x86 & x64 (PureBasic v.5.71b)
User avatar
Kuron
Addict
Addict
Posts: 1626
Joined: Sat Oct 17, 2009 10:51 pm
Location: Pacific Northwest

Re: Physics - Airplane

Post by Kuron »

Hi-Toro wrote:Thanks for posting this, and your other demos! I'm currently struggling with aircraft physics so will study this!

Really cool stuff.
James, here are two things that may help and are good to learn from.

1. Corncob 3D was one of the better DOS flight sims for its time, and the author Kevin Stokes has released the source code. You can find it at either link below:

https://archive.org/details/3srcj12
https://github.com/foone/Corncob3D

2. This book is really good.
Hi-Toro
Enthusiast
Enthusiast
Posts: 265
Joined: Sat Apr 26, 2003 3:23 pm

Re: Physics - Airplane

Post by Hi-Toro »

Thanks, Kuron, interesting links. The source is assembly, though, so definitely not for me! Book looks interesting.

My project is only a simple arcade-style flight game, using basic forces/torque for "good enough" flight, but failing to handle stalling, which this does nicely.

I had a look last night and the core of pf shadoko's simulation is surprisingly simple, so I'm fairly hopeful I can translate the basic principles into my project. (Thanks, pf!)
James Boyd
http://www.hi-toro.com/
Death to the Pixies!
Post Reply