Advertisement
Guest User

Untitled

a guest
Oct 1st, 2016
364
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
BlitzMax 29.15 KB | None | 0 0
  1. SuperStrict
  2. Framework sidesign.minib3d 'https://github.com/si-design/minib3d
  3. Import brl.Stream
  4. Import brl.linkedlist
  5. Import brl.standardio
  6. Import brl.bmploader
  7. Import brl.pngloader
  8.  
  9. 'Data sizes
  10. Const B_BYTE:Int = 1
  11. Const B_SHORT:Int = 2
  12. Const B_INT:Int = 4
  13. Const B_FLOAT:Int = 4
  14.  
  15. SetGraphicsDriver GLGraphicsDriver(),GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER
  16. Graphics3D(DesktopWidth() * 0.7, DesktopHeight() * 0.7, 0, 2)
  17. ClearTextureFilters()
  18.  
  19. Global camera:TCamera = CreateCamera()
  20. MoveEntity(camera, 0, 0, -10)
  21.  
  22. 'AmbientLight(255, 255, 255)
  23. 'Local light:TLight = CreateLight(1)
  24. 'RotateEntity(light, 45, 45, 0)
  25.  
  26. TQPalette.LoadPalette("palette.lmp")
  27. Global myBSP:TQBSP
  28. Global levelMesh:TMesh
  29. Global levelMeshAlpha:TMesh
  30.  
  31. 'Debug make a mesh
  32. Function GenerateBSPMesh(mesh:TMesh var, alphaMesh:TMesh var, myBSP:TQBSP)
  33.     If mesh Then FreeEntity(mesh)
  34.     If alphaMesh Then FreeEntity(alphaMesh)
  35.     'Local mesh:TMesh = CreateMesh()
  36.     'Local surf:TSurface[1024 * 10]
  37.    
  38.     GCCollect()
  39.    
  40.     mesh = CreateMesh()
  41.     alphaMesh = CreateMesh()
  42.    
  43.     Local face:TQFace
  44.     Local ledge:TQLedge
  45.     Local edge:TQEdge
  46.     Local plane:TQPlane
  47.     Local texInfo:TQSurface
  48.     Local vert:TQVertex
  49.     Local fNr:Int
  50.     Local vNr:Int
  51.     Local surf:TSurface
  52.     Local vertCount:Int
  53.     Local newVertCount:Int
  54.    
  55.     Local s:Float
  56.     Local t:Float
  57.    
  58.     For Local model:TQModel = EachIn myBSP.Models 'Go through models
  59.         For fNr = model.Face_ID Until model.Face_ID + model.Face_Num 'Go through faces
  60.             'Debug progress
  61.             'If fNr Mod 100 <= 0 Then Print "Generating: " + fNr + "/" + model.Face_Num
  62.             face = myBSP.Faces[fNr] 'Get current face
  63.             texInfo = myBSP.texInfo[face.TexInfo_ID]
  64.             plane = myBSP.PLANES[face.Plane_ID]
  65.            
  66.             If myBSP.MipTexs[texInfo.Texture_ID].Name.StartsWith("trigger") Then Continue
  67.            
  68.             'ERROR if we're using too many vertices
  69.             If face.Surface And face.Surface.CountVertices() > (10000 * 3) - 1 Then Print "TOO MANY VERTICES!!";End
  70.            
  71.             'If we don't have a surface to work with, create one
  72.             If Not face.Surface Then
  73.                 If myBSP.MipTexs[texInfo.Texture_ID].Name.StartsWith("*") Then
  74.                     face.Surface = CreateSurface(alphaMesh, Null)
  75.                 Else
  76.                     face.Surface = CreateSurface(mesh, Null)
  77.                 EndIf
  78.             EndIf
  79.            
  80.             surf = face.Surface
  81.            
  82.             'Get verts
  83.             newVertCount = 0
  84.             vertCount = surf.CountVertices()
  85.             For vNr = face.Ledge_ID Until face.Ledge_ID + face.Ledge_Num 'Go through edges
  86.                 ledge = myBSP.Ledges[vNr] 'Get ledge
  87.                 edge = myBSP.Edges[Abs(ledge.edge)] 'Get edge via ledge
  88.                
  89.                 If ledge.edge < 0 Then
  90.                     vert = myBSP.Vertices[edge.Vertex0]
  91.                 Else
  92.                     vert = myBSP.Vertices[edge.Vertex1]
  93.                 EndIf
  94.                
  95.                 AddVertex(surf, -vert.Y * 0.2, vert.Z * 0.2, vert.X * 0.2)
  96.                
  97.                 'Calculate UV
  98.                 s = DotProduct(vert.X, vert.Y, vert.Z, texInfo.VectorS.X, texInfo.VectorS.Y, texInfo.VectorS.Z) + texInfo.DistS
  99.                 t = DotProduct(vert.X, vert.Y, vert.Z, texInfo.VectorT.X, texInfo.VectorT.Y, texInfo.VectorT.Z) + texInfo.DistT
  100.                 'Based on texture size
  101.                 s:/myBSP.MipTexs[texInfo.Texture_ID].width
  102.                 t:/myBSP.MipTexs[texInfo.Texture_ID].Height
  103.                
  104.                 'Test UV for lightmap
  105.                 Select plane.Typ
  106.                     Case 0, 3 VertexTexCoords(surf, vertCount, (vert.z - face.LightMinPos.z) / face.LightDist.z, (vert.y - face.LightMinPos.y) / face.LightDist.y)
  107.                     Case 1, 4 VertexTexCoords(surf, vertCount, (vert.x - face.LightMinPos.x) / face.LightDist.x, (vert.z - face.LightMinPos.z) / face.LightDist.z)
  108.                     Case 2, 5 VertexTexCoords(surf, vertCount, (vert.x - face.LightMinPos.x) / face.LightDist.x, (vert.y - face.LightMinPos.y) / face.LightDist.y)
  109.                 EndSelect
  110.                
  111.                 'VertexTexCoords(surf, vertCount, s, t) 'Real texture UV
  112.                 VertexNormal(surf, vertCount, plane.Normal.Z, plane.Normal.Y, plane.Normal.X)
  113.                
  114.                 'This works but since lightmaps don't the level will be all black
  115.                 'VertexColor(surf, vertCount, 255 - face.BaseLight, 255 - face.BaseLight, 255 - face.BaseLight)
  116.                
  117.                 vertCount:+1
  118.                 newVertCount:+1
  119.             Next
  120.            
  121.             'Make Tris
  122.             For Local i:Int = vertCount - newVertCount Until vertCount - 2
  123.                 AddTriangle(surf, vertCount - newVertCount, i + 1, i + 2)
  124.             Next
  125.            
  126.             'PaintSurface(surf, myBSP.MipTexs[texInfo.Texture_ID].Brush)
  127.             If face.LightBrush Then PaintSurface(surf, face.LightBrush)
  128.         Next
  129.     Next
  130.    
  131.     EntityFX(mesh, 1 + 2)
  132.     EntityFX(alphaMesh, 1 + 2)
  133.    
  134.     'Return mesh
  135.     GCCollect()
  136. EndFunction
  137.  
  138. 'Print mesh.CountSurfaces()
  139.  
  140. Function RequestBSP()
  141.     Local filter:String = "BSP Files:bsp;All Files:*"
  142.     Local file:String = RequestFile("Select BSP file to load", filter:String)
  143.    
  144.     If file Then
  145.         PositionEntity(camera, -2, 2.5, -10)
  146.         RotateEntity(camera, 0, 0, 0)
  147.        
  148.         myBSP = TQBSP.LoadFile(file)
  149.         GenerateBSPMesh(levelMesh, levelMeshAlpha, myBSP)
  150.     EndIf
  151.    
  152.     FlushKeys()
  153.     FlushMouse()
  154. EndFunction
  155.  
  156. If FileSize(AppDir + "/dm1.bsp") > 0 Then
  157.     myBSP = TQBSP.LoadFile(AppDir + "/dm1.bsp")
  158.     GenerateBSPMesh(levelMesh, levelMeshAlpha, myBSP)
  159.    
  160.     PositionEntity(camera, -250, 30, 70)
  161.     RotateEntity(camera, 15, 180 + 25, 0)
  162. Else
  163.     RequestBSP()
  164. EndIf
  165.  
  166. 'Main loop
  167. While Not AppTerminate() And Not KeyDown(KEY_ESCAPE)
  168.     'Cls()
  169.     'If KeyHit(KEY_O) Then Wireframe(False)
  170.     If KeyDown(KEY_P) Then Wireframe(True)
  171.    
  172.     If KeyDown(KEY_LEFT) Then TurnEntity(camera, 0, 2, 0)
  173.     If KeyDown(KEY_RIGHT) Then TurnEntity(camera, 0, -2, 0)
  174.     If KeyDown(KEY_UP) Then TurnEntity(camera, -2, 0, 0)
  175.     If KeyDown(KEY_DOWN) Then TurnEntity(camera, 2, 0, 0)
  176.    
  177.     If KeyDown(KEY_W) Then MoveEntity(camera, 0, 0, 1.5)
  178.     If KeyDown(KEY_S) Then MoveEntity(camera, 0, 0, -1.5)
  179.     If KeyDown(KEY_A) Then MoveEntity(camera, -1.5, 0, 0)
  180.     If KeyDown(KEY_D) Then MoveEntity(camera, 1.5, 0, 0)
  181.    
  182.     If KeyDown(KEY_SPACE) Then MoveEntity(camera, 0, 1, 0)
  183.     If KeyDown(KEY_LCONTROL) Then MoveEntity(camera, 0, -1, 0)
  184.    
  185.     If KeyHit(KEY_TAB) Then RequestBSP()
  186.    
  187.     If myBSP Then myBSP.Update()
  188.     RenderWorld()
  189.    
  190.     BeginMax2D()
  191.     DrawText("TAB: Open BSP", 0, 0)
  192.     EndMax2D()
  193.    
  194.     Flip(1)
  195. Wend
  196. End
  197.  
  198. Type TQBSP
  199.     Field File:String
  200.     Field Stream:TStream
  201.    
  202.     Field Header:TQHeader
  203.    
  204.     Field PLANES:TQPlane[]
  205.     Field Vertices:TQVertex[]
  206.     Field Nodes:TList = CreateList()
  207.     Field TexInfo:TQSurface[]
  208.     Field MipTexHeader:TQMipHeader
  209.     Field MipTexs:TQMipTex[]
  210.     Field AnimatedMipTexs:TQMipTex[]
  211.     Field Faces:TQFace[]
  212.     Field ClipNodes:TList = CreateList()
  213.     Field Leaves:TList = CreateList()
  214.     Field Edges:TQEdge[]
  215.     Field Ledges:TQLedge[]
  216.     Field Models:TQModel[]
  217.     'Field LightMap:Byte[]
  218.    
  219.     Field StartMS:Int
  220.    
  221.     Function LoadFile:TQBSP(url:String)
  222.         Local nB:TQBSP = New TQBSP
  223.         nB.File = url
  224.        
  225.         If nB.Process() Then
  226.             Return nB
  227.         Else
  228.             nB.StreamError("Map ~q" + nB.file + "~q NOT loaded")
  229.             Return Null
  230.         EndIf
  231.     EndFunction
  232.    
  233.     Method Update()
  234.         For Local m:TQMipTex = EachIn Self.AnimatedMipTexs
  235.             PositionTexture(GetBrushTexture(m.Brush), (MilliSecs() - StartMS) * 0.00005, -(MilliSecs() - StartMS) * 0.0001)
  236.             RotateTexture(GetBrushTexture(m.Brush), (MilliSecs() - StartMS) * 0.0005)
  237.         Next
  238.     EndMethod
  239.    
  240.     Method StreamError(MSG:String)
  241.         If Stream Then CloseStream(Stream)
  242.         DebugLog "Read error: " + MSG
  243.     EndMethod
  244.    
  245.     Method Process:Int()
  246.         Stream = OpenStream(File)
  247.         If Not Stream Then
  248.             StreamError("Unable to read file ~q" + file + "~q")
  249.             Return False
  250.         EndIf
  251.        
  252.         Local num:Int 'For counting stuff
  253.         Local i:Int 'For loops
  254.        
  255.         'Read header
  256.         Self.Header = TQHeader.Read(Stream)
  257.        
  258.         'Read planes
  259.         num = Self.Header.PLANES.Count(TQPlane.Size())
  260.         DebugLog "Planes: " + num
  261.         Self.PLANES = New TQPlane[num]
  262.         Self.Header.PLANES.JumpTo(Stream)
  263.         For i = 0 Until num
  264.             'ListAddLast(Self.PLANES, TQPlane.Read(Stream))
  265.             Self.PLANES[i] = TQPlane.Read(Stream)
  266.         Next
  267.        
  268.         'Read vertices
  269.         num = Self.Header.Vertices.Count(TQVertex.Size())
  270.         DebugLog "Vertices: " + num
  271.         Self.Vertices = New TQVertex[num]
  272.         Self.Header.Vertices.JumpTo(Stream)
  273.         For i = 0 Until num
  274.             'ListAddLast(Self.Vertices, TQVertex.Read(Stream))
  275.             Self.Vertices[i] = TQVertex.Read(Stream)
  276.         Next
  277.        
  278.         'Read nodes
  279.         'num = Self.Header.Nodes.Count(TQNode.Size())
  280.         'DebugLog "Nodes: " + num
  281.         'Self.Header.Nodes.JumpTo(Stream)
  282.         'For i = 0 Until num
  283.         '   ListAddLast(Self.Nodes, TQNode.Read(Stream))
  284.         'Next
  285.        
  286.         'Read texture info
  287.         num = Self.Header.TexInfo.Count(TQSurface.Size())
  288.         DebugLog "TexInfo: " + num
  289.         Self.TexInfo = New TQSurface[num]
  290.         Self.Header.TexInfo.JumpTo(Stream)
  291.         For i = 0 Until num
  292.             Self.TexInfo[i] = TQSurface.Read(Stream)
  293.         Next
  294.        
  295.         'Read mipmap header
  296.         Self.Header.MipTex.JumpTo(Stream)
  297.         Self.MipTexHeader = TQMipHeader.Read(Stream)
  298.         num = Self.MipTexHeader._count
  299.         DebugLog "MipMap Texs: " + num
  300.        
  301.         'Read miptexs from mipmap header
  302.         'CreateDir(AppDir + "/tex/", True) 'Debug for exporting
  303.        
  304.         MipTexs = New TQMipTex[num]
  305.         For i = 0 Until num
  306.             Stream.Seek(Self.Header.MipTex.Offset + Self.MipTexHeader.Offset[i])
  307.             Self.MipTexs[i] = TQMipTex.Read(Stream)
  308.            
  309.             If Self.MipTexs[i].width > 1 And Self.MipTexs[i].Height > 1 Then
  310.                 Local pix:TPixmap = CreatePixmap(Self.MipTexs[i].width, Self.MipTexs[i].Height, PF_RGB888)
  311.                 Local x:Int
  312.                 Local y:Int
  313.                 Local colorID:Byte
  314.                 Local palColor:TQColor32
  315.                
  316.                 Stream.Seek(Self.Header.MipTex.Offset + Self.MipTexHeader.Offset[i] + Self.MipTexs[i].Offset1)
  317.                 For Local bI:Int = 0 Until pix.width * pix.Height
  318.                     colorID = ReadByte(Stream)
  319.                     palColor = TQPalette.colors[colorID]
  320.                    
  321.                     pix.WritePixel(x, y, GenRGB(palColor.r, palColor.g, palColor.b))
  322.                    
  323.                     x:+1
  324.                     If x >= pix.width Then
  325.                         x = 0
  326.                         y:+1
  327.                     EndIf
  328.                 Next
  329.                
  330.                 If pix Then
  331.                     Self.MipTexs[i].Brush = LoadBrushPixmap(pix, 0)
  332.                     If Self.MipTexs[i].Name.StartsWith("*") Then
  333.                         BrushAlpha(Self.MipTexs[i].Brush, 0.65)
  334.                         BrushBlend(Self.MipTexs[i].Brush, 1)
  335.                         AnimatedMipTexs = AnimatedMipTexs[..AnimatedMipTexs.Length + 1]
  336.                         AnimatedMipTexs[AnimatedMipTexs.Length - 1] = Self.MipTexs[i]
  337.                     EndIf
  338.                 EndIf
  339.             EndIf
  340.         Next
  341.        
  342.         'Read faces
  343.         num = Self.Header.Faces.Count(TQFace.Size())
  344.         DebugLog "Faces: " + num
  345.         Self.Faces = New TQFace[num]
  346.         Self.Header.Faces.JumpTo(Stream)
  347.         For i = 0 Until num
  348.             Self.Faces[i] = TQFace.Read(Stream)
  349.         Next
  350.        
  351.         'Read lightmaps
  352.         'Self.Header.LightMaps.JumpTo(Stream)
  353.         'LightMap = New Byte[Self.Header.LightMaps.Size]
  354.         'For i:Int = 0 Until LightMap.Length
  355.         '   LightMap[i] = ReadByte(Stream)
  356.         'Next
  357.         'Stream.ReadBytes(LightMap, LightMap.Length)
  358.        
  359.         'Read clipnodes
  360.         'num = Self.Header.ClipNodes.Count(TQClipNode.Size())
  361.         'DebugLog "ClipNodes: " + num
  362.         'Self.Header.ClipNodes.JumpTo(Stream)
  363.         'For i = 0 Until num
  364.         '   ListAddLast(Self.ClipNodes, TQClipNode.Read(Stream))
  365.         'Next
  366.        
  367.         'Read leaves
  368.         'num = Self.Header.Leaves.Count(TQDLeaf.Size())
  369.         'DebugLog "Leaves: " + num
  370.         'Self.Header.Leaves.JumpTo(Stream)
  371.         'For i = 0 Until num
  372.         '   ListAddLast(Self.Leaves, TQDLeaf.Read(Stream))
  373.         'Next
  374.        
  375.         'Read edges
  376.         num = Self.Header.Edges.Count(TQEdge.Size())
  377.         DebugLog "Edges: " + num
  378.         Self.Edges = New TQEdge[num]
  379.         Self.Header.Edges.JumpTo(Stream)
  380.         For i = 0 Until num
  381.             'ListAddLast(Self.Edges, TQEdge.Read(Stream))
  382.             Self.Edges[i] = TQEdge.Read(Stream)
  383.         Next
  384.        
  385.         'Read ledges
  386.         num = Self.Header.Ledges.Count(TQLedge.Size())
  387.         DebugLog "Ledges: " + num
  388.         Self.Ledges = New TQLedge[num]
  389.         Self.Header.Ledges.JumpTo(Stream)
  390.         For i = 0 Until num
  391.             'ListAddLast(Self.Ledges, TQLedge.Read(Stream))
  392.             Self.Ledges[i] = TQLedge.Read(Stream)
  393.         Next
  394.        
  395.         'Read models
  396.         num = Self.Header.Models.Count(TQModel.Size())
  397.         DebugLog "Models: " + num
  398.         Self.Models = New TQModel[num]
  399.         Self.Header.Models.JumpTo(Stream)
  400.         For i = 0 Until num
  401.             'ListAddLast(Self.Models, TQModel.Read(Stream))
  402.             Self.Models[i] = TQModel.Read(Stream)
  403.         Next
  404.        
  405.         'Read lightmaps from faces
  406.         For i = 0 Until Self.Faces.Length
  407.             Self.Faces[i].GetLightmap(Self)
  408.         Next
  409.        
  410.         StartMS = MilliSecs()
  411.        
  412.         CloseStream(Stream)
  413.         Return True
  414.     EndMethod
  415. EndType
  416.  
  417. 'http://www.gamers.org/dEngine/quake/spec/quake-spec34/qkspec_4.htm
  418. 'char 8bit = negative byte
  419. 'u_char 8bit = byte
  420. 'short 16bit = negative short
  421. 'u_short 16bit = short
  422. 'long 32bit = int
  423. 'u_long 32bit = longer int
  424. 'float 32bit = float
  425. 'scalar_t 32bit = float
  426.  
  427. Type TQHeader
  428.     Field Version:Int
  429.     Field Entities:TQEntry
  430.     Field PLANES:TQEntry
  431.     Field MipTex:TQEntry
  432.     Field Vertices:TQEntry
  433.     Field VisiList:TQEntry
  434.     Field Nodes:TQEntry
  435.     Field TexInfo:TQEntry
  436.     Field Faces:TQEntry
  437.     Field LightMaps:TQEntry
  438.     Field ClipNodes:TQEntry
  439.     Field Leaves:TQEntry
  440.     Field LFace:TQEntry
  441.     Field Edges:TQEntry
  442.     Field Ledges:TQEntry
  443.     Field Models:TQEntry
  444.    
  445.     Function Read:TQHeader(Stream:TStream)
  446.         Local nH:TQHeader = New TQHeader
  447.        
  448.         nH.Version = ReadInt(Stream)
  449.         If nH.Version = "29" Then
  450.             DebugLog "BSP version: " + nH.Version + " (correct)"
  451.         Else
  452.             DebugLog "BSP version: " + nH.Version + " (incorrect)"
  453.         EndIf
  454.        
  455.         nH.Entities = TQEntry.Read(Stream)
  456.         nH.PLANES = TQEntry.Read(Stream)
  457.        
  458.         nH.MipTex = TQEntry.Read(Stream)
  459.         nH.Vertices = TQEntry.Read(Stream)
  460.        
  461.         nH.VisiList = TQEntry.Read(Stream)
  462.         nH.Nodes = TQEntry.Read(Stream)
  463.        
  464.         nH.TexInfo = TQEntry.Read(Stream)
  465.        
  466.         nH.Faces = TQEntry.Read(Stream)
  467.        
  468.         nH.LightMaps = TQEntry.Read(Stream)
  469.         nH.ClipNodes = TQEntry.Read(Stream)
  470.        
  471.         nH.Leaves = TQEntry.Read(Stream)
  472.        
  473.         nH.LFace = TQEntry.Read(Stream)
  474.         nH.Edges = TQEntry.Read(Stream)
  475.        
  476.         nH.Ledges = TQEntry.Read(Stream)
  477.         nH.Models = TQEntry.Read(Stream)
  478.        
  479.         Return nH
  480.     EndFunction
  481. EndType
  482.  
  483. Type TQModel
  484.     Field Bound:TQBoundBox
  485.     Field Origin:TQVec3
  486.     Field Node_ID0:Int
  487.     Field Node_ID1:Int
  488.     Field Node_ID2:Int
  489.     Field Node_ID3:Int
  490.     Field NumLeafs:Int
  491.     Field Face_ID:Int
  492.     Field Face_Num:Int
  493.    
  494.     Function Read:TQModel(Stream:TStream)
  495.         Local nM:TQModel = New TQModel
  496.         nM.Bound = TQBoundBox.Read(Stream)
  497.         nM.Origin = TQVec3.Read(Stream)
  498.         nM.Node_ID0 = ReadInt(Stream)
  499.         nM.Node_ID1 = ReadInt(Stream)
  500.         nM.Node_ID2 = ReadInt(Stream)
  501.         nM.Node_ID3 = ReadInt(Stream)
  502.         nM.NumLeafs = ReadInt(Stream)
  503.         nM.Face_ID = ReadInt(Stream)
  504.         nM.Face_Num = ReadInt(Stream)
  505.         Return nM
  506.     EndFunction
  507.    
  508.     Function Size:Int()
  509.         Return (B_INT * 7) + TQBoundBox.Size() + TQVec3.Size()
  510.     EndFunction
  511. EndType
  512.  
  513. Type TQVertex
  514.     Field X:Float
  515.     Field Y:Float
  516.     Field Z:Float
  517.    
  518.     Function Read:TQVertex(Stream:TStream)
  519.         Local nV:TQVertex = New TQVertex
  520.         nV.X = ReadFloat(Stream)
  521.         nV.Y = ReadFloat(Stream)
  522.         nV.Z = ReadFloat(Stream)
  523.        
  524.         Return nV
  525.     EndFunction
  526.    
  527.     Function Size:Int()
  528.         Return B_FLOAT * 3
  529.     EndFunction
  530. EndType
  531.  
  532. Type TQSurface
  533.     Field VectorS:TQVec3
  534.     Field DistS:Float
  535.     Field VectorT:TQVec3
  536.     Field DistT:Float
  537.     Field Texture_ID:Int
  538.    
  539.     Field Animated:Int
  540.    
  541.     Function Read:TQSurface(Stream:TStream)
  542.         Local nS:TQSurface = New TQSurface
  543.         nS.VectorS = TQVec3.Read(Stream)
  544.         nS.DistS = ReadFloat(Stream)
  545.         nS.VectorT = TQVec3.Read(Stream)
  546.         nS.DistT = ReadFloat(Stream)
  547.         nS.Texture_ID = ReadInt(Stream)
  548.         nS.Animated = ReadInt(Stream)
  549.         Return nS
  550.     EndFunction
  551.    
  552.     Function Size:Int()
  553.         Return (B_FLOAT * 2) + (B_INT * 2) + (TQVec3.Size() * 2)
  554.     EndFunction
  555. EndType
  556.  
  557. Type TQEdge
  558.     Field Vertex0:Short
  559.     Field Vertex1:Short
  560.    
  561.     Function Read:TQEdge(Stream:TStream)
  562.         Local nE:TQEdge = New TQEdge
  563.         nE.Vertex0 = ReadShort(Stream)
  564.         nE.Vertex1 = ReadShort(Stream)
  565.         Return nE
  566.     EndFunction
  567.    
  568.     Function Size:Int()
  569.         Return B_SHORT * 2
  570.     EndFunction
  571. EndType
  572.  
  573. Type TQLedge
  574.     Field Edge:Int
  575.    
  576.     Function Read:TQLedge(Stream:TStream)
  577.         Local nL:TQLedge = New TQLedge
  578.         nL.Edge = ReadInt(Stream)
  579.         Return nL
  580.     EndFunction
  581.    
  582.     Function Size:Int()
  583.         Return B_INT
  584.     EndFunction
  585. EndType
  586.  
  587. Type TQFace
  588.     Field Plane_ID:Short
  589.    
  590.     Field Side:Short
  591.     Field Ledge_ID:Int
  592.    
  593.     Field Ledge_Num:Short
  594.     Field TexInfo_ID:Short
  595.    
  596.     Field TypeLight:Byte
  597.     Field BaseLight:Byte
  598.     Field Light:Byte[2]
  599.     Field LightMap:Int
  600.    
  601.     Field Surface:TSurface
  602.    
  603.     Field LightBrush:TBrush
  604.     Field LightDist:TQVec3
  605.     Field LightMinPos:TQVec3
  606.     Field LightMaxPos:TQVec3
  607.    
  608.     Function Read:TQFace(Stream:TStream)
  609.         Local nF:TQFace = New TQFace
  610.         nF.Plane_ID = ReadShort(Stream)
  611.         nF.Side = ReadShort(Stream)
  612.         nF.Ledge_ID = ReadInt(Stream)
  613.         nF.Ledge_Num = ReadShort(Stream)
  614.         nF.TexInfo_ID = ReadShort(Stream)
  615.         nF.TypeLight = ReadByte(Stream)
  616.         nF.BaseLight = ReadByte(Stream)
  617.         nF.Light[0] = ReadByte(Stream)
  618.         nF.Light[1] = ReadByte(Stream)
  619.         nF.LightMap = ReadInt(Stream)
  620.         Return nF
  621.     EndFunction
  622.    
  623.     Method GetLightmap(bsp:TQBSP)
  624.         bsp.Stream.Seek(bsp.Header.LightMaps.Offset + Self.LightMap)
  625.        
  626.         Local plane:TQPlane = bsp.PLANES[Self.Plane_ID]
  627.        
  628.         'Get the vertex data from all edges
  629.         LightMinPos:TQVec3 = New TQVec3
  630.         LightMaxPos:TQVec3 = New TQVec3
  631.         LightDist:TQVec3 = New TQVec3
  632.         Local ledge:TQLedge
  633.         Local edge:TQEdge
  634.         Local vert:TQVertex
  635.         For Local eNr:Int = Self.Ledge_ID Until Self.Ledge_ID + Self.Ledge_Num 'Go through edges
  636.             ledge = bsp.Ledges[eNr] 'Get ledge
  637.             edge = bsp.Edges[Abs(ledge.edge)] 'Get edge via ledge
  638.            
  639.             If ledge.edge < 0 Then
  640.                 vert = bsp.Vertices[edge.Vertex0]
  641.             Else
  642.                 vert = bsp.Vertices[edge.Vertex1]
  643.             EndIf
  644.            
  645.             If (eNr = Self.Ledge_ID) Then
  646.                 'Starting point
  647.                 LightMinPos.x = vert.x
  648.                 LightMaxPos.x = vert.x
  649.                 LightMinPos.y = vert.y
  650.                 LightMaxPos.y = vert.y
  651.                 LightMinPos.z = vert.z
  652.                 LightMaxPos.z = vert.z
  653.             Else
  654.                 'Is this a new minimum?
  655.                 If vert.x < LightMinPos.x Then LightMinPos.x = vert.x
  656.                 If vert.y < LightMinPos.y Then LightMinPos.y = vert.y
  657.                 If vert.z < LightMinPos.z Then LightMinPos.z = vert.z
  658.                
  659.                 'Is this a new maximum
  660.                 If vert.x > LightMaxPos.x Then LightMaxPos.x = vert.x
  661.                 If vert.y > LightMaxPos.y Then LightMaxPos.y = vert.y
  662.                 If vert.z > LightMaxPos.z Then LightMaxPos.z = vert.z
  663.             End If
  664.         Next
  665.        
  666.         'Get distances
  667.         LightDist.x = LightMaxPos.x - LightMinPos.x
  668.         LightDist.y = LightMaxPos.y - LightMinPos.y
  669.         LightDist.z = LightMaxPos.z - LightMinPos.z
  670.        
  671.         'Plane types:
  672.         '• 0: Axial plane, in X
  673.         '• 1: Axial plane, in Y
  674.         '• 2: Axial plane, in Z
  675.         '• 3: Non axial plane, roughly toward X
  676.         '• 4: Non axial plane, roughly toward Y
  677.         '• 5: Non axial plane, roughly toward Z
  678.        
  679.         Local pix:TPixmap
  680.        
  681.         Select plane.Typ
  682.             Case 0, 3
  683.                 pix = CreatePixmap(Ceil(LightDist.z / 16.0), Ceil(LightDist.y / 16.0), PF_RGB888)
  684.                 'pix = CreatePixmap(LightDist.z / 16, LightDist.y / 16, PF_RGB888)
  685.             Case 1, 4
  686.                 pix = CreatePixmap(Ceil(LightDist.x / 16.0), Ceil(LightDist.z / 16.0), PF_RGB888)
  687.                 'pix = CreatePixmap(LightDist.x / 16, LightDist.z / 16, PF_RGB888)
  688.             Case 2, 5
  689.                 pix = CreatePixmap(Ceil(LightDist.x / 16.0), Ceil(LightDist.y / 16.0), PF_RGB888)
  690.                 'pix = CreatePixmap(LightDist.x / 16, LightDist.y / 16, PF_RGB888)
  691.             Default
  692.                 Print "Unknown plane type: "+plane.Typ
  693.         EndSelect
  694.        
  695.         If pix.width <= 1 Or pix.Height <= 1 Then
  696.             pix = Null
  697.             Return
  698.         EndIf
  699.         'Print pix.width + "/" + pix.Height
  700.         Local x:Int
  701.         Local y:Int
  702.         Local color:Byte
  703.         For y = 0 Until pix.Height
  704.         For x = 0 Until pix.width
  705.             color = bsp.Stream.ReadByte()
  706.             pix.WritePixel(x, y, GenRGB(color,color,color))
  707.         Next
  708.         Next
  709.        
  710.         If FileType(AppDir + "/lightmaps") = FILETYPE_DIR Then SavePixmapPNG(pix, AppDir + "/lightmaps/" + Plane_ID + ".png", 0)
  711.        
  712.         Self.LightBrush = LoadBrushPixmap(pix, 0)
  713.     EndMethod
  714.    
  715.     Function Size:Int()
  716.         Return (B_SHORT * 4) + (B_INT * 2) + (B_BYTE * 4)
  717.     EndFunction
  718. EndType
  719.  
  720. Type TQMipHeader
  721.     Field NumTex:Int
  722.     Field Offset:Int[]
  723.    
  724.     Field _count:Int
  725.    
  726.     Function Read:TQMipHeader(Stream:TStream)
  727.         Local nM:TQMipHeader = New TQMipHeader
  728.         nM.NumTex = ReadInt(Stream)
  729.        
  730.         'Should I even read this?
  731.         nM.Offset = New Int[nM.NumTex]
  732.         For Local i:Int = 0 Until nM.NumTex
  733.             nM.Offset[i] = ReadInt(Stream)
  734.             nM._count:+1
  735.         Next
  736.         Return nM
  737.     EndFunction
  738. EndType
  739.  
  740. Type TQMipTex
  741.     Field Name:String
  742.     Field width:Int
  743.     Field Height:Int
  744.     Field Offset1:Int
  745.     Field Offset2:Int
  746.     Field Offset4:Int
  747.     Field Offset8:Int
  748.    
  749.     Field Texture:TTexture
  750.     Field Brush:TBrush
  751.    
  752.     Function Read:TQMipTex(Stream:TStream)
  753.         Local nM:TQMipTex = New TQMipTex
  754.         For Local i:Int = 0 Until 16
  755.             nM.Name:+Chr(ReadByte(Stream))
  756.         Next
  757.         nM.width = ReadInt(Stream)
  758.         nM.Height = ReadInt(Stream)
  759.         nM.Offset1 = ReadInt(Stream)
  760.         nM.Offset2 = ReadInt(Stream)
  761.         nM.Offset4 = ReadInt(Stream)
  762.         nM.Offset8 = ReadInt(Stream)
  763.         Return nM
  764.     EndFunction
  765.    
  766.     Function Size:Int()
  767.         Return (B_BYTE * 16) + (B_INT * 6)
  768.     EndFunction
  769. EndType
  770.  
  771. Type TQEntry
  772.     Field Offset:Int
  773.     Field Size:Int
  774.    
  775.     Function Read:TQEntry(Stream:TStream)
  776.         Local nE:TQEntry = New TQEntry
  777.         nE.Offset = ReadInt(Stream)
  778.         nE.Size = ReadInt(Stream)
  779.         Return nE
  780.     EndFunction
  781.    
  782.     Method Count:Int(typeSize:Int)
  783.         Return Size / typeSize
  784.     EndMethod
  785.    
  786.     Method JumpTo(Stream:TStream)
  787.         Stream.Seek(Self.Offset)
  788.     EndMethod
  789. EndType
  790.  
  791. Type TQNode
  792.     Field Plane_ID:Int
  793.    
  794.     Field Front:Short
  795.    
  796.     Field Back:Short
  797.    
  798.     Field Box:TQBBoxShort
  799.     Field Face_ID:Short
  800.     Field Face_Num:Short
  801.    
  802.     Function Read:TQNode(Stream:TStream)
  803.         Local nN:TQNode = New TQNode
  804.         nN.Plane_ID = ReadInt(Stream)
  805.         nN.Front = ReadShort(Stream)
  806.         nN.Back = ReadShort(Stream)
  807.         nN.Box = TQBBoxShort.Read(Stream)
  808.         nN.Face_ID = ReadShort(Stream)
  809.         nN.Face_Num = ReadShort(Stream)
  810.         Return nN
  811.     EndFunction
  812. EndType
  813.  
  814. Type TQDLeaf
  815.     Field Typ:Int
  816.     Field VisList:Int
  817.    
  818.     Field Bound:TQBBoxShort
  819.     Field LFace_ID:Short
  820.    
  821.     Field LFace_Num:Short
  822.     Field SndWater:Byte
  823.     Field SndSky:Byte
  824.     Field SndSlime:Byte
  825.     Field SndLava:Byte
  826.    
  827.     Function Read:TQDLeaf(Stream:TStream)
  828.         Local nD:TQDLeaf = New TQDLeaf
  829.         nD.Typ = ReadInt(Stream)
  830.         nD.VisList = ReadInt(Stream)
  831.        
  832.         nD.Bound = TQBBoxShort.Read(Stream)
  833.         nD.LFace_ID = ReadShort(Stream)
  834.        
  835.         nD.LFace_Num = ReadShort(Stream)
  836.         nD.SndWater = ReadByte(Stream)
  837.         nD.SndSky = ReadByte(Stream)
  838.         nD.SndSlime = ReadByte(Stream)
  839.         nD.SndLava = ReadByte(Stream)
  840.         Return nD
  841.     EndFunction
  842. EndType
  843.  
  844. Type TQPlane
  845.     Field Normal:TQVec3
  846.    
  847.     Field Dist:Float
  848.    
  849.     Field Typ:Int
  850.    
  851.     Function Read:TQPlane(Stream:TStream)
  852.         Local nP:TQPlane = New TQPlane
  853.         nP.Normal = TQVec3.Read(Stream)
  854.         nP.Dist = ReadFloat(Stream)
  855.         nP.Typ = ReadInt(Stream)
  856.         Return nP
  857.     EndFunction
  858.    
  859.     Function Size:Int()
  860.         Return B_FLOAT + B_INT + TQVec3.Size()
  861.     EndFunction
  862. EndType
  863.  
  864. Type TQClipNode
  865.     Field PlaneNum:Int
  866.     Field Front:Short
  867.    
  868.     Field Back:Short
  869.    
  870.     Function Read:TQClipNode(Stream:TStream)
  871.         Local nC:TQClipNode = New TQClipNode
  872.         nC.PlaneNum = ReadInt(Stream)
  873.         nC.Front = ReadShort(Stream)
  874.         nC.Back = ReadShort(Stream)
  875.         Return nC
  876.     EndFunction
  877. EndType
  878.  
  879. Type TQPalette
  880.     Global colors:TQColor32[]
  881.    
  882.     Function LoadPalette(url:String)
  883.         Local Stream:TStream = OpenStream(url, True, False)
  884.         If Not Stream Then Print("Unable to load palette ~q" + url + "~q")
  885.         colors = New TQColor32[Stream.Size() / 3]
  886.        
  887.         For Local i:Int = 0 Until colors.Length
  888.             colors[i] = New TQColor32
  889.             colors[i].r = Stream.ReadByte()
  890.             colors[i].g = Stream.ReadByte()
  891.             colors[i].b = Stream.ReadByte()
  892.         Next
  893.        
  894.         'debug save palette
  895.         Rem
  896.         Local pix:TPixmap = CreatePixmap(colors.Length, 8, PF_RGB888)
  897.         For Local i:Int = 0 Until colors.Length
  898.             For Local y:Int = 0 Until pix.Height
  899.                 pix.WritePixel(i, y, GenRGB(colors[i].r, colors[i].g, colors[i].b))
  900.             Next
  901.         Next
  902.         SavePixmapPNG(pix, AppDir + "/palette.png", 9)
  903.         endrem
  904.        
  905.         CloseStream(Stream)
  906.         DebugLog "Palette: " + url + " @ " + colors.Length + " colors"
  907.     EndFunction
  908.    
  909. EndType
  910.  
  911. Type TQColor32
  912.     Field r:Byte
  913.     Field g:Byte
  914.     Field b:Byte
  915. EndType
  916.  
  917. 'Basic types
  918. Type TQVec3
  919.     Field X:Float
  920.     Field Y:Float
  921.     Field Z:Float
  922.    
  923.     Function Read:TQVec3(Stream:TStream)
  924.         Local nV:TQVec3 = New TQVec3
  925.         nV.X = ReadFloat(Stream)
  926.         nV.Y = ReadFloat(Stream)
  927.         nV.Z = ReadFloat(Stream)
  928.         Return nV
  929.     EndFunction
  930.    
  931.     Function Size:Int()
  932.         Return B_FLOAT * 3
  933.     EndFunction
  934. EndType
  935.  
  936. Type TQBoundBox
  937.     Field Minimum:TQVec3
  938.     Field Maximum:TQVec3
  939.    
  940.     Function Read:TQBoundBox(Stream:TStream)
  941.         Local nB:TQBoundBox = New TQBoundBox
  942.         nB.Minimum = TQVec3.Read(Stream)
  943.         nB.Maximum = TQVec3.Read(Stream)
  944.         Return nB
  945.     EndFunction
  946.    
  947.     Function Size:Int()
  948.             Return TQVec3.Size() * 2
  949.     EndFunction
  950. EndType
  951.  
  952. Type TQBBoxShort
  953.     Field Minimum:Short
  954.     Field Maximum:Short
  955.    
  956.     Function Read:TQBBoxShort(Stream:TStream)
  957.         Local nB:TQBBoxShort = New TQBBoxShort
  958.         nB.Minimum = ReadShort(Stream)
  959.         nB.Maximum = ReadShort(Stream)
  960.         Return nB
  961.     EndFunction
  962.    
  963.     Function Size:Int()
  964.         Return B_SHORT * 2
  965.     EndFunction
  966. EndType
  967.  
  968. 'Common
  969. Function CrossProduct:TQVec3(x1:Float, y1:Float, z1:Float, x2:Float, y2:Float, z2:Float)
  970.     Local CProd:TQVec3 = New TQVec3
  971.     CProd.x = (y1 * z2) - (z1 * y2)
  972.     CProd.y = (z1 * x2) - (x1 * z2)
  973.     CProd.z = (x1 * y2) - (y1 * x2)
  974.     Return CProd
  975. End Function
  976. Function DotProduct:Float(x1:Float, y1:Float, z1:Float, x2:Float, y2:Float, z2:Float)
  977.     Return ((x1 * x2) + (y1 * y2) + (z1 * z2))
  978. EndFunction
  979.  
  980. Function GenRGB:Int(r:Byte, g:Byte, b:Byte, a:Byte = 255)
  981.     Return (a Shl 24) | (r Shl 16) | (g Shl 8) | b
  982. EndFunction
  983.    
  984. Function GetRGB:Int(argb:Int, a:byte Var, r:byte Var, g:byte Var, b:byte Var)
  985.     a=(argb Shr 24) & $ff
  986.     r=(argb Shr 16) & $ff
  987.     g=(argb Shr 8) & $ff
  988.     b=argb & $ff
  989. EndFunction
  990.  
  991. 'Custom brushes
  992. Function LoadBrushPixmap:TBrush(pixmapin:TPixmap, Flags:Int = 1, u_scale:Float = 1.0, v_scale:Float = 1.0)
  993.     Return PixTBrush.LoadBrushPixmap(pixmapin, Flags, u_scale, v_scale)
  994. EndFunction
  995.  
  996. Function LoadTexturePixmap:TTexture(pixmapin:TPixmap,flags:Int=1)
  997.     Return PixTTexture.LoadTexturePixmap(pixmapin, Flags)
  998. EndFunction
  999.  
  1000. Type PixTBrush Extends TBrush
  1001.  
  1002.     Function LoadBrushPixmap:TBrush(pixmapin:TPixmap,flags:Int=1,u_scale:Float=1.0,v_scale:Float=1.0)
  1003.    
  1004.         Local brush:TBrush=New TBrush
  1005.        
  1006.         brush.tex[0]=PixTTexture.LoadTexturePixmap:TTexture(pixmapin,flags)
  1007.         brush.no_texs=1
  1008.        
  1009.         'brush.tex[0].u_scale#=u_scale#
  1010.         'brush.tex[0].v_scale#=v_scale#
  1011.        
  1012.         pixmapin = Null
  1013.                
  1014.         Return brush
  1015.        
  1016.     EndFunction
  1017. EndType
  1018.  
  1019. Type PixTTexture Extends TTexture
  1020.  
  1021.     Function LoadTexturePixMap:TTexture(pixmapin:TPixmap,flags:Int=1,tex:TTexture=Null)
  1022.    
  1023.         Return LoadAnimTexturePixMap:TTexture(pixmapin,flags,0,0,0,1,tex)
  1024.        
  1025.     End Function
  1026.  
  1027.     Function LoadAnimTexturePixMap:TTexture(pixmapin:TPixmap,flags:Int,frame_width:Int,frame_height:Int,first_frame:Int,frame_count:Int,tex:TTexture=Null)
  1028.    
  1029.         Local pixmapFileName:String="pixmap"+MilliSecs()+Rnd()
  1030.        
  1031.         If flags&128 Then Return LoadCubeMapTexture(pixmapFileName$,flags,tex)
  1032.    
  1033.         If tex=Null Then tex:TTexture=New TTexture
  1034.        
  1035.         tex.file:String=pixmapFileName
  1036.         tex.file_abs:String=pixmapFileName
  1037.        
  1038.         ' set tex.flags before TexInList
  1039.         tex.flags=flags
  1040.         tex.FilterFlags()
  1041.        
  1042.         ' check to see if texture with same properties exists already, if so return existing texture
  1043.         Local old_tex:TTexture
  1044.         old_tex=tex.TexInList()
  1045.         If old_tex<>Null And old_tex<>tex
  1046.             Return old_tex
  1047.         Else
  1048.             If old_tex<>tex
  1049.                 ListAddLast(tex_list,tex)
  1050.             EndIf
  1051.         EndIf
  1052.    
  1053.         ' load pixmap
  1054.         tex.pixmap = CopyPixmap(pixmapin)
  1055.        
  1056.         ' check to see if pixmap contain alpha layer, set alpha_present to true if so (do this before converting)
  1057.         Local alpha_present:Int=False
  1058.         If tex.pixmap.format=PF_RGBA8888 Or tex.pixmap.format=PF_BGRA8888 Or tex.pixmap.format=PF_A8 Then alpha_present=True
  1059.    
  1060.         ' convert pixmap to appropriate format
  1061.         If tex.pixmap.format<>PF_RGBA8888
  1062.             tex.pixmap=tex.pixmap.Convert(PF_RGBA8888)
  1063.         EndIf
  1064.        
  1065.         ' if alpha flag is true and pixmap doesn't contain alpha info, apply alpha based on color values
  1066.         If tex.flags&2 And alpha_present=False
  1067.             tex.pixmap=ApplyAlpha(tex.pixmap)
  1068.         EndIf      
  1069.    
  1070.         ' if mask flag is true, mask pixmap
  1071.         If tex.flags&4
  1072.             tex.pixmap=MaskPixmap(tex.pixmap,0,0,0)
  1073.         EndIf
  1074.        
  1075.         ' ---
  1076.        
  1077.         ' if tex not anim tex, get frame width and height
  1078.         If frame_width=0 And frame_height=0
  1079.             frame_width=tex.pixmap.width
  1080.             frame_height=tex.pixmap.height
  1081.         EndIf
  1082.    
  1083.         ' ---
  1084.        
  1085.         tex.no_frames=frame_count
  1086.         tex.gltex=tex.gltex[..tex.no_frames]
  1087.    
  1088.         ' ---
  1089.        
  1090.         ' pixmap -> tex
  1091.    
  1092.         Local xframes:Int=tex.pixmap.width/frame_width
  1093.         Local yframes:Int=tex.pixmap.height/frame_height
  1094.            
  1095.         Local startx:Int=first_frame Mod xframes
  1096.         Local starty:Int=(first_frame/yframes) Mod yframes
  1097.            
  1098.         Local x:Int=startx
  1099.         Local y:Int=starty
  1100.    
  1101.         Local pixmap:TPixmap
  1102.    
  1103.         For Local i:Int=0 To tex.no_frames-1
  1104.    
  1105.             ' get static pixmap window. when resize pixmap is called new pixmap will be returned.
  1106.             pixmap=tex.pixmap.Window(x*frame_width,y*frame_height,frame_width,frame_height)
  1107.             x=x+1
  1108.             If x>=xframes
  1109.                 x=0
  1110.                 y=y+1
  1111.             EndIf
  1112.        
  1113.             ' ---
  1114.        
  1115.             pixmap=AdjustPixmap(pixmap)
  1116.             tex.width=pixmap.width
  1117.             tex.height=pixmap.height
  1118.             Local width:Int=pixmap.width
  1119.             Local height:Int=pixmap.height
  1120.    
  1121.             Local name:Int
  1122.             glGenTextures 1,Varptr name
  1123.             glBindtexture GL_TEXTURE_2D,name
  1124.    
  1125.             Local mipmap:Int
  1126.             If tex.flags&8 Then mipmap=True
  1127.             Local mip_level:Int=0
  1128.             Repeat
  1129.                 glPixelStorei GL_UNPACK_ROW_LENGTH,pixmap.pitch/BytesPerPixel[pixmap.format]
  1130.                 glTexImage2D GL_TEXTURE_2D,mip_level,GL_RGBA8,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,pixmap.pixels
  1131.                 If Not mipmap Then Exit
  1132.                 If width=1 And height=1 Exit
  1133.                 If width>1 width:/2
  1134.                 If height>1 height:/2
  1135.    
  1136.                 pixmap=ResizePixmap(pixmap,width,height)
  1137.                 mip_level:+1
  1138.             Forever
  1139.             tex.no_mipmaps=mip_level
  1140.    
  1141.             tex.gltex[i]=name
  1142.    
  1143.         Next
  1144.                
  1145.         tex.pixmap = Null
  1146.                
  1147.         Return tex
  1148.        
  1149.     End Function
  1150. EndType
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement