Changed license to Creative Commons Zero (CC0).
[sixth-3d.git] / src / main / java / eu / svjatoslav / sixth / e3d / renderer / raster / shapes / basic / ForwardOrientedTexture.java
1 /*
2  * Sixth 3D engine. Author: Svjatoslav Agejenko. 
3  * This project is released under Creative Commons Zero (CC0) license.
4  *
5 *
6  */
7
8 package eu.svjatoslav.sixth.e3d.renderer.raster.shapes.basic;
9
10 import eu.svjatoslav.sixth.e3d.geometry.Point2D;
11 import eu.svjatoslav.sixth.e3d.geometry.Point3D;
12 import eu.svjatoslav.sixth.e3d.gui.RenderingContext;
13 import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.AbstractCoordinateShape;
14 import eu.svjatoslav.sixth.e3d.renderer.raster.texture.Texture;
15 import eu.svjatoslav.sixth.e3d.renderer.raster.texture.TextureBitmap;
16
17 public class ForwardOrientedTexture extends AbstractCoordinateShape {
18
19     private static final double SIZE_MULTIPLIER = 0.005;
20     public final Texture texture;
21     private double scale;
22
23     public ForwardOrientedTexture(final Point3D point, final double scale,
24                                   final Texture texture) {
25         super(point);
26         this.texture = texture;
27         setScale(scale);
28     }
29
30     @Override
31     public void paint(final RenderingContext targetRenderingArea) {
32
33         final double z = coordinates[0].transformedCoordinate.z;
34
35         final double visibleHorizontalDistanceFromCenter = (targetRenderingArea.width
36                 * scale * texture.primaryBitmap.width)
37                 / z;
38
39         final double visibleVerticalDistanceFromCenter = (targetRenderingArea.width
40                 * scale * texture.primaryBitmap.height)
41                 / z;
42
43         // compute visible pixel density, and get appropriate bitmap
44         final double zoom = (visibleHorizontalDistanceFromCenter * 2)
45                 / texture.primaryBitmap.width;
46
47         final TextureBitmap textureBitmap = texture.getZoomedBitmap(zoom);
48
49         final Point2D onScreenLocation = coordinates[0].onScreenCoordinate;
50
51         // compute Y
52         final int initialYStart = (int) (onScreenLocation.y - visibleVerticalDistanceFromCenter);
53         final int initialYEnd = (int) (onScreenLocation.y + visibleVerticalDistanceFromCenter);
54         final int maxYDistance = initialYEnd - initialYStart;
55
56         int yStart = initialYStart;
57         int yEnd = initialYEnd;
58
59         if (yStart < 0)
60             yStart = 0;
61
62         if (yEnd > targetRenderingArea.height)
63             yEnd = targetRenderingArea.height;
64
65         // compute X
66         final int initialXStart = (int) (onScreenLocation.x - visibleHorizontalDistanceFromCenter);
67         final int initialXEnd = (int) (onScreenLocation.x + visibleHorizontalDistanceFromCenter);
68         final int maxXDistance = initialXEnd - initialXStart;
69
70         int xStart = initialXStart;
71         int xEnd = initialXEnd;
72
73         if (xStart < 0)
74             xStart = 0;
75
76         if (xEnd > targetRenderingArea.width)
77             xEnd = targetRenderingArea.width;
78
79         final byte[] targetRenderingAreaBytes = targetRenderingArea.pixels;
80
81         final int textureWidth = textureBitmap.width;
82
83         for (int y = yStart; y < yEnd; y++) {
84
85             final int relativeTextureOffset = ((textureBitmap.height * (y - initialYStart)) / maxYDistance)
86                     * textureWidth;
87
88             int targetRenderingAreaOffset = ((y * targetRenderingArea.width) + xStart) * 4;
89
90             for (int x = xStart; x < xEnd; x++) {
91
92                 final int textureOffset = (relativeTextureOffset + ((textureWidth * (x - initialXStart)) / maxXDistance)) * 4;
93
94                 textureBitmap.drawPixel(textureOffset,
95                         targetRenderingAreaBytes, targetRenderingAreaOffset);
96
97                 targetRenderingAreaOffset += 4;
98             }
99         }
100     }
101
102     public void setScale(final double scale) {
103         this.scale = scale * SIZE_MULTIPLIER;
104     }
105
106     public Point3D getLocation() {
107         return coordinates[0].coordinate;
108     }
109
110 }