Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- SuperStrict
- Framework sidesign.minib3d 'https://github.com/si-design/minib3d
- Import brl.Stream
- Import brl.linkedlist
- Import brl.standardio
- 'Data sizes
- Const B_BYTE:Int = 1
- Const B_SHORT:Int = 2
- Const B_INT:Int = 4
- Const B_FLOAT:Int = 4
- Graphics3D(DesktopWidth() * 0.7, DesktopHeight() * 0.7, 0, 2)
- Local camera:TCamera = CreateCamera()
- MoveEntity(camera, 0, 0, -10)
- AmbientLight(255, 255, 255)
- Local myBSP:TQBSP = TQBSP.LoadFile("DM1.BSP")
- 'Debug make a mesh
- Local mesh:TMesh = CreateMesh()
- Local surf:TSurface[8]
- Local face:TQFace
- Local ledge:TQLedge
- Local edge:TQEdge
- Local vert:TQVertex
- Local fNr:Int
- Local vNr:Int
- Local surfNr:Int
- Local vertCount:Int
- Local newVertCount:Int
- For Local model:TQModel = EachIn myBSP.Models 'Go through models
- For fNr = model.Face_ID Until model.Face_ID + model.Face_Num 'Go through faces
- 'Debug progress
- 'If fNr Mod 100 <= 0 Then Print "Generating: " + fNr + "/" + model.Face_Num
- face = myBSP.Faces[fNr] 'Get current face
- 'Move to next surface if we're using too many vertices
- If surf[surfNr] And surf[surfNr].CountVertices() > (10000 * 3) - 1 Then surfNr:+1
- 'If we don't have a surface to work with, create one
- If Not surf[surfNr] Then surf[surfNr] = CreateSurface(mesh, Null)
- 'Get verts
- newVertCount = 0
- For vNr = face.Ledge_ID Until face.Ledge_ID + face.Ledge_Num 'Go through edges
- ledge = myBSP.Ledges[vNr] 'Get ledge
- edge = myBSP.Edges[Abs(ledge.edge)] 'Get edge via ledge
- If ledge.edge < 0 Then
- vert = myBSP.Vertices[edge.Vertex0]
- Else
- vert = myBSP.Vertices[edge.Vertex1]
- EndIf
- AddVertex(surf[surfNr], vert.X * 0.1, vert.Y * 0.1, vert.Z * 0.1)
- vertCount:+1
- newVertCount:+1
- Next
- 'Make Tris
- For Local i:Int = vertCount - newVertCount Until vertCount
- AddTriangle(surf[surfNr], i, i + 1, i + 2)
- Next
- Next
- Next
- 'Main loop
- While Not AppTerminate() And Not KeyDown(KEY_ESCAPE)
- 'Cls()
- If KeyHit(KEY_O) Then Wireframe(False)
- If KeyHit(KEY_P) Then Wireframe(True)
- If KeyDown(KEY_LEFT) Then TurnEntity(camera, 0, 2, 0)
- If KeyDown(KEY_RIGHT) Then TurnEntity(camera, 0, -2, 0)
- If KeyDown(KEY_UP) Then TurnEntity(camera, -2, 0, 0)
- If KeyDown(KEY_DOWN) Then TurnEntity(camera, 2, 0, 0)
- If KeyDown(KEY_W) Then MoveEntity(camera, 0, 0, 1.5)
- If KeyDown(KEY_S) Then MoveEntity(camera, 0, 0, -1.5)
- If KeyDown(KEY_A) Then MoveEntity(camera, -1.5, 0, 0)
- If KeyDown(KEY_D) Then MoveEntity(camera, 1.5, 0, 0)
- If KeyDown(KEY_SPACE) Then MoveEntity(camera, 0, 1, 0)
- If KeyDown(KEY_LCONTROL) Then MoveEntity(camera, 0, -1, 0)
- RenderWorld()
- Flip(1)
- Wend
- End
- Type TQBSP
- Field File:String
- Field Stream:TStream
- Field Header:TQHeader
- Field PLANES:TList = CreateList()
- Field Vertices:TQVertex[]
- Field Nodes:TList = CreateList()
- Field TexInfo:TList = CreateList()
- Field Faces:TQFace[]
- Field ClipNodes:TList = CreateList()
- Field Leaves:TList = CreateList()
- Field Edges:TQEdge[]
- Field Ledges:TQLedge[]
- Field Models:TQModel[]
- Function LoadFile:TQBSP(url:String)
- Local nB:TQBSP = New TQBSP
- nB.File = url
- If nB.Process() Then
- Return nB
- Else
- nB.StreamError("Map ~q" + nB.file + "~q NOT loaded")
- Return Null
- EndIf
- EndFunction
- Method StreamError(MSG:String)
- If Stream Then CloseStream(Stream)
- DebugLog "Read error: " + MSG
- EndMethod
- Method Process:Int()
- Stream = OpenStream(File)
- If Not Stream Then
- StreamError("Unable to read file ~q" + file + "~q")
- Return False
- EndIf
- Local num:Int 'For counting stuff
- Local i:Int 'For loops
- 'Read header
- Self.Header = TQHeader.Read(Stream)
- 'Read planes
- 'num = Self.Header.PLANES.Count(TQPlane.Size())
- 'DebugLog "Planes: " + num
- 'Self.Header.PLANES.JumpTo(Stream)
- 'For i = 0 Until num
- ' ListAddLast(Self.PLANES, TQPlane.Read(Stream))
- 'Next
- 'Read vertices
- num = Self.Header.Vertices.Count(TQVertex.Size())
- DebugLog "Vertices: " + num
- Self.Vertices = New TQVertex[num]
- Self.Header.Vertices.JumpTo(Stream)
- For i = 0 Until num
- 'ListAddLast(Self.Vertices, TQVertex.Read(Stream))
- Self.Vertices[i] = TQVertex.Read(Stream)
- Next
- 'Read nodes
- 'num = Self.Header.Nodes.Count(TQNode.Size())
- 'DebugLog "Nodes: " + num
- 'Self.Header.Nodes.JumpTo(Stream)
- 'For i = 0 Until num
- ' ListAddLast(Self.Nodes, TQNode.Read(Stream))
- 'Next
- 'Read texture info
- 'num = Self.Header.TexInfo.Count(TQSurface.Size())
- 'DebugLog "TexInfos: " + num
- 'Self.Header.TexInfo.JumpTo(Stream)
- 'For i = 0 Until num
- ' ListAddLast(Self.TexInfo, TQSurface.Read(Stream))
- 'Next
- 'Read faces
- num = Self.Header.Faces.Count(TQFace.Size())
- DebugLog "Faces: " + num
- Self.Faces = New TQFace[num]
- Self.Header.Faces.JumpTo(Stream)
- For i = 0 Until num
- 'ListAddLast(Self.Faces, TQFace.Read(Stream))
- Self.Faces[i] = TQFace.Read(Stream)
- Next
- 'Read clipnodes
- 'num = Self.Header.ClipNodes.Count(TQClipNode.Size())
- 'DebugLog "ClipNodes: " + num
- 'Self.Header.ClipNodes.JumpTo(Stream)
- 'For i = 0 Until num
- ' ListAddLast(Self.ClipNodes, TQClipNode.Read(Stream))
- 'Next
- 'Read leaves
- 'num = Self.Header.Leaves.Count(TQDLeaf.Size())
- 'DebugLog "Leaves: " + num
- 'Self.Header.Leaves.JumpTo(Stream)
- 'For i = 0 Until num
- ' ListAddLast(Self.Leaves, TQDLeaf.Read(Stream))
- 'Next
- 'Read edges
- num = Self.Header.Edges.Count(TQEdge.Size())
- DebugLog "Edges: " + num
- Self.Edges = New TQEdge[num]
- Self.Header.Edges.JumpTo(Stream)
- For i = 0 Until num
- 'ListAddLast(Self.Edges, TQEdge.Read(Stream))
- Self.Edges[i] = TQEdge.Read(Stream)
- Next
- 'Read ledges
- num = Self.Header.Ledges.Count(TQLedge.Size())
- DebugLog "Ledges: " + num
- Self.Ledges = New TQLedge[num]
- Self.Header.Ledges.JumpTo(Stream)
- For i = 0 Until num
- 'ListAddLast(Self.Ledges, TQLedge.Read(Stream))
- Self.Ledges[i] = TQLedge.Read(Stream)
- Next
- 'Read models
- num = Self.Header.Models.Count(TQModel.Size())
- DebugLog "Models: " + num
- Self.Models = New TQModel[num]
- Self.Header.Models.JumpTo(Stream)
- For i = 0 Until num
- 'ListAddLast(Self.Models, TQModel.Read(Stream))
- Self.Models[i] = TQModel.Read(Stream)
- Next
- CloseStream(Stream)
- Return True
- EndMethod
- EndType
- 'http://www.gamers.org/dEngine/quake/spec/quake-spec34/qkspec_4.htm
- 'char 8bit = negative byte
- 'u_char 8bit = byte
- 'short 16bit = negative short
- 'u_short 16bit = short
- 'long 32bit = int
- 'u_long 32bit = longer int
- 'float 32bit = float
- 'scalar_t 32bit = float
- Type TQHeader
- Field Version:Int
- Field Entities:TQEntry
- Field PLANES:TQEntry
- Field MipTex:TQEntry
- Field Vertices:TQEntry
- Field VisiList:TQEntry
- Field Nodes:TQEntry
- Field TexInfo:TQEntry
- Field Faces:TQEntry
- Field LightMaps:TQEntry
- Field ClipNodes:TQEntry
- Field Leaves:TQEntry
- Field LFace:TQEntry
- Field Edges:TQEntry
- Field Ledges:TQEntry
- Field Models:TQEntry
- Function Read:TQHeader(Stream:TStream)
- Local nH:TQHeader = New TQHeader
- nH.Version = ReadInt(Stream)
- If nH.Version = "29" Then
- DebugLog "Correct BSP version (" + nH.Version + ")"
- Else
- DebugLog "Warning: Wrong BSP version (" + nH.Version + ")"
- EndIf
- nH.Entities = TQEntry.Read(Stream)
- nH.PLANES = TQEntry.Read(Stream)
- nH.MipTex = TQEntry.Read(Stream)
- nH.Vertices = TQEntry.Read(Stream)
- nH.VisiList = TQEntry.Read(Stream)
- nH.Nodes = TQEntry.Read(Stream)
- nH.TexInfo = TQEntry.Read(Stream)
- nH.Faces = TQEntry.Read(Stream)
- nH.LightMaps = TQEntry.Read(Stream)
- nH.ClipNodes = TQEntry.Read(Stream)
- nH.Leaves = TQEntry.Read(Stream)
- nH.LFace = TQEntry.Read(Stream)
- nH.Edges = TQEntry.Read(Stream)
- nH.Ledges = TQEntry.Read(Stream)
- nH.Models = TQEntry.Read(Stream)
- Return nH
- EndFunction
- EndType
- Type TQModel
- Field Bound:TQBoundBox
- Field Origin:TQVec3
- Field Node_ID0:Int
- Field Node_ID1:Int
- Field Node_ID2:Int
- Field Node_ID3:Int
- Field NumLeafs:Int
- Field Face_ID:Int
- Field Face_Num:Int
- Function Read:TQModel(Stream:TStream)
- Local nM:TQModel = New TQModel
- nM.Bound = TQBoundBox.Read(Stream)
- nM.Origin = TQVec3.Read(Stream)
- nM.Node_ID0 = ReadInt(Stream)
- nM.Node_ID1 = ReadInt(Stream)
- nM.Node_ID2 = ReadInt(Stream)
- nM.Node_ID3 = ReadInt(Stream)
- nM.NumLeafs = ReadInt(Stream)
- nM.Face_ID = ReadInt(Stream)
- nM.Face_Num = ReadInt(Stream)
- Return nM
- EndFunction
- Function Size:Int()
- Return (B_INT * 7) + TQBoundBox.Size() + TQVec3.Size()
- EndFunction
- EndType
- Type TQVertex
- Field X:Float
- Field Y:Float
- Field Z:Float
- Function Read:TQVertex(Stream:TStream)
- Local nV:TQVertex = New TQVertex
- nV.Z = ReadFloat(Stream)
- nV.X = ReadFloat(Stream)
- nV.Y = ReadFloat(Stream)
- Return nV
- EndFunction
- Function Size:Int()
- Return B_FLOAT * 3
- EndFunction
- EndType
- Type TQSurface
- Field VectorS:TQVec3
- Field DistS:Float
- Field VectorT:TQVec3
- Field DistT:Float
- Field Texture_ID:Int
- Field Animated:Int
- Function Read:TQSurface(Stream:TStream)
- Local nS:TQSurface = New TQSurface
- nS.VectorS = TQVec3.Read(Stream)
- nS.DistS = ReadFloat(Stream)
- nS.VectorT = TQVec3.Read(Stream)
- nS.DistT = ReadFloat(Stream)
- nS.Texture_ID = ReadInt(Stream)
- nS.Animated = ReadInt(Stream)
- Return nS
- EndFunction
- Function Size:Int()
- Return (B_FLOAT * 2) + (B_INT * 2) + (TQVec3.Size() * 2)
- EndFunction
- EndType
- Type TQEdge
- Field Vertex0:Short
- Field Vertex1:Short
- Function Read:TQEdge(Stream:TStream)
- Local nE:TQEdge = New TQEdge
- nE.Vertex0 = ReadShort(Stream)
- nE.Vertex1 = ReadShort(Stream)
- Return nE
- EndFunction
- Function Size:Int()
- Return B_SHORT * 2
- EndFunction
- EndType
- Type TQLedge
- Field Edge:Int
- Function Read:TQLedge(Stream:TStream)
- Local nL:TQLedge = New TQLedge
- nL.Edge = ReadInt(Stream)
- Return nL
- EndFunction
- Function Size:Int()
- Return B_INT
- EndFunction
- EndType
- Type TQFace
- Field Plane_ID:Short
- Field Side:Short
- Field Ledge_ID:Int
- Field Ledge_Num:Short
- Field TexInfo_ID:Short
- Field TypeLight:Byte
- Field BaseLight:Byte
- Field Light:Byte[2]
- Field LightMap:Int
- Function Read:TQFace(Stream:TStream)
- Local nF:TQFace = New TQFace
- nF.Plane_ID = ReadShort(Stream)
- nF.Side = ReadShort(Stream)
- nF.Ledge_ID = ReadInt(Stream)
- nF.Ledge_Num = ReadShort(Stream)
- nF.TexInfo_ID = ReadShort(Stream)
- nF.TypeLight = ReadByte(Stream)
- nF.BaseLight = ReadByte(Stream)
- nF.Light[0] = ReadByte(Stream)
- nF.Light[1] = ReadByte(Stream)
- nF.LightMap = ReadInt(Stream)
- Return nF
- EndFunction
- Function Size:Int()
- Return (B_SHORT * 4) + (B_INT * 2) + (B_BYTE * 4)
- EndFunction
- EndType
- Type TQMipHeader
- Field NumTex:Int
- Field Offset:Int[]
- Function Read:TQMipHeader(Stream:TStream)
- Local nM:TQMipHeader = New TQMipHeader
- nM.NumTex = ReadInt(Stream)
- 'Should I even read this?
- nM.Offset = New Int[nM.NumTex]
- For Local i:Int = 0 Until nM.NumTex
- nM.Offset[i] = ReadInt(Stream)
- Next
- Return nM
- EndFunction
- EndType
- Type TQMipTex
- Field Name:String
- Field width:Int
- Field Height:Int
- Field Offset1:Int
- Field Offset2:Int
- Field Offset4:Int
- Field Offset8:Int
- Function Read:TQMipTex(Stream:TStream)
- Local nM:TQMipTex = New TQMipTex
- For Local i:Int = 0 Until 16
- nM.Name:+Chr(ReadByte(Stream))
- Next
- nM.width = ReadInt(Stream)
- nM.Height = ReadInt(Stream)
- nM.Offset1 = ReadInt(Stream)
- nM.Offset2 = ReadInt(Stream)
- nM.Offset4 = ReadInt(Stream)
- nM.Offset8 = ReadInt(Stream)
- Return nM
- EndFunction
- Function Size:Int()
- Return (B_BYTE * 16) + (B_INT * 6)
- EndFunction
- EndType
- Type TQEntry
- Field Offset:Int
- Field Size:Int
- Function Read:TQEntry(Stream:TStream)
- Local nE:TQEntry = New TQEntry
- nE.Offset = ReadInt(Stream)
- nE.Size = ReadInt(Stream)
- Return nE
- EndFunction
- Method Count:Int(typeSize:Int)
- Return Size / typeSize
- EndMethod
- Method JumpTo(Stream:TStream)
- Stream.Seek(Self.Offset)
- EndMethod
- EndType
- Type TQNode
- Field Plane_ID:Int
- Field Front:Short
- Field Back:Short
- Field Box:TQBBoxShort
- Field Face_ID:Short
- Field Face_Num:Short
- Function Read:TQNode(Stream:TStream)
- Local nN:TQNode = New TQNode
- nN.Plane_ID = ReadInt(Stream)
- nN.Front = ReadShort(Stream)
- nN.Back = ReadShort(Stream)
- nN.Box = TQBBoxShort.Read(Stream)
- nN.Face_ID = ReadShort(Stream)
- nN.Face_Num = ReadShort(Stream)
- Return nN
- EndFunction
- EndType
- Type TQDLeaf
- Field Typ:Int
- Field VisList:Int
- Field Bound:TQBBoxShort
- Field LFace_ID:Short
- Field LFace_Num:Short
- Field SndWater:Byte
- Field SndSky:Byte
- Field SndSlime:Byte
- Field SndLava:Byte
- Function Read:TQDLeaf(Stream:TStream)
- Local nD:TQDLeaf = New TQDLeaf
- nD.Typ = ReadInt(Stream)
- nD.VisList = ReadInt(Stream)
- nD.Bound = TQBBoxShort.Read(Stream)
- nD.LFace_ID = ReadShort(Stream)
- nD.LFace_Num = ReadShort(Stream)
- nD.SndWater = ReadByte(Stream)
- nD.SndSky = ReadByte(Stream)
- nD.SndSlime = ReadByte(Stream)
- nD.SndLava = ReadByte(Stream)
- Return nD
- EndFunction
- EndType
- Type TQPlane
- Field Normal:TQVec3
- Field Dist:Float
- Field Typ:Int
- Function Read:TQPlane(Stream:TStream)
- Local nP:TQPlane = New TQPlane
- nP.Normal = TQVec3.Read(Stream)
- nP.Dist = ReadFloat(Stream)
- nP.Typ = ReadInt(Stream)
- Return nP
- EndFunction
- EndType
- Type TQClipNode
- Field PlaneNum:Int
- Field Front:Short
- Field Back:Short
- Function Read:TQClipNode(Stream:TStream)
- Local nC:TQClipNode = New TQClipNode
- nC.PlaneNum = ReadInt(Stream)
- nC.Front = ReadShort(Stream)
- nC.Back = ReadShort(Stream)
- Return nC
- EndFunction
- EndType
- 'Basic types
- Type TQVec3
- Field X:Float
- Field Y:Float
- Field Z:Float
- Function Read:TQVec3(Stream:TStream)
- Local nV:TQVec3 = New TQVec3
- nV.X = ReadFloat(Stream)
- nV.Y = ReadFloat(Stream)
- nV.Z = ReadFloat(Stream)
- Return nV
- EndFunction
- Function Size:Int()
- Return B_FLOAT * 3
- EndFunction
- EndType
- Type TQBoundBox
- Field Minimum:TQVec3
- Field Maximum:TQVec3
- Function Read:TQBoundBox(Stream:TStream)
- Local nB:TQBoundBox = New TQBoundBox
- nB.Minimum = TQVec3.Read(Stream)
- nB.Maximum = TQVec3.Read(Stream)
- Return nB
- EndFunction
- Function Size:Int()
- Return TQVec3.Size() * 2
- EndFunction
- EndType
- Type TQBBoxShort
- Field Minimum:Short
- Field Maximum:Short
- Function Read:TQBBoxShort(Stream:TStream)
- Local nB:TQBBoxShort = New TQBBoxShort
- nB.Minimum = ReadShort(Stream)
- nB.Maximum = ReadShort(Stream)
- Return nB
- EndFunction
- Function Size:Int()
- Return B_SHORT * 2
- EndFunction
- EndType
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement