sunrize 1.7.1 → 1.7.2

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": "1.7.1",
4
+ "version": "1.7.2",
5
5
  "description": "A Multi-Platform X3D Editor",
6
6
  "main": "src/main.js",
7
7
  "bin": {
@@ -66,6 +66,11 @@
66
66
  "name": "Holger Seelig",
67
67
  "email": "holger.seelig@gmail.com",
68
68
  "url": "https://github.com/create3000"
69
+ },
70
+ {
71
+ "name": "John Carlson",
72
+ "email": "yottzumm@gmail.com",
73
+ "url": "https://github.com/coderextreme"
69
74
  }
70
75
  ],
71
76
  "funding": {
@@ -567,7 +567,7 @@ module .exports = class Application
567
567
  type: "radio",
568
568
  checked: this .menuOptions .primitiveQuality === "LOW",
569
569
  click: () => this .mainWindow .webContents .send ("primitive-quality", "LOW"),
570
- }
570
+ },
571
571
  ],
572
572
  },
573
573
  {
@@ -590,9 +590,80 @@ module .exports = class Application
590
590
  type: "radio",
591
591
  checked: this .menuOptions .textureQuality === "LOW",
592
592
  click: () => this .mainWindow .webContents .send ("texture-quality", "LOW"),
593
- }
593
+ },
594
594
  ],
595
595
  },
