88import lombok .*;
99import org .apache .commons .math3 .geometry .euclidean .threed .Vector3D ;
1010
11- import java .util .LinkedList ;
12- import java .util .List ;
13- import java .util .Random ;
14- import java .util .UUID ;
11+ import java .util .*;
1512import java .util .concurrent .Executors ;
1613import java .util .concurrent .ScheduledExecutorService ;
1714
@@ -27,7 +24,7 @@ public class Ring {
2724 @ Getter @ Setter private RingData ringData ;
2825 @ Getter @ Setter private LightType lightType ;
2926
30- private final transient List <LaserWrapper > lasers = new LinkedList <>() ;
27+ private final transient LinkedHashMap < Integer , List <LaserWrapper >> lasers ;
3128 private transient double zoomTime = 0 ; // 0 to 1, current zoom time. does nothing if <=0
3229 private transient double rotationTime = 0 ; // current rotation time
3330 @ Getter @ Setter private transient double rotation = 0 ; // 0 to 360, degrees rotation
@@ -46,70 +43,106 @@ public Ring(UUID uniqueId, String name, Location location, RingData ringData, Li
4643 this .location = location ;
4744 this .ringData = ringData ;
4845 this .lightType = lightType ;
46+ lasers = new LinkedHashMap <>();
4947 this .run = () -> {
50- // Do nothing if no need to rotate
51- if (rotationTime > 0 ) {
52- double duration = getRingData ().getRingRotation ();
53- zoomTime = zoomTime - duration /10 ;
54- }
55- if (isZoomed ? zoomTime > 0 : zoomTime < 1 ) {
48+ if (isZoomed ? zoomTime < 1 : zoomTime > 0 ) {
5649 double duration = getRingData ().getRingMovementData ().getDuration ();
5750 zoomTime = isZoomed ?
58- zoomTime - duration >= 0 ? duration / 1000 / (DELAY / 10.0 ) : 1
59- : zoomTime + duration <= 1 ? duration / 1000 / (DELAY / 10.0 ) : 1 ;
51+ zoomTime + duration / 1000 / (DELAY / 10.0 )
52+ : zoomTime - duration / 1000 / (DELAY / 10.0 );
53+ }
54+ zoomTime = zoomTime < 0 && !isZoomed ? 0 : zoomTime ;
55+ zoomTime = zoomTime > 1 && isZoomed ? 1 : zoomTime ;
56+
57+ rotationTime = rotationTime > 45 ? 45 : rotationTime ;
58+ rotationTime = rotationTime < -45 ? -45 : rotationTime ;
59+
60+ if (rotationTime < 0.5 && rotationTime > -0.5 ) {
61+ rotationTime = 0 ;
62+ }
63+ if (rotationTime > 0.5 || rotationTime < -0.5 ) {
64+ rotationTime -= rotationTime /10 ;
65+ } else if (rotationTime < 0.5 && rotationTime > -0.5 ) {
66+ rotationTime += rotationTime /10 ;
6067 }
68+
6169 rotation = rotation + rotationTime ;
6270 rotation = rotation % 360 ;
63- List <Vector3D > ringEdgePoints = getRingData ().calculateRingEdgePoints (this .location .toVector3D (), Math .toRadians (rotation ));
64- for (int i = 0 ; i < lasers .size (); i ++) {
65- LaserWrapper laser = lasers .get (i );
66- Vector3D ringedgePoint = ringEdgePoints .get (i );
67- Vector3D nextRingEdgePoint = ringEdgePoints .get ((i + 1 ) % ringEdgePoints .size ());
68- Vector3D v1 = getRingData ().getRingMovementData ().calculateMovement (zoomTime );
69- laser .setStart (this .location .clone ().add (Location .fromVector3D (ringedgePoint .add (v1 ))));
70- laser .setEnd (this .location .clone ().add (Location .fromVector3D (nextRingEdgePoint .add (v1 ))));
71+ for (int ring = 0 ; ring < this .ringData .getRingCount (); ring ++) {
72+ // a (invisible) "ray" the size of length, pointing towards the set pitch and yaw
73+ Vector3D v = new Vector3D (Math .toRadians (this .location .getYaw ()), Math .toRadians (this .location .getPitch ()))
74+ .normalize ().scalarMultiply ((ring * this .ringData .getRingSpacing ()) / (zoomTime +1 ));
75+
76+ List <Vector3D > ringEdgePoints = RingData .calculateRingEdgePoints (this .location .toVector3D ().add (v ),
77+ Math .toRadians (rotation *(this .ringData .getRingOffset ()+ring )), this .ringData .getRingLightCount (), this .ringData .getRingSize ());
78+
79+ List <LaserWrapper > laserWrappers = lasers .get (ring );
80+
81+ for (int i = 0 ; i < laserWrappers .size (); i ++) {
82+ LaserWrapper laser = laserWrappers .get (i );
83+ Vector3D ringedgePoint = ringEdgePoints .get (i );
84+ Vector3D nextRingEdgePoint = ringEdgePoints .get ((i + 1 ) % ringEdgePoints .size ());
85+ Vector3D v1 = getRingData ().getRingMovementData ().calculateMovement (zoomTime );
86+
87+ laser .setStart (this .location .clone ().add (Location .fromVector3D (ringedgePoint .add (v1 ).add (v ))));
88+ laser .setEnd (this .location .clone ().add (Location .fromVector3D (nextRingEdgePoint .add (v1 ).add (v ))));
89+ }
7190 }
7291 };
7392 }
7493
7594 public void buildLasers () {
76- for (LaserWrapper laser : lasers ) {
77- laser .stop ();
95+ for (List <LaserWrapper > laserWrappers : lasers .values ()) {
96+ for (LaserWrapper laserWrapper : laserWrappers ) {
97+ laserWrapper .stop ();
98+ }
7899 }
79100 lasers .clear ();
80- List <Vector3D > ringEdgePoints = getRingData ().calculateRingEdgePoints (this .location .toVector3D (), Math .toRadians (rotation ));
81- for (int i = 0 ; i < getRingData ().getRingCount (); i ++) {
82- LaserWrapper laser ;
83- Vector3D ringedgePoint = ringEdgePoints .get (i );
84- Vector3D nextRingEdgePoint = ringEdgePoints .get ((i + 1 ) % ringEdgePoints .size ());
85- laser = Nightclub .getLaserFactory ().build (Location .fromVector3D (ringedgePoint ),Location .fromVector3D (nextRingEdgePoint ), -1 , 256 , lightType );
86- lasers .add (laser );
101+ for (int ring = 0 ; ring < this .ringData .getRingCount (); ring ++) {
102+ List <Vector3D > ringEdgePoints = RingData .calculateRingEdgePoints (this .location .toVector3D (),
103+ Math .toRadians (rotation *(ring +1 )), this .ringData .getRingLightCount (), this .ringData .getRingSize ());
104+ List <LaserWrapper > laserWrappers = new LinkedList <>();
105+ for (int i = 0 ; i < ringData .getRingLightCount (); i ++) {
106+ Vector3D ringedgePoint = ringEdgePoints .get (i );
107+ Vector3D nextRingEdgePoint = ringEdgePoints .get ((i + 1 ) % ringEdgePoints .size ());
108+ LaserWrapper laser = Nightclub .getLaserFactory ().build (Location .fromVector3D (ringedgePoint ),Location .fromVector3D (nextRingEdgePoint ), -1 , 256 , lightType );
109+ laserWrappers .add (laser );
110+ }
111+ lasers .put (ring , laserWrappers );
87112 }
88113 }
89114
90115 public void start () {
91116 stop ();
92- for (LaserWrapper laser : lasers ) {
93- laser .start ();
117+ for (List <LaserWrapper > laserWrappers : lasers .values ()) {
118+ for (LaserWrapper laserWrapper : laserWrappers ) {
119+ laserWrapper .start ();
120+ }
94121 }
95122 executorService = Executors .newScheduledThreadPool (1 );
96123 executorService .scheduleAtFixedRate (run , 0 , DELAY , java .util .concurrent .TimeUnit .MILLISECONDS );
97124 }
98125
99126 public void stop () {
100127 executorService .shutdown ();
101- for (LaserWrapper laser : lasers ) {
102- laser .stop ();
128+ for (List <LaserWrapper > laserWrappers : lasers .values ()) {
129+ for (LaserWrapper laserWrapper : laserWrappers ) {
130+ laserWrapper .stop ();
131+ }
103132 }
104133 }
105134
106135 public void spin () {
107136 // Replicates beat sabers ring system which is random, TODO: Implement chroma support of customizable ring direction
108- rotationTime = Math .min (random .nextBoolean () ? rotationTime + Math .sqrt (ringData .getRingRotation ()) : rotationTime - Math .sqrt (ringData .getRingRotation ()),45 );
137+ rotationTime = random .nextBoolean () ? rotationTime + Math .sqrt (ringData .getRingRotation ()) : rotationTime - Math .sqrt (ringData .getRingRotation ());
138+ for (List <LaserWrapper > laserWrappers : lasers .values ()) {
139+ for (LaserWrapper laserWrapper : laserWrappers ) {
140+ laserWrapper .changeColor ();
141+ }
142+ }
109143 }
110144
111145 public void ringZoom () {
112146 isZoomed = !isZoomed ;
113- zoomTime = isZoomed ? 1 : 0 ;
114147 }
115148}
0 commit comments