I am building a minecraft clone and using the jme3 cubes plugin by @destroflyer . I’m implementing a torch block and I have it working just fine if the orientation is standing straight up. See image below. However, I’m trying to now make it so that the torch is rotated at a 45 degree angle and appears attached to it’s neighbor block.
The rotation is what I’m getting stuck on. Since I have to rotate the coordinates before adding to the mesh I don’t have the option of using the Geometry.rotate method. I only have the mesh vertex coordinates. Below is the code and the screenshot of the way it is standing upright. I have tried writing my own rotate method for each of the vertexes using the formula here http://en.wikipedia.org/wiki/Rotation_%28mathematics%29 but the torch is no longer visible when I do that.
Any pointers on math or utilities for doing this would be appreciated. I’m sure the code is in jme3 somewhere because ultimately that must be what it is doing behind the scenes for rotating Spatials.
Here’s the code:
public class BlockShape_Torch extends BlockShape{
public BlockShape_Torch(){
this.extents = new float[]{0.08f, 0.5f, 0.05f, 0.05f, 0.05f, 0.05f};
}
//{top, bottom, left, right, front, back}
private float[] extents;
@Override
public void addTo(BlockChunkControl chunk, Vector3Int blockLocation){
Block block = chunk.getBlock(blockLocation);
Vector3f blockLocation3f = new Vector3f(blockLocation.getX(), blockLocation.getY(), blockLocation.getZ());
Vector3f faceLoc_Bottom_TopLeft = blockLocation3f.add(new Vector3f((0.5f - extents[2]), (0.5f - extents[1]), (0.5f - extents[5])));
Vector3f faceLoc_Bottom_TopRight = blockLocation3f.add(new Vector3f((0.5f + extents[3]), (0.5f - extents[1]), (0.5f - extents[5])));
Vector3f faceLoc_Bottom_BottomLeft = blockLocation3f.add(new Vector3f((0.5f - extents[2]), (0.5f - extents[1]), (0.5f + extents[4])));
Vector3f faceLoc_Bottom_BottomRight = blockLocation3f.add(new Vector3f((0.5f + extents[3]), (0.5f - extents[1]), (0.5f + extents[4])));
Vector3f faceLoc_Top_TopLeft = blockLocation3f.add(new Vector3f((0.5f - extents[2]), (0.5f + extents[0]), (0.5f - extents[5])));
Vector3f faceLoc_Top_TopRight = blockLocation3f.add(new Vector3f((0.5f + extents[3]), (0.5f + extents[0]), (0.5f - extents[5])));
Vector3f faceLoc_Top_BottomLeft = blockLocation3f.add(new Vector3f((0.5f - extents[2]), (0.5f + extents[0]), (0.5f + extents[4])));
Vector3f faceLoc_Top_BottomRight = blockLocation3f.add(new Vector3f((0.5f + extents[3]), (0.5f + extents[0]), (0.5f + extents[4])));
if(shouldFaceBeAdded(chunk, blockLocation, Block.Face.Top)){
addFaceIndices(indices, positions.size());
positions.add(faceLoc_Top_BottomLeft);
positions.add(faceLoc_Top_BottomRight);
positions.add(faceLoc_Top_TopLeft);
positions.add(faceLoc_Top_TopRight);
addSquareNormals(normals, 0, 1, 0);
addTopTextureCoordinates(chunk, textureCoordinates, block.getSkin(chunk, blockLocation, Block.Face.Top).getTextureLocation());
}
if(shouldFaceBeAdded(chunk, blockLocation, Block.Face.Bottom)){
addFaceIndices(indices, positions.size());
positions.add(faceLoc_Bottom_BottomRight);
positions.add(faceLoc_Bottom_BottomLeft);
positions.add(faceLoc_Bottom_TopRight);
positions.add(faceLoc_Bottom_TopLeft);
addSquareNormals(normals, 0, -1, 0);
addTextureCoordinates(chunk, textureCoordinates, block.getSkin(chunk, blockLocation, Block.Face.Bottom).getTextureLocation());
}
if(shouldFaceBeAdded(chunk, blockLocation, Block.Face.Left)){
addFaceIndices(indices, positions.size());
positions.add(faceLoc_Bottom_TopLeft);
positions.add(faceLoc_Bottom_BottomLeft);
positions.add(faceLoc_Top_TopLeft);
positions.add(faceLoc_Top_BottomLeft);
addSquareNormals(normals, -1, 0, 0);
addTextureCoordinates(chunk, textureCoordinates, block.getSkin(chunk, blockLocation, Block.Face.Left).getTextureLocation());
}
if(shouldFaceBeAdded(chunk, blockLocation, Block.Face.Right)){
addFaceIndices(indices, positions.size());
positions.add(faceLoc_Bottom_BottomRight);
positions.add(faceLoc_Bottom_TopRight);
positions.add(faceLoc_Top_BottomRight);
positions.add(faceLoc_Top_TopRight);
addSquareNormals(normals, 1, 0, 0);
addTextureCoordinates(chunk, textureCoordinates, block.getSkin(chunk, blockLocation, Block.Face.Right).getTextureLocation());
}
if(shouldFaceBeAdded(chunk, blockLocation, Block.Face.Front)){
addFaceIndices(indices, positions.size());
positions.add(faceLoc_Bottom_BottomLeft);
positions.add(faceLoc_Bottom_BottomRight);
positions.add(faceLoc_Top_BottomLeft);
positions.add(faceLoc_Top_BottomRight);
addSquareNormals(normals, 0, 0, 1);
addTextureCoordinates(chunk, textureCoordinates,block.getSkin(chunk, blockLocation, Block.Face.Front).getTextureLocation());
}
if(shouldFaceBeAdded(chunk, blockLocation, Block.Face.Back)){
addFaceIndices(indices, positions.size());
positions.add(faceLoc_Bottom_TopRight);
positions.add(faceLoc_Bottom_TopLeft);
positions.add(faceLoc_Top_TopRight);
positions.add(faceLoc_Top_TopLeft);
addSquareNormals(normals, 0, 0, -1);
addTextureCoordinates(chunk, textureCoordinates, block.getSkin(chunk, blockLocation, Block.Face.Back).getTextureLocation());
}
}
private void addFaceIndices(List<Short> indices, int offset){
indices.add((short) (offset + 2));
indices.add((short) (offset + 0));
indices.add((short) (offset + 1));
indices.add((short) (offset + 1));
indices.add((short) (offset + 3));
indices.add((short) (offset + 2));
}
private void addSquareNormals(List<Float> normals, float normalX, float normalY, float normalZ){
for(int i=0;i<4;i++){
normals.add(normalX);
normals.add(normalY);
normals.add(normalZ);
}
}
private void addTextureCoordinates(BlockChunkControl chunk, List<Vector2f> textureCoordinates, BlockSkin_TextureLocation textureLocation){
float xOffset = 14.0f/32.0f;
float topYOffset = 12/32.0f;
Vector2f v1 = getTextureCoordinates(chunk, textureLocation, 0 + xOffset, 0);
textureCoordinates.add(v1);
Vector2f v2 = getTextureCoordinates(chunk, textureLocation, 1 - xOffset, 0);
textureCoordinates.add(v2);
Vector2f v3 = getTextureCoordinates(chunk, textureLocation, 0 + xOffset, 1 - topYOffset);
textureCoordinates.add(v3);
Vector2f v4 = getTextureCoordinates(chunk, textureLocation, 1 - xOffset, 1 - topYOffset);
textureCoordinates.add(v4);
}
private void addTopTextureCoordinates(BlockChunkControl chunk, List<Vector2f> textureCoordinates, BlockSkin_TextureLocation textureLocation){
float xOffset = 14.0f/32.0f;
float topYOffset = 12/32.0f;
float bottomYOffset = 16/32.0f;
Vector2f v1 = getTextureCoordinates(chunk, textureLocation, 0 + xOffset, 0 + bottomYOffset);
textureCoordinates.add(v1);
Vector2f v2 = getTextureCoordinates(chunk, textureLocation, 1 - xOffset, 0 + bottomYOffset);
textureCoordinates.add(v2);
Vector2f v3 = getTextureCoordinates(chunk, textureLocation, 0 + xOffset, 1 - topYOffset);
textureCoordinates.add(v3);
Vector2f v4 = getTextureCoordinates(chunk, textureLocation, 1 - xOffset, 1 - topYOffset);
textureCoordinates.add(v4);
}
@Override
protected boolean canBeMerged(Block.Face face){
boolean isAllowed = true;
Block.Face oppositeFace = BlockNavigator.getOppositeFace(face);
for(int i=0;i<extents.length;i++){
if((i != oppositeFace.ordinal()) && (extents[i] != 0.5f)){
isAllowed = false;
break;
}
}
return isAllowed;
}
}
Here is the screenshot of what the code produces: