// Handle movement assuming there is a physics body associated with the camera. // This attempts to smooth out movement by adding a higher initial velocity push // and then capping movement once max accelleration is reached. func (c *cam) move(bod vu.Pov, x, y, z float64, dir *lin.Q) { if body := bod.Body(); body != nil { boost := 40.0 // kick into high gear from stop. maxAccel := 10.0 // limit accelleration. sx, _, sz := body.Speed() if x != 0 { switch { case sx == 0.0: // apply push in the current direction. dx, dy, dz := lin.MultSQ(x*boost, 0, 0, dir) body.Push(dx, dy, dz) case math.Abs(sx) < maxAccel && math.Abs(sz) < maxAccel: dx, dy, dz := lin.MultSQ(x, 0, 0, dir) body.Push(dx, dy, dz) } } if z != 0 { switch { case sz == 0.0: dx, dy, dz := lin.MultSQ(0, 0, z*boost, dir) body.Push(dx, dy, dz) case math.Abs(sx) < maxAccel && math.Abs(sz) < maxAccel: dx, dy, dz := lin.MultSQ(0, 0, z, dir) body.Push(dx, dy, dz) } } } else { bod.Move(x, y, z, dir) } }
// Culler implmentation. // Project the part location back along the lookat vector. func (fc *frontCull) Cull(cam Camera, px, py, pz float64) bool { fudgeFactor := float64(0.8) // don't move all the way up. cx, cy, cz := lin.MultSQ(0, 0, -fc.radius*fudgeFactor, cam.Lookat()) px, py, pz = px-cx, py-cy, pz-cz // move part location back. toc := cam.Distance(px, py, pz) // cull if outside radius. return toc > fc.rr }
// Move relative to the given orientation. // Use Look() to fly. Use Yaw() to run along XZ. func (c *camera) Move(x, y, z float64, q *lin.Q) { dx, dy, dz := lin.MultSQ(x, y, z, q) c.at.Loc.X += dx c.at.Loc.Y += dy c.at.Loc.Z += dz c.updateTransform() }
// Implements Shape.Aabb // The axis aligned bounding box must be big enough to surround a box // that has been transformed. func (b *box) Aabb(t *lin.T, ab *Abox, margin float64) *Abox { // transform the basis vectors, keeping them positive for extents. xx, xy, xz := lin.MultSQ(1, 0, 0, t.Rot) yx, yy, yz := lin.MultSQ(0, 1, 0, t.Rot) zx, zy, zz := lin.MultSQ(0, 0, 1, t.Rot) xx, xy, xz = math.Abs(xx), math.Abs(xy), math.Abs(xz) yx, yy, yz = math.Abs(yx), math.Abs(yy), math.Abs(yz) zx, zy, zz = math.Abs(zx), math.Abs(zy), math.Abs(zz) // Dot the half-extents, plus margin, with the transformed basis vectors. // to get the furthest extent in each direction. hmx, hmy, hmz := b.Hx+margin, b.Hy+margin, b.Hz+margin ex := hmx*xx + hmy*xy + hmz*xz ey := hmx*yx + hmy*yy + hmz*yz ez := hmx*zx + hmy*zy + hmz*zz // assign the final Aabb values. ab.Sx, ab.Sy, ab.Sz = t.Loc.X-ex, t.Loc.Y-ey, t.Loc.Z-ez ab.Lx, ab.Ly, ab.Lz = t.Loc.X+ex, t.Loc.Y+ey, t.Loc.Z+ez return ab }
// Move directly affects the location by the given translation amounts // along the given direction. Physics bodies should use Body.Push which // affects velocity. func (p *pov) Move(x, y, z float64, dir *lin.Q) { dx, dy, dz := lin.MultSQ(x, y, z, dir) p.at.Loc.X += dx p.at.Loc.Y += dy p.at.Loc.Z += dz }