package wow.doge.mygame.game.subsystems.movement import com.jme3.bullet.control.BetterCharacterControl import com.jme3.math.FastMath import com.jme3.math.Quaternion import com.jme3.math.Vector3f import monix.eval.Coeval import wow.doge.mygame.implicits._ import wow.doge.mygame.math.ImVector3f import wow.doge.mygame.subsystems.movement.RotateDir // experiment to see if it would be useful to use an effect wrapper for a typeclass like this trait CanMove2[-A, F[_]] { // def getDirection(cam: Camera, cardinalDir: CardinalDirection): ImVector3f def move(inst: A, direction: ImVector3f, speedFactor: Float = 20f): F[Unit] def location(inst: A): F[ImVector3f] def jump(inst: A): F[Unit] def stop(inst: A): F[Unit] def rotate(inst: A, rotateDir: RotateDir): F[Unit] } object CanMove2 { implicit val implCanMoveForBetterCharacterControl = new CanMove2[BetterCharacterControl, Coeval] { override def move( inst: BetterCharacterControl, direction: ImVector3f, speedFactor: Float = 20f ): Coeval[Unit] = Coeval { val dir = direction.mutable.normalizeLocal() inst.setViewDirection(dir.negate()) inst.setWalkDirection(dir.mult(speedFactor)) } override def location(inst: BetterCharacterControl) = Coeval(inst.getSpatial().getLocalTranslation().immutable) override def jump(inst: BetterCharacterControl): Coeval[Unit] = Coeval(inst.jump()) override def rotate( inst: BetterCharacterControl, rotateDir: RotateDir ): Coeval[Unit] = Coeval { val q = rotateDir match { case RotateDir.Left => new Quaternion() .fromAngleNormalAxis(5 * FastMath.DEG_TO_RAD, Vector3f.UNIT_Y) case RotateDir.Right => new Quaternion() .fromAngleAxis(-5 * FastMath.DEG_TO_RAD, Vector3f.UNIT_Y) } val tmp = new Vector3f() inst.getViewDirection(tmp) inst.setViewDirection(q.mult(tmp)) } override def stop(inst: BetterCharacterControl) = Coeval(inst.setWalkDirection(Vector3f.ZERO)) } }