Here's my own solution for 90° rotations:
/**
* Created on 2018-02-09.
*
* @author Alexander Winter
*/
public class RotatableParticleEffect extends ParticleEffect {
public RotatableParticleEffect() {}
public RotatableParticleEffect(ParticleEffect effect) {
super(effect);
}
public void rotateBy(int turnQuarter) {
while(turnQuarter < 0)
turnQuarter += 4;
turnQuarter %= 4;
for(ParticleEmitter emitter : getEmitters()) {
ScaledNumericValue angle = emitter.getAngle();
angle.setHighMax(angle.getHighMax() + turnQuarter * -90f);
angle.setHighMin(angle.getHighMin() + turnQuarter * -90f);
angle.setLowMax(angle.getLowMax() + turnQuarter * -90f);
angle.setLowMin(angle.getLowMin() + turnQuarter * -90f);
ScaledNumericValue rot = emitter.getRotation();
rot.setHighMax(rot.getHighMax() + turnQuarter * -90f);
rot.setHighMin(rot.getHighMin() + turnQuarter * -90f);
rot.setLowMax(rot.getLowMax() + turnQuarter * -90f);
rot.setLowMin(rot.getLowMin() + turnQuarter * -90f);
for(int i = 0; i < turnQuarter; i++) {
swapFields(emitter.getXOffsetValue(), emitter.getYOffsetValue());
emitter.getYOffsetValue().setLowMin(-emitter.getYOffsetValue().getLowMin());
emitter.getYOffsetValue().setLowMax(-emitter.getYOffsetValue().getLowMax());
}
}
}
private static void swapFields(Object o1, Object o2) {
if(o1 == null || o2 == null)
throw new IllegalArgumentException("Objects must not be null");
if(!o1.getClass().equals(o2.getClass()))
throw new IllegalArgumentException("Objects are not the same type");
Class<?> type = o1.getClass();
while(type != null) {
for(Field field : type.getDeclaredFields()) {
if(!field.isAccessible())
field.setAccessible(true);
try {
Object tmp = field.get(o1);
field.set(o1, field.get(o2));
field.set(o2, tmp);
} catch(IllegalAccessException ex) {
throw new RuntimeException(ex);
}
}
type = type.getSuperclass();
}
}
}
With this solution, you can't rotate with any angle. If you'd need to, you will need to adjust the X and Y offsets with a rotation. offsetY = originalOffsetY * sin(angle)
and same for X with cos()
. I didn't implement the full solution for any angle because I didn't need it. However, I can confirm this simpler solution works for me.