2 * Sixth 3D engine. Author: Svjatoslav Agejenko.
3 * This project is released under Creative Commons Zero (CC0) license.
5 package eu.svjatoslav.sixth.e3d.renderer.raster.shapes.basic;
7 import eu.svjatoslav.sixth.e3d.geometry.Point2D;
8 import eu.svjatoslav.sixth.e3d.geometry.Point3D;
9 import eu.svjatoslav.sixth.e3d.gui.RenderingContext;
10 import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.AbstractCoordinateShape;
11 import eu.svjatoslav.sixth.e3d.renderer.raster.texture.Texture;
12 import eu.svjatoslav.sixth.e3d.renderer.raster.texture.TextureBitmap;
14 public class ForwardOrientedTexture extends AbstractCoordinateShape {
16 private static final double SCALE_MULTIPLIER = 0.005;
17 public final Texture texture;
20 * Scale of the texture object.
22 * Object rendered visible size on the screen depends on underlying texture size and scale.
24 * 0 means that object will be infinitely small.
25 * 1 in recommended value to maintain sharpness of the texture as seen by the viewer.
29 public ForwardOrientedTexture(final Point3D point, final double scale,
30 final Texture texture) {
32 this.texture = texture;
37 * Paint the texture on the screen (targetRenderingArea)
39 * @param targetRenderingArea the screen to paint on
42 public void paint(final RenderingContext targetRenderingArea) {
44 // distance from camera/viewer to center of the texture
45 final double z = coordinates[0].transformedCoordinate.z;
47 // compute forward oriented texture visible distance from center
48 final double visibleHorizontalDistanceFromCenter = (targetRenderingArea.width
49 * scale * texture.primaryBitmap.width) / z;
51 final double visibleVerticalDistanceFromCenter = (targetRenderingArea.width
52 * scale * texture.primaryBitmap.height) / z;
54 // compute visible pixel density, and get appropriate bitmap
55 final double zoom = (visibleHorizontalDistanceFromCenter * 2)
56 / texture.primaryBitmap.width;
58 final TextureBitmap textureBitmap = texture.getZoomedBitmap(zoom);
60 final Point2D onScreenCoordinate = coordinates[0].onScreenCoordinate;
63 final int onScreenUncappedYStart = (int) (onScreenCoordinate.y - visibleVerticalDistanceFromCenter);
64 final int onScreenUncappedYEnd = (int) (onScreenCoordinate.y + visibleVerticalDistanceFromCenter);
65 final int onScreenUncappedHeight = onScreenUncappedYEnd - onScreenUncappedYStart;
67 int onScreenCappedYStart = onScreenUncappedYStart;
68 int onScreenCappedYEnd = onScreenUncappedYEnd;
70 // cap Y to upper screen border
71 if (onScreenCappedYStart < 0)
72 onScreenCappedYStart = 0;
74 // cap Y to lower screen border
75 if (onScreenCappedYEnd > targetRenderingArea.height)
76 onScreenCappedYEnd = targetRenderingArea.height;
79 final int onScreenUncappedXStart = (int) (onScreenCoordinate.x - visibleHorizontalDistanceFromCenter);
80 final int onScreenUncappedXEnd = (int) (onScreenCoordinate.x + visibleHorizontalDistanceFromCenter);
81 final int onScreenUncappedWidth = onScreenUncappedXEnd - onScreenUncappedXStart;
83 // cap X to left screen border
84 int onScreenCappedXStart = onScreenUncappedXStart;
85 if (onScreenCappedXStart < 0)
86 onScreenCappedXStart = 0;
88 // cap X to right screen border
89 int onScreenCappedXEnd = onScreenUncappedXEnd;
90 if (onScreenCappedXEnd > targetRenderingArea.width)
91 onScreenCappedXEnd = targetRenderingArea.width;
93 final byte[] targetRenderingAreaBytes = targetRenderingArea.pixels;
95 final int textureWidth = textureBitmap.width;
97 for (int y = onScreenCappedYStart; y < onScreenCappedYEnd; y++) {
99 final int sourceBitmapScanlinePixel = ((textureBitmap.height * (y - onScreenUncappedYStart)) / onScreenUncappedHeight)
102 int targetRenderingAreaOffset = ((y * targetRenderingArea.width) + onScreenCappedXStart) * 4;
104 for (int x = onScreenCappedXStart; x < onScreenCappedXEnd; x++) {
106 final int sourceBitmapPixelAddress = (sourceBitmapScanlinePixel + ((textureWidth * (x - onScreenUncappedXStart)) / onScreenUncappedWidth)) * 4;
108 textureBitmap.drawPixel(sourceBitmapPixelAddress, targetRenderingAreaBytes, targetRenderingAreaOffset);
110 targetRenderingAreaOffset += 4;
116 * Set the scale of the texture
118 * @param scale the scale of the texture
120 public void setScale(final double scale) {
121 this.scale = scale * SCALE_MULTIPLIER;
124 public Point3D getLocation() {
125 return coordinates[0].coordinate;