sunrize 2.0.6 → 2.0.7

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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "sunrize",
3
3
  "productName": "Sunrize X3D Editor",
4
- "version": "2.0.6",
4
+ "version": "2.0.7",
5
5
  "description": "A Multi-Platform X3D Editor",
6
6
  "main": "src/main.js",
7
7
  "bin": {
@@ -92,7 +92,7 @@
92
92
  "@vscode/codicons": "^0.0.44",
93
93
  "capitalize": "^2.0.4",
94
94
  "console": "^0.7.2",
95
- "electron": "^40.6.1",
95
+ "electron": "^40.8.0",
96
96
  "electron-prompt": "^1.7.0",
97
97
  "electron-squirrel-startup": "^1.0.1",
98
98
  "electron-tabs": "^1.0.4",
@@ -111,7 +111,7 @@
111
111
  "string-similarity": "^4.0.4",
112
112
  "tweakpane": "^3.1.10",
113
113
  "update-electron-app": "^3.1.2",
114
- "x_ite": "^14.0.6",
114
+ "x_ite": "^14.0.8",
115
115
  "x3d-traverse": "^1.0.22"
116
116
  }
117
117
  }
@@ -4,9 +4,10 @@ const
4
4
  $ = require ("jquery"),
5
5
  X3D = require ("../X3D"),
6
6
  LibraryPane = require ("./LibraryPane"),
7
+ Editor = require("../Undo/Editor"),
7
8
  _ = require ("../Application/GetText");
8
9
 
9
- module .exports = class Materials extends LibraryPane
10
+ module .exports = class MaterialsLibrary extends LibraryPane
10
11
  {
11
12
  id = "MATERIALS";
12
13
  description = "Materials";
@@ -36,7 +37,7 @@ module .exports = class Materials extends LibraryPane
36
37
  const
37
38
  canvas = $("<x3d-canvas preserveDrawingBuffer='true' xrSessionMode='NONE'></x3d-canvas>"),
38
39
  browser = canvas .prop ("browser"),
39
- scene = await browser .createX3DFromURL (new X3D .MFString (`file://${__dirname}/Materials.x3d`));
40
+ scene = await browser .createX3DFromURL (new X3D .MFString (`file://${__dirname}/../assets/X3D/Materials.x3d`));
40
41
 
41
42
  // Buttons
42
43
 
@@ -113,7 +114,7 @@ module .exports = class Materials extends LibraryPane
113
114
  const
114
115
  canvas = $("<x3d-canvas preserveDrawingBuffer='true' xrSessionMode='NONE'></x3d-canvas>"),
115
116
  browser = canvas .prop ("browser"),
116
- scene = await browser .createX3DFromURL (new X3D .MFString (`file://${__dirname}/Materials.x3d`));
117
+ scene = await browser .createX3DFromURL (new X3D .MFString (`file://${__dirname}/../assets/X3D/Materials.x3d`));
117
118
 
118
119
  scene .addComponent (browser .getComponent ("X_ITE"));
119
120
 
@@ -146,7 +147,7 @@ module .exports = class Materials extends LibraryPane
146
147
 
147
148
  if (this .config .global .convertToPhysical)
148
149
  {
149
- const material = this .convertPhongToPhysical (scene, appearance .material);
150
+ const material = Editor .convertPhongToPhysical (scene, appearance .material, null);
150
151
 
151
152
  scene .updateNamedNode (appearance .material .getNodeName (), material);
152
153
 
@@ -170,49 +171,4 @@ module .exports = class Materials extends LibraryPane
170
171
  browser .dispose ();
171
172
  canvas .remove ();
172
173
  }
173
-
174
- convertPhongToPhysical (executionContext, phong)
175
- {
176
- let
177
- physical = executionContext .createNode ("PhysicalMaterial"),
178
- baseColor = phong .diffuseColor .sRGBToLinear (),
179
- specularColor = phong .specularColor .sRGBToLinear (),
180
- specularIntensity = Math .max (... specularColor),
181
- metallic = Math .min (Math .max ((specularIntensity - 0.04) / (1.0 - 0.04), 0), 1) * 0.5,
182
- roughness = 1 - phong .shininess,
183
- emissiveColor = phong .emissiveColor .sRGBToLinear (),
184
- transparency = phong .transparency,
185
- transmission = transparency ** (1/3);
186
-
187
- if ([... specularColor] .some (Boolean) && roughness)
188
- {
189
- const specularMaterial = executionContext .createNode ("SpecularMaterialExtension");
190
-
191
- specularMaterial .specularColor = specularColor;
192
- specularMaterial .specularStrength = 10 * roughness;
193
-
194
- physical .extensions .push (specularMaterial);
195
-
196
- metallic *= 0.1;
197
- roughness *= 0.5;
198
- }
199
-
200
- if (transparency)
201
- {
202
- const transmissionMaterial = executionContext .createNode ("TransmissionMaterialExtension");
203
-
204
- transmissionMaterial .transmission = transmission;
205
-
206
- physical .extensions .push (transmissionMaterial);
207
-
208
- roughness *= 0.5 * (1 - transparency);
209
- }
210
-
211
- physical .baseColor = baseColor;
212
- physical .metallic = metallic;
213
- physical .roughness = roughness;
214
- physical .emissiveColor = emissiveColor;
215
-
216
- return physical;
217
- }
218
174
  };
