3d trails (for 3d bullets)

Started by RemiD, October 05, 2023, 08:57:44

Previous topic - Next topic

RemiD

an example to have 3d trails follow 3d bullets

;3d trails (for 3d bullets) by RemiD 20210508-1240

;graphics window
Graphics3D(854,480,32,2)

HidePointer()

SeedRnd(MilliSecs())

;camera
Global Camera = CreateCamera()
CameraViewport(Camera,0,0,GraphicsWidth(),GraphicsHeight())
CameraRange(Camera,0.15,150)
CameraClsColor(Camera,000,000,000)


Radius# = 0.1/2
;bullet mesh
Global XBullet = CreateSphere(8)
ScaleMesh(XBullet,Radius/2,Radius/2,Radius/2)
EntityColor(XBullet,250,250,250) : EntityFX(XBullet,1)
HideEntity(XBullet)

;trail mesh
Global XTrail = CreateMesh()
Surface = CreateSurface(XTrail) ;vertices 0,1 and 4,5 are the start of the trail, vertices 2,3 and 6,7 are the end of the trail
VI% = AddVertex(Surface,-Radius/2,0.0,0.0) : VertexColor(Surface,VI,250,250,250,0.0)
VI% = AddVertex(Surface,+Radius/2,0.0,0.0) : VertexColor(Surface,VI,250,250,250,0.0)
VI% = AddVertex(Surface,-Radius/2,0.0,+1.0) : VertexColor(Surface,VI,250,250,250,0.66)
VI% = AddVertex(Surface,+Radius/2,0.0,+1.0) : VertexColor(Surface,VI,250,250,250,0.66)
VI% = AddVertex(Surface,0.0,+Radius/2,0.0) : VertexColor(Surface,VI,250,250,250,0.0)
VI% = AddVertex(Surface,0.0,-Radius/2,0.0) : VertexColor(Surface,VI,250,250,250,0.0)
VI% = AddVertex(Surface,0.0,+Radius/2,+1.0) : VertexColor(Surface,VI,250,250,250,0.66)
VI% = AddVertex(Surface,0.0,-Radius/2,+1.0) : VertexColor(Surface,VI,250,250,250,0.66)
AddTriangle(Surface,0,1,2)
AddTriangle(Surface,2,1,3)
AddTriangle(Surface,4,5,6)
AddTriangle(Surface,6,5,7)
UpdateNormals(XTrail)
EntityFX(XTrail,1+2+16+32)
HideEntity(XTrail)

;input
Global MXDiff%
Global MYDiff%

;origine
Global Origine = CreateCube()
ScaleMesh(Origine,0.01,0.01,0.01)
EntityColor(Origine,250,000,250)
EntityFX(Origine,1)

;ghost
Global Ghost_Root
Global Ghost_RootYaw#
Global Ghost_RootPitch#
Global Ghost_Eyes

AddGhost()

;environment
For n% = 1 To 26*10
 Thing = CreateSphere(2)
 ScaleEntity(Thing,0.1/2,0.1/2,0.1/2)
 EntityColor(Thing,250,250,250) : EntityFX(Thing,1)
 PositionEntity(Thing,Rnd(-30,+30),Rnd(-30,+30),Rnd(-30,+30),True)
Next

;bullets
Global BulletsCount% = 0
Type Bullet
 Field Shape
 Field TrailH%
End Type

;trails
Global TrailsCount% = 0
Type Trail
 Field Shape
 Field BulletH%
End Type

Global ShootLastMilli% = MilliSecs()

;light
SLight = CreateLight(2)
LightRange(SLight,10.0)
LightColor(SLight,180,180,180)
PositionEntity(SLight,EntityX(Ghost_Eyes,True),EntityY(Ghost_Eyes,True),EntityZ(Ghost_Eyes,True),True)
RotateEntity(SLight,EntityPitch(Ghost_Eyes,True),EntityYaw(Ghost_Eyes,True),EntityRoll(Ghost_Eyes,True),True)
EntityParent(SLight,Ghost_Eyes,True)
AmbientLight(030,030,030)

PositionEntity(Ghost_Root,0,0,-5,True)

Global MainLoopTimer = CreateTimer(30)

Main()

End()

Function Main()

 Repeat

  MainLoopMilliStart% = MilliSecs()

   MXDiff = MouseXSpeed() : MYDiff = MouseYSpeed()

   UpdateGhost()

 ;If( KeyDown(57)=1 )
  ;if last bullet was shot more than xmillis before
  If( MilliSecs() - ShootLastMilli > 100 )

   ;choose a random color
   R% = Rand(025,250) : G% = Rand(025,250) : B% = Rand(025,250)

   ;create a new bullet
   BulletsCount = BulletsCount + 1
   bul.Bullet = New Bullet
   bul\Shape = CopyEntity(XBullet)
   ;color bullet
   EntityColor(bul\Shape,R,G,B) : EntityFX(bul\Shape,1)
   EntityBlend(bul\Shape,3)
   PositionEntity(bul\Shape,0,0,0,True)
   RotateEntity(bul\Shape,Rand(-180,+180),Rand(-180,+180),0,True)
   TurnEntity(bul\Shape,Rnd(-1,+1),Rnd(-1,+1),0)

   ;create new trail
   TrailsCount = TrailsCount + 1
   tra.Trail = New Trail
   ;tra\Shape = CopyEntity(XTrail)
   tra\Shape = CopyMesh(XTrail)
   ;color trail
   ;EntityColor(tra\Shape,R,G,B)
   Surface = GetSurface(tra\Shape,1)
   For VI% = 0 To CountVertices(Surface)-1
    A# = VertexAlpha(Surface,VI)
    VertexColor(Surface,VI,R,G,B,A)
   Next
   EntityFX(tra\Shape,1+2+16+32)
   EntityBlend(tra\Shape,3)
   PositionEntity(tra\Shape,EntityX(bul\Shape,True),EntityY(bul\Shape,True),EntityZ(bul\Shape,True),True)
   RotateEntity(tra\Shape,EntityPitch(bul\Shape,True),EntityYaw(bul\Shape,True),EntityRoll(bul\Shape,True),True)
   ScaleEntity(tra\Shape,1.0,1.0,0.001)

   ;associate bullet and trail
   bul\TrailH% = Handle(tra)

   ;associate trail and bullet
   tra\BulletH% = Handle(bul)

   ;reset shoot timer
   ShootLastMilli = MilliSecs()

  EndIf

  UpdateBullets()

  UpdateTrails()
 
  WireFrame(False)
  If( KeyDown(2)=1 )
   WireFrame(True)
  EndIf

  PositionEntity(Camera,EntityX(Ghost_Eyes,True),EntityY(Ghost_Eyes,True),EntityZ(Ghost_Eyes,True),True)
  RotateEntity(Camera,EntityPitch(Ghost_Eyes,True),EntityYaw(Ghost_Eyes,True),EntityRoll(Ghost_Eyes,True),True)

  CameraViewport(Camera,0,0,GraphicsWidth(),GraphicsHeight())
  CameraClsColor(Camera,000,000,000)
  SetBuffer(BackBuffer())
  RenderWorld()

  Color(255,255,255)

  CText("Tris = "+TrisRendered(),0,0)
  CText("FPS = "+FPS,0,20)

  CText(BulletsCount,854/2-StringWidth("000")/2,0)
  CText(TrailsCount,854/2-StringWidth("000")/2,20)

  ;Flip(1)
  WaitTimer(MainLoopTimer)
  VWait():Flip(False)

  MainLoopMilliTime = MilliSecs() - MainLoopMilliStart
  If( MainLoopMilliTime < 1 )
   MainLoopMilliTime = 1
  EndIf

  FPS% = 1000.0/MainLoopMilliTime

 Until( KeyDown(1)=1 )

End Function

Function CText(TextStr$,PX%,PY%)

 Text(PX,PY,TextStr,False,False)

End Function

Function Distance2D#(PAX#,PAZ#,PBX#,PBZ#)

 Distance2D# = Sqr( ( ( PBX - PAX ) * ( PBX - PAX ) ) + ( ( PBZ - PAZ ) * ( PBZ - PAZ ) ) )
 Return Distance2D

End Function

Function Distance3D#(PAX#,PAY#,PAZ#,PBX#,PBY#,PBZ#)

 Distance3D# = Sqr( ( ( PBX - PAX ) * ( PBX - PAX ) ) + ( ( PBY - PAY ) * ( PBY - PAY ) ) + ( ( PBZ - PAZ ) * ( PBZ - PAZ ) ) )
 Return Distance3D

End Function

Function AddGhost()
 
 Ghost_Root = CreatePivot()
 Ghost_RootPitch = 0
 Ghost_RootYaw = 0

 Ghost_Eyes = CreatePivot()
 EntityParent(Ghost_Eyes,Ghost_Root,True)

End Function

Function UpdateGhost()

 MoveMouse(GraphicsWidth()/2,GraphicsHeight()/2)
 Ghost_RootPitch = Ghost_RootPitch + Float(MYDiff)/10
 If( Ghost_RootPitch < -89 ) : Ghost_RootPitch = -89 : EndIf
 If( Ghost_RootPitch > +89 ) : Ghost_RootPitch = +89 : EndIf
 Ghost_RootYaw = Ghost_RootYaw - Float(MXDiff)/10
 RotateEntity(Ghost_Root,Ghost_RootPitch,Ghost_RootYaw,0,False)

 If( KeyDown(42) = 0 And KeyDown(29) = 0 )
  Speed# = 0.1
 Else If( KeyDown(42) = 1 And KeyDown(29) = 0 )
  Speed# = 1
 Else If( KeyDown(42) = 0 And KeyDown(29) = 1 )
  Speed# = 0.01
 EndIf

 If( KeyDown(17)=1 )
  MoveEntity(Ghost_Root,0,0,Speed)
 Else If( KeyDown(31)=1 )
  MoveEntity(Ghost_Root,0,0,-Speed)
 EndIf
 If( KeyDown(30)=1 )
  MoveEntity(Ghost_Root,-Speed,0,0)
 Else If( KeyDown(32)=1 )
  MoveEntity(Ghost_Root,Speed,0,0)
 EndIf
 If( KeyDown(16)=1 )
  MoveEntity(Ghost_Root,0,-Speed,0)
 Else If( KeyDown(18)=1 )
  MoveEntity(Ghost_Root,0,Speed,0)
 EndIf

End Function

Function UpdateBullets()

 For bul.Bullet = Each Bullet

  ;move Bullet
  MoveEntity(bul\Shape,0,0,0.1)

  ;calculate distance between bullet and center of game area
  D#=Distance3D(0,0,0,EntityX(bul\Shape,True),EntityY(bul\Shape,True),EntityZ(bul\Shape,True))
 
  ;if too far
  If( D > 30.0 )
 
   ;destroy the associated trail
   traH% = bul\TrailH
   tra.Trail = Object.Trail(traH)
   FreeEntity(tra\Shape) : Delete(tra)
   TrailsCount = TrailsCount - 1

   ;destroy the Bullet
   FreeEntity(bul\Shape) : Delete(bul)
   BulletsCount = BulletsCount - 1

  EndIf

 Next

End Function

Function UpdateTrails()

 For tra.Trail = Each Trail

  ;calculate distance between bullet and trail
  bulH% = tra\BulletH
  bul.Bullet = Object.Bullet(bulH)
  D# = Distance3D(EntityX(tra\Shape,True),EntityY(tra\Shape,True),EntityZ(tra\Shape,True),EntityX(bul\Shape,True),EntityY(bul\Shape,True),EntityZ(bul\Shape,True))
  ;scale the trail
  ScaleEntity(tra\Shape,1,1,D)

 Next

End Function