private void manage(Entity e, float elapsedTime) { Model model = e.get(Model.class); if (!model.isCreated()) return; PlanarStance stance = e.get(PlanarStance.class); Spatial s = SpatialPool.models.get(e.getId()); // translation s.setLocalTranslation(TranslateUtil.toVector3f(stance.getCoord().get3D(stance.getElevation()))); // rotation Quaternion r = new Quaternion(); Point3D pu = stance.getUpVector(); Point3D pv = stance.getPlanarVector(); Vector3f u = TranslateUtil.toVector3f(pu).normalize(); Vector3f v = TranslateUtil.toVector3f(pv).normalize(); r.lookAt(v, u); // we correct the pitch of the unit because the direction is always flatten // this is only to follow the terrain relief double angle = Math.acos(pu.getDotProduct(pv) / (pu.getNorm() * pv.getNorm())); r = r.mult( new Quaternion() .fromAngles( (float) (-angle + AngleUtil.RIGHT + model.getPitchFix()), (float) (model.getRollFix()), (float) (model.getYawFix()))); s.setLocalRotation(r); }
@Override protected void onEntityEachTick(Entity e) { Spatial s = Pool.models.get(e.getId()); if (s == null) return; PlanarStance stance = e.get(PlanarStance.class); // translation s.setLocalTranslation(TranslateUtil.toVector3f(stance.coord.get3D(stance.elevation))); // rotation Quaternion r = new Quaternion(); Point3D pu = stance.upVector; Point3D pv = Point3D.UNIT_X.getRotationAroundZ(stance.orientation.getValue()); Vector3f u = TranslateUtil.toVector3f(pu).normalize(); Vector3f v = TranslateUtil.toVector3f(pv).normalize(); r.lookAt(v, u); double angle = Math.acos(pu.getDotProduct(pv) / (pu.getNorm() * pv.getNorm())); r = r.mult(new Quaternion().fromAngles((float) (-angle), 0, 0)); s.setLocalRotation(r); }