596
+ {
597
+ label: _("Color Space"),
598
+ submenu: [
599
+ {
600
+ label: _("Linear"),
601
+ type: "radio",
602
+ checked: this .menuOptions .colorSpace === "LINEAR",
603
+ click: () => this .mainWindow .webContents .send ("color-space", "LINEAR"),
604
+ },
605
+ {
606
+ label: _("Linear When PhysicalMaterial"),
607
+ type: "radio",
608
+ checked: this .menuOptions .colorSpace === "LINEAR_WHEN_PHYSICAL_MATERIAL",
609
+ click: () => this .mainWindow .webContents .send ("color-space", "LINEAR_WHEN_PHYSICAL_MATERIAL"),
610
+ },
611
+ {
612
+ label: _("sRGB"),
613
+ type: "radio",
614
+ checked: this .menuOptions .colorSpace === "SRGB",
615
+ click: () => this .mainWindow .webContents .send ("color-space", "SRGB"),
616
+ },
617
+ ],
618
+ },
619
+ {
620
+ label: _("Tone Mapping"),
621
+ submenu: [
622
+ {
623
+ label: _("KHR PBR Neutral"),
624
+ type: "radio",
625
+ checked: this .menuOptions .toneMapping === "KHR_PBR_NEUTRAL",
626
+ click: () => this .mainWindow .webContents .send ("tone-mapping", "KHR_PBR_NEUTRAL"),
627
+ },
628
+ {
629
+ label: _("ACES Hill Exposure Boost"),
630
+ type: "radio",
631
+ checked: this .menuOptions .toneMapping === "ACES_HILL_EXPOSURE_BOOST",
632
+ click: () => this .mainWindow .webContents .send ("tone-mapping", "ACES_HILL_EXPOSURE_BOOST"),
633
+ },
634
+ {
635
+ label: _("ACES Hill"),
636
+ type: "radio",
637
+ checked: this .menuOptions .toneMapping === "ACES_HILL",
638
+ click: () => this .mainWindow .webContents .send ("tone-mapping", "ACES_HILL"),
639
+ },
640
+ {
641
+ label: _("ACES Narkowicz"),
642
+ type: "radio",
643
+ checked: this .menuOptions .toneMapping === "ACES_NARKOWICZ",
644
+ click: () => this .mainWindow .webContents .send ("tone-mapping", "ACES_NARKOWICZ"),
645
+ },
646
+ {
647
+ label: _("None"),
648
+ type: "radio",
649
+ checked: this .menuOptions .toneMapping === "NONE",
650
+ click: () => this .mainWindow .webContents .send ("tone-mapping", "NONE"),
651
+ },
652
+ ],
653
+ },
654
+ {
655
+ label: _("Order Independent Transparency"),
656
+ type: "checkbox",
657
+ checked: this .menuOptions .orderIndependentTransparency,
658
+ click: () => this .mainWindow .webContents .send ("order-independent-transparency", !this .menuOptions .orderIndependentTransparency),
659
+ },
660
+ {
661
+ label: _("Logarithmic Depth Buffer"),
662
+ type: "checkbox",
663
+ checked: this .menuOptions .logarithmicDepthBuffer,
664
+ click: () => this .mainWindow .webContents .send ("logarithmic-depth-buffer", !this .menuOptions .logarithmicDepthBuffer),
665
+ },
666
+ { type: "separator" },
596
667
  {
597
668
  label: _("Display Rubberband"),
598
669
  type: "checkbox",
@@ -40,6 +40,9 @@ module .exports = class Document extends Interface
40
40
  this .footer = new Footer ($("#footer"));
41
41
  this .sidebar = new Sidebar ($("#sidebar"));
42
42
 
43
+ // Prevent scrolling when Panel becomes larger.
44
+ $("#vertical-splitter") .on ("scroll", () => $("#vertical-splitter") .scrollTop (0));
45
+
43
46
  // Additional Parsers
44
47
 
45
48
  X3D .GoldenGate .addParsers (ImageParser, VideoParser, AudioParser);
@@ -91,11 +94,15 @@ module .exports = class Document extends Interface
91
94
 
92
95
  // View Menu
93
96
 
94
- electron .ipcRenderer .on ("primitive-quality", (event, value) => this .setPrimitiveQuality (value));
95
- electron .ipcRenderer .on ("texture-quality", (event, value) => this .setTextureQuality (value));
96
- electron .ipcRenderer .on ("display-rubberband", (event, value) => this .setDisplayRubberband (value));
97
- electron .ipcRenderer .on ("display-timings", (event, value) => this .setDisplayTimings (value));
98
- electron .ipcRenderer .on ("show-library", (event) => this .showLibrary ());
97
+ electron .ipcRenderer .on ("primitive-quality", (event, value) => this .setPrimitiveQuality (value));
98
+ electron .ipcRenderer .on ("texture-quality", (event, value) => this .setTextureQuality (value));
99
+ electron .ipcRenderer .on ("color-space", (event, value) => this .setColorSpace (value));
100
+ electron .ipcRenderer .on ("tone-mapping", (event, value) => this .setToneMapping (value));
101
+ electron .ipcRenderer .on ("order-independent-transparency", (event, value) => this .setOrderIndependentTransparency (value));
102
+ electron .ipcRenderer .on ("logarithmic-depth-buffer", (event, value) => this .setLogarithmicDepthBuffer (value));
103
+ electron .ipcRenderer .on ("display-rubberband", (event, value) => this .setDisplayRubberband (value));
104
+ electron .ipcRenderer .on ("display-timings", (event, value) => this .setDisplayTimings (value));
105
+ electron .ipcRenderer .on ("show-library", (event) => this .showLibrary ());
99
106
 
100
107
  // Layout Menu
101
108
 
@@ -120,10 +127,19 @@ module .exports = class Document extends Interface
120
127
 
121
128
  // Connect browser options.
122
129
 
123
- this .browser .getBrowserOptions () .getField ("PrimitiveQuality") .addInterest ("set_primitiveQuality", this);
124
- this .browser .getBrowserOptions () .getField ("TextureQuality") .addInterest ("set_textureQuality", this);
125
- this .browser .getBrowserOptions () .getField ("Rubberband") .addInterest ("set_rubberband", this);
126
- this .browser .getBrowserOptions () .getField ("Timings") .addInterest ("set_timings", this);
130
+ const browserOptions = [
131
+ "PrimitiveQuality",
132
+ "TextureQuality",
133
+ "ColorSpace",
134
+ "ToneMapping",
135
+ "OrderIndependentTransparency",
136
+ "LogarithmicDepthBuffer",
137
+ "Rubberband",
138
+ "Timings",
139
+ ];
140
+
141
+ for (const option of browserOptions)
142
+ this .browser .getBrowserOptions () .getField (option) .addInterest (`set_${option}`, this);
127
143
 
128
144
  this .browser .setBrowserOption ("AlwaysUpdateGeometries", true);
129
145
  this .browser .setBrowserOption ("MetadataReference", require ("../../package.json") .homepage);
@@ -152,6 +168,10 @@ module .exports = class Document extends Interface
152
168
  inferProfileAndComponents: true,
153
169
  primitiveQuality: "MEDIUM",
154
170
  textureQuality: "MEDIUM",
171
+ colorSpace: "LINEAR_WHEN_PHYSICAL_MATERIAL",
172
+ toneMapping: "NONE",
173
+ orderIndependentTransparency: false,
174
+ logarithmicDepthBuffer: false,
155
175
  rubberband: true,
156
176
  timings: false,
157
177
  });
