Page 1 of 2

Physics - Airplane

Posted: Tue Apr 30, 2019 7:57 pm
by pf shadoko
In the "low-cost simulator" series, the airplane

Code: Select all

; ;Physics - Airplane - pf Shadoko - 2019

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,k,n
    Protected.f x,y,y0,y1,wx,wy,delta
    
    RandomSeed(rnd)
    Dim t.f(ddx+1,ddy+1)
    Dim pat.f(0,0)
    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
    CopyArray(pa(),pat())
    For k=0 To 1:n=2<<k:delta=1/n
        For j=0 To dy:For i=0 To dx:pa(i,j)+pat((i*n) % dx,(j*n) % dy)*delta: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.MeshVertex(0)
  Protected Dim MeshDataF.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 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.15):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)
  ;PBO_BodySetCenterOfMass(0,10,0,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=1.5,       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=1,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 
    While WindowEvent():Wend
    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,#PB_Local )
    
    ; poussée
    fpoussee=poussee*10
    ApplyEntityForce(0, 0,0,fpoussee,0,0,1,#PB_Local,#PB_Local)
    
    ; trainée
    ftrainee=vit:mul3d(ftrainee,-v*cx)
    ApplyEntityForce(0,ftrainee\x,ftrainee\y,ftrainee\z,decy,decz,-2, #PB_World, #PB_Local )
    
    stabilise(0,800)
    
    rotp=poussee*1.111: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) Or MouseButton(3)
EndProcedure

init()
affiche3d()

Re: Physics - Airplane

Posted: Tue Apr 30, 2019 10:07 pm
by BarryG
Can't run because it crashes with illegal memory access for me. Not what you wanted to hear, I know.

Re: Physics - Airplane

Posted: Tue Apr 30, 2019 11:25 pm
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.

Re: Physics - Airplane

Posted: Wed May 01, 2019 12:11 am
by VB6_to_PBx
awesome !

works great on Win 8.0 64-Bit Computer , with PB5.70LTS ( 32-Bit compiler version X86 )

Re: Physics - Airplane

Posted: Wed May 01, 2019 12:58 am
by oreopa
Runs perfect here. Another incredible demo. Great work.

W7 x64 / PB 5.71beta1 x86

Re: Physics - Airplane

Posted: Wed May 01, 2019 9:05 am
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!

Re: Physics - Airplane

Posted: Thu May 02, 2019 10:24 am
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....

Re: Physics - Airplane

Posted: Sat May 18, 2019 4:59 pm
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.

Re: Physics - Airplane

Posted: Sun May 19, 2019 2:06 pm
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. :)

Re: Physics - Airplane

Posted: Mon May 20, 2019 2:49 pm
by Mijikai
Nice :)

OpenGL works but DirectX crashes x86 & x64 (PureBasic v.5.71b)

Re: Physics - Airplane

Posted: Mon May 20, 2019 11:10 pm
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.

Re: Physics - Airplane

Posted: Mon May 20, 2019 11:43 pm
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!)

Re: Physics - Airplane

Posted: Thu Mar 28, 2024 5:38 pm
by Psychophanta
Up and Down can not be managed in PB6.10

Re: Physics - Airplane

Posted: Thu Mar 28, 2024 6:19 pm
by pf shadoko
I updated the code
it's now ok

Re: Physics - Airplane

Posted: Tue Apr 02, 2024 1:05 am
by minimy
Awesome demo! Thanks for share! Your demos are really fantastic!
'I can feel i like can fly!!!' ♫♪♫ :D