예제 #1
0
func (c *FreeFlightCamera) Strafe(dist float32) {
	position := vec3.T(c.Pos)
	right := vec3.T(c.Right())

	right.Scale(dist)
	c.Pos = Vec3(vec3.Add(&position, &right))
}
예제 #2
0
func (c *FreeFlightCamera) Move(dist float32) {
	position := vec3.T(c.Pos)
	forward := vec3.T(c.Forward())

	forward.Scale(dist)
	c.Pos = Vec3(vec3.Add(&position, &forward))
}
예제 #3
0
func (c *FreeFlightCamera) Lift(dist float32) {
	position := vec3.T(c.Pos)
	forward := vec3.T(c.Forward())
	right := vec3.T(c.Right())
	up := vec3.Cross(&forward, &right)

	up.Scale(dist)
	c.Pos = Vec3(vec3.Add(&position, &up))
}
예제 #4
0
func (rt *Raytracer) traceScanLines(job *rtJob) {
	cfg := &rt.cfg
	idx := job.idx
	img := cfg.Images[idx]
	depth := rt.depth[idx]
	size := img.Bounds().Max

	testDepth := cfg.Depth
	nodeScale := cfg.TreeScale
	nodePos := vec3.T(cfg.TreePosition)
	viewDist := cfg.ViewDist

	jitter, step := 0, 1
	if cfg.Jitter {
		jitter = 1
		step = 2
		size.X *= 2
	}

	xInc, yInc, bottomLeft := rt.calcIncVectors(job.camera, size)
	eyePoint := vec3.T(job.camera.Position())

	var (
		col  color.RGBA
		dist float32
	)

	for h := job.from; h < job.to; h++ {
		start := ((h + idx) % 2) * jitter

		for w := start; w < size.X; w += step {
			x := xInc.Scaled(float32(w))
			y := yInc.Scaled(float32(h))

			x = vec3.Add(&x, &y)
			viewPlanePoint := vec3.Add(&bottomLeft, &x)

			dir := vec3.Sub(&viewPlanePoint, &eyePoint)
			dir.Normalize()

			ray := infiniteRay{eyePoint, dir}
			dx, dy := w/step, size.Y-h

			if testDepth {
				max := (float32(depth.Gray16At(dx, dy).Y) / math.MaxUint16) * viewDist
				dist, col = rt.intersectTree(job.tree, &ray, &nodePos, nodeScale, max, job.maxDepth, 0, 0)
				d := color.Gray16{uint16(math.MaxUint16 * (dist / viewDist))}
				depth.SetGray16(dx, dy, d)
			} else {
				_, col = rt.intersectTree(job.tree, &ray, &nodePos, nodeScale, viewDist, job.maxDepth, 0, 0)
			}
			img.SetRGBA(dx, dy, col)
		}
	}
}
예제 #5
0
func (c *FreeFlightCamera) LookAt() Vec3 {
	forward := vec3.T{0, 0, -1}
	position := vec3.T(c.Pos)

	quat := quaternion.FromEulerAngles(c.XRot, c.YRot, 0)
	quat.RotateVec3(&forward)

	return Vec3(vec3.Add(&position, &forward))
}
예제 #6
0
func (rt *Raytracer) calcIncVectors(camera Camera, size image.Point) (vec3.T, vec3.T, vec3.T) {
	width := float32(size.X)
	height := float32(size.Y)

	lookAtPoint := vec3.T(camera.LookAt())
	eyePoint := vec3.T(camera.Position())
	up := vec3.T(camera.Up())

	viewDirection := vec3.Sub(&lookAtPoint, &eyePoint)
	u := vec3.Cross(&viewDirection, &up)
	v := vec3.Cross(&u, &viewDirection)
	u.Normalize()
	v.Normalize()

	viewPlaneHalfWidth := float32(math.Tan(float64(rt.cfg.FieldOfView / 2)))
	aspectRatio := height / width
	viewPlaneHalfHeight := aspectRatio * viewPlaneHalfWidth

	sV := v.Scaled(viewPlaneHalfHeight)
	sU := u.Scaled(viewPlaneHalfWidth)

	lookV := vec3.Sub(&lookAtPoint, &sV)
	viewPlaneBottomLeftPoint := vec3.Sub(&lookV, &sU)

	xIncVector := u.Scaled(2 * viewPlaneHalfWidth)
	yIncVector := v.Scaled(2 * viewPlaneHalfHeight)

	xIncVector[0] /= width
	xIncVector[1] /= width
	xIncVector[2] /= width

	yIncVector[0] /= height
	yIncVector[1] /= height
	yIncVector[2] /= height

	return xIncVector, yIncVector, viewPlaneBottomLeftPoint
}
예제 #7
0
func (c *FreeFlightCamera) Right() Vec3 {
	up := vec3.T(c.Up())
	forward := vec3.T(c.Forward())
	return Vec3(vec3.Cross(&up, &forward))
}
예제 #8
0
func (c *FreeFlightCamera) Forward() Vec3 {
	lookAt := vec3.T(c.LookAt())
	position := vec3.T(c.Pos)
	return Vec3(vec3.Sub(&lookAt, &position))
}