use of io.xol.chunkstories.api.world.cell.CellData in project chunkstories by Hugobros3.
the class VoxelOverlays method drawSelectionBox.
public void drawSelectionBox(RenderingInterface renderingInterface, Location location) {
if (vertexBuffer == null)
vertexBuffer = renderingInterface.newVertexBuffer();
int x = (int) (double) location.x();
int y = (int) (double) location.y();
int z = (int) (double) location.z();
CellData peek = location.getWorld().peekSafely(x, y, z);
if (peek.getVoxel() == null || peek.getVoxel().isAir())
return;
CollisionBox[] boxes = peek.getTranslatedCollisionBoxes();
// TODO: getTranslatedCollisionBoxes(voxelContext)
if (boxes == null)
return;
renderingInterface.setCullingMode(CullingMode.DISABLED);
renderingInterface.setBlendMode(BlendMode.MIX);
renderingInterface.setDepthTestMode(DepthTestMode.LESS_OR_EQUAL);
// ShadersLibrary.getShaderProgram("overlay");
Shader overlayProgram = renderingInterface.useShader("overlay");
renderingInterface.getCamera().setupShader(overlayProgram);
overlayProgram.setUniform4f("colorIn", new Vector4f(1.0f, 1.0f, 1.0f, 1.0f));
ByteBuffer data = ByteBuffer.allocateDirect(4 * 3 * 8 * 3 * boxes.length);
data.order(ByteOrder.nativeOrder());
// FloatBuffer fb = data.asFloatBuffer();
// fb.order(ByteOrder.nativeOrder());
// float[] data = new float[3 * 8 * 6 * boxes.length];
int i = 0;
for (CollisionBox box : boxes) {
i = cubeVertices(data, i, (float) box.xpos, (float) box.ypos, (float) box.zpos, (float) box.xw, (float) box.h, (float) box.zw);
}
data.flip();
vertexBuffer.uploadData(data);
renderingInterface.bindAttribute("vertexIn", vertexBuffer.asAttributeSource(VertexFormat.FLOAT, 3));
// renderingContext.bindAttribute("vertexIn", new FloatBufferAttributeSource(data, 3));
renderingInterface.draw(Primitive.LINE, 0, boxes.length * 3 * 8);
renderingInterface.setBlendMode(BlendMode.DISABLED);
// System.out.println("k");
/*
glColor4f(1, 1, 1, 1.0f);
//GL11.glBlendFunc(GL11.GL_ONE_MINUS_SRC_COLOR, GL11.GL_ZERO);
//GL11.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE);
//GL11.glBlendEquation(GL11.);
glBegin(GL_LINES);
VoxelContext bri = new VoxelContextOlder(world, x, y, z);
if (bri.getVoxel() == null)
{
System.out.println(bri.getData());
return;
}
for (CollisionBox box : bri.getVoxel().getTranslatedCollisionBoxes(world, x, y, z))
cubeVertices((float) box.xpos, (float) box.ypos, (float) box.zpos, (float) box.xw, (float) box.h, (float) box.zw);
glEnd();
glColor4f(1, 1, 1, 1);*/
}
use of io.xol.chunkstories.api.world.cell.CellData in project chunkstories by Hugobros3.
the class CustomVoxelModel method renderInto.
public int renderInto(VoxelBakerHighPoly baker, ChunkRenderContext bakingContext, CellData info, Chunk chunk, int x, int y, int z) {
// int lightLevelSun = chunk.getSunLight(x, y, z);
// int lightLevelVoxel = chunk.getBlockLight(x, y, z);
// Obtains the light amount (sun/voxel) for this model
// TODO interpolation w/ neighbors
// float[] lightColors = bakeLightColors(lightLevelVoxel, lightLevelVoxel, lightLevelVoxel, lightLevelVoxel, lightLevelSun, lightLevelSun, lightLevelSun, lightLevelSun);
// We have an array of textures and we jump to the next based on baked offsets and vertice counting
int modelTextureIndex = 0;
VoxelTexture currentVoxelTexture = null;
// Selects an appropriate texture
currentVoxelTexture = selectsTextureFromIndex(info, modelTextureIndex);
baker.usingTexture(currentVoxelTexture);
int maxVertexIndexToUseThisTextureFor = this.texturesOffsets[modelTextureIndex];
// Actual coordinates in the Atlas
// int textureS = currentVoxelTexture.getAtlasS();
// int textureT = currentVoxelTexture.getAtlasT();
// We look the 6 adjacent faces to determine wether or not we should consider them culled
boolean[] cullingCache = new boolean[6];
for (int j = 0; j < 6; j++) {
CellData adj = info.getNeightbor(j);
// If it is, don't draw it.
cullingCache[j] = adj.getVoxel().getDefinition().isOpaque() || adj.getVoxel().isFaceOpaque(VoxelSide.values()[j], adj.getMetaData()) || info.getVoxel().getDefinition().isSelfOpaque() && adj.getVoxel().sameKind(info.getVoxel()) && adj.getMetaData() == info.getMetaData();
}
// Generate some jitter if it is enabled
float dx = 0f, dy = 0f, dz = 0f;
if (this.jitterX != 0.0f)
dx = (float) ((Math.random() * 2.0 - 1.0) * this.jitterX);
if (this.jitterY != 0.0f)
dy = (float) ((Math.random() * 2.0 - 1.0) * this.jitterY);
if (this.jitterZ != 0.0f)
dz = (float) ((Math.random() * 2.0 - 1.0) * this.jitterZ);
// int drewVertices = 0;
drawVertex: for (int i_currentVertex = 0; i_currentVertex < this.vertices.length / 3; i_currentVertex++) {
if (i_currentVertex >= maxVertexIndexToUseThisTextureFor) {
modelTextureIndex++;
// Selects an appropriate texture
currentVoxelTexture = selectsTextureFromIndex(info, modelTextureIndex);
maxVertexIndexToUseThisTextureFor = this.texturesOffsets[modelTextureIndex];
baker.usingTexture(currentVoxelTexture);
// textureS = currentVoxelTexture.getAtlasS();// +mod(sx,texture.textureScale)*offset;
// textureT = currentVoxelTexture.getAtlasT();// +mod(sz,texture.textureScale)*offset;
}
/*
* How culling works :
* culling[][] array contains [vertices.len/3][faces (6)] booleans
* for each triangle (vert/3) it checks for i 0 -> 6 that either ![v][i] or [v][i] && info.neightbours[i] is solid
* if any cull condition fails then it doesn't render this triangle.<
*/
int cullIndex = i_currentVertex / 3;
// boolean drawFace = true;
for (int j = 0; j < 6; j++) {
// Is culling enabled on this face, on this vertex ?
if (this.culling[cullIndex][j]) {
// TODO possible optimization : skip to the next culling spec label
if (cullingCache[j]) {
i_currentVertex += 2;
continue drawVertex;
}
}
}
float vertX = this.vertices[i_currentVertex * 3 + 0];
float vertY = this.vertices[i_currentVertex * 3 + 1];
float vertZ = this.vertices[i_currentVertex * 3 + 2];
baker.beginVertex(vertX + x + dx, vertY + y + dy, vertZ + z + dz);
// renderByteBuffer.addVerticeFloat(vertX + x + dx, vertY + y + dy, vertZ + z + dz);
baker.setTextureCoordinates(this.texCoords[i_currentVertex * 2 + 0], this.texCoords[i_currentVertex * 2 + 1]);
// renderByteBuffer.addTexCoordInt((int) (textureS + this.texCoords[i_currentVertex*2+0] * currentVoxelTexture.getAtlasOffset()), (int) (textureT + this.texCoords[i_currentVertex*2+1] * currentVoxelTexture.getAtlasOffset()));
byte sunLight, blockLight, ao;
sunLight = bakingContext.getCurrentVoxelLighter().getSunlightLevelInterpolated(vertX, vertY, vertZ);
blockLight = bakingContext.getCurrentVoxelLighter().getBlocklightLevelInterpolated(vertX, vertY, vertZ);
ao = bakingContext.getCurrentVoxelLighter().getAoLevelInterpolated(vertX, vertY, vertZ);
baker.setVoxelLight(sunLight, blockLight, ao);
// renderByteBuffer.addColors(sunLight, blockLight, ao);
baker.setNormal(normals[i_currentVertex * 3 + 0], normals[i_currentVertex * 3 + 1], normals[i_currentVertex * 3 + 2]);
baker.setWavyFlag(this.extra[i_currentVertex] != 0);
// renderByteBuffer.addNormalsInt(intifyNormal(this.normals[i_currentVertex*3+0]), intifyNormal(this.normals[i_currentVertex*3+1]), intifyNormal(this.normals[i_currentVertex*3+2]), this.extra[i_currentVertex]);
baker.endVertex();
// drewVertices++;
}
return this.vertices.length;
}
use of io.xol.chunkstories.api.world.cell.CellData in project chunkstories by Hugobros3.
the class DefaultWorldCollisionsManager method raytraceSolid.
private Location raytraceSolid(Vector3dc initialPosition, Vector3dc directionIn, double limit, boolean outer, boolean selectable) {
Vector3d direction = new Vector3d();
directionIn.normalize(direction);
// direction.scale(0.02);
// float distance = 0f;
CellData cell;
// Voxel vox;
int x, y, z;
x = (int) Math.floor(initialPosition.x());
y = (int) Math.floor(initialPosition.y());
z = (int) Math.floor(initialPosition.z());
// DDA algorithm
// It requires double arrays because it works using loops over each dimension
double[] rayOrigin = new double[3];
double[] rayDirection = new double[3];
rayOrigin[0] = initialPosition.x();
rayOrigin[1] = initialPosition.y();
rayOrigin[2] = initialPosition.z();
rayDirection[0] = direction.x();
rayDirection[1] = direction.y();
rayDirection[2] = direction.z();
int[] voxelCoords = new int[] { x, y, z };
int[] voxelDelta = new int[] { 0, 0, 0 };
double[] deltaDist = new double[3];
double[] next = new double[3];
int[] step = new int[3];
int side = 0;
// Prepare distances
for (int i = 0; i < 3; ++i) {
double deltaX = rayDirection[0] / rayDirection[i];
double deltaY = rayDirection[1] / rayDirection[i];
double deltaZ = rayDirection[2] / rayDirection[i];
deltaDist[i] = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ);
if (rayDirection[i] < 0.f) {
step[i] = -1;
next[i] = (rayOrigin[i] - voxelCoords[i]) * deltaDist[i];
} else {
step[i] = 1;
next[i] = (voxelCoords[i] + 1.f - rayOrigin[i]) * deltaDist[i];
}
}
do {
// DDA steps
side = 0;
for (int i = 1; i < 3; ++i) {
if (next[side] > next[i]) {
side = i;
}
}
next[side] += deltaDist[side];
voxelCoords[side] += step[side];
voxelDelta[side] += step[side];
x = voxelCoords[0];
y = voxelCoords[1];
z = voxelCoords[2];
cell = world.peekSafely(x, y, z);
if (cell.getVoxel().getDefinition().isSolid() || (selectable && cell.getVoxel().getDefinition().isSelectable())) {
boolean collides = false;
for (CollisionBox box : cell.getTranslatedCollisionBoxes()) {
// System.out.println(box);
Vector3dc collisionPoint = box.lineIntersection(initialPosition, direction);
if (collisionPoint != null) {
collides = true;
// System.out.println("collides @ "+collisionPoint);
}
}
if (collides) {
if (!outer)
return new Location(world, x, y, z);
else {
// Back off a bit
switch(side) {
case 0:
x -= step[side];
break;
case 1:
y -= step[side];
break;
case 2:
z -= step[side];
break;
}
return new Location(world, x, y, z);
}
}
}
// distance += deltaDist[side];
} while (voxelDelta[0] * voxelDelta[0] + voxelDelta[1] * voxelDelta[1] + voxelDelta[2] * voxelDelta[2] < limit * limit);
return null;
}
use of io.xol.chunkstories.api.world.cell.CellData in project chunkstories-core by Hugobros3.
the class EntityPlayer method onControllerInput.
@Override
public boolean onControllerInput(Input input, Controller controller) {
// We are moving inventory bringup here !
if (input.getName().equals("inventory") && world instanceof WorldClient) {
if (creativeMode.get()) {
((WorldClient) getWorld()).getClient().openInventories(this.inventoryComponent.getInventory(), new InventoryLocalCreativeMenu(world));
} else {
((WorldClient) getWorld()).getClient().openInventories(this.inventoryComponent.getInventory(), this.armor.getInventory());
}
return true;
}
Location blockLocation = this.getBlockLookingAt(true);
double maxLen = 1024;
if (blockLocation != null) {
Vector3d diff = new Vector3d(blockLocation).sub(this.getLocation());
// Vector3d dir = diff.clone().normalize();
maxLen = diff.length();
}
Vector3d initialPosition = new Vector3d(getLocation());
initialPosition.add(new Vector3d(0, eyePosition, 0));
Vector3dc direction = getDirectionLookingAt();
Iterator<Entity> i = world.collisionsManager().rayTraceEntities(initialPosition, direction, maxLen);
while (i.hasNext()) {
Entity e = i.next();
if (e.handleInteraction(this, input))
return true;
}
ItemPile itemSelected = getSelectedItemComponent().getSelectedItem();
if (itemSelected != null) {
// See if the item handles the interaction
if (itemSelected.getItem().onControllerInput(this, itemSelected, input, controller))
return true;
}
if (getWorld() instanceof WorldMaster) {
// Creative mode features building and picking.
if (this.getCreativeModeComponent().get()) {
if (input.getName().equals("mouse.left")) {
if (blockLocation != null) {
// Player events mod
if (controller instanceof Player) {
Player player = (Player) controller;
WorldCell cell = world.peekSafely(blockLocation);
FutureCell future = new FutureCell(cell);
future.setVoxel(this.getDefinition().store().parent().voxels().air());
future.setBlocklight(0);
future.setSunlight(0);
future.setMetaData(0);
PlayerVoxelModificationEvent event = new PlayerVoxelModificationEvent(cell, future, EntityCreative.CREATIVE_MODE, player);
// Anyone has objections ?
world.getGameContext().getPluginManager().fireEvent(event);
if (event.isCancelled())
return true;
Vector3d rnd = new Vector3d();
for (int k = 0; k < 40; k++) {
rnd.set(blockLocation);
rnd.add(Math.random() * 0.98, Math.random() * 0.98, Math.random() * 0.98);
world.getParticlesManager().spawnParticleAtPosition("voxel_frag", rnd);
}
world.getSoundManager().playSoundEffect("sounds/gameplay/voxel_remove.ogg", Mode.NORMAL, blockLocation, 1.0f, 1.0f);
try {
world.poke(future, this);
// world.poke((int)blockLocation.x, (int)blockLocation.y, (int)blockLocation.z, null, 0, 0, 0, this);
} catch (WorldException e) {
// Discard but maybe play some effect ?
}
return true;
}
}
} else if (input.getName().equals("mouse.middle")) {
if (blockLocation != null) {
CellData ctx = this.getWorld().peekSafely(blockLocation);
if (!ctx.getVoxel().isAir()) {
// Spawn new itemPile in his inventory
ItemVoxel item = (ItemVoxel) world.getGameContext().getContent().items().getItemDefinition("item_voxel").newItem();
item.voxel = ctx.getVoxel();
item.voxelMeta = ctx.getMetaData();
ItemPile itemVoxel = new ItemPile(item);
this.getInventory().setItemPileAt(getSelectedItemComponent().getSelectedSlot(), 0, itemVoxel);
return true;
}
}
}
}
}
// Then we check if the world minds being interacted with
return world.handleInteraction(this, blockLocation, input);
}
Aggregations