Beispiel #1
0
// forAllSurfaces loops over all surfaces of the given model and concurrently
// launches functions mapping the surfaces to string values. The results of the
// mapping operation are handled by a single goroutine to prevent writes from
// potentially parallel sources.
func forAllSurfaces(model *md3.Model, fn surfaceMappingFunc) map[*md3.Surface]string {

	numSurfs := model.NumSurfaces()

	pairs := make(map[*md3.Surface]string, numSurfs)
	builtPairs := make(chan surfaceStringPair)
	waitSignal := make(chan bool)

	for surfaceIndex := 0; surfaceIndex < numSurfs; surfaceIndex++ {
		surf := model.Surface(surfaceIndex)
		go fn(surf, builtPairs)
	}

	go func(count int, builtPairs <-chan surfaceStringPair, waitSignal chan<- bool) {
		for ; count > 0; count-- {
			pair := <-builtPairs
			pairs[pair.surface] = pair.value
		}
		waitSignal <- true
	}(numSurfs, builtPairs, waitSignal)

	<-waitSignal

	return pairs
}
Beispiel #2
0
// objTriangleLists produces a map of strings that can be used to write the
// triangle lists for all frames of an MD3's surface. Special variation on the
// forAllSurfaces function that handles base vertices (i.e., sequence is
// much more important).
func objTriangleLists(model *md3.Model) map[*md3.Surface]string {
	numSurfs := model.NumSurfaces()

	triStrings := make(map[*md3.Surface]string, numSurfs)
	builtPairs := make(chan surfaceStringPair)
	waitSignal := make(chan bool)

	baseVertex := 1
	for surfaceIndex := 0; surfaceIndex < numSurfs; surfaceIndex++ {
		surf := model.Surface(surfaceIndex)
		go surfaceTriangleList(surf, baseVertex, builtPairs)
		baseVertex += surf.NumVertices()
	}

	go func(count int, builtPairs <-chan surfaceStringPair, waitSignal chan<- bool) {
		for ; count > 0; count-- {
			pair := <-builtPairs
			triStrings[pair.surface] = pair.value
		}
		waitSignal <- true
	}(numSurfs, builtPairs, waitSignal)

	<-waitSignal

	return triStrings
}
Beispiel #3
0
func performConvertModel(modelPath string, model *md3.Model, signal chan<- bool, writeQueue chan<- func()) {

	waitSignal := make(chan bool)
	triLists := objTriangleLists(model)
	tcLists := objTexCoordLists(model)

	var _ = triLists
	var _ = tcLists

	name := path.Base(modelPath)
	name = name[:len(name)-len(path.Ext(name))]
	dir := path.Clean(*outputPath)
	os.MkdirAll(dir, 0755)

	numFrames := model.NumFrames()

	for frame := 0; frame < numFrames; frame++ {
		go func(frame int) {
			writeQueue <- func() {
				defer func(waitSignal chan<- bool) {
					go func() { waitSignal <- true }()
				}(waitSignal)

				var err error
				var file *os.File
				outName := fmt.Sprintf("%s+%d.obj", name, frame)
				outPath := path.Join(dir, outName)

				file, err = os.Create(outPath)
				if err != nil {
					log.Println("Error creating", outPath, "from", modelPath, "->", err)
					return
				}
				defer file.Close()

				_, err = fmt.Fprintf(file, "o %s\n", model.Name())
				if err != nil {
					log.Println("Error writing header for", outPath, "from", modelPath, "->", err)
				}

				numSurfaces := model.NumSurfaces()
				posNorms := objPosNormLists(model, frame)
				for surfIndex := 0; surfIndex < numSurfaces; surfIndex++ {
					surf := model.Surface(surfIndex)
					err = writeOBJSurface(file, surf, posNorms, tcLists, triLists)
					if err != nil {
						log.Println("Error writing surface for", outPath, "from", modelPath, "->", err)
						return
					}
				}
			}
		}(frame)
	}

	for frame := 0; frame < numFrames; frame++ {
		<-waitSignal
	}

	signal <- true
}
Beispiel #4
0
func logModelSpec(model *md3.Model) {
	fmt.Printf("MD3(%s):\n", stringOrEmpty(model.Name(), "no name"))
	fmt.Printf("  Frames: %d\n", model.NumFrames())
	fmt.Printf("  Tags(%d):\n", model.NumTags())
	for tag := range model.Tags() {
		fmt.Printf("    %s\n", tag.Name())
	}
	fmt.Printf("  Surfaces(%d):\n", model.NumSurfaces())
	for surf := range model.Surfaces() {
		fmt.Printf("    %s:\n", stringOrEmpty(surf.Name(), "(no name)"))
		if surf.NumFrames() != model.NumFrames() {
			fmt.Printf("      Frames:    %d\n", surf.NumFrames())
		}
		fmt.Printf("      Vertices:  %d\n", surf.NumVertices())
		fmt.Printf("      Triangles: %d\n", surf.NumTriangles())
		fmt.Printf("      Shaders[%d]:\n", surf.NumShaders())
		for shader := range surf.Shaders() {
			fmt.Printf("        Shader[%d]: %s\n", shader.Index, stringOrEmpty(shader.Name, "(no name)"))
		}
	}
}