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 +3 -3
- package/src/Editors/MaterialsLibrary.js +5 -49
- package/src/Editors/OutlineEditor.js +96 -6
- package/src/Tools/Networking/InlineGeometryTool.js +7 -0
- package/src/Undo/Editor.js +52 -0
- package/src/assets/X3D/MaterialPreview.x3d +11 -6
- /package/src/{Editors → assets/X3D}/CannonExterior.avif +0 -0
- /package/src/{Editors → assets/X3D}/Materials.x3d +0 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sunrize",
|
|
3
3
|
"productName": "Sunrize X3D Editor",
|
|
4
|
-
"version": "2.0.
|
|
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.
|
|
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.
|
|
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
|
|
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 =
|
|
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
|
-
|
|
1515
|
-
x3dSyntax = await Editor .exportX3D (inlineNode .getInternalScene (),
|
|
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
|
-
|
|
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 (
|
|
1822
|
+
const inlineNode = executionContext .createNode (typeName) .getValue ();
|
|
1733
1823
|
|
|
1734
1824
|
inlineNode ._url = [Editor .relativePath (executionContext, response .filePath)];
|
|
1735
1825
|
|
package/src/Undo/Editor.js
CHANGED
|
@@ -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.
|
|
3
|
-
<X3D profile='Interchange' version='4.
|
|
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='
|
|
5
|
+
<component name='CubeMapTexturing' level='2'/>
|
|
6
|
+
<component name='Geometry2D' level='1'/>
|
|
6
7
|
<component name='Layering' level='1'/>
|
|
7
|
-
<component name='Layout' level='
|
|
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
|
|
13
|
-
<meta name='modified' content='
|
|
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
|