Graphics3D 800,600,32,2SetBuffer BackBuffer()Const TurnSpeed# = 4.000 ; cam turn speedConst RollSpeed# = 0.500 ; cam roll speedConst CameraSpeed# = 0.005 ; cam move speedConst Stars% = 240000 ; number of starsConst Spiralarms% = 4 ; number of spiral armsConst Spread# = 20.0 ; star spreadConst Rotation# = 4.0 ; how many spiral rotationsConst Range# = 100.0 ; milkyway radiusGlobal WIDTH%=GraphicsWidth()Global HEIGHT%=GraphicsHeight()Global TIMER%=CreateTimer(60)Global Scale#=WIDTH/3.0 ; star scaleGlobal meshes%[256]Global total%,vis%Local cam%,galaxy%,tex%Type quad Field surf% Field x#,y#,z# Field v% Field scale# Field r%,g%,b% Field lastdist# End Typetex=CreateSunTexture(256,128,128,128)TextureBlend tex,3; init galaxygalaxy=InitGalaxy(Stars,Spiralarms,Spread,Rotation,Range)For i=0 To galaxy If meshes[i]>0 Then EntityFX meshes[i],1+2 EntityBlend meshes[i],3 EntityTexture meshes[i],tex EndIf Next; init cameracam=CreateCamera()CameraRange cam,0.1,1000PositionEntity cam,0,90,150PointEntity cam,meshes[0]; update galaxy onceLocal cx#=EntityX(cam)Local cy#=EntityY(cam)Local cz#=EntityZ(cam)Local q.quad,d#,s#For q.quad = Each quad ; adaptive size d=Distance3D(qx,qy,qz,cx,cy,cz) s=(qscale/d)+(d/Scale) If s<d/Scale Then s=d/Scale ; align single surface quads to cam UpdateQuad(q.quad,s,cam) qlastdist=dNext MoveMouse WIDTH/2,HEIGHT/2; main loopWhile Not KeyHit(1) Local ms%,me% Movement(cam) ms=MilliSecs() i=i+1 : If i>=10 Then i=0 UpdateGalaxy(cam,Scale,i) me=MilliSecs()-ms RenderWorld WaitTimer TIMER AppTitle vis+" Stars updated ["+total+" Stars total] "+me+"ms" Flip 0 WendEnd; update quads in single surface meshFunction UpdateGalaxy(cam%,scale#=256.0,part%) Local cx#=EntityX(cam) Local cy#=EntityY(cam) Local cz#=EntityZ(cam) Local q.quad,d#,s#,steps%,i%,start%,ende% total=0 vis=0 steps=Stars/10 For q.quad = Each quad ; set start and end start=part*steps ende=(part+1)*steps ; check only current part or nearby stars If i>=start And i<ende Or qlastdist<5 Then TFormPoint qx,qy,qz,0,cam ; in front of cam? If TFormedZ()>0 Then ; adaptive size d#=Distance3D(qx,qy,qz,cx,cy,cz) s#=(qscale/d)+(d/scale) If s<d/scale Then s=d/scale ; store last distance calculation qlastdist=d ; align single surface quads to cam UpdateQuad(q.quad,s,cam) vis=vis+1 EndIf EndIf i=i+1 total=total+1 Next End Function; create galaxyFunction InitGalaxy%(stars%=10000,arms%=4,spread#=40.0,rot#=2.0,range#=100.0) Local mesh%=CreateMesh() Local surf%=CreateSurface(mesh) Local q.quad Local angle#,dist#,turb# Local i%,col#,multi#,lum#,bulge%,counter%,surfs%=1,m%=0 meshes[0]=mesh For i=1 To stars q.quad = New quad ; color col=Rnd(1) If col>0.90 And col<=1.00 Then q=255 : qg= 0 : q= 0 If col>0.70 And col<=0.90 Then q=255 : qg=255 : q= 0 If col>0.50 And col<=0.70 Then q= 0 : qg= 0 : q=255 If col>0.00 And col<=0.50 Then q=255 : qg=255 : q=255 ; angle angle=Int(Floor(i*1.0/(stars/arms)))*(360.0/arms) ; center / arm relation If Rnd(1)>0.5 Then multi=Rnd(0.1,1) Else multi=Rnd(1,2) ; distance and turbulence dist=Rnd(0,range)*Rnd(1,Rnd(Rnd(multi))) turb=Rnd(0,Rnd(spread)) : If Rnd(1)>0.5 Then turb=-turb ; more red/yellow stars in bulge lum=Rnd(1) If dist<range/2*lum Then If lum>0.75 Then q=255 : qg=0 : q=0 ; red stars Else If lum>0.5 Then q=255 : qg=255 : q=0 ; yellow stars EndIf Else If lum>0.75 Then q=0 : qg=0 : q=255 ; blue stars Else If lum>0.5 Then q=255 : qg=255 : q=255 ; white stars EndIf EndIf ; star position x/z qx=dist*Cos(angle+(dist*rot))+Rnd(Rnd(Rnd(-spread)),Rnd(Rnd(spread))) qz=dist*Sin(angle+(dist*rot))+Rnd(Rnd(Rnd(-spread)),Rnd(Rnd(spread))) ; star position y bulge=Normalize(Distance2D(qx,qz,0,0),0,range/2.0,0,180)/2.0 If bulge>90 Then bulge=90 qy=(Cos(bulge)*Rnd(Rnd(-spread),Rnd(spread))/2.0)+(turb/10.0) ; scale qscale=Rnd(0.01,Rnd(0.02,Rnd(0.04,0.08))) ; create new surface if too many vertices If counter+4>32000 Then If surfs+1>3 Then m=m+1 mesh=CreateMesh() meshes[m]=mesh surfs=0 EndIf surf=CreateSurface(mesh) counter=0 surfs=surfs+1 EndIf qsurf=surf ; add vertices qv=AddVertex(qsurf,0,0,0,0,0) AddVertex(qsurf,0,0,0,1,0) AddVertex(qsurf,0,0,0,1,1) AddVertex(qsurf,0,0,0,0,1) ; color vertices VertexColor qsurf,qv,q,qg,q VertexColor qsurf,qv+1,q,qg,q VertexColor qsurf,qv+2,q,qg,q VertexColor qsurf,qv+3,q,qg,q ; add triangles AddTriangle(qsurf,qv,qv+1,qv+2) AddTriangle(qsurf,qv,qv+2,qv+3) ; vertex counter counter=counter+4 Next DebugLog m Return m End Function; align single surface quad to camFunction UpdateQuad(q.quad,s#,target%) Local x1#,y1#,z1#,x2#,y2#,z2# TFormVector -s,0,0,target,0 x1=TFormedX() y1=TFormedY() z1=TFormedZ() TFormVector 0,-s,0,target,0 x2=TFormedX() y2=TFormedY() z2=TFormedZ() VertexCoords qsurf,qv+0,qx-x1-x2,qy-y1-y2,qz-z1-z2 VertexCoords qsurf,qv+1,qx-x1+x2,qy-y1+y2,qz-z1+z2 VertexCoords qsurf,qv+2,qx+x1+x2,qy+y1+y2,qz+z1+z2 VertexCoords qsurf,qv+3,qx+x1-x2,qy+y1-y2,qz+z1-z2 End Function; calculate 2D DistanceFunction Distance2D#(x1#,y1#,x2#,y2#) Local x#=x1-x2 Local y#=y1-y2 Return Sqr((x*x)+(y*y)) End Function; calucate 3D DistanceFunction Distance3D#(x1#,y1#,z1#,x2#,y2#,z2#) Local x#=x1-x2 Local y#=y1-y2 Local z#=z1-z2 Return Sqr((x*x)+(y*y)+(z*z)) End Function; normalize a valueFunction Normalize#(value#=128.0,vmin#=0.0,vmax#=255.0,nmin#=0.0,nmax#=1.0) Return ((value#-vmin#)/(vmax#-vmin#))*(nmax#-nmin#)+nmin# End Function; camera movementFunction Movement(cam%,sensitivity#=1.0) Local roll#,cz#,tx#,ty#,multi%=1 ; arrows = move / LMB = Turbo / RMB = Lightspeed / LMB+RMB = incredible speed cz=(KeyDown(200)-KeyDown(208))*CameraSpeed roll=(KeyDown(203)-KeyDown(205))*RollSpeed If MouseDown(1) Then multi=10 If MouseDown(2) Then multi=multi*10 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,0,0,cz*multi End Function; create a stunning sun textureFunction CreateSunTexture(size%=512,r%=255,g%=255,b%=255) Local tex%=CreateTexture(size,size,3) Local tb%=TextureBuffer(tex) Local i#,j%,col%,rgb% Local x%,y%,xx%,yy% Local a% LockBuffer tb For j=0 To (size/2)-1 col=255-Normalize(j,0,(size/2.0)-1,0,255) If col>255 Then col=255 rgb=col*$1000000+col*$10000+col*$100+col For i=0 To 360 Step 0.05 WritePixelFast (size/2)+(Sin(i)*j),(size/2)+(Cos(i)*j),rgb,tb Next Next UnlockBuffer tb ; temp camera Local tempcam%=CreateCamera() CameraRange tempcam,1,WIDTH*2 ; temp pivot Local tempsun%=CreatePivot() ; create 4 layers CreateQuad(tempsun,size/4.0,tex,3,1+8+16,r*1.00,g*1.00,b*1.00,1.00) CreateQuad(tempsun,size/1.5,tex,3,1+8+16,r*1.00,g*1.00,b*1.00,1.00) CreateQuad(tempsun,size/1.2,tex,3,1+8+16,r*0.75,g*0.75,b*0.50,0.75) CreateQuad(tempsun,size/1.0,tex,3,1+8+16,r*0.50,g*0.50,b*0.50,0.50) PositionEntity tempsun,0,0,WIDTH ; render it RenderWorld ; delete pivot FreeEntity tempsun LockBuffer BackBuffer() LockBuffer tb ; grab image For x=0 To size-1 For y=0 To size-1 xx=(WIDTH/2)-(size/2)+x yy=(HEIGHT/2)-(size/2)+y rgb=ReadPixelFast(xx,yy,BackBuffer()) r=(rgb And $ff0000)/$10000 g=(rgb And $ff00)/$100 b=(rgb And $ff) a=255 ; alpha If (r+g+b)/3 < 32 Then a=Normalize((r+g+b)/3,0,32,0,255) ; rgb rgb=(r+g+b)/3*$1000000+r*$10000+g*$100+b WritePixelFast x,y,rgb,tb Next Next UnlockBuffer tb UnlockBuffer BackBuffer() RenderWorld ; delete temp cam FreeEntity tempcam Return tex End Function; advanced quad creationFunction CreateQuad(parent%=False,scale#=1.0,tex%=False,blend%=False,fx%=False,r%=255,g%=255,b%=255,a#=1.0) Local mesh%=CreateMesh() Local surf%=CreateSurface(mesh) Local v0%=AddVertex(surf, 1, 1,0,0,0) Local v1%=AddVertex(surf,-1, 1,0,1,0) Local v2%=AddVertex(surf,-1,-1,0,1,1) Local v3%=AddVertex(surf, 1,-1,0,0,1) AddTriangle surf,v0,v1,v2 AddTriangle surf,v0,v2,v3 If parent Then EntityParent mesh,parent If fx Then EntityFX mesh,fx If tex Then EntityTexture mesh,tex If blend Then EntityBlend mesh,blend EntityColor mesh,r,g,b EntityAlpha mesh,a 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 ScaleEntity mesh,scale,scale,scale Return mesh End Function
If bulge>90 Then bulge=90 qy=(Cos(bulge)*Rnd(Rnd(-spread),Rnd(spread))/2.0)+(turb/10.0)
Import sidesign.minib3dGraphics3D 800, 600, 32, 2ClearTextureFilters()Const TurnSpeed:Float = 4.00Const RollSpeed:Float = 0.50Const CameraSpeed:Float = 0.01Const Stars:Int = 250000 ' number of starsConst Spiralarms:Int = 4 ' number of spiral armsConst Spread:Float = 20.0 ' star spreadConst Rotation:Float = 4.0 ' how many spiral rotationsConst Range:Float = 100.0 ' milkyway radiusConst QuatToEulerAccuracy:Double = 0.00001Global WIDTH:Int = GraphicsWidth()Global HEIGHT:Int = GraphicsHeight()Global TIMER:TTimer = CreateTimer(60)Global Scale:Float = WIDTH / 3.0 ' star scaleGlobal meshes:Int[256]Global total:Int, vis:IntLocal cam:TCamera, galaxy:Int, tex:TTexture, i:Int, g:IntType quad Global List:TList = CreateList() Method New() ListAddLast(List, Self) End Method Field surf:Int Field x:Float, y:Float, z:Float Field v:Int Field scale:Float Field r:Int, g:Int, b:Int Field lastdist:Float End Typetex = CreateSunTexture(256, 128, 128, 128)TextureBlend tex, 3' init galaxygalaxy = InitGalaxy(Stars, Spiralarms, Spread, Rotation, Range)For i = 0 To galaxy If meshes[i] > 0 Then EntityFX meshes[i], 1 + 2 EntityBlend meshes[i], 3 EntityTexture meshes[i], tex EndIf Next' init cameracam = CreateCamera()CameraRange cam, 0.1, 1000PositionEntity cam, 0, 90, 150PointEntity cam, meshes[0]' update galaxy onceLocal cx:Float = EntityX(cam)Local cy:Float = EntityY(cam)Local cz:Float = EntityZ(cam)Local q:quad, d:Float, s:FloatFor q:quad = EachIn quad.List ' adaptive size d = Distance3D(q.x, q.y, q.z, cx, cy, cz) s = (q.Scale / d) + (d / Scale) If s < d / Scale Then s = d / Scale ' align single surface quads to cam UpdateQuad(q:quad, s, cam) q.lastdist = d NextMoveMouse WIDTH / 2, HEIGHT / 2' main loopWhile Not AppTerminate() Cls ' Escape = Terminate If KeyHit(KEY_ESCAPE) Then End Movement(cam, 1) Local ms:Int, me:Int ms = MilliSecs() g = g + 1 If g >= 10 Then g = 0 UpdateGalaxy(cam, Scale, g) me = MilliSecs() - ms RenderWorld WaitTimer TIMER Text 0, 0, vis + " Stars updated [" + total + " Stars total] " + me + "ms" Flip 0 WendEndFunction Movement(cam:TCamera, sensitivity:Float = 1.0) Local roll:Float, cz:Float, tx:Float, ty:Float, multi:Int = 1 cz = (KeyDown(KEY_UP) - KeyDown(KEY_DOWN)) * CameraSpeed roll = (KeyDown(KEY_LEFT) - KeyDown(KEY_RIGHT)) * RollSpeed If KeyDown(KEY_RSHIFT) Or MouseDown(1) Then multi = 10 If MouseDown(2) Then multi = multi * 10 tx = Normalize(MouseX(), 0, GraphicsWidth(), 1, -1) ty = Normalize(MouseY(), 0, GraphicsHeight(), -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 TurnCam cam, ty * TurnSpeed, tx * TurnSpeed, roll * TurnSpeed MoveEntity cam, 0, 0, cz * multi End Function' update quads in single surface meshFunction UpdateGalaxy(cam:TEntity, scale:Float = 256.0, part:Int) Local cx:Float = EntityX(cam) Local cy:Float = EntityY(cam) Local cz:Float = EntityZ(cam) Local q:quad, d:Float, s:Float, steps:Int, i:Int, start:Int, ende:Int total = 0 vis = 0 steps = Stars / 10 For q:quad = EachIn quad.List ' set start and end start = part * steps ende = (part + 1) * steps ' check only current part or nearby stars If i >= start And i < ende Or q.lastdist < 5 Then TFormPoint q.x, q.y, q.z, 0, cam ' in front of cam? If TFormedZ() > 0 Then ' adaptive size d:Float = Distance3D(q.x, q.y, q.z, cx, cy, cz) s:Float = (q.Scale / d) + (d / Scale) If s < d / Scale Then s = d / Scale ' store last distance calculation q.lastdist = d ' align single surface quads To cam UpdateQuad(q:quad, s, cam) vis = vis + 1 EndIf EndIf i = i + 1 total = total + 1 Next End Function' Create galaxyFunction InitGalaxy:Int(stars:Int = 10000, arms:Int = 4, spread:Float = 40.0, rot:Float = 2.0, range:Float = 100.0) Local mesh:TMesh = CreateMesh() Local surf:TSurface = CreateSurface(mesh) Local q:quad Local angle:Float, dist:Float, turb:Float Local i:Int, col:Float, multi:Float, lum:Float, bulge:Int, counter:Int, surfs:Int = 1, m:Int = 0 meshes[0] = mesh For i = 1 To Stars q:quad = New quad ' color col = Rnd(1) If col > 0.90 And col <= 1.00 Then q.r = 255 q.g = 0 q.b = 0 EndIf If col > 0.70 And col <= 0.90 Then q.r = 255 q.g = 255 q.b = 0 EndIf If col > 0.50 And col <= 0.70 Then q.r = 0 q.g = 0 q.b = 255 EndIf If col > 0.00 And col <= 0.50 Then q.r = 255 q.g = 255 q.b = 255 EndIf ' angle angle = Int(Floor(i * 1.0 / (Stars / arms))) * (360.0 / arms) ' center / arm relation If Rnd(1) > 0.5 Then multi = Rnd(0.1, 1) Else multi = Rnd(1, 2) EndIf ' distance And turbulence dist = Rnd(0, Range) * Rnd(1, Rnd(Rnd(multi))) turb = Rnd(0, Rnd(Spread)) If Rnd(1) > 0.5 Then turb = -turb ' more red/yellow Stars in bulge lum = Rnd(1) If dist < Range / 2 * lum Then If lum > 0.75 Then q.r = 255 q.g = 0 q.b = 0 ' red Stars Else If lum > 0.5 Then q.r = 255 q.g = 255 q.b = 0 ' yellow Stars EndIf Else If lum > 0.75 Then q.r = 0 q.g = 0 q.b = 255 ' blue Stars Else If lum > 0.5 Then q.r = 255 q.g = 255 q.b = 255 ' white Stars EndIf EndIf ' star position x/z q.x = dist * Cos(angle + (dist * rot)) + Rnd(Rnd(Rnd(-Spread)), Rnd(Rnd(Spread))) q.z = dist * Sin(angle + (dist * rot)) + Rnd(Rnd(Rnd(-Spread)), Rnd(Rnd(Spread))) ' star position y bulge = Normalize(Distance2D(q.x, q.z, 0, 0), 0, Range / 2.0, 0, 180) / 2.0 If bulge > 90 Then bulge = 90 q.y = (Cos(bulge) * Rnd(Rnd(-Spread), Rnd(Spread)) / 2.0) + (turb / 10.0) ' Scale q.Scale = Rnd(0.01, Rnd(0.02, Rnd(0.04, 0.08))) ' Create New surface If too many vertices If counter + 4 > 32000 Then If surfs + 1 > 3 Then m = m + 1 mesh = CreateMesh() meshes[m] = mesh surfs = 0 EndIf surf = CreateSurface(mesh) counter = 0 surfs = surfs + 1 EndIf q.surf = surf ' add vertices q.v = AddVertex(q.surf, 0, 0, 0, 0, 0) AddVertex(q.surf, 0, 0, 0, 1, 0) AddVertex(q.surf, 0, 0, 0, 1, 1) AddVertex(q.surf, 0, 0, 0, 0, 1) ' color vertices VertexColor q.surf, q.v + 0, q.r, q.g, q.b VertexColor q.surf, q.v + 1, q.r, q.g, q.b VertexColor q.surf, q.v + 2, q.r, q.g, q.b VertexColor q.surf, q.v + 3, q.r, q.g, q.b ' add triangles AddTriangle(q.surf, q.v, q.v + 1, q.v + 2) AddTriangle(q.surf, q.v, q.v + 2, q.v + 3) ' vertex counter counter = counter + 4 Next Return m End Function' align single surface quad To camFunction UpdateQuad(q:quad, s:Float, target:TEntity) Local x1:Float, y1:Float, z1:Float, x2:Float, y2:Float, z2:Float TFormVector - s, 0, 0, target, 0 x1 = TFormedX() y1 = TFormedY() z1 = TFormedZ() TFormVector 0, -s, 0, target, 0 x2 = TFormedX() y2 = TFormedY() z2 = TFormedZ() VertexCoords q.surf, q.v + 0, q.x - x1 - x2, q.y - y1 - y2, q.z - z1 - z2 VertexCoords q.surf, q.v + 1, q.x - x1 + x2, q.y - y1 + y2, q.z - z1 + z2 VertexCoords q.surf, q.v + 2, q.x + x1 + x2, q.y + y1 + y2, q.z + z1 + z2 VertexCoords q.surf, q.v + 3, q.x + x1 - x2, q.y + y1 - y2, q.z + z1 - z2 End Function' calculate 2D DistanceFunction Distance2D:Float(x1:Float, y1:Float, x2:Float, y2:Float) Local x:Float = x1 - x2 Local y:Float = y1 - y2 Return Sqr((x * x) + (y * y)) End Function' calucate 3D DistanceFunction Distance3D:Float(x1:Float, y1:Float, z1:Float, x2:Float, y2:Float, z2:Float) Local x:Float = x1 - x2 Local y:Float = y1 - y2 Local z:Float = z1 - z2 Return Sqr((x * x) + (y * y) + (z * z)) End Function' Normalize a valueFunction Normalize:Float(value:Float = 128.0, vmin:Float = 0.0, vmax:Float = 255.0, nmin:Float = 0.0, nmax:Float = 1.0) Return ((value:Float - vmin:Float) / (vmax:Float - vmin:Float)) * (nmax:Float - nmin:Float) + nmin:Float End Function' Create a stunning sun textureFunction CreateSunTexture:TTexture(size:Int = 512, r:Int = 255, g:Int = 255, b:Int = 255) Local i:Float, j:Int, col:Int, rgb:Int Local tempcam:TCamera, tempsun:TPivot, tex:TTexture Local pixmap:TPixmap = CreatePixmap(size, size, PF_RGBA8888) Local source:TPixmap For j = 0 To (size / 2) - 1 col = 255 - Normalize(j, 0, (size / 2.0) - 1, 0, 255) If col > 255 Then col = 255 rgb = col * $1000000 + col * $10000 + col * $100 + col For i = 0 To 360 Step 0.1 WritePixel(pixmap, (size / 2) + (Sin(i) * j), (size / 2) + (Cos(i) * j), rgb) Next Next SavePixmapPNG(pixmap, "sun1.png") tex = LoadTexture("sun1.png", 2) ' temp camera tempcam = CreateCamera() CameraRange tempcam, 1, WIDTH * 2 ' temp pivot tempsun = CreatePivot() ' Create 4 layers CreateQuad(tempsun, size / 4.0, tex, 3, 1 + 8 + 16, r * 1.00, g * 1.00, b * 1.00, 1.00) CreateQuad(tempsun, size / 1.5, tex, 3, 1 + 8 + 16, r * 1.00, g * 1.00, b * 1.00, 1.00) CreateQuad(tempsun, size / 1.2, tex, 3, 1 + 8 + 16, r * 0.75, g * 0.75, b * 0.50, 0.75) CreateQuad(tempsun, size / 1.0, tex, 3, 1 + 8 + 16, r * 0.50, g * 0.50, b * 0.50, 0.50) PositionEntity tempsun, 0, 0, WIDTH ' render it RenderWorld RenderWorld source = GrabPixmap(0, 0, WIDTH, HEIGHT) ' grab image For x = 0 To size - 1 For y = 0 To size - 1 xx = (WIDTH / 2) - (size / 2) + x yy = (HEIGHT / 2) - (size / 2) + y rgb = ReadPixel(source, xx, yy) r = (rgb & $ff0000) / $10000 g = (rgb & $ff00) / $100 b = (rgb & $ff) ' rgb rgb = (r + g + b) / 3 * $1000000 + r * $10000 + g * $100 + b WritePixel(pixmap, x, y, rgb) Next Next SavePixmapPNG(pixmap, "sun2.png") ' Load texture tex = LoadTexture("sun2.png", 2) ' Delete pivot and temp cam FreeEntity tempsun FreeEntity tempcam Return tex End Function' advanced quad creationFunction CreateQuad:Tmesh(parent:TEntity, scale:Float = 1.0, tex:TTexture = Null, blend:Int = False, fx:Int = False, r:Int = 255, g:Int = 255, b:Int = 255, a:Float = 1.0) Local mesh:TMesh = CreateMesh() Local surf:TSurface = CreateSurface(mesh) Local v0:Int, v1:Int, v2:Int, v3:Int v0 = AddVertex(surf, 1, 1, 0, 0, 0) v1 = AddVertex(surf, -1, 1, 0, 1, 0) v2 = AddVertex(surf, -1, -1, 0, 1, 1) v3 = AddVertex(surf, 1, -1, 0, 0, 1) AddTriangle surf, v0, v1, v2 AddTriangle surf, v0, v2, v3 If parent Then EntityParent Mesh, parent If fx Then EntityFX Mesh, fx If tex Then EntityTexture Mesh, tex If blend Then EntityBlend Mesh, blend EntityColor Mesh, r, g, b EntityAlpha Mesh, a 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 ScaleEntity Mesh, Scale, Scale, Scale Return Mesh End FunctionFunction TurnCam(Ent:TEntity, X:Float, Y:Float, Z:Float, Glob:Int = False) Local Pitch:Float = 0.0 Local Yaw:Float = 0.0 Local Roll:Float = 0.0 Local Quat:TQuaternion = EulerToQuat( 0.0, 0.0, 0.0 ) Local Turn_Quat:TQuaternion = EulerToQuat( 0.0, 0.0, 0.0 ) If Glob=False Quat = EulerToQuat( EntityPitch( Ent, True ), EntityYaw( Ent, True ), EntityRoll( Ent, True ) ) Turn_Quat = EulerToQuat( X, Y, Z ) Quat = MultiplyQuats( Quat, Turn_Quat ) Quat = NormalizeQuat( Quat ) QuatToEuler2( Quat.x, Quat.y, Quat.z, Quat.w, Pitch, Yaw, Roll ) RotateEntity Ent, Pitch, Yaw, Roll Else RotateEntity Ent, EntityPitch( Ent )+X, EntityYaw( Ent )+Y, EntityRoll( Ent )+Z EndIf End FunctionFunction EulerToQuat:TQuaternion(pitch:Float,yaw:Float,roll:Float) Local cr:Float=Cos(-roll/2.0) Local cp:Float=Cos(pitch/2.0) Local cy:Float=Cos(yaw/2.0) Local sr:Float=Sin(-roll/2.0) Local sp:Float=Sin(pitch/2.0) Local sy:Float=Sin(yaw/2.0) Local cpcy:Float=cp*cy Local spsy:Float=sp*sy Local spcy:Float=sp*cy Local cpsy:Float=cp*sy Local q:TQuaternion=New TQuaternion q.w:Float=cr*cpcy+sr*spsy q.x:Float=sr*cpcy-cr*spsy q.y:Float=cr*spcy+sr*cpsy q.z:Float=cr*cpsy-sr*spcy Return q End FunctionFunction QuatToEuler2(x:Float,y:Float,z:Float,w:Float,pitch:Float Var,yaw:Float Var,roll:Float Var) Local sint:Float=(2.0*w*y)-(2.0*x*z) Local cost_temp:Float=1.0-(sint*sint) Local cost:Float If Abs(cost_temp)>QuatToEulerAccuracy cost=Sqr(cost_temp) Else cost=0.0 EndIf Local sinv:Float,cosv:Float,sinf:Float,cosf:Float If Abs(cost)>QuatToEulerAccuracy sinv=((2.0*y*z)+(2.0*w*x))/cost cosv=(1.0-(2.0*x*x)-(2.0*y*y))/cost sinf=((2.0*x*y)+(2.0*w*z))/cost cosf=(1.0-(2.0*y*y)-(2.0*z*z))/cost Else sinv=(2.0*w*x)-(2.0*y*z) cosv=1.0-(2.0*x*x)-(2.0*z*z) sinf=0.0 cosf=1.0 EndIf pitch=ATan2(sint,cost) yaw=ATan2(sinf,cosf) roll=-ATan2(sinv,cosv) End FunctionFunction MultiplyQuats:TQuaternion(q1:TQuaternion,q2:TQuaternion) Local q:TQuaternion=New TQuaternion q.w = q1.w*q2.w - q1.x*q2.x - q1.y*q2.y - q1.z*q2.z q.x = q1.w*q2.x + q1.x*q2.w + q1.y*q2.z - q1.z*q2.y q.y = q1.w*q2.y + q1.y*q2.w + q1.z*q2.x - q1.x*q2.z q.z = q1.w*q2.z + q1.z*q2.w + q1.x*q2.y - q1.y*q2.x Return qEnd FunctionFunction NormalizeQuat:TQuaternion(q:TQuaternion) Local uv:Float=Sqr(q.w*q.w+q.x*q.x+q.y*q.y+q.z*q.z) q.w=q.w/uv q.x=q.x/uv q.y=q.y/uv q.z=q.z/uv Return qEnd Function