sunrize 2.0.6 → 2.0.8
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 +5 -5
- package/src/Application/Application.js +2 -9
- package/src/Application/Document.js +2 -0
- package/src/Controls/MaterialPreviewPopover.js +28 -25
- package/src/Controls/TexturePreviewPopover.js +14 -12
- package/src/Editors/Library.js +1 -1
- package/src/Editors/MaterialsLibrary.js +6 -50
- package/src/Editors/NodesLibrary.js +3 -3
- package/src/Editors/OutlineEditor.js +124 -29
- package/src/Editors/Panel.js +182 -40
- package/src/Editors/PrimitivesLibrary.js +2 -2
- package/src/Editors/ScriptEditor.js +9 -4
- package/src/Tools/Geometry2D/Arc2DTool.js +5 -5
- package/src/Tools/Geometry2D/Circle2DTool.js +5 -5
- package/src/Tools/Geometry2D/Polyline2DTool.js +2 -2
- package/src/Tools/Geometry2D/Polypoint2DTool.js +2 -2
- package/src/Tools/NURBS/NurbsCurveTool.js +2 -2
- package/src/Tools/Networking/InlineGeometryTool.js +7 -0
- package/src/Tools/Rendering/IndexedLineSetTool.js +2 -2
- package/src/Tools/Rendering/LineSetTool.js +2 -2
- package/src/Tools/Rendering/PointSetTool.js +2 -2
- package/src/Tools/Rendering/X3DGeometryNodeTool.js +39 -15
- package/src/Tools/Rendering/X3DGeometryNodeTool.x3d +43 -8
- package/src/Undo/Editor.js +52 -0
- package/src/assets/X3D/MaterialPreview.x3d +11 -6
- package/src/Tools/Rendering/X3DLineGeometryNodeTool.js +0 -40
- package/src/Tools/Rendering/X3DLineGeometryNodeTool.x3d +0 -64
- package/src/Tools/Rendering/X3DPointGeometryNodeTool.js +0 -40
- package/src/Tools/Rendering/X3DPointGeometryNodeTool.x3d +0 -54
- /package/src/{Editors → assets/X3D}/CannonExterior.avif +0 -0
- /package/src/{Editors → assets/X3D}/Materials.x3d +0 -0
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sunrize",
|
|
3
3
|
"productName": "Sunrize X3D Editor",
|
|
4
|
-
"version": "2.0.
|
|
5
|
-
"description": "A Multi-Platform X3D Editor",
|
|
4
|
+
"version": "2.0.8",
|
|
5
|
+
"description": "Sunrize — A Multi-Platform X3D Editor",
|
|
6
6
|
"main": "src/main.js",
|
|
7
7
|
"bin": {
|
|
8
8
|
"sunrize": "bin/sunrize.js"
|
|
@@ -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": "^
|
|
95
|
+
"electron": "^41.0.0",
|
|
96
96
|
"electron-prompt": "^1.7.0",
|
|
97
97
|
"electron-squirrel-startup": "^1.0.1",
|
|
98
98
|
"electron-tabs": "^1.0.4",
|
|
@@ -109,9 +109,9 @@
|
|
|
109
109
|
"qtip2": "^3.0.3",
|
|
110
110
|
"spectrum-colorpicker2": "^2.0.10",
|
|
111
111
|
"string-similarity": "^4.0.4",
|
|
112
|
-
"tweakpane": "^
|
|
112
|
+
"tweakpane": "^4.0.5",
|
|
113
113
|
"update-electron-app": "^3.1.2",
|
|
114
|
-
"x_ite": "^14.0.
|
|
114
|
+
"x_ite": "^14.0.9",
|
|
115
115
|
"x3d-traverse": "^1.0.22"
|
|
116
116
|
}
|
|
117
117
|
}
|
|
@@ -51,6 +51,8 @@ module .exports = class Application
|
|
|
51
51
|
|
|
52
52
|
constructor ()
|
|
53
53
|
{
|
|
54
|
+
// process .env .SUNRISE_ENVIRONMENT = "DEVELOPMENT"; // Windows test
|
|
55
|
+
|
|
54
56
|
if (process .env .SUNRISE_ENVIRONMENT === "DEVELOPMENT")
|
|
55
57
|
process .env .ELECTRON_ENABLE_LOGGING = 1;
|
|
56
58
|
|
|
@@ -527,15 +529,6 @@ module .exports = class Application
|
|
|
527
529
|
label: _("Show All Objects"),
|
|
528
530
|
click: () => this .mainWindow .webContents .send ("show-all-objects"),
|
|
529
531
|
},
|
|
530
|
-
{ type: "separator" },
|
|
531
|
-
{
|
|
532
|
-
label: _("Transform to Zero"),
|
|
533
|
-
click: () => this .mainWindow .webContents .send ("transform-to-zero"),
|
|
534
|
-
},
|
|
535
|
-
{
|
|
536
|
-
label: _("Remove Empty Groups"),
|
|
537
|
-
click: () => this .mainWindow .webContents .send ("remove-empty-groups"),
|
|
538
|
-
},
|
|
539
532
|
],
|
|
540
533
|
},
|
|
541
534
|
{
|
|
@@ -1267,6 +1267,8 @@ Viewpoint {
|
|
|
1267
1267
|
label: _("Viewpoints"),
|
|
1268
1268
|
submenu: viewpoints .filter ((_, index) => index > 0) .map ((viewpointNode, index) => ({
|
|
1269
1269
|
label: `${viewpointNode ._description .getValue () || viewpointNode .getDisplayName () || `VP${index + 1}}`}`,
|
|
1270
|
+
type: "radio",
|
|
1271
|
+
checked: viewpointNode ._isBound .getValue (),
|
|
1270
1272
|
args: ["bindViewpoint", index + 1],
|
|
1271
1273
|
})),
|
|
1272
1274
|
},
|
|
@@ -37,26 +37,22 @@ $.fn.materialPreviewPopover = async function (node)
|
|
|
37
37
|
// Create material node.
|
|
38
38
|
|
|
39
39
|
const
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
x3dSyntax = await Editor .exportX3D (node .getExecutionContext (), [node]),
|
|
41
|
+
nodes = await Editor .importX3D (scene, x3dSyntax),
|
|
42
|
+
previewNode = nodes [0],
|
|
43
|
+
appearanceNode = browser .currentScene .getExportedNode ("Appearance");
|
|
42
44
|
|
|
43
45
|
// Assign material node.
|
|
44
46
|
|
|
45
47
|
for (const field of previewNode .getFields ())
|
|
48
|
+
connect (field, node .getField (field .getName ()));
|
|
49
|
+
|
|
50
|
+
for (const [i, extension] of previewNode ._extensions ?.entries () ?? [ ])
|
|
46
51
|
{
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
break
|
|
52
|
-
case X3D .X3DConstants .MFNode:
|
|
53
|
-
field .length = 0;
|
|
54
|
-
break;
|
|
55
|
-
default:
|
|
56
|
-
field .addReference (node .getField (field .getName ()));
|
|
57
|
-
field .removeFieldInterest (node .getField (field .getName ()));
|
|
58
|
-
break;
|
|
59
|
-
}
|
|
52
|
+
const original = node ._extensions [i] .getValue ();
|
|
53
|
+
|
|
54
|
+
for (const field of extension .getValue () .getFields ())
|
|
55
|
+
connect (field, original .getField (field .getName ()));
|
|
60
56
|
}
|
|
61
57
|
|
|
62
58
|
previewNode .setup ();
|
|
@@ -90,16 +86,7 @@ $.fn.materialPreviewPopover = async function (node)
|
|
|
90
86
|
field = backPreviewNode .getField (name),
|
|
91
87
|
back = `back${name [0] .toUpperCase ()}${name .slice (1)}`;
|
|
92
88
|
|
|
93
|
-
|
|
94
|
-
{
|
|
95
|
-
case X3D .X3DConstants .SFNode:
|
|
96
|
-
case X3D .X3DConstants .MFNode:
|
|
97
|
-
break;
|
|
98
|
-
default:
|
|
99
|
-
field .addReference (node .getField (back));
|
|
100
|
-
field .removeFieldInterest (node .getField (back));
|
|
101
|
-
break;
|
|
102
|
-
}
|
|
89
|
+
connect (field, node .getField (back));
|
|
103
90
|
}
|
|
104
91
|
|
|
105
92
|
appearanceNode .material = backPreviewNode;
|
|
@@ -119,6 +106,9 @@ $.fn.materialPreviewPopover = async function (node)
|
|
|
119
106
|
events: {
|
|
120
107
|
hide: (event, api) =>
|
|
121
108
|
{
|
|
109
|
+
for (const extension of Array .from (previewNode ._extensions ?? [ ]))
|
|
110
|
+
extension .dispose ();
|
|
111
|
+
|
|
122
112
|
previewNode .dispose ();
|
|
123
113
|
backPreviewNode ?.dispose ();
|
|
124
114
|
browser .dispose ();
|
|
@@ -135,3 +125,16 @@ $.fn.materialPreviewPopover = async function (node)
|
|
|
135
125
|
return this;
|
|
136
126
|
};
|
|
137
127
|
|
|
128
|
+
function connect (field, original)
|
|
129
|
+
{
|
|
130
|
+
switch (field .getType ())
|
|
131
|
+
{
|
|
132
|
+
case X3D .X3DConstants .SFNode:
|
|
133
|
+
case X3D .X3DConstants .MFNode:
|
|
134
|
+
break;
|
|
135
|
+
default:
|
|
136
|
+
original .addFieldInterest (field);
|
|
137
|
+
field .assign (original);
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
@@ -69,18 +69,7 @@ $.fn.texturePreviewPopover = async function (node)
|
|
|
69
69
|
// Assign texture node.
|
|
70
70
|
|
|
71
71
|
for (const field of previewNode .getFields ())
|
|
72
|
-
|
|
73
|
-
switch (field .getType ())
|
|
74
|
-
{
|
|
75
|
-
case X3D .X3DConstants .SFNode:
|
|
76
|
-
case X3D .X3DConstants .MFNode:
|
|
77
|
-
break;
|
|
78
|
-
default:
|
|
79
|
-
field .addReference (node .getField (field .getName ()));
|
|
80
|
-
field .removeFieldInterest (node .getField (field .getName ()));
|
|
81
|
-
break;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
72
|
+
connect (field, node .getField (field .getName ()));
|
|
84
73
|
|
|
85
74
|
appearanceNode .texture = previewNode;
|
|
86
75
|
|
|
@@ -194,3 +183,16 @@ $.fn.texturePreviewPopover = async function (node)
|
|
|
194
183
|
return this;
|
|
195
184
|
};
|
|
196
185
|
|
|
186
|
+
function connect (field, original)
|
|
187
|
+
{
|
|
188
|
+
switch (field .getType ())
|
|
189
|
+
{
|
|
190
|
+
case X3D .X3DConstants .SFNode:
|
|
191
|
+
case X3D .X3DConstants .MFNode:
|
|
192
|
+
break;
|
|
193
|
+
default:
|
|
194
|
+
original .addFieldInterest (field);
|
|
195
|
+
field .assign (original);
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
}
|
package/src/Editors/Library.js
CHANGED
|
@@ -188,7 +188,7 @@ module .exports = new class Library extends Dialog
|
|
|
188
188
|
const node = nodes .find (node => node .text () .toLowerCase () === input)
|
|
189
189
|
?? nodes .sort ((a, b) => a .data ("similarity") - b .data ("similarity")) .at (-1);
|
|
190
190
|
|
|
191
|
-
node .trigger ("
|
|
191
|
+
node .trigger ("dblclick");
|
|
192
192
|
}
|
|
193
193
|
|
|
194
194
|
update ()
|
|
@@ -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
|
|
|
@@ -83,7 +84,7 @@ module .exports = class Materials extends LibraryPane
|
|
|
83
84
|
.addClass ("text")
|
|
84
85
|
.text (`${group .getNodeName ()} ${c + 1}`))
|
|
85
86
|
.appendTo (this .#list)
|
|
86
|
-
.on ("
|
|
87
|
+
.on ("dblclick", () => this .importMaterial (material .getNodeName ())));
|
|
87
88
|
}
|
|
88
89
|
}
|
|
89
90
|
|
|
@@ -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
|
};
|
|
@@ -77,7 +77,7 @@ module .exports = class NodesLibrary extends LibraryPane
|
|
|
77
77
|
.text (node .typeName)
|
|
78
78
|
.attr ("componentName", node .componentInfo .name)
|
|
79
79
|
.appendTo (this .#list)
|
|
80
|
-
.on ("
|
|
80
|
+
.on ("dblclick", () => this .createNode (node .typeName, node .componentInfo .name));
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
|
|
@@ -97,7 +97,7 @@ module .exports = class NodesLibrary extends LibraryPane
|
|
|
97
97
|
.addClass ("node")
|
|
98
98
|
.text (proto .name)
|
|
99
99
|
.appendTo (this .#list)
|
|
100
|
-
.on ("
|
|
100
|
+
.on ("dblclick", () => this .createProto (proto));
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
|
|
@@ -123,7 +123,7 @@ module .exports = class NodesLibrary extends LibraryPane
|
|
|
123
123
|
.text (node .typeName)
|
|
124
124
|
.attr ("componentName", node .componentInfo .name)
|
|
125
125
|
.appendTo (this .#list)
|
|
126
|
-
.on ("
|
|
126
|
+
.on ("dblclick", () => this .createNode (node .typeName, node .componentInfo .name));
|
|
127
127
|
}
|
|
128
128
|
}
|
|
129
129
|
|
|
@@ -24,9 +24,6 @@ module .exports = class OutlineEditor extends OutlineRouteGraph
|
|
|
24
24
|
|
|
25
25
|
electron .ipcRenderer .on ("outline-editor", (event, key, ... args) => this [key] (... args));
|
|
26
26
|
|
|
27
|
-
electron .ipcRenderer .on ("transform-to-zero", () => this .transformToZero ());
|
|
28
|
-
electron .ipcRenderer .on ("remove-empty-groups", () => this .removeEmptyGroups ());
|
|
29
|
-
|
|
30
27
|
this .setup ();
|
|
31
28
|
}
|
|
32
29
|
|
|
@@ -54,26 +51,6 @@ module .exports = class OutlineEditor extends OutlineRouteGraph
|
|
|
54
51
|
]);
|
|
55
52
|
}
|
|
56
53
|
|
|
57
|
-
transformToZero ()
|
|
58
|
-
{
|
|
59
|
-
const
|
|
60
|
-
selection = this .sceneGraph .find (".node.primary, .node.manually"),
|
|
61
|
-
ids = selection .map (function () { return this .id }) .get (),
|
|
62
|
-
nodes = ids .length ? ids .map (id => this .getNode ($(`#${id}`))) : this .executionContext .rootNodes;
|
|
63
|
-
|
|
64
|
-
Editor .transformToZero (this .executionContext, nodes);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
removeEmptyGroups ()
|
|
68
|
-
{
|
|
69
|
-
const
|
|
70
|
-
selection = this .sceneGraph .find (".node.primary, .node.manually"),
|
|
71
|
-
ids = selection .map (function () { return this .id }) .get (),
|
|
72
|
-
nodes = ids .length ? ids .map (id => this .getNode ($(`#${id}`))) : this .executionContext .rootNodes;
|
|
73
|
-
|
|
74
|
-
Editor .removeEmptyGroups (this .executionContext, nodes);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
54
|
showContextMenu (event)
|
|
78
55
|
{
|
|
79
56
|
const element = $(document .elementFromPoint (event .pageX, event .pageY))
|
|
@@ -305,6 +282,14 @@ module .exports = class OutlineEditor extends OutlineRouteGraph
|
|
|
305
282
|
});
|
|
306
283
|
}
|
|
307
284
|
|
|
285
|
+
if (!node .getType () .includes (X3D .X3DConstants .InlineGeometry))
|
|
286
|
+
{
|
|
287
|
+
menu .push ({
|
|
288
|
+
label: _("Convert Node to InlineGeometry..."),
|
|
289
|
+
args: ["convertNodeToInlineFile", element .attr ("id"), executionContext .getId (), node .getId (), "InlineGeometry"],
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
|
|
308
293
|
continue;
|
|
309
294
|
}
|
|
310
295
|
case X3D .X3DConstants .ImageTexture:
|
|
@@ -334,6 +319,21 @@ module .exports = class OutlineEditor extends OutlineRouteGraph
|
|
|
334
319
|
|
|
335
320
|
continue;
|
|
336
321
|
}
|
|
322
|
+
case X3D .X3DConstants .InlineGeometry:
|
|
323
|
+
{
|
|
324
|
+
menu .push ({
|
|
325
|
+
label: _("Open InlineGeometry Scene in New Tab"),
|
|
326
|
+
enabled: node .checkLoadState () === X3D .X3DConstants .COMPLETE_STATE,
|
|
327
|
+
args: ["openFileInNewTab", node .getInternalScene () ?.worldURL],
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
label: _("Fold InlineGeometry Back into Scene"),
|
|
331
|
+
enabled: node .checkLoadState () === X3D .X3DConstants .COMPLETE_STATE && !!node .getGeometry (),
|
|
332
|
+
args: ["foldInlineGeometryBackIntoScene", element .attr ("id"), executionContext .getId (), node .getId ()],
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
continue;
|
|
336
|
+
}
|
|
337
337
|
case X3D .X3DConstants .PixelTexture:
|
|
338
338
|
{
|
|
339
339
|
menu .push ({
|
|
@@ -360,6 +360,15 @@ module .exports = class OutlineEditor extends OutlineRouteGraph
|
|
|
360
360
|
|
|
361
361
|
continue;
|
|
362
362
|
}
|
|
363
|
+
case X3D .X3DConstants .Material:
|
|
364
|
+
{
|
|
365
|
+
menu .push ({
|
|
366
|
+
label: _("Convert Node to PhysicalMaterial"),
|
|
367
|
+
args: ["convertToPhysicalMaterial", element .attr ("id"), executionContext .getId (), node .getId ()],
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
continue;
|
|
371
|
+
}
|
|
363
372
|
case X3D .X3DConstants .X3DPrototypeInstance:
|
|
364
373
|
{
|
|
365
374
|
if (!$.try (() => node .getInnerNode ()))
|
|
@@ -379,7 +388,7 @@ module .exports = class OutlineEditor extends OutlineRouteGraph
|
|
|
379
388
|
{
|
|
380
389
|
menu .push ({
|
|
381
390
|
label: _("Convert Node to Inline File..."),
|
|
382
|
-
args: ["convertNodeToInlineFile", element .attr ("id"), executionContext .getId (), node .getId ()],
|
|
391
|
+
args: ["convertNodeToInlineFile", element .attr ("id"), executionContext .getId (), node .getId (), "Inline"],
|
|
383
392
|
});
|
|
384
393
|
|
|
385
394
|
continue;
|
|
@@ -401,6 +410,15 @@ module .exports = class OutlineEditor extends OutlineRouteGraph
|
|
|
401
410
|
|
|
402
411
|
continue;
|
|
403
412
|
}
|
|
413
|
+
case X3D .X3DConstants .X3DTransformNode:
|
|
414
|
+
{
|
|
415
|
+
menu .push ({
|
|
416
|
+
label: _("Transform to Zero"),
|
|
417
|
+
args: ["transformToZero", element .attr ("id"), executionContext .getId (), node .getId ()],
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
continue;
|
|
421
|
+
}
|
|
404
422
|
case X3D .X3DConstants .X3DUrlObject:
|
|
405
423
|
{
|
|
406
424
|
if (node ._url .some (fileURL => !fileURL .match (/^\s*(?:data|ecmascript|javascript|vrmlscript):/s)))
|
|
@@ -1321,6 +1339,25 @@ module .exports = class OutlineEditor extends OutlineRouteGraph
|
|
|
1321
1339
|
UndoManager .shared .endUndo ();
|
|
1322
1340
|
}
|
|
1323
1341
|
|
|
1342
|
+
transformToZero (id, executionContextId, nodeId)
|
|
1343
|
+
{
|
|
1344
|
+
const
|
|
1345
|
+
executionContext = this .objects .get (executionContextId),
|
|
1346
|
+
transformNode = this .objects .get (nodeId);
|
|
1347
|
+
|
|
1348
|
+
Editor .transformToZero (executionContext, [transformNode]);
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
removeEmptyGroups ()
|
|
1352
|
+
{
|
|
1353
|
+
const
|
|
1354
|
+
selection = this .sceneGraph .find (".node.primary, .node.manually"),
|
|
1355
|
+
ids = selection .map (function () { return this .id }) .get (),
|
|
1356
|
+
nodes = ids .length ? ids .map (id => this .getNode ($(`#${id}`))) : this .executionContext .rootNodes;
|
|
1357
|
+
|
|
1358
|
+
Editor .removeEmptyGroups (this .executionContext, nodes);
|
|
1359
|
+
}
|
|
1360
|
+
|
|
1324
1361
|
convertImageTextureToPixelTexture (id, executionContextId, nodeId)
|
|
1325
1362
|
{
|
|
1326
1363
|
const
|
|
@@ -1438,6 +1475,26 @@ module .exports = class OutlineEditor extends OutlineRouteGraph
|
|
|
1438
1475
|
UndoManager .shared .endUndo ();
|
|
1439
1476
|
}
|
|
1440
1477
|
|
|
1478
|
+
convertToPhysicalMaterial (id, executionContextId, nodeId)
|
|
1479
|
+
{
|
|
1480
|
+
const
|
|
1481
|
+
executionContext = this .objects .get (executionContextId),
|
|
1482
|
+
materialNode = this .objects .get (nodeId);
|
|
1483
|
+
|
|
1484
|
+
// Add undo step.
|
|
1485
|
+
|
|
1486
|
+
UndoManager .shared .beginUndo (_("Convert Node to PhysicalMaterial"));
|
|
1487
|
+
|
|
1488
|
+
const physicalMaterialNode = Editor .convertPhongToPhysical (executionContext, new X3D .SFNode (materialNode))
|
|
1489
|
+
|
|
1490
|
+
if (materialNode .getName ())
|
|
1491
|
+
Editor .updateNamedNode (executionContext, materialNode .getName (), physicalMaterialNode);
|
|
1492
|
+
|
|
1493
|
+
Editor .replaceAllOccurrences (executionContext, materialNode, physicalMaterialNode);
|
|
1494
|
+
|
|
1495
|
+
UndoManager .shared .endUndo ();
|
|
1496
|
+
}
|
|
1497
|
+
|
|
1441
1498
|
async convertPixelTextureToImageTexture (id, executionContextId, nodeId)
|
|
1442
1499
|
{
|
|
1443
1500
|
const
|
|
@@ -1511,8 +1568,8 @@ module .exports = class OutlineEditor extends OutlineRouteGraph
|
|
|
1511
1568
|
|
|
1512
1569
|
const
|
|
1513
1570
|
rootNodes = executionContext .rootNodes .copy (),
|
|
1514
|
-
|
|
1515
|
-
x3dSyntax = await Editor .exportX3D (inlineNode .getInternalScene (),
|
|
1571
|
+
nodesToExport = [... inlineNode .getInternalScene () .rootNodes] .map (node => node .getValue ()),
|
|
1572
|
+
x3dSyntax = await Editor .exportX3D (inlineNode .getInternalScene (), nodesToExport, { importedNodes: true }),
|
|
1516
1573
|
nodes = await Editor .importX3D (executionContext, x3dSyntax);
|
|
1517
1574
|
|
|
1518
1575
|
// Remove imported nodes from root nodes.
|
|
@@ -1557,6 +1614,36 @@ module .exports = class OutlineEditor extends OutlineRouteGraph
|
|
|
1557
1614
|
this .expandTo (childNode, { expandObject: true });
|
|
1558
1615
|
}
|
|
1559
1616
|
|
|
1617
|
+
async foldInlineGeometryBackIntoScene (id, executionContextId, nodeId)
|
|
1618
|
+
{
|
|
1619
|
+
const
|
|
1620
|
+
executionContext = this .objects .get (executionContextId),
|
|
1621
|
+
inlineGeometryNode = this .objects .get (nodeId);
|
|
1622
|
+
|
|
1623
|
+
UndoManager .shared .beginUndo (_("Fold InlineGeometry Back into Scene"));
|
|
1624
|
+
|
|
1625
|
+
const
|
|
1626
|
+
rootNodes = executionContext .rootNodes .copy (),
|
|
1627
|
+
nodesToExport = [inlineGeometryNode .getGeometry ()],
|
|
1628
|
+
x3dSyntax = await Editor .exportX3D (inlineGeometryNode .getInternalScene (), nodesToExport),
|
|
1629
|
+
nodes = await Editor .importX3D (executionContext, x3dSyntax),
|
|
1630
|
+
geometryNode = nodes [0];
|
|
1631
|
+
|
|
1632
|
+
// Remove imported nodes from root nodes.
|
|
1633
|
+
|
|
1634
|
+
Editor .setFieldValue (executionContext, executionContext, executionContext .rootNodes, rootNodes);
|
|
1635
|
+
|
|
1636
|
+
// Insert InlineGeometry node.
|
|
1637
|
+
|
|
1638
|
+
Editor .replaceAllOccurrences (executionContext, inlineGeometryNode, geometryNode);
|
|
1639
|
+
|
|
1640
|
+
UndoManager .shared .endUndo ();
|
|
1641
|
+
|
|
1642
|
+
await this .browser .nextFrame ();
|
|
1643
|
+
|
|
1644
|
+
this .expandTo (geometryNode, { expandObject: true });
|
|
1645
|
+
}
|
|
1646
|
+
|
|
1560
1647
|
protocolToMimeType = new Map ([
|
|
1561
1648
|
["ecmascript:", "application/ecmascript"],
|
|
1562
1649
|
["javascript:", "application/javascript"],
|
|
@@ -1707,7 +1794,7 @@ module .exports = class OutlineEditor extends OutlineRouteGraph
|
|
|
1707
1794
|
UndoManager .shared .endUndo ();
|
|
1708
1795
|
}
|
|
1709
1796
|
|
|
1710
|
-
async convertNodeToInlineFile (id, executionContextId, nodeId)
|
|
1797
|
+
async convertNodeToInlineFile (id, executionContextId, nodeId, typeName)
|
|
1711
1798
|
{
|
|
1712
1799
|
const
|
|
1713
1800
|
executionContext = this .objects .get (executionContextId),
|
|
@@ -1719,7 +1806,15 @@ module .exports = class OutlineEditor extends OutlineRouteGraph
|
|
|
1719
1806
|
if (response .canceled)
|
|
1720
1807
|
return;
|
|
1721
1808
|
|
|
1722
|
-
|
|
1809
|
+
switch (typeName)
|
|
1810
|
+
{
|
|
1811
|
+
case "Inline":
|
|
1812
|
+
UndoManager .shared .beginUndo (_("Convert Node to Inline File"));
|
|
1813
|
+
break;
|
|
1814
|
+
case "InlineGeometry":
|
|
1815
|
+
UndoManager .shared .beginUndo (_("Convert Node to InlineGeometry"));
|
|
1816
|
+
break;
|
|
1817
|
+
}
|
|
1723
1818
|
|
|
1724
1819
|
// Create inline file.
|
|
1725
1820
|
|
|
@@ -1729,7 +1824,7 @@ module .exports = class OutlineEditor extends OutlineRouteGraph
|
|
|
1729
1824
|
|
|
1730
1825
|
await Editor .addComponent (executionContext, "Networking");
|
|
1731
1826
|
|
|
1732
|
-
const inlineNode = executionContext .createNode (
|
|
1827
|
+
const inlineNode = executionContext .createNode (typeName) .getValue ();
|
|
1733
1828
|
|
|
1734
1829
|
inlineNode ._url = [Editor .relativePath (executionContext, response .filePath)];
|
|
1735
1830
|
|