return this;
}
- public boolean isZero(){
+ public boolean isZero() {
return (x == 0) && (y == 0);
}
package eu.svjatoslav.sixth.e3d.geometry;
-import static java.lang.Math.cos;
-import static java.lang.Math.sin;
-import static java.lang.Math.sqrt;
+import static java.lang.Math.*;
/**
* Used to represent point in a 3D space or vector.
}
@Override
- public boolean isZero(){
+ public boolean isZero() {
return (x == 0) && (y == 0) && (z == 0);
}
* Just in case we want to adjust global speed for some reason.
*/
private static final double SPEED_MULTIPLIER = .02d;
+ /**
+ * Determines amount of friction user experiences every millisecond while moving around in space.
+ */
+ private static final double MILLISECOND_FRICTION = 1.005;
/**
* Avatar movement speed, relative to avatar itself. When avatar coordinates
* are updated within the world, avatar orientation relative to the world is
* Avatar location within the 3D world.
*/
private Point3D location = new Point3D();
-
/**
* Avatar orientation on the X-Z plane. It changes when turning left or
* right.
*/
private double orientationXZ;
-
/**
* Avatar orientation on the Y-Z plane. It changes when looking up or down.
*/
private double orientationYZ;
- /**
- * Determines amount of friction user experiences every millisecond while moving around in space.
- */
- private static final double MILLISECOND_FRICTION = 1.005;
-
public Avatar() {
}
import eu.svjatoslav.sixth.e3d.geometry.Box;
import eu.svjatoslav.sixth.e3d.geometry.Point3D;
-import eu.svjatoslav.sixth.e3d.math.Transform;
import eu.svjatoslav.sixth.e3d.gui.humaninput.MouseInteractionController;
import eu.svjatoslav.sixth.e3d.gui.humaninput.UserInputHandler;
import eu.svjatoslav.sixth.e3d.gui.textEditorComponent.KeyboardHelper;
+import eu.svjatoslav.sixth.e3d.math.Transform;
import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.basic.line.LineAppearance;
import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.base.AbstractCompositeShape;
import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.wireframe.WireframeBox;
public class RenderingContext {
public static final int bufferedImageType = BufferedImage.TYPE_4BYTE_ABGR;
-
- final BufferedImage bufferedImage;
-
public final Graphics2D graphics;
-
public final byte[] pixels;
-
public final int width;
public final int height;
-
public final int xCenter;
public final int yCenter;
-
public final double zoom;
-
+ final BufferedImage bufferedImage;
public int frameNumber = 0;
/**
if (textPointer.row < row)
return 1;
- if (textPointer.column > column)
- return -1;
- if (textPointer.column < column)
- return 1;
+ return Integer.compare(column, textPointer.column);
- return 0;
}
public boolean isBetween(final TextPointer start, final TextPointer end) {
package eu.svjatoslav.sixth.e3d.gui;
-import eu.svjatoslav.sixth.e3d.math.GeometryCoordinate;
import eu.svjatoslav.sixth.e3d.geometry.Point3D;
+import eu.svjatoslav.sixth.e3d.math.GeometryCoordinate;
import eu.svjatoslav.sixth.e3d.math.TransformPipe;
public class UserRelativityTracker {
import java.util.Timer;
public class ViewPanel extends JPanel implements ComponentListener {
+ private static final long serialVersionUID = 1683277888885045387L;
private final UserInputTracker userInputTracker = new UserInputTracker(this);
-
private final KeyboardFocusTracker keyboardFocusTracker = new KeyboardFocusTracker(
this);
-
private final Avatar avatar = new Avatar();
-
private final ShapeCollection rootShapeCollection = new ShapeCollection();
-
-
- public Avatar getAvatar() {
- return avatar;
- }
-
- public KeyboardFocusTracker getKeyboardFocusTracker() {
- return keyboardFocusTracker;
- }
-
- public ShapeCollection getRootShapeCollection() {
- return rootShapeCollection;
- }
-
- public UserInputTracker getUserInputTracker() {
- return userInputTracker;
- }
-
- private static final long serialVersionUID = 1683277888885045387L;
private final List<ViewRenderListener> viewRenderListeners = new ArrayList<>();
/**
* Last time this view was updated.
private Timer canvasUpdateTimer;
private ViewUpdateTimerTask canvasUpdateTimerTask;
private RenderingContext renderingContext = null;
-
/**
* UI component that mouse is currently hovering over.
*/
private MouseInteractionController currentMouseOverComponent;
-
/**
* Currently target FPS for this view. It can be changed at runtime. Also when nothing
* changes in the view, then frames are not really repainted.
*/
private int targetFPS = 30;
-
/**
* Set to true if it is known than next frame reeds to be painted. Flag is cleared
* immediately after frame got updated.
*/
private boolean viewRepaintNeeded = true;
-
public ViewPanel() {
viewRenderListeners.add(avatar);
viewRenderListeners.add(userInputTracker);
addComponentListener(this);
}
+ public Avatar getAvatar() {
+ return avatar;
+ }
+
+ public KeyboardFocusTracker getKeyboardFocusTracker() {
+ return keyboardFocusTracker;
+ }
+
+ public ShapeCollection getRootShapeCollection() {
+ return rootShapeCollection;
+ }
+
+ public UserInputTracker getUserInputTracker() {
+ return userInputTracker;
+ }
+
public void addViewUpdateListener(final ViewRenderListener listener) {
viewRenderListeners.add(listener);
}
* graphics is needed.
*/
public void updateView() {
- if (renderingContext != null){
+ if (renderingContext != null) {
renderingContext.mouseClick = null;
renderingContext.clickedItem = null;
}
/**
* Notifies that it is about time to render next frame and
* allows listener to do any related processing that it needs to.
- *
+ * <p>
* Each {@link ViewRenderListener} will be notified exactly once before every frame is rendered.
- *
+ * <p>
* {@link ViewRenderListener} can determine if frame repaint is actually
* needed from its perspective. Frame will be rendered only if at least one listener says yes.
*
this.value = value;
}
- boolean isEmpty() {
- return value == ' ';
+ boolean hasValue() {
+ return value != ' ';
}
}
package eu.svjatoslav.sixth.e3d.gui.textEditorComponent;
import eu.svjatoslav.sixth.e3d.geometry.Point2D;
-import eu.svjatoslav.sixth.e3d.gui.ViewPanel;
-import eu.svjatoslav.sixth.e3d.math.Transform;
import eu.svjatoslav.sixth.e3d.gui.GuiComponent;
import eu.svjatoslav.sixth.e3d.gui.TextPointer;
+import eu.svjatoslav.sixth.e3d.gui.ViewPanel;
+import eu.svjatoslav.sixth.e3d.math.Transform;
import eu.svjatoslav.sixth.e3d.renderer.raster.Color;
import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.textcanvas.TextCanvas;
}
cursorLocation.column = 0;
- return;
}
}
return 0;
for (int i = 0; i < chars.size(); i++)
- if (!chars.get(i).isEmpty())
+ if (chars.get(i).hasValue())
return i;
throw new RuntimeException("This code shall never execute");
int newLength = 0;
for (int i = chars.size() - 1; i >= 0; i--)
- if (!chars.get(i).isEmpty()) {
+ if (chars.get(i).hasValue()) {
newLength = i + 1;
break;
}
* modify it under the terms of version 3 of the GNU Lesser General Public License
* or later as published by the Free Software Foundation.
*
+ * Realtime voxel renderer (in software).
+ * Uses octree for data compression.
*/
package eu.svjatoslav.sixth.e3d.renderer.octree;
-/**
- * Realtime voxel renderer (in software).
- * Uses octree for data compression.
- */
package eu.svjatoslav.sixth.e3d.renderer.octree.raytracer;
import eu.svjatoslav.sixth.e3d.geometry.Point3D;
-import eu.svjatoslav.sixth.e3d.math.Transform;
import eu.svjatoslav.sixth.e3d.gui.Avatar;
+import eu.svjatoslav.sixth.e3d.math.Transform;
import eu.svjatoslav.sixth.e3d.renderer.raster.Color;
import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.basic.line.LineAppearance;
import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.TexturedRectangle;
texture.resetResampledBitmapCache();
viewPanel.repaintDuringNextViewUpdate();
- // System.out.println("Raytracing done.");
- // System.out.println("New lights computed:" + computedLights);
}
- public int traceLight(final LightSource l, final int cubeX,
- final int cubeY, final int cubeZ) {
- return 0;
- }
-
- public int traceRay(final Ray r) {
+ private int traceRay(final Ray ray) {
- final int re = octreeVolume.traceCell(0, 0, 0,
- octreeVolume.masterCellSize, 0, r);
+ final int intersectingCell = octreeVolume.traceCell(0, 0, 0,
+ octreeVolume.masterCellSize, 0, ray);
- if (re != -1) {
+ if (intersectingCell != -1) {
// if lightening not computed, compute it
- if (octreeVolume.ce3[re] == -1)
+ if (octreeVolume.ce3[intersectingCell] == -1)
// if cell is larger than 1
- if (r.hitCellSize > 1) {
+ if (ray.hitCellSize > 1) {
// break it up
- octreeVolume.breakSolidCell(re);
- return traceRay(r);
+ octreeVolume.breakSolidCell(intersectingCell);
+ return traceRay(ray);
} else {
computedLights++;
float red = 30, green = 30, blue = 30;
for (final LightSource l : lights) {
- final int xDist = (l.x - r.hitCellX);
- final int yDist = (l.y - r.hitCellY);
- final int zDist = (l.z - r.hitCellZ);
+ final int xDist = (l.x - ray.hitCellX);
+ final int yDist = (l.y - ray.hitCellY);
+ final int zDist = (l.z - ray.hitCellZ);
double newRed = 0, newGreen = 0, newBlue = 0;
double tempRed, tempGreen, tempBlue;
+ (yDist * yDist) + (zDist * zDist));
distance = (distance / 3) + 1;
- final Ray r1 = new Ray(r.hitCellX, r.hitCellY
- - (float) 1.5, r.hitCellZ,
+ final Ray r1 = new Ray(ray.hitCellX, ray.hitCellY
+ - (float) 1.5, ray.hitCellZ,
- (float) l.x - (float) r.hitCellX, l.y
- - (r.hitCellY - (float) 1.5), (float) l.z
- - (float) r.hitCellZ);
+ (float) l.x - (float) ray.hitCellX, l.y
+ - (ray.hitCellY - (float) 1.5), (float) l.z
+ - (float) ray.hitCellZ);
final int rt1 = octreeVolume.traceCell(0, 0, 0,
octreeVolume.masterCellSize, 0, r1);
newBlue = (l.color.b * l.brightness) / distance;
}
- final Ray r2 = new Ray(r.hitCellX - (float) 1.5,
- r.hitCellY, r.hitCellZ,
+ final Ray r2 = new Ray(ray.hitCellX - (float) 1.5,
+ ray.hitCellY, ray.hitCellZ,
- l.x - (r.hitCellX - (float) 1.5), (float) l.y
- - (float) r.hitCellY, (float) l.z
- - (float) r.hitCellZ);
+ l.x - (ray.hitCellX - (float) 1.5), (float) l.y
+ - (float) ray.hitCellY, (float) l.z
+ - (float) ray.hitCellZ);
final int rt2 = octreeVolume.traceCell(0, 0, 0,
octreeVolume.masterCellSize, 0, r2);
newBlue = tempBlue;
}
- final Ray r3 = new Ray(r.hitCellX, r.hitCellY,
- r.hitCellZ - (float) 1.5,
+ final Ray r3 = new Ray(ray.hitCellX, ray.hitCellY,
+ ray.hitCellZ - (float) 1.5,
- (float) l.x - (float) r.hitCellX, (float) l.y
- - (float) r.hitCellY, l.z
- - (r.hitCellZ - (float) 1.5));
+ (float) l.x - (float) ray.hitCellX, (float) l.y
+ - (float) ray.hitCellY, l.z
+ - (ray.hitCellZ - (float) 1.5));
final int rt3 = octreeVolume.traceCell(0, 0, 0,
octreeVolume.masterCellSize, 0, r3);
newBlue = tempBlue;
}
- final Ray r4 = new Ray(r.hitCellX, r.hitCellY
- + (float) 1.5, r.hitCellZ,
+ final Ray r4 = new Ray(ray.hitCellX, ray.hitCellY
+ + (float) 1.5, ray.hitCellZ,
- (float) l.x - (float) r.hitCellX, l.y
- - (r.hitCellY + (float) 1.5), (float) l.z
- - (float) r.hitCellZ);
+ (float) l.x - (float) ray.hitCellX, l.y
+ - (ray.hitCellY + (float) 1.5), (float) l.z
+ - (float) ray.hitCellZ);
final int rt4 = octreeVolume.traceCell(0, 0, 0,
octreeVolume.masterCellSize, 0, r4);
newBlue = tempBlue;
}
- final Ray r5 = new Ray(r.hitCellX + (float) 1.5,
- r.hitCellY, r.hitCellZ,
+ final Ray r5 = new Ray(ray.hitCellX + (float) 1.5,
+ ray.hitCellY, ray.hitCellZ,
- l.x - (r.hitCellX + (float) 1.5), (float) l.y
- - (float) r.hitCellY, (float) l.z
- - (float) r.hitCellZ);
+ l.x - (ray.hitCellX + (float) 1.5), (float) l.y
+ - (float) ray.hitCellY, (float) l.z
+ - (float) ray.hitCellZ);
final int rt5 = octreeVolume.traceCell(0, 0, 0,
octreeVolume.masterCellSize, 0, r5);
newBlue = tempBlue;
}
- final Ray r6 = new Ray(r.hitCellX, r.hitCellY,
- r.hitCellZ + (float) 1.5,
+ final Ray r6 = new Ray(ray.hitCellX, ray.hitCellY,
+ ray.hitCellZ + (float) 1.5,
- (float) l.x - (float) r.hitCellX, (float) l.y
- - (float) r.hitCellY, l.z
- - (r.hitCellZ + (float) 1.5));
+ (float) l.x - (float) ray.hitCellX, (float) l.y
+ - (float) ray.hitCellY, l.z
+ - (ray.hitCellZ + (float) 1.5));
final int rt6 = octreeVolume.traceCell(0, 0, 0,
octreeVolume.masterCellSize, 0, r6);
}
- final int cellColor = octreeVolume.ce2[re];
+ final int cellColor = octreeVolume.ce2[intersectingCell];
red = (red * ((cellColor & 0xFF0000) >> 16)) / 255;
green = (green * ((cellColor & 0xFF00) >> 8)) / 255;
if (blue > 255)
blue = 255;
- octreeVolume.ce3[re] = (((int) red) << 16)
+ octreeVolume.ce3[intersectingCell] = (((int) red) << 16)
+ (((int) green) << 8) + ((int) blue);
}
- if (octreeVolume.ce3[re] == 0)
- return octreeVolume.ce2[re];
- return octreeVolume.ce3[re];
+ if (octreeVolume.ce3[intersectingCell] == 0)
+ return octreeVolume.ce2[intersectingCell];
+ return octreeVolume.ce3[intersectingCell];
}
// return (200 << 16) + (200 << 8) + 255;
* modify it under the terms of version 3 of the GNU Lesser General Public License
* or later as published by the Free Software Foundation.
*
+ * Raytracer through voxel data.
*/
package eu.svjatoslav.sixth.e3d.renderer.octree.raytracer;
-/**
- * Raytracer through voxel data.
- */
* modify it under the terms of version 3 of the GNU Lesser General Public License
* or later as published by the Free Software Foundation.
*
+ * Various 3D renderers utilizing different rendering approaches.
*/
package eu.svjatoslav.sixth.e3d.renderer;
-/**
- * Various 3D renderers utilizing different rendering approaches.
- */
* modify it under the terms of version 3 of the GNU Lesser General Public License
* or later as published by the Free Software Foundation.
*
- */
-
-package eu.svjatoslav.sixth.e3d.renderer.raster;
-
-/**
* <pre>
* Realtime renderer (in software) using traditional approaches:
* Wireframe
* Z-Buffer
* </pre>
*/
+
+package eu.svjatoslav.sixth.e3d.renderer.raster;
+
package eu.svjatoslav.sixth.e3d.renderer.raster.shapes;
-import eu.svjatoslav.sixth.e3d.math.GeometryCoordinate;
import eu.svjatoslav.sixth.e3d.geometry.Point3D;
-import eu.svjatoslav.sixth.e3d.math.TransformPipe;
import eu.svjatoslav.sixth.e3d.gui.RenderingContext;
+import eu.svjatoslav.sixth.e3d.math.GeometryCoordinate;
+import eu.svjatoslav.sixth.e3d.math.TransformPipe;
import eu.svjatoslav.sixth.e3d.renderer.raster.RenderAggregator;
import java.util.concurrent.atomic.AtomicInteger;
public static final AtomicInteger lastShapeId = new AtomicInteger();
public final int shapeId;
+ public final GeometryCoordinate[] coordinates;
public double onScreenZ;
- public GeometryCoordinate[] coordinates;
public AbstractCoordinateShape(final int pointsCount) {
coordinates = new GeometryCoordinate[pointsCount];
package eu.svjatoslav.sixth.e3d.renderer.raster.shapes;
-import eu.svjatoslav.sixth.e3d.math.TransformPipe;
import eu.svjatoslav.sixth.e3d.gui.RenderingContext;
import eu.svjatoslav.sixth.e3d.gui.humaninput.MouseInteractionController;
+import eu.svjatoslav.sixth.e3d.math.TransformPipe;
import eu.svjatoslav.sixth.e3d.renderer.raster.RenderAggregator;
public abstract class AbstractShape {
public class ForwardOrientedTexture extends AbstractCoordinateShape {
private static final double SIZE_MULTIPLIER = 0.005;
- public Texture texture;
+ public final Texture texture;
private double scale;
public ForwardOrientedTexture(final Point3D point, final double scale,
public class GlowingPoint extends ForwardOrientedTexture {
private static final int TEXTURE_SIZE = 50;
- private static final Set<GlowingPoint> glowingPoints = Collections.newSetFromMap(new WeakHashMap<GlowingPoint, Boolean>());
+ private static final Set<GlowingPoint> glowingPoints = Collections.newSetFromMap(new WeakHashMap<>());
private final Color color;
public GlowingPoint(final Point3D point, final double pointSize,
if (absoluteHeight > o.absoluteHeight)
return -1;
- if (width < o.width)
- return 1;
- if (width > o.width)
- return -1;
+ return Integer.compare(o.width, width);
- return 0;
}
@Override
import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.base.AbstractCompositeShape;
import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.textcanvas.TextCanvas;
-import java.io.IOException;
import java.util.List;
public class Graph extends AbstractCompositeShape {
private final Color plotColor;
public Graph(final double scale, final List<Point2D> data,
- final String label, final Point3D location) throws IOException {
+ final String label, final Point3D location) {
super(location);
width = 20;
plotColor = new Color(255, 0, 0, 100);
addVerticalLines(scale);
- addXlabels(scale);
+ addXLabels(scale);
addHorizontalLinesAndLabels(scale);
plotData(scale, data);
addShape(labelCanvas);
}
- public void addHorizontalLinesAndLabels(final double scale)
- throws IOException {
+ private void addHorizontalLinesAndLabels(final double scale) {
for (double y = yMin; y <= yMax; y += verticalStep) {
final Point3D p1 = new Point3D(0, y, 0).scaleUp(scale);
}
}
- public void addVerticalLines(final double scale) {
+ private void addVerticalLines(final double scale) {
for (double x = 0; x <= width; x += horizontalStep) {
final Point3D p1 = new Point3D(x, yMin, 0).scaleUp(scale);
}
}
- public void addXlabels(final double scale) throws IOException {
+ private void addXLabels(final double scale) {
for (double x = 0; x <= width; x += horizontalStep * 2) {
final Point3D labelLocation = new Point3D(x, yMin - 0.4, 0)
.scaleUp(scale);
}
}
- public void plotData(final double scale, final List<Point2D> data) {
+ private void plotData(final double scale, final List<Point2D> data) {
Point3D previousPoint = null;
for (final Point2D point : data) {
package eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.base;
import eu.svjatoslav.sixth.e3d.geometry.Point3D;
-import eu.svjatoslav.sixth.e3d.math.Transform;
-import eu.svjatoslav.sixth.e3d.math.TransformPipe;
import eu.svjatoslav.sixth.e3d.gui.RenderingContext;
import eu.svjatoslav.sixth.e3d.gui.UserRelativityTracker;
import eu.svjatoslav.sixth.e3d.gui.humaninput.MouseInteractionController;
+import eu.svjatoslav.sixth.e3d.math.Transform;
+import eu.svjatoslav.sixth.e3d.math.TransformPipe;
import eu.svjatoslav.sixth.e3d.renderer.raster.Color;
import eu.svjatoslav.sixth.e3d.renderer.raster.RenderAggregator;
import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.AbstractShape;
}
public void setGroupForUngrouped(final String groupIdentifier) {
- originalSubShapes.stream().filter(subShape -> subShape.isUngrouped()).forEach(subShape -> subShape.setGroup(groupIdentifier));
+ originalSubShapes.stream().filter(SubShape::isUngrouped).forEach(subShape -> subShape.setGroup(groupIdentifier));
}
@Override
package eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.textcanvas;
import eu.svjatoslav.sixth.e3d.geometry.Point3D;
-import eu.svjatoslav.sixth.e3d.math.Transform;
-import eu.svjatoslav.sixth.e3d.math.TransformPipe;
import eu.svjatoslav.sixth.e3d.gui.RenderingContext;
import eu.svjatoslav.sixth.e3d.gui.TextPointer;
+import eu.svjatoslav.sixth.e3d.math.Transform;
+import eu.svjatoslav.sixth.e3d.math.TransformPipe;
import eu.svjatoslav.sixth.e3d.renderer.raster.Color;
import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.TexturedRectangle;