@houstonp/rubiks-cube 2.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/README.md +494 -63
  2. package/package.json +22 -12
  3. package/src/core/index.js +478 -0
  4. package/src/rubiksCube/index.js +3 -0
  5. package/src/rubiksCube/rubiksCubeController.js +111 -0
  6. package/src/rubiksCube3D/centerPiece.js +79 -0
  7. package/src/rubiksCube3D/cornerPiece.js +114 -0
  8. package/src/rubiksCube3D/cubeConfig.js +87 -0
  9. package/src/rubiksCube3D/cubeSettings.js +30 -0
  10. package/src/rubiksCube3D/edgePiece.js +51 -0
  11. package/src/rubiksCube3D/index.js +3 -0
  12. package/src/rubiksCube3D/rubiksCube3D.js +383 -0
  13. package/src/rubiksCube3D/sticker.js +38 -0
  14. package/src/state/index.js +4 -0
  15. package/src/state/rubiksCubeState.js +471 -0
  16. package/src/state/slice.js +236 -0
  17. package/src/state/stickerState.js +185 -0
  18. package/src/{cameraState.js → webComponent/cameraState.js} +17 -25
  19. package/src/webComponent/constants.js +67 -0
  20. package/src/{debouncer.js → webComponent/debouncer.js} +1 -1
  21. package/src/webComponent/index.js +7 -0
  22. package/src/webComponent/rubiksCubeElement.js +379 -0
  23. package/src/{settings.js → webComponent/settings.js} +47 -22
  24. package/tests/common.js +10 -0
  25. package/tests/core.test.js +56 -0
  26. package/tests/rubiksCube.solves.test.js +41 -0
  27. package/tests/rubiksCube3D.solves.test.js +185 -0
  28. package/tests/rubiksCubeState.solves.test.js +35 -0
  29. package/tests/setup.js +36 -0
  30. package/tests/testScrambles.js +194 -0
  31. package/types/core/index.d.ts +451 -0
  32. package/types/rubiksCube/index.d.ts +3 -0
  33. package/types/rubiksCube/rubiksCubeController.d.ts +62 -0
  34. package/types/rubiksCube3D/centerPiece.d.ts +27 -0
  35. package/types/rubiksCube3D/cornerPiece.d.ts +38 -0
  36. package/types/rubiksCube3D/cubeConfig.d.ts +32 -0
  37. package/types/rubiksCube3D/cubeSettings.d.ts +33 -0
  38. package/types/rubiksCube3D/edgePiece.d.ts +18 -0
  39. package/types/rubiksCube3D/index.d.ts +3 -0
  40. package/types/rubiksCube3D/rubiksCube3D.d.ts +120 -0
  41. package/types/rubiksCube3D/sticker.d.ts +18 -0
  42. package/types/state/index.d.ts +5 -0
  43. package/types/state/rubiksCubeState.d.ts +108 -0
  44. package/types/state/slice.d.ts +46 -0
  45. package/types/state/stickerState.d.ts +34 -0
  46. package/types/webComponent/cameraState.d.ts +22 -0
  47. package/types/webComponent/constants.d.ts +57 -0
  48. package/types/webComponent/index.d.ts +6 -0
  49. package/types/webComponent/rubiksCubeElement.d.ts +89 -0
  50. package/types/{settings.d.ts → webComponent/settings.d.ts} +9 -8
  51. package/src/core.js +0 -127
  52. package/src/cube/cube.js +0 -324
  53. package/src/cube/cubeRotation.js +0 -79
  54. package/src/cube/cubeSettings.js +0 -18
  55. package/src/cube/cubeState.js +0 -192
  56. package/src/cube/slice.js +0 -143
  57. package/src/index.js +0 -496
  58. package/src/schema.js +0 -22
  59. package/src/threejs/materials.js +0 -54
  60. package/src/threejs/pieces.js +0 -100
  61. package/src/threejs/stickers.js +0 -40
  62. package/types/cameraState.d.ts +0 -19
  63. package/types/core.d.ts +0 -125
  64. package/types/cube/cube.d.ts +0 -102
  65. package/types/cube/cubeRotation.d.ts +0 -33
  66. package/types/cube/cubeSettings.d.ts +0 -17
  67. package/types/cube/cubeState.d.ts +0 -16
  68. package/types/cube/slice.d.ts +0 -15
  69. package/types/index.d.ts +0 -65
  70. package/types/schema.d.ts +0 -11
  71. package/types/threejs/materials.d.ts +0 -21
  72. package/types/threejs/pieces.d.ts +0 -28
  73. package/types/threejs/stickers.d.ts +0 -6
  74. /package/src/{globals.ts → webComponent/globals.ts} +0 -0
  75. /package/types/{debouncer.d.ts → webComponent/debouncer.d.ts} +0 -0
  76. /package/types/{globals.d.ts → webComponent/globals.d.ts} +0 -0
