[B3D] Planetenatmosphäre und Freelancer-Steuerung

Übersicht BlitzBasic Codearchiv

Neue Antwort erstellen

 

Krischan

Betreff: [B3D] Planetenatmosphäre und Freelancer-Steuerung

BeitragSo, Nov 16, 2008 18:59
Antworten mit Zitat
Benutzer-Profile anzeigen
Hier eine komplett ohne Texturen lauffähige Demo eines Planeten mit Atmosphäre und einer Freelancer-ähnlichen Steuerung. Man kann dabei vom Weltraum nahtlos in die Atmosphäre eintauchen und auch wieder herausfliegen. Es werden dabei zwei Mesh-Ringe dynamisch zur Entfernung des Spielers zum Planeten skaliert und kegelförmig verbogen sowie berücksichtigt, ob man auf der der Sonne zu- oder abgewandten Seite fliegt.

Steuerung: Maus, Pfeiltasten
Rotes Fadenkreuz: Flugrichtung
Grüner Kasten: Zielrichtung
SPACE = Wireframe an/aus

Im Weltraum
user posted image

Eintritt in die Atmosphäre
user posted image

Flug über die Oberfläche
user posted image

Code: [AUSKLAPPEN]
AppTitle "Planet Atmosphere Glow Demo"
; by Krischan webmaster(at)jaas.de

; Constants
Const ScreenWidth%            = 800         ; Screen width
Const ScreenHeight%            = 600         ; Screen height
Const ColorDepth%            = 32         ; Color depth
Const ScreenMode%            = 2            ; Screen Mode
Const MouseSpeed#            = 0.1         ; Mousespeed
Const CameraSmoothness#         = 10         ; Smoothness of movement
Const Scale#               = 12.756      ; Approx. the diameter of earth (1 unit = 1000km)
Const GameTime%               = 20         ; Game speed
Const CursorSize%            = 33         ; Size of cursor and crosshair image
Const TurnSpeed#            = 2.0         ; Turnspeed of player
Const RollSpeed#            = 1.0         ; Roll speed
Const MaxRollAngle#            = 20.0         ; Maximum roll angle
Const RingDetail%            = 60         ; Number of segments

; Glow Color scheme
Const R1%=192,G1%=224,B1%=255               ; Surface near color
Const R2%=128,G2%=160,B2%=255               ; Surface far color

; Variables
Global CameraSpeed#            = Scale/10.0   ; Movement speed
Global TargetDistance#         = 10.0*Scale   ; Mousetarget distance to player
Global FrameTime            = MilliSecs()   ; Initialize Frame Timer
Global Period%               = 1000/75.0      ; Calc frame period (here: 75FPS)

; help variables and objects
Global MX%,MY%                           ; Mouse position
Global Player%,MouseTarget%,Cam%,Ship%         ; Player
Global Cursor%,Cross%                     ; Images
Global Planet%,Light%,Sun%,StarBox%,GlowPivot%   ; Scene objects
Global Glow1%,Glow2%                     ; Glow rings
Global GlowScale#                        ; Glow scale indicator
Global Tween#                           ; Frame tween

; Init 3D
Graphics3D ScreenWidth,ScreenHeight,ColorDepth,ScreenMode

; Init Player and Scene
InitPlayer()
InitScene()

; Center mouse and hide pointer
MoveMouse ScreenWidth/2,ScreenHeight/2
HidePointer

; Main loop
While Not KeyHit(1)
   
   ; Frame tweening
   Tween#=Float(MilliSecs()-FrameTime)/Float(GameTime) : FrameTime=MilliSecs()
   
   ; SPACE = Wireframe
   If KeyHit(57) Then wf%=1-wf : WireFrame wf
   
   ; Get Distance player to planet
   Local distance#=EntityDistance(Cam,Planet)
   
   ; Update atmosphere glow
   UpdateAtmosphere(distance)
   
   ; Attach Starbox to camera
   PositionEntity StarBox,EntityX(Player),EntityY(Player),EntityZ(Player)
   
   ; Sun points to player
   PointEntity Sun,Player
   
   UpdateWorld
   RenderWorld
   
   ; Move player
   Movement(GlowScale,distance)
   
   ; Draw cursor and crosshair by chasing the mousetarget
   CameraProject Cam,EntityX(MouseTarget,1),EntityY(MouseTarget,1),EntityZ(MouseTarget,1)
   DrawImage Cursor,MX-(CursorSize/2),MY-(CursorSize/2)
   DrawImage Cross,ProjectedX()-(CursorSize/2),ProjectedY()-(CursorSize/2)
   
   ; Statistics
   Text 0, 0,"Triangles rendered....: "+TrisRendered()
   Text 0,15,"Distance To Surface...: "+Int((distance-Scale)*1000)+" km"
   
   Flip 0
   
Wend

End

; The functions that creates the mesh and surface for a ring
Function CreateRing(fx%=0,blend%=0)
   
   Local a1#,a2#,a3#,a4#,angle%
   Local v0%,v1%,v2%,v3%
   
   Local mesh=CreateMesh()
   Local surf=CreateSurface(mesh)
   
   ; Ring FX
   If fx>0 Then EntityFX mesh,fx
   If blend>0 Then EntityBlend mesh,blend
   
   Return mesh
   
End Function

