sunrize 1.6.13 → 1.6.14
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 +26 -2
- package/src/Application/Document.js +8 -1
- package/src/Editors/OutlineView.js +14 -11
- package/src/Editors/Primitives.js +1 -0
- package/src/Parser/AudioParser.js +94 -0
- package/src/Parser/ImageParser.js +108 -0
- package/src/Parser/VideoParser.js +113 -0
- package/src/assets/themes/default-template.css +10 -8
- package/src/assets/themes/default.css +10 -8
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sunrize",
|
|
3
3
|
"productName": "Sunrize X3D Editor",
|
|
4
|
-
"version": "1.6.
|
|
4
|
+
"version": "1.6.14",
|
|
5
5
|
"description": "A Multi-Platform X3D Editor",
|
|
6
6
|
"main": "src/main.js",
|
|
7
7
|
"bin": {
|
|
@@ -81,16 +81,16 @@
|
|
|
81
81
|
"dependencies": {
|
|
82
82
|
"capitalize": "^2.0.4",
|
|
83
83
|
"console": "^0.7.2",
|
|
84
|
-
"electron": "^30.0.
|
|
84
|
+
"electron": "^30.0.6",
|
|
85
85
|
"electron-prompt": "^1.7.0",
|
|
86
|
-
"electron-squirrel-startup": "^1.0.
|
|
86
|
+
"electron-squirrel-startup": "^1.0.1",
|
|
87
87
|
"electron-tabs": "^1.0.4",
|
|
88
88
|
"fullname": "^5.0.0",
|
|
89
89
|
"jquery": "^3.7.1",
|
|
90
90
|
"jquery-ui-dist": "^1.13.2",
|
|
91
91
|
"jstree": "^3.3.16",
|
|
92
92
|
"material-icons": "^1.13.12",
|
|
93
|
-
"material-symbols": "^0.
|
|
93
|
+
"material-symbols": "^0.18.0",
|
|
94
94
|
"md5": "^2.3.0",
|
|
95
95
|
"mime-types": "^2.1.35",
|
|
96
96
|
"monaco-editor": "^0.48.0",
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
"string-similarity": "^4.0.4",
|
|
101
101
|
"tweakpane": "^3.1.10",
|
|
102
102
|
"update-electron-app": "^3.0.0",
|
|
103
|
-
"x_ite": "^9.6.
|
|
103
|
+
"x_ite": "^9.6.2"
|
|
104
104
|
},
|
|
105
105
|
"config": {
|
|
106
106
|
"forge": {
|
|
@@ -886,6 +886,29 @@ module .exports = class Application
|
|
|
886
886
|
|
|
887
887
|
async showOpenDialog ({ defaultPath, filters, properties = ["multiSelections"] })
|
|
888
888
|
{
|
|
889
|
+
const defaultFilters = [
|
|
890
|
+
{
|
|
891
|
+
name: _("X3D"),
|
|
892
|
+
extensions: ["x3d", "x3dz", "x3dv", "x3dvz", "x3dj", "x3djz", "wrl", "wrz", "wrl.gz", "vrml"],
|
|
893
|
+
},
|
|
894
|
+
{
|
|
895
|
+
name: _("3D"),
|
|
896
|
+
extensions: ["gltf", "glb", "obj", "stl", "ply", "svg"],
|
|
897
|
+
},
|
|
898
|
+
{
|
|
899
|
+
name: _("Audio"),
|
|
900
|
+
extensions: ["mp3", "wav", "oga", "ogg"],
|
|
901
|
+
},
|
|
902
|
+
{
|
|
903
|
+
name: _("Images"),
|
|
904
|
+
extensions: ["png", "jpg", "jpeg", "gif", "webp", "ktx2"],
|
|
905
|
+
},
|
|
906
|
+
{
|
|
907
|
+
name: _("Video"),
|
|
908
|
+
extensions: ["mp4", "webm", "ogv"],
|
|
909
|
+
},
|
|
910
|
+
];
|
|
911
|
+
|
|
889
912
|
this .pushMenu (this .createDialogMenu ());
|
|
890
913
|
|
|
891
914
|
const response = await electron .dialog .showOpenDialog ({
|
|
@@ -893,9 +916,10 @@ module .exports = class Application
|
|
|
893
916
|
properties: ["openFile", ... properties],
|
|
894
917
|
filters: filters ?? [
|
|
895
918
|
{
|
|
896
|
-
name: _("
|
|
897
|
-
extensions:
|
|
919
|
+
name: _("All Documents"),
|
|
920
|
+
extensions: defaultFilters .reduce ((p, c) => p .concat (c .extensions), [ ]),
|
|
898
921
|
},
|
|
922
|
+
... defaultFilters,
|
|
899
923
|
],
|
|
900
924
|
});
|
|
901
925
|
|
|
@@ -15,6 +15,9 @@ const
|
|
|
15
15
|
ActionKeys = require ("./ActionKeys"),
|
|
16
16
|
Editor = require ("../Undo/Editor"),
|
|
17
17
|
UndoManager = require ("../Undo/UndoManager"),
|
|
18
|
+
ImageParser = require ("../Parser/ImageParser"),
|
|
19
|
+
VideoParser = require ("../Parser/VideoParser"),
|
|
20
|
+
AudioParser = require ("../Parser/AudioParser"),
|
|
18
21
|
_ = require ("./GetText");
|
|
19
22
|
|
|
20
23
|
module .exports = class Document extends Interface
|
|
@@ -36,6 +39,10 @@ module .exports = class Document extends Interface
|
|
|
36
39
|
this .secondaryToolbar = new Dashboard ($("#secondary-toolbar"));
|
|
37
40
|
this .footer = new Footer ($("#footer"));
|
|
38
41
|
this .sidebar = new Sidebar ($("#sidebar"));
|
|
42
|
+
|
|
43
|
+
// Additional Parsers
|
|
44
|
+
|
|
45
|
+
X3D .GoldenGate .addParsers (ImageParser, VideoParser, AudioParser);
|
|
39
46
|
}
|
|
40
47
|
|
|
41
48
|
/**
|
|
@@ -378,7 +385,7 @@ Viewpoint {
|
|
|
378
385
|
|
|
379
386
|
if (this .filePath)
|
|
380
387
|
{
|
|
381
|
-
if (path .extname (this .filePath) .match (/\.(?:
|
|
388
|
+
if (!path .extname (this .filePath) .match (/\.(?:x3dz?|x3dvz?|x3djz?|html)$/i))
|
|
382
389
|
{
|
|
383
390
|
if (!this .fileSaveFileTypeWarning)
|
|
384
391
|
console .warn (`Couldn't save '${this .filePath}'. File type is not supported.`);
|
|
@@ -993,7 +993,7 @@ module .exports = class OutlineView extends Interface
|
|
|
993
993
|
|
|
994
994
|
$("<span></span>")
|
|
995
995
|
.addClass (["toggle-visibility", "button", "material-symbols-outlined"])
|
|
996
|
-
.addClass (node .isHidden () ? "off" : "")
|
|
996
|
+
.addClass (node .isHidden () ? "off" : "on")
|
|
997
997
|
.attr ("title", "Toggle visibility.")
|
|
998
998
|
.text (node .isHidden () ? "visibility_off" : "visibility")
|
|
999
999
|
.appendTo (name);
|
|
@@ -1005,7 +1005,7 @@ module .exports = class OutlineView extends Interface
|
|
|
1005
1005
|
|
|
1006
1006
|
$("<span></span>")
|
|
1007
1007
|
.addClass (["toggle-tool", "button", "material-symbols-outlined"])
|
|
1008
|
-
.addClass (node .valueOf () === node ? "off" : "")
|
|
1008
|
+
.addClass (node .valueOf () === node ? "off" : "on")
|
|
1009
1009
|
.attr ("title", _("Toggle display tool."))
|
|
1010
1010
|
.text ("build_circle")
|
|
1011
1011
|
.appendTo (name);
|
|
@@ -1036,7 +1036,7 @@ module .exports = class OutlineView extends Interface
|
|
|
1036
1036
|
|
|
1037
1037
|
$("<span></span>")
|
|
1038
1038
|
.addClass (["bind-node", "button", "material-symbols-outlined"])
|
|
1039
|
-
.addClass (node ._isBound .getValue () ? "" : "off")
|
|
1039
|
+
.addClass (node ._isBound .getValue () ? "on" : "off")
|
|
1040
1040
|
.attr ("title", _("Bind node."))
|
|
1041
1041
|
.text (node ._isBound .getValue () ? "radio_button_checked" : "radio_button_unchecked")
|
|
1042
1042
|
.appendTo (name);
|
|
@@ -1143,8 +1143,8 @@ module .exports = class OutlineView extends Interface
|
|
|
1143
1143
|
this .sceneGraph
|
|
1144
1144
|
.find (`.node[node-id=${node .getId ()}]`)
|
|
1145
1145
|
.find ("> .item .bind-node")
|
|
1146
|
-
.removeClass ("off")
|
|
1147
|
-
.addClass (node ._isBound .getValue () ? "" : "off")
|
|
1146
|
+
.removeClass (["on", "off"])
|
|
1147
|
+
.addClass (node ._isBound .getValue () ? "on" : "off")
|
|
1148
1148
|
.text (node ._isBound .getValue () ? "radio_button_checked" : "radio_button_unchecked");
|
|
1149
1149
|
}
|
|
1150
1150
|
|
|
@@ -2936,8 +2936,8 @@ module .exports = class OutlineView extends Interface
|
|
|
2936
2936
|
|
|
2937
2937
|
this .sceneGraph .find (`.node[node-id=${node .getId ()}]`)
|
|
2938
2938
|
.find ("> .item .toggle-visibility")
|
|
2939
|
-
.removeClass ("off")
|
|
2940
|
-
.addClass (hidden ? "off" : "")
|
|
2939
|
+
.removeClass (["on", "off"])
|
|
2940
|
+
.addClass (hidden ? "off" : "on")
|
|
2941
2941
|
.text (hidden ? "visibility_off" : "visibility");
|
|
2942
2942
|
}
|
|
2943
2943
|
|
|
@@ -2965,8 +2965,8 @@ module .exports = class OutlineView extends Interface
|
|
|
2965
2965
|
node .setUserData (_changing, true);
|
|
2966
2966
|
|
|
2967
2967
|
this .sceneGraph .find (`.node[node-id=${node .getId ()}] > .item .toggle-tool`)
|
|
2968
|
-
.removeClass ("off")
|
|
2969
|
-
.addClass (tool ? "off" : "");
|
|
2968
|
+
.removeClass (["on", "off"])
|
|
2969
|
+
.addClass (tool ? "off" : "on");
|
|
2970
2970
|
}
|
|
2971
2971
|
|
|
2972
2972
|
activateLayer (event) { }
|
|
@@ -3013,8 +3013,8 @@ module .exports = class OutlineView extends Interface
|
|
|
3013
3013
|
|
|
3014
3014
|
this .sceneGraph .find (`.node[node-id=${node .getId ()}]`)
|
|
3015
3015
|
.find ("> .item .toggle-visibility")
|
|
3016
|
-
.removeClass ("off")
|
|
3017
|
-
.addClass (node .isHidden () ? "off" : "")
|
|
3016
|
+
.removeClass (["on", "off"])
|
|
3017
|
+
.addClass (node .isHidden () ? "off" : "on")
|
|
3018
3018
|
.text (node .isHidden () ? "visibility_off" : "visibility")
|
|
3019
3019
|
})
|
|
3020
3020
|
|
|
@@ -3035,6 +3035,7 @@ module .exports = class OutlineView extends Interface
|
|
|
3035
3035
|
this .sceneGraph .find (`.node[node-id=${node .getId ()}]`)
|
|
3036
3036
|
.find ("> .item .toggle-visibility")
|
|
3037
3037
|
.removeClass ("off")
|
|
3038
|
+
.addClass ("on")
|
|
3038
3039
|
.text ("visibility")
|
|
3039
3040
|
})
|
|
3040
3041
|
}
|
|
@@ -3053,6 +3054,7 @@ module .exports = class OutlineView extends Interface
|
|
|
3053
3054
|
this .sceneGraph .find (`.node[node-id=${node .getId ()}]`)
|
|
3054
3055
|
.find ("> .item .toggle-visibility")
|
|
3055
3056
|
.removeClass ("off")
|
|
3057
|
+
.addClass ("on")
|
|
3056
3058
|
.text ("visibility")
|
|
3057
3059
|
})
|
|
3058
3060
|
}
|
|
@@ -3069,6 +3071,7 @@ module .exports = class OutlineView extends Interface
|
|
|
3069
3071
|
this .sceneGraph .find (`.node[node-id=${node .getId ()}]`)
|
|
3070
3072
|
.find ("> .item .toggle-visibility")
|
|
3071
3073
|
.removeClass ("off")
|
|
3074
|
+
.addClass ("on")
|
|
3072
3075
|
.text ("visibility")
|
|
3073
3076
|
})
|
|
3074
3077
|
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const
|
|
4
|
+
X3D = require ("../X3D"),
|
|
5
|
+
url = require ("url"),
|
|
6
|
+
path = require ("path");
|
|
7
|
+
|
|
8
|
+
class AudioParser extends X3D .X3DParser
|
|
9
|
+
{
|
|
10
|
+
constructor (scene)
|
|
11
|
+
{
|
|
12
|
+
super (scene);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
getEncoding ()
|
|
16
|
+
{
|
|
17
|
+
return "ARRAY_BUFFER";
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
setInput (input)
|
|
21
|
+
{ }
|
|
22
|
+
|
|
23
|
+
isValid ()
|
|
24
|
+
{
|
|
25
|
+
const worldURL = new URL (this .getScene () .worldURL);
|
|
26
|
+
|
|
27
|
+
if (!worldURL .pathname .match (/\.(?:mp3|wav|oga|ogg)$/i))
|
|
28
|
+
return;
|
|
29
|
+
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
parseIntoScene (resolve, reject)
|
|
34
|
+
{
|
|
35
|
+
this .audio ()
|
|
36
|
+
.then (resolve)
|
|
37
|
+
.catch (reject);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async audio ()
|
|
41
|
+
{
|
|
42
|
+
const
|
|
43
|
+
browser = this .getBrowser (),
|
|
44
|
+
scene = this .getScene ();
|
|
45
|
+
|
|
46
|
+
scene .setEncoding ("AUDIO");
|
|
47
|
+
scene .setProfile (browser .getProfile ("Interchange"));
|
|
48
|
+
scene .addComponent (browser .getComponent ("Sound", 1));
|
|
49
|
+
|
|
50
|
+
await this .loadComponents ();
|
|
51
|
+
|
|
52
|
+
// Rectangle
|
|
53
|
+
|
|
54
|
+
const
|
|
55
|
+
soundNode = scene .createNode ("Sound"),
|
|
56
|
+
audioClipNode = scene .createNode ("AudioClip");
|
|
57
|
+
|
|
58
|
+
audioClipNode .url = new X3D .MFString (this .getURL (scene .worldURL));
|
|
59
|
+
audioClipNode .loop = true;
|
|
60
|
+
|
|
61
|
+
soundNode .source = audioClipNode;
|
|
62
|
+
|
|
63
|
+
scene .rootNodes .push (soundNode);
|
|
64
|
+
|
|
65
|
+
// Name
|
|
66
|
+
|
|
67
|
+
const
|
|
68
|
+
worldURL = new URL (scene .worldURL),
|
|
69
|
+
name = worldURL .pathname .match (/([^\/]+)\.[^.]+$/);
|
|
70
|
+
|
|
71
|
+
if (name)
|
|
72
|
+
{
|
|
73
|
+
audioClipNode .description = decodeURIComponent (name [1]);
|
|
74
|
+
|
|
75
|
+
scene .addNamedNode (this .sanitizeName (decodeURIComponent (name [1])), soundNode);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return scene;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
getURL (worldURL)
|
|
82
|
+
{
|
|
83
|
+
try
|
|
84
|
+
{
|
|
85
|
+
return encodeURIComponent (path .basename (url .fileURLToPath (worldURL)));
|
|
86
|
+
}
|
|
87
|
+
catch
|
|
88
|
+
{
|
|
89
|
+
return worldURL;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
module .exports = AudioParser;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const
|
|
4
|
+
X3D = require ("../X3D"),
|
|
5
|
+
url = require ("url"),
|
|
6
|
+
path = require ("path");
|
|
7
|
+
|
|
8
|
+
class ImageParser extends X3D .X3DParser
|
|
9
|
+
{
|
|
10
|
+
constructor (scene)
|
|
11
|
+
{
|
|
12
|
+
super (scene);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
getEncoding ()
|
|
16
|
+
{
|
|
17
|
+
return "ARRAY_BUFFER";
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
setInput (input)
|
|
21
|
+
{ }
|
|
22
|
+
|
|
23
|
+
isValid ()
|
|
24
|
+
{
|
|
25
|
+
const worldURL = new URL (this .getScene () .worldURL);
|
|
26
|
+
|
|
27
|
+
if (!worldURL .pathname .match (/\.(?:png|jpg|jpeg|gif|webp|ktx2)$/i))
|
|
28
|
+
return;
|
|
29
|
+
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
parseIntoScene (resolve, reject)
|
|
34
|
+
{
|
|
35
|
+
this .image ()
|
|
36
|
+
.then (resolve)
|
|
37
|
+
.catch (reject);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async image ()
|
|
41
|
+
{
|
|
42
|
+
const
|
|
43
|
+
browser = this .getBrowser (),
|
|
44
|
+
scene = this .getScene ();
|
|
45
|
+
|
|
46
|
+
scene .setEncoding ("IMAGE");
|
|
47
|
+
scene .setProfile (browser .getProfile ("Interchange"));
|
|
48
|
+
scene .addComponent (browser .getComponent ("Geometry2D", 1));
|
|
49
|
+
|
|
50
|
+
await this .loadComponents ();
|
|
51
|
+
|
|
52
|
+
// Rectangle
|
|
53
|
+
|
|
54
|
+
const
|
|
55
|
+
transformNode = scene .createNode ("Transform"),
|
|
56
|
+
shapeNode = scene .createNode ("Shape"),
|
|
57
|
+
appearanceNode = scene .createNode ("Appearance"),
|
|
58
|
+
textureNode = scene .createNode ("ImageTexture"),
|
|
59
|
+
rectangleNode = scene .createNode ("Rectangle2D");
|
|
60
|
+
|
|
61
|
+
textureNode .url = new X3D .MFString (this .getURL (scene .worldURL));
|
|
62
|
+
textureNode .repeatS = false;
|
|
63
|
+
textureNode .repeatT = false;
|
|
64
|
+
|
|
65
|
+
await textureNode .getValue () .loading ();
|
|
66
|
+
|
|
67
|
+
appearanceNode .texture = textureNode;
|
|
68
|
+
|
|
69
|
+
rectangleNode .size .x = textureNode .getValue () .getWidth () / 72 * 0.0254;
|
|
70
|
+
rectangleNode .size .y = textureNode .getValue () .getHeight () / 72 * 0.0254;
|
|
71
|
+
|
|
72
|
+
shapeNode .appearance = appearanceNode;
|
|
73
|
+
shapeNode .geometry = rectangleNode;
|
|
74
|
+
|
|
75
|
+
transformNode .children .push (shapeNode);
|
|
76
|
+
|
|
77
|
+
scene .rootNodes .push (transformNode);
|
|
78
|
+
|
|
79
|
+
// Name
|
|
80
|
+
|
|
81
|
+
const
|
|
82
|
+
worldURL = new URL (scene .worldURL),
|
|
83
|
+
name = worldURL .pathname .match (/([^\/]+)\.[^.]+$/);
|
|
84
|
+
|
|
85
|
+
if (name)
|
|
86
|
+
{
|
|
87
|
+
textureNode .description = decodeURIComponent (name [1]);
|
|
88
|
+
|
|
89
|
+
scene .addNamedNode (this .sanitizeName (decodeURIComponent (name [1])), transformNode);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return scene;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
getURL (worldURL)
|
|
96
|
+
{
|
|
97
|
+
try
|
|
98
|
+
{
|
|
99
|
+
return encodeURIComponent (path .basename (url .fileURLToPath (worldURL)));
|
|
100
|
+
}
|
|
101
|
+
catch
|
|
102
|
+
{
|
|
103
|
+
return worldURL;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
module .exports = ImageParser;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const
|
|
4
|
+
X3D = require ("../X3D"),
|
|
5
|
+
url = require ("url"),
|
|
6
|
+
path = require ("path");
|
|
7
|
+
|
|
8
|
+
class VideoParser extends X3D .X3DParser
|
|
9
|
+
{
|
|
10
|
+
constructor (scene)
|
|
11
|
+
{
|
|
12
|
+
super (scene);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
getEncoding ()
|
|
16
|
+
{
|
|
17
|
+
return "ARRAY_BUFFER";
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
setInput (input)
|
|
21
|
+
{ }
|
|
22
|
+
|
|
23
|
+
isValid ()
|
|
24
|
+
{
|
|
25
|
+
const worldURL = new URL (this .getScene () .worldURL);
|
|
26
|
+
|
|
27
|
+
if (!worldURL .pathname .match (/\.(?:mp4|webm|ogv)$/i))
|
|
28
|
+
return;
|
|
29
|
+
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
parseIntoScene (resolve, reject)
|
|
34
|
+
{
|
|
35
|
+
this .video ()
|
|
36
|
+
.then (resolve)
|
|
37
|
+
.catch (reject);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async video ()
|
|
41
|
+
{
|
|
42
|
+
const
|
|
43
|
+
browser = this .getBrowser (),
|
|
44
|
+
scene = this .getScene ();
|
|
45
|
+
|
|
46
|
+
scene .setEncoding ("VIDEO");
|
|
47
|
+
scene .setProfile (browser .getProfile ("Interchange"));
|
|
48
|
+
scene .addComponent (browser .getComponent ("Geometry2D", 1));
|
|
49
|
+
scene .addComponent (browser .getComponent ("Sound", 1));
|
|
50
|
+
|
|
51
|
+
await this .loadComponents ();
|
|
52
|
+
|
|
53
|
+
// Rectangle
|
|
54
|
+
|
|
55
|
+
const
|
|
56
|
+
transformNode = scene .createNode ("Transform"),
|
|
57
|
+
shapeNode = scene .createNode ("Shape"),
|
|
58
|
+
appearanceNode = scene .createNode ("Appearance"),
|
|
59
|
+
textureNode = scene .createNode ("MovieTexture"),
|
|
60
|
+
rectangleNode = scene .createNode ("Rectangle2D"),
|
|
61
|
+
soundNode = scene .createNode ("Sound");
|
|
62
|
+
|
|
63
|
+
textureNode .url = new X3D .MFString (this .getURL (scene .worldURL));
|
|
64
|
+
textureNode .loop = true;
|
|
65
|
+
textureNode .repeatS = false;
|
|
66
|
+
textureNode .repeatT = false;
|
|
67
|
+
|
|
68
|
+
await textureNode .getValue () .loading ();
|
|
69
|
+
|
|
70
|
+
appearanceNode .texture = textureNode;
|
|
71
|
+
|
|
72
|
+
rectangleNode .size .x = textureNode .getValue () .getWidth () / 72 * 0.0254;
|
|
73
|
+
rectangleNode .size .y = textureNode .getValue () .getHeight () / 72 * 0.0254;
|
|
74
|
+
|
|
75
|
+
shapeNode .appearance = appearanceNode;
|
|
76
|
+
shapeNode .geometry = rectangleNode;
|
|
77
|
+
|
|
78
|
+
soundNode .source = textureNode;
|
|
79
|
+
|
|
80
|
+
transformNode .children .push (shapeNode, soundNode);
|
|
81
|
+
|
|
82
|
+
scene .rootNodes .push (transformNode);
|
|
83
|
+
|
|
84
|
+
// Name
|
|
85
|
+
|
|
86
|
+
const
|
|
87
|
+
worldURL = new URL (scene .worldURL),
|
|
88
|
+
name = worldURL .pathname .match (/([^\/]+)\.[^.]+$/);
|
|
89
|
+
|
|
90
|
+
if (name)
|
|
91
|
+
{
|
|
92
|
+
textureNode .description = decodeURIComponent (name [1]);
|
|
93
|
+
|
|
94
|
+
scene .addNamedNode (this .sanitizeName (decodeURIComponent (name [1])), transformNode);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return scene;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
getURL (worldURL)
|
|
101
|
+
{
|
|
102
|
+
try
|
|
103
|
+
{
|
|
104
|
+
return encodeURIComponent (path .basename (url .fileURLToPath (worldURL)));
|
|
105
|
+
}
|
|
106
|
+
catch
|
|
107
|
+
{
|
|
108
|
+
return worldURL;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
module .exports = VideoParser;
|
|
@@ -549,9 +549,6 @@ tr.disabled ~ tr > td > div {
|
|
|
549
549
|
background-color: var(--system-gray7);
|
|
550
550
|
}
|
|
551
551
|
|
|
552
|
-
#secondary-toolbar {
|
|
553
|
-
}
|
|
554
|
-
|
|
555
552
|
/* Dialog */
|
|
556
553
|
|
|
557
554
|
.dialog ::selection {
|
|
@@ -1010,13 +1007,15 @@ body.dark .ui-widget .library-list .component {
|
|
|
1010
1007
|
|
|
1011
1008
|
/* Outline Editor */
|
|
1012
1009
|
|
|
1013
|
-
.outline-editor {
|
|
1014
|
-
}
|
|
1015
|
-
|
|
1016
1010
|
.scene-graph .material-symbols-outlined {
|
|
1017
1011
|
font-size: var(--font-size);
|
|
1018
1012
|
position: relative;
|
|
1019
1013
|
top: 2.5px;
|
|
1014
|
+
color: var(--system-blue);
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
.scene-graph .material-symbols-outlined:hover {
|
|
1018
|
+
color: var(--system-gray0);
|
|
1020
1019
|
}
|
|
1021
1020
|
|
|
1022
1021
|
.scene-graph .hidden {
|
|
@@ -1162,7 +1161,6 @@ body.dark .ui-widget .library-list .component {
|
|
|
1162
1161
|
position: relative;
|
|
1163
1162
|
top: 4px;
|
|
1164
1163
|
margin-left: 10px;
|
|
1165
|
-
color: black;
|
|
1166
1164
|
font-variation-settings: 'GRAD' 200;
|
|
1167
1165
|
}
|
|
1168
1166
|
|
|
@@ -1319,7 +1317,11 @@ body.dark .ui-widget .library-list .component {
|
|
|
1319
1317
|
}
|
|
1320
1318
|
|
|
1321
1319
|
.scene-graph .button.off {
|
|
1322
|
-
color: var(--
|
|
1320
|
+
color: var(--system-gray1);
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1323
|
+
.scene-graph .button.off:hover {
|
|
1324
|
+
color: var(--system-gray0);
|
|
1323
1325
|
}
|
|
1324
1326
|
|
|
1325
1327
|
/* Spectrum Color Picker */
|
|
@@ -549,9 +549,6 @@ tr.disabled ~ tr > td > div {
|
|
|
549
549
|
background-color: var(--system-gray7);
|
|
550
550
|
}
|
|
551
551
|
|
|
552
|
-
#secondary-toolbar {
|
|
553
|
-
}
|
|
554
|
-
|
|
555
552
|
/* Dialog */
|
|
556
553
|
|
|
557
554
|
.dialog ::selection {
|
|
@@ -1010,13 +1007,15 @@ body.dark .ui-widget .library-list .component {
|
|
|
1010
1007
|
|
|
1011
1008
|
/* Outline Editor */
|
|
1012
1009
|
|
|
1013
|
-
.outline-editor {
|
|
1014
|
-
}
|
|
1015
|
-
|
|
1016
1010
|
.scene-graph .material-symbols-outlined {
|
|
1017
1011
|
font-size: var(--font-size);
|
|
1018
1012
|
position: relative;
|
|
1019
1013
|
top: 2.5px;
|
|
1014
|
+
color: var(--system-blue);
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
.scene-graph .material-symbols-outlined:hover {
|
|
1018
|
+
color: var(--system-gray0);
|
|
1020
1019
|
}
|
|
1021
1020
|
|
|
1022
1021
|
.scene-graph .hidden {
|
|
@@ -1162,7 +1161,6 @@ body.dark .ui-widget .library-list .component {
|
|
|
1162
1161
|
position: relative;
|
|
1163
1162
|
top: 4px;
|
|
1164
1163
|
margin-left: 10px;
|
|
1165
|
-
color: black;
|
|
1166
1164
|
font-variation-settings: 'GRAD' 200;
|
|
1167
1165
|
}
|
|
1168
1166
|
|
|
@@ -1319,7 +1317,11 @@ body.dark .ui-widget .library-list .component {
|
|
|
1319
1317
|
}
|
|
1320
1318
|
|
|
1321
1319
|
.scene-graph .button.off {
|
|
1322
|
-
color: var(--
|
|
1320
|
+
color: var(--system-gray1);
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1323
|
+
.scene-graph .button.off:hover {
|
|
1324
|
+
color: var(--system-gray0);
|
|
1323
1325
|
}
|
|
1324
1326
|
|
|
1325
1327
|
/* Spectrum Color Picker */
|