arcanumcube 0.1.0 → 0.1.2

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.
@@ -264,6 +264,42 @@ function getRandomTwistList(steps = 0) {
264
264
  }
265
265
  return list;
266
266
  }
267
+ var SIDE_FACES = Object.freeze([
268
+ [1, 2, 4, 5],
269
+ [2, 0, 5, 3],
270
+ [0, 1, 3, 4],
271
+ [2, 1, 5, 4],
272
+ [0, 2, 3, 5],
273
+ [1, 0, 4, 3]
274
+ ]);
275
+ function getInitialState(up, front) {
276
+ const down = (up + 3) % 6;
277
+ const side = SIDE_FACES[up];
278
+ const state = new Array(CUBE_SIZE * CUBE_SIZE).fill(up);
279
+ for (let i = 0; i < 4; i++) {
280
+ if (i == 2) {
281
+ const downs = [...Array(CUBE_SIZE * CUBE_SIZE)].fill(down);
282
+ state.push(...downs);
283
+ }
284
+ const sides = [...Array(CUBE_SIZE * CUBE_SIZE)].fill(side[(front + i) % 4]);
285
+ state.push(...sides);
286
+ }
287
+ return state;
288
+ }
289
+ function isSameArrays(arr1, arr2) {
290
+ if (arr1.length !== arr2.length) return false;
291
+ return !arr1.some((v, i) => v !== arr2[i]);
292
+ }
293
+ var GOAL_STATE_LIST = [];
294
+ for (let up = 0; up < 6; up++) {
295
+ for (let front = 0; front < 4; front++) {
296
+ GOAL_STATE_LIST.push(getInitialState(up, front));
297
+ }
298
+ }
299
+ Object.freeze(GOAL_STATE_LIST);
300
+ function MatchGoalState(state) {
301
+ return GOAL_STATE_LIST.some((s) => isSameArrays(state, s));
302
+ }
267
303
  var Cube = class {
268
304
  type;
269
305
  position;
@@ -408,6 +444,9 @@ var ArcanumCube = class {
408
444
  const list = this.getUndoList(steps);
409
445
  this.twist(list, true);
410
446
  }
447
+ isSolved() {
448
+ return MatchGoalState(this.getStickerColors());
449
+ }
411
450
  getHistory() {
412
451
  return this._history;
413
452
  }
@@ -630,6 +669,12 @@ function createDefaultLogoTexture() {
630
669
  texture.needsUpdate = true;
631
670
  return texture;
632
671
  }
672
+ function GetSkinByName(name) {
673
+ return SkinMap[name];
674
+ }
675
+ function GetSkinNameList() {
676
+ return Object.keys(SkinMap);
677
+ }
633
678
  var standardSkin = {
634
679
  name: "Standard",
635
680
  enableEnvMap: false,
@@ -1128,12 +1173,14 @@ var WebGLCube = class extends Cube {
1128
1173
  stickerScale: 0.92,
1129
1174
  gap: 0.01,
1130
1175
  enableShadow: false,
1131
- skin: DefaultSkin.name
1176
+ skin: DefaultSkin,
1177
+ wireframe: false,
1178
+ wireframeColor: 32768
1132
1179
  };
1133
1180
  if (opts) {
1134
1181
  Object.assign(this._config, opts);
1135
1182
  }
1136
- this._skin = SkinMap[this._config.skin];
1183
+ this._skin = this._config.skin;
1137
1184
  }
1138
1185
  getGroup() {
1139
1186
  return this._group;
@@ -1167,9 +1214,13 @@ var WebGLCube = class extends Cube {
1167
1214
  const geo = mesh.geometry.clone();
1168
1215
  geo.scale(scale, scale, scale);
1169
1216
  const mat = this._skin.cube.material();
1170
- if (this._skin.enableEnvMap && config.envMap && (mat instanceof THREE3.MeshStandardMaterial || mat instanceof THREE3.MeshBasicMaterial)) {
1217
+ if (this._skin.enableEnvMap && config.envMap && (mat instanceof THREE3.MeshStandardMaterial || mat instanceof THREE3.MeshBasicMaterial || mat instanceof THREE3.MeshPhysicalMaterial)) {
1171
1218
  mat.envMap = config.envMap;
1172
1219
  }
1220
+ if (config.wireframe) {
1221
+ mat.wireframe = config.wireframe;
1222
+ mat.color = new THREE3.Color(config.wireframeColor);
1223
+ }
1173
1224
  const m = new THREE3.Mesh(geo, mat);
1174
1225
  m.name = this.type;
1175
1226
  for (const r of angles) {
@@ -1179,6 +1230,7 @@ var WebGLCube = class extends Cube {
1179
1230
  m.geometry.rotateZ(Math.PI * axis[2] * steps / 2);
1180
1231
  }
1181
1232
  m.castShadow = config.enableShadow;
1233
+ m.receiveShadow = config.enableShadow;
1182
1234
  m.position.x += (x - 1) * CUBE_SIDE_LEN * (1 + config.gap) * scale;
1183
1235
  m.position.y += (y - 1) * CUBE_SIDE_LEN * (1 + config.gap) * scale;
1184
1236
  m.position.z += (z - 1) * CUBE_SIDE_LEN * (1 + config.gap) * scale;
@@ -1203,12 +1255,17 @@ var WebGLCube = class extends Cube {
1203
1255
  pgeo.scale(scale * config.stickerScale, scale, scale * config.stickerScale);
1204
1256
  sticker.color = sticker.face;
1205
1257
  const pmat = this._skin.sticker.material(x, y, z, sticker.color);
1206
- if (this._skin.enableEnvMap && config.envMap && (pmat instanceof THREE3.MeshStandardMaterial || pmat instanceof THREE3.MeshBasicMaterial)) {
1258
+ if (this._skin.enableEnvMap && config.envMap && (pmat instanceof THREE3.MeshStandardMaterial || pmat instanceof THREE3.MeshBasicMaterial || pmat instanceof THREE3.MeshPhysicalMaterial)) {
1207
1259
  pmat.envMap = config.envMap;
1208
1260
  }
1261
+ if (config.wireframe) {
1262
+ pmat.wireframe = config.wireframe;
1263
+ pmat.color = new THREE3.Color(config.wireframeColor);
1264
+ }
1209
1265
  const pm = new THREE3.Mesh(pgeo, pmat);
1210
1266
  pm.name = CUBE.STICKER;
1211
1267
  pm.castShadow = config.enableShadow;
1268
+ m.receiveShadow = config.enableShadow;
1212
1269
  const stickerAngle = STICKER_FACE_2_ANGLE[sticker.face];
1213
1270
  pm.geometry.rotateX(Math.PI * stickerAngle[0] / 180);
1214
1271
  pm.geometry.rotateY(Math.PI * stickerAngle[1] / 180);
@@ -1293,7 +1350,7 @@ var WebGLArcanumCube = class extends ArcanumCube {
1293
1350
  /** tween group */
1294
1351
  _tweens;
1295
1352
  /** light at the center of cube */
1296
- _pointLights;
1353
+ _coreLights;
1297
1354
  constructor(options) {
1298
1355
  super(options);
1299
1356
  this._config = {
@@ -1304,8 +1361,14 @@ var WebGLArcanumCube = class extends ArcanumCube {
1304
1361
  stickerScale: 0.92,
1305
1362
  gap: 0.01,
1306
1363
  enableShadow: false,
1307
- skin: DefaultSkin.name,
1308
- enableLight: false
1364
+ skin: DefaultSkin,
1365
+ autoReset: true,
1366
+ enableCoreLight: false,
1367
+ coreLightColor: 33023,
1368
+ coreLightIntensity: 30,
1369
+ wireframe: false,
1370
+ wireframeColor: 32768,
1371
+ twistOptions: {}
1309
1372
  };
1310
1373
  this._matrix = [];
1311
1374
  this._group = new THREE3.Group();
@@ -1313,7 +1376,7 @@ var WebGLArcanumCube = class extends ArcanumCube {
1313
1376
  this._cubeMap = {};
1314
1377
  this._cancelDragDeg = 15;
1315
1378
  this._tweens = new TWEEN.Group();
1316
- this._pointLights = [];
1379
+ this._coreLights = [];
1317
1380
  if (options) {
1318
1381
  Object.assign(this._config, options);
1319
1382
  }
@@ -1324,11 +1387,8 @@ var WebGLArcanumCube = class extends ArcanumCube {
1324
1387
  getCubeObjectList() {
1325
1388
  return this._cubeObjectList;
1326
1389
  }
1327
- static getSkinNameList() {
1328
- return Object.keys(SkinMap);
1329
- }
1330
1390
  async init() {
1331
- const skin = SkinMap[this._config.skin];
1391
+ const skin = this._config.skin;
1332
1392
  if (skin.modelLoading) {
1333
1393
  this._init();
1334
1394
  } else {
@@ -1342,7 +1402,7 @@ var WebGLArcanumCube = class extends ArcanumCube {
1342
1402
  this._cubeMap = {};
1343
1403
  this._matrix = [];
1344
1404
  this._history = [];
1345
- this._pointLights = [];
1405
+ this._coreLights = [];
1346
1406
  const fixedGroups = new THREE3.Group();
1347
1407
  const config = this._config;
1348
1408
  const yarray = [];
@@ -1357,7 +1417,9 @@ var WebGLArcanumCube = class extends ArcanumCube {
1357
1417
  gap: config.gap,
1358
1418
  enableShadow: config.enableShadow,
1359
1419
  skin: config.skin,
1360
- envMap: config.envMap
1420
+ envMap: config.envMap,
1421
+ wireframe: config.wireframe,
1422
+ wireframeColor: config.wireframeColor
1361
1423
  });
1362
1424
  cube.init();
1363
1425
  xarray.push(cube);
@@ -1365,13 +1427,18 @@ var WebGLArcanumCube = class extends ArcanumCube {
1365
1427
  this._cubeObjectList.push(entityGroup);
1366
1428
  this._cubeMap[entityGroup.id] = cube;
1367
1429
  fixedGroups.add(cube.getGroup());
1368
- if (config.enableLight) {
1430
+ if (config.enableCoreLight) {
1369
1431
  if (x !== SIDE_MIN && y !== SIDE_MIN && z !== SIDE_MIN) {
1370
- const light = new THREE3.PointLight(33023, 30, 20, 0.1);
1432
+ const light = new THREE3.PointLight(
1433
+ config.wireframe ? config.wireframeColor : config.coreLightColor,
1434
+ config.coreLightIntensity,
1435
+ 20,
1436
+ 0.1
1437
+ );
1371
1438
  light.position.x = (x - 1 / 2) * CUBE_SIDE_LEN * (1 + config.gap) * config.scale;
1372
1439
  light.position.y = (y - 1 / 2) * CUBE_SIDE_LEN * (1 + config.gap) * config.scale;
1373
1440
  light.position.z += (z - 1 / 2) * CUBE_SIDE_LEN * (1 + config.gap) * config.scale;
1374
- this._pointLights.push(light);
1441
+ this._coreLights.push(light);
1375
1442
  }
1376
1443
  }
1377
1444
  }
@@ -1381,14 +1448,14 @@ var WebGLArcanumCube = class extends ArcanumCube {
1381
1448
  }
1382
1449
  this._matrix = yarray;
1383
1450
  this._group.clear();
1384
- if (config.enableLight) {
1385
- this._pointLights.forEach((light) => {
1451
+ if (config.enableCoreLight) {
1452
+ this._coreLights.forEach((light) => {
1386
1453
  this._group.add(light);
1387
1454
  });
1388
1455
  }
1389
1456
  this._group.add(fixedGroups);
1390
1457
  }
1391
- async setSkin(name) {
1458
+ async setSkin(skin) {
1392
1459
  const dispose = (obj) => {
1393
1460
  if (obj instanceof THREE3.Group) {
1394
1461
  for (const o of obj.children) {
@@ -1400,7 +1467,7 @@ var WebGLArcanumCube = class extends ArcanumCube {
1400
1467
  obj.geometry.dispose();
1401
1468
  }
1402
1469
  };
1403
- this._config.skin = name;
1470
+ this._config.skin = skin;
1404
1471
  for (const obj of this._group.children) {
1405
1472
  dispose(obj);
1406
1473
  }
@@ -1584,8 +1651,8 @@ var WebGLArcanumCube = class extends ArcanumCube {
1584
1651
  }
1585
1652
  }
1586
1653
  this._group.clear();
1587
- if (this._config.enableLight) {
1588
- this._pointLights.forEach((light) => {
1654
+ if (this._config.enableCoreLight) {
1655
+ this._coreLights.forEach((light) => {
1589
1656
  this._group.add(light);
1590
1657
  });
1591
1658
  }
@@ -1622,7 +1689,7 @@ var WebGLArcanumCube = class extends ArcanumCube {
1622
1689
  // twist randomly several steps
1623
1690
  scramble(steps = 0, duration = 3e3) {
1624
1691
  const list = getRandomTwistList(steps);
1625
- this.tweenTwist(list, false, duration);
1692
+ this.tweenTwist(list, false, duration, false);
1626
1693
  }
1627
1694
  undo(steps = 1, duration = 300) {
1628
1695
  const list = this.getUndoList(steps);
@@ -1630,17 +1697,25 @@ var WebGLArcanumCube = class extends ArcanumCube {
1630
1697
  }
1631
1698
  // twisting(複数回対応)
1632
1699
  // durationを0にするとTweenなしとなる
1633
- tweenTwist(twist, reverse = false, duration = 500, cancel = false) {
1700
+ tweenTwist(twist, reverse = false, duration = 500, cancel = false, options) {
1634
1701
  if (this._tweens.getAll().length > 0) return;
1702
+ if (options == null) options = this._config.twistOptions;
1635
1703
  if (duration === 0) {
1636
1704
  if (Array.isArray(twist)) {
1637
1705
  if (twist.length == 0) return;
1638
- for (const c of twist) {
1706
+ options?.onStart && options.onStart(this);
1707
+ const len = twist.length;
1708
+ for (let i = 0; i < len; i++) {
1709
+ const c = twist[i];
1639
1710
  this._immediatelyTwist(c, reverse);
1711
+ options?.onTwisted && options.onTwisted(this, c, i + 1, len);
1640
1712
  }
1641
1713
  } else {
1714
+ options?.onStart && options.onStart(this);
1642
1715
  this._immediatelyTwist(twist, reverse);
1716
+ options?.onTwisted && options.onTwisted(this, twist, 1, 1);
1643
1717
  }
1718
+ options?.onComplete && options.onComplete(this);
1644
1719
  return;
1645
1720
  }
1646
1721
  let firstTween = void 0;
@@ -1648,8 +1723,15 @@ var WebGLArcanumCube = class extends ArcanumCube {
1648
1723
  if (Array.isArray(twist)) {
1649
1724
  if (twist.length == 0) return;
1650
1725
  const lap = duration / twist.length;
1651
- for (const c of twist) {
1652
- const t = this._tweenTwist(c, reverse, lap, cancel);
1726
+ const len = twist.length;
1727
+ for (let i = 0; i < len; i++) {
1728
+ const c = twist[i];
1729
+ const opts = {};
1730
+ const ontwisted = options?.onTwisted;
1731
+ if (ontwisted)
1732
+ opts.onTwisted = (self, twist2, n1, n2) => ontwisted(this, twist2, i + 1, len);
1733
+ if (i === len - 1 && options?.onComplete) opts.onComplete = options.onComplete;
1734
+ const t = this._tweenTwist(c, reverse, lap, cancel, opts);
1653
1735
  this._tweens.add(t);
1654
1736
  if (!tween) {
1655
1737
  firstTween = tween = t;
@@ -1659,10 +1741,11 @@ var WebGLArcanumCube = class extends ArcanumCube {
1659
1741
  }
1660
1742
  }
1661
1743
  } else {
1662
- firstTween = this._tweenTwist(twist, reverse, duration, cancel);
1744
+ firstTween = this._tweenTwist(twist, reverse, duration, cancel, options);
1663
1745
  this._tweens.add(firstTween);
1664
1746
  }
1665
1747
  if (firstTween) {
1748
+ options?.onStart && options.onStart(this);
1666
1749
  firstTween.start();
1667
1750
  }
1668
1751
  }
@@ -1684,7 +1767,7 @@ var WebGLArcanumCube = class extends ArcanumCube {
1684
1767
  super.twist(twist, reverse);
1685
1768
  }
1686
1769
  // twist with tween
1687
- _tweenTwist(twist, reverse, duration, cancel) {
1770
+ _tweenTwist(twist, reverse, duration, cancel, options = {}) {
1688
1771
  let qa;
1689
1772
  if (this._draggingTwist) {
1690
1773
  this._twistGroup = this._draggingTwist.group;
@@ -1721,12 +1804,28 @@ var WebGLArcanumCube = class extends ArcanumCube {
1721
1804
  super.twist(twist, reverse);
1722
1805
  }
1723
1806
  this._tweens.remove(tween);
1807
+ options.onTwisted && options.onTwisted(this, twist, 1, 1);
1808
+ options.onComplete && options.onComplete(this);
1809
+ if (this._config.autoReset && this.isSolved()) this.reset(0);
1724
1810
  });
1725
1811
  return tween;
1726
1812
  }
1727
1813
  updateTweens() {
1728
1814
  this._tweens.update();
1729
1815
  }
1816
+ // set color of core lights
1817
+ setCoreLightColor(color) {
1818
+ const c = new THREE3.Color(color);
1819
+ this._coreLights.forEach((l) => {
1820
+ l.color = c;
1821
+ });
1822
+ }
1823
+ // change intensity of core lights
1824
+ setCoreLightIntensity(intensity) {
1825
+ this._coreLights.forEach((l) => {
1826
+ l.intensity = intensity;
1827
+ });
1828
+ }
1730
1829
  };
1731
1830
  export {
1732
1831
  ArcanumCube,
@@ -1740,6 +1839,9 @@ export {
1740
1839
  DefaultModel,
1741
1840
  DefaultSkin,
1742
1841
  FACE,
1842
+ GetSkinByName,
1843
+ GetSkinNameList,
1844
+ MatchGoalState,
1743
1845
  SIDE_MAX,
1744
1846
  SIDE_MIDDLE,
1745
1847
  SIDE_MIN,