Skip to content

Commit

Permalink
vastly improve water and block wake particles
Browse files Browse the repository at this point in the history
  • Loading branch information
parzivail committed Nov 17, 2022
1 parent 9e359aa commit cfcbfb2
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,29 @@ public Particle createParticle(BlockStateParticleEffect blockStateParticleEffect
}
}

private final float maxScale;

public WakeParticle(ClientWorld world, double x, double y, double z, double velocityX, double velocityY, double velocityZ, BlockState state)
{
super(world, x, y, z, velocityX, velocityY, velocityZ, state);
this.gravityStrength = 0.02f;
this.velocityY = velocityY + (Math.random() * 2.0 - 1.0) * velocityY * 0.1f;
this.velocityX = (Math.random() * 2.0 - 1.0) * velocityX;
this.velocityZ = (Math.random() * 2.0 - 1.0) * velocityZ;

this.maxScale = 0.04F * (this.random.nextFloat() * this.random.nextFloat() * 6.0F + 1.0F);
}

@Override
public void tick()
{
this.scale = this.maxScale * (float)Math.min(Math.pow(20f * this.age / this.maxAge, 4), 1);

this.prevPosX = this.x;
this.prevPosY = this.y;
this.prevPosZ = this.z;

if (this.maxAge-- <= 0)
if (this.age++ >= maxAge)
this.markDead();
else
{
Expand All @@ -49,7 +55,10 @@ public void tick()
this.velocityZ *= 0.98;

if (this.onGround)
this.markDead();
{
this.velocityX *= 0.7;
this.velocityZ *= 0.7;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package com.parzivail.pswg.client.particle;

import com.parzivail.util.client.particle.PParticleType;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.particle.*;
import net.minecraft.client.world.ClientWorld;

public class WaterWakeParticle extends SpriteBillboardParticle
{
private final SpriteProvider spriteProvider;
private final float maxScale;

public WaterWakeParticle(ClientWorld world, double x, double y, double z, double velocityX, double velocityY, double velocityZ, SpriteProvider spriteProvider)
{
super(world, x, y, z);
this.spriteProvider = spriteProvider;
float f = this.random.nextFloat() * 0.3F + 0.7F;
this.red = f;
this.green = f;
this.blue = f;
this.maxScale = 0.1F * (this.random.nextFloat() * this.random.nextFloat() * 6.0F + 1.0F);
this.scale = 0;
this.maxAge = (int)(16.0 / ((double)this.random.nextFloat() * 0.8 + 0.2)) + 2;
this.setSpriteForAge(spriteProvider);

this.gravityStrength = 0.02f;
this.velocityY = velocityY + (Math.random() * 2.0 - 1.0) * velocityY * 0.1f;
this.velocityX = (Math.random() * 2.0 - 1.0) * velocityX;
this.velocityZ = (Math.random() * 2.0 - 1.0) * velocityZ;
}

public ParticleTextureSheet getType()
{
return ParticleTextureSheet.PARTICLE_SHEET_OPAQUE;
}

public void tick()
{
this.scale = this.maxScale * (float)Math.min(Math.pow(20f * this.age / this.maxAge, 4), 1);
this.prevPosX = this.x;
this.prevPosY = this.y;
this.prevPosZ = this.z;

if (this.age++ >= maxAge)
this.markDead();
else
{
this.velocityY -= this.gravityStrength;
this.move(this.velocityX, this.velocityY, this.velocityZ);

this.velocityX *= 0.98;
this.velocityY *= 0.98;
this.velocityZ *= 0.98;

if (this.onGround)
{
this.velocityX *= 0.7;
this.velocityZ *= 0.7;
}
}

this.setSpriteForAge(this.spriteProvider);
}

@Environment(EnvType.CLIENT)
public static class Factory implements ParticleFactory<PParticleType>
{
private final SpriteProvider spriteProvider;

public Factory(SpriteProvider spriteProvider)
{
this.spriteProvider = spriteProvider;
}

public Particle createParticle(PParticleType defaultParticleType, ClientWorld clientWorld, double d, double e, double f, double g, double h, double i)
{
return new WaterWakeParticle(clientWorld, d, e, f, g, h, i, this.spriteProvider);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@

import com.mojang.serialization.Codec;
import com.parzivail.pswg.Resources;
import com.parzivail.pswg.client.particle.ScorchParticle;
import com.parzivail.pswg.client.particle.SlugTrailParticle;
import com.parzivail.pswg.client.particle.SparkParticle;
import com.parzivail.pswg.client.particle.WakeParticle;
import com.parzivail.pswg.client.particle.*;
import com.parzivail.util.client.particle.PParticleType;
import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry;
import net.minecraft.client.particle.ParticleFactory;
Expand All @@ -19,6 +16,7 @@ public class SwgParticles
public static final PParticleType SLUG_TRAIL = register(Resources.id("slug_trail"), true, SlugTrailParticle.Factory::new);
public static final PParticleType SPARK = register(Resources.id("spark"), true, SparkParticle.Factory::new);
public static final PParticleType SCORCH = register(Resources.id("scorch"), true, ScorchParticle.Factory::new);
public static final PParticleType WATER_WAKE = register(Resources.id("water_wake"), true, WaterWakeParticle.Factory::new);
public static final ParticleType<BlockStateParticleEffect> WAKE = registerBlockStateBased(Resources.id("wake"), true, new WakeParticle.Factory());

private static PParticleType register(Identifier name, boolean alwaysShow, ParticleFactoryRegistry.PendingParticleFactory<PParticleType> factory)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ public class RigT65B extends ModelRig<T65BXwing>
{
public static final RigT65B INSTANCE = new RigT65B();

public static final String[] CANNONS = new String[] { "CannonTopLeft", "CannonBottomLeft", "CannonTopRight", "CannonBottomRight" };
public static final String[] WINGS = new String[] { "WingTopLeft", "WingBottomLeft", "WingTopRight", "WingBottomRight" };
public static final String[] ENGINES = new String[] { "EngineTopLeft", "EngineBottomLeft", "EngineTopRight", "EngineBottomRight" };

private RigT65B()
{
super(Resources.id("rigs/ship/xwing_t65b.p3dr"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import net.minecraft.particle.BlockStateParticleEffect;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvent;
import net.minecraft.tag.FluidTags;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Matrix4f;
Expand Down Expand Up @@ -167,35 +168,39 @@ public void tick()
int maxParticles = (int)(15 * velocityLength * velocityLength);
var steps = (5 * velocityLength + 1);

spawnWakeParticles(maxDistance, (dt) -> RigT65B.INSTANCE.getWorldPosition(stack, this, getViewRotation(dt), "CannonBottomLeft", dt).add(this.getLerpedPos(dt)), velocityLength, rayDir, maxParticles, steps);
spawnWakeParticles(maxDistance, (dt) -> RigT65B.INSTANCE.getWorldPosition(stack, this, getViewRotation(dt), "CannonBottomRight", dt).add(this.getLerpedPos(dt)), velocityLength, rayDir, maxParticles, steps);
for (var cannon : RigT65B.CANNONS)
spawnWakeParticles(maxDistance, (dt) -> RigT65B.INSTANCE.getWorldPosition(stack, this, getViewRotation(dt), cannon, dt).add(this.getLerpedPos(dt)), velocityLength, rayDir, maxParticles, steps);
for (var engine : RigT65B.ENGINES)
spawnWakeParticles(maxDistance, (dt) -> RigT65B.INSTANCE.getWorldPosition(stack, this, getViewRotation(dt), engine, dt).add(this.getLerpedPos(dt)), velocityLength, rayDir, maxParticles, steps);
}
}

private void spawnWakeParticles(float maxDistance, Function<Float, Vec3d> sourcePosSupplier, double velocityLength, Vec3d rayDir, int maxParticles, double steps)
{
var velSquared = velocityLength * velocityLength;

var ddt = 1 / steps;
for (var dt = 0f; dt <= 1; dt += ddt)
{
var sourcePos = sourcePosSupplier.apply(dt);
var blockHit = EntityUtil.raycastBlocks(sourcePos, rayDir, maxDistance, this, RaycastContext.ShapeType.COLLIDER, RaycastContext.FluidHandling.ANY);
if (blockHit.getType() != HitResult.Type.MISS)
{
var particle = new BlockStateParticleEffect(SwgParticles.WAKE, world.getBlockState(blockHit.getBlockPos()));
var state = world.getBlockState(blockHit.getBlockPos());
var particle = state.getFluidState().isIn(FluidTags.WATER) ? SwgParticles.WATER_WAKE : new BlockStateParticleEffect(SwgParticles.WAKE, state);

var hitPos = blockHit.getPos();
var dist = hitPos.distanceTo(sourcePos);
var dist = Math.max(hitPos.distanceTo(sourcePos), 0.5f);
var count = (MathHelper.clamp(15 / dist, 0, maxParticles)) / steps;

var sqrtDist = Math.sqrt(dist);
var lateralVelocity = Math.pow(velocityLength / (1.8f * sqrtDist), 2);
var verticalVelocity = Math.pow(velocityLength / (2.5f * sqrtDist), 2);
var lateralVelocity = velSquared / (3.24 * dist);
var verticalVelocity = velSquared / (6.25 * dist);

for (int i = 0; i < count; i++)
{
if (this.random.nextFloat() * 2 > velocityLength)
continue;
this.world.addParticle(particle, hitPos.x, hitPos.y, hitPos.z, lateralVelocity, verticalVelocity, lateralVelocity);
this.world.addParticle(particle, hitPos.x + this.random.nextGaussian() / 4, hitPos.y, hitPos.z + this.random.nextGaussian() / 4, lateralVelocity, verticalVelocity, lateralVelocity);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"textures": [
"minecraft:generic_7",
"minecraft:generic_6",
"minecraft:generic_5",
"minecraft:generic_4",
"minecraft:generic_3",
"minecraft:generic_2",
"minecraft:generic_1",
"minecraft:generic_0"
]
}

0 comments on commit cfcbfb2

Please sign in to comment.