func (gm *GeoMipMap) buildLODIndices(dev g3.GraphicsDevice) { gm.lodIndices = make([][]g3.IndexBuffer, numCrackTypes) for i, _ := range gm.lodIndices { gm.lodIndices[i] = make([]g3.IndexBuffer, gm.maxLOD) } indicesChannel := make(chan generatedLODIndices) numMipMaps := createAllLODIndices(gm.maxLOD, indicesChannel) for i := uint(0); i < numMipMaps; i++ { c := <-indicesChannel gm.lodIndices[c.crackIndex][c.lod] = dev.NewIndexBuffer(c.indices) } }
// TODO: How can this be done in parallel with goroutines? func (gm *GeoMipMap) buildQuadTreeRec(dev g3.GraphicsDevice, depth uint, x, y, w, h int, parent g3.SpatElement) (g3.SpatElement, int) { // TODO: remove magic numbers; calc from LOD if depth >= gm.maxDepth /*|| w <= gm.maxPatchWidth || h <= gm.maxPatchHeight*/ { //println(w, h) vertices, normals := createPatchVertices(gm.heightMap, x, y, w, h, gm.maxLOD, gm.whScale, gm.hScale) bbox := g3.MakeBoundingBoxFromPoints(vertices) center := bbox.CalculateCenter() patch := patch{center, dev.NewVertexBufferVec3(vertices), dev.NewVertexBufferVec3(normals)} return &g3.SpatLeaf{g3.SpatElementData{&bbox, parent, patch}}, 1 } p := &g3.SpatNode{g3.SpatElementData{nil, parent, nil}, make([]g3.SpatElement, 4)} c1, l1 := gm.buildQuadTreeRec(dev, depth+1, x, y, w/2, h/2, p) c2, l2 := gm.buildQuadTreeRec(dev, depth+1, x+w/2, y, w/2, h/2, p) c3, l3 := gm.buildQuadTreeRec(dev, depth+1, x, y+h/2, w/2, h/2, p) c4, l4 := gm.buildQuadTreeRec(dev, depth+1, x+w/2, y+h/2, w/2, h/2, p) bbox := g3.MakeBoundingBoxFromBoxes([]g3.BoundingBox{ *c1.GetBoundingVolume().(*g3.BoundingBox), *c2.GetBoundingVolume().(*g3.BoundingBox), *c3.GetBoundingVolume().(*g3.BoundingBox), *c4.GetBoundingVolume().(*g3.BoundingBox)}) p.BVolume = &bbox p.Children = []g3.SpatElement{c1, c2, c3, c4} return p, l1 + l2 + l3 + l4 }
func (gm *GeoMipMap) Render(dev g3.GraphicsDevice, frustum *g3.Frustum) { gm.root.TraverseFrustum(frustum, func(element g3.SpatElement, leaf bool) bool { if leaf { patch := element.GetData().(patch) dev.SetVertices(patch.vertices) dev.SetNormals(patch.normals) lodIndex, distIndex := gm.selectIndexBuffer(frustum, &patch.center, gm.maxLOD) dev.DrawIndexed(gm.lodIndices[lodIndex][distIndex]) } return true }) }