/// <summary> /// Rotates the face by given angle and returns the interpolated brightness of this face. /// </summary> /// <param name="radX"></param> /// <param name="radY"></param> /// <param name="radZ"></param> /// <param name="BlockSideBrightnessByFacing">Array of brightness values between 0 and 1 per face. In index order (N, E, S, W, U, D)</param> /// <returns></returns> public float GetFaceBrightness(float radX, float radY, float radZ, float[] BlockSideBrightnessByFacing) { float[] matrix = Mat4f.Create(); Mat4f.RotateX(matrix, matrix, radX); Mat4f.RotateY(matrix, matrix, radY); Mat4f.RotateZ(matrix, matrix, radZ); FastVec3f pos = Mat4f.MulWithVec3(matrix, Normalf.X, Normalf.Y, Normalf.Z); float brightness = 0; for (int i = 0; i < ALLFACES.Length; i++) { BlockFacing f = ALLFACES[i]; float angle = (float)Math.Acos(f.Normalf.Dot(pos)); if (angle >= GameMath.PIHALF) { continue; } brightness += (1 - angle / GameMath.PIHALF) * BlockSideBrightnessByFacing[f.Index]; } return(brightness); }
/// <summary> /// Applies a 3d rotation on the face and returns the face thats closest to the rotated face /// </summary> /// <param name="radX"></param> /// <param name="radY"></param> /// <param name="radZ"></param> /// <returns></returns> public BlockFacing FaceWhenRotatedBy(float radX, float radY, float radZ) { float[] matrix = Mat4f.Create(); Mat4f.RotateX(matrix, matrix, radX); Mat4f.RotateY(matrix, matrix, radY); Mat4f.RotateZ(matrix, matrix, radZ); float[] pos = new float[] { Normalf.X, Normalf.Y, Normalf.Z, 1 }; pos = Mat4f.MulWithVec4(matrix, pos); float smallestAngle = GameMath.PI; BlockFacing facing = null; for (int i = 0; i < ALLFACES.Length; i++) { BlockFacing f = ALLFACES[i]; float angle = (float)Math.Acos(f.Normalf.Dot(pos)); if (angle < smallestAngle) { smallestAngle = angle; facing = f; } } return(facing); }
/// <summary> /// Performs a 3-dimensional rotation on the cuboid and returns a new axis-aligned cuboid resulting from this rotation. Not sure it it makes any sense to use this for other rotations than 90 degree intervals. /// </summary> public Cuboidf RotatedCopy(float degX, float degY, float degZ, Vec3d origin) { float radX = degX * GameMath.DEG2RAD; float radY = degY * GameMath.DEG2RAD; float radZ = degZ * GameMath.DEG2RAD; float[] matrix = Mat4f.Create(); Mat4f.RotateX(matrix, matrix, radX); Mat4f.RotateY(matrix, matrix, radY); Mat4f.RotateZ(matrix, matrix, radZ); float[] min = new float[] { X1 - (float)origin.X, Y1 - (float)origin.Y, Z1 - (float)origin.Z, 1 }; float[] max = new float[] { X2 - (float)origin.X, Y2 - (float)origin.Y, Z2 - (float)origin.Z, 1 }; min = Mat4f.MulWithVec4(matrix, min); max = Mat4f.MulWithVec4(matrix, max); float tmp; if (max[0] < min[0]) { tmp = max[0]; max[0] = min[0]; min[0] = tmp; } if (max[1] < min[1]) { tmp = max[1]; max[1] = min[1]; min[1] = tmp; } if (max[2] < min[2]) { tmp = max[2]; max[2] = min[2]; min[2] = tmp; } Cuboidf cube = new Cuboidf() { X1 = min[0] + (float)origin.X, Y1 = min[1] + (float)origin.Y, Z1 = min[2] + (float)origin.Z, X2 = max[0] + (float)origin.X, Y2 = max[1] + (float)origin.Y, Z2 = max[2] + (float)origin.Z }; return(cube); }