@@ -160,10 +180,14 @@ module .exports = class Document extends Interface
160
180
 
161
181
  // Configure browser options.
162
182
 
163
- this .setPrimitiveQuality (this .config .file .primitiveQuality);
164
- this .setTextureQuality (this .config .file .textureQuality);
165
- this .setDisplayRubberband (this .config .file .rubberband);
166
- this .setDisplayTimings (this .config .file .timings);
183
+ this .setPrimitiveQuality (this .config .file .primitiveQuality);
184
+ this .setTextureQuality (this .config .file .textureQuality);
185
+ this .setColorSpace (this .config .file .colorSpace);
186
+ this .setToneMapping (this .config .file .toneMapping);
187
+ this .setOrderIndependentTransparency (this .config .file .orderIndependentTransparency);
188
+ this .setLogarithmicDepthBuffer (this .config .file .logarithmicDepthBuffer);
189
+ this .setDisplayRubberband (this .config .file .rubberband);
190
+ this .setDisplayTimings (this .config .file .timings);
167
191
 
168
192
  // Configure grids.
169
193
 
@@ -583,7 +607,7 @@ Viewpoint {
583
607
  this .browser .setDescription (`Primitive Quality: ${value .toLowerCase ()}`);
584
608
  }
585
609
 
586
- set_primitiveQuality ()
610
+ set_PrimitiveQuality ()
587
611
  {
588
612
  this .config .file .primitiveQuality = this .browser .getBrowserOption ("PrimitiveQuality");
589
613
 
@@ -600,13 +624,81 @@ Viewpoint {
600
624
  this .browser .setDescription (`Texture Quality: ${value .toLowerCase ()}`);
601
625
  }
602
626
 
603
- set_textureQuality ()
627
+ set_TextureQuality ()
604
628
  {
605
629
  this .config .file .textureQuality = this .browser .getBrowserOption ("TextureQuality");
606
630
 
607
631
  this .updateMenu ();
608
632
  }
609
633
 
634
+ /**
635
+ *
636
+ * @param {string} value
637
+ */
638
+ setColorSpace (value)
639
+ {
640
+ this .browser .setBrowserOption ("ColorSpace", value);
641
+ this .browser .setDescription (`Color Space: ${value}`);
642
+ }
643
+
644
+ set_ColorSpace ()
645
+ {
646
+ this .config .file .colorSpace = this .browser .getBrowserOption ("ColorSpace");
647
+
648
+ this .updateMenu ();
649
+ }
650
+
651
+ /**
652
+ *
653
+ * @param {string} value
654
+ */
655
+ setToneMapping (value)
656
+ {
657
+ this .browser .setBrowserOption ("ToneMapping", value);
658
+ this .browser .setDescription (`Tone Mapping: ${value}`);
659
+ }
660
+
661
+ set_ToneMapping ()
662
+ {
663
+ this .config .file .toneMapping = this .browser .getBrowserOption ("ToneMapping");
664
+
665
+ this .updateMenu ();
666
+ }
667
+
668
+ /**
669
+ *
670
+ * @param {boolean} value
671
+ */
672
+ setOrderIndependentTransparency (value)
673
+ {
674
+ this .browser .setBrowserOption ("OrderIndependentTransparency", value);
675
+ this .browser .setDescription (`OrderIndependentTransparency: ${value ? "on" : "off"}`);
676
+ }
677
+
678
+ set_OrderIndependentTransparency ()
679
+ {
680
+ this .config .file .orderIndependentTransparency = this .browser .getBrowserOption ("OrderIndependentTransparency");
681
+
682
+ this .updateMenu ();
683
+ }
684
+
685
+ /**
686
+ *
687
+ * @param {boolean} value
688
+ */
689
+ setLogarithmicDepthBuffer (value)
690
+ {
691
+ this .browser .setBrowserOption ("LogarithmicDepthBuffer", value);
692
+ this .browser .setDescription (`LogarithmicDepthBuffer: ${value ? "on" : "off"}`);
693
+ }
694
+
695
+ set_LogarithmicDepthBuffer ()
696
+ {
697
+ this .config .file .logarithmicDepthBuffer = this .browser .getBrowserOption ("LogarithmicDepthBuffer");
698
+
699
+ this .updateMenu ();
700
+ }
701
+
610
702
  /**
611
703
  *
612
704
  * @param {boolean} value
@@ -617,7 +709,7 @@ Viewpoint {
617
709
  this .browser .setDescription (`Rubberband: ${value ? "on" : "off"}`);
618
710
  }
619
711
 
620
- set_rubberband ()
712
+ set_Rubberband ()
621
713
  {
622
714
  this .config .file .rubberband = this .browser .getBrowserOption ("Rubberband");
623
715
 
@@ -633,7 +725,7 @@ Viewpoint {
633
725
  this .browser .setBrowserOption ("Timings", value);
634
726
  }
635
727
 
636
- set_timings ()
728
+ set_Timings ()
637
729
  {
638
730
  this .config .file .timings = this .browser .getBrowserOption ("Timings");
639
731
 
@@ -646,6 +738,10 @@ Viewpoint {
646
738
  {
647
739
  primitiveQuality: this .config .file .primitiveQuality,
648
740
  textureQuality: this .config .file .textureQuality,
741
+ colorSpace: this .config .file .colorSpace,
742
+ toneMapping: this .config .file .toneMapping,
743
+ orderIndependentTransparency: this .config .file .orderIndependentTransparency,
744
+ logarithmicDepthBuffer: this .config .file .logarithmicDepthBuffer,
649
745
  rubberband: this .config .file .rubberband,
650
746
  timings: this .config .file .timings,
651
747
  });
@@ -209,4 +209,44 @@ module .exports = class Interface
209
209
  }
210
210
 
211
211
  configure () { }
212
+
213
+ linearToSRGB (node, color)
214
+ {
215
+ if (this .browser .getBrowserOption ("ColorSpace") === "SRGB")
216
+ return color;
217
+
218
+ if (this .browser .getBrowserOption ("ColorSpace") === "LINEAR_WHEN_PHYSICAL_MATERIAL" && !this .isPhysical (node))
219
+ {
220
+ return color;
221
+ }
222
+
223
+ return color .linearToSRGB ();
224
+ }
225
+
226
+ sRGBToLinear (node, color)
227
+ {
228
+ if (this .browser .getBrowserOption ("ColorSpace") === "SRGB")
229
+ return color;
230
+
231
+ if (this .browser .getBrowserOption ("ColorSpace") === "LINEAR_WHEN_PHYSICAL_MATERIAL" && !this .isPhysical (node))
232
+ {
233
+ return color;
234
+ }
235
+
236
+ return color .sRGBToLinear ();
237
+ }
238
+
239
+ isPhysical (node)
240
+ {
241
+ if (node .getType () .includes (X3D .X3DConstants .PhysicalMaterial))
242
+ return true;
243
+
244
+ if (node .getType () .includes (X3D .X3DConstants .X3DMaterialExtensionNode))
245
+ return true;
246
+
247
+ if (node .getType () .includes (X3D .X3DConstants .SpecularGlossinessMaterial))
248
+ return true;
249
+
250
+ return false;
251
+ }
212
252
  };
@@ -88,6 +88,10 @@ module .exports = new class Tabs
88
88
 
89
89
  this .forwardToActiveTab ("primitive-quality");
90
90
  this .forwardToActiveTab ("texture-quality");
91
+ this .forwardToActiveTab ("color-space");
92
+ this .forwardToActiveTab ("tone-mapping");
93
+ this .forwardToActiveTab ("order-independent-transparency");
94
+ this .forwardToActiveTab ("logarithmic-depth-buffer");
91
95
  this .forwardToActiveTab ("display-rubberband");
92
96
  this .forwardToActiveTab ("display-timings");
93
97
  this .forwardToActiveTab ("show-library");
@@ -3,7 +3,11 @@ const
3
3
  fs = require ("fs"),
4
4
  path = require ("path");
5
5
 
6
- const X3DUOM = $($.parseXML (fs .readFileSync (path .join (__dirname, "..", "assets", "x3duom.xml"), "utf-8")));
6
+ const
7
+ X3DUOM = $($.parseXML (fs .readFileSync (path .join (__dirname, "..", "assets", "x3duom.xml"), "utf-8"))),
8
+ X_ITE = $($.parseXML (fs .readFileSync (path .join (__dirname, "..", "assets", "x3duom-x_ite.xml"), "utf-8")));
9
+
10
+ X3DUOM .find ("ConcreteNodes") .append (X_ITE .find ("ConcreteNode"));
7
11
 
8
12
  // emissiveColor fix
9
13
  X3DUOM .find ("AbstractNodeType[name=X3DOneSidedMaterialNode]")
@@ -24,50 +28,4 @@ X3DUOM .find ("ConcreteNode[name=Shape]")
24
28
  X3DUOM .find ("ConcreteNode[name=ParticleSystem]")
25
29
  .append (X3DUOM .find ("field[name=pointerEvents]") .first () .clone ());
26
30
 
27
- // InstancedShape
28
- X3DUOM .find ("ConcreteNode[name=Shape]") .clone ()
29
- .appendTo (X3DUOM .find ("ConcreteNodes"))
30
- .attr ("name", "InstancedShape")
31
- .append ($(X3DUOM [0] .createElement ("field"))
32
- .attr ("name", "translations")
33
- .attr ("type", "MFVec3f")
34
- .attr ("accessType", "inputOutput")
35
- .attr ("description", "List of translations, one for each instance."))
36
- .append ($(X3DUOM [0] .createElement ("field"))
37
- .attr ("name", "rotations")
38
- .attr ("type", "MFRotation")
39
- .attr ("accessType", "inputOutput")
40
- .attr ("description", "List of rotations, one for each instance."))
41
- .append ($(X3DUOM [0] .createElement ("field"))
42
- .attr ("name", "scales")
43
- .attr ("type", "MFVec3f")
44
- .attr ("accessType", "inputOutput")
45
- .attr ("description", "List of scales, one for each instance."));
46
-
47
- // BlendMode
48
- const BlendMode = X3DUOM .find ("ConcreteNode[name=Material]") .clone ();
49
-
50
- BlendMode .find ("field:not([name=metadata])") .remove ();
51
-
52
- BlendMode .find ("InterfaceDefinition")
53
- .attr ("specificationUrl", "https://create3000.github.io/x_ite/components/x-ite/blendmode/")
54
- .attr ("appinfo", "BlendMode controls how pixels of an objects are drawn. Pixels can be drawn using a function that blends the incoming (source) RGBA values with the RGBA values that are already in the frame buffer (the destination values). BlendMode is an X3DAppearanceChildNode node that handles blend operations.");
55
-
56
- BlendMode
57
- .appendTo (X3DUOM .find ("ConcreteNodes"))
58
- .attr ("name", "BlendMode");
59
-
60
- // DepthMode
61
- const DepthMode = X3DUOM .find ("ConcreteNode[name=Material]") .clone ();
62
-
63
- DepthMode .find ("field:not([name=metadata])") .remove ();
64
-
65
- DepthMode .find ("InterfaceDefinition")
66
- .attr ("specificationUrl", "https://create3000.github.io/x_ite/components/x-ite/depthmode/")
67
- .attr ("appinfo", "DepthMode contains parameters that are specific for depth control, like the value used for depth buffer comparisons.");
68
-
69
- DepthMode
70
- .appendTo (X3DUOM .find ("ConcreteNodes"))
71
- .attr ("name", "DepthMode");
72
-
73
31
  module .exports = X3DUOM;
@@ -22,6 +22,7 @@ $.fn.materialPreviewPopover = async function (node)
22
22
  .attr ("splashScreen", false)
23
23
  .attr ("contextMenu", false)
24
24
  .attr ("notifications", false)
25
+ .attr ("colorSpace", node .getBrowser () .getBrowserOption ("ColorSpace"))
25
26
  .appendTo (preview);
26
27
 
27
28
  const
@@ -46,6 +46,7 @@ $.fn.texturePreviewPopover = async function (node)
46
46
  .attr ("splashScreen", false)
47
47
  .attr ("contextMenu", false)
48
48
  .attr ("notifications", false)
49
+ .attr ("colorSpace", node .getBrowser () .getBrowserOption ("ColorSpace"))
49
50
  .appendTo (preview);
50
51
 
51
52
  const
@@ -8,6 +8,7 @@ const
8
8
  UndoManager = require ("../Undo/UndoManager"),
9
9
  Primitives = require ("./Primitives"),
10
10
  StringSimilarity = require ("string-similarity"),
11
+ Traverse = require("../Application/Traverse"),
11
12
  _ = require ("../Application/GetText");
12
13
 
13
14
  module .exports = new class Library extends Dialog
@@ -377,6 +378,27 @@ module .exports = new class Library extends Dialog
377
378
  node = (await Editor .importX3D (this .executionContext, x3dSyntax)) .pop (),
378
379
  field = this .field ?? $.try (() => this .node ?.getField (node .getContainerField ()));
379
380
 
381
+ if (this .browser .getBrowserOption ("ColorSpace") === "LINEAR")
382
+ {
383
+ Traverse .traverse (node, Traverse .ROOT_NODES, node =>
384
+ {
385
+ for (const field of node .getFields ())
386
+ {
387
+ switch (field .getType ())
388
+ {
389
+ case X3D .X3DConstants .SFColor:
390
+ case X3D .X3DConstants .SFColorRGBA:
391
+ field .assign (field .sRGBToLinear ());
392
+ break;
393
+ case X3D .X3DConstants .MFColor:
394
+ case X3D .X3DConstants .MFColorRGBA:
395
+ field .assign (field .map (value => value .sRGBToLinear ()));
396
+ break;
397
+ }
398
+ }
399
+ });
400
+ }
401
+
380
402
  switch (field ?.getType ())
381
403
  {
382
404
  case X3D .X3DConstants .SFNode:
@@ -1930,7 +1930,7 @@ module .exports = class OutlineEditor extends OutlineRouteGraph
1930
1930
  })
1931
1931
  .on ("beforeShow.spectrum", (event) =>
1932
1932
  {
1933
- button .spectrum ("set", button .css ("background-color"));
1933
+ button .spectrum ("set", this .getColorFromField (node, this .linearToSRGB (node, field), "SRGB"));
1934
1934
  })
1935
1935
  .on("move.spectrum", (event, tinyColor) =>
1936
1936
  {
@@ -1945,7 +1945,7 @@ module .exports = class OutlineEditor extends OutlineRouteGraph
1945
1945
  if (value .getType () === X3D .X3DConstants .SFColorRGBA)
1946
1946
  value .a = rgb .a;
1947
1947
 
1948
- Editor .setFieldValue (node .getExecutionContext (), node, field, value);
1948
+ Editor .setFieldValue (node .getExecutionContext (), node, field, this .sRGBToLinear (node, value));
1949
1949
  })
1950
1950
  .on ("dragstart.spectrum", (event, tinyColor) =>
1951
1951
  {
@@ -52,6 +52,7 @@ module .exports = class OutlineView extends Interface
52
52
  .on ("dragend", this .onDragEnd .bind (this))
53
53
  .appendTo (this .treeView);
54
54
 
55
+ this .browser .getBrowserOptions () ._ColorSpace .addInterest ("updateSceneGraph", this);
55
56
  this .browser ._activeLayer .addInterest ("updateActiveLayer", this);
56
57
 
57
58
  electron .ipcRenderer .on ("deselect-all", () => this .deselectAll ());
@@ -1420,7 +1421,7 @@ module .exports = class OutlineView extends Interface
1420
1421
  $("<div></div>")
1421
1422
  .addClass (["color-button", "field-button"])
1422
1423
  .attr ("title", _("Open color picker."))
1423
- .css ("background-color", this .getColorFromField (field))
1424
+ .css ("background-color", this .getColorFromField (node, field))
1424
1425
  .appendTo (child);
1425
1426
 
1426
1427
  field .addFieldCallback (this .#fieldButtonSymbol, this .updateColor .bind (this, parent, node, field));
@@ -1718,18 +1719,31 @@ module .exports = class OutlineView extends Interface
1718
1719
  updateColor (parent, node, field)
1719
1720
  {
1720
1721
  parent .find (`.field[field-id=${field .getId ()}] > .item .color-button`)
1721
- .css ("background-color", this .getColorFromField (field))
1722
+ .css ("background-color", this .getColorFromField (node, field))
1722
1723
  }
1723
1724
 
1724
- getColorFromField (field)
1725
+ getColorFromField (node, field, colorSpace = this .browser .getBrowserOption ("ColorSpace"))
1725
1726
  {
1726
- const
1727
- r = Math .floor (field .r * 255),
1728
- g = Math .floor (field .g * 255),
1729
- b = Math .floor (field .b * 255),
1730
- a = field .a ?? 1
1727
+ if (colorSpace === "LINEAR" || (colorSpace === "LINEAR_WHEN_PHYSICAL_MATERIAL" && this .isPhysical (node)))
1728
+ {
1729
+ const
1730
+ r = field .r * 100,
1731
+ g = field .g * 100,
1732
+ b = field .b * 100,
1733
+ a = field .a ?? 1;
1731
1734
 
1732
- return `rgba(${r},${g},${b},${a})`
1735
+ return `color(srgb-linear ${r}% ${g}% ${b}% / ${a})`;
1736
+ }
1737
+ else
1738
+ {
1739
+ const
1740
+ r = field .r * 255,
1741
+ g = field .g * 255,
1742
+ b = field .b * 255,
1743
+ a = field .a ?? 1;
1744
+
1745
+ return `rgba(${r},${g},${b},${a})`;
1746
+ }
1733
1747
  }
1734
1748
 
1735
1749
  getAccessTypeImage (field, active)