Fixed #433 - Electric bolt render NPE
This commit is contained in:
parent
7f9acda277
commit
92993e832d
1 changed files with 309 additions and 270 deletions
|
@ -1,23 +1,14 @@
|
||||||
package mekanism.induction.client;
|
package icbm.explosion.fx;
|
||||||
|
|
||||||
import static org.lwjgl.opengl.GL11.GL_BLEND;
|
import icbm.core.ICBMCore;
|
||||||
import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA;
|
|
||||||
import static org.lwjgl.opengl.GL11.GL_SMOOTH;
|
|
||||||
import static org.lwjgl.opengl.GL11.GL_SRC_ALPHA;
|
|
||||||
import static org.lwjgl.opengl.GL11.glBlendFunc;
|
|
||||||
import static org.lwjgl.opengl.GL11.glEnable;
|
|
||||||
import static org.lwjgl.opengl.GL11.glShadeModel;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import mekanism.induction.common.MekanismInduction;
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.particle.EntityFX;
|
import net.minecraft.client.particle.EntityFX;
|
||||||
import net.minecraft.client.renderer.Tessellator;
|
import net.minecraft.client.renderer.Tessellator;
|
||||||
|
@ -28,105 +19,95 @@ import net.minecraft.world.World;
|
||||||
import org.lwjgl.opengl.GL11;
|
import org.lwjgl.opengl.GL11;
|
||||||
|
|
||||||
import universalelectricity.core.vector.Vector3;
|
import universalelectricity.core.vector.Vector3;
|
||||||
|
import calclavia.lib.render.CalclaviaRenderHelper;
|
||||||
import cpw.mods.fml.client.FMLClientHandler;
|
import cpw.mods.fml.client.FMLClientHandler;
|
||||||
import cpw.mods.fml.relauncher.Side;
|
import cpw.mods.fml.relauncher.Side;
|
||||||
import cpw.mods.fml.relauncher.SideOnly;
|
import cpw.mods.fml.relauncher.SideOnly;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Electric shock Fxs.
|
* An effect that renders a electrical bolt from one position to another. Inspired by Azanor's
|
||||||
|
* lightning wand.
|
||||||
*
|
*
|
||||||
* @author Calclavia
|
* @author Calclavia
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@SideOnly(Side.CLIENT)
|
@SideOnly(Side.CLIENT)
|
||||||
public class FXElectricBolt extends EntityFX
|
public class FXElectricBolt extends EntityFX
|
||||||
{
|
{
|
||||||
public static final ResourceLocation TEXTURE = new ResourceLocation(MekanismInduction.DOMAIN, MekanismInduction.MODEL_TEXTURE_DIRECTORY + "fadedSphere.png");
|
private static final ResourceLocation TEXTURE = new ResourceLocation(ICBMCore.DOMAIN, ICBMCore.TEXTURE_PATH + "fadedSphere.png");
|
||||||
public static final ResourceLocation PARTICLE_RESOURCE = new ResourceLocation("textures/particle/particles.png");
|
|
||||||
|
|
||||||
/** The width of the electrical bolt. */
|
/** The width of the electrical bolt. */
|
||||||
private float boltWidth;
|
private float boltWidth = 0.05f;
|
||||||
/** The maximum length of the bolt */
|
|
||||||
public double boltLength;
|
|
||||||
/** Electric Bolt's start and end positions; */
|
/** Electric Bolt's start and end positions; */
|
||||||
private BoltPoint start;
|
private Vector3 start;
|
||||||
private BoltPoint end;
|
private Vector3 end;
|
||||||
/** An array of the segments of the bolt. */
|
/** An array of the segments of the bolt. */
|
||||||
private List<BoltSegment> segments = new ArrayList<BoltSegment>();
|
private ArrayList<BoltSegment> segments = new ArrayList<BoltSegment>();
|
||||||
private final Map<Integer, Integer> parentIDMap = new HashMap<Integer, Integer>();
|
private HashMap<Integer, Integer> splitparents = new HashMap<Integer, Integer>();
|
||||||
/** Determines how complex the bolt is. */
|
/** Determines how complex the bolt is. */
|
||||||
public float complexity;
|
public float complexity;
|
||||||
|
/** The maximum length of the bolt */
|
||||||
|
public double length;
|
||||||
public int segmentCount;
|
public int segmentCount;
|
||||||
private int maxSplitID;
|
private int maxSplitID = 0;
|
||||||
private Random rand;
|
private Random rand;
|
||||||
|
/** Are the segments calculated? */
|
||||||
|
private boolean isCalculated;
|
||||||
|
|
||||||
public FXElectricBolt(World world, Vector3 startVec, Vector3 targetVec, boolean doSplits)
|
public FXElectricBolt(World world, Vector3 startVec, Vector3 targetVec, long seed)
|
||||||
{
|
{
|
||||||
super(world, startVec.x, startVec.y, startVec.z);
|
super(world, startVec.x, startVec.y, startVec.z, 0.0D, 0.0D, 0.0D);
|
||||||
|
|
||||||
rand = new Random();
|
if (seed == 0)
|
||||||
start = new BoltPoint(startVec);
|
|
||||||
end = new BoltPoint(targetVec);
|
|
||||||
|
|
||||||
if(end.y == Double.POSITIVE_INFINITY)
|
|
||||||
{
|
{
|
||||||
end.y = Minecraft.getMinecraft().thePlayer.posY + 30;
|
this.rand = new Random();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.rand = new Random(seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.start = startVec;
|
||||||
|
this.end = targetVec;
|
||||||
/** By default, we do an electrical color */
|
/** By default, we do an electrical color */
|
||||||
segmentCount = 1;
|
this.particleAge = (3 + this.rand.nextInt(3) - 1);
|
||||||
particleMaxAge = (3 + rand.nextInt(3) - 1);
|
this.particleRed = 0.55f + (this.rand.nextFloat() * 0.1f);
|
||||||
complexity = 2f;
|
this.particleGreen = 0.7f + (this.rand.nextFloat() * 0.1f);
|
||||||
boltWidth = 0.05f;
|
this.particleBlue = 1f;
|
||||||
boltLength = start.distance(end);
|
this.segmentCount = 1;
|
||||||
setUp(doSplits);
|
this.length = this.start.distanceTo(this.end);
|
||||||
|
this.particleMaxAge = (3 + this.rand.nextInt(3) - 1);
|
||||||
|
this.complexity = 2f;
|
||||||
|
|
||||||
|
/** Calculate all required segments of the entire bolt. */
|
||||||
|
this.segments.add(new BoltSegment(this.start, this.end));
|
||||||
|
this.recalculateDifferences();
|
||||||
|
this.split(2, this.length * this.complexity / 8.0F, 0.7F, 0.1F, 45.0F);
|
||||||
|
this.split(2, this.length * this.complexity / 12.0F, 0.5F, 0.1F, 50.0F);
|
||||||
|
this.split(2, this.length * this.complexity / 17.0F, 0.5F, 0.1F, 55.0F);
|
||||||
|
this.split(2, this.length * this.complexity / 23.0F, 0.5F, 0.1F, 60.0F);
|
||||||
|
this.split(2, this.length * this.complexity / 30.0F, 0.0F, 0.0F, 0.0F);
|
||||||
|
this.split(2, this.length * this.complexity / 34.0F, 0.0F, 0.0F, 0.0F);
|
||||||
|
this.split(2, this.length * this.complexity / 40.0F, 0.0F, 0.0F, 0.0F);
|
||||||
|
this.finalizeBolt();
|
||||||
}
|
}
|
||||||
|
|
||||||
public FXElectricBolt(World world, Vector3 startVec, Vector3 targetVec)
|
public FXElectricBolt setMultiplier(float m)
|
||||||
{
|
{
|
||||||
this(world, startVec, targetVec, true);
|
this.complexity = m;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public FXElectricBolt setWidth(float m)
|
||||||
* Calculate all required segments of the entire bolt.
|
|
||||||
*/
|
|
||||||
private void setUp(boolean doSplits)
|
|
||||||
{
|
{
|
||||||
segments.add(new BoltSegment(start, end));
|
this.boltWidth = m;
|
||||||
recalculate();
|
return this;
|
||||||
|
|
||||||
if(doSplits)
|
|
||||||
{
|
|
||||||
double offsetRatio = boltLength * complexity;
|
|
||||||
split(2, offsetRatio / 10, 0.7f, 0.1f, 20 / 2);
|
|
||||||
split(2, offsetRatio / 15, 0.5f, 0.1f, 25 / 2);
|
|
||||||
split(2, offsetRatio / 25, 0.5f, 0.1f, 28 / 2);
|
|
||||||
split(2, offsetRatio / 38, 0.5f, 0.1f, 30 / 2);
|
|
||||||
split(2, offsetRatio / 55, 0, 0, 0);
|
|
||||||
split(2, offsetRatio / 70, 0, 0, 0);
|
|
||||||
recalculate();
|
|
||||||
|
|
||||||
Collections.sort(segments, new Comparator()
|
|
||||||
{
|
|
||||||
public int compare(BoltSegment bolt1, BoltSegment bolt2)
|
|
||||||
{
|
|
||||||
return Float.compare(bolt2.alpha, bolt1.alpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compare(Object obj1, Object obj2)
|
|
||||||
{
|
|
||||||
return compare((BoltSegment) obj1, (BoltSegment) obj2);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public FXElectricBolt setColor(float r, float g, float b)
|
public FXElectricBolt setColor(float r, float g, float b)
|
||||||
{
|
{
|
||||||
particleRed = r + (rand.nextFloat() * 0.1f) - 0.1f;
|
this.particleRed = r;
|
||||||
particleGreen = g + (rand.nextFloat() * 0.1f) - 0.1f;
|
this.particleGreen = g;
|
||||||
particleBlue = b + (rand.nextFloat() * 0.1f) - 0.1f;
|
this.particleBlue = b;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,89 +121,113 @@ public class FXElectricBolt extends EntityFX
|
||||||
* @param splitAngle - The angle of the split.
|
* @param splitAngle - The angle of the split.
|
||||||
*/
|
*/
|
||||||
public void split(int splitAmount, double offset, float splitChance, float splitLength, float splitAngle)
|
public void split(int splitAmount, double offset, float splitChance, float splitLength, float splitAngle)
|
||||||
|
{
|
||||||
|
if (!this.isCalculated)
|
||||||
{
|
{
|
||||||
/** Temporarily store old segments in a new array */
|
/** Temporarily store old segments in a new array */
|
||||||
List<BoltSegment> oldSegments = segments;
|
ArrayList<BoltSegment> oldSegments = this.segments;
|
||||||
segments = new ArrayList();
|
this.segments = new ArrayList();
|
||||||
/** Previous segment */
|
/** Previous segment */
|
||||||
BoltSegment prev = null;
|
BoltSegment prev = null;
|
||||||
|
|
||||||
for(BoltSegment segment : oldSegments)
|
for (BoltSegment segment : oldSegments)
|
||||||
{
|
{
|
||||||
prev = segment.prev;
|
prev = segment.prevSegment;
|
||||||
/** Length of each subsegment */
|
|
||||||
Vector3 subSegment = segment.difference.clone().scale(1.0F / splitAmount);
|
Vector3 subSegment = segment.difference.clone().scale(1.0F / splitAmount);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an array of new bolt points. The first and last points of the bolts are the
|
* Creates an array of new bolt points. The first and last points of the bolts are
|
||||||
* respected start and end points of the current segment.
|
* the respected start and end points of the current segment.
|
||||||
*/
|
*/
|
||||||
BoltPoint[] newPoints = new BoltPoint[splitAmount + 1];
|
BoltPoint[] newPoints = new BoltPoint[splitAmount + 1];
|
||||||
Vector3 startPoint = segment.start;
|
Vector3 startPoint = segment.startBolt.point;
|
||||||
newPoints[0] = segment.start;
|
newPoints[0] = segment.startBolt;
|
||||||
newPoints[splitAmount] = segment.end;
|
newPoints[splitAmount] = segment.endBolt;
|
||||||
|
|
||||||
/**
|
for (int i = 1; i < splitAmount; i++)
|
||||||
* Create bolt points.
|
|
||||||
*/
|
|
||||||
for(int i = 1; i < splitAmount; i++)
|
|
||||||
{
|
{
|
||||||
Vector3 newOffset = segment.difference.getPerpendicular().rotate(rand.nextFloat() * 360, segment.difference).scale((rand.nextFloat() - 0.5F) * offset);
|
Vector3 offsetVec = segment.difference.getPerpendicular().rotate(this.rand.nextFloat() * 360.0F, segment.difference).scale((this.rand.nextFloat() - 0.5F) * offset);
|
||||||
Vector3 basePoint = startPoint.clone().translate(subSegment.clone().scale(i));
|
Vector3 basepoint = startPoint.clone().translate(subSegment.clone().scale(i));
|
||||||
|
newPoints[i] = new BoltPoint(basepoint, offsetVec);
|
||||||
newPoints[i] = new BoltPoint(basePoint, newOffset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < splitAmount; i++)
|
for (int i = 0; i < splitAmount; i++)
|
||||||
{
|
{
|
||||||
BoltSegment next = new BoltSegment(newPoints[i], newPoints[(i + 1)], segment.alpha, segment.id * splitAmount + i, segment.splitID);
|
BoltSegment next = new BoltSegment(newPoints[i], newPoints[(i + 1)], segment.weight, segment.segmentID * splitAmount + i, segment.splitID);
|
||||||
next.prev = prev;
|
next.prevSegment = prev;
|
||||||
|
|
||||||
if(prev != null)
|
if (prev != null)
|
||||||
{
|
{
|
||||||
prev.next = next;
|
prev.nextSegment = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((i != 0) && (rand.nextFloat() < splitChance))
|
if ((i != 0) && (this.rand.nextFloat() < splitChance))
|
||||||
{
|
{
|
||||||
Vector3 splitrot = next.difference.xCrossProduct().rotate(rand.nextFloat() * 360, next.difference);
|
Vector3 splitrot = next.difference.xCrossProduct().rotate(this.rand.nextFloat() * 360.0F, next.difference);
|
||||||
Vector3 diff = next.difference.clone().rotate((rand.nextFloat() * 0.66F + 0.33F) * splitAngle, splitrot).scale(splitLength);
|
Vector3 diff = next.difference.clone().rotate((this.rand.nextFloat() * 0.66F + 0.33F) * splitAngle, splitrot).scale(splitLength);
|
||||||
maxSplitID += 1;
|
this.maxSplitID += 1;
|
||||||
parentIDMap.put(maxSplitID, next.splitID);
|
this.splitparents.put(this.maxSplitID, next.splitID);
|
||||||
BoltSegment split = new BoltSegment(newPoints[i], new BoltPoint(newPoints[(i + 1)].base, newPoints[(i + 1)].offset.clone().translate(diff)), segment.alpha / 2f, next.id, maxSplitID);
|
BoltSegment split = new BoltSegment(newPoints[i], new BoltPoint(newPoints[(i + 1)].basePoint, newPoints[(i + 1)].offSet.clone().translate(diff)), segment.weight / 2.0F, next.segmentID, this.maxSplitID);
|
||||||
split.prev = prev;
|
split.prevSegment = prev;
|
||||||
segments.add(split);
|
this.segments.add(split);
|
||||||
}
|
}
|
||||||
|
|
||||||
prev = next;
|
prev = next;
|
||||||
segments.add(next);
|
this.segments.add(next);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(segment.next != null)
|
if (segment.nextSegment != null)
|
||||||
{
|
{
|
||||||
segment.next.prev = prev;
|
segment.nextSegment.prevSegment = prev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
segmentCount *= splitAmount;
|
this.segmentCount *= splitAmount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void recalculate()
|
public void finalizeBolt()
|
||||||
|
{
|
||||||
|
if (!this.isCalculated)
|
||||||
|
{
|
||||||
|
this.isCalculated = true;
|
||||||
|
recalculateDifferences();
|
||||||
|
|
||||||
|
Collections.sort(this.segments, new Comparator()
|
||||||
|
{
|
||||||
|
public int compare(BoltSegment o1, BoltSegment o2)
|
||||||
|
{
|
||||||
|
return Float.compare(o2.weight, o1.weight);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(Object obj, Object obj1)
|
||||||
|
{
|
||||||
|
return compare((BoltSegment) obj, (BoltSegment) obj1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Vector3 getRelativeViewVector(Vector3 pos)
|
||||||
|
{
|
||||||
|
EntityPlayer renderentity = Minecraft.getMinecraft().thePlayer;
|
||||||
|
return new Vector3((float) renderentity.posX - pos.x, (float) renderentity.posY - pos.y, (float) renderentity.posZ - pos.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void recalculateDifferences()
|
||||||
{
|
{
|
||||||
HashMap<Integer, Integer> lastActiveSegment = new HashMap<Integer, Integer>();
|
HashMap<Integer, Integer> lastActiveSegment = new HashMap<Integer, Integer>();
|
||||||
|
|
||||||
Collections.sort(segments, new Comparator()
|
Collections.sort(this.segments, new Comparator()
|
||||||
{
|
{
|
||||||
public int compare(BoltSegment o1, BoltSegment o2)
|
public int compare(BoltSegment o1, BoltSegment o2)
|
||||||
{
|
{
|
||||||
int comp = Integer.valueOf(o1.splitID).compareTo(Integer.valueOf(o2.splitID));
|
int comp = Integer.valueOf(o1.splitID).compareTo(Integer.valueOf(o2.splitID));
|
||||||
|
if (comp == 0)
|
||||||
if(comp == 0)
|
|
||||||
{
|
{
|
||||||
return Integer.valueOf(o1.id).compareTo(Integer.valueOf(o2.id));
|
return Integer.valueOf(o1.segmentID).compareTo(Integer.valueOf(o2.segmentID));
|
||||||
}
|
}
|
||||||
|
|
||||||
return comp;
|
return comp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,16 +241,19 @@ public class FXElectricBolt extends EntityFX
|
||||||
int lastSplitCalc = 0;
|
int lastSplitCalc = 0;
|
||||||
int lastActiveSeg = 0;
|
int lastActiveSeg = 0;
|
||||||
|
|
||||||
for(BoltSegment segment : segments)
|
for (BoltSegment segment : this.segments)
|
||||||
{
|
{
|
||||||
if(segment.splitID > lastSplitCalc)
|
if (segment != null)
|
||||||
|
{
|
||||||
|
if (segment.splitID > lastSplitCalc)
|
||||||
{
|
{
|
||||||
lastActiveSegment.put(lastSplitCalc, lastActiveSeg);
|
lastActiveSegment.put(lastSplitCalc, lastActiveSeg);
|
||||||
lastSplitCalc = segment.splitID;
|
lastSplitCalc = segment.splitID;
|
||||||
lastActiveSeg = lastActiveSegment.get(parentIDMap.get(segment.splitID)).intValue();
|
lastActiveSeg = lastActiveSegment.get(this.splitparents.get(segment.splitID)).intValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
lastActiveSeg = segment.id;
|
lastActiveSeg = segment.segmentID;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lastActiveSegment.put(lastSplitCalc, lastActiveSeg);
|
lastActiveSegment.put(lastSplitCalc, lastActiveSeg);
|
||||||
|
@ -253,40 +261,118 @@ public class FXElectricBolt extends EntityFX
|
||||||
lastActiveSeg = lastActiveSegment.get(0).intValue();
|
lastActiveSeg = lastActiveSegment.get(0).intValue();
|
||||||
BoltSegment segment;
|
BoltSegment segment;
|
||||||
|
|
||||||
for(Iterator<BoltSegment> iterator = segments.iterator(); iterator.hasNext(); segment.recalculate())
|
for (Iterator<BoltSegment> iterator = this.segments.iterator(); iterator.hasNext(); segment.calculateEndDifferences())
|
||||||
{
|
{
|
||||||
segment = iterator.next();
|
segment = iterator.next();
|
||||||
|
|
||||||
if(lastSplitCalc != segment.splitID)
|
if (lastSplitCalc != segment.splitID)
|
||||||
{
|
{
|
||||||
lastSplitCalc = segment.splitID;
|
lastSplitCalc = segment.splitID;
|
||||||
lastActiveSeg = lastActiveSegment.get(segment.splitID);
|
lastActiveSeg = lastActiveSegment.get(segment.splitID);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(segment.id > lastActiveSeg)
|
if (segment.segmentID > lastActiveSeg)
|
||||||
{
|
{
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Renders the bolts. */
|
||||||
|
private void renderBolt(Tessellator tessellator, float partialframe, float cosyaw, float cospitch, float sinyaw, float cossinpitch, int pass)
|
||||||
|
{
|
||||||
|
Vector3 playerVector = new Vector3(sinyaw * -cospitch, -cossinpitch / cosyaw, cosyaw * cospitch);
|
||||||
|
float voltage = this.particleAge >= 0 ? ((float) this.particleAge / (float) this.particleMaxAge) : 0.0F;
|
||||||
|
|
||||||
|
float mainAlpha = 1.0F;
|
||||||
|
|
||||||
|
if (pass == 0)
|
||||||
|
{
|
||||||
|
mainAlpha = (1.0F - voltage) * 0.4F;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mainAlpha = 1.0F - voltage * 0.5F;
|
||||||
|
}
|
||||||
|
|
||||||
|
int renderlength = (int) ((this.particleAge + partialframe + (int) (this.length * 3.0F)) / (int) (this.length * 3.0F) * this.segmentCount);
|
||||||
|
|
||||||
|
for (BoltSegment renderSegment : this.segments)
|
||||||
|
{
|
||||||
|
if (renderSegment != null && renderSegment.segmentID <= renderlength)
|
||||||
|
{
|
||||||
|
float width = (float) (this.boltWidth * (getRelativeViewVector(renderSegment.startBolt.point).getMagnitude() / 5.0F + 1.0F) * (1.0F + renderSegment.weight) * 0.5F);
|
||||||
|
Vector3 diff1 = playerVector.crossProduct(renderSegment.prevDiff).scale(width / renderSegment.sinPrev);
|
||||||
|
Vector3 diff2 = playerVector.crossProduct(renderSegment.nextDiff).scale(width / renderSegment.sinNext);
|
||||||
|
Vector3 startvec = renderSegment.startBolt.point;
|
||||||
|
Vector3 endvec = renderSegment.endBolt.point;
|
||||||
|
float rx1 = (float) (startvec.x - interpPosX);
|
||||||
|
float ry1 = (float) (startvec.y - interpPosY);
|
||||||
|
float rz1 = (float) (startvec.z - interpPosZ);
|
||||||
|
float rx2 = (float) (endvec.x - interpPosX);
|
||||||
|
float ry2 = (float) (endvec.y - interpPosY);
|
||||||
|
float rz2 = (float) (endvec.z - interpPosZ);
|
||||||
|
tessellator.setColorRGBA_F(this.particleRed, this.particleGreen, this.particleBlue, mainAlpha * renderSegment.weight);
|
||||||
|
tessellator.addVertexWithUV(rx2 - diff2.x, ry2 - diff2.y, rz2 - diff2.z, 0.5D, 0.0D);
|
||||||
|
tessellator.addVertexWithUV(rx1 - diff1.x, ry1 - diff1.y, rz1 - diff1.z, 0.5D, 0.0D);
|
||||||
|
tessellator.addVertexWithUV(rx1 + diff1.x, ry1 + diff1.y, rz1 + diff1.z, 0.5D, 1.0D);
|
||||||
|
tessellator.addVertexWithUV(rx2 + diff2.x, ry2 + diff2.y, rz2 + diff2.z, 0.5D, 1.0D);
|
||||||
|
|
||||||
|
if (renderSegment.nextSegment == null)
|
||||||
|
{
|
||||||
|
Vector3 roundend = renderSegment.endBolt.point.clone().add(renderSegment.difference.clone().normalize().scale(width));
|
||||||
|
float rx3 = (float) (roundend.x - interpPosX);
|
||||||
|
float ry3 = (float) (roundend.y - interpPosY);
|
||||||
|
float rz3 = (float) (roundend.z - interpPosZ);
|
||||||
|
tessellator.addVertexWithUV(rx3 - diff2.x, ry3 - diff2.y, rz3 - diff2.z, 0.0D, 0.0D);
|
||||||
|
tessellator.addVertexWithUV(rx2 - diff2.x, ry2 - diff2.y, rz2 - diff2.z, 0.5D, 0.0D);
|
||||||
|
tessellator.addVertexWithUV(rx2 + diff2.x, ry2 + diff2.y, rz2 + diff2.z, 0.5D, 1.0D);
|
||||||
|
tessellator.addVertexWithUV(rx3 + diff2.x, ry3 + diff2.y, rz3 + diff2.z, 0.0D, 1.0D);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (renderSegment.prevSegment == null)
|
||||||
|
{
|
||||||
|
Vector3 roundend = renderSegment.startBolt.point.clone().subtract(renderSegment.difference.clone().normalize().scale(width));
|
||||||
|
float rx3 = (float) (roundend.x - interpPosX);
|
||||||
|
float ry3 = (float) (roundend.y - interpPosY);
|
||||||
|
float rz3 = (float) (roundend.z - interpPosZ);
|
||||||
|
tessellator.addVertexWithUV(rx1 - diff1.x, ry1 - diff1.y, rz1 - diff1.z, 0.5D, 0.0D);
|
||||||
|
tessellator.addVertexWithUV(rx3 - diff1.x, ry3 - diff1.y, rz3 - diff1.z, 0.0D, 0.0D);
|
||||||
|
tessellator.addVertexWithUV(rx3 + diff1.x, ry3 + diff1.y, rz3 + diff1.z, 0.0D, 1.0D);
|
||||||
|
tessellator.addVertexWithUV(rx1 + diff1.x, ry1 + diff1.y, rz1 + diff1.z, 0.5D, 1.0D);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUpdate()
|
public void onUpdate()
|
||||||
{
|
{
|
||||||
prevPosX = posX;
|
this.prevPosX = this.posX;
|
||||||
prevPosY = posY;
|
this.prevPosY = this.posY;
|
||||||
prevPosZ = posZ;
|
this.prevPosZ = this.posZ;
|
||||||
|
|
||||||
if(particleAge++ >= particleMaxAge)
|
if (this.particleAge++ >= this.particleMaxAge)
|
||||||
{
|
{
|
||||||
setDead();
|
this.setDead();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderParticle(Tessellator tessellator, float partialframe, float cosYaw, float cosPitch, float sinYaw, float sinSinPitch, float cosSinPitch)
|
public void renderParticle(Tessellator tessellator, float partialframe, float cosYaw, float cosPitch, float sinYaw, float sinSinPitch, float cosSinPitch)
|
||||||
{
|
{
|
||||||
EntityPlayer player = Minecraft.getMinecraft().thePlayer;
|
EntityPlayer renderentity = Minecraft.getMinecraft().thePlayer;
|
||||||
|
int visibleDistance = 100;
|
||||||
|
|
||||||
|
if (!Minecraft.getMinecraft().gameSettings.fancyGraphics)
|
||||||
|
{
|
||||||
|
visibleDistance /= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (renderentity.getDistance(this.posX, this.posY, this.posZ) > visibleDistance)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
tessellator.draw();
|
tessellator.draw();
|
||||||
GL11.glPushMatrix();
|
GL11.glPushMatrix();
|
||||||
|
@ -294,165 +380,118 @@ public class FXElectricBolt extends EntityFX
|
||||||
GL11.glDepthMask(false);
|
GL11.glDepthMask(false);
|
||||||
GL11.glEnable(3042);
|
GL11.glEnable(3042);
|
||||||
|
|
||||||
glShadeModel(GL_SMOOTH);
|
|
||||||
glEnable(GL_BLEND);
|
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
|
|
||||||
FMLClientHandler.instance().getClient().renderEngine.bindTexture(TEXTURE);
|
FMLClientHandler.instance().getClient().renderEngine.bindTexture(TEXTURE);
|
||||||
/**
|
/** Render the actual bolts. */
|
||||||
* Render the actual bolts.
|
|
||||||
*/
|
|
||||||
tessellator.startDrawingQuads();
|
tessellator.startDrawingQuads();
|
||||||
tessellator.setBrightness(15728880);
|
tessellator.setBrightness(15728880);
|
||||||
Vector3 playerVector = new Vector3(sinYaw * -cosPitch, -cosSinPitch / cosYaw, cosYaw * cosPitch);
|
this.renderBolt(tessellator, partialframe, cosYaw, cosPitch, sinYaw, cosSinPitch, 0);
|
||||||
|
tessellator.draw();
|
||||||
|
|
||||||
int renderlength = (int)((particleAge + partialframe + (int)(boltLength * 3.0F)) / (int)(boltLength * 3.0F) * segmentCount);
|
// GL11.glBlendFunc(770, 771);
|
||||||
|
|
||||||
for(BoltSegment segment : segments)
|
|
||||||
{
|
|
||||||
if(segment != null && segment.id <= renderlength)
|
|
||||||
{
|
|
||||||
double renderWidth = boltWidth * ((new Vector3(player).distance(segment.start) / 5f + 1f) * (1 + segment.alpha) * 0.5f);
|
|
||||||
renderWidth = Math.min(boltWidth, Math.max(renderWidth, 0));
|
|
||||||
|
|
||||||
if(segment.difference.getMagnitude() > 0 && segment.difference.getMagnitude() != Double.NaN && segment.difference.getMagnitude() != Double.POSITIVE_INFINITY && renderWidth > 0 && renderWidth != Double.NaN && renderWidth != Double.POSITIVE_INFINITY)
|
|
||||||
{
|
|
||||||
Vector3 diffPrev = playerVector.crossProduct(segment.prevDiff).scale(renderWidth / segment.sinPrev);
|
|
||||||
Vector3 diffNext = playerVector.crossProduct(segment.nextDiff).scale(renderWidth / segment.sinNext);
|
|
||||||
Vector3 startVec = segment.start;
|
|
||||||
Vector3 endVec = segment.end;
|
|
||||||
float rx1 = (float)(startVec.x - interpPosX);
|
|
||||||
float ry1 = (float)(startVec.y - interpPosY);
|
|
||||||
float rz1 = (float)(startVec.z - interpPosZ);
|
|
||||||
float rx2 = (float)(endVec.x - interpPosX);
|
|
||||||
float ry2 = (float)(endVec.y - interpPosY);
|
|
||||||
float rz2 = (float)(endVec.z - interpPosZ);
|
|
||||||
|
|
||||||
tessellator.setColorRGBA_F(particleRed, particleGreen, particleBlue, (1.0F - (particleAge >= 0 ? ((float)particleAge / (float)particleMaxAge) : 0.0F) * 0.6f) * segment.alpha);
|
|
||||||
tessellator.addVertexWithUV(rx2 - diffNext.x, ry2 - diffNext.y, rz2 - diffNext.z, 0.5D, 0.0D);
|
|
||||||
tessellator.addVertexWithUV(rx1 - diffPrev.x, ry1 - diffPrev.y, rz1 - diffPrev.z, 0.5D, 0.0D);
|
|
||||||
tessellator.addVertexWithUV(rx1 + diffPrev.x, ry1 + diffPrev.y, rz1 + diffPrev.z, 0.5D, 1.0D);
|
|
||||||
tessellator.addVertexWithUV(rx2 + diffNext.x, ry2 + diffNext.y, rz2 + diffNext.z, 0.5D, 1.0D);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Render the bolts balls.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if(segment.next == null)
|
|
||||||
{
|
|
||||||
Vector3 roundEnd = segment.end.clone().translate(segment.difference.clone().normalize().scale(renderWidth));
|
|
||||||
float rx3 = (float)(roundEnd.x - interpPosX);
|
|
||||||
float ry3 = (float)(roundEnd.y - interpPosY);
|
|
||||||
float rz3 = (float)(roundEnd.z - interpPosZ);
|
|
||||||
tessellator.addVertexWithUV(rx3 - diffNext.x, ry3 - diffNext.y, rz3 - diffNext.z, 0.0D, 0.0D);
|
|
||||||
tessellator.addVertexWithUV(rx2 - diffNext.x, ry2 - diffNext.y, rz2 - diffNext.z, 0.5D, 0.0D);
|
|
||||||
tessellator.addVertexWithUV(rx2 + diffNext.x, ry2 + diffNext.y, rz2 + diffNext.z, 0.5D, 1.0D);
|
|
||||||
tessellator.addVertexWithUV(rx3 + diffNext.x, ry3 + diffNext.y, rz3 + diffNext.z, 0.0D, 1.0D);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(segment.prev == null)
|
|
||||||
{
|
|
||||||
Vector3 roundEnd = segment.start.clone().difference(segment.difference.clone().normalize().scale(renderWidth));
|
|
||||||
float rx3 = (float)(roundEnd.x - interpPosX);
|
|
||||||
float ry3 = (float)(roundEnd.y - interpPosY);
|
|
||||||
float rz3 = (float)(roundEnd.z - interpPosZ);
|
|
||||||
tessellator.addVertexWithUV(rx1 - diffPrev.x, ry1 - diffPrev.y, rz1 - diffPrev.z, 0.5D, 0.0D);
|
|
||||||
tessellator.addVertexWithUV(rx3 - diffPrev.x, ry3 - diffPrev.y, rz3 - diffPrev.z, 0.0D, 0.0D);
|
|
||||||
tessellator.addVertexWithUV(rx3 + diffPrev.x, ry3 + diffPrev.y, rz3 + diffPrev.z, 0.0D, 1.0D);
|
|
||||||
tessellator.addVertexWithUV(rx1 + diffPrev.x, ry1 + diffPrev.y, rz1 + diffPrev.z, 0.5D, 1.0D);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
tessellator.startDrawingQuads();
|
||||||
|
tessellator.setBrightness(15728880);
|
||||||
|
this.renderBolt(tessellator, partialframe, cosYaw, cosPitch, sinYaw, cosSinPitch, 1);
|
||||||
tessellator.draw();
|
tessellator.draw();
|
||||||
|
|
||||||
GL11.glDisable(3042);
|
GL11.glDisable(3042);
|
||||||
GL11.glDepthMask(true);
|
GL11.glDepthMask(true);
|
||||||
GL11.glPopMatrix();
|
GL11.glPopMatrix();
|
||||||
|
|
||||||
FMLClientHandler.instance().getClient().renderEngine.bindTexture(PARTICLE_RESOURCE);
|
FMLClientHandler.instance().getClient().renderEngine.bindTexture(CalclaviaRenderHelper.PARTICLE_RESOURCE);
|
||||||
|
|
||||||
tessellator.startDrawingQuads();
|
tessellator.startDrawingQuads();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class BoltPoint extends Vector3
|
@Override
|
||||||
|
public boolean shouldRenderInPass(int pass)
|
||||||
{
|
{
|
||||||
public Vector3 base;
|
return pass == 2;
|
||||||
public Vector3 offset;
|
|
||||||
|
|
||||||
public BoltPoint(Vector3 b, Vector3 o)
|
|
||||||
{
|
|
||||||
super(b.clone().translate(o));
|
|
||||||
base = b;
|
|
||||||
offset = o;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public BoltPoint(Vector3 base)
|
public class BoltPoint
|
||||||
{
|
{
|
||||||
this(base, new Vector3());
|
Vector3 point;
|
||||||
|
Vector3 basePoint;
|
||||||
|
Vector3 offSet;
|
||||||
|
|
||||||
|
public BoltPoint(Vector3 basePoint, Vector3 offSet)
|
||||||
|
{
|
||||||
|
this.point = basePoint.clone().translate(offSet);
|
||||||
|
this.basePoint = basePoint;
|
||||||
|
this.offSet = offSet;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class BoltSegment
|
public class BoltSegment
|
||||||
{
|
{
|
||||||
public BoltPoint start;
|
public BoltPoint startBolt;
|
||||||
public BoltPoint end;
|
public BoltPoint endBolt;
|
||||||
public BoltSegment prev;
|
public Vector3 difference;
|
||||||
public BoltSegment next;
|
public BoltSegment prevSegment;
|
||||||
public float alpha;
|
public BoltSegment nextSegment;
|
||||||
public int id;
|
public Vector3 nextDiff;
|
||||||
|
public Vector3 prevDiff;
|
||||||
|
public float sinPrev;
|
||||||
|
public float sinNext;
|
||||||
|
/** The order of important */
|
||||||
|
public float weight;
|
||||||
|
public int segmentID;
|
||||||
public int splitID;
|
public int splitID;
|
||||||
|
|
||||||
/**
|
public BoltSegment(BoltPoint startBolt, BoltPoint endBolt, float weight, int segmentID, int splitID)
|
||||||
* All differences are cached.
|
|
||||||
*/
|
|
||||||
public Vector3 difference;
|
|
||||||
public Vector3 prevDiff;
|
|
||||||
public Vector3 nextDiff;
|
|
||||||
public double sinPrev;
|
|
||||||
public double sinNext;
|
|
||||||
|
|
||||||
public BoltSegment(BoltPoint start, BoltPoint end)
|
|
||||||
{
|
{
|
||||||
this(start, end, 1, 0, 0);
|
this.startBolt = startBolt;
|
||||||
|
this.endBolt = endBolt;
|
||||||
|
this.weight = weight;
|
||||||
|
this.segmentID = segmentID;
|
||||||
|
this.splitID = splitID;
|
||||||
|
this.calculateDifference();
|
||||||
}
|
}
|
||||||
|
|
||||||
public BoltSegment(BoltPoint s, BoltPoint e, float a, int i, int id)
|
public BoltSegment(Vector3 start, Vector3 end)
|
||||||
{
|
{
|
||||||
start = s;
|
this(new BoltPoint(start, new Vector3(0.0D, 0.0D, 0.0D)), new BoltPoint(end, new Vector3(0.0D, 0.0D, 0.0D)), 1.0F, 0, 0);
|
||||||
end = e;
|
|
||||||
alpha = a;
|
|
||||||
id = i;
|
|
||||||
splitID = id;
|
|
||||||
difference = end.clone().difference(start);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void recalculate()
|
public void calculateDifference()
|
||||||
{
|
{
|
||||||
if(prev != null)
|
this.difference = this.endBolt.point.clone().subtract(this.startBolt.point);
|
||||||
{
|
|
||||||
Vector3 prevDiffNorm = prev.difference.clone().normalize();
|
|
||||||
Vector3 diffNorm = difference.clone().normalize();
|
|
||||||
prevDiff = diffNorm.clone().translate(prevDiffNorm).normalize();
|
|
||||||
sinPrev = Math.sin(diffNorm.anglePreNorm(prevDiffNorm.clone().scale(-1)) / 2);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
prevDiff = difference.clone().normalize();
|
|
||||||
sinPrev = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(next != null)
|
public void calculateEndDifferences()
|
||||||
{
|
{
|
||||||
Vector3 nextDiffNorm = next.difference.clone().normalize();
|
if (this.prevSegment != null)
|
||||||
Vector3 diffNorm = difference.clone().normalize();
|
{
|
||||||
nextDiff = diffNorm.clone().translate(nextDiffNorm).normalize();
|
Vector3 prevdiffnorm = this.prevSegment.difference.clone().normalize();
|
||||||
sinNext = Math.sin(diffNorm.anglePreNorm(nextDiffNorm.clone().scale(-1)) / 2);
|
Vector3 thisdiffnorm = this.difference.clone().normalize();
|
||||||
|
this.prevDiff = thisdiffnorm.translate(prevdiffnorm).normalize();
|
||||||
|
this.sinPrev = ((float) Math.sin(Vector3.anglePreNorm(thisdiffnorm, prevdiffnorm.scale(-1.0F)) / 2.0F));
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
nextDiff = difference.clone().normalize();
|
{
|
||||||
sinNext = 1;
|
this.prevDiff = this.difference.clone().normalize();
|
||||||
|
this.sinPrev = 1.0F;
|
||||||
|
}
|
||||||
|
if (this.nextSegment != null)
|
||||||
|
{
|
||||||
|
Vector3 nextdiffnorm = this.nextSegment.difference.clone().normalize();
|
||||||
|
Vector3 thisdiffnorm = this.difference.clone().normalize();
|
||||||
|
this.nextDiff = thisdiffnorm.translate(nextdiffnorm).normalize();
|
||||||
|
this.sinNext = ((float) Math.sin(Vector3.anglePreNorm(thisdiffnorm, nextdiffnorm.scale(-1.0F)) / 2.0F));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.nextDiff = this.difference.clone().normalize();
|
||||||
|
this.sinNext = 1.0F;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return this.startBolt.point.toString() + " " + this.endBolt.point.toString();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in a new issue