Added galaxy support (wip)

- allow multiple hyperspaces
- allow custom skyboxes (fixed #263)
- fixed stars brightness
- prepared radar update
This commit is contained in:
LemADEC 2017-05-21 12:07:41 +02:00
parent 9ac17bef8d
commit b41698e71f
10 changed files with 561 additions and 230 deletions

View file

@ -4,8 +4,7 @@ import cr0s.warpdrive.Commons;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.block.TileEntityAbstractEnergy;
import cr0s.warpdrive.config.WarpDriveConfig;
import cr0s.warpdrive.data.StarMapRegistryItem;
import cr0s.warpdrive.data.VectorI;
import cr0s.warpdrive.data.RadarEcho;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.peripheral.IComputerAccess;
import li.cil.oc.api.machine.Arguments;
@ -21,7 +20,8 @@ import cpw.mods.fml.common.Optional;
import net.minecraftforge.common.util.ForgeDirection;
public class TileEntityRadar extends TileEntityAbstractEnergy {
private ArrayList<StarMapRegistryItem> results;
private ArrayList<RadarEcho> results;
// radius defined for next scan
private int radius = 0;
@ -58,7 +58,7 @@ public class TileEntityRadar extends TileEntityAbstractEnergy {
if (getBlockMetadata() == 2) {
scanning_ticks++;
if (scanning_ticks > scanningDuration_ticks) {
results = WarpDrive.starMap.radarScan(this, scanningRadius);
results = WarpDrive.starMap.getRadarEchos(this, scanningRadius);
if (WarpDriveConfig.LOGGING_RADAR) {
WarpDrive.logger.info(this + " Scan found " + results.size() + " results in " + scanningRadius + " radius...");
}
@ -209,13 +209,12 @@ public class TileEntityRadar extends TileEntityAbstractEnergy {
}
Object[] objectResults = new Object[results.size()];
int index = 0;
for (StarMapRegistryItem starMapRegistryItem : results) {
final VectorI spaceCoordinates = starMapRegistryItem.getSpaceCoordinates();
for (RadarEcho radarEcho : results) {
objectResults[index++] = new Object[] {
starMapRegistryItem.type.toString(),
starMapRegistryItem.name == null ? "" : starMapRegistryItem.name,
spaceCoordinates.x, spaceCoordinates.y, spaceCoordinates.z,
starMapRegistryItem.mass };
radarEcho.type,
radarEcho.name == null ? "" : radarEcho.name,
radarEcho.x, radarEcho.y, radarEcho.z,
radarEcho.mass };
}
return objectResults;
}
@ -236,15 +235,14 @@ public class TileEntityRadar extends TileEntityAbstractEnergy {
return new Object[] { false, COMPUTER_ERROR_TAG, null, 0, 0, 0 };
}
if (index >= 0 && index < results.size()) {
StarMapRegistryItem starMapRegistryItem = results.get(index);
if (starMapRegistryItem != null) {
VectorI spaceCoordinates = starMapRegistryItem.getSpaceCoordinates();
RadarEcho radarEcho = results.get(index);
if (radarEcho != null) {
return new Object[] {
true,
starMapRegistryItem.type.toString(),
starMapRegistryItem.name == null ? "" : starMapRegistryItem.name,
spaceCoordinates.x, spaceCoordinates.y, spaceCoordinates.z,
starMapRegistryItem.mass };
radarEcho.type,
radarEcho.name == null ? "" : radarEcho.name,
radarEcho.x, radarEcho.y, radarEcho.z,
radarEcho.mass };
}
}
}

View file

@ -49,6 +49,14 @@ public class CelestialObject implements Cloneable, IStringSerializable {
public boolean isBreathable;
private final RandomCollection<StructureGroup> randomStructures = new RandomCollection<>();
public ColorData backgroundColor;
public float baseStarBrightness;
public float vanillaStarBrightness;
public float opacityCelestialObjects;
public ColorData colorFog;
public ColorData factorFog;
public LinkedHashSet<RenderData> setRenderData;
public CelestialObject(final String location, final String parentElementGroup, final String parentElementName, Element elementCelestialObject) throws InvalidXmlException {
@ -104,7 +112,7 @@ public class CelestialObject implements Cloneable, IStringSerializable {
throw new InvalidXmlException(String.format("Celestial object %s can only have up to one parent element", getFullName()));
}
if (listParents.size() == 1) {
Element elementParent = listParents.get(0);
final Element elementParent = listParents.get(0);
// save linked parent
final String parentGroupRead = elementParent.getAttribute("group");
@ -188,13 +196,36 @@ public class CelestialObject implements Cloneable, IStringSerializable {
WarpDrive.logger.info(" loaded " + this);
}
// get optional skybox element
final List<Element> listSkyboxes = XmlFileManager.getChildrenElementByTagName(elementCelestialObject, "skybox");
if (listSkyboxes.size() > 1) {
throw new InvalidXmlException(String.format("Celestial object %s can only have up to one skybox element", getFullName()));
}
if (listSkyboxes.isEmpty()) {
backgroundColor = new ColorData(0.0F , 0.0F , 0.0F );
baseStarBrightness = 0.0F;
vanillaStarBrightness = 1.0F;
opacityCelestialObjects = 1.0F;
colorFog = new ColorData(0.7529412F, 0.84705883F, 1.0F );
factorFog = new ColorData(0.94F , 0.94F , 0.91F);
} else {
final Element elementSkybox = listSkyboxes.get(0);
final String locationSkybox = String.format("Celestial object %s skybox 1/1", getFullName());
backgroundColor = getColorData(locationSkybox, elementSkybox, "backgroundColor" , 0.0F, 0.0F, 0.0F );
baseStarBrightness = getFloat(locationSkybox, elementSkybox, "starBrightnessBase", 0.0F);
vanillaStarBrightness = getFloat(locationSkybox, elementSkybox, "starBrightnessVanilla", 1.0F);
opacityCelestialObjects = getFloat(locationSkybox, elementSkybox, "celestialObjectOpacity", 1.0F);
colorFog = getColorData(locationSkybox, elementSkybox, "fogColor" , 0.7529412F, 0.84705883F, 1.0F );
factorFog = getColorData(locationSkybox, elementSkybox, "fogFactor", 0.94F , 0.94F , 0.91F);
}
// get optional render element(s)
final List<Element> listRenders = XmlFileManager.getChildrenElementByTagName(elementCelestialObject, "render");
setRenderData = new LinkedHashSet<>(listRenders.size());
if (!listRenders.isEmpty()) {
for (int indexElement = 0; indexElement < listRenders.size(); indexElement++) {
final Element elementRender = listRenders.get(indexElement);
final String locationRender = String.format("Celestial object %s generate %d/%d", getFullName(), indexElement + 1, listRenders.size());
final String locationRender = String.format("Celestial object %s render %d/%d", getFullName(), indexElement + 1, listRenders.size());
final RenderData renderData = new RenderData(locationRender, elementRender);
setRenderData.add(renderData);
}
@ -203,6 +234,35 @@ public class CelestialObject implements Cloneable, IStringSerializable {
return true;
}
private float getFloat(final String locationParent, final Element elementParent, final String tagName, final float value) throws InvalidXmlException {
final List<Element> listElements = XmlFileManager.getChildrenElementByTagName(elementParent, tagName);
if (listElements.size() > 1) {
throw new InvalidXmlException(String.format("%s can only have up to one %s element", locationParent, tagName));
}
if (listElements.isEmpty()) {
return value;
} else {
final Element elementSub = listElements.get(0);
final String valueSub = elementSub.getTextContent();
// final String locationChild = String.format("%s %s 1/1", locationParent, tagName);
return Commons.clamp(0.0F, 1.0F, Float.parseFloat(valueSub));
}
}
private ColorData getColorData(final String locationParent, final Element elementParent, final String tagName, final float red, final float green, final float blue) throws InvalidXmlException {
final List<Element> listElements = XmlFileManager.getChildrenElementByTagName(elementParent, tagName);
if (listElements.size() > 1) {
throw new InvalidXmlException(String.format("%s can only have up to one %s element", locationParent, tagName));
}
if (listElements.isEmpty()) {
return new ColorData(red, green, blue);
} else {
final Element elementChild = listElements.get(0);
final String locationChild = String.format("%s %s 1/1", locationParent, tagName);
return new ColorData(locationChild, elementChild);
}
}
private static double parseGravity(final String stringGravity) {
try {
switch(stringGravity) {
@ -367,7 +427,7 @@ public class CelestialObject implements Cloneable, IStringSerializable {
* @return square distance to transition borders, 0 if we're in orbit of the object
*/
public double getSquareDistanceInParent(final int dimensionId, final double x, final double z) {
// are in another dimension?
// are we in another dimension?
if (dimensionId != parentDimensionId) {
return Double.POSITIVE_INFINITY;
}
@ -444,6 +504,33 @@ public class CelestialObject implements Cloneable, IStringSerializable {
}
public class ColorData {
public float red;
public float green;
public float blue;
ColorData(final float red, final float green, final float blue) throws InvalidXmlException {
this.red = red;
this.green = green;
this.blue = blue;
}
ColorData(final String location, final Element elementColor) throws InvalidXmlException {
try {
red = Commons.clamp(0.0F, 1.0F, Float.parseFloat(elementColor.getAttribute("red")));
green = Commons.clamp(0.0F, 1.0F, Float.parseFloat(elementColor.getAttribute("green")));
blue = Commons.clamp(0.0F, 1.0F, Float.parseFloat(elementColor.getAttribute("blue")));
} catch (Exception exception) {
exception.printStackTrace();
WarpDrive.logger.error("Exception while parsing Color element at " + location);
red = 0.5F;
green = 0.5F;
blue = 0.5F;
}
}
}
public class RenderData {
public float red;

View file

@ -51,20 +51,8 @@ public class GlobalPosition {
return getWorldServerIfLoaded() != null;
}
public VectorI getSpaceCoordinates() {
CelestialObject celestialObject = StarMapRegistry.getCelestialObject(dimensionId, x, z);
if (celestialObject == null) {
// not a registered area
return null;
}
if (celestialObject.isHyperspace()) {
return new VectorI(x, y + 512, z);
}
if (celestialObject.isSpace()) {
return new VectorI(x, y + 256, z);
}
VectorI vEntry = celestialObject.getEntryOffset();
return new VectorI(x - vEntry.x, y, z - vEntry.z);
public Vector3 getUniversalCoordinates() {
return StarMapRegistry.getUniversalCoordinates(dimensionId, x, y, z);
}
public boolean equals(final TileEntity tileEntity) {

View file

@ -0,0 +1,65 @@
package cr0s.warpdrive.data;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.api.IStarMapRegistryTileEntity;
import java.util.HashMap;
import java.util.UUID;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
public class RadarEcho extends Vector3 {
public final String type;
public int mass;
public String name = "default";
public RadarEcho(
final String type,
final double x, final double y, final double z,
final int mass,
final String name) {
super(x, y, z);
this.type = type;
this.mass = mass;
this.name = name;
}
public RadarEcho(
final String type,
final Vector3 vectorCoordinates,
final int mass,
final String name) {
super(vectorCoordinates.x, vectorCoordinates.y, vectorCoordinates.z);
this.type = type;
this.mass = mass;
this.name = name;
}
public RadarEcho(final StarMapRegistryItem starMapRegistryItem) {
this(starMapRegistryItem.type.getName(),
starMapRegistryItem.getUniversalCoordinates(),
starMapRegistryItem.mass,
starMapRegistryItem.name );
}
// public RadarEcho(final EntityLivingBase entityLivingBase) {
// this("entity",
// entityLivingBase.worldObj.provider.dimensionId,
// starMapRegistryItem.getUniversalCoordinates(),
// entityLivingBase.width * entityLivingBase.height * 4,
// entityLivingBase.getCommandSenderName() );
// }
@Override
public String toString() {
return String.format("%s %s @ (%d %d %d) %s %s",
getClass().getSimpleName(),
type,
x, y, z,
mass,
name);
}
}

View file

@ -19,6 +19,7 @@ import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.MathHelper;
import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
@ -226,29 +227,40 @@ public class StarMapRegistry {
return 0;
}
public ArrayList<StarMapRegistryItem> radarScan(final TileEntity tileEntity, final int radius) {
final ArrayList<StarMapRegistryItem> starMapRegistryItems = new ArrayList<>(registry.size());
public ArrayList<RadarEcho> getRadarEchos(final TileEntity tileEntity, final int radius) {
final ArrayList<RadarEcho> arrayListRadarEchos = new ArrayList<>(registry.size());
cleanup();
final Vector3 vectorRadar = getUniversalCoordinates(
tileEntity.getWorldObj().provider.dimensionId,
tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord);
// printRegistry();
int radius2 = radius * radius;
for (Map.Entry<Integer, CopyOnWriteArraySet<StarMapRegistryItem>> entryDimension : registry.entrySet()) {
for (StarMapRegistryItem entry : entryDimension.getValue()) {
final double dX = entry.x - tileEntity.xCoord;
final double dY = entry.y - tileEntity.yCoord;
final double dZ = entry.z - tileEntity.zCoord;
final double distance2 = dX * dX + dY * dY + dZ * dZ;
if ( distance2 <= radius2
&& (entry.isolationRate == 0.0D || tileEntity.getWorldObj().rand.nextDouble() >= entry.isolationRate)
&& (entry.getSpaceCoordinates() != null)
&& (entry.type != EnumStarMapEntryType.ACCELERATOR) ) {
starMapRegistryItems.add(entry);
for (StarMapRegistryItem starMapRegistryItem : entryDimension.getValue()) {
if (starMapRegistryItem.type == EnumStarMapEntryType.ACCELERATOR) {
continue;
}
final Vector3 vectorItem = starMapRegistryItem.getUniversalCoordinates();
if (vectorItem == null) {
continue;
}
final double dX = vectorItem.x - vectorRadar.x;
final double dY = vectorItem.y - vectorRadar.y;
final double dZ = vectorItem.z - vectorRadar.z;
final double distance2 = dX * dX + dY * dY + dZ * dZ;
if (distance2 > radius2) {
continue;
}
if ( starMapRegistryItem.isolationRate != 0.0D
&& tileEntity.getWorldObj().rand.nextDouble() < starMapRegistryItem.isolationRate) {
continue;
}
arrayListRadarEchos.add( new RadarEcho(starMapRegistryItem) );
}
}
return starMapRegistryItems;
return arrayListRadarEchos;
}
public boolean isInSpace(final World world, final int x, final int z) {
@ -269,7 +281,28 @@ public class StarMapRegistry {
public boolean isPlanet(final World world, final int x, final int z) {
final CelestialObject celestialObject = getCelestialObject(world, x, z);
return celestialObject == null
|| (!celestialObject.isSpace() && !celestialObject.isHyperspace());
|| (!celestialObject.isSpace() && !celestialObject.isHyperspace());
}
public static Vector3 getUniversalCoordinates(final int dimensionId, final double x, final double y, final double z) {
CelestialObject celestialObject = StarMapRegistry.getCelestialObject(dimensionId, MathHelper.floor_double(x), MathHelper.floor_double(z));
return getUniversalCoordinates(celestialObject, x, y, z);
}
public static Vector3 getUniversalCoordinates(CelestialObject celestialObject, final double x, final double y, final double z) {
if (celestialObject == null) {
// not a registered area
return null;
}
final Vector3 vec3Result = new Vector3(x, y + 512.0D, z);
while (!celestialObject.isHyperspace()) {
final VectorI vEntry = celestialObject.getEntryOffset();
vec3Result.x -= vEntry.x;
vec3Result.y -= 256.0D;
vec3Result.z -= vEntry.z;
celestialObject = StarMapRegistry.getCelestialObject(celestialObject.parentDimensionId, celestialObject.parentCenterX, celestialObject.parentCenterZ);
}
return vec3Result;
}
public void printRegistry(final String trigger) {

View file

@ -5,6 +5,8 @@ import cr0s.warpdrive.config.CelestialObjectManager;
import cr0s.warpdrive.config.WarpDriveConfig;
import cr0s.warpdrive.data.CelestialObject;
import cr0s.warpdrive.data.CelestialObject.RenderData;
import cr0s.warpdrive.data.StarMapRegistry;
import cr0s.warpdrive.data.Vector3;
import java.awt.Color;
import java.util.Random;
@ -33,17 +35,13 @@ public class RenderSpaceSky extends IRenderHandler {
}
public static final int callListStars = GLAllocation.generateDisplayLists(3);
private static float starBrightness = 0.0F;
private static final float ALPHA_TOLERANCE = 1.0F / 256.0F;
public static final int callListUpperSkyBox = callListStars + 1;
public static final int callListBottomSkyBox = callListStars + 2;
{
// pre-generate the starfield
GL11.glPushMatrix();
GL11.glNewList(callListStars, GL11.GL_COMPILE);
renderStars();
GL11.glEndList();
GL11.glPopMatrix();
static {
// pre-generate skyboxes
final Tessellator tessellator = Tessellator.instance;
@ -80,9 +78,9 @@ public class RenderSpaceSky extends IRenderHandler {
@Override
public void render(float partialTicks, WorldClient world, Minecraft mc) {
final Vec3 playerCoordinates = mc.thePlayer.getPosition(partialTicks);
final boolean isSpace = world.provider == null
|| WarpDrive.starMap.isInSpace(world, (int) playerCoordinates.xCoord, (int) playerCoordinates.zCoord);
final Vec3 vec3Player = mc.thePlayer.getPosition(partialTicks);
final CelestialObject celestialObject = world.provider == null ? null
: StarMapRegistry.getCelestialObject(world.provider.dimensionId, (int) vec3Player.xCoord, (int) vec3Player.zCoord);
final Tessellator tessellator = Tessellator.instance;
@ -113,7 +111,7 @@ public class RenderSpaceSky extends IRenderHandler {
/**/
// compute global alpha
final float alphaBase = 1.0F - world.getRainStrength(partialTicks);
final float alphaBase = 1.0F; // - world.getRainStrength(partialTicks);
// draw star systems
GL11.glEnable(GL11.GL_BLEND);
@ -121,15 +119,10 @@ public class RenderSpaceSky extends IRenderHandler {
GL11.glDisable(GL11.GL_ALPHA_TEST);
float starBrightness = 0.2F;
if (world.provider != null) {
starBrightness = world.provider.getStarBrightness(partialTicks);
starBrightness = world.getStarBrightness(partialTicks);
}
if (starBrightness > 0.0F) {
if (isSpace) {
GL11.glColor4f(1.0F, 1.0F, 0.9F, alphaBase * starBrightness);
} else {
GL11.glColor4f(0.5F, 0.6F, 0.4F, alphaBase * starBrightness);
}
GL11.glCallList(callListStars);
if (starBrightness > 0.0F && celestialObject != null) {
renderStars_cached(alphaBase * starBrightness);
}
// enable texture with alpha blending
@ -187,8 +180,17 @@ public class RenderSpaceSky extends IRenderHandler {
/**/
// Planets
for(CelestialObject celestialObject : CelestialObjectManager.celestialObjects) {
renderCelestialObject(tessellator, celestialObject, isSpace, mc.thePlayer.getEntityWorld().provider.dimensionId, playerCoordinates);
if (celestialObject != null) {
final Vector3 vectorPlayer = StarMapRegistry.getUniversalCoordinates(celestialObject, vec3Player.xCoord, vec3Player.yCoord, vec3Player.zCoord);
for (CelestialObject celestialObjectChild : CelestialObjectManager.celestialObjects) {
if (celestialObject == celestialObjectChild) {
continue;
}
renderCelestialObject(tessellator,
celestialObjectChild,
celestialObject.opacityCelestialObjects,
vectorPlayer);
}
}
// final double playerAltitude = mc.thePlayer.getPosition(partialTicks).yCoord - world.getHorizon();
@ -255,15 +257,43 @@ public class RenderSpaceSky extends IRenderHandler {
static final double PLANET_FAR = 1786.0D;
static final double PLANET_APPROACHING = 512.0D;
static final double PLANET_ORBIT = 128.0D;
private static void renderCelestialObject(Tessellator tessellator, final CelestialObject celestialObject, final boolean isSpace, final int dimensionId, final Vec3 vec3Player) {
private static void renderCelestialObject(final Tessellator tessellator, final CelestialObject celestialObject,
final float alphaSky, final Vector3 vectorPlayer) {
// @TODO compute relative coordinates for rendering on celestialObject
if (dimensionId != celestialObject.parentDimensionId) {
if (celestialObject.isHyperspace() || celestialObject.isSpace()) {
return;
}
final double distanceToCenterX = celestialObject.parentCenterX - vec3Player.xCoord;
final double distanceToCenterZ = celestialObject.parentCenterZ - vec3Player.zCoord;
final double distanceToBorder = Math.sqrt(Math.max(0, celestialObject.getSquareDistanceInParent(dimensionId, vec3Player.xCoord, vec3Player.zCoord)));
// get universal coordinates
final Vector3 vectorCenter = StarMapRegistry.getUniversalCoordinates(celestialObject,
celestialObject.dimensionCenterX,
64,
celestialObject.dimensionCenterZ);
final Vector3 vectorBorderPos = StarMapRegistry.getUniversalCoordinates(celestialObject,
celestialObject.dimensionCenterX + celestialObject.borderRadiusX,
64,
celestialObject.dimensionCenterZ + celestialObject.borderRadiusZ);
final double borderRadiusX = vectorBorderPos.x - vectorCenter.x;
final double borderRadiusZ = vectorBorderPos.z - vectorCenter.z;
// compute distances
final double distanceToBorder;
{
final double dx = Math.abs(vectorPlayer.x - vectorCenter.x) - borderRadiusX;
final double dz = Math.abs(vectorPlayer.z - vectorCenter.z) - borderRadiusZ;
// are we in orbit?
if ((dx <= 0.0D) && (dz <= 0.0D)) {
distanceToBorder = 0.0D;
} else {
// do the maths
final double dxOutside = Math.max(0.0D, dx);
final double dzOutside = Math.max(0.0D, dz);
distanceToBorder = Math.sqrt(dxOutside * dxOutside + dzOutside * dzOutside);
}
}
final double distanceToCenterX = vectorCenter.x - vectorPlayer.x;
final double distanceToCenterZ = vectorCenter.z - vectorPlayer.z;
final double distanceToCenter = Math.sqrt(distanceToCenterX * distanceToCenterX + distanceToCenterZ * distanceToCenterZ);
// transition values
@ -278,21 +308,21 @@ public class RenderSpaceSky extends IRenderHandler {
final double transitionOrbit = Math.max(0.0D, Math.min(PLANET_ORBIT, distanceToBorder)) / PLANET_ORBIT;
// relative position above celestialObject
final double offsetX = (1.0 - transitionOrbit) * (distanceToCenterX / celestialObject.borderRadiusX);
final double offsetZ = (1.0 - transitionOrbit) * (distanceToCenterZ / celestialObject.borderRadiusZ);
final double offsetX = (1.0 - transitionOrbit) * (distanceToCenterX / borderRadiusX);
final double offsetZ = (1.0 - transitionOrbit) * (distanceToCenterZ / borderRadiusZ);
// simulating a non-planar universe...
final double planetY_far = (celestialObject.dimensionId + 99 % 100 - 50) * Math.log(distanceToCenter) / 4.0D;
final double planetY = planetY_far * transitionApproaching;
// render range is only used for Z-ordering
double renderRange = 90.0D + 5.0D * (distanceToCenter / Math.max(celestialObject.borderRadiusX, celestialObject.borderRadiusZ));
double renderRange = 90.0D + 5.0D * (distanceToCenter / Math.max(borderRadiusX, borderRadiusZ));
// render size is 1 at space border range
// render size is 10 at approaching range
// render size is 90 at orbit range
// render size is min(1000, celestialObject border) at orbit range
final double renderSize = 50.0D / 1000.0D * Math.min(1000.0D, Math.max(celestialObject.borderRadiusX, celestialObject.borderRadiusZ)) * (1.0D - transitionOrbit)
final double renderSize = 50.0D / 1000.0D * Math.min(1000.0D, Math.max(borderRadiusX, borderRadiusZ)) * (1.0D - transitionOrbit)
+ 25.0D * (transitionOrbit < 1.0D ? transitionOrbit : (1.0D - transitionApproaching))
+ 2.5D * (transitionApproaching < 1.0D ? transitionApproaching : (1.0D - transitionFar))
+ 1.0D * transitionFar;
@ -331,7 +361,7 @@ public class RenderSpaceSky extends IRenderHandler {
final float offsetV = (float) ( Math.signum(renderData.periodV) * ((time / Math.abs(renderData.periodV)) % 1.0D) );
// apply rendering parameters
GL11.glColor4f(renderData.red, renderData.green, renderData.blue, renderData.alpha * (isSpace ? 1.0F : 0.2F));
GL11.glColor4f(renderData.red, renderData.green, renderData.blue, renderData.alpha * alphaSky);
if (renderData.texture != null) {
GL11.glEnable(GL11.GL_TEXTURE_2D);
FMLClientHandler.instance().getClient().renderEngine.bindTexture(renderData.resourceLocation);
@ -374,7 +404,7 @@ public class RenderSpaceSky extends IRenderHandler {
GL11.glPopMatrix();
}
private void renderStars() {
private void renderStars_direct(final float brightness) {
final Random rand = new Random(10842L);
final boolean hasMoreStars = rand.nextBoolean() || rand.nextBoolean();
final Tessellator tessellator = Tessellator.instance;
@ -414,7 +444,7 @@ public class RenderSpaceSky extends IRenderHandler {
// colorization
final int rgb = getStarColorRGB(rand);
GL11.glColor4f(((rgb >> 16) & 0xFF) / 255.0F, ((rgb >> 8) & 0xFF) / 255.0F, (rgb & 0xFF) / 255.0F, 1.0F /* isSpace ? 1.0F : 0.2F /**/);
GL11.glColor4f(((rgb >> 16) & 0xFF) / 255.0F, ((rgb >> 8) & 0xFF) / 255.0F, (rgb & 0xFF) / 255.0F, brightness);
// pre-computations
final double sinH = Math.sin(angleH);
@ -442,6 +472,18 @@ public class RenderSpaceSky extends IRenderHandler {
}
private void renderStars_cached(final float brightness) {
if (Math.abs(starBrightness - brightness) > ALPHA_TOLERANCE) {
starBrightness = brightness;
GL11.glPushMatrix();
GL11.glNewList(callListStars, GL11.GL_COMPILE);
renderStars_direct(brightness);
GL11.glEndList();
GL11.glPopMatrix();
}
GL11.glCallList(callListStars);
}
// colorization loosely inspired from Hertzsprung-Russell diagram
// (we're using it for non-star objects too, so yeah...)
private static int getStarColorRGB(Random rand) {

View file

@ -1,6 +1,8 @@
package cr0s.warpdrive.world;
import cr0s.warpdrive.Commons;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.data.CelestialObject;
import cr0s.warpdrive.data.StarMapRegistry;
import cr0s.warpdrive.render.RenderBlank;
import cr0s.warpdrive.render.RenderSpaceSky;
@ -9,6 +11,7 @@ import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.init.Blocks;
import net.minecraft.util.ChunkCoordinates;
import net.minecraft.util.MathHelper;
import net.minecraft.util.Vec3;
import net.minecraft.world.WorldProvider;
import net.minecraft.world.biome.BiomeGenBase;
@ -36,12 +39,6 @@ public class HyperSpaceWorldProvider extends WorldProvider {
return true;
}
@SideOnly(Side.CLIENT)
@Override
public float getStarBrightness(float partialTicks) {
return 0.2F;
}
@Override
public boolean isSurfaceWorld() {
return true;
@ -99,6 +96,11 @@ public class HyperSpaceWorldProvider extends WorldProvider {
return var3 != 0;
}
// shared for getFogColor(), getStarBrightness()
@SideOnly(Side.CLIENT)
private static CelestialObject celestialObject = null;
@SideOnly(Side.CLIENT)
@Override
public Vec3 getSkyColor(Entity cameraEntity, float partialTicks) {
if (getCloudRenderer() == null) {
@ -107,12 +109,42 @@ public class HyperSpaceWorldProvider extends WorldProvider {
if (getSkyRenderer() == null) {
setSkyRenderer(RenderSpaceSky.getInstance());
}
return Vec3.createVectorHelper(1.0D, 0.0D, 0.0D);
celestialObject = cameraEntity.worldObj == null ? null : StarMapRegistry.getCelestialObject(
cameraEntity.worldObj.provider.dimensionId,
MathHelper.floor_double(cameraEntity.posX), MathHelper.floor_double(cameraEntity.posZ));
if (celestialObject == null) {
return Vec3.createVectorHelper(1.0D, 0.0D, 0.0D);
} else {
return Vec3.createVectorHelper(celestialObject.backgroundColor.red, celestialObject.backgroundColor.green, celestialObject.backgroundColor.blue);
}
}
@SideOnly(Side.CLIENT)
@Override
public Vec3 getFogColor(float par1, float par2) {
return Vec3.createVectorHelper(0.1D, 0.0D, 0.0D);
public Vec3 getFogColor(float celestialAngle, float par2) {
final float factor = Commons.clamp(0.0F, 1.0F, MathHelper.cos(celestialAngle * (float) Math.PI * 2.0F) * 2.0F + 0.5F);
float red = celestialObject == null ? 0.0F : celestialObject.colorFog.red;
float green = celestialObject == null ? 0.0F : celestialObject.colorFog.green;
float blue = celestialObject == null ? 0.0F : celestialObject.colorFog.blue;
float factorRed = celestialObject == null ? 0.0F : celestialObject.factorFog.red;
float factorGreen = celestialObject == null ? 0.0F : celestialObject.factorFog.green;
float factorBlue = celestialObject == null ? 0.0F : celestialObject.factorFog.blue;
red *= factor * factorRed + (1.0F - factorRed );
green *= factor * factorGreen + (1.0F - factorGreen);
blue *= factor * factorBlue + (1.0F - factorBlue );
return Vec3.createVectorHelper(red, green, blue);
}
@SideOnly(Side.CLIENT)
@Override
public float getStarBrightness(float partialTicks) {
if (celestialObject == null) {
return 0.0F;
}
final float starBrightnessVanilla = super.getStarBrightness(partialTicks);
return celestialObject.baseStarBrightness + celestialObject.vanillaStarBrightness * starBrightnessVanilla;
}
@SideOnly(Side.CLIENT)

View file

@ -1,6 +1,8 @@
package cr0s.warpdrive.world;
import cr0s.warpdrive.Commons;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.data.CelestialObject;
import cr0s.warpdrive.data.StarMapRegistry;
import cr0s.warpdrive.render.RenderBlank;
import cr0s.warpdrive.render.RenderSpaceSky;
@ -8,6 +10,7 @@ import cr0s.warpdrive.render.RenderSpaceSky;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.util.ChunkCoordinates;
import net.minecraft.util.MathHelper;
import net.minecraft.util.Vec3;
import net.minecraft.world.WorldProvider;
import net.minecraft.world.biome.BiomeGenBase;
@ -35,12 +38,6 @@ public class SpaceWorldProvider extends WorldProvider {
return true;
}
@SideOnly(Side.CLIENT)
@Override
public float getStarBrightness(float partialTicks) {
return 0.9F;
}
@Override
public boolean isSurfaceWorld() {
return true;
@ -95,11 +92,16 @@ public class SpaceWorldProvider extends WorldProvider {
/*
@Override
public boolean canCoordinateBeSpawn(int par1, int par2) {
Block var3 = worldObj.getTopSolidOrLiquidBlock(par1, par2);
int var3 = worldObj.getTopSolidOrLiquidBlock(par1, par2);
return var3 != 0;
}
/**/
// shared for getFogColor(), getStarBrightness()
@SideOnly(Side.CLIENT)
private static CelestialObject celestialObject = null;
@SideOnly(Side.CLIENT)
@Override
public Vec3 getSkyColor(Entity cameraEntity, float partialTicks) {
if (getCloudRenderer() == null) {
@ -108,14 +110,45 @@ public class SpaceWorldProvider extends WorldProvider {
if (getSkyRenderer() == null) {
setSkyRenderer(RenderSpaceSky.getInstance());
}
return Vec3.createVectorHelper(0.0D, 0.0D, 0.0D);
celestialObject = cameraEntity.worldObj == null ? null : StarMapRegistry.getCelestialObject(
cameraEntity.worldObj.provider.dimensionId,
MathHelper.floor_double(cameraEntity.posX), MathHelper.floor_double(cameraEntity.posZ));
if (celestialObject == null) {
return Vec3.createVectorHelper(0.0D, 0.0D, 0.0D);
} else {
return Vec3.createVectorHelper(celestialObject.backgroundColor.red, celestialObject.backgroundColor.green, celestialObject.backgroundColor.blue);
}
}
@SideOnly(Side.CLIENT)
@Override
public Vec3 getFogColor(float par1, float par2) {
return Vec3.createVectorHelper(0.0D, 0.0D, 0.0D);
public Vec3 getFogColor(float celestialAngle, float par2) {
final float factor = Commons.clamp(0.0F, 1.0F, MathHelper.cos(celestialAngle * (float) Math.PI * 2.0F) * 2.0F + 0.5F);
float red = celestialObject == null ? 0.0F : celestialObject.colorFog.red;
float green = celestialObject == null ? 0.0F : celestialObject.colorFog.green;
float blue = celestialObject == null ? 0.0F : celestialObject.colorFog.blue;
float factorRed = celestialObject == null ? 0.0F : celestialObject.factorFog.red;
float factorGreen = celestialObject == null ? 0.0F : celestialObject.factorFog.green;
float factorBlue = celestialObject == null ? 0.0F : celestialObject.factorFog.blue;
red *= factor * factorRed + (1.0F - factorRed );
green *= factor * factorGreen + (1.0F - factorGreen);
blue *= factor * factorBlue + (1.0F - factorBlue );
return Vec3.createVectorHelper(red, green, blue);
}
@SideOnly(Side.CLIENT)
@Override
public float getStarBrightness(float partialTicks) {
if (celestialObject == null) {
return 0.0F;
}
final float starBrightnessVanilla = super.getStarBrightness(partialTicks);
return celestialObject.baseStarBrightness + celestialObject.vanillaStarBrightness * starBrightnessVanilla;
}
@SideOnly(Side.CLIENT)
@Override
public boolean isSkyColored() {
return false;

View file

@ -115,6 +115,24 @@
<xs:element name="dimension" type="dimensionElement" minOccurs="0" maxOccurs="1" />
<xs:element name="skybox" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:annotation>
<xs:documentation xml:lang="en">
Sky rendering parameters
</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="backgroundColor" type="colorElement" minOccurs="0" maxOccurs="1" />
<xs:element name="starBrightnessBase" type="xs:float" minOccurs="0" maxOccurs="1" />
<xs:element name="starBrightnessVanilla" type="xs:float" minOccurs="0" maxOccurs="1" />
<xs:element name="celestialObjectOpacity" type="xs:float" minOccurs="0" maxOccurs="1" />
<xs:element name="fogColor" type="colorElement" minOccurs="0" maxOccurs="1" />
<xs:element name="fogFactor" type="colorElement" minOccurs="0" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="render" type="renderElement" minOccurs="0" maxOccurs="unbounded" />
<xs:choice minOccurs="0" maxOccurs="1">
@ -165,6 +183,12 @@
<xs:attribute name="z" type="worldPositionType" use="required" />
</xs:complexType>
<xs:complexType name="colorElement">
<xs:attribute name="red" type="xs:float" use="required" />
<xs:attribute name="green" type="xs:float" use="required" />
<xs:attribute name="blue" type="xs:float" use="required" />
</xs:complexType>
<xs:complexType name="renderElement">
<xs:attribute name="red" type="xs:float" use="required" />
<xs:attribute name="green" type="xs:float" use="required" />
@ -207,7 +231,7 @@
<xs:element name="for" type="forElement" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="fillerSet" type="fillerSetElement" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="structure" type="structureElement" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="celestialObject" type="celestialObjectElement" minOccurs="0" maxOccurs="1" />
<xs:element name="celestialObject" type="celestialObjectElement" minOccurs="0" maxOccurs="unbounded" />
</xs:choice>
<xs:attribute name="version" type="xs:string" use="required" fixed="2" />
<xs:attribute name="mods" type="xs:string" use="optional" />

View file

@ -1,131 +1,160 @@
<?xml version="1.0" encoding="utf-8"?>
<worldGeneration version="2"
xmlns="WarpDrive"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="WarpDrive WarpDrive.xsd">
<!--
An astronomical object or celestial object is a naturally occurring physical entity, association, or structure in the observable universe.
They can be a planet, a more abstract construct like solar system (space dimension) or the all mighty hyperspace.
Hyperspace is a dimension which is its own parent. In other words, hyperspace.dimensionId = hyperspace.parentDimensionId. There can be only one.
A Space is a dimension with Hyperspace as its parent.
In theory, multiple planets can exists in the same minecraft world.
-->
<!-- Top level is hyperspace, typically a galaxy. -->
<celestialObject group="milkyWay" name="hyperspace">
<!--
side defines the world border size, measured in blocks. This is also the size of the orbit area in space, so don't go too big.
-->
<size x="100000" z="100000" />
<!--
dimension defines an actual game world. If it's missing, that celestialObject remains visible but you can't "land" on it.
dimension.id: this is the id of the dimension. 0 is the Overworld, -1 is the Nether, 1 is the End.
dimension.isBreathable: this is a boolean flag defining if ambient atmosphere is breathable.
dimension.gravity: this is the gravity simulation type. 0 is vanilla, 1 is space, 2 is hyperspace.
dimension.center.x, dimension.center.z: those are the center coordinate of that dimension world border, measured in blocks. For convenience, it's usually 0, 0.
dimension.isProvidedByWarpDrive (optional): this is a boolean flag defining if WarpDrive provides this dimension or not.
Currently only Space and Hyperspace can be provided: use other mods to generate planet world.
-->
<dimension id="-3" isBreathable="false" gravity="legacyHyperspace" isProvidedByWarpDrive="true">
<center x="0" z="0" />
</dimension>
<!-- Second level is space, typically a star system. -->
<celestialObject group="milkyWay" name="solarSystem">
<!--
parent defines the relation with a bigger enveloping celestial object.
parent.group, parent.name (optional): when using multiple files, you can attach to a parent by its group and name.
parent.center.x, parent.center.z: this is the center coordinates in the parent dimension, measured in blocks.
-->
<parent>
<center x="0" z="0" />
</parent>
<size x="200000" z="200000" />
<dimension id="-2" isBreathable="false" gravity="legacySpace" isProvidedByWarpDrive="true">
<center x="0" z="0" />
<!--
generate defines the chance of different structures to generate
generate.group, generate.name: identify the structure from the related XML files
Those only works in WarpDrive dimensions, they're ignored otherwise.
-->
<generate group="moon" ratio="0.008" />
<generate group="asteroid" ratio="0.0015" />
<generate group="asteroidField" ratio="0.006" />
</dimension>
<!-- Sun is just displayed, there's no actual game dimension -->
<celestialObject group="solarSystem" name="sun">
<parent>
<!-- sun is at the center of the solarSystem -->
<center x="0" z="0" />
</parent>
<size x="10000" z="10000" />
<!--
render defines several layers from surface to high atmosphere representing the planet.
red, green, blue: color mixing from 0.00 (black) to 1.00 (white)
alpha: transparency factor from 0.00 (invisible) to 1.00 (opaque)
texture: optional texture to use, can come from resource pack, vanilla or the mod itself
periodU, periodV: optional rotation period, measured in seconds, defaults to 0 (disabled)
additive: optional blending function, defaults to false (multiplicative)
-->
<render red="0.80" green="0.50" blue="0.20" alpha="1.00" texture="" />
<render red="0.80" green="0.70" blue="0.30" alpha="0.40" texture="warpdrive:textures/celestial/planet_icy.png" periodU="-20" periodV="104" additive="true" />
<render red="0.80" green="0.55" blue="0.10" alpha="0.48" texture="warpdrive:textures/celestial/planet_metallic.png" periodU="-40" periodV="140" additive="true" />
<render red="0.80" green="0.45" blue="0.30" alpha="0.34" texture="warpdrive:textures/celestial/planet_magma.png" periodU="24" periodV="-35" additive="true" />
<render red="0.80" green="0.50" blue="0.20" alpha="0.08" texture="" />
<render red="0.75" green="0.48" blue="0.20" alpha="0.08" texture="" />
<render red="0.70" green="0.55" blue="0.20" alpha="0.08" texture="" />
</celestialObject>
<!-- Earth is the overworld (dimension.id is 0) -->
<celestialObject group="solarSystem" name="earth">
<parent>
<!-- coordinates in the solar system, measured in blocks -->
<center x="-40000" z="20000" />
</parent>
<size x="4000" z="4000" />
<dimension id="0" isBreathable="true" gravity="normal">
<center x="0" z="0" />
</dimension>
<render red="0.70" green="0.70" blue="0.70" alpha="1.00" texture="warpdrive:textures/celestial/planet_temperate.png" />
<render red="0.90" green="0.95" blue="1.00" alpha="0.15" texture="warpdrive:textures/celestial/cloud_small.png" periodU="100" periodV="1100" additive="true" />
<render red="0.90" green="0.90" blue="1.00" alpha="0.15" texture="warpdrive:textures/celestial/cloud_medium.png" periodU="300" periodV="1500" additive="false" />
<render red="0.80" green="0.70" blue="1.00" alpha="0.15" texture="warpdrive:textures/celestial/cloud_large.png" periodU="500" periodV="2100" additive="false" />
<render red="0.50" green="0.50" blue="1.00" alpha="0.08" />
<render red="0.50" green="0.50" blue="1.00" alpha="0.08" />
<render red="0.50" green="0.50" blue="1.00" alpha="0.08" />
<!-- Hell is the nether. It's located below earth. In other words, falling below bedrock will drop you to the nether... -->
<celestialObject group="solarSystem" name="hell">
<parent>
<center x="0" z="0" />
</parent>
<size x="1000" z="1000" />
<dimension id="-1" isBreathable="true" gravity="normal">
<center x="0" z="0" />
</dimension>
</celestialObject>
</celestialObject>
<!-- Pluto is The End. It's a far planet. -->
<celestialObject group="solarSystem" name="pluto">
<parent>
<center x="90000" z="70000" />
</parent>
<size x="4000" z="4000" />
<dimension id="1" isBreathable="true" gravity="normal">
<center x="0" z="0" />
</dimension>
<render red="1.00" green="1.00" blue="1.00" alpha="1.00" texture="minecraft:textures/blocks/end_stone.png" periodU="150" />
<render red="0.50" green="0.50" blue="0.40" alpha="0.30" />
</celestialObject>
</celestialObject>
</celestialObject>
xmlns="WarpDrive"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="WarpDrive WarpDrive.xsd">
<!--
An astronomical object or celestial object is a naturally occurring physical entity, association, or structure in the observable universe.
They can be a planet, a more abstract construct like solar system (space dimension) or the all mighty hyperspace.
Hyperspace is a dimension which is its own parent. In other words, hyperspace.dimensionId = hyperspace.parentDimensionId.
Space is a dimension with Hyperspace as its parent.
In theory, multiple planets can exists in the same minecraft world.
In theory, multiple hyperspaces can be defined.
-->
<!-- Top level is hyperspace, typically a galaxy. -->
<celestialObject group="milkyWay" name="hyperspace">
<!--
side defines the world border size, measured in blocks. This is also the size of the orbit area in space, so don't go too big.
-->
<size x="100000" z="100000" />
<!--
dimension defines an actual game world. If it's missing, that celestialObject remains visible but you can't "land" on it.
dimension.id: this is the id of the dimension. 0 is the Overworld, -1 is the Nether, 1 is the End.
dimension.isBreathable: this is a boolean flag defining if ambient atmosphere is breathable.
dimension.gravity: this is the gravity simulation type. 0 is vanilla, 1 is space, 2 is hyperspace.
dimension.center.x, dimension.center.z: those are the center coordinate of that dimension world border, measured in blocks. For convenience, it's usually 0, 0.
dimension.isProvidedByWarpDrive (optional): this is a boolean flag defining if WarpDrive provides this dimension or not.
Currently only Space and Hyperspace can be provided: use other mods to generate planet world.
-->
<dimension id="-3" isBreathable="false" gravity="legacyHyperspace" isProvidedByWarpDrive="true">
<center x="0" z="0" />
</dimension>
<!--
skybox defines the sky rendering while inside a WarpDrive provided dimensions.
Those can be adjusted to your lore: in hyperspace, Babylon 5 is redish, Stargate is bluish, etc.
skybox.backgroundColor is self explanatory. Vanilla enforces plain black at max render distance.
skybox.starBrightnessBase is the minimum brightness of stars in the sky.
skybox.starBrightnessVanilla is how much of the vanilla star brightness is used. Space and hyperspace have no Sun, hence it's a fixed value.
skybox.celestialObjectOpacity is used for that eery feeling. 0 will completly hide celestial objects.
skybox.fogColor is the main color. Higher values increases the halo effect.
skybox.fogFactor is the fog opacity depending on local Sun position. Space and hyperspace have no Sun, hence it's a fixed value.
-->
<skybox>
<backgroundColor red="1.0" green="0.0" blue="0.0" />
<starBrightnessBase>0.2</starBrightnessBase>
<starBrightnessVanilla>0.0</starBrightnessVanilla>
<celestialObjectOpacity>0.3</celestialObjectOpacity>
<fogColor red="0.15" green="0.0" blue="0.0" />
<fogFactor red="0.0" green="0.0" blue="0.0" />
</skybox>
<!-- Second level is space, typically a star system. -->
<celestialObject group="milkyWay" name="solarSystem">
<!--
parent defines the relation with a bigger enveloping celestial object.
parent.group, parent.name (optional): when using multiple files, you can attach to a parent by its group and name.
parent.center.x, parent.center.z: this is the center coordinates in the parent dimension, measured in blocks.
-->
<parent>
<center x="0" z="0" />
</parent>
<size x="200000" z="200000" />
<dimension id="-2" isBreathable="false" gravity="legacySpace" isProvidedByWarpDrive="true">
<center x="0" z="0" />
<!--
generate defines the chance of different structures to generate
generate.group, generate.name: identify the structure from the related XML files
Those only works in WarpDrive dimensions, they're ignored otherwise.
-->
<generate group="moon" ratio="0.008" />
<generate group="asteroid" ratio="0.0015" />
<generate group="asteroidField" ratio="0.006" />
</dimension>
<skybox>
<backgroundColor red="0.0" green="0.0" blue="0.0" />
<starBrightnessBase>0.9</starBrightnessBase>
<starBrightnessVanilla>0.0</starBrightnessVanilla>
<celestialObjectOpacity>1.0</celestialObjectOpacity>
<fogColor red="0.0" green="0.0" blue="0.0" />
<fogFactor red="0.0" green="0.0" blue="0.0" />
</skybox>
<!-- Sun is just displayed, there's no actual game dimension -->
<celestialObject group="solarSystem" name="sun">
<parent>
<!-- sun is at the center of the solarSystem -->
<center x="0" z="0" />
</parent>
<size x="10000" z="10000" />
<!--
render defines several layers from surface to high atmosphere representing the planet.
red, green, blue: color mixing from 0.00 (black) to 1.00 (white)
alpha: transparency factor from 0.00 (invisible) to 1.00 (opaque)
texture: optional texture to use, can come from resource pack, vanilla or the mod itself
periodU, periodV: optional rotation period, measured in seconds, defaults to 0 (disabled)
additive: optional blending function, defaults to false (multiplicative)
-->
<render red="0.80" green="0.50" blue="0.20" alpha="1.00" texture="" />
<render red="0.80" green="0.70" blue="0.30" alpha="0.40" texture="warpdrive:textures/celestial/planet_icy.png" periodU="-20" periodV="104" additive="true" />
<render red="0.80" green="0.55" blue="0.10" alpha="0.48" texture="warpdrive:textures/celestial/planet_metallic.png" periodU="-40" periodV="140" additive="true" />
<render red="0.80" green="0.45" blue="0.30" alpha="0.34" texture="warpdrive:textures/celestial/planet_magma.png" periodU="24" periodV="-35" additive="true" />
<render red="0.80" green="0.50" blue="0.20" alpha="0.08" texture="" />
<render red="0.75" green="0.48" blue="0.20" alpha="0.08" texture="" />
<render red="0.70" green="0.55" blue="0.20" alpha="0.08" texture="" />
</celestialObject>
<!-- Earth is the overworld (dimension.id is 0) -->
<celestialObject group="solarSystem" name="earth">
<parent>
<!-- coordinates in the solar system, measured in blocks -->
<center x="-40000" z="20000" />
</parent>
<size x="4000" z="4000" />
<dimension id="0" isBreathable="true" gravity="normal">
<center x="0" z="0" />
</dimension>
<render red="0.70" green="0.70" blue="0.70" alpha="1.00" texture="warpdrive:textures/celestial/planet_temperate.png" />
<render red="0.90" green="0.95" blue="1.00" alpha="0.15" texture="warpdrive:textures/celestial/cloud_small.png" periodU="100" periodV="1100" additive="true" />
<render red="0.90" green="0.90" blue="1.00" alpha="0.15" texture="warpdrive:textures/celestial/cloud_medium.png" periodU="300" periodV="1500" additive="false" />
<render red="0.80" green="0.70" blue="1.00" alpha="0.15" texture="warpdrive:textures/celestial/cloud_large.png" periodU="500" periodV="2100" additive="false" />
<render red="0.50" green="0.50" blue="1.00" alpha="0.08" />
<render red="0.50" green="0.50" blue="1.00" alpha="0.08" />
<render red="0.50" green="0.50" blue="1.00" alpha="0.08" />
<!-- Hell is the nether. It's located below earth. In other words, falling below bedrock will drop you to the nether... -->
<celestialObject group="solarSystem" name="hell">
<parent>
<center x="0" z="0" />
</parent>
<size x="1000" z="1000" />
<dimension id="-1" isBreathable="true" gravity="normal">
<center x="0" z="0" />
</dimension>
</celestialObject>
</celestialObject>
<!-- Pluto is The End. It's a far planet. -->
<celestialObject group="solarSystem" name="pluto">
<parent>
<center x="90000" z="70000" />
</parent>
<size x="4000" z="4000" />
<dimension id="1" isBreathable="true" gravity="normal">
<center x="0" z="0" />
</dimension>
<render red="1.00" green="1.00" blue="1.00" alpha="1.00" texture="minecraft:textures/blocks/end_stone.png" periodU="150" />
<render red="0.50" green="0.50" blue="0.40" alpha="0.30" />
</celestialObject>
</celestialObject>
</celestialObject>
</worldGeneration>