@colijnit/configurator 12.0.12 → 12.0.13

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.
@@ -396,7 +396,7 @@ class Material {
396
396
 
397
397
  // @dynamic
398
398
  class ImageUtils {
399
- static CreateTextureFromBase64(id, base64, material) {
399
+ static CreateTextureFromBase64(id, base64, material, defaultFlip = false) {
400
400
  return new Promise((resolve) => {
401
401
  if (ImageUtils.textures.has(id)) {
402
402
  resolve(ImageUtils.textures.get(id));
@@ -412,6 +412,7 @@ class ImageUtils {
412
412
  texture.wrapS = THREE.RepeatWrapping;
413
413
  texture.wrapT = THREE.RepeatWrapping;
414
414
  texture.repeat = new THREE.Vector2(material ? material.repeatX : 1, material ? material.repeatY : 1);
415
+ texture.flipY = defaultFlip;
415
416
  texture.needsUpdate = true;
416
417
  ImageUtils.textures.set(id, texture);
417
418
  resolve(texture);
@@ -471,9 +472,6 @@ class AssetUtils {
471
472
  if (asset.normal) {
472
473
  material.normal = yield ImageUtils.CreateTextureFromBase64(asset.id + '_normal', asset.normal, material);
473
474
  material.normalFilename = asset.normalFilename;
474
- // material.normal.anisotropy = 1;
475
- // material.normal.repeat.set(1, 1);
476
- // material.normal.flipY = false;
477
475
  }
478
476
  if (asset.orm) {
479
477
  material.ao = yield ImageUtils.CreateTextureFromBase64(asset.id + '_orm', asset.orm, material);
@@ -502,13 +500,42 @@ class AssetUtils {
502
500
  material.displacementFilename = asset.displacementFilename;
503
501
  }
504
502
  if (asset.envMap) {
505
- material.envMap = yield ImageUtils.CreateTextureFromBase64(asset.id + '_env', asset.envMap, material);
503
+ material.envMap = yield ImageUtils.CreateTextureFromBase64(asset.id + '_env', asset.envMap, material, true);
506
504
  material.envMapFilename = asset.envMapFilename;
507
505
  }
506
+ if (asset.sheenColorMap) {
507
+ material.sheenColorMap = yield ImageUtils.CreateTextureFromBase64(asset.id + '_sheen_color', asset.sheenColorMap, material);
508
+ material.sheenColorMapFileName = asset.sheenColorMapFilename;
509
+ }
510
+ if (asset.sheenRoughnessMap) {
511
+ material.sheenRoughnessMap = yield ImageUtils.CreateTextureFromBase64(asset.id + '_sheen_roughness', asset.sheenRoughnessMap, material);
512
+ material.sheenRoughnessMapFileName = asset.sheenRoughnessMapFilename;
513
+ }
508
514
  if (asset.emissive) {
509
515
  material.emissive = yield ImageUtils.CreateTextureFromBase64(asset.id + '_emissive', asset.emissive, material);
510
516
  material.emissiveFileName = asset.emissiveFilename;
511
517
  }
518
+ const metalness = parseFloat(asset['metalness']);
519
+ if (!isNaN(metalness)) {
520
+ material.metalnessValue = Math.min(1, metalness);
521
+ }
522
+ const roughness = parseFloat(asset['roughness']);
523
+ if (!isNaN(roughness)) {
524
+ material.roughnessValue = Math.min(1, roughness);
525
+ }
526
+ material.sheen = asset.sheen;
527
+ material.emissiveIntensityValue = asset.emissiveIntensity;
528
+ material.emissiveValue = asset.emissiveValue;
529
+ material.side = asset.side;
530
+ material.sheenColor = asset.sheenColor;
531
+ material.sheenRoughness = asset.sheenRoughness;
532
+ material.opacity = asset.opacity;
533
+ material.transparent = asset.transparent;
534
+ material.envMapIntensity = asset.envMapIntensity;
535
+ material.reflectivity = asset.reflectivity;
536
+ material.displacementValue = asset.displacementValue;
537
+ material.transparency = asset.transparency;
538
+ material.transmission = asset.transmission;
512
539
  return material;
513
540
  });
514
541
  }
@@ -531,44 +558,6 @@ class AssetUtils {
531
558
  if (!isNaN(repeaty)) {
532
559
  material.repeatY = repeaty;
533
560
  }
534
- const metalness = parseFloat(settings['metalness']);
535
- if (!isNaN(metalness)) {
536
- material.metalnessValue = Math.min(1, metalness);
537
- }
538
- const roughness = parseFloat(settings['roughness']);
539
- if (!isNaN(roughness)) {
540
- material.roughnessValue = Math.min(1, roughness);
541
- }
542
- if (settings.hasOwnProperty('side')) {
543
- material.side = settings.side;
544
- }
545
- if (settings.hasOwnProperty('sheenColor')) {
546
- material.sheenColor = settings.sheenColor;
547
- }
548
- if (settings.hasOwnProperty('opacity')) {
549
- material.opacity = settings.opacity;
550
- }
551
- if (settings.hasOwnProperty('transparent')) {
552
- material.transparent = settings.transparent;
553
- }
554
- if (settings.hasOwnProperty('envMap')) {
555
- material.envMap = settings.envMap;
556
- }
557
- if (settings.hasOwnProperty('envMapIntensity')) {
558
- material.envMapIntensity = settings.envMapIntensity;
559
- }
560
- if (settings.hasOwnProperty('reflectivity')) {
561
- material.reflectivity = settings.reflectivity;
562
- }
563
- if (settings.hasOwnProperty('displacementValue')) {
564
- material.displacementValue = settings.displacementValue;
565
- }
566
- if (settings.hasOwnProperty('transparency')) {
567
- material.transparency = settings.transparency;
568
- }
569
- if (settings.hasOwnProperty('transmission')) {
570
- material.transmission = settings.transmission;
571
- }
572
561
  }
573
562
  }
574
563
 
@@ -717,27 +706,41 @@ class VariationUtils {
717
706
  variationSettings.envMap = yield VariationUtils.LoadFileContentFromZip(zipContent.files[index.envMapFile], index.envMapFile);
718
707
  variationSettings.envMapFilename = index.envMapFile;
719
708
  }
720
- variationSettings.settings =
721
- (yield VariationUtils.LoadFileContentFromZip(zipContent.files['repeat.json'], 'repeat.json', false)) || {};
722
- Object.assign(variationSettings.settings, index.repeat);
723
- variationSettings.settings.metalness = index.metalness;
724
- variationSettings.settings.roughness = index.roughness;
709
+ if (index.sheenColorMapFile) {
710
+ variationSettings.sheenColorMap = yield VariationUtils.LoadFileContentFromZip(zipContent.files[index.sheenColorMapFile], index.sheenColorMapFile);
711
+ variationSettings.sheenColorMapFilename = index.sheenColorMapFile;
712
+ }
713
+ if (index.sheenRoughnessMapFile) {
714
+ variationSettings.sheenRoughnessMap = yield VariationUtils.LoadFileContentFromZip(zipContent.files[index.sheenRoughnessMapFile], index.sheenRoughnessMapFile);
715
+ variationSettings.sheenRoughnessMapFilename = index.sheenColorMapFile;
716
+ }
717
+ if (index.repeat) {
718
+ variationSettings.settings = {
719
+ repeatx: index.repeat.repeatx,
720
+ repeaty: index.repeat.repeaty
721
+ };
722
+ }
723
+ // variationSettings.settings =
724
+ // await VariationUtils.LoadFileContentFromZip(zipContent.files['repeat.json'], 'repeat.json', false) || {};
725
+ variationSettings.metalness = index.metalness;
726
+ variationSettings.roughness = index.roughness;
727
+ variationSettings.sheen = index.sheen;
725
728
  if (index.sheenColor) {
726
- variationSettings.settings.sheenColor = new THREE.Color(index.sheenColor.r, index.sheenColor.g, index.sheenColor.b);
729
+ variationSettings.sheenColor = new THREE.Color(index.sheenColor.r, index.sheenColor.g, index.sheenColor.b);
727
730
  }
728
- variationSettings.settings.envMap = index.envMap;
729
- variationSettings.settings.envMapIntensity = index.envMapIntensity;
730
- variationSettings.settings.transparent = index.transparent;
731
- variationSettings.settings.opacity = index.opacity;
731
+ variationSettings.sheenRoughness = index.sheenRoughness;
732
+ variationSettings.envMapIntensity = index.envMapIntensity;
733
+ variationSettings.transparent = index.transparent;
734
+ variationSettings.opacity = index.opacity;
732
735
  if (index.emissiveValue) {
733
- variationSettings.settings.emissiveValue = new THREE.Color(index.emissiveValue.r, index.emissiveValue.g, index.emissiveValue.b);
734
- }
735
- variationSettings.settings.emissiveIntensity = index.emissiveIntensity;
736
- variationSettings.settings.reflectivity = index.reflectivity;
737
- variationSettings.settings.displacementValue = index.displacementValue;
738
- variationSettings.settings.side = index.side;
739
- variationSettings.settings.transparency = index.transparency;
740
- variationSettings.settings.transmission = index.transmission;
736
+ variationSettings.emissiveValue = new THREE.Color(index.emissiveValue.r, index.emissiveValue.g, index.emissiveValue.b);
737
+ }
738
+ variationSettings.emissiveIntensity = index.emissiveIntensity;
739
+ variationSettings.reflectivity = index.reflectivity;
740
+ variationSettings.displacementValue = index.displacementValue;
741
+ variationSettings.side = index.side;
742
+ variationSettings.transparency = index.transparency;
743
+ variationSettings.transmission = index.transmission;
741
744
  });
742
745
  }
743
746
  static CreateSettingsBasedOnFileName(variationSettings, zipContent) {
@@ -794,6 +797,18 @@ class VariationUtils {
794
797
  variationSettings.envMapFilename = fileName;
795
798
  }));
796
799
  }
800
+ else if (file.name.toLowerCase().indexOf('sheenColorMap') > -1 && this.FileIsImage(file.name)) {
801
+ allLoaded.push(zipContent.files[fileName].async('base64').then((sheenColorMapFile) => {
802
+ variationSettings.sheenColorMap = `data:image/${this.GetBase64FileType(file.name)};base64,${sheenColorMapFile}`;
803
+ variationSettings.sheenColorMapFilename = fileName;
804
+ }));
805
+ }
806
+ else if (file.name.toLowerCase().indexOf('sheenRoughnessMap') > -1 && this.FileIsImage(file.name)) {
807
+ allLoaded.push(zipContent.files[fileName].async('base64').then((sheenRoughnessMapFile) => {
808
+ variationSettings.sheenRoughnessMap = `data:image/${this.GetBase64FileType(file.name)};base64,${sheenRoughnessMapFile}`;
809
+ variationSettings.sheenRoughnessMapFilename = fileName;
810
+ }));
811
+ }
797
812
  else if (file.name.indexOf('.jp') > -1) {
798
813
  allLoaded.push(zipContent.files[fileName].async('base64').then((textureFile) => {
799
814
  variationSettings.texture = 'data:image/jpeg;base64,' + textureFile;
@@ -1131,171 +1146,198 @@ class VariationHelper {
1131
1146
  }
1132
1147
  }
1133
1148
  _setMeshMaterialFromVariation(name, variation, usePbr = false) {
1134
- if (variation.material.texture) {
1135
- variation.material.texture.needsUpdate = true;
1136
- variation.material.texture.mapping = THREE.EquirectangularReflectionMapping;
1149
+ const material = variation.material;
1150
+ if (material.texture) {
1151
+ material.texture.needsUpdate = true;
1152
+ material.texture.mapping = THREE.EquirectangularReflectionMapping;
1137
1153
  }
1138
1154
  if (!usePbr) {
1139
1155
  const newMaterial = new THREE.MeshPhongMaterial({
1140
1156
  name: name,
1141
- shininess: variation.material.shininess,
1142
- specular: variation.material.specular,
1143
- map: variation.material.texture,
1144
- normalMap: variation.material.normal
1157
+ shininess: material.shininess,
1158
+ specular: material.specular,
1159
+ map: material.texture,
1160
+ normalMap: material.normal
1145
1161
  });
1146
1162
  newMaterial.color.setRGB(0.8, 0.8, 0.8);
1147
1163
  newMaterial.needsUpdate = true;
1148
1164
  return newMaterial;
1149
1165
  }
1150
- if (variation.material.sheenColor || variation.material.reflectivity) {
1166
+ if (material.sheen || material.sheenColor || material.reflectivity) { // TODO: Proper check for all unique physical material properties
1151
1167
  const params = {
1152
1168
  // side: material.side ? material.side : FrontSide,
1153
1169
  name: name,
1154
- roughness: variation.material.roughnessValue ? variation.material.roughnessValue : 1,
1155
- metalness: variation.material.metalnessValue ? variation.material.metalnessValue : 0,
1156
- envMapIntensity: variation.material.envMapIntensity ? variation.material.envMapIntensity : 0.01,
1157
- clearcoatMap: variation.material.clearcoatMap ? variation.material.clearcoatMap : null,
1158
- clearcoatRoughnessMap: variation.material.clearcoatRoughnessMap ? variation.material.clearcoatRoughnessMap : null,
1170
+ roughness: material.roughnessValue ? material.roughnessValue : 1,
1171
+ metalness: material.metalnessValue ? material.metalnessValue : 0,
1172
+ envMapIntensity: material.envMapIntensity ? material.envMapIntensity : 0.01,
1173
+ clearcoatMap: material.clearcoatMap ? material.clearcoatMap : null,
1174
+ clearcoatRoughnessMap: material.clearcoatRoughnessMap ? material.clearcoatRoughnessMap : null,
1159
1175
  // wireframe: true,
1160
1176
  // opacity: 0.3,
1161
1177
  // transparent: true,
1162
1178
  };
1163
- if (variation.material.displacementValue) {
1164
- params.displacementScale = variation.material.displacementValue;
1179
+ if (material.displacementValue) {
1180
+ params.displacementScale = material.displacementValue;
1165
1181
  }
1166
- if (variation.material.sheenColor) {
1167
- params.sheen = variation.material.sheenColor;
1182
+ if (material.opacity) {
1183
+ params.opacity = material.opacity;
1168
1184
  }
1169
- if (variation.material.opacity) {
1170
- params.opacity = variation.material.opacity;
1185
+ if (material.transparency) {
1186
+ params.transmission = material.transparency;
1171
1187
  }
1172
- if (variation.material.transparent) {
1173
- params.transparent = variation.material.transparent;
1188
+ if (material.transmission) {
1189
+ params.transmission = material.transmission;
1174
1190
  }
1175
- if (variation.material.emissiveValue) {
1176
- params.emissive = variation.material.emissiveValue;
1191
+ if (material.transparent) {
1192
+ params.transparent = material.transparent;
1177
1193
  }
1178
- if (variation.material.emissiveIntensityValue) {
1179
- params.emissiveIntensity = variation.material.emissiveIntensityValue;
1194
+ if (material.emissiveValue) {
1195
+ params.emissive = material.emissiveValue;
1180
1196
  }
1181
- if (variation.material.texture) {
1182
- params.map = variation.material.texture;
1197
+ if (material.emissiveIntensityValue) {
1198
+ params.emissiveIntensity = material.emissiveIntensityValue;
1199
+ }
1200
+ if (material.texture) {
1201
+ params.map = material.texture;
1183
1202
  params.map.needsUpdate = true;
1184
1203
  }
1185
- if (variation.material.ao) {
1186
- params.aoMap = variation.material.ao;
1204
+ if (material.ao) {
1205
+ params.aoMap = material.ao;
1187
1206
  params.aoMap.needsUpdate = true;
1188
1207
  }
1189
- if (variation.material.roughness) {
1190
- params.roughnessMap = variation.material.roughness;
1208
+ if (material.roughness) {
1209
+ params.roughnessMap = material.roughness;
1191
1210
  params.roughnessMap.needsUpdate = true;
1192
- // variation.material.roughness.magFilter = NearestFilter;
1211
+ // material.roughness.magFilter = NearestFilter;
1193
1212
  }
1194
- if (variation.material.metalness) {
1195
- params.metalnessMap = variation.material.metalness;
1213
+ if (material.metalness) {
1214
+ params.metalnessMap = material.metalness;
1196
1215
  params.metalnessMap.needsUpdate = true;
1197
1216
  }
1198
- if (variation.material.normal) {
1199
- params.normalMap = variation.material.normal;
1217
+ if (material.normal) {
1218
+ params.normalMap = material.normal;
1200
1219
  params.normalMap.needsUpdate = true;
1201
1220
  }
1202
- if (variation.material.displacement) {
1203
- params.displacementMap = variation.material.displacement;
1221
+ if (material.displacement) {
1222
+ params.displacementMap = material.displacement;
1204
1223
  params.displacementMap.needsUpdate = true;
1205
1224
  }
1206
- if (variation.material.emissive) {
1207
- params.emissiveMap = variation.material.emissive;
1225
+ if (material.emissive) {
1226
+ params.emissiveMap = material.emissive;
1208
1227
  params.emissiveMap.needsUpdate = true;
1209
1228
  }
1210
- if (variation.material.envMap) {
1211
- if (variation.material.envMapIntensity != null || 0) {
1212
- params.envMap = variation.material.envMap;
1229
+ if (material.envMap) {
1230
+ if (material.envMapIntensity != null || 0) {
1231
+ params.envMap = material.envMap;
1213
1232
  params.envMap.needsUpdate = true;
1214
- variation.material.envMap.mapping = THREE.EquirectangularReflectionMapping;
1215
- variation.material.envMap.minFilter = THREE.NearestFilter;
1216
- variation.material.envMap.magFilter = THREE.NearestFilter;
1233
+ material.envMap.mapping = THREE.EquirectangularReflectionMapping;
1234
+ material.envMap.minFilter = THREE.NearestFilter;
1235
+ material.envMap.magFilter = THREE.NearestFilter;
1217
1236
  }
1218
1237
  }
1219
- if (variation.material.reflectivity) {
1220
- params.reflectivity = variation.material.reflectivity;
1238
+ if (material.reflectivity) {
1239
+ params.reflectivity = material.reflectivity;
1221
1240
  }
1222
- if (variation.material.side) {
1223
- params.side = variation.material.side;
1241
+ if (material.side) {
1242
+ params.side = material.side;
1224
1243
  }
1225
1244
  const newMaterial = new THREE.MeshPhysicalMaterial(params);
1226
1245
  newMaterial.color.setRGB(1, 1, 1);
1227
- newMaterial.needsUpdate = true;
1228
- if (variation.material.transmission) {
1229
- newMaterial.transmission = variation.material.transmission;
1246
+ if (material.sheen) {
1247
+ newMaterial.sheen = material.sheen;
1248
+ }
1249
+ if (material.sheenColor) {
1250
+ newMaterial.sheenColor = material.sheenColor;
1230
1251
  }
1252
+ if (material.sheenRoughness) {
1253
+ newMaterial.sheenRoughness = material.sheenRoughness;
1254
+ }
1255
+ if (material.sheenColorMap) {
1256
+ newMaterial.sheenColorMap = material.sheenColorMap;
1257
+ newMaterial.sheenColorMap.needsUpdate = true;
1258
+ }
1259
+ if (material.sheenRoughnessMap) {
1260
+ newMaterial.sheenRoughnessMap = material.sheenRoughnessMap;
1261
+ newMaterial.sheenRoughnessMap.needsUpdate = true;
1262
+ }
1263
+ if (material.transmission) {
1264
+ newMaterial.transmission = material.transmission;
1265
+ }
1266
+ newMaterial.needsUpdate = true;
1231
1267
  return newMaterial;
1232
1268
  }
1233
1269
  else {
1234
1270
  const params = {
1235
1271
  // side: material.side ? material.side : FrontSide,
1236
1272
  name: name,
1237
- roughness: variation.material.roughnessValue ? variation.material.roughnessValue : 1,
1238
- metalness: variation.material.metalnessValue ? variation.material.metalnessValue : 0,
1239
- envMapIntensity: variation.material.envMapIntensity ? variation.material.envMapIntensity : 0.01
1273
+ roughness: material.roughnessValue ? material.roughnessValue : 1,
1274
+ metalness: material.metalnessValue ? material.metalnessValue : 0,
1275
+ envMapIntensity: material.envMapIntensity ? material.envMapIntensity : 0.01
1240
1276
  // wireframe: true,
1241
1277
  // opacity: 0.3,
1242
1278
  // transparent: true,
1243
1279
  };
1244
- if (variation.material.displacementValue) {
1245
- params.displacementScale = variation.material.displacementValue;
1280
+ if (material.displacementValue) {
1281
+ params.displacementScale = material.displacementValue;
1282
+ }
1283
+ if (material.opacity) {
1284
+ params.opacity = material.opacity;
1285
+ }
1286
+ if (material.transparency) {
1287
+ params.opacity = material.transparency;
1246
1288
  }
1247
- if (variation.material.opacity) {
1248
- params.opacity = variation.material.opacity;
1289
+ if (material.transmission) {
1290
+ params.opacity = material.transmission;
1249
1291
  }
1250
- if (variation.material.transparent) {
1251
- params.transparent = variation.material.transparent;
1292
+ if (material.transparent) {
1293
+ params.transparent = material.transparent;
1252
1294
  }
1253
- if (variation.material.emissiveValue) {
1254
- params.emissive = variation.material.emissiveValue;
1295
+ if (material.emissiveValue) {
1296
+ params.emissive = material.emissiveValue;
1255
1297
  }
1256
- if (variation.material.emissiveIntensityValue) {
1257
- params.emissiveIntensity = variation.material.emissiveIntensityValue;
1298
+ if (material.emissiveIntensityValue) {
1299
+ params.emissiveIntensity = material.emissiveIntensityValue;
1258
1300
  }
1259
- if (variation.material.texture) {
1260
- params.map = variation.material.texture;
1301
+ if (material.texture) {
1302
+ params.map = material.texture;
1261
1303
  params.map.needsUpdate = true;
1262
1304
  }
1263
- if (variation.material.ao) {
1264
- params.aoMap = variation.material.ao;
1305
+ if (material.ao) {
1306
+ params.aoMap = material.ao;
1265
1307
  params.aoMap.needsUpdate = true;
1266
1308
  }
1267
- if (variation.material.roughness) {
1268
- params.roughnessMap = variation.material.roughness;
1309
+ if (material.roughness) {
1310
+ params.roughnessMap = material.roughness;
1269
1311
  params.roughnessMap.needsUpdate = true;
1270
- // variation.material.roughness.magFilter = NearestFilter;
1312
+ // material.roughness.magFilter = NearestFilter;
1271
1313
  }
1272
- if (variation.material.metalness) {
1273
- params.metalnessMap = variation.material.metalness;
1314
+ if (material.metalness) {
1315
+ params.metalnessMap = material.metalness;
1274
1316
  params.metalnessMap.needsUpdate = true;
1275
1317
  }
1276
- if (variation.material.normal) {
1277
- params.normalMap = variation.material.normal;
1318
+ if (material.normal) {
1319
+ params.normalMap = material.normal;
1278
1320
  params.normalMap.needsUpdate = true;
1279
1321
  }
1280
- if (variation.material.displacement) {
1281
- params.displacementMap = variation.material.displacement;
1322
+ if (material.displacement) {
1323
+ params.displacementMap = material.displacement;
1282
1324
  params.displacementMap.needsUpdate = true;
1283
1325
  }
1284
- if (variation.material.emissive) {
1285
- params.emissiveMap = variation.material.emissive;
1326
+ if (material.emissive) {
1327
+ params.emissiveMap = material.emissive;
1286
1328
  params.emissiveMap.needsUpdate = true;
1287
1329
  }
1288
- if (variation.material.envMap) {
1289
- if (variation.material.envMapIntensity != null || 0) {
1290
- params.envMap = variation.material.envMap;
1330
+ if (material.envMap) {
1331
+ if (material.envMapIntensity != null || 0) {
1332
+ params.envMap = material.envMap;
1291
1333
  params.envMap.needsUpdate = true;
1292
- variation.material.envMap.mapping = THREE.EquirectangularReflectionMapping;
1293
- variation.material.envMap.minFilter = THREE.NearestFilter;
1294
- variation.material.envMap.magFilter = THREE.NearestFilter;
1334
+ material.envMap.mapping = THREE.EquirectangularReflectionMapping;
1335
+ material.envMap.minFilter = THREE.NearestFilter;
1336
+ material.envMap.magFilter = THREE.NearestFilter;
1295
1337
  }
1296
1338
  }
1297
- if (variation.material.side) {
1298
- params.side = variation.material.side;
1339
+ if (material.side) {
1340
+ params.side = material.side;
1299
1341
  }
1300
1342
  const newMaterial = new THREE.MeshStandardMaterial(params);
1301
1343
  newMaterial.color.setRGB(1, 1, 1);