Fish
Fish

Reputation: 1697

Libgdx - how to rotate the emmition trail of a 3d particle

I have encountered a problem while using libGDX 3D particles.

I wanted to change the direction the particles are being emitted.

I tried

effect.rotate(new Vector3(0, 1, 0));

when my particle starts at point (1, 0, 1), and the emission goes towards -x; which only rotated the spawn point of the particles but NOT the direction of the emitted particles

I also tried the matrix4 way

targetMatrix.idt();
targetMatrix.setToRotation(...);

and

targetMatrix.rotate(...);

however none of them did what I wanted it to do.

Upvotes: 4

Views: 1197

Answers (1)

Andreas Toresäter
Andreas Toresäter

Reputation: 589

I had this problem too trying to make a simple fireball effect. The rotation or any transform done to the effect will not do what you wan't, don't ask me why it's just one of the strange things about the 3d-particle system.

What you can do is get the emitters for the effect and manually change the theta and phi angles. I do not have access to my code right now but can give you an example if needed. But once you find those two angles you can make the particles emit in any direction you wan't.

This is how I initialize my fireball effect. The theta and phi angles could be changed each tick and it would fix your problem.

effect = Assets.assetManager.get(skillInfo.skillEffect, ParticleEffect.class).copy();

    for (int i = 0; i < effect.getControllers().size; i++) {

        effect.getControllers().get(i).attached = skillInfo.attached;

        if (skillInfo.attached && effect.getControllers().get(i).findInfluencer(DynamicsInfluencer.class) != null) {
            // Gdx.app.log("INFO", "FOUND DI");
            DynamicsInfluencer di = effect.getControllers().get(i).findInfluencer(DynamicsInfluencer.class);
            DynamicsModifier dm;
            for (int j = 0; j < di.velocities.size; j++) {

                dm = (DynamicsModifier) di.velocities.get(j);

                if (dm instanceof PolarAcceleration) {
                    // horizontal +/- spread
                    float phiSpread = Math.abs(((PolarAcceleration) dm).phiValue.getHighMax()
                            - ((PolarAcceleration) dm).phiValue.getHighMin());
                    ((PolarAcceleration) dm).phiValue.setHigh(90 - 0.5f * phiSpread, 90 + 0.5f * phiSpread);

                    // change to acc in opposite direction of movement
                    // direction
                    float angle = getAngleAroundY(direction);
                    float thetaSpread = Math.abs(((PolarAcceleration) dm).thetaValue.getHighMax()
                            - ((PolarAcceleration) dm).thetaValue.getHighMin());
                    ((PolarAcceleration) dm).thetaValue.setHigh(angle - thetaSpread * 0.5f, angle + thetaSpread * 0.5f); // rotation
                                                                                                                            // around
                                                                                                                            // y-axis

                } else {
                    // Gdx.app.log("INFO", "NO polar acc for: " +
                    // skillInfo.name);
                }
            }
        } else {
            // Gdx.app.log("INFO", "no DI");
        }

Where :

                    ((PolarAcceleration) dm).phiValue.setHigh(90 - 0.5f * phiSpread, 90 + 0.5f * phiSpread);


                    ((PolarAcceleration) dm).thetaValue.setHigh(angle - thetaSpread * 0.5f, angle + thetaSpread * 0.5f);

Would be the part interesting for you.

EDIT: See below for the code that is relevant for setting the theta and phi angles in code

 DynamicsInfluencer di = effect.getControllers().get(i).findInfluencer(DynamicsInfluencer.class);
        DynamicsModifier dm;
        for (int j = 0; j < di.velocities.size; j++) {

            dm = (DynamicsModifier) di.velocities.get(j);

                ((PolarAcceleration) dm).phiValue.setHigh(90 - 0.5f * phiSpread, 90 + 0.5f * phiSpread);

                ((PolarAcceleration) dm).thetaValue.setHigh(angle - thetaSpread * 0.5f, angle + thetaSpread * 0.5f);
        }

Upvotes: 3

Related Questions