@@ -305,6 +305,14 @@ module .exports = class OutlineEditor extends OutlineRouteGraph
305
305
  });
306
306
  }
307
307
 
308
+ if (!node .getType () .includes (X3D .X3DConstants .InlineGeometry))
309
+ {
310
+ menu .push ({
311
+ label: _("Convert Node to InlineGeometry..."),
312
+ args: ["convertNodeToInlineFile", element .attr ("id"), executionContext .getId (), node .getId (), "InlineGeometry"],
313
+ });
314
+ }
315
+
308
316
  continue;
309
317
  }
310
318
  case X3D .X3DConstants .ImageTexture:
@@ -334,6 +342,21 @@ module .exports = class OutlineEditor extends OutlineRouteGraph
334
342
 
335
343
  continue;
336
344
  }
345
+ case X3D .X3DConstants .InlineGeometry:
346
+ {
347
+ menu .push ({
348
+ label: _("Open InlineGeometry Scene in New Tab"),
349
+ enabled: node .checkLoadState () === X3D .X3DConstants .COMPLETE_STATE,
350
+ args: ["openFileInNewTab", node .getInternalScene () ?.worldURL],
351
+ },
352
+ {
353
+ label: _("Fold InlineGeometry Back into Scene"),
354
+ enabled: node .checkLoadState () === X3D .X3DConstants .COMPLETE_STATE && !!node .getGeometry (),
355
+ args: ["foldInlineGeometryBackIntoScene", element .attr ("id"), executionContext .getId (), node .getId ()],
356
+ });
357
+
358
+ continue;
359
+ }
337
360
  case X3D .X3DConstants .PixelTexture:
