func pov(p pak.MultiPak, args ...string) { fs := flag.NewFlagSet("pov", flag.ExitOnError) fs.Usage = func() { fmt.Fprintf(os.Stderr, "Usage: %s -pak <pak0,pak1,...> pov [options] <maps/eXmX.bsp> \n", os.Args[0]) fs.PrintDefaults() } lights := fs.Bool("lights", true, "Export lights.") flatColor := fs.String("flat_color", "Gray25", "") textures := fs.Bool("textures", false, "Use textures.") //maps := fs.String("maps", ".*", "Regex of maps to convert.") fs.Parse(args) if fs.NArg() == 0 { log.Fatalf("Need to specify a map name.") } maps := fs.Arg(0) res, err := p.Get(maps) if err != nil { log.Fatalf("Finding %q: %v", maps, err) } m, err := bsp.Load(res) if err != nil { log.Fatalf("Loading %q: %v", maps, err) } mesh, err := m.POVTriangleMesh(bsp.ModelMacroPrefix(maps), *textures, *flatColor) if err != nil { log.Fatalf("Error getting mesh: %v", err) } fmt.Println(mesh) if *lights { fmt.Println(m.POVLights()) } }
func writePOV(fn, texturesPath string, state *dem.State, cameraLight, radiosity bool, cameraType string, cameraAngle string) { ufo, err := os.Create(fn) if err != nil { log.Fatalf("Creating %q: %v", fn, err) } defer ufo.Close() fo := bufio.NewWriter(ufo) defer fo.Flush() lookAt := bsp.Vertex{ X: 1, Y: 0, Z: 0, } pos := bsp.Vertex{ X: state.Entities[state.CameraEnt].Pos.X, Y: state.Entities[state.CameraEnt].Pos.Y, Z: state.Entities[state.CameraEnt].Pos.Z, } models := []string{} if *entities { for _, m := range state.ServerInfo.Models { if !validModel(m) { continue } if strings.HasSuffix(m, ".mdl") { models = append(models, fmt.Sprintf(`%s/model.inc`, m)) } if strings.HasSuffix(m, ".bsp") { models = append(models, fmt.Sprintf(`%s/level.inc`, m)) } } } eyeLevel := bsp.Vertex{ Z: 10, } tmpl := template.Must(template.New("header").Parse(` {{$root := .}} #version {{.Version}}; #include "rad_def.inc" global_settings { assumed_gamma {{.Gamma}} {{ if .Radiosity }}radiosity { Rad_Settings(Radiosity_Normal,off,off)}{{ end }} } #include "{{.Prefix}}progs/soldier.mdl/model.inc" #include "{{.Prefix}}{{.Level}}/level.inc" {{ range .Models }}#include "{{$root.Prefix}}{{ . }}" {{ end }} camera { {{.CameraType}} angle {{.CameraAngle}} location <0,0,0> sky <0,0,1> up <0,0,9> right <-16,0,0> look_at <{{.LookAt}}> rotate <{{.AngleX}},0,0> rotate <0,{{.AngleY}},0> rotate <0,0,{{.AngleZ}}> translate <{{.Pos}}> translate <{{.EyeLevel}}> } `)) gamma := "1.0" switch *version { case "3.6": gamma = "2.0" } if err := tmpl.Execute(fo, struct { Gamma string Prefix string Version string Radiosity bool AngleX, AngleY, AngleZ float64 Pos string LookAt string Level string EyeLevel string Models []string CameraType string CameraAngle string }{ Prefix: *prefix, Version: *version, Gamma: gamma, Radiosity: radiosity, Level: state.ServerInfo.Models[0], Models: models, LookAt: lookAt.String(), AngleX: float64(state.ViewAngle.Z), AngleY: float64(state.ViewAngle.X), AngleZ: float64(state.ViewAngle.Y), Pos: pos.String(), EyeLevel: eyeLevel.String(), CameraType: cameraType, CameraAngle: cameraAngle, }); err != nil { log.Fatalf("Executing template: %v", err) } re := regexp.MustCompile(`^\*(\d+)$`) for _, e := range state.Entities { if !e.Visible { continue } nm := e.Model mod := state.ServerInfo.Models[nm] m := re.FindStringSubmatch(mod) if len(m) == 2 { i, _ := strconv.Atoi(m[1]) fmt.Fprintf(fo, "%s_%d(<%v>,<0,0,0>,\"%s\")\n", bsp.ModelMacroPrefix(state.ServerInfo.Models[0]), i, e.Pos.String(), *prefix+texturesPath) } } if cameraLight { fmt.Fprintf(fo, "light_source { <%s> rgb<1,1,1> translate <%s> }\n", pos.String(), eyeLevel.String()) } if *entities { for n, e := range state.Entities { if !e.Visible { continue } if int(state.CameraEnt) == n { continue } if e.Model == 0 { // Unused. continue } if int(e.Model) >= len(state.ServerInfo.Models) { // TODO: this is dynamic entities? continue } name := state.ServerInfo.Models[e.Model] frame := int(e.Frame) //log.Printf("Entity %d has model %d of %d", n, e.Model, len(d.ServerInfo.Models)) //log.Printf(" Name: %q", d.ServerInfo.Models[e.Model]) if validModel(state.ServerInfo.Models[e.Model]) { a := e.Angle a.X, a.Y, a.Z = a.Z, a.X, a.Y modelName := state.ServerInfo.Models[e.Model] if strings.HasSuffix(modelName, ".mdl") { useTextures := true // TODO if useTextures { skinName := path.Join(name, fmt.Sprintf("skin_%v.png", e.Skin)) fmt.Fprintf(fo, "// Entity %d\n%s(<%s>,<%s>,\"%s\")\n", n, frameName(name, frame), e.Pos.String(), a.String(), *prefix+skinName) } else { fmt.Fprintf(fo, "// Entity %d\n%s(<%s>,<%s>)\n", n, frameName(name, frame), e.Pos.String(), a.String()) } } else if strings.HasSuffix(state.ServerInfo.Models[e.Model], ".bsp") { fmt.Fprintf(fo, "// BSP Entity %d\n%s_0(<%s>,<%s>, \"%s\")\n", n, bsp.ModelMacroPrefix(modelName), e.Pos.String(), a.String(), *prefix+modelName) } } } } }
func convert(p pak.MultiPak, args ...string) { fs := flag.NewFlagSet("convert", flag.ExitOnError) fs.Usage = func() { fmt.Fprintf(os.Stderr, "Usage: %s -pak pak0,pak1,... convert [options]\n", os.Args[0]) fs.PrintDefaults() } outDir := fs.String("out", ".", "Output directory.") retexturePack := fs.String("retexture", "", "Path to retexture pack.") flatColor := fs.String("flat_color", "<0.25,0.25,0.25>", "") textures := fs.Bool("textures", true, "Use textures.") lights := fs.Bool("lights", false, "Export lights.") maps := fs.String("maps", ".*", "Maps regex.") fs.Parse(args) re, err := regexp.Compile(*maps) if err != nil { log.Fatalf("Maps regex %q invalid: %v", *maps, err) } //errors := []string{} os.Mkdir(*outDir, 0755) for _, mf := range p.List() { if path.Ext(mf) != ".bsp" { continue } if !re.MatchString(mf) { continue } func() { o, err := p.Get(mf) if err != nil { log.Fatalf("Getting %q: %v", mf, err) } b, err := bsp.Load(o) if err != nil { log.Fatalf("Loading %q: %v", mf, err) } mkdirP(*outDir, mf) fn := fmt.Sprintf(path.Join(mf, "level.inc")) of, err := os.Create(path.Join(*outDir, fn)) if err != nil { log.Fatalf("Model create of %q fail: %v", fn, err) } defer of.Close() m, err := b.POVTriangleMesh(bsp.ModelMacroPrefix(mf), *textures, *flatColor) if err != nil { log.Fatalf("Making mesh of %q: %v", mf, err) } fmt.Fprintln(of, m) if *lights { fmt.Fprintln(of, b.POVLights()) } if *textures { for n, texture := range b.Raw.MipTexData { fn := path.Join(*outDir, mf, fmt.Sprintf("texture_%d.png", n)) retexFn, retex := retexture(*retexturePack, mf, b.Raw.MipTex[n], texture) if retex { if err := os.Symlink(retexFn, fn); err != nil { log.Fatalf("Failed to symlink %q to %q for texture pack: %v", fn, retexFn, err) } continue } func() { of, err := os.Create(fn) if err != nil { log.Fatalf("Texture create of %q fail: %v", fn, err) } defer of.Close() if err := (&png.Encoder{CompressionLevel: pngCompressionLevel}).Encode(of, texture); err != nil { log.Fatalf("Encoding texture to png: %v", err) } }() } } }() } }