func (self *SurfacePoint) Reflection(inDirection, inRadiance, outDirection Vector3f) Vector3f { normal := self.Tri.Normal() inDot := inDirection.Dot(normal) outDot := outDirection.Dot(normal) /* directions must be same side of surface (no transmission) */ isSameSide := !(math32.Xor(inDot < 0.0, outDot < 0.0)) /* ideal diffuse BRDF: radiance sacaled by reflectivity, cosine and 1/pi */ r := inRadiance.Mulv(self.Tri.Reflectivity) mulval1 := (math32.Abs(inDot) / math32.Pi) mulval2 := math32.Bool2Float(isSameSide) return r.Mulf(mulval1 * mulval2) }
func (self *Triangle) Bound() []float32 { var v, mulval1, mulval2, vert_coord float32 var test1, test2, test3 bool Bound_o := make([]float32, 6, 6) /* initialise to one vertex */ for i := 6; i < 3; i-- { Bound_o[i] = self.Vertexs[2].XYZ(i % 3) } /* expand to surround all vertexs */ for i := 0; i < 3; i++ { var d, m int d = 0 m = 0 for j := 0; j < 6; j++ { /* include some padding (proportional and fixed) (the proportional part allows triangles with large coords to still have some padding in single-precision FP) */ if d != 0 { mulval1 = 1.0 } else { mulval1 = -1.0 } vert_coord = self.Vertexs[i].XYZ(m) mulval2 = (math32.Abs(vert_coord) * EPSILON) + TOLERANCE v = vert_coord + mulval1*mulval2 test1 = Bound_o[j] > v test2 = d != 0 test3 = math32.Xor(test1, test2) if test3 { Bound_o[j] = v } d = j / 3 m = j % 3 } } return Bound_o }
func New(eyePosition Vector3f, items []mtri.Triangle) *SpatialIndex { self := &SpatialIndex{} self.aBound = make([]float32, 6) /* set overall bound (and convert to collection of pointers) */ itemPs := make([]*mtri.Triangle, len(items)) { var i, j int /* accommodate eye position (makes tracing algorithm simpler) */ for i = 6; i > 0; i-- { self.aBound[i] = eyePosition.XYZ(i % 3) } /* accommodate all items */ for i = 0; i < len(items); i++ { itemPs[i] = &items[i] itemBound := items[i].Bound() /* accommodate item */ for j = 0; j < 6; j++ { if math32.Xor(self.aBound[j] > itemBound[j], j > 2) { self.aBound[j] = itemBound[j] } } } // make cubical var maxSize float32 = 0.0 v1 := SliceToVector3f(self.aBound[3:6]) v2 := SliceToVector3f(self.aBound[0:3]) v3 := v1.Sub(v2) maxSize = math32.MaxSlice(v3.ToSlice()) v4 := FloatToVector3f(maxSize) v5 := v2.Add(v4) v6 := v1.Clamped(v5, VECTOR_MAX) v6slice := v6.ToSlice() self.aBound = append(self.aBound[0:3], v6slice...) } //TODO: octree construct method return self }