338
361
  {
339
362
  menu .push ({
@@ -360,6 +383,15 @@ module .exports = class OutlineEditor extends OutlineRouteGraph
360
383
 
361
384
  continue;
362
385
  }
386
+ case X3D .X3DConstants .Material:
387
+ {
388
+ menu .push ({
389
+ label: _("Convert Node to PhysicalMaterial"),
390
+ args: ["convertToPhysicalMaterial", element .attr ("id"), executionContext .getId (), node .getId ()],
391
+ });
392
+
393
+ continue;
394
+ }
363
395
  case X3D .X3DConstants .X3DPrototypeInstance:
364
396
  {
365
397
  if (!$.try (() => node .getInnerNode ()))
@@ -379,7 +411,7 @@ module .exports = class OutlineEditor extends OutlineRouteGraph
379
411
  {
380
412
  menu .push ({
381
413
  label: _("Convert Node to Inline File..."),
382
- args: ["convertNodeToInlineFile", element .attr ("id"), executionContext .getId (), node .getId ()],
414
+ args: ["convertNodeToInlineFile", element .attr ("id"), executionContext .getId (), node .getId (), "Inline"],
383
415
  });
384
416
 
385
417
  continue;
@@ -1438,6 +1470,26 @@ module .exports = class OutlineEditor extends OutlineRouteGraph
1438
1470
  UndoManager .shared .endUndo ();
1439
1471
  }
1440
1472
 
1473
+ convertToPhysicalMaterial (id, executionContextId, nodeId)
1474
+ {
1475
+ const
1476
+ executionContext = this .objects .get (executionContextId),
1477
+ materialNode = this .objects .get (nodeId);
1478
+
1479
+ // Add undo step.
1480
+
1481
+ UndoManager .shared .beginUndo (_("Convert Node to PhysicalMaterial"));
1482
+
1483
+ const physicalMaterialNode = Editor .convertPhongToPhysical (executionContext, new X3D .SFNode (materialNode))
1484
+
1485
+ if (materialNode .getName ())
1486
+ Editor .updateNamedNode (executionContext, materialNode .getName (), physicalMaterialNode);
1487
+
1488
+ Editor .replaceAllOccurrences (executionContext, materialNode, physicalMaterialNode);
1489
+
1490
+ UndoManager .shared .endUndo ();
1491
+ }
1492
+
1441
1493
  async convertPixelTextureToImageTexture (id, executionContextId, nodeId)
1442
1494
  {
1443
1495
  const
@@ -1511,8 +1563,8 @@ module .exports = class OutlineEditor extends OutlineRouteGraph
1511
1563
 
1512
1564
  const
1513
1565
  rootNodes = executionContext .rootNodes .copy (),
1514
- nodesToImport = [... inlineNode .getInternalScene () .rootNodes] .map (node => node .getValue ()),
1515
- x3dSyntax = await Editor .exportX3D (inlineNode .getInternalScene (), nodesToImport, { importedNodes: true }),
1566
+ nodesToExport = [... inlineNode .getInternalScene () .rootNodes] .map (node => node .getValue ()),
1567
+ x3dSyntax = await Editor .exportX3D (inlineNode .getInternalScene (), nodesToExport, { importedNodes: true }),
1516
1568
  nodes = await Editor .importX3D (executionContext, x3dSyntax);
1517
1569
 
1518
1570
  // Remove imported nodes from root nodes.
@@ -1557,6 +1609,36 @@ module .exports = class OutlineEditor extends OutlineRouteGraph
1557
1609
  this .expandTo (childNode, { expandObject: true });
1558
1610
  }
1559
1611
 
1612
+ async foldInlineGeometryBackIntoScene (id, executionContextId, nodeId)
1613
+ {
1614
+ const
1615
+ executionContext = this .objects .get (executionContextId),
1616
+ inlineGeometryNode = this .objects .get (nodeId);
1617
+
1618
+ UndoManager .shared .beginUndo (_("Fold InlineGeometry Back into Scene"));
1619
+
1620
+ const
1621
+ rootNodes = executionContext .rootNodes .copy (),
1622
+ nodesToExport = [inlineGeometryNode .getGeometry ()],
1623
+ x3dSyntax = await Editor .exportX3D (inlineGeometryNode .getInternalScene (), nodesToExport),
1624
+ nodes = await Editor .importX3D (executionContext, x3dSyntax),
1625
+ geometryNode = nodes [0];
1626
+
1627
+ // Remove imported nodes from root nodes.
1628
+
1629
+ Editor .setFieldValue (executionContext, executionContext, executionContext .rootNodes, rootNodes);
1630
+
1631
+ // Insert InlineGeometry node.
1632
+
1633
+ Editor .replaceAllOccurrences (executionContext, inlineGeometryNode, geometryNode);
1634
+
1635
+ UndoManager .shared .endUndo ();
1636
+
1637
+ await this .browser .nextFrame ();
1638
+
1639
+ this .expandTo (geometryNode, { expandObject: true });
1640
+ }
1641
+
1560
1642
  protocolToMimeType = new Map ([
1561
1643
  ["ecmascript:", "application/ecmascript"],
1562
1644
  ["javascript:", "application/javascript"],
@@ -1707,7 +1789,7 @@ module .exports = class OutlineEditor extends OutlineRouteGraph
1707
1789
  UndoManager .shared .endUndo ();
1708
1790
  }
1709
1791
 
1710
- async convertNodeToInlineFile (id, executionContextId, nodeId)
1792
+ async convertNodeToInlineFile (id, executionContextId, nodeId, typeName)
1711
1793
  {
1712
1794
  const
1713
1795
  executionContext = this .objects .get (executionContextId),
@@ -1719,7 +1801,15 @@ module .exports = class OutlineEditor extends OutlineRouteGraph
1719
1801
  if (response .canceled)
1720
1802
  return;
1721
1803
 
1722
- UndoManager .shared .beginUndo (_("Convert Node to Inline File"));
1804
+ switch (typeName)
1805
+ {
1806
+ case "Inline":
1807
+ UndoManager .shared .beginUndo (_("Convert Node to Inline File"));
1808
+ break;
1809
+ case "InlineGeometry":
1810
+ UndoManager .shared .beginUndo (_("Convert Node to InlineGeometry"));
1811
+ break;
1812
+ }
1723
1813
 
1724
1814
  // Create inline file.
1725
1815
 
@@ -1729,7 +1819,7 @@ module .exports = class OutlineEditor extends OutlineRouteGraph
1729
1819
 
1730
1820
  await Editor .addComponent (executionContext, "Networking");
1731
1821
 
1732
- const inlineNode = executionContext .createNode ("Inline") .getValue ();
1822
+ const inlineNode = executionContext .createNode (typeName) .getValue ();
1733
1823
 
1734
1824
  inlineNode ._url = [Editor .relativePath (executionContext, response .filePath)];
1735
1825
 
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+
3
+ const X3DGeometryNodeTool = require ("../Rendering/X3DGeometryNodeTool");
4
+
5
+ class InlineGeometryTool extends X3DGeometryNodeTool { }
6
+
7
+ module .exports = InlineGeometryTool;
@@ -2551,6 +2551,58 @@ ${scene .toXMLString ({ html: true, indent: " " .repeat (6) }) .trimEnd () }
2551
2551
  return Math .abs (target - value) < epsilon;
2552
2552
  }
2553
2553
 
2554
+ static convertPhongToPhysical (executionContext, phong, undoManager = UndoManager .shared)
2555
+ {
2556
+ let
2557
+ browser = executionContext .getBrowser (),
2558
+ physical = executionContext .createNode ("PhysicalMaterial"),
2559
+ baseColor = phong .diffuseColor .sRGBToLinear (),
2560
+ specularColor = phong .specularColor .sRGBToLinear (),
2561
+ specularIntensity = Math .max (... specularColor),
2562
+ metallic = Math .min (Math .max ((specularIntensity - 0.04) / (1.0 - 0.04), 0), 1) * 0.5,
2563
+ roughness = 1 - phong .shininess,
2564
+ emissiveColor = phong .emissiveColor .sRGBToLinear (),
2565
+ transparency = phong .transparency,
2566
+ transmission = transparency ** (1/3);
2567
+
2568
+ if ([... specularColor] .some (Boolean) && roughness)
2569
+ {
2570
+ if (undoManager && !executionContext .hasComponent ("X_ITE"))
2571
+ this .addComponent (executionContext, browser .getComponent ("X_ITE"), undoManager);
2572
+
2573
+ const specularMaterial = executionContext .createNode ("SpecularMaterialExtension");
2574
+
2575
+ specularMaterial .specularColor = specularColor;
2576
+ specularMaterial .specularStrength = 10 * roughness;
2577
+
2578
+ physical .extensions .push (specularMaterial);
2579
+
2580
+ metallic *= 0.1;
2581
+ roughness *= 0.5;
2582
+ }
2583
+
2584
+ if (transparency)
2585
+ {
2586
+ if (undoManager && !executionContext .hasComponent ("X_ITE"))
2587
+ this .addComponent (executionContext, browser .getComponent ("X_ITE"), undoManager);
2588
+
2589
+ const transmissionMaterial = executionContext .createNode ("TransmissionMaterialExtension");
2590
+
2591
+ transmissionMaterial .transmission = transmission;
2592
+
2593
+ physical .extensions .push (transmissionMaterial);
2594
+
2595
+ roughness *= 0.5 * (1 - transparency);
2596
+ }
2597
+
2598
+ physical .baseColor = baseColor;
2599
+ physical .metallic = metallic;
2600
+ physical .roughness = roughness;
2601
+ physical .emissiveColor = emissiveColor;
2602
+
2603
+ return physical;
2604
+ }
2605
+
2554
2606
  static moveViewpoint (viewpointNode, position, orientation, centerOfRotation, fieldOfView, undoManager = UndoManager .shared)
2555
2607
  {
2556
2608
  viewpointNode = viewpointNode .valueOf ();
@@ -1,16 +1,17 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
- <!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 4.0//EN" "http://www.web3d.org/specifications/x3d-4.0.dtd">
3
- <X3D profile='Interchange' version='4.0' xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='http://www.web3d.org/specifications/x3d-4.0.xsd'>
2
+ <!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 4.1//EN" "https://www.web3d.org/specifications/x3d-4.1.dtd">
3
+ <X3D profile='Interchange' version='4.1' xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='https://www.web3d.org/specifications/x3d-4.1.xsd'>
4
4
  <head>
5
- <component name='Geometry2D' level='2'/>
5
+ <component name='CubeMapTexturing' level='2'/>
6
+ <component name='Geometry2D' level='1'/>
6
7
  <component name='Layering' level='1'/>
7
- <component name='Layout' level='2'/>
8
+ <component name='Layout' level='1'/>
8
9
  <component name='PointingDeviceSensor' level='1'/>
9
10
  <component name='Scripting' level='1'/>
10
11
  <meta name='created' content='Thu, 10 Jul 2014 17:28:33 GMT'/>
11
12
  <meta name='creator' content='Holger Seelig'/>
12
- <meta name='generator' content='Sunrize X3D Editor V1.7.6, https://create3000.github.io/sunrize/'/>
13
- <meta name='modified' content='Fri, 19 Jul 2024 18:04:50 GMT'/>
13
+ <meta name='generator' content='Sunrize X3D Editor V2.0.6, https://create3000.github.io/sunrize/'/>
14
+ <meta name='modified' content='Mon, 02 Mar 2026 11:28:07 GMT'/>
14
15
  </head>
15
16
  <Scene>
16
17
  <LayerSet
@@ -44,6 +45,10 @@
44
45
  position='0 0 3'>
45
46
  <NavigationInfo USE='_1' containerField='navigationInfo'/>
46
47
  </Viewpoint>
48
+ <EnvironmentLight DEF='CannonExterior_1'>
49
+ <ImageCubeMapTexture containerField='specularTexture'
50
+ url='"CannonExterior.avif"'/>
51
+ </EnvironmentLight>
47
52
  <DirectionalLight
48
53
  ambientIntensity='0.4'/>
49
54
  <Group DEF='Models'>
File without changes
File without changes