package/src/cube/cube.js DELETED
@@ -1,324 +0,0 @@
1
- // @ts-check
2
- import { Group, Material, Mesh, Object3D, Vector3 } from 'three';
3
- import { createCoreMesh } from '../threejs/pieces';
4
- import { createCubeState } from './cubeState';
5
- import { CubeRotation } from './cubeRotation';
6
- import CubeSettings from './cubeSettings';
7
- import GetMovementSlice, { GetRotationSlice } from './slice';
8
- import { Axi } from '../core';
9
-
10
- /** @typedef {{ up: import('../core').Face[][], down: import('../core').Face[][], front: import('../core').Face[][], back: import('../core').Face[][], left: import('../core').Face[][], right: import('../core').Face[][] }} StickerState*/
11
- export default class Cube {
12
- /**
13
- * @param {CubeSettings} cubeSettings
14
- */
15
- constructor(cubeSettings) {
16
- /** @type {CubeSettings} */
17
- this.cubeSettings = cubeSettings;
18
- /** @type {Group} */
19
- this.group = new Group();
20
- /** @type {Group} */
21
- this.rotationGroup = new Group();
22
- /** @type {CubeRotation[]} */
23
- this.rotationQueue = [];
24
- /** @type {CubeRotation | undefined} */
25
- this.currentRotation = undefined;
26
-
27
- /** @type {number | undefined} */
28
- this._matchSpeed = undefined;
29
- /** @type {number} */
30
- this._lastGap = cubeSettings.pieceGap;
31
-
32
- // initialise threejs Objects
33
- this.init();
34
-
35
- /** @type {StickerState} */
36
- this.currentState = this.getStickerState();
37
- }
38
-
39
- /**
40
- * adds threejs objects to group
41
- */
42
- init() {
43
- const core = createCoreMesh();
44
- core.userData = {
45
- position: { x: 0, y: 0, z: 0 },
46
- rotation: { x: 0, y: 0, z: 0 },
47
- initialPosition: { x: 0, y: 0, z: 0 },
48
- initialRotation: { x: 0, y: 0, z: 0 },
49
- type: 'core',
50
- };
51
- this.group.add(core);
52
-
53
- for (const piece of createCubeState()) {
54
- var pieceGroup = piece.group;
55
- pieceGroup.position.set(
56
- piece.position.x * this.cubeSettings.pieceGap,
57
- piece.position.y * this.cubeSettings.pieceGap,
58
- piece.position.z * this.cubeSettings.pieceGap,
59
- );
60
- pieceGroup.rotation.set(piece.rotation.x, piece.rotation.y, piece.rotation.z);
61
- pieceGroup.userData = {
62
- position: Object.assign({}, piece.position),
63
- rotation: Object.assign({}, piece.rotation),
64
- initialPosition: Object.assign({}, piece.position),
65
- initialRotation: Object.assign({}, piece.rotation),
66
- type: piece.type,
67
- };
68
- this.group.add(pieceGroup);
69
- }
70
- return this.group;
71
- }
72
-
73
- /**
74
- * update the cube and continue any rotations
75
- */
76
- update() {
77
- if (this.currentRotation === undefined) {
78
- if (this._lastGap !== this.cubeSettings.pieceGap) {
79
- this.updateGap();
80
- }
81
- this.currentRotation = this.rotationQueue.shift();
82
- if (this.currentRotation === undefined) {
83
- this._matchSpeed = undefined; // reset speed for the match animation options
84
- return;
85
- }
86
- }
87
- if (this.currentRotation.status === 'pending') {
88
- this.rotationGroup.add(...this.getRotationLayer(this.currentRotation.slice));
89
- this.currentRotation.initialise();
90
- }
91
- if (this.currentRotation.status === 'initialised' || this.currentRotation.status === 'inProgress') {
92
- var speed = this.getRotationSpeed();
93
- this.currentRotation.update(this.rotationGroup, speed);
94
- }
95
- if (this.currentRotation.status === 'complete') {
96
- this.clearRotationGroup();
97
- this.currentState = this.getStickerState();
98
- this.currentRotation.completedCallback(this.kociembaState);
99
- this.currentRotation = undefined;
100
- }
101
- return;
102
- }
103
-
104
- /**
105
- * Updates the gap of the pieces. To be used when the cube is not rotating
106
- * @returns {void}
107
- */
108
- updateGap() {
109
- if (this.currentRotation === undefined) {
110
- this.group.children.forEach((piece) => {
111
- var { x, y, z } = piece.userData.position;
112
- piece.position.set(x * this.cubeSettings.pieceGap, y * this.cubeSettings.pieceGap, z * this.cubeSettings.pieceGap);
113
- });
114
- this._lastGap = this.cubeSettings.pieceGap;
115
- }
116
- }
117
-
118
- /**
119
- *
120
- * calculates the current speed of the current rotation in ms.
121
- * calculation is dependent on animation style and animation speed settings
122
- * - exponential: speeds up rotations depending on the queue length
123
- * - next: an animation speed of 0 when there is another animation in the queue
124
- * - match: will match the speed of rotations to the frequency of key presses.
125
- * - fixed: will return a constant value
126
- * @returns {number}
127
- */
128
- getRotationSpeed() {
129
- if (this.cubeSettings.animationStyle === 'exponential') {
130
- return this.cubeSettings.animationSpeedMs / 2 ** this.rotationQueue.length;
131
- }
132
- if (this.cubeSettings.animationStyle === 'next') {
133
- return this.rotationQueue.length > 0 ? 0 : this.cubeSettings.animationSpeedMs;
134
- }
135
- if (this.cubeSettings.animationStyle === 'match') {
136
- if (this.rotationQueue.length > 0) {
137
- const rotation = /** @type {CubeRotation} */ (this.currentRotation);
138
- const lastTimeStamp = rotation.timestampMs;
139
- let minGap = this._matchSpeed ?? this.cubeSettings.animationSpeedMs;
140
- for (var i = 0; i < this.rotationQueue.length; i++) {
141
- var gap = this.rotationQueue[i].timestampMs - lastTimeStamp;
142
- if (gap < minGap) {
143
- minGap = gap;
144
- }
145
- }
146
- this._matchSpeed = minGap;
147
- }
148
- if (this._matchSpeed !== undefined) {
149
- return this._matchSpeed;
150
- }
151
- return this.cubeSettings.animationSpeedMs;
152
- }
153
- if (this.cubeSettings.animationStyle === 'fixed') {
154
- return this.cubeSettings.animationSpeedMs;
155
- }
156
- return this.cubeSettings.animationSpeedMs;
157
- }
158
-
159
- /**
160
- * Complete the current rotation and reset the cube
161
- * @param {(state:string) => boolean} completedCallback
162
- * @returns {void}
163
- */
164
- reset(completedCallback) {
165
- this.rotationQueue.forEach((cubeRotation) => cubeRotation.failedCallback('State reset during action'));
166
- this.rotationQueue = [];
167
- if (this.currentRotation) {
168
- this.currentRotation.update(this.rotationGroup, 0);
169
- this.clearRotationGroup();
170
- this.currentRotation.failedCallback('State reset during action');
171
- this.currentRotation = undefined;
172
- }
173
- this.group.children.forEach((piece) => {
174
- const { x, y, z } = piece.userData.initialPosition;
175
- const { x: u, y: v, z: w } = piece.userData.initialRotation;
176
- piece.position.set(x * this.cubeSettings.pieceGap, y * this.cubeSettings.pieceGap, z * this.cubeSettings.pieceGap);
177
- piece.rotation.set(u, v, w);
178
- piece.userData.position.x = x;
179
- piece.userData.position.y = y;
180
- piece.userData.position.z = z;
181
- piece.userData.rotation.x = u;
182
- piece.userData.rotation.y = v;
183
- piece.userData.rotation.z = w;
184
- });
185
-
186
- this.currentState = this.getStickerState();
187
- if (!completedCallback(this.kociembaState)) {
188
- console.error('Failed to invoke reset completedCallback');
189
- }
190
- }
191
-
192
- /**
193
- * Adds pieces in the rotationGroup back into the main group.
194
- * @returns {void}
195
- */
196
- clearRotationGroup() {
197
- if (this.currentRotation == null) {
198
- console.error('cannot clear rotation when rotation is null');
199
- return;
200
- }
201
- if (this.currentRotation.status != 'complete') {
202
- console.error('cannot clear rotation group while rotating');
203
- return;
204
- }
205
- this.rotationGroup.children.forEach((piece) => {
206
- piece.getWorldPosition(piece.position);
207
- piece.getWorldQuaternion(piece.quaternion);
208
- var x = Math.round(piece.position.x);
209
- var y = Math.round(piece.position.y);
210
- var z = Math.round(piece.position.z);
211
- piece.userData.position.x = Math.abs(x) > 1 ? Math.sign(x) : x;
212
- piece.userData.position.y = Math.abs(y) > 1 ? Math.sign(y) : y;
213
- piece.userData.position.z = Math.abs(z) > 1 ? Math.sign(z) : z;
214
- piece.userData.rotation.x = piece.rotation.x;
215
- piece.userData.rotation.y = piece.rotation.y;
216
- piece.userData.rotation.z = piece.rotation.z;
217
- });
218
- this.group.add(...this.rotationGroup.children);
219
- this.rotationGroup.rotation.set(0, 0, 0);
220
- this.currentRotation.status = 'disposed';
221
- }
222
-
223
- /**
224
- * @param {string} eventId
225
- * @param {import('../core').Rotation} rotation
226
- * @param {((state: string) => void )} completedCallback
227
- * @param {((reason: string) => void )} failedCallback
228
- */
229
- rotation(eventId, rotation, completedCallback, failedCallback) {
230
- const slice = GetRotationSlice(rotation);
231
- this.rotationQueue.push(new CubeRotation(eventId, slice, completedCallback, failedCallback));
232
- }
233
-
234
- /**
235
- * @param {string} eventId
236
- * @param {import('../core').Movement} movement
237
- * @param {((state: string) => void )} completedCallback
238
- * @param {((reason: string) => void )} failedCallback
239
- */
240
- movement(eventId, movement, completedCallback, failedCallback) {
241
- const slice = GetMovementSlice(movement);
242
- this.rotationQueue.push(new CubeRotation(eventId, slice, completedCallback, failedCallback));
243
- }
244
-
245
- /**
246
- * @param {import('./slice').Slice} slice
247
- * @returns {Object3D[]}
248
- */
249
- getRotationLayer(slice) {
250
- if (slice.layers.length === 0) {
251
- return [...this.group.children];
252
- }
253
- return this.group.children.filter((piece) => {
254
- if (slice.axis === Axi.x) {
255
- const roundedPos = /** @type {(-1|0|1)} */ (Math.round(piece.userData.position.x));
256
- return slice.layers.includes(roundedPos);
257
- } else if (slice.axis === Axi.y) {
258
- const roundedPos = /** @type {(-1|0|1)} */ (Math.round(piece.userData.position.y));
259
- return slice.layers.includes(roundedPos);
260
- } else if (slice.axis === Axi.z) {
261
- const roundedPos = /** @type {(-1|0|1)} */ (Math.round(piece.userData.position.z));
262
- return slice.layers.includes(roundedPos);
263
- }
264
- return false;
265
- });
266
- }
267
-
268
- /**
269
- * @returns {string}
270
- */
271
- get kociembaState() {
272
- return this.toKociemba(this.currentState);
273
- }
274
-
275
- /**
276
- * @param {StickerState} stickerState
277
- * @returns {string}
278
- */
279
- toKociemba(stickerState) {
280
- return `${stickerState.up.flat().join('')}${stickerState.right.flat().join('')}${stickerState.front.flat().join('')}${stickerState.down.flat().join('')}${stickerState.left.flat().join('')}${stickerState.back.flat().join('')}`;
281
- }
282
-
283
- /**
284
- * @returns {StickerState}
285
- */
286
- getStickerState() {
287
- /** @type {StickerState} */
288
- let state = { up: [[], [], []], down: [[], [], []], front: [[], [], []], back: [[], [], []], left: [[], [], []], right: [[], [], []] };
289
- this.group.children.forEach((piece) => {
290
- if (piece.userData.type === 'core') {
291
- return;
292
- }
293
- piece.children.forEach((object3D) => {
294
- if (object3D.userData.type === 'sticker') {
295
- const mesh = /** @type {Mesh} */ (object3D);
296
- const piecepos = new Vector3();
297
- piecepos.copy(piece.userData.position);
298
- piecepos.round();
299
- const stickerpos = new Vector3();
300
- mesh.getWorldPosition(stickerpos);
301
- stickerpos.sub(piecepos);
302
- stickerpos.multiplyScalar(2);
303
- stickerpos.round();
304
- const material = /** @type {Material} */ (mesh.material);
305
- const materialUserData = /** @type {import('../threejs/materials').StickerUserData} */ (material.userData);
306
- if (stickerpos.x === 1) {
307
- state.right[1 - Math.round(piecepos.y)][1 - Math.round(piecepos.z)] = materialUserData.face;
308
- } else if (stickerpos.x === -1) {
309
- state.left[1 - Math.round(piecepos.y)][1 + Math.round(piecepos.z)] = materialUserData.face;
310
- } else if (stickerpos.y === 1) {
311
- state.up[1 + Math.round(piecepos.z)][1 + Math.round(piecepos.x)] = materialUserData.face;
312
- } else if (stickerpos.y === -1) {
313
- state.down[1 - Math.round(piecepos.z)][1 + Math.round(piecepos.x)] = materialUserData.face;
314
- } else if (stickerpos.z === 1) {
315
- state.front[1 - Math.round(piecepos.y)][1 + Math.round(piecepos.x)] = materialUserData.face;
316
- } else if (stickerpos.z === -1) {
317
- state.back[1 - Math.round(piecepos.y)][1 - Math.round(piecepos.x)] = materialUserData.face;
318
- }
319
- }
320
- });
321
- });
322
- return state;
323
- }
324
- }
@@ -1,79 +0,0 @@
1
- // @ts-check
2
- import { Vector3, Group } from 'three';
3
-
4
- export class CubeRotation {
5
- /**
6
- * @param {string} eventId
7
- * @param {import('./slice').Slice} slice
8
- * @param {((state: string) => void )} completedCallback
9
- * @param {((reason: string) => void )} failedCallback
10
- */
11
- constructor(eventId, slice, completedCallback, failedCallback) {
12
- /** @type {((state: string) => void )} */
13
- this.completedCallback = completedCallback;
14
- /** @type {((reason: string) => void )} */
15
- this.failedCallback = failedCallback;
16
- /** @type {string} */
17
- this.eventId = eventId;
18
- /** @type {import('./slice').Slice} */
19
- this.slice = slice;
20
- /** @type {"pending" | "initialised" | "inProgress" | "complete" | "disposed"} */
21
- this.status = 'pending';
22
- /** @type {number} */
23
- this.timestampMs = performance.now();
24
- /** @type {number | undefined} */
25
- this._lastUpdatedTimeMs = undefined;
26
- /** @type {number} */
27
- this._rotationPercentage = 0;
28
- }
29
-
30
- initialise() {
31
- this._lastUpdatedTimeMs = performance.now();
32
- this.status = 'initialised';
33
- }
34
-
35
- /**
36
- *
37
- * @param {Group} rotationGroup
38
- * @param {number} speedMs
39
- */
40
- update(rotationGroup, speedMs) {
41
- if (this.status === 'initialised') {
42
- this.status = 'inProgress';
43
- }
44
-
45
- if (this.status !== 'inProgress' || this._lastUpdatedTimeMs == null) {
46
- console.error(`Cannot update cubeRotation. Status - [${this.status}]. LastUpdated - [${this._lastUpdatedTimeMs}].`);
47
- return;
48
- }
49
-
50
- var intervalMs = performance.now() - this._lastUpdatedTimeMs;
51
- this._lastUpdatedTimeMs = performance.now();
52
-
53
- var increment = 100 - this._rotationPercentage;
54
- if (speedMs != 0) {
55
- var potentialIncrement = (intervalMs / speedMs) * 100;
56
- if (potentialIncrement + this._rotationPercentage < 100) {
57
- increment = potentialIncrement;
58
- }
59
- }
60
- const rotationIncrement = (Math.abs(this.slice.direction) * ((increment / 100) * Math.PI)) / 2;
61
- this._rotationPercentage += increment;
62
- rotationGroup.rotateOnWorldAxis(
63
- new Vector3(
64
- this.slice.axis === 'x' ? this.slice.direction : 0,
65
- this.slice.axis === 'y' ? this.slice.direction : 0,
66
- this.slice.axis === 'z' ? this.slice.direction : 0,
67
- ).normalize(),
68
- rotationIncrement,
69
- );
70
-
71
- if (this._rotationPercentage === 100) {
72
- this.status = 'complete';
73
- }
74
-
75
- if (this._rotationPercentage > 100) {
76
- throw new Error('rotation percentage > 100');
77
- }
78
- }
79
- }
@@ -1,18 +0,0 @@
1
- // @ts-check
2
- /** @typedef {"exponential" | "next" | "fixed" | "match"} AnimationStyle */
3
- export default class CubeSettings {
4
- /**
5
- *
6
- * @param {number} pieceGap
7
- * @param {number} animationSpeed
8
- * @param {AnimationStyle} animationStyle
9
- */
10
- constructor(pieceGap, animationSpeed, animationStyle) {
11
- /** @type {number} pieceGap */
12
- this.pieceGap = pieceGap;
13
- /** @type {number} pieceGap */
14
- this.animationSpeedMs = animationSpeed;
15
- /** @type {AnimationStyle} pieceGap */
16
- this.animationStyle = animationStyle;
17
- }
18
- }
@@ -1,192 +0,0 @@
1
- // @ts-check
2
- import { Group } from 'three';
3
- import Materials from '../threejs/materials';
4
- import { createCornerGroup, createEdgeGroup, createCenterGroup } from '../threejs/pieces';
5
-
6
- /**
7
- * @typedef {{x: number,y: number,z: number}} vector
8
- */
9
-
10
- /**
11
- * @typedef {{position: vector, rotation: vector, type: "corner" | "edge" | "center", group: Group}} state
12
- */
13
-
14
- /**
15
- * @return {state[]}
16
- */
17
- const corners = () => [
18
- {
19
- position: { x: 1, y: 1, z: 1 },
20
- rotation: { x: 0, y: 0, z: 0 },
21
- type: 'corner',
22
- group: createCornerGroup(Materials.front, Materials.right, Materials.up, Materials.core),
23
- },
24
- {
25
- position: { x: 1, y: 1, z: -1 },
26
- rotation: { x: 0, y: Math.PI / 2, z: 0 },
27
- type: 'corner',
28
- group: createCornerGroup(Materials.right, Materials.back, Materials.up, Materials.core),
29
- },
30
- {
31
- position: { x: 1, y: -1, z: 1 },
32
- rotation: { x: 0, y: Math.PI / 2, z: Math.PI },
33
- type: 'corner',
34
- group: createCornerGroup(Materials.right, Materials.front, Materials.down, Materials.core),
35
- },
36
- {
37
- position: { x: 1, y: -1, z: -1 },
38
- rotation: { x: 0, y: Math.PI, z: Math.PI },
39
- type: 'corner',
40
- group: createCornerGroup(Materials.back, Materials.right, Materials.down, Materials.core),
41
- },
42
- {
43
- position: { x: -1, y: 1, z: 1 },
44
- rotation: { x: 0, y: -Math.PI / 2, z: 0 },
45
- type: 'corner',
46
- group: createCornerGroup(Materials.left, Materials.front, Materials.up, Materials.core),
47
- },
48
- {
49
- position: { x: -1, y: 1, z: -1 },
50
- rotation: { x: 0, y: Math.PI, z: 0 },
51
- type: 'corner',
52
- group: createCornerGroup(Materials.back, Materials.left, Materials.up, Materials.core),
53
- },
54
- {
55
- position: { x: -1, y: -1, z: 1 },
56
- rotation: { x: 0, y: 0, z: Math.PI },
57
- type: 'corner',
58
- group: createCornerGroup(Materials.front, Materials.left, Materials.down, Materials.core),
59
- },
60
- {
61
- position: { x: -1, y: -1, z: -1 },
62
- rotation: { x: 0, y: -Math.PI / 2, z: Math.PI },
63
- type: 'corner',
64
- group: createCornerGroup(Materials.left, Materials.back, Materials.down, Materials.core),
65
- },
66
- ];
67
-
68
- /**
69
- * @return {state[]}
70
- */
71
- const edges = () => [
72
- {
73
- position: { x: 1, y: 1, z: 0 },
74
- rotation: { x: 0, y: Math.PI / 2, z: 0 },
75
- type: 'edge',
76
- group: createEdgeGroup(Materials.right, Materials.up, Materials.core),
77
- },
78
- {
79
- position: { x: 1, y: 0, z: 1 },
80
- rotation: { x: 0, y: 0, z: -Math.PI / 2 },
81
- type: 'edge',
82
- group: createEdgeGroup(Materials.front, Materials.right, Materials.core),
83
- },
84
- {
85
- position: { x: 1, y: 0, z: -1 },
86
- rotation: { x: 0, y: Math.PI / 2, z: -Math.PI / 2 },
87
- type: 'edge',
88
- group: createEdgeGroup(Materials.right, Materials.back, Materials.core),
89
- },
90
- {
91
- position: { x: 1, y: -1, z: 0 },
92
- rotation: { x: Math.PI, y: Math.PI / 2, z: 0 },
93
- type: 'edge',
94
- group: createEdgeGroup(Materials.right, Materials.down, Materials.core),
95
- },
96
- {
97
- position: { x: 0, y: 1, z: 1 },
98
- rotation: { x: 0, y: 0, z: 0 },
99
- type: 'edge',
100
- group: createEdgeGroup(Materials.front, Materials.up, Materials.core),
101
- },
102
- {
103
- position: { x: 0, y: 1, z: -1 },
104
- rotation: { x: -Math.PI / 2, y: 0, z: 0 },
105
- type: 'edge',
106
- group: createEdgeGroup(Materials.up, Materials.back, Materials.core),
107
- },
108
- {
109
- position: { x: 0, y: -1, z: 1 },
110
- rotation: { x: Math.PI / 2, y: 0, z: 0 },
111
- type: 'edge',
112
- group: createEdgeGroup(Materials.down, Materials.front, Materials.core),
113
- },
114
- {
115
- position: { x: 0, y: -1, z: -1 },
116
- rotation: { x: Math.PI, y: 0, z: 0 },
117
- type: 'edge',
118
- group: createEdgeGroup(Materials.back, Materials.down, Materials.core),
119
- },
120
- {
121
- position: { x: -1, y: 1, z: 0 },
122
- rotation: { x: 0, y: -Math.PI / 2, z: 0 },
123
- type: 'edge',
124
- group: createEdgeGroup(Materials.left, Materials.up, Materials.core),
125
- },
126
- {
127
- position: { x: -1, y: 0, z: 1 },
128
- rotation: { x: 0, y: 0, z: Math.PI / 2 },
129
- type: 'edge',
130
- group: createEdgeGroup(Materials.front, Materials.left, Materials.core),
131
- },
132
- {
133
- position: { x: -1, y: 0, z: -1 },
134
- rotation: { x: 0, y: -Math.PI / 2, z: Math.PI / 2 },
135
- type: 'edge',
136
- group: createEdgeGroup(Materials.left, Materials.back, Materials.core),
137
- },
138
- {
139
- position: { x: -1, y: -1, z: 0 },
140
- rotation: { x: 0, y: -Math.PI / 2, z: Math.PI },
141
- type: 'edge',
142
- group: createEdgeGroup(Materials.left, Materials.down, Materials.core),
143
- },
144
- ];
145
-
146
- /**
147
- * @return {state[]}
148
- */
149
- const centers = () => [
150
- {
151
- position: { x: 1, y: 0, z: 0 },
152
- rotation: { x: 0, y: Math.PI / 2, z: 0 },
153
- type: 'center',
154
- group: createCenterGroup(Materials.right, Materials.core),
155
- },
156
- {
157
- position: { x: 0, y: 1, z: 0 },
158
- rotation: { x: -Math.PI / 2, y: 0, z: 0 },
159
- type: 'center',
160
- group: createCenterGroup(Materials.up, Materials.core),
161
- },
162
- {
163
- position: { x: 0, y: 0, z: 1 },
164
- rotation: { x: 0, y: 0, z: 0 },
165
- type: 'center',
166
- group: createCenterGroup(Materials.front, Materials.core),
167
- },
168
- {
169
- position: { x: 0, y: 0, z: -1 },
170
- rotation: { x: 0, y: Math.PI, z: 0 },
171
- type: 'center',
172
- group: createCenterGroup(Materials.back, Materials.core),
173
- },
174
- {
175
- position: { x: 0, y: -1, z: 0 },
176
- rotation: { x: Math.PI / 2, y: 0, z: 0 },
177
- type: 'center',
178
- group: createCenterGroup(Materials.down, Materials.core),
179
- },
180
- {
181
- position: { x: -1, y: 0, z: 0 },
182
- rotation: { x: 0, y: -Math.PI / 2, z: 0 },
183
- type: 'center',
184
- group: createCenterGroup(Materials.left, Materials.core),
185
- },
186
- ];
187
-
188
- /**
189
- * @return {state[]}
190
- */
191
- const createCubeState = () => [...corners(), ...edges(), ...centers()];
192
- export { createCubeState };