]> git.lizzy.rs Git - BoundingBoxOutlineReloaded.git/blob - src/main/java/com/irtimaled/bbor/client/models/BoundingBoxLine.java
General performance improvements and serverside fixes
[BoundingBoxOutlineReloaded.git] / src / main / java / com / irtimaled / bbor / client / models / BoundingBoxLine.java
1 package com.irtimaled.bbor.client.models;
2
3 import com.irtimaled.bbor.client.ClientRenderer;
4 import com.irtimaled.bbor.client.RenderCulling;
5 import com.irtimaled.bbor.client.renderers.AbstractRenderer;
6 import com.irtimaled.bbor.client.renderers.LineRenderer;
7 import com.irtimaled.bbor.common.BoundingBoxType;
8 import com.irtimaled.bbor.common.MathHelper;
9 import com.irtimaled.bbor.common.TypeHelper;
10 import com.irtimaled.bbor.common.models.AbstractBoundingBox;
11
12 public class BoundingBoxLine extends AbstractBoundingBox {
13     private static final AbstractRenderer<BoundingBoxLine> RENDERER = ClientRenderer.registerRenderer(BoundingBoxLine.class, () -> new LineRenderer());
14
15     private final Point minPoint;
16     private final Point maxPoint;
17     private final Double width;
18     private final Point[] corners;
19
20     protected BoundingBoxLine(Point minPoint, Point maxPoint, double width, BoundingBoxType type, Point... corners) {
21         super(type);
22         this.minPoint = minPoint;
23         this.maxPoint = maxPoint;
24         this.width = width;
25         this.corners = corners;
26     }
27
28     public static BoundingBoxLine from(Point minPoint, Point maxPoint, Double width, BoundingBoxType type) {
29         if (width == 0) return new BoundingBoxLine(minPoint, maxPoint, width, type);
30
31         double halfWidth = width / 2.0d;
32
33         double dx = maxPoint.getX() - minPoint.getX();
34         double dz = maxPoint.getZ() - minPoint.getZ();
35
36         double dxm = dx == 0 ? 0 : dx / Math.abs(dx);
37         double dzm = dz == 0 ? 0 : dz / Math.abs(dz);
38
39         double xc, zc;
40         if (dxm == 0 || dzm == 0) {
41             xc = Math.abs(dzm) * halfWidth;
42             zc = Math.abs(dxm) * halfWidth;
43         } else {
44             double h = Math.sqrt(dx * dx + dz * dz);
45             double theta = Math.acos((dz * dz + h * h - dx * dx) / (2 * dz * h));
46             zc = halfWidth * Math.sin(theta);
47             xc = Math.sqrt(halfWidth * halfWidth - zc * zc) * dxm * dzm;
48         }
49
50         return new BoundingBoxLine(minPoint, maxPoint, width, type,
51                 new Point(minPoint.getX() + xc, minPoint.getY(), minPoint.getZ() - zc),
52                 new Point(minPoint.getX() - xc, minPoint.getY(), minPoint.getZ() + zc),
53                 new Point(maxPoint.getX() - xc, maxPoint.getY(), maxPoint.getZ() + zc),
54                 new Point(maxPoint.getX() + xc, maxPoint.getY(), maxPoint.getZ() - zc));
55     }
56
57     @Override
58     public int hashCode() {
59         return TypeHelper.combineHashCodes(minPoint.hashCode(), maxPoint.hashCode());
60     }
61
62     @Override
63     public boolean equals(Object obj) {
64         if (this == obj) return true;
65         if (obj == null || getClass() != obj.getClass()) return false;
66         BoundingBoxLine other = (BoundingBoxLine) obj;
67         return minPoint.equals(other.minPoint) && maxPoint.equals(other.maxPoint);
68     }
69
70     public Point getMinPoint() {
71         return minPoint;
72     }
73
74     public Point getMaxPoint() {
75         return maxPoint;
76     }
77
78     public double getWidth() {
79         return width;
80     }
81
82     public Point[] getCorners() {
83         return corners;
84     }
85
86     @Override
87     public Boolean intersectsBounds(int minX, int minZ, int maxX, int maxZ) {
88         boolean minXWithinBounds = isBetween(minPoint.getX(), minX, maxX);
89         boolean maxXWithinBounds = isBetween(maxPoint.getX(), minX, maxX);
90         boolean minZWithinBounds = isBetween(minPoint.getZ(), minZ, maxZ);
91         boolean maxZWithinBounds = isBetween(maxPoint.getZ(), minZ, maxZ);
92
93         return (minXWithinBounds && minZWithinBounds) ||
94                 (maxXWithinBounds && maxZWithinBounds) ||
95                 (minXWithinBounds && maxZWithinBounds) ||
96                 (maxXWithinBounds && minZWithinBounds);
97     }
98
99     @Override
100     protected double getDistanceX(double x) {
101         return x - MathHelper.clamp(x, minPoint.getX(), maxPoint.getX());
102     }
103
104     @Override
105     protected double getDistanceY(double y) {
106         return y - MathHelper.clamp(y, minPoint.getY(), maxPoint.getY());
107     }
108
109     @Override
110     protected double getDistanceZ(double z) {
111         return z - MathHelper.clamp(z, minPoint.getZ(), maxPoint.getZ());
112     }
113
114     private boolean isBetween(double val, int min, int max) {
115         return val >= min && val <= max;
116     }
117
118     @Override
119     public AbstractRenderer<?> getRenderer() {
120         return RENDERER;
121     }
122
123     @Override
124     public boolean isVisibleCulling() {
125         return RenderCulling.isVisibleCulling(minPoint.getX(), minPoint.getY(), minPoint.getZ(), maxPoint.getX(), maxPoint.getY(), maxPoint.getZ()); // TODO better culling
126     }
127 }