Esempio n. 1
0
func (self *SurfacePoint) NextDirection(r *rand.Rand,
	inDirection Vector3f,
	outDirection_o *Vector3f,
	colour *Vector3f) bool {
	reflectivityMean := self.Tri.Reflectivity.Dot(VECTOR_ONE) / 3.0

	/* russian-roulette for reflectance 'magnitude' */
	isAlive := r.Float32() < reflectivityMean

	if !isAlive {
		return false
	}

	/* cosine-weighted importance sample hemisphere */
	_2pr1 := math32.Pi * 2.0 * r.Float32()
	sr2 := math32.Sqrt(r.Float32())

	/* make coord frame coefficients (z in normal direction) */
	x := math32.Cos(_2pr1) * sr2
	y := math32.Sin(_2pr1) * sr2
	z := math32.Sqrt(1.0 - (sr2 * sr2))

	/* make coord frame */
	t := self.Tri.Tangent()
	n := self.Tri.Normal()
	var c Vector3f
	/* put normal on inward ray side of surface (preventing transmission) */
	if n.Dot(inDirection) < 0.0 {
		n.Neg()
	}
	c = n.Cross(t)

	/* scale frame by coefficients */
	tx := t.Mulf(x)
	cy := c.Mulf(y)
	nz := n.Mulf(z)

	/* make direction from sum of scaled components */
	sum := tx.Add(cy)
	*outDirection_o = sum.Add(nz)

	/* make color by dividing-out mean from reflectivity */
	*colour = self.Tri.Reflectivity.Mulf(1.0 / reflectivityMean)

	/* discluding degenerate result direction */
	return isAlive && !outDirection_o.Is_Zero()
}
Esempio n. 2
0
func (self *Triangle) SamplePoint(r *rand.Rand) Vector3f {
	/* get two randoms */
	sqr1 := math32.Sqrt(r.Float32())
	r2 := r.Float32()

	/* make barycentric coords */
	c0 := 1.0 - sqr1
	c1 := (1.0 - r2) * sqr1

	/* make barycentric axes */
	a0 := self.Vertexs[1].Sub(self.Vertexs[0])
	a1 := self.Vertexs[2].Sub(self.Vertexs[0])

	/* scale axes by coords */
	ac0 := a0.Mulf(c0)
	ac1 := a1.Mulf(c1)

	/* sum scaled components, and offset from corner */
	sum := ac0.Add(ac1)
	return sum.Add(self.Vertexs[0])
}
Esempio n. 3
0
func (self *Vector3f) Mag() float32 {
	return math32.Sqrt(self.X*self.X + self.Y*self.Y + self.Z*self.Z)
}
Esempio n. 4
0
func (self *Triangle) Area() float32 {
	/* half area of parallelogram (area = magnitude of cross of two edges) */
	normalV := self.NormalV()
	return math32.Sqrt(normalV.Dot(normalV)) * 0.5
}