Пример #1
0
func NewOctreeNode(vol *TVolume, parent *TOctree, root *TOctree, brickSize, nodeX, nodeY, nodeZ, rootX, rootY, rootZ int) *TOctree {
	var me = &TOctree{}
	var boxSize float64
	var allSolid = true
	var lastColor gfx.TColor
	var i = 0
	me.NodeX, me.NodeY, me.NodeZ, me.RootX, me.RootY, me.RootZ = nodeX, nodeY, nodeZ, rootX, rootY, rootZ
	if parent == nil {
		root, boxSize, me.Box, me.Total, me.Level, me.MaxLevel = me, vol.Box.Extent, vol.Box, 1, 0, 0
	} else {
		me.Level = parent.Level + 1
		boxSize = parent.Box.Extent * 0.5
		me.Box = gfx.NewBox(gfx.NilColor, num.Vec3{parent.Box.Pos.X + (boxSize * float64(nodeX)), parent.Box.Pos.Y + (boxSize * float64(nodeY)), parent.Box.Pos.Z + (boxSize * float64(nodeZ))}, num.Vec3{boxSize, boxSize, boxSize}, 0)
	}
	if boxSize > float64(brickSize) {
		me.ChildNodes = make([]*TOctree, 8)
		root.Total += 8
		for x := 0; x < 2; x++ {
			for y := 0; y < 2; y++ {
				for z := 0; z < 2; z++ {
					me.ChildNodes[i] = NewOctreeNode(vol, me, root, brickSize, x, y, z, rootX+(int(boxSize/2)*x), rootY+(int(boxSize/2)*y), rootZ+(int(boxSize/2)*z))
					i++
				}
			}
		}
		lastColor = me.ChildNodes[0].Col
		for _, cn := range me.ChildNodes {
			if (cn.Brick != nil) || !cn.Col.Equals(&lastColor) {
				allSolid = false
			}
		}
		if allSolid {
			me.ChildNodes = nil
			root.TotalSolids++
			me.Brick, me.Col = nil, lastColor
		} else {
			root.TotalBricks++
			me.Brick, me.Col = vol.MakeBrick(brickSize, rootX, rootY, rootZ, int(boxSize))
		}
	} else {
		root.MaxLevel = me.Level
		if me.Brick, me.Col = vol.SubVolume(me.Box, rootX, rootY, rootZ, int(boxSize)); me.Brick == nil {
			root.TotalSolids++
		} else {
			root.TotalBricks++
		}
	}
	return me
}
Пример #2
0
func NewVolume(filePath string, volSize int) *TVolume {
	var fsize = float64(volSize)
	var normVec num.Vec3
	var x, y, z int
	var prev, next uint8
	var max = volSize - 1
	var raw = LoadVolumeRaw(filePath, volSize)
	var invSize, inv256 = 1 / float64(volSize), 1.0 / 256.0
	var me = &TVolume{}
	me.InvScale, me.Scale = 1, 1
	me.Box = gfx.NewBox(gfx.NilColor, num.Vec3{0, 0, 0}, num.Vec3{fsize, fsize, fsize}, 0)
	me.Col, me.Normals, me.Size = make([][][]gfx.TColor, volSize), make([][][]num.Vec3, volSize), volSize
	for x = 0; x < volSize; x++ {
		me.Col[x], me.Normals[x] = make([][]gfx.TColor, volSize), make([][]num.Vec3, volSize)
		for y = 0; y < volSize; y++ {
			// log.Printf("ALLOC %v,%v...", x, y)
			me.Col[x][y], me.Normals[x][y] = make([]gfx.TColor, volSize), make([]num.Vec3, volSize)
		}
	}
	for x = 0; x < volSize; x++ {
		for y = 0; y < volSize; y++ {
			for z = 0; z < volSize; z++ {
				if raw[x][y][z] > 0 {
					me.Col[x][y][z].R = float64(x) * invSize
					me.Col[x][y][z].G = float64(y) * invSize
					me.Col[x][y][z].B = float64(z) * invSize
					me.Col[x][y][z].A = float64(raw[x][y][z]) * inv256 // float64(raw[x][y][z].A) / 256
					if x > 0 {
						prev = raw[x-1][y][z]
					} else {
						prev = 0
					}
					if x < max {
						next = raw[x+1][y][z]
					} else {
						next = 0
					}
					normVec.X = (float64(next) * inv256) - (float64(prev) * inv256)
					if y > 0 {
						prev = raw[x][y-1][z]
					} else {
						prev = 0
					}
					if y < max {
						next = raw[x][y+1][z]
					} else {
						next = 0
					}
					normVec.Y = (float64(next) * inv256) - (float64(prev) * inv256)
					if z > 0 {
						prev = raw[x][y][z-1]
					} else {
						prev = 0
					}
					if z < max {
						next = raw[x][y][z+1]
					} else {
						next = 0
					}
					normVec.Z = (float64(next) * inv256) - (float64(prev) * inv256)
					normVec.Normalize()
					me.Normals[x][y][z] = normVec
				}
			}
		}
	}
	return me
}
Пример #3
0
func Reinit(w, h int, target *image.RGBA) {
	var rt *TThread
	width, height = w, h
	Width, Height = float64(w), float64(h)
	WidthHeightRatio = Width / Height
	planeHeight = planeWidth / WidthHeightRatio
	planeHeightHalf = planeHeight / 2
	planeStepX, planeStepY = 1/Width, 1/Height
	planeStepWidth, planeStepHeight = planeStepX*planeWidth, planeStepY*planeHeight
	renderTarget, HeightWidthRatio, tileWidth, tileHeight = target, Height/Width, int(math.Ceil(Width/float64(NumThreads))), int(math.Ceil(Height/float64(NumThreads)))
	if Scene == nil {
		log.Printf("Loading scene...")
		RootOctree = voxels.NewOctree(voxels.NewVolume("/ssd2/ScanModels/dragon512.raw", volSize), 8)
		RootOctree.Print(0)
		MaxSteps = int(VolSize * 1.5)
		Scene = NewScene()
		Scene.CamPos.X, Scene.CamPos.Y, Scene.CamPos.Z = 21, 39, 35 // VolSize / 2, VolSize / 2, -(VolSize * 2)
		Scene.ColAmbient = gfx.TColor{0.66, 0.66, 0.66, 1}
		Scene.Fog = true
		Scene.Objects = []*gfx.TObject{
			gfx.NewSphere(gfx.TColor{0.33, 0.5, 0.33, 1}, num.Vec3{0, -8198, 0}, 8192, 0.33),
			gfx.NewSphere(gfx.TColor{0.66, 0.66, 0, 1}, num.Vec3{-8, 0, 0}, 2, 0.25),
			gfx.NewSphere(gfx.TColor{0, 0, 0.66, 1}, num.Vec3{2.5, -5, 0}, 1.5, 0.75),
			gfx.NewSphere(gfx.TColor{0.44, 0.22, 0, 1}, num.Vec3{0, 0, 16}, 2.5, 1),
			gfx.NewSphere(gfx.TColor{0, 0, 0.33, 1}, num.Vec3{0, 0, -18}, 2, 0.75),
			gfx.NewSphere(gfx.TColor{0.33, 0, 0, 1}, num.Vec3{2.5, 5, 0}, 1.5, 0.25),
			gfx.NewBox(gfx.TColor{0.44, 0.22, 0, 1}, num.Vec3{0, 0, 0}, num.Vec3{4, 4, 4}, 0.5),
			gfx.NewBox(gfx.TColor{0.05, 0.05, 0.05, 1}, num.Vec3{-256, -4, 4}, num.Vec3{512, 1, 8}, 0.5),
		}
		Scene.Lights = []*gfx.TLight{
			gfx.NewLight(num.Vec3{-200, 200, 200}, num.Vec3{20.1, 20.1, 20.1}, gfx.TColor{0.8, 0.8, 0.8, 1}, 256),
			// NewLight(num.Vec3 { 20, 20, 20 }, num.Vec3 { 0.4, 0.4, 0.4 }, gfx.TColor { 0.6, 0.6, 0.6, 1 }, 20),
			// NewLight(num.Vec3 { 10, 30, -10 }, num.Vec3 { 0.7,  0.7, 0.7 }, gfx.TColor { 0.4, 0.4, 0.4, 1 }, 20),
			gfx.NewLight(num.Vec3{600, 600, -600}, num.Vec3{81, 81, 81}, gfx.TColor{0.9, 0.9, 0.9, 1}, 512),
		}
		Scene.UpdateCamRot()
		threads = make([]*TThread, NumThreads*NumThreads)
		for t := 0; t < len(threads); t++ {
			rt = &TThread{}
			rt.picker = gfx.NewPicker(Scene.Objects, Scene.Range)
			rt.cols, rt.srpd, rt.srpr, rt.srd, rt.srld = make([]gfx.TColor, maxRec+2), make([]float64, maxRec+2), make([]float64, maxRec+2), make([]float64, maxRec+2), make([]float64, maxRec+2)
			rt.srays, rt.prays, rt.lrays = make([]*gfx.TRay, maxRec+2), make([]*gfx.TRay, maxRec+2), make([]*gfx.TRay, maxRec+2)
			rt.fcols = make([]gfx.TColor, 8)
			rt.fweights = make([]float64, 8)
			rt.voxelFilter = voxels.NewVoxelFilter(nil)
			rt.voxelFilter.SubVolSize = 8
			rt.numIndices, rt.numIndices2 = 8, 8
			rt.nodeIndices, rt.nodeIndices2 = make([]int, rt.numIndices), make([]int, rt.numIndices)
			for i := 0; i < rt.numIndices; i++ {
				rt.nodeIndices[i], rt.nodeIndices2[i] = i, i
			}
			if RootOctree != nil {
				rt.snrMaxLevel = float64(RootOctree.MaxLevel)
				rt.traverser = voxels.NewOctreeTraverser(RootOctree, Scene.Lights)
			}
			for i := 0; i < len(rt.srays); i++ {
				rt.prays[i], rt.srays[i], rt.lrays[i] = &gfx.TRay{}, &gfx.TRay{}, &gfx.TRay{}
			}
			threads[t] = rt
		}
	}
	Scene.FieldOfView = 33.75 * math.Min(2, WidthHeightRatio) //   math.Max(1, WidthHeightRatio))
	sceneZoom = 1 / math.Tan(num.DegToRad(Scene.FieldOfView)*0.5)
	planePosZ = planeWidthHalf * sceneZoom
	planeRange = planeWidth * Scene.Range
	runtime.GC()
}