// RotateTo adjusts the yaw and pitch to face a point. func (c *QuatCamera) RotateTo(center mgl.Vec3) { direction := center.Sub(c.position).Normalize() right := direction.Cross(AxisUp) up := right.Cross(direction) c.rotation = mgl.QuatLookAtV(c.position, center, up) }
//PointToLineDist distance from line (a,b) to point func PointToLineDist(a, b, point mgl32.Vec3) float32 { ab := b.Sub(a) ap := point.Sub(a) prj := ap.Dot(ab) lenSq := ab.Dot(ab) t := prj / lenSq return ab.Mul(t).Add(a).Sub(point).Len() }
func (f *fPlane) setPoints(v1, v2, v3 mgl32.Vec3) { aux1 := v1.Sub(v2) aux2 := v3.Sub(v2) f.N = aux2.Cross(aux1) f.N = safeNormalize(f.N) f.P = v2 f.D = -(f.N.Dot(f.P)) }
// Lerp will interpolate between the desired position/center by amount. func (c *QuatCamera) Lerp(position mgl.Vec3, center mgl.Vec3, amount float32) { direction := center.Sub(position).Normalize() right := direction.Cross(AxisUp) up := right.Cross(direction) targetRot := mgl.QuatLookAtV(position, center, up) c.rotation = mgl.QuatNlerp(c.rotation, targetRot, amount) c.position = c.position.Add(position.Sub(c.position).Mul(amount)) }
func getIntersection(fDst1, fDst2 float32, P1, P2 mgl32.Vec3, Hit *mgl32.Vec3) bool { if (fDst1 * fDst2) >= 0.0 { return false } if fDst1 == fDst2 { return false } *Hit = P1.Add((P2.Sub(P1)).Mul(-fDst1 / (fDst2 - fDst1))) return true }
func (p *fullPiano) GetKeyFromRay(rayStart, rayEnd mgl32.Vec3) *PianoKey { minDist := float32(10000) minDistIdx := -1 for i, k := range p.Keys { hit, pos := k.Hit(rayStart, rayEnd) if hit { dist := rayStart.Sub(pos).Len() if dist < minDist { minDistIdx = i minDist = dist } } } if minDistIdx != -1 { return &p.Keys[minDistIdx] } return nil }
// NewPianoKey returns a key for our piano. func NewPianoKey(pos mgl32.Vec3, lightColor mgl32.Vec3, white bool, freq float32) PianoKey { var color mgl32.Vec4 var keySize float32 if white { color = mgl32.Vec4{0.98, 0.97, 0.94} keySize = 2 } else { color = mgl32.Vec4{0.1, 0.1, 0.1, 1.0} keySize = 1 } pk := PianoKey{Pos: pos, Angle: 0, Color: color, Frequency: freq, Finger: -1, white: white, LightColor: lightColor} pk.BBox[0] = pos.Sub(mgl32.Vec3{0.5, 0.6, keySize}) pk.BBox[1] = pos.Add(mgl32.Vec3{0.5, 0.6, keySize}) pk.source = al.GenSources(1)[0] pk.source.SetGain(1.0) pk.source.SetPosition(al.Vector{pos.X(), pos.Y(), pos.Z()}) pk.source.SetVelocity(al.Vector{}) pk.buffers = al.GenBuffers(3) var samples [1024 * 16]int16 sampleRate := 44100 amplitude := float32(0.8 * 0x7FFF) for i := 0; i < len(samples); i++ { val := f32.Sin((2.0 * math.Pi * freq) / float32(sampleRate) * float32(i)) samples[i] = int16(amplitude * val) } buf := &bytes.Buffer{} binary.Write(buf, binary.LittleEndian, &samples) pk.buffers[0].BufferData(al.FormatMono16, buf.Bytes(), 44100) f, _ := os.Create("audio.raw") binary.Write(f, binary.LittleEndian, &samples) f.Close() return pk }
//PointToPlaneDist distance from plane (a,b,c) to point func PointToPlaneDist(a, b, c, point mgl32.Vec3) float32 { ab := b.Sub(a) ac := c.Sub(a) ap := point.Sub(a) normal := ac.Cross(ab).Normalize() return float32(math.Abs(float64(ap.Dot(normal)))) }
// updates the Colors of the model to fake lighting func esLightModel(p PositionComponent, s SizeComponent, m interface { Model() *render.StaticModel }) { if m.Model() == nil { return } xx, yy, zz := p.Position() bounds := s.Bounds() bounds = bounds.Shift(float32(xx), float32(yy), float32(zz)) c := mgl32.Vec3{float32(xx), float32(yy), float32(zz)} c[1] += bounds.Max.Sub(bounds.Min).Mul(0.5).Y() var light, skyLight float32 var count float32 for y := bounds.Min.Y(); y <= bounds.Max.Y(); y++ { for z := bounds.Min.Z() - 1; z <= bounds.Max.Z()+1; z++ { for x := bounds.Min.X() - 1; x <= bounds.Max.X()+1; x++ { bx, by, bz := int(math.Floor(float64(x))), int(math.Floor(float64(y))), int(math.Floor(float64(z))) bl := float32(chunkMap.BlockLight(bx, by, bz)) sl := float32(chunkMap.SkyLight(bx, by, bz)) dist := 1.0 - c.Sub(mgl32.Vec3{float32(bx) + 0.5, float32(by) + 0.5, float32(bz) + 0.5}).Len() if dist < 0 { continue } light += bl * dist skyLight += sl * dist count += dist } } } light /= count skyLight /= count model := m.Model() model.BlockLight, model.SkyLight = light, skyLight }
func (f *Frustum) SetCamera(p, l, u mgl32.Vec3) { Z := p.Sub(l) Z = safeNormalize(Z) X := u.Cross(Z) X = safeNormalize(X) Y := Z.Cross(X) nc := p.Sub(Z.Mul(f.near)) fc := p.Sub(Z.Mul(f.far)) ntl := nc.Add(Y.Mul(f.nh)).Sub(X.Mul(f.nw)) ntr := nc.Add(Y.Mul(f.nh)).Add(X.Mul(f.nw)) nbl := nc.Sub(Y.Mul(f.nh)).Sub(X.Mul(f.nw)) nbr := nc.Sub(Y.Mul(f.nh)).Add(X.Mul(f.nw)) ftl := fc.Add(Y.Mul(f.fh)).Sub(X.Mul(f.fw)) ftr := fc.Add(Y.Mul(f.fh)).Add(X.Mul(f.fw)) fbl := fc.Sub(Y.Mul(f.fh)).Sub(X.Mul(f.fw)) fbr := fc.Sub(Y.Mul(f.fh)).Add(X.Mul(f.fw)) const ( top = iota bottom left right nearP farP ) f.planes[top].setPoints(ntr, ntl, ftl) f.planes[bottom].setPoints(nbl, nbr, fbr) f.planes[left].setPoints(ntl, nbl, fbl) f.planes[right].setPoints(nbr, ntr, fbr) f.planes[nearP].setPoints(ntl, ntr, nbr) f.planes[farP].setPoints(ftr, ftl, fbl) }
//given 3 vertices, returns the normal of the plane formed by this triangle //TODO: move to a math package func NormalToPlane(v1, v2, v3 glm.Vec3) glm.Vec3 { u := v2.Sub(v1) v := v3.Sub(v1) return glm.Vec3{u.Y()*v.Z() - u.Z()*v.Y(), u.Z()*v.X() - u.X()*v.Z(), u.X()*v.Y() - u.Y()*v.X()} }
//PointLiesInsideTriangle - return true if the point lies within the triangle formed by points (a,b,c) func PointLiesInsideTriangle(a, b, c, point mgl32.Vec3) bool { ab := a.Sub(b) bc := b.Sub(c) ca := c.Sub(a) ap := a.Sub(point) bp := b.Sub(point) cp := c.Sub(point) cross1 := ap.Cross(ab) cross2 := bp.Cross(bc) cross3 := cp.Cross(ca) dot12 := cross1.Dot(cross2) dot13 := cross1.Dot(cross3) return dot12 > 0 && dot13 > 0 }