; Re-creates the ring vertices and triangles with different values
Function UpdateRing(mesh%,radius1#=1.0,radius2#=2.0,segments%=360,r1%=255,g1%=255,b1%=255,alpha1#=1.0,r2%=0,g2%=0,b2%=0,alpha2#=1.0,scale#=0.0)
   
   Local a1#,a2#,a3#,a4#,angle%
   Local v0%,v1%,v2%,v3%
   
   ; Get and clear the surface
   Local surf=GetSurface(mesh,1)
   ClearSurface surf,1,1
   
   ; Limit segments
   If segments>360 Then segments=360
   
   ; Create ring
   For angle=1 To segments
      
      a1=angle*360.0/segments
      a2=angle*360.0/segments +360.0/segments
      a3=angle*360.0/segments +180.0/segments
      a4=angle*360.0/segments -180.0/segments
      
      ; Calc vertex points
      v0=AddVertex(surf,radius1*Cos(a1),radius1*Sin(a1),0,0,0)
      v1=AddVertex(surf,radius1*Cos(a2),radius1*Sin(a2),0,0,0)
      v2=AddVertex(surf,radius2*Cos(a3),radius2*Sin(a3),scale,1,1)
      v3=AddVertex(surf,radius2*Cos(a4),radius2*Sin(a4),scale,1,1)
      
      ; Color
      VertexColor surf,v0,r1,g1,b1,alpha1
      VertexColor surf,v1,r1,g1,b1,alpha1
      VertexColor surf,v2,r2,g2,b2,alpha2
      VertexColor surf,v3,r2,g2,b2,alpha2
      
      ; Create Triangles
      AddTriangle surf,v2,v1,v0
      AddTriangle surf,v0,v3,v2
      
   Next
   
   Return mesh
   
End Function

; Initialize player, camera
Function InitPlayer()
   
   Local i%
   
   ; Player pivot
   Player=CreatePivot()
   PositionEntity Player,-Scale*2,0,Scale*2
   
   ; Ship mesh
   Ship=CreateCube(Player)
   EntityFX Ship,1
   ScaleEntity Ship,0.2,0.05,0.2
   PositionEntity Ship,0,-0.5,1.5
   EntityOrder Ship,-1000
   
   ; Mousetarget in space
   MouseTarget=CreatePivot(Ship)
   MoveEntity MouseTarget,0,0,TargetDistance
   
   ; Camera
   Cam=CreateCamera(Player)
   PositionEntity Cam,0,0,0
   CameraRange Cam,0.01,1000*Scale
   
   ; Create cursor image
   Cursor=CreateImage(CursorSize,CursorSize)
   SetBuffer ImageBuffer(Cursor)
   For i=0 To 2
      Color 0,Int(255.0/(1+i)),0
      Rect i,i,CursorSize-(2*i),CursorSize-(2*i),0
   Next
   
   ; Create crosshair image
   Cross=CreateImage(CursorSize,CursorSize)
   SetBuffer ImageBuffer(Cross)
   Color 255,0,0
   Line (CursorSize-1)/2.0,0,(CursorSize-1)/2.0,CursorSize
   Line 0,(CursorSize-1)/2.0,CursorSize,(CursorSize-1)/2.0
   
   ; reset buffer and color
   SetBuffer BackBuffer()
   Color 255,255,255
   
End Function

; Initialize scene
Function InitScene()
   
   Local startex%,i%,col%,rgb%
   
   ; Planet
   Planet=CreateSphere(60)
   ScaleEntity Planet,Scale,Scale,Scale
   EntityColor Planet,32,192,64
   
   ; Directional Sunlight
   Light=CreateLight(1)
   PositionEntity Light,0,0,-Scale*200
   LightRange Light,200*Scale
   AmbientLight 16,16,16
   
   ; Sun
   Sun=CreateQuad()
   ScaleEntity Sun,Scale*10,Scale*10,Scale*10
   EntityFX Sun,1
   EntityColor Sun,255,255,192
   EntityParent Sun,Light
   PositionEntity Sun,0,0,0
   EntityBlend Sun,3
   EntityTexture Sun,CreateSunTexture()
   
   ; Simple Starbox
   StarBox=CreateCube()
   startex=CreateTexture(1024,1024)
   LockBuffer TextureBuffer(startex)
   For i=1 To 1000
      col=Rand(0,255)
      rgb=col*$10000+col*$100+col
      WritePixelFast Rand(0,1023),Rand(0,1023),rgb,TextureBuffer(startex)
   Next
   UnlockBuffer TextureBuffer(startex)
   EntityTexture StarBox,startex
   ScaleEntity StarBox,10,10,10
   EntityOrder StarBox,1
   EntityFX StarBox,1
   FlipMesh StarBox
   
   ; Glow
   GlowPivot=CreatePivot()
   Glow1=CreateRing(1+2+16+32,1)
   Glow2=CreateRing(1+2+16+32,3)
   EntityParent Glow1,GlowPivot
   EntityParent Glow2,GlowPivot
   EntityOrder Glow1,1
   EntityOrder Glow2,1
   
   ; Player points to planet first
   PointEntity Player,Planet
   TurnEntity Player,0,-20,-90
   
End Function

; Update atmosphere glow and background color
Function UpdateAtmosphere(distance#)
   
   Local s2#,s2d#,aa#,bb#,cc#
   Local angle#,intensity#,clscol#,horizon#
   
   ; Calculate ring scale with the help of two right-angled triangles and trigonometry
   s2#=Scale^2
   s2d#=s2/distance
   GlowScale#=(Sqr(s2+(Scale/Tan(90-(90-(90-ATan(Sqr((distance-(s2d))*(s2d))/(distance-(s2d)))))))^2))/Scale
   
   ; Calculcate the sun light angle (1 = exactly between sun and planet, 0 = exactly behind the planet)
   aa#=EntityDistance(Cam,Planet)
   bb#=EntityDistance(Planet,Light)
   cc#=EntityDistance(Cam,Light)
   angle#=ACos((aa^2+cc^2-bb^2)/(2*aa*cc))/180.0
   If angle>1 Then angle=1
   If angle<0 Then angle=0
   
   ; Calculate the glow intensity according to sun light angle and distance to planet
   intensity#=1-(1.0/Exp(GlowScale*angle))
   If intensity<0 Then intensity=0
   If intensity>1 Then intensity=1
   
   ; Calculate the horizon glow scale multiplicator
   horizon#=1-(1.2/Exp(GlowScale*angle/2.0))
   If horizon<0 Then horizon=0
   If horizon>1 Then horizon=1
   
   ; Update ring intensity according to sun light angle and distance to planet
   UpdateRing(Glow1,0.6*Scale,0.01*Scale,RingDetail,R1*intensity,G1*intensity,B1*intensity,angle,R2*(angle-intensity),G2*(angle-intensity),B2*(angle-intensity),   0,Scale/3.0)
   UpdateRing(Glow2,(1.0-(horizon/10.0))*Scale,(1.05+(horizon/10.0))*Scale,RingDetail,R1*intensity,G1*intensity,B1*intensity,1.0-horizon,R2*angle,G2*angle,B2*angle,0,horizon*2)
   
   ; Scale the rings and always point to player
   ScaleEntity GlowPivot,GlowScale,GlowScale,GlowScale
   PointEntity GlowPivot,Player
   
   ; Calculate the background color to simulate atmosphere penetration
   clscol#=(1-(5.0/Exp(GlowScale*angle/2.0)))*intensity
   If clscol<0 Then clscol=0
   If clscol>1 Then clscol=1
   CameraClsColor Cam,R2*clscol,G2*clscol,B2*clscol
   
   ; Change Starbox alpha
   EntityAlpha StarBox,1-clscol
   
End Function

; Player movement
Function Movement(scale#,distance#)
   
   Local roll#,mox#,moz#,cx#,cz#
   Local t1#,t2#
   
   ; get mouse position
   MX=MouseX()
   MY=MouseY()
   
   ; Movement with speed limit
   cx=(KeyDown(205)-KeyDown(203))*CameraSpeed
   cz=(KeyDown(200)-KeyDown(208))*CameraSpeed
   
   ; Arrow left/right = roll
   If KeyDown(203) Then roll=RollSpeed
   If KeyDown(205) Then roll=-RollSpeed
   
   ; Normalize Mouse position (-1 to +1)
   t1=Normalize(MY,0,ScreenHeight,-1,1)
   t2=Normalize(MX,0,ScreenWidth,1,-1)
   
   ; Slower cursor movement in the center of the screen
   If t1<0 Then t1=(Abs(t1)^2.0)*-1 Else t1=t1^2.0
   If t2<0 Then t2=(Abs(t2)^2.0)*-1 Else t2=t2^2.0
   
   ; Rotate ship mesh and turn player pivot
   RotateEntity Ship,t1*MaxRollAngle,t2*MaxRollAngle,t2*MaxRollAngle*2
   TurnEntity Player,t1*TurnSpeed*Tween,t2*TurnSpeed*Tween,roll*TurnSpeed*Tween
   
   ; Move the player forward/backward
   MoveEntity Player,0,0,(cz*1.0/(scale)^3)*Tween
   
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

Function CreateQuad()
   
   ; Create mesh and surface
   Local mesh%=CreateMesh()
   Local surf%=CreateSurface(mesh)
   
   ; Add vertices
   Local v0%=AddVertex(surf,  1.0,  1.0, 0.0, 0.0, 0.0 )   ; upper left
   Local v1%=AddVertex(surf, -1.0,  1.0, 0.0, 1.0, 0.0 )   ; upper right
   Local v2%=AddVertex(surf, -1.0, -1.0, 0.0, 1.0, 1.0 )   ; lower right
   Local v3%=AddVertex(surf,  1.0, -1.0, 0.0, 0.0, 1.0 )   ; lower left
   
   ; Connect vertices
   AddTriangle surf,v0,v1,v2
   AddTriangle surf,v0,v2,v3
   
   Return mesh
   
End Function

; Create a simple sun texture
Function CreateSunTexture()
   
   Local tex%=CreateTexture(512,512,2)
   Local tb%=TextureBuffer(tex)
   
   Local i#,j%,col%,rgb%
   
   SetBuffer tb
   LockBuffer tb
   
   ; Intensity steps
   For j=0 To 255
      
      ; Exponential falloff
      col=Int((1.0/Exp(j*0.075))*100000000)
      If col>255 Then col=255
      rgb=col*$1000000+col*$10000+col*$100+col
      
      ; Draw circles
      For i=0 To 360 Step 0.1
         WritePixelFast 256+(Sin(i)*j),256+(Cos(i)*j),rgb,tb
      Next
   
   Next
   
   UnlockBuffer tb
   SetBuffer BackBuffer()
   
   Return tex
   
End Function
  • Zuletzt bearbeitet von Krischan am So, Nov 16, 2008 19:49, insgesamt einmal bearbeitet
 

Krischan

BeitragSo, Nov 16, 2008 19:00
Antworten mit Zitat
Benutzer-Profile anzeigen
Ups da bin ich im Blitzmax Codearchiv gelandet, kann das mal einer nach B3D verschieben? Danke!
 

BIG BUG

BeitragMo, Nov 17, 2008 0:33
Antworten mit Zitat
Benutzer-Profile anzeigen
Super Ding muss ich da sagen. Vielleicht sollte das Raumschiff in Planetennähe nicht ganz sooo langsam fliegen - Eine Speedanzeige wäre da auch praktisch...
Wann kommt da eine Stadt hin in die man eintauchen kann? Smile
B3D-Exporter für Cinema4D!(V1.4)
MD2-Exporter für Cinema4D!(final)
 

Krischan

BeitragMo, Nov 17, 2008 8:39
Antworten mit Zitat
Benutzer-Profile anzeigen
Kannst ja mal an der Zeile

MoveEntity Player,0,0,(cz*1.0/(scale)^3)*Tween

herumspielen, z.B. aus dem ^3 ein ^2 machen, dann gehts fixer (allerdings bekommt man dann auch schneller Probleme mit der Cameraviewrange). Die Geschwindigkeit wäre so auszurechnen:

movespeed#=(cz*1.0/(scale)^3)*3600000

Und zwar in km/h - bei 300km Höhe hätte ich so noch 45.000km/h und bei 10km Höhe etwa 300km/h drauf. Bisschen wenig bei 10km und ein bisschen zu viel bei 300km, naja.

Ausserdem ist mir noch aufgefallen, dass die Maus-Speedlimitierung nicht so doll funktioniert, die Steuerung flutscht besser, wenn man diese beiden Zeilen auskommentiert:

If t1<0 Then t1=(Abs(t1)^2.0)*-1 Else t1=t1^2.0
If t2<0 Then t2=(Abs(t2)^2.0)*-1 Else t2=t2^2.0


Das mit der Stadt wird mit diesem Planeten ein wenig schwierig. Ich selbst könnte das nur mit tarnen, täuschen, tricksen realisieren. Mir schwebt da vor, beim Eintritt zwischen 100km und 10km Höhe Wolken auf die Camera zufliegen zu lassen, die immer dichter werden und sobald das ganze Fenster zugeklebt ist, die Szene zu wechseln und durch eine 3D-Landschaft mit Sky auszuwechseln. Die Alternative wäre wie schon einmal im Forum angesprochen ein Superikosaeder, Perlin-Noise und dynamic LOD, alles ist aber weit ausserhalb meiner jetzigen Programmierkenntnisse.

Wobei mir wenn überhaupt eher ein Starflight-Clone vorschwebt, da gabs eher Raumstationen als Städte, konnte aber auch auf Planeten landen (das war aber in Forth geschrieben und grottenlangsam).
 

Krischan

BeitragSo, Nov 30, 2008 11:45
Antworten mit Zitat
Benutzer-Profile anzeigen
Nachtrag: ich habe festgestellt, dass es auch mit weniger Vertices geht, wenn man die Funktion ein wenig umbaut, dabei werden nun 50% weniger Vertices benötigt. Und ich kann die Atmosphäre jetzt mit optisch gleichem Resultat mit 42 Vertices/40 Triangles anstatt 240 Vertices/120 Triangles darstellen (Variable Ringdetail 20 anstatt 60):

Code: [AUSKLAPPEN]
; Re-creates the ring vertices and triangles with different values
Function UpdateRing(mesh%,radius1#=1.0,radius2#=2.0,segments%=360,r1%=255,g1%=255,b1%=255,alpha1#=1.0,r2%=0,g2%=0,b2%=0,alpha2#=1.0,scale#=0.0)
   
   Local a1#,a2#,angle%
   Local v0%,v1%,v2%,v3%,v%
   
   ; get and clear the surface
   Local surf=GetSurface(mesh,1)
   ClearSurface surf,1,1
   
   ; Limit segments
   If segments>360 Then segments=360
   
   ; Create ring
   For angle=0 To segments
      
      a1=angle*360.0/segments
      a2=angle*360.0/segments+180.0/segments
      
      ; Calc vertex points
      v0=AddVertex(surf,radius1*Cos(a1),radius1*Sin(a1),0,0,0)
      v1=AddVertex(surf,radius2*Cos(a2),radius2*Sin(a2),scale,1,1)
      
      ; Color
      VertexColor surf,v0,r1,g1,b1,alpha1
      VertexColor surf,v1,r2,g2,b2,alpha2
      
   Next
   
   ; Create Triangles
   For v=0 To CountVertices(surf)-3
      
      AddTriangle(surf,v,v+1,v+2)
      
   Next
   
   Return mesh
   
End Function
 

Shaggy82

Betreff: problem mit planetengrößen

BeitragSa, Nov 21, 2009 3:04
Antworten mit Zitat
Benutzer-Profile anzeigen
hallo Krischan,

habe ein problem mit deinem code. habe es zwar geschaft mehrer planeten zu erzeugen. doch kann ich durch alle hindurchfliegen bis auf den zuletzt erstellten. und soblad ich die größe verändere passt der Atmosphere effekt nicht mehr.

hier mein versuch:

BlitzBasic: [AUSKLAPPEN]

AppTitle "Planet Atmosphere Glow Demo"
; by Krischan webmaster(at)jaas.de

; Constants
Const ScreenWidth% = 800 ; Screen width
Const ScreenHeight% = 600 ; Screen height
Const ColorDepth% = 32 ; Color depth
Const ScreenMode% = 2 ; Screen Mode
Const MouseSpeed# = 0.1 ; Mousespeed
Const CameraSmoothness# = 10 ; Smoothness of movement
Const Scale# = 12.756 ; Approx. the diameter of earth (1 unit = 1000km)
Const GameTime% = 20 ; Game speed
Const CursorSize% = 33 ; Size of cursor and crosshair image
Const TurnSpeed# = 2.0 ; Turnspeed of player
Const RollSpeed# = 1.0 ; Roll speed
Const MaxRollAngle# = 20.0 ; Maximum roll angle
Const RingDetail% = 60 ; Number of segments

; Glow Color scheme
Const R1%=192,G1%=224,B1%=255 ; Surface near color
Const R2%=128,G2%=160,B2%=255 ; Surface far color

; Variables
Global CameraSpeed# = Scale/10.0 ; Movement speed
Global TargetDistance# = 10.0*Scale ; Mousetarget distance to player
Global FrameTime = MilliSecs() ; Initialize Frame Timer
Global Period% = 1000/75.0 ; Calc frame period (here: 75FPS)

; help variables and objects
Global MX%,MY% ; Mouse position
Global Player%,MouseTarget%,Cam%,Ship% ; Player
Global Cursor%,Cross% ; Images
Global Planet%,Light%,Sun%,StarBox%,GlowPivot% ; Scene objects
Global Glow1%,Glow2% ; Glow rings
Global GlowScale# ; Glow scale indicator
Global Tween# ; Frame tween


Type Datenbank_Systeme_Planeten

Field Objekt_Name$

Field System_pos_x#
Field System_pos_y#

Field grundtype%

Field klasse%
Field planet_mesh%
Field planet_wolken%
Field glowpivot%


Field Glow1%
Field Glow2%
Field durchmesser2#
End Type





; Init 3D
Graphics3D ScreenWidth,ScreenHeight,ColorDepth,ScreenMode

; Init Player and Scene
InitPlayer()
InitScene()

; Center mouse and hide pointer
MoveMouse ScreenWidth/2,ScreenHeight/2
HidePointer
PositionEntity player ,0,0,148800

; Main loop
While Not KeyHit(1)

; Frame tweening
Tween#=Float(MilliSecs()-FrameTime)/Float(GameTime) : FrameTime=MilliSecs()

; SPACE = Wireframe
If KeyHit(57) Then wf%=1-wf : WireFrame wf

; Get Distance player to planet
;Local distance#=EntityDistance(Cam,Planet)

; Update atmosphere glow
UpdateAtmosphere()

; Attach Starbox to camera
PositionEntity StarBox,EntityX(Player),EntityY(Player),EntityZ(Player)

; Sun points to player
PointEntity Sun,Player
update_planeten()
UpdateWorld
RenderWorld

; Move player
Movement(GlowScale,distance)

; Draw cursor and crosshair by chasing the mousetarget
CameraProject Cam,EntityX(MouseTarget,1),EntityY(MouseTarget,1),EntityZ(MouseTarget,1)
DrawImage Cursor,MX-(CursorSize/2),MY-(CursorSize/2)
DrawImage Cross,ProjectedX()-(CursorSize/2),ProjectedY()-(CursorSize/2)

; Statistics
Text 0, 0,"Triangles rendered....: "+TrisRendered()
Text 0,15,"Distance To Surface...: "+Int((distance-Scale)*1000)+" km"

Flip 0

Wend

End

; The functions that creates the mesh and surface for a ring
Function CreateRing(fx%=0,blend%=0)

Local a1#,a2#,a3#,a4#,angle%
Local v0%,v1%,v2%,v3%

Local mesh=CreateMesh()
Local surf=CreateSurface(mesh)

; Ring FX
If fx>0 Then EntityFX mesh,fx
If blend>0 Then EntityBlend mesh,blend

Return mesh

End Function

; Re-creates the ring vertices and triangles with different values
Function UpdateRing(mesh%,radius1#=1.0,radius2#=2.0,segments%=360,r1%=255,g1%=255,b1%=255,alpha1#=1.0,r2%=0,g2%=0,b2%=0,alpha2#=1.0,scale#=0.0)

Local a1#,a2#,a3#,a4#,angle%
Local v0%,v1%,v2%,v3%

; Get and clear the surface
Local surf=GetSurface(mesh,1)
ClearSurface surf,1,1

; Limit segments
If segments>360 Then segments=360

; Create ring
For angle=1 To segments

a1=angle*360.0/segments
a2=angle*360.0/segments +360.0/segments
a3=angle*360.0/segments +180.0/segments
a4=angle*360.0/segments -180.0/segments

; Calc vertex points
v0=AddVertex(surf,radius1*Cos(a1),radius1*Sin(a1),0,0,0)
v1=AddVertex(surf,radius1*Cos(a2),radius1*Sin(a2),0,0,0)
v2=AddVertex(surf,radius2*Cos(a3),radius2*Sin(a3),scale,1,1)
v3=AddVertex(surf,radius2*Cos(a4),radius2*Sin(a4),scale,1,1)

; Color
VertexColor surf,v0,r1,g1,b1,alpha1
VertexColor surf,v1,r1,g1,b1,alpha1
VertexColor surf,v2,r2,g2,b2,alpha2
VertexColor surf,v3,r2,g2,b2,alpha2

; Create Triangles
AddTriangle surf,v2,v1,v0
AddTriangle surf,v0,v3,v2

Next

Return mesh

End Function

; Initialize player, camera
Function InitPlayer()

Local i%

; Player pivot
Player=CreatePivot()
PositionEntity Player,-Scale*2,0,Scale*2

; Ship mesh
Ship=CreateCube(Player)
EntityFX Ship,1
ScaleEntity Ship,0.2,0.05,0.2
PositionEntity Ship,0,-0.5,1.5
EntityOrder Ship,-1000

; Mousetarget in space
MouseTarget=CreatePivot(Ship)
MoveEntity MouseTarget,0,0,TargetDistance

; Camera
Cam=CreateCamera(Player)
PositionEntity Cam,0,0,0
CameraRange Cam,0.01,10000000;*Scale

; Create cursor image
Cursor=CreateImage(CursorSize,CursorSize)
SetBuffer ImageBuffer(Cursor)
For i=0 To 2
Color 0,Int(255.0/(1+i)),0
Rect i,i,CursorSize-(2*i),CursorSize-(2*i),0
Next

; Create crosshair image
Cross=CreateImage(CursorSize,CursorSize)
SetBuffer ImageBuffer(Cross)
Color 255,0,0
Line (CursorSize-1)/2.0,0,(CursorSize-1)/2.0,CursorSize
Line 0,(CursorSize-1)/2.0,CursorSize,(CursorSize-1)/2.0

; reset buffer and color
SetBuffer BackBuffer()
Color 255,255,255

End Function

; Initialize scene
Function InitScene()

Local startex%,i%,col%,rgb%

; Planet
;Planet=CreateSphere(60)
;ScaleEntity Planet,Scale,Scale,Scale
;EntityColor Planet,32,192,64

;PositionEntity Planet,0,0,149000
; Directional Sunlight
Light=CreateLight(1)
PositionEntity Light,0,0,-Scale*200
LightRange Light,200*Scale
AmbientLight 16,16,16

; Sun
Sun=CreateQuad()
ScaleEntity Sun,1390,1390,1390
EntityFX Sun,1
EntityColor Sun,255,255,192
EntityParent Sun,Light
PositionEntity Sun,0,0,0
EntityBlend Sun,3
EntityTexture Sun,CreateSunTexture()

; Simple Starbox
StarBox=CreateCube()
startex=CreateTexture(1024,1024)
LockBuffer TextureBuffer(startex)
For i=1 To 1000
col=Rand(0,255)
rgb=col*$10000+col*$100+col
WritePixelFast Rand(0,1023),Rand(0,1023),rgb,TextureBuffer(startex)
Next
UnlockBuffer TextureBuffer(startex)
EntityTexture StarBox,startex
ScaleEntity StarBox,10,10,10
EntityOrder StarBox,1
EntityFX StarBox,1
FlipMesh StarBox

; Glow
;GlowPivot=CreatePivot()
;Glow1=CreateRing(1+2+16+32,1)
;Glow2=CreateRing(1+2+16+32,3)
;EntityParent Glow1,GlowPivot
;EntityParent Glow2,GlowPivot
;EntityOrder Glow1,1
;EntityOrder Glow2,1


;PositionEntity GlowPivot,0,0,149000
ADD_Planet("Erde" , 0,0,0,149000,1,1 ,12.756)
ADD_Planet("Mars" , 0,0,100,149000,1,1 ,12.756)
ADD_Planet("mond" , 0,0,-100,149000,1,1 ,12.756)

ADD_Planet("Pluto" , 0,0,-200,149000,1,1 ,2.756)

; Player points to planet first
;PointEntity Player,Planet
;TurnEntity Player,0,-20,-90

End Function

; Update atmosphere glow and background color
Function UpdateAtmosphere()


Local s2#,s2d#,aa#,bb#,cc#
Local angle#,intensity#,clscol#,horizon#



For systeme.Datenbank_Systeme_Planeten = Each Datenbank_Systeme_Planeten

distance#=EntityDistance(Cam,systeme\planet_mesh%)


; Calculate ring scale with the help of two right-angled triangles and trigonometry
s2#=Scale^2
s2d#=s2/distance
GlowScale#=(Sqr(s2+(systeme\durchmesser2#/Tan(90-(90-(90-ATan(Sqr((distance-(s2d))*(s2d))/(distance-(s2d)))))))^2))/systeme\durchmesser2#

DebugLog GlowScale#

; Calculcate the sun light angle (1 = exactly between sun and planet, 0 = exactly behind the planet)
aa#=EntityDistance(Cam,systeme\planet_mesh%)
bb#=EntityDistance(systeme\planet_mesh%,Light)
cc#=EntityDistance(Cam,Light)
angle#=ACos((aa^2+cc^2-bb^2)/(2*aa*cc))/180.0
If angle>1 Then angle=1
If angle<0 Then angle=0

; Calculate the glow intensity according to sun light angle and distance to planet
intensity#=1-(1.0/Exp(GlowScale*angle))
If intensity<0 Then intensity=0
If intensity>1 Then intensity=1

; Calculate the horizon glow scale multiplicator
horizon#=1-(1.2/Exp(GlowScale*angle/2.0))
If horizon<0 Then horizon=0
If horizon>1 Then horizon=1

; Update ring intensity according to sun light angle and distance to planet
UpdateRing(systeme\Glow1,0.6*systeme\durchmesser2#,0.01*systeme\durchmesser2#,RingDetail,R1*intensity,G1*intensity,B1*intensity,angle,R2*(angle-intensity),G2*(angle-intensity),B2*(angle-intensity), 0,systeme\durchmesser2#/3.0)
UpdateRing(systeme\Glow2,(1.0-(horizon/10.0))*systeme\durchmesser2#,(1.05+(horizon/10.0))*systeme\durchmesser2#,RingDetail,R1*intensity,G1*intensity,B1*intensity,1.0-horizon,R2*angle,G2*angle,B2*angle,0,horizon*2)

; Scale the rings and always point to player
ScaleEntity systeme\GlowPivot,GlowScale,GlowScale,GlowScale

;ScaleEntity systeme\planet_mesh%,MeshWidth(systeme\Glow2)/2,MeshWidth(systeme\Glow2)/2,MeshWidth(systeme\Glow2)/2
PointEntity systeme\GlowPivot,Player

; Calculate the background color to simulate atmosphere penetration
clscol#=(1-(5.0/Exp(GlowScale*angle/2.0)))*intensity
If clscol<0 Then clscol=0
If clscol>1 Then clscol=1
CameraClsColor Cam,R2*clscol,G2*clscol,B2*clscol
; Change Starbox alpha
EntityAlpha StarBox,1-clscol

Next

End Function

; Player movement
Function Movement(scale#,distance#)

Local roll#,mox#,moz#,cx#,cz#
Local t1#,t2#

; get mouse position
MX=MouseX()
MY=MouseY()

; Movement with speed limit
cx=(KeyDown(205)-KeyDown(203))*CameraSpeed
cz=(KeyDown(200)-KeyDown(208))*CameraSpeed

; Arrow left/right = roll
If KeyDown(203) Then roll=RollSpeed
If KeyDown(205) Then roll=-RollSpeed

; Normalize Mouse position (-1 to +1)
t1=Normalize(MY,0,ScreenHeight,-1,1)
t2=Normalize(MX,0,ScreenWidth,1,-1)

; Slower cursor movement in the center of the screen
If t1<0 Then t1=(Abs(t1)^2.0)*-1 Else t1=t1^2.0
If t2<0 Then t2=(Abs(t2)^2.0)*-1 Else t2=t2^2.0

; Rotate ship mesh and turn player pivot
RotateEntity Ship,t1*MaxRollAngle,t2*MaxRollAngle,t2*MaxRollAngle*2
TurnEntity Player,t1*TurnSpeed*Tween,t2*TurnSpeed*Tween,roll*TurnSpeed*Tween

; Move the player forward/backward
MoveEntity Player,0,0,(cz*1.0/(scale)^3)*Tween

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

Function CreateQuad()

; Create mesh and surface
Local mesh%=CreateMesh()
Local surf%=CreateSurface(mesh)

; Add vertices
Local v0%=AddVertex(surf, 1.0, 1.0, 0.0, 0.0, 0.0 ) ; upper left
Local v1%=AddVertex(surf, -1.0, 1.0, 0.0, 1.0, 0.0 ) ; upper right
Local v2%=AddVertex(surf, -1.0, -1.0, 0.0, 1.0, 1.0 ) ; lower right
Local v3%=AddVertex(surf, 1.0, -1.0, 0.0, 0.0, 1.0 ) ; lower left

; Connect vertices
AddTriangle surf,v0,v1,v2
AddTriangle surf,v0,v2,v3

Return mesh

End Function

; Create a simple sun texture
Function CreateSunTexture()

Local tex%=CreateTexture(512,512,2)
Local tb%=TextureBuffer(tex)

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

SetBuffer tb
LockBuffer tb

; Intensity steps
For j=0 To 255

; Exponential falloff
col=Int((1.0/Exp(j*0.075))*100000000)
If col>255 Then col=255
rgb=col*$1000000+col*$10000+col*$100+col

; Draw circles
For i=0 To 360 Step 0.1
WritePixelFast 256+(Sin(i)*j),256+(Cos(i)*j),rgb,tb
Next

Next

UnlockBuffer tb
SetBuffer BackBuffer()

Return tex

End Function




; ##########################################################



Function ADD_Planet(name$ , x1%,y1%,x2#,y2#,typ%,klasse%=1 ,Durchmesser2#)


; Planet
tmp_Planet1% =CreateSphere(60)
ScaleEntity tmp_Planet1%,durchmesser2#,durchmesser2#,durchmesser2#


wolken_schicht%=CreateSphere(60)
ScaleEntity wolken_schicht%,durchmesser2#+0.1,durchmesser2#+0.1,durchmesser2#+0.1


EntityColor tmp_Planet1%,212,43,56
EntityColor wolken_schicht%,212,43,56

;textur% = LoadTexture ("earth2.bmp")
;EntityTexture tmp_Planet1%,textur%,0,1

;wolken% = LoadTexture ("clouds.bmp",2)
;EntityTexture wolken_schicht%,wolken%


; Glow
GlowPivot=CreatePivot()
Glow1=CreateRing(1+2+16+32,1)
Glow2=CreateRing(1+2+16+32,3)
EntityParent Glow1,GlowPivot
EntityParent Glow2,GlowPivot
EntityOrder Glow1,1
EntityOrder Glow2,1



systeme.Datenbank_Systeme_Planeten= New Datenbank_Systeme_Planeten
systeme\Objekt_Name$ = name$

systeme\System_pos_x# =x2#
systeme\System_pos_y# =y2#
systeme\grundtype% = typ%
systeme\klasse%=klasse%
systeme\planet_mesh%=tmp_Planet1%
systeme\planet_wolken%=wolken_schicht%
systeme\glowpivot%=GlowPivot

systeme\Glow1%=Glow1
systeme\Glow2%=Glow2
systeme\durchmesser2#=durchmesser2#
Return tmp_Planet1%

End Function

; ##########################################################

Function update_planeten()

For systeme.Datenbank_Systeme_Planeten = Each Datenbank_Systeme_Planeten
PositionEntity systeme\planet_mesh%,systeme\System_pos_x#,0,systeme\System_pos_y#
PositionEntity systeme\planet_wolken% ,systeme\System_pos_x# ,0,systeme\System_pos_y#
PositionEntity systeme\glowpivot% ,systeme\System_pos_x# ,0,systeme\System_pos_y#
;DebugLog systeme\Objekt_Name$+" auf pso " + System_pos_x#

TurnEntity systeme\planet_wolken% ,0,0.001,0

Next


End Function


kannst du mir vieleicht weiterhelfen. die formeln in deinem code sind mir leider ein pissel zu hoch.

mfg shaggy

LINKed

BeitragSa, Nov 21, 2009 13:32
Antworten mit Zitat
Benutzer-Profile anzeigen
sieht gut aus, aber man sollte vielleicht die atmosphäre die von der Sonne abgewendet ist dunkler machen.
Es sieht komisch aus wenn der Boden dunkel ist, aber der Himmel leuchtend blau.
 

Krischan

BeitragMo, Nov 23, 2009 15:54
Antworten mit Zitat
Benutzer-Profile anzeigen
Also ich blicke da bei Deinem Code nicht so ganz durch. Beschäftige Dich am Besten erst einmal mit dem zugrunde liegenden Prinzip wie ich den Ring / die Atmosphäre ursprünglich erstellt habe, das steht in diesem Post (der ganze Thread drumherum ist auch interessant):

https://www.blitzforum.de/foru...822#312051
 

Krischan

BeitragMi, Nov 25, 2009 18:49
Antworten mit Zitat
Benutzer-Profile anzeigen
Jetzt habe ich noch einmal selbst an meinem Beispiel herumgebastelt und - nachdem ich alles komplett umschreiben musste habe ich gleich ein ganzes Sonnensystem daraus gebastelt. Es ist unglaublich schwierig die Distanzen einigermassen unter einen Hut zu bringen, so dass der Eindruck entsteht dass man wirklich durch ein Sonnensystem fliegt, aber trotzdem noch in Atmosphären von Planeten eintauchen kann. Geht bestimmt noch eleganter aber so läuft es erstmal und taugt als Beispiel.

Die Steuerung ist wieder ganz einfach gehalten:
Maus = Zielrichtung
Pfeiltasten = vor/zurück sowie Rollen
Linke Maustaste = 10x Zoom
Rechte Maustaste = 10x schneller
SPACE = Wireframe

So sieht die Demo aus
user posted image

Und hier ein gepimpter Screenshot mit Milchstrasse und Raumschiff, 99% gleiche Codebasis
user posted image

Und hier der Code
Code: [AUSKLAPPEN]
Graphics3D 800,600,32,2


;Include "milkyway.bb"


; the answer to all questions
SeedRnd 42


; Frametween stuff
Global GameSpeed%=60
Global Screenwidth%=GraphicsWidth()
Global Screenheight%=GraphicsHeight()
Global FramePeriod%=1000/GameSpeed
Global FrameTime%=MilliSecs()-FramePeriod


; variables
Global RingDetail%   = 120
Global TargetDist#   = 10000
Global RollSpeed#   = 1.0
Global TurnSpeed#   = 2.0
Global MaxRoll#      = 20.0
Global Speed#      = 500
Global CursorSize%   = 33


; Glow Color scheme
Const R1%=192,G1%=224,B1%=255
Const R2%=128,G2%=160,B2%=255


; player / movement
Global MX%,MY%,Player%,MouseTarget%,Cam%,Ship%,Cursor%,Cross%,movedistance#,speedtimer%,mm#,wf%


; nearest object
Global nearestdist#,nearestscale#,nearestname%,nearestglowscale#


; scene objects
Global Light%,Sun0%,Sun1%,Sun2%,Sun3%;,MilkyWay%
Global masterpivot%,solidpivot%,wiredpivot%


; homekeeping
Global localx#,localy#,localz#
Global globalx#,globaly#,globalz#
Global simx#,simy#,simz#
Global newx#,newy#,newz#
Global oldx#,oldy#,oldz#


; planet type
Type planet
   
   Field id%
   Field Planet%
   Field GlowPivot%
   Field Glow1%
   Field Glow2%
   Field Scale#
   Field glowscale#
   Field d#
   Field angle#
   Field intensity#
   Field horizon#
   Field clscol#
   Field orbit%
   Field radius#
   Field atmofactor#
   
End Type


; Init Player and Scene
InitPlayer()
InitScene()

; initiate homekeeping and movespeed calculation
HomeKeeping(Player,masterpivot,1000)
oldx=simx
oldy=simy
oldz=simz


; Center mouse and hide pointer
MoveMouse Screenwidth/2,Screenheight/2
HidePointer


; Main loop
While Not KeyHit(1)
   
   Cls
   
   Local FrameElapsed%,FrameTicks%,FrameTween#,t%
   
   Repeat FrameElapsed=MilliSecs()-FrameTime Until FrameElapsed
   FrameTicks=FrameElapsed/FramePeriod
   FrameTween=Float(FrameElapsed Mod FramePeriod)/Float(FramePeriod)
   
   ; main tweened loop
   For t=1 To FrameTicks
      
      FrameTime=FrameTime+FramePeriod : If t=FrameTicks Then CaptureWorld
      
      ; SPACE = Wireframe
      If KeyHit(57) Then wf%=1-wf : WireFrame wf
      
      ; updates scene
      UpdateScene(p.planet)
      
      ; moves player
      Movement()
      
      ; keeps the player in its "home area"
      HomeKeeping(Player,masterpivot,1000)
      
      ; calcs the speed/sec
      CalcSpeed()
      
      ; sorts the planets
      SortPlanets()
      
      ; updates the planets atmospheres
      UpdatePlanets(p.planet)
      
      ; attaches galaxy to player
      ;PositionEntity MilkyWay,localx,localy,localz
      
      UpdateWorld
      
   Next
   
   ; tweened render Wireframe
   WireFrame 1
   ShowEntity wiredpivot
   HideEntity solidpivot
   ;HideEntity MilkyWay
   CameraClsMode Cam,1,1
   RenderWorld FrameTween
   
   ; tweened render solid objects
   WireFrame wf
   HideEntity wiredpivot
   ShowEntity solidpivot
   ;ShowEntity MilkyWay
   CameraClsMode Cam,0,0
   RenderWorld FrameTween
   
   ; draw planet names
   DrawPlanetNames(p)
   
   ; Draw cursor and crosshair by chasing the mousetarget
   CameraProject Cam,EntityX(MouseTarget,1),EntityY(MouseTarget,1),EntityZ(MouseTarget,1)
   DrawImage Cursor,MX-(CursorSize/2),MY-(CursorSize/2)
   DrawImage Cross,ProjectedX()-(CursorSize/2),ProjectedY()-(CursorSize/2)
   
   ; Statistics
   Text 0, 0,"Triangles rendered....: "+TrisRendered()
   Text 0,15,"Distance To Sun.......: "+(EntityDistance(Player,Sun0)/100)+" Mio. km"
   Text 0,30,"Nearest Planet........: "+Int((nearestdist-nearestscale)*100)+"km [Planet "+nearestname+"]"
   Text 0,45,"Movespeed.............: "+(movedistance*100)+"km/s ["+((movedistance*100)/299792)+"c]"
   Text 0,60,"Player Position X/Y/Z.: "+simx+" / "+simy+" / "+simz
   
   Flip 0
   
Wend

End


; updates the planets distances, the speed multiplicator, the camerarange, the lightrange and the sunscale
Function UpdateScene(p.planet)
   
   Local cr#,sunscale#
   
   For p.planet = Each planet
      
      p\d=EntityDistance(Player,p\Planet)
      
      ; Update atmosphere glow
      UpdateAtmosphere(p)
      
   Next
   
   ; calculate speed multiplicator
   If (nearestdist-nearestscale)<50000 Then mm#=(nearestdist-nearestscale)/50000 Else mm=1
   
   ; adjust camerarange
   cr=Abs(mm):If cr<0.1 Then cr=0.1
   CameraRange Cam,cr,5000000
   
   ; adjust lightrange
   LightRange Light,EntityDistance(Player,Sun0)*2
   
   ; sun quads point to player
   PointEntity Sun0,Player
   PointEntity Sun1,Player
   PointEntity Sun2,Player
   PointEntity Sun3,Player
   
   ; adjust sunscale
   sunscale=((1-(1.0/Exp(EntityDistance(Player,Sun0)*0.0000001)))*500000)
   ScaleEntity Sun0,sunscale,sunscale,sunscale
   
End Function


; updates the planets atmospheres
Function UpdatePlanets(p.planet)
   
   Local flag%=0
   
   For p.planet = Each planet
      
      ; first planet = nearest planet
      If p\d>0 And flag=0 Then
         
         flag=1
         
         ; set nearest variables
         nearestdist#=p\d
         nearestscale#=p\Scale*1.005
         nearestname%=p\id
         nearestglowscale#=p\glowscale
         
         ; update background color ("sky")
         CameraClsColor Cam,R2*p\clscol,G2*p\clscol,B2*p\clscol
         
         ; fade galaxy and stars
         ;UpdatePatch(Starbox,255,255,255,1-(p\clscol*1.1),False,True)
         ;UpdatePatch(Fogpanorama,255,255,255,1-(p\clscol*1.1),False,True)
         ;UpdatePatch(Starsphere,255,255,255,1-(p\clscol*1.1),False,True)
         
         ; switch blend mode
         EntityBlend p\Planet,1
         ShowEntity p\GlowPivot
         
         ; Update ring intensity according to sun light angle and distance to planet
         UpdateRing(p\Glow1,0.6*p\Scale,0.01*p\Scale,RingDetail,R1*p\intensity,G1*p\intensity,B1*p\intensity,p\angle,R2*(p\angle-p\intensity),G2*(p\angle-p\intensity),B2*(p\angle-p\intensity),   0,p\atmofactor*p\Scale/3.0)
         UpdateRing(p\Glow2,(1.0-(p\horizon/10.0))*p\Scale,(1.05+(p\horizon/10.0))*p\Scale,RingDetail,R1*p\intensity,G1*p\intensity,B1*p\intensity,1.0-p\horizon,R2*p\angle,G2*p\angle,B2*p\angle,0,p\atmofactor*p\horizon*2)
         
         ; Scale the rings and always point to player
         ScaleEntity p\GlowPivot,p\glowscale,p\glowscale,p\glowscale
         PointEntity p\GlowPivot,Player
         
      Else
         
         ; switch blend mode and hide glow
         EntityBlend p\Planet,3
         HideEntity p\GlowPivot
         
      EndIf
      
      ; fade orbit
      UpdatePatch(p\orbit,64,64,64,0.5/Exp(nearestglowscale),False)
      
   Next
   
End Function


; draws the planet name above the current position, visible only
Function DrawPlanetNames(p.planet)
   
   ; draw planet names
   For p.planet = Each planet
      
      If EntityInView(p\Planet,Cam) Then
         
         CameraProject Cam,EntityX(p\Planet)-globalx,EntityY(p\Planet)-globaly,EntityZ(p\Planet)-globalz
         Text ProjectedX()-4,ProjectedY()-20,p\id
         
      EndIf
      
   Next
   
End Function


; keeps the player in a given distance while the world can move far away
Function HomeKeeping(player%,world%,homesize%=100)
   
   ; store local player position
   localx=EntityX(player)
   localy=EntityY(player)
   localz=EntityZ(player)
   
   ; check X axis
   While localx>homesize
      globalx=globalx+homesize
      localx=localx-homesize
      PositionEntity player,localx,localy,localz
      MoveEntity world,-homesize,0,0
   Wend
   While localx<-homesize
      globalx=globalx-homesize
      localx=localx+homesize
      PositionEntity player,localx,localy,localz
      MoveEntity world,homesize,0,0
   Wend
   
   ; check Y axis
   While localy>homesize
      globaly=globaly+homesize
      localy=localy-homesize
      PositionEntity player,localx,localy,localz
      MoveEntity world,0,-homesize,0
   Wend
   While localy<-homesize
      globaly=globaly-homesize
      localy=localy+homesize
      PositionEntity player,localx,localy,localz
      MoveEntity world,0,homesize,0
   Wend
   
   ; check Z axis
   While localz>homesize
      globalz=globalz+homesize
      localz=localz-homesize
      PositionEntity player,localx,localy,localz
      MoveEntity world,0,0,-homesize
   Wend
   While localz<-homesize
      globalz=globalz-homesize
      localz=localz+homesize
      PositionEntity player,localx,localy,localz
      MoveEntity world,0,0,homesize
   Wend
   
   ; store simulated player position
   simx=localx+globalx
   simy=localy+globaly
   simz=localz+globalz
   
End Function


; sorts planets by distance to player
Function SortPlanets()
   
   Local o.planet,no.planet,o1.planet,o2.planet,t%
   
   no=After First planet
   
   While no<>Null
      
      o=no
      no=After o
      o1=o:t=o\d
      
      Repeat
         
         o2=Before o1
         If o2=Null Then Exit
         If t>=o2\d Then Exit
         o1=o2
         
      Forever
      
      o2=o
      Insert o2 Before o1
      
   Wend
   
End Function


; The functions that creates the mesh and surface for a ring
Function CreateRing(fx%=0,blend%=0,parent%=False,x#=0.0,y#=0.0,z#=0.0,order%=False)
   
   Local mesh=CreateMesh(),surf%
   
   surf=CreateSurface(mesh)
   
   ; Ring fx
   If fx Then EntityFX mesh,fx
   If blend Then EntityBlend mesh,blend
   If parent Then EntityParent mesh,parent
   If order Then EntityOrder mesh,order
   PositionEntity mesh,x,y,z
   
   Return mesh
   
End Function


; Re-creates the ring vertices and triangles with different values
Function UpdateRing(mesh%,radius1#=1.0,radius2#=2.0,segments%=360,r1%=255,g1%=255,b1%=255,alpha1#=1.0,r2%=0,g2%=0,b2%=0,alpha2#=1.0,scale#=0.0)
   
   Local a1#,a2#,angle%
   Local v0%,v1%,v%
   
   ; get and clear the surface
   Local surf=GetSurface(mesh,1)
   ClearSurface surf,1,1
   
   ; Limit segments
   If segments>360 Then segments=360
   
   ; Create ring
   For angle=0 To segments
      
      a1=angle*360.0/segments
      a2=angle*360.0/segments+180.0/segments
      
      ; Calc vertex points
      v0=AddVertex(surf,radius1*Cos(a1),radius1*Sin(a1),0,0,0)
      v1=AddVertex(surf,radius2*Cos(a2),radius2*Sin(a2),scale,1,1)
      
      ; Color
      VertexColor surf,v0,r1,g1,b1,alpha1
      VertexColor surf,v1,r2,g2,b2,alpha2
      
   Next
   
   ; Create Triangles
   For v=0 To CountVertices(surf)-3
      
      AddTriangle(surf,v,v+1,v+2)
      
   Next
   
   Return mesh
   
End Function


; Initialize player, camera
Function InitPlayer()
   
   Local i%
   
   ; Player pivot
   Player=CreatePivot()
   PositionEntity Player,-7280,25,-6961
   
   ; Ship mesh
   Ship=CreateCube(Player)
   EntityFX Ship,1
   ScaleEntity Ship,0.2,0.05,0.2
   PositionEntity Ship,0,-0.5,1.5
   EntityOrder Ship,-1000
   
   ; Mousetarget in space
   MouseTarget=CreatePivot(Ship)
   PositionEntity MouseTarget,0,0,TargetDist
   
   ; Camera
   Cam=CreateCamera(Player)
   PositionEntity Cam,0,0,0
   CameraRange Cam,1,5000000
   CameraFogMode Cam,True
   CameraFogRange Cam,500000,1000000
   
   ; Create cursor image
   Cursor=CreateImage(CursorSize,CursorSize)
   SetBuffer ImageBuffer(Cursor)
   For i=0 To 2
      Color 0,Int(255.0/(1+i)),0
      Rect i,i,CursorSize-(2*i),CursorSize-(2*i),0
   Next
   
   ; Create crosshair image
   Cross=CreateImage(CursorSize,CursorSize)
   SetBuffer ImageBuffer(Cross)
   Color 255,0,0
   Line (CursorSize-1)/2.0,0,(CursorSize-1)/2.0,CursorSize
   Line 0,(CursorSize-1)/2.0,CursorSize,(CursorSize-1)/2.0
   
   ; reset buffer and color
   SetBuffer BackBuffer()
   Color 255,255,255
   
End Function


; Initialize scene
Function InitScene()
   
   Local i%,suntex%
   
   masterpivot=CreatePivot()
   solidpivot=CreatePivot(masterpivot)
   wiredpivot=CreatePivot(masterpivot)
   
   ; Sunlight
   Light=CreateLight(2,solidpivot)
   PositionEntity Light,0,0,0
   AmbientLight 0,0,0
   LightRange Light,100
   
   ; Create Sun Texture
   suntex=CreateSunTexture()
   
   ; Sun Quads
   Sun0=CreateQuad(Light,1000,suntex,3,1+8,255,255,255,1.00)
   Sun1=CreateQuad(Light,1500,suntex,3,1+8,255,192,128,1.00)
   Sun2=CreateQuad(Light,3000,suntex,3,1+8,255,255,224,0.75)
   Sun3=CreateQuad(Light,6000,suntex,3,1+8,255,255,224,0.50)
   
   ; Milkyway background
   ;MilkyWay=InitMilkyway(1000,0.5,10,40,Sun0,10,0,0,0,1,128,96,64,1,0,0,0,1)
   
   For i=1 To 9
   
      p.planet = New planet
      p\planet=CreateSphere(64,solidpivot)
      p\scale=50+Rnd(i*10,i*2*10)
      p\atmofactor=Sqr(p\scale^4.2)/10000.0
      p\radius=(4+3*2^(i-1))*1000
      p\id=i
      
      RotateEntity p\planet,0,Rnd(0,360),0
      MoveEntity p\planet,0,0,p\radius
      ScaleEntity p\planet,p\scale,p\scale,p\scale
      EntityColor p\planet,32,128,64
      
      p\glowpivot=CreatePivot(solidpivot)
      PositionEntity p\glowpivot,EntityX(p\planet),EntityY(p\planet),EntityZ(p\planet)
      p\glow1=CreateRing(1+2+16+32,1,p\glowpivot,0,0,0,1)
      p\glow2=CreateRing(1+2+16+32,3,p\glowpivot,0,0,0,1)
      
      p\orbit=CreateOrbit(360,0,p\radius,p\radius,128,255,128,0.0)
      EntityParent p\orbit,wiredpivot
   
   Next
   
   ; Player points to planet first
   PointEntity Player,Sun0
   
End Function


; updates a patch
Function UpdatePatch(mesh%,r%,g%,b%,a#,usealpha%=False,usevertexcolors%=False)
   
   Local surf%=GetSurface(mesh,1),v%
   
   For v=0 To CountVertices(surf)-1
      
      If usealpha Then a=VertexAlpha(surf,v)
      
      If usevertexcolors Then
         
         r=VertexRed(surf,v)
         g=VertexGreen(surf,v)
         b=VertexBlue(surf,v)
         
      EndIf
      
      VertexColor surf,v,r,g,b,a
   Next
   
End Function


; Update atmosphere glow and background color
Function UpdateAtmosphere#(p.planet)
   
   Local s2#,s2d#,aa#,bb#,cc#
   
   ; calculate ring scale with the help of two right-angled triangles and trigonometry
   s2#=p\Scale^2
   s2d#=s2/p\d
   p\glowscale#=(Sqr(s2+(p\Scale/Tan(90-(90-(90-ATan(Sqr((p\d-(s2d))*(s2d))/(p\d-(s2d)))))))^2))/p\Scale
   
   ; calculcate the sun light angle (1 = exactly between sun and planet, 0 = exactly behind the planet)
   aa#=EntityDistance(Cam,p\Planet)
   bb#=EntityDistance(p\Planet,Light)
   cc#=EntityDistance(Cam,Light)
   p\angle=ACos((aa^2+cc^2-bb^2)/(2*aa*cc))/180.0
   If p\angle>1 Then p\angle=1
   If p\angle<0 Then p\angle=0
   
   ; calculate the glow intensity according to sun light angle and distance to planet
   p\intensity=1-(1.0/Exp(p\glowscale*p\angle))
   If p\intensity<0 Then p\intensity=0
   If p\intensity>1 Then p\intensity=1
   
   ; calculate the horizon glow scale multiplicator
   p\horizon=1-(1.2/Exp(p\glowscale*p\angle/2.0))
   If p\horizon<0 Then p\horizon=0
   If p\horizon>1 Then p\horizon=1
   
   ; calculate the background color to simulate atmosphere penetration
   p\clscol=(1-(5.0/Exp(p\glowscale*p\angle/2.0)))*p\intensity
   If p\clscol<0 Then p\clscol=0
   If p\clscol>1 Then p\clscol=1
   
End Function


; Player movement
Function Movement()
   
   Local roll#,cx#,cz#,multi%,limit#
   Local t1#,t2#
   
   ; get mouse position
   MX=MouseX()
   MY=MouseY()
   
   ; Movement with speed limit
   cx=(KeyDown(205)-KeyDown(203))*Speed
   cz=(KeyDown(200)-KeyDown(208))*Speed
   
   ; LMB = adjust Camerazoom
   If MouseDown(1) Then CameraZoom Cam,10 Else CameraZoom Cam,1
   
   ; RMB or RSHIFT = speedup 10x
   If MouseDown(2) Or KeyDown(54) Then multi=10 Else multi=1
   
   ; Arrow left/right = roll
   If KeyDown(203) Then roll=RollSpeed
   If KeyDown(205) Then roll=-RollSpeed
   
   ; Normalize Mouse position (-1 to +1)
   t1=Normalize(MY,0,Screenheight,-1,1)
   t2=Normalize(MX,0,Screenwidth,1,-1)
   
   ; Rotate ship mesh and turn player pivot
   RotateEntity Ship,t1*MaxRoll,t2*MaxRoll,t2*MaxRoll*2
   TurnEntity Player,t1*TurnSpeed,t2*TurnSpeed,roll*TurnSpeed
   
   ; Move the player forward/backward
   MoveEntity Player,0,0,cz*Abs(mm)*multi
   
End Function


; quick distance calculation between two 3D points
Function Distance#(x1#,y1#,z1#,x2#,y2#,z2#)
   
   Return Sqr((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2))
   
End Function


; calculates moved units per second
Function CalcSpeed#(interval%=1000)
   
   Local ms%=MilliSecs()
   
   ; check each second
   If ms>speedtimer+interval Then
      
      ; store current position
      newx=simx
      newy=simy
      newz=simz
      
      ; calculate Distance between current and old position
      movedistance=Distance(oldx,oldy,oldz,newx,newy,newz)
      
      ; store old position
      oldx=simx
      oldy=simy
      oldz=simz
      
      ; reset timer
      speedtimer=ms
      
   EndIf
   
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


; creates a 3D wireframe orbit line
Function CreateOrbit(segments%,mesh=0,r1#=1,r2#=1.5,r%=255,g%=255,b%=255,a#=1.0)
   
   Local la#,na#,i%
   
   For i = 1 To segments
      
      na=la+(360.0/segments)
      mesh=CreateLine(mesh,Cos(la)*r1,0,Sin(la)*r2,Cos(na)*r1,0,Sin(na)*r2,r,g,b,a)
      la=na
      
   Next
   
   Return mesh
   
End Function


; creates a 3D line (for orbit)
Function CreateLine(mesh,x0#,y0#,z0#,x1#,y1#,z1#,r%=255,g%=255,b%=255,a#=1.0)
   
   Local surf%,v1%,v2%
   
   If mesh Then
      
      surf=GetSurface(mesh,1)
      
   Else
      
      mesh = CreateMesh()
      surf = CreateSurface(mesh)
      EntityFX mesh,1+2+16+32
      
   End If
   
    v1=AddVertex(surf,x1,y1,z1)
   v2=AddVertex(surf,x0,y0,z0)
   AddTriangle surf,v1,v1,v2
   
    VertexColor surf,v1,r,g,b,a
   VertexColor surf,v2,r,g,b,a
   
   Return mesh
   
End Function


; advanced quad creation
Function CreateQuad(parent%=False,scale#=1.0,tex%=False,blend%=False,fx%=False,r%=255,g%=255,b%=255,a#=1.0)
   
   ; create mesh and surface
   Local mesh%=CreateMesh()
   Local surf%=CreateSurface(mesh)
   
   ; add vertices
   Local v0%=AddVertex(surf, 1, 1,0,0,0)      ; upper left
   Local v1%=AddVertex(surf,-1, 1,0,1,0)      ; upper right
   Local v2%=AddVertex(surf,-1,-1,0,1,1)      ; lower right
   Local v3%=AddVertex(surf, 1,-1,0,0,1)      ; lower left
   
   ; connect vertices
   AddTriangle surf,v0,v1,v2
   AddTriangle surf,v0,v2,v3
   
   ; parent, fx, texcture and blending
   If parent Then EntityParent mesh,parent
   If fx Then EntityFX mesh,fx
   If tex Then EntityTexture mesh,tex
   If blend Then EntityBlend mesh,blend
   
   ; color and alpha
   EntityColor mesh,r,g,b
   EntityAlpha mesh,a
   
   ; vertexcolor and vertexalpha
   VertexColor surf,v0,r,g,b,a
   VertexColor surf,v1,r,g,b,a
   VertexColor surf,v2,r,g,b,a
   VertexColor surf,v3,r,g,b,a
   
   ; scale
   ScaleEntity mesh,scale,scale,scale
   
   Return mesh
   
End Function


; Create a simple but impressive sun texture
Function CreateSunTexture()
   
   Local tex%=CreateTexture(512,512,3)
   Local tb%=TextureBuffer(tex)
   
   Local i#,j%,col%,rgb%
   
   SetBuffer tb
   LockBuffer tb
   
   ; Intensity steps
   For j=0 To 255
      
      col=255-j
      If col>255 Then col=255
      rgb=col*$1000000+col*$10000+col*$100+col
      
      ; Draw circles
      For i=0 To 360 Step 0.1
         WritePixelFast 256+(Sin(i)*j),256+(Cos(i)*j),rgb,tb
      Next
      
   Next
   
   UnlockBuffer tb
   SetBuffer BackBuffer()
   
   Return tex
   
End Function

Alkan

Betreff: Hmmm??

BeitragSo, Jan 10, 2010 19:46
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich find das sehr gut was du da programmiert hast,doch irgendwie klappt das bei mir nicht!
Ich hab blitz3d und da steht im debugger immer :
Zitat:
Function Not Found
kanns du mir vieleicht sagen wieso das passiert?
Ich hab den neusten Code von dir Kopiert und Eingefügt.
MfG
Alkan
Hauptrechner: Win7 Ultimate x64|AMD Phenom II X4 965 BlackEdition 4x3.4GHz|4 GB DualKit DDR3-1600 Ram|1.5 TB Samsung EcoGreen|Cougar CM 700Watt|ASRock M3A790GFX/120M|Nvidia GeForce 9500GT|Ati Radeon HD3300(Onboard-Deaktiviert)
Server(früher Hauptrechner): Ubuntu 9.1 x86|Intel P4 HT 3GHz|Ati Radeon X600Pro|200 GB HDD
Worklog: Planetensimulation
Homepage(Under Construction): alkan96.dyndns.org
Wenn schon falsch, dann richtig falsch.

Nicdel

BeitragSo, Jan 10, 2010 19:51
Antworten mit Zitat
Benutzer-Profile anzeigen
Welche Zeile ist markiert? Welche Blitz3D-Version hast du? (Version findest du unter "Help->About Blitz3D!")
Desktop: Intel Pentium 4 2650 Mhz, 2 GB RAM, ATI Radeon HD 3850 512 MB, Windows XP
Notebook: Intel Core i7 720 QM 1.6 Ghz, 4 GB DDR3 RAM, nVidia 230M GT, Windows 7

Alkan

Betreff: nicdel

BeitragSo, Jan 10, 2010 19:55
Antworten mit Zitat
Benutzer-Profile anzeigen
Da ist ja eben überhaupt keine zeile markiert.
Und die Version:
Alos da steht:
Zitat:
IDE V1.66 - Linker V1.64 - Runtime V1.66
Hauptrechner: Win7 Ultimate x64|AMD Phenom II X4 965 BlackEdition 4x3.4GHz|4 GB DualKit DDR3-1600 Ram|1.5 TB Samsung EcoGreen|Cougar CM 700Watt|ASRock M3A790GFX/120M|Nvidia GeForce 9500GT|Ati Radeon HD3300(Onboard-Deaktiviert)
Server(früher Hauptrechner): Ubuntu 9.1 x86|Intel P4 HT 3GHz|Ati Radeon X600Pro|200 GB HDD
Worklog: Planetensimulation
Homepage(Under Construction): alkan96.dyndns.org
Wenn schon falsch, dann richtig falsch.

Nicdel

BeitragSo, Jan 10, 2010 20:00
Antworten mit Zitat
Benutzer-Profile anzeigen
Geh auf www.blitzbasic.com , meld dich an und lad im "Account"-Bereich das neuste Update herunter.
Desktop: Intel Pentium 4 2650 Mhz, 2 GB RAM, ATI Radeon HD 3850 512 MB, Windows XP
Notebook: Intel Core i7 720 QM 1.6 Ghz, 4 GB DDR3 RAM, nVidia 230M GT, Windows 7

Chrise

Betreff: Re: nicdel

BeitragSo, Jan 10, 2010 20:06
Antworten mit Zitat
Benutzer-Profile anzeigen
Wie übel genial ist das denn?? Du bekommst meine Bewunderung, Krischan!
Sehr realistisch!

Einziges Problem. Aber ner bestimmten Nähe zum Planeten will das Raumschiff irgendwie nimmer weiterfliegen Wink
Llama 1 Llama 2 Llama 3
Vielen Dank an Pummelie, der mir auf seinem Server einen Platz für LlamaNet bietet.
 

Krischan

Betreff: Re: nicdel

BeitragMo, Jan 11, 2010 8:02
Antworten mit Zitat
Benutzer-Profile anzeigen
Chrise hat Folgendes geschrieben:
Einziges Problem. Aber ner bestimmten Nähe zum Planeten will das Raumschiff irgendwie nimmer weiterfliegen Wink


Das liegt an viel zu kleinen Werten, die bei meinen Funktionen irgendwann herauskommen müssen. Du musst eigentlich nur in der Movement-Funktion abfragen, dass der Bewegungswert (cz*Abs(mm)*multi) nicht zu klein wird. Falls ja: das Schiff stoppen oder in einen Autopilot-Orbit einschwenken lassen.

Neue Antwort erstellen


Übersicht BlitzBasic Codearchiv

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group