func UpdateCam() {
	updateCam = false
	CamRad.X, CamRad.Y, CamRad.Z = num.DegToRad(CamRot.X), num.DegToRad(CamRot.Y), num.DegToRad(CamRot.Z)
	rmat = num.NewDmat4RotationY(CamRad.Y)
	CamLookAt.X, CamLookAt.Y, CamLookAt.Z = 0, 0, 1
	CamLookAt.MultMat(rmat)
	CamLookAt.Add(CamPos)
	CamAxisZ = CamLookAt.Sub(CamPos)
	CamAxisZ.Normalize()
	CamAxisX = CamUp.Cross(CamAxisZ)
	CamAxisY = CamAxisX.Cross(CamAxisZ.SwapSign())
	cmat1 = num.NewDmat4LookAt2(CamPos, CamAxisX, CamAxisY, CamAxisZ, tmpFloats)
	// origin.X, origin.Y, origin.Z = 0, 0, planeDist
	// origin.MultMat2(cmat1)
	// plane00.X, plane00.Y, plane00.Z = -0.5, 0.5, 0
	// plane00.MultMat2(cmat1)
	// plane10.X, plane10.Y, plane10.Z = 0.5, 0.5, 0
	// plane10.MultMat2(cmat1)
	// plane11.X, plane11.Y, plane11.Z = 0.5, -0.5, 0
	// plane11.MultMat2(cmat1)
	// plane01.X, plane01.Y, plane01.Z = -0.5, -0.5, 0
	// plane01.MultMat2(cmat1)
	// dx = plane10.Sub(plane00).Mult1(1 / width)
	// dy = plane01.Sub(plane00).Mult1(1 / height)
}
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()
}