Revert "Fixed #433 - Electric bolt render NPE"

This reverts commit 92993e832d.
This commit is contained in:
Calclavia 2013-11-20 20:21:10 +08:00
parent 92993e832d
commit ce458d2e77

View file

@ -1,14 +1,23 @@
package icbm.explosion.fx; package mekanism.induction.client;
import icbm.core.ICBMCore; import static org.lwjgl.opengl.GL11.GL_BLEND;
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;
@ -19,95 +28,105 @@ 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;
/** /**
* An effect that renders a electrical bolt from one position to another. Inspired by Azanor's * Electric shock Fxs.
* lightning wand.
* *
* @author Calclavia * @author Calclavia
*
*/ */
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class FXElectricBolt extends EntityFX public class FXElectricBolt extends EntityFX
{ {
private static final ResourceLocation TEXTURE = new ResourceLocation(ICBMCore.DOMAIN, ICBMCore.TEXTURE_PATH + "fadedSphere.png"); public static final ResourceLocation TEXTURE = new ResourceLocation(MekanismInduction.DOMAIN, MekanismInduction.MODEL_TEXTURE_DIRECTORY + "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 = 0.05f; private float boltWidth;
/** The maximum length of the bolt */
public double boltLength;
/** Electric Bolt's start and end positions; */ /** Electric Bolt's start and end positions; */
private Vector3 start; private BoltPoint start;
private Vector3 end; private BoltPoint end;
/** An array of the segments of the bolt. */ /** An array of the segments of the bolt. */
private ArrayList<BoltSegment> segments = new ArrayList<BoltSegment>(); private List<BoltSegment> segments = new ArrayList<BoltSegment>();
private HashMap<Integer, Integer> splitparents = new HashMap<Integer, Integer>(); private final Map<Integer, Integer> parentIDMap = 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 = 0; private int maxSplitID;
private Random rand; private Random rand;
/** Are the segments calculated? */
private boolean isCalculated;
public FXElectricBolt(World world, Vector3 startVec, Vector3 targetVec, long seed) public FXElectricBolt(World world, Vector3 startVec, Vector3 targetVec, boolean doSplits)
{ {
super(world, startVec.x, startVec.y, startVec.z, 0.0D, 0.0D, 0.0D); super(world, startVec.x, startVec.y, startVec.z);
if (seed == 0) rand = new Random();
start = new BoltPoint(startVec);
end = new BoltPoint(targetVec);
if(end.y == Double.POSITIVE_INFINITY)
{ {
this.rand = new Random(); end.y = Minecraft.getMinecraft().thePlayer.posY + 30;
}
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 */
this.particleAge = (3 + this.rand.nextInt(3) - 1); segmentCount = 1;
this.particleRed = 0.55f + (this.rand.nextFloat() * 0.1f); particleMaxAge = (3 + rand.nextInt(3) - 1);
this.particleGreen = 0.7f + (this.rand.nextFloat() * 0.1f); complexity = 2f;
this.particleBlue = 1f; boltWidth = 0.05f;
this.segmentCount = 1; boltLength = start.distance(end);
this.length = this.start.distanceTo(this.end); setUp(doSplits);
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 setMultiplier(float m) public FXElectricBolt(World world, Vector3 startVec, Vector3 targetVec)
{ {
this.complexity = m; this(world, startVec, targetVec, true);
return this;
} }
public FXElectricBolt setWidth(float m) /**
* Calculate all required segments of the entire bolt.
*/
private void setUp(boolean doSplits)
{ {
this.boltWidth = m; segments.add(new BoltSegment(start, end));
return this; recalculate();
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)
{ {
this.particleRed = r; particleRed = r + (rand.nextFloat() * 0.1f) - 0.1f;
this.particleGreen = g; particleGreen = g + (rand.nextFloat() * 0.1f) - 0.1f;
this.particleBlue = b; particleBlue = b + (rand.nextFloat() * 0.1f) - 0.1f;
return this; return this;
} }
@ -121,113 +140,89 @@ 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 */
ArrayList<BoltSegment> oldSegments = this.segments; List<BoltSegment> oldSegments = segments;
this.segments = new ArrayList(); segments = new ArrayList();
/** Previous segment */ /** Previous segment */
BoltSegment prev = null; BoltSegment prev = null;
for(BoltSegment segment : oldSegments) for(BoltSegment segment : oldSegments)
{ {
prev = segment.prevSegment; prev = segment.prev;
/** 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 * Creates an array of new bolt points. The first and last points of the bolts are the
* the respected start and end points of the current segment. * respected start and end points of the current segment.
*/ */
BoltPoint[] newPoints = new BoltPoint[splitAmount + 1]; BoltPoint[] newPoints = new BoltPoint[splitAmount + 1];
Vector3 startPoint = segment.startBolt.point; Vector3 startPoint = segment.start;
newPoints[0] = segment.startBolt; newPoints[0] = segment.start;
newPoints[splitAmount] = segment.endBolt; newPoints[splitAmount] = segment.end;
/**
* Create bolt points.
*/
for(int i = 1; i < splitAmount; i++) for(int i = 1; i < splitAmount; i++)
{ {
Vector3 offsetVec = segment.difference.getPerpendicular().rotate(this.rand.nextFloat() * 360.0F, segment.difference).scale((this.rand.nextFloat() - 0.5F) * offset); Vector3 newOffset = segment.difference.getPerpendicular().rotate(rand.nextFloat() * 360, segment.difference).scale((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.weight, segment.segmentID * splitAmount + i, segment.splitID); BoltSegment next = new BoltSegment(newPoints[i], newPoints[(i + 1)], segment.alpha, segment.id * splitAmount + i, segment.splitID);
next.prevSegment = prev; next.prev = prev;
if(prev != null) if(prev != null)
{ {
prev.nextSegment = next; prev.next = next;
} }
if ((i != 0) && (this.rand.nextFloat() < splitChance)) if((i != 0) && (rand.nextFloat() < splitChance))
{ {
Vector3 splitrot = next.difference.xCrossProduct().rotate(this.rand.nextFloat() * 360.0F, next.difference); Vector3 splitrot = next.difference.xCrossProduct().rotate(rand.nextFloat() * 360, next.difference);
Vector3 diff = next.difference.clone().rotate((this.rand.nextFloat() * 0.66F + 0.33F) * splitAngle, splitrot).scale(splitLength); Vector3 diff = next.difference.clone().rotate((rand.nextFloat() * 0.66F + 0.33F) * splitAngle, splitrot).scale(splitLength);
this.maxSplitID += 1; maxSplitID += 1;
this.splitparents.put(this.maxSplitID, next.splitID); parentIDMap.put(maxSplitID, next.splitID);
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); 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);
split.prevSegment = prev; split.prev = prev;
this.segments.add(split); segments.add(split);
} }
prev = next; prev = next;
this.segments.add(next); segments.add(next);
} }
if (segment.nextSegment != null) if(segment.next != null)
{ {
segment.nextSegment.prevSegment = prev; segment.next.prev = prev;
} }
} }
this.segmentCount *= splitAmount; segmentCount *= splitAmount;
}
} }
public void finalizeBolt() private void recalculate()
{
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(this.segments, new Comparator() Collections.sort(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.segmentID).compareTo(Integer.valueOf(o2.segmentID)); return Integer.valueOf(o1.id).compareTo(Integer.valueOf(o2.id));
} }
return comp; return comp;
} }
@ -241,19 +236,16 @@ public class FXElectricBolt extends EntityFX
int lastSplitCalc = 0; int lastSplitCalc = 0;
int lastActiveSeg = 0; int lastActiveSeg = 0;
for (BoltSegment segment : this.segments) for(BoltSegment segment : segments)
{
if (segment != null)
{ {
if(segment.splitID > lastSplitCalc) if(segment.splitID > lastSplitCalc)
{ {
lastActiveSegment.put(lastSplitCalc, lastActiveSeg); lastActiveSegment.put(lastSplitCalc, lastActiveSeg);
lastSplitCalc = segment.splitID; lastSplitCalc = segment.splitID;
lastActiveSeg = lastActiveSegment.get(this.splitparents.get(segment.splitID)).intValue(); lastActiveSeg = lastActiveSegment.get(parentIDMap.get(segment.splitID)).intValue();
} }
lastActiveSeg = segment.segmentID; lastActiveSeg = segment.id;
}
} }
lastActiveSegment.put(lastSplitCalc, lastActiveSeg); lastActiveSegment.put(lastSplitCalc, lastActiveSeg);
@ -261,7 +253,7 @@ public class FXElectricBolt extends EntityFX
lastActiveSeg = lastActiveSegment.get(0).intValue(); lastActiveSeg = lastActiveSegment.get(0).intValue();
BoltSegment segment; BoltSegment segment;
for (Iterator<BoltSegment> iterator = this.segments.iterator(); iterator.hasNext(); segment.calculateEndDifferences()) for(Iterator<BoltSegment> iterator = segments.iterator(); iterator.hasNext(); segment.recalculate())
{ {
segment = iterator.next(); segment = iterator.next();
@ -271,108 +263,30 @@ public class FXElectricBolt extends EntityFX
lastActiveSeg = lastActiveSegment.get(segment.splitID); lastActiveSeg = lastActiveSegment.get(segment.splitID);
} }
if (segment.segmentID > lastActiveSeg) if(segment.id > 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()
{ {
this.prevPosX = this.posX; prevPosX = posX;
this.prevPosY = this.posY; prevPosY = posY;
this.prevPosZ = this.posZ; prevPosZ = posZ;
if (this.particleAge++ >= this.particleMaxAge) if(particleAge++ >= particleMaxAge)
{ {
this.setDead(); 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 renderentity = Minecraft.getMinecraft().thePlayer; EntityPlayer player = 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();
@ -380,118 +294,165 @@ 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);
this.renderBolt(tessellator, partialframe, cosYaw, cosPitch, sinYaw, cosSinPitch, 0); Vector3 playerVector = new Vector3(sinYaw * -cosPitch, -cosSinPitch / cosYaw, cosYaw * cosPitch);
tessellator.draw();
// GL11.glBlendFunc(770, 771); int renderlength = (int)((particleAge + partialframe + (int)(boltLength * 3.0F)) / (int)(boltLength * 3.0F) * segmentCount);
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(CalclaviaRenderHelper.PARTICLE_RESOURCE); FMLClientHandler.instance().getClient().renderEngine.bindTexture(PARTICLE_RESOURCE);
tessellator.startDrawingQuads(); tessellator.startDrawingQuads();
} }
@Override private class BoltPoint extends Vector3
public boolean shouldRenderInPass(int pass)
{ {
return pass == 2; public Vector3 base;
public Vector3 offset;
public BoltPoint(Vector3 b, Vector3 o)
{
super(b.clone().translate(o));
base = b;
offset = o;
} }
public class BoltPoint public BoltPoint(Vector3 base)
{ {
Vector3 point; this(base, new Vector3());
Vector3 basePoint;
Vector3 offSet;
public BoltPoint(Vector3 basePoint, Vector3 offSet)
{
this.point = basePoint.clone().translate(offSet);
this.basePoint = basePoint;
this.offSet = offSet;
} }
} }
public class BoltSegment private class BoltSegment
{ {
public BoltPoint startBolt; public BoltPoint start;
public BoltPoint endBolt; public BoltPoint end;
public Vector3 difference; public BoltSegment prev;
public BoltSegment prevSegment; public BoltSegment next;
public BoltSegment nextSegment; public float alpha;
public Vector3 nextDiff; public int id;
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.startBolt = startBolt; this(start, end, 1, 0, 0);
this.endBolt = endBolt;
this.weight = weight;
this.segmentID = segmentID;
this.splitID = splitID;
this.calculateDifference();
} }
public BoltSegment(Vector3 start, Vector3 end) public BoltSegment(BoltPoint s, BoltPoint e, float a, int i, int id)
{ {
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); start = s;
end = e;
alpha = a;
id = i;
splitID = id;
difference = end.clone().difference(start);
} }
public void calculateDifference() public void recalculate()
{ {
this.difference = this.endBolt.point.clone().subtract(this.startBolt.point); if(prev != null)
{
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;
} }
public void calculateEndDifferences() if(next != null)
{ {
if (this.prevSegment != null) Vector3 nextDiffNorm = next.difference.clone().normalize();
{ Vector3 diffNorm = difference.clone().normalize();
Vector3 prevdiffnorm = this.prevSegment.difference.clone().normalize(); nextDiff = diffNorm.clone().translate(nextDiffNorm).normalize();
Vector3 thisdiffnorm = this.difference.clone().normalize(); sinNext = Math.sin(diffNorm.anglePreNorm(nextDiffNorm.clone().scale(-1)) / 2);
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();
this.prevDiff = this.difference.clone().normalize(); sinNext = 1;
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();
} }
} }
}