Skip to content

Commit bdf2780

Browse files
committed
parse more data & refactor
1 parent 71db9ef commit bdf2780

File tree

8 files changed

+478
-133
lines changed

8 files changed

+478
-133
lines changed

go.mod

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,19 @@ go 1.18
44

55
require (
66
github.com/galaco/bsp v0.3.0
7+
github.com/galaco/studiomodel v0.2.2
8+
github.com/galaco/vpk2 v1.0.0
79
github.com/go-gl/mathgl v1.0.0
10+
github.com/pkg/errors v0.9.1
811
github.com/stretchr/testify v1.7.5
912
)
1013

1114
require (
15+
github.com/andygrunwald/vdf v1.0.0 // indirect
1216
github.com/davecgh/go-spew v1.1.1 // indirect
1317
github.com/pmezard/go-difflib v1.0.0 // indirect
1418
golang.org/x/image v0.0.0-20210504121937-7319ad40d33e // indirect
1519
gopkg.in/yaml.v3 v3.0.1 // indirect
1620
)
21+
22+
replace github.com/galaco/studiomodel => github.com/markus-wa/studiomodel v1.0.0-alpha.2.0.20220628141029-a69ed886475d

go.sum

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,20 @@
1+
github.com/andygrunwald/vdf v1.0.0 h1:2HuC85EVF1Sm1bwKH8tiyucny2qzf9GSjB3flsdqoM4=
2+
github.com/andygrunwald/vdf v1.0.0/go.mod h1:qi5jZfY3lrHXbibKeC2MCEge1tOsLODBgOHoS+RbRLk=
13
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
24
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
35
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
46
github.com/galaco/bsp v0.3.0 h1:+NngnwLiFEJbvZ2yrva75Veh+zaWtvkN+l4oIGos1t8=
57
github.com/galaco/bsp v0.3.0/go.mod h1:DKbfL4GiSQ0RvdbMJAE8q/hP4AvKx4AZM2NQzMgqNe4=
8+
github.com/galaco/studiomodel v0.2.2 h1:RfWJd5NbKa9RG/QybYFgLVeK1T91R762moHmhYI7JDo=
9+
github.com/galaco/studiomodel v0.2.2/go.mod h1:3sH4l4amq6gij37dAP6d5Jn99YRL6Hm8u6uq4t7zIY8=
10+
github.com/galaco/vpk2 v1.0.0 h1:+C44FliOTW2CH+Nz1w1WvtL93hJUUCHEGPcl0z5dBJc=
11+
github.com/galaco/vpk2 v1.0.0/go.mod h1:jL22XAWuUlYUmONuamxDdbDlGJhuOFkqNRPJwuBA3X8=
612
github.com/go-gl/mathgl v1.0.0 h1:t9DznWJlXxxjeeKLIdovCOVJQk/GzDEL7h/h+Ro2B68=
713
github.com/go-gl/mathgl v1.0.0/go.mod h1:yhpkQzEiH9yPyxDUGzkmgScbaBVlhC06qodikEM0ZwQ=
14+
github.com/markus-wa/studiomodel v1.0.0-alpha.2.0.20220628141029-a69ed886475d h1:r4tm/sYpuUVETo32g0FpRMo4KtpN48drwpUuu7KhSss=
15+
github.com/markus-wa/studiomodel v1.0.0-alpha.2.0.20220628141029-a69ed886475d/go.mod h1:3sH4l4amq6gij37dAP6d5Jn99YRL6Hm8u6uq4t7zIY8=
16+
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
17+
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
818
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
919
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
1020
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=

pkg/bsptracer/bsptracer.go

Lines changed: 68 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,21 @@
33
package bsptracer
44

55
import (
6-
"path/filepath"
7-
86
"github.com/galaco/bsp"
97
"github.com/galaco/bsp/lumps"
108
"github.com/galaco/bsp/primitives/brush"
119
"github.com/galaco/bsp/primitives/brushside"
10+
"github.com/galaco/bsp/primitives/dispinfo"
11+
"github.com/galaco/bsp/primitives/disptris"
12+
"github.com/galaco/bsp/primitives/dispvert"
1213
"github.com/galaco/bsp/primitives/face"
1314
"github.com/galaco/bsp/primitives/leaf"
1415
"github.com/galaco/bsp/primitives/node"
1516
"github.com/galaco/bsp/primitives/plane"
17+
"github.com/galaco/studiomodel"
18+
"github.com/galaco/vpk2"
1619
"github.com/go-gl/mathgl/mgl32"
20+
"github.com/pkg/errors"
1721
)
1822

1923
const (
@@ -35,19 +39,28 @@ type Map struct {
3539
surfaces []face.Face
3640
surfEdges []int32
3741
vertices []mgl32.Vec3
42+
game *lumps.Game // TODO: may be needed for props + leaves? or maybe not ...
43+
dispInfo []dispinfo.DispInfo // TODO: trace against displacements
44+
dispVerts []dispvert.DispVert
45+
dispTris []disptris.DispTri
3846

3947
// constructed by this package
48+
entities []map[string]string // TODO: not yet sure if we'll need this
4049
polygons []polygon
50+
props []*studiomodel.StudioModel // TODO: place props in the world and trace against them
4151
}
4252

43-
// LoadMap loads a BSP map from a file.
44-
func LoadMap(directory, mapName string) (*Map, error) {
45-
bspfile, err := bsp.ReadFromFile(filepath.Join(directory, mapName))
46-
if err != nil {
47-
return nil, err
48-
}
53+
// LoadMap loads a map from a BSP file and VPKs.
54+
// May return MissingModelsError if models can't be found - this is not fatal and the map can still be used.
55+
func LoadMap(bspfile *bsp.Bsp, vpks ...*vpk.VPK) (Map, error) {
56+
entitiesStr := bspfile.Lump(bsp.LumpEntities).(*lumps.EntData).GetData()
57+
entities := parseEntities(entitiesStr)
4958

50-
m := &Map{
59+
polygons := parsePolygons(bspfile)
60+
61+
props, missingModelsErr := loadProps(bspfile, vpks)
62+
63+
m := Map{
5164
brushes: bspfile.Lump(bsp.LumpBrushes).(*lumps.Brush).GetData(),
5265
brushSides: bspfile.Lump(bsp.LumpBrushSides).(*lumps.BrushSide).GetData(),
5366
edges: bspfile.Lump(bsp.LumpEdges).(*lumps.Edge).GetData(),
@@ -59,55 +72,69 @@ func LoadMap(directory, mapName string) (*Map, error) {
5972
surfaces: bspfile.Lump(bsp.LumpFaces).(*lumps.Face).GetData(),
6073
surfEdges: bspfile.Lump(bsp.LumpSurfEdges).(*lumps.Surfedge).GetData(),
6174
vertices: bspfile.Lump(bsp.LumpVertexes).(*lumps.Vertex).GetData(),
75+
game: bspfile.Lump(bsp.LumpGame).(*lumps.Game).GetData(),
76+
dispInfo: bspfile.Lump(bsp.LumpDispInfo).(*lumps.DispInfo).GetData(),
77+
dispVerts: bspfile.Lump(bsp.LumpDispVerts).(*lumps.DispVert).GetData(),
78+
dispTris: bspfile.Lump(bsp.LumpDispTris).(*lumps.DispTris).GetData(),
79+
entities: entities,
80+
polygons: polygons,
81+
props: props,
6282
}
6383

64-
m.parsePolygons()
84+
if missingModelsErr != nil {
85+
return m, missingModelsErr
86+
}
6587

6688
return m, nil
6789
}
6890

69-
func (m *Map) parsePolygons() {
70-
m.polygons = make([]polygon, len(m.surfaces), 2*len(m.surfaces))
71-
72-
for _, surface := range m.surfaces {
73-
firstEdge := int(surface.FirstEdge)
74-
numEdges := int(surface.NumEdges)
91+
// LoadMapFromFileSystem loads a BSP map from the file system.
92+
// vpkPaths is a list of paths to either single or multi VPKs to load models, in order of priority.
93+
// for CS:GO, vpkPaths should be paths to ("SteamLibrary/steamapps/common/Counter-Strike Global Offensive/csgo/pak01", "SteamLibrary/steamapps/common/Counter-Strike Global Offensive/platform/platform_pak01")
94+
// See also LoadMap()
95+
func LoadMapFromFileSystem(mapPath string, vpkPaths ...string) (Map, error) {
96+
bspfile, err := bsp.ReadFromFile(mapPath)
97+
if err != nil {
98+
return Map{}, err
99+
}
75100

76-
if numEdges < 3 || numEdges > maxSurfinfoVerts || surface.TexInfo <= 0 {
77-
continue
78-
}
101+
vpks := make([]*vpk.VPK, len(vpkPaths))
79102

80-
var (
81-
polygon polygon
82-
edge mgl32.Vec3
83-
)
103+
for i, path := range vpkPaths {
104+
var err error
84105

85-
for i := 0; i < numEdges; i++ {
86-
edgeIndex := m.surfEdges[firstEdge+i]
87-
if edgeIndex >= 0 {
88-
edge = m.vertices[m.edges[edgeIndex][0]]
89-
} else {
90-
edge = m.vertices[m.edges[-edgeIndex][1]]
106+
vpks[i], err = vpk.Open(vpk.MultiVPK(path))
107+
if err != nil {
108+
vpks[i], err = vpk.Open(vpk.SingleVPK(path))
109+
if err != nil {
110+
return Map{}, errors.Wrapf(err, "failed to open vpk %q", path)
91111
}
92-
93-
polygon.verts[i] = edge
94112
}
95-
96-
polygon.numVerts = numEdges
97-
polygon.plane.origin = m.planes[surface.Planenum].Normal
98-
polygon.plane.distance = m.planes[surface.Planenum].Distance
99-
m.polygons = append(m.polygons, polygon)
100113
}
114+
115+
return LoadMap(bspfile, vpks...)
101116
}
102117

103118
// IsVisible returns true if destination is visible from origin, as computed by
104119
// a ray trace.
105-
func (m *Map) IsVisible(origin, destination mgl32.Vec3) bool {
120+
func (m Map) IsVisible(origin, destination mgl32.Vec3) bool {
106121
return m.TraceRay(origin, destination).Fraction >= 1
107122
}
108123

124+
// Trace captures the result of a ray trace.
125+
type Trace struct {
126+
AllSolid bool
127+
StartSolid bool
128+
Fraction float32
129+
FractionLeftSolid float32
130+
EndPos mgl32.Vec3
131+
Contents int32
132+
Brush *brush.Brush
133+
NumBrushSides int32
134+
}
135+
109136
// TraceRay traces a ray from origin to destination and returns the result.
110-
func (m *Map) TraceRay(origin, destination mgl32.Vec3) *Trace {
137+
func (m Map) TraceRay(origin, destination mgl32.Vec3) *Trace {
111138
out := &Trace{
112139
AllSolid: true,
113140
StartSolid: true,
@@ -127,7 +154,7 @@ func (m *Map) TraceRay(origin, destination mgl32.Vec3) *Trace {
127154
return out
128155
}
129156

130-
func (m *Map) rayCastNode(nodeIndex int32, startFraction, endFraction float32,
157+
func (m Map) rayCastNode(nodeIndex int32, startFraction, endFraction float32,
131158
origin, destination mgl32.Vec3, out *Trace,
132159
) {
133160
if out.Fraction <= startFraction {
@@ -237,7 +264,7 @@ func (m *Map) rayCastNode(nodeIndex int32, startFraction, endFraction float32,
237264
}
238265
}
239266

240-
func (m *Map) rayCastBrush(brush *brush.Brush, origin, destination mgl32.Vec3, out *Trace) {
267+
func (m Map) rayCastBrush(brush *brush.Brush, origin, destination mgl32.Vec3, out *Trace) {
241268
if brush.NumSides != 0 {
242269
fractionToEnter := float32(-99)
243270
fractionToLeave := float32(1)
@@ -324,7 +351,7 @@ func (m *Map) rayCastBrush(brush *brush.Brush, origin, destination mgl32.Vec3, o
324351
}
325352
}
326353

327-
func (m *Map) rayCastSurface(index int, origin, destination mgl32.Vec3, out *Trace) {
354+
func (m Map) rayCastSurface(index int, origin, destination mgl32.Vec3, out *Trace) {
328355
if index >= len(m.polygons) {
329356
return
330357
}
@@ -367,33 +394,3 @@ func (m *Map) rayCastSurface(index int, origin, destination mgl32.Vec3, out *Tra
367394
}
368395
}
369396
}
370-
371-
type polygon struct {
372-
verts [maxSurfinfoVerts]mgl32.Vec3
373-
numVerts int
374-
plane vplane
375-
edgePlanes []vplane
376-
vec2d [maxSurfinfoVerts]mgl32.Vec3
377-
skip int
378-
}
379-
380-
type vplane struct {
381-
origin mgl32.Vec3
382-
distance float32
383-
}
384-
385-
func (v *vplane) dist(destination mgl32.Vec3) float32 {
386-
return v.origin.Dot(destination) - v.distance
387-
}
388-
389-
// Trace captures the result of a ray trace.
390-
type Trace struct {
391-
AllSolid bool
392-
StartSolid bool
393-
Fraction float32
394-
FractionLeftSolid float32
395-
EndPos mgl32.Vec3
396-
Contents int32
397-
Brush *brush.Brush
398-
NumBrushSides int32
399-
}

0 commit comments

Comments
 (0)