Browse Source

Merge branch 'release/1.10.x'

rdb 1 year ago
parent
commit
5f96cc592e

+ 48 - 17
direct/src/filter/CommonFilters.py

@@ -100,6 +100,11 @@ void fshader(out float4 o_color : COLOR,
 """
 """
 
 
 
 
+class ToneMap:
+    ACES = object()
+    PBR_NEUTRAL = object()
+
+
 class FilterConfig:
 class FilterConfig:
     pass
     pass
 
 
@@ -279,16 +284,19 @@ class CommonFilters:
 
 
             text = "//Cg\n"
             text = "//Cg\n"
             if "HighDynamicRange" in configuration:
             if "HighDynamicRange" in configuration:
-                text += "static const float3x3 aces_input_mat = {\n"
-                text += "  {0.59719, 0.35458, 0.04823},\n"
-                text += "  {0.07600, 0.90834, 0.01566},\n"
-                text += "  {0.02840, 0.13383, 0.83777},\n"
-                text += "};\n"
-                text += "static const float3x3 aces_output_mat = {\n"
-                text += "  { 1.60475, -0.53108, -0.07367},\n"
-                text += "  {-0.10208,  1.10813, -0.00605},\n"
-                text += "  {-0.00327, -0.07276,  1.07602},\n"
-                text += "};\n"
+                tonemap = configuration["HighDynamicRange"]
+                if tonemap is ToneMap.ACES:
+                    text += "static const float3x3 aces_input_mat = {\n"
+                    text += "  {0.59719, 0.35458, 0.04823},\n"
+                    text += "  {0.07600, 0.90834, 0.01566},\n"
+                    text += "  {0.02840, 0.13383, 0.83777},\n"
+                    text += "};\n"
+                    text += "static const float3x3 aces_output_mat = {\n"
+                    text += "  { 1.60475, -0.53108, -0.07367},\n"
+                    text += "  {-0.10208,  1.10813, -0.00605},\n"
+                    text += "  {-0.00327, -0.07276,  1.07602},\n"
+                    text += "};\n"
+
             text += "void vshader(float4 vtx_position : POSITION,\n"
             text += "void vshader(float4 vtx_position : POSITION,\n"
             text += "  out float4 l_position : POSITION,\n"
             text += "  out float4 l_position : POSITION,\n"
 
 
@@ -381,10 +389,30 @@ class CommonFilters:
             if "ExposureAdjust" in configuration:
             if "ExposureAdjust" in configuration:
                 text += "  o_color.rgb *= k_exposure;\n"
                 text += "  o_color.rgb *= k_exposure;\n"
 
 
-            # With thanks to Stephen Hill!
             if "HighDynamicRange" in configuration:
             if "HighDynamicRange" in configuration:
-                text += "  float3 aces_color = mul(aces_input_mat, o_color.rgb);\n"
-                text += "  o_color.rgb = saturate(mul(aces_output_mat, (aces_color * (aces_color + 0.0245786f) - 0.000090537f) / (aces_color * (0.983729f * aces_color + 0.4329510f) + 0.238081f)));\n"
+                tonemap = configuration["HighDynamicRange"]
+                if tonemap is ToneMap.ACES:
+                    # With thanks to Stephen Hill!
+                    text += "  float3 aces_color = mul(aces_input_mat, o_color.rgb);\n"
+                    text += "  o_color.rgb = saturate(mul(aces_output_mat, (aces_color * (aces_color + 0.0245786f) - 0.000090537f) / (aces_color * (0.983729f * aces_color + 0.4329510f) + 0.238081f)));\n"
+                elif tonemap is ToneMap.PBR_NEUTRAL:
+                    text += "  const float start_compression = 0.8 - 0.04;\n"
+                    text += "  const float desaturation = 0.15;\n"
+
+                    text += "  float x = min(o_color.r, min(o_color.g, o_color.b));\n"
+                    text += "  float offset = x < 0.08 ? x - 6.25 * x * x : 0.04;\n"
+                    text += "  o_color.rgb -= offset;\n"
+
+                    text += "  float peak = max(o_color.r, max(o_color.g, o_color.b));\n"
+
+                    text += "  if (peak >= start_compression) {\n"
+                    text += "    const float d = 1.0 - start_compression;\n"
+                    text += "    float new_peak = 1.0 - d * d / (peak + d - start_compression);\n"
+                    text += "    o_color.rgb *= new_peak / peak;\n"
+                    text += "    float g = 1.0 - 1.0 / (desaturation * (peak - new_peak) + 1.0);\n"
+
+                    text += "    o_color.rgb = lerp(o_color.rgb, new_peak * float3(1, 1, 1), g);\n"
+                    text += "}\n"
 
 
             if "GammaAdjust" in configuration:
             if "GammaAdjust" in configuration:
                 gamma = configuration["GammaAdjust"]
                 gamma = configuration["GammaAdjust"]
@@ -668,10 +696,10 @@ class CommonFilters:
             return self.reconfigure(old_enable, "SrgbEncode")
             return self.reconfigure(old_enable, "SrgbEncode")
         return True
         return True
 
 
-    def setHighDynamicRange(self):
+    def setHighDynamicRange(self, tonemap=ToneMap.ACES):
         """ Enables HDR rendering by using a floating-point framebuffer,
         """ Enables HDR rendering by using a floating-point framebuffer,
         disabling color clamping on the main scene, and applying a tone map
         disabling color clamping on the main scene, and applying a tone map
-        operator (ACES).
+        operator (ACES or Khronos PBR Neutral).
 
 
         It may also be necessary to use setExposureAdjust to perform exposure
         It may also be necessary to use setExposureAdjust to perform exposure
         compensation on the scene, depending on the lighting intensity.
         compensation on the scene, depending on the lighting intensity.
@@ -679,8 +707,11 @@ class CommonFilters:
         .. versionadded:: 1.10.7
         .. versionadded:: 1.10.7
         """
         """
 
 
-        fullrebuild = (("HighDynamicRange" in self.configuration) is False)
-        self.configuration["HighDynamicRange"] = 1
+        fullrebuild = "HighDynamicRange" not in self.configuration or \
+                      self.configuration["HighDynamicRange"] is not tonemap
+        if tonemap is not ToneMap.ACES and tonemap is not ToneMap.PBR_NEUTRAL:
+            raise ValueError("Invalid value for tonemap")
+        self.configuration["HighDynamicRange"] = tonemap
         return self.reconfigure(fullrebuild, "HighDynamicRange")
         return self.reconfigure(fullrebuild, "HighDynamicRange")
 
 
     def delHighDynamicRange(self):
     def delHighDynamicRange(self):

+ 2 - 3
direct/src/fsm/FSM.py

@@ -485,9 +485,8 @@ class FSM(DirectObject):
                     new_index = (cur_index + 1) % len(self.stateArray)
                     new_index = (cur_index + 1) % len(self.stateArray)
                     return self.request(self.stateArray[new_index], args)
                     return self.request(self.stateArray[new_index], args)
             else:
             else:
-                assert self.notifier.debug(
+                assert self.notify.debug(
                                     "stateArray empty. Can't switch to next.")
                                     "stateArray empty. Can't switch to next.")
-
         finally:
         finally:
             self.fsmLock.release()
             self.fsmLock.release()
 
 
@@ -503,7 +502,7 @@ class FSM(DirectObject):
                     new_index = (cur_index - 1) % len(self.stateArray)
                     new_index = (cur_index - 1) % len(self.stateArray)
                     return self.request(self.stateArray[new_index], args)
                     return self.request(self.stateArray[new_index], args)
             else:
             else:
-                assert self.notifier.debug(
+                assert self.notify.debug(
                                     "stateArray empty. Can't switch to next.")
                                     "stateArray empty. Can't switch to next.")
         finally:
         finally:
             self.fsmLock.release()
             self.fsmLock.release()

+ 2 - 2
direct/src/interval/cMetaInterval.cxx

@@ -679,7 +679,7 @@ write(std::ostream &out, int indent_level) const {
   int total_digits = num_decimals + 4;
   int total_digits = num_decimals + 4;
   static const int max_digits = 32;  // totally arbitrary
   static const int max_digits = 32;  // totally arbitrary
   nassertv(total_digits <= max_digits);
   nassertv(total_digits <= max_digits);
-  char format_str[16];
+  char format_str[26];
   sprintf(format_str, "%%%d.%df", total_digits, num_decimals);
   sprintf(format_str, "%%%d.%df", total_digits, num_decimals);
 
 
   indent(out, indent_level) << get_name() << ":\n";
   indent(out, indent_level) << get_name() << ":\n";
@@ -708,7 +708,7 @@ timeline(std::ostream &out) const {
   int total_digits = num_decimals + 4;
   int total_digits = num_decimals + 4;
   static const int max_digits = 32;  // totally arbitrary
   static const int max_digits = 32;  // totally arbitrary
   nassertv(total_digits <= max_digits);
   nassertv(total_digits <= max_digits);
-  char format_str[16];
+  char format_str[26];
   sprintf(format_str, "%%%d.%df", total_digits, num_decimals);
   sprintf(format_str, "%%%d.%df", total_digits, num_decimals);
 
 
   int extra_indent_level = 0;
   int extra_indent_level = 0;

+ 1 - 1
direct/src/stdpy/glob.py

@@ -52,7 +52,7 @@ def glob1(dirname, pattern):
     if not dirname:
     if not dirname:
         dirname = os.curdir
         dirname = os.curdir
     try:
     try:
-        names = os.listdir(dirname)
+        names = file.listdir(dirname)
     except os.error:
     except os.error:
         return []
         return []
     if pattern[0] != '.':
     if pattern[0] != '.':

+ 1 - 1
panda/src/glstuff/glShaderContext_src.cxx

@@ -1839,7 +1839,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
               << " is bound to image unit " << binding << "\n";
               << " is bound to image unit " << binding << "\n";
           }
           }
 
 
-          if (binding >= _glsl_img_inputs.size()) {
+          if (binding >= (GLint)_glsl_img_inputs.size()) {
             _glsl_img_inputs.resize(binding + 1);
             _glsl_img_inputs.resize(binding + 1);
           }
           }
 
 

+ 22 - 8
panda/src/pgui/pgItem.cxx

@@ -775,9 +775,14 @@ move(const MouseWatcherParameter &param) {
  */
  */
 void PGItem::
 void PGItem::
 background_press(const MouseWatcherParameter &param) {
 background_press(const MouseWatcherParameter &param) {
-  for (PGItem *item : _background_focus) {
+  // We have to be careful, because objects may remove themselves from the set
+  // while we're iterating over it.
+  auto it = _background_focus.begin();
+  while (it != _background_focus.end()) {
+    PGItem *item = *it++;
     if (!item->get_focus()) {
     if (!item->get_focus()) {
-      item->press(param, true);
+      PT(PGItem) item_ref(item);
+      item_ref->press(param, true);
     }
     }
   }
   }
 }
 }
@@ -787,9 +792,12 @@ background_press(const MouseWatcherParameter &param) {
  */
  */
 void PGItem::
 void PGItem::
 background_release(const MouseWatcherParameter &param) {
 background_release(const MouseWatcherParameter &param) {
-  for (PGItem *item : _background_focus) {
+  auto it = _background_focus.begin();
+  while (it != _background_focus.end()) {
+    PGItem *item = *it++;
     if (!item->get_focus()) {
     if (!item->get_focus()) {
-      item->release(param, true);
+      PT(PGItem) item_ref(item);
+      item_ref->release(param, true);
     }
     }
   }
   }
 }
 }
@@ -799,9 +807,12 @@ background_release(const MouseWatcherParameter &param) {
  */
  */
 void PGItem::
 void PGItem::
 background_keystroke(const MouseWatcherParameter &param) {
 background_keystroke(const MouseWatcherParameter &param) {
-  for (PGItem *item : _background_focus) {
+  auto it = _background_focus.begin();
+  while (it != _background_focus.end()) {
+    PGItem *item = *it++;
     if (!item->get_focus()) {
     if (!item->get_focus()) {
-      item->keystroke(param, true);
+      PT(PGItem) item_ref(item);
+      item_ref->keystroke(param, true);
     }
     }
   }
   }
 }
 }
@@ -811,9 +822,12 @@ background_keystroke(const MouseWatcherParameter &param) {
  */
  */
 void PGItem::
 void PGItem::
 background_candidate(const MouseWatcherParameter &param) {
 background_candidate(const MouseWatcherParameter &param) {
-  for (PGItem *item : _background_focus) {
+  auto it = _background_focus.begin();
+  while (it != _background_focus.end()) {
+    PGItem *item = *it++;
     if (!item->get_focus()) {
     if (!item->get_focus()) {
-      item->candidate(param, true);
+      PT(PGItem) item_ref(item);
+      item_ref->candidate(param, true);
     }
     }
   }
   }
 }
 }

+ 7 - 6
panda/src/putil/simpleHashMap.I

@@ -292,8 +292,8 @@ remove(const Key &key) {
 
 
   // Now remove this element.
   // Now remove this element.
   size_t last = _num_entries - 1;
   size_t last = _num_entries - 1;
-  size_t index = (size_t)index_array[slot];
-  if (index < _num_entries) {
+  int index = index_array[slot];
+  if ((size_t)index < _num_entries) {
     // Find the last element in the index array.
     // Find the last element in the index array.
     int other_slot = find_slot(_table[last]._key);
     int other_slot = find_slot(_table[last]._key);
     nassertr(other_slot != -1, false);
     nassertr(other_slot != -1, false);
@@ -301,7 +301,7 @@ remove(const Key &key) {
 
 
     // Swap it with the last one, so that we don't get any gaps in the table
     // Swap it with the last one, so that we don't get any gaps in the table
     // of entries.
     // of entries.
-    _table[index] = std::move(_table[last]);
+    _table[(size_t)index] = std::move(_table[last]);
     index_array[(size_t)other_slot] = index;
     index_array[(size_t)other_slot] = index;
   }
   }
 
 
@@ -321,13 +321,13 @@ remove(const Key &key) {
   // Now we have put a hole in the index array.  If there was a hash conflict
   // Now we have put a hole in the index array.  If there was a hash conflict
   // in the slot after this one, we have to move it down to close the hole.
   // in the slot after this one, we have to move it down to close the hole.
   slot = next_hash(slot);
   slot = next_hash(slot);
-  while (has_slot(slot)) {
-    size_t index = (size_t)index_array[slot];
+  index = index_array[slot];
+  while (index >= 0) {
     size_t wants_slot = get_hash(_table[index]._key);
     size_t wants_slot = get_hash(_table[index]._key);
     if (wants_slot != slot) {
     if (wants_slot != slot) {
       // This one was a hash conflict; try to put it where it belongs.  We
       // This one was a hash conflict; try to put it where it belongs.  We
       // can't just put it in n, since maybe it belongs somewhere after n.
       // can't just put it in n, since maybe it belongs somewhere after n.
-      while (wants_slot != slot && has_slot(wants_slot)) {
+      while (wants_slot != slot && index_array[wants_slot] >= 0) {
         wants_slot = next_hash(wants_slot);
         wants_slot = next_hash(wants_slot);
       }
       }
       if (wants_slot != slot) {
       if (wants_slot != slot) {
@@ -341,6 +341,7 @@ remove(const Key &key) {
     // Continue until we encounter the next unused slot.  Until we do, we
     // Continue until we encounter the next unused slot.  Until we do, we
     // can't be sure we've found all of the potential hash conflicts.
     // can't be sure we've found all of the potential hash conflicts.
     slot = next_hash(slot);
     slot = next_hash(slot);
+    index = index_array[slot];
   }
   }
 
 
 #ifdef _DEBUG
 #ifdef _DEBUG

+ 16 - 16
panda/src/text/textAssembler.cxx

@@ -427,14 +427,14 @@ calc_r_c(int &r, int &c, int n) const {
     c = 0;
     c = 0;
     int i = row._row_start;
     int i = row._row_start;
     while (i < n - 1) {
     while (i < n - 1) {
-      if (_text_string[i]._character != text_soft_hyphen_key &&
-          _text_string[i]._character != text_soft_break_key) {
+      if (_text_string[i]._character != (char32_t)text_soft_hyphen_key &&
+          _text_string[i]._character != (char32_t)text_soft_break_key) {
         ++c;
         ++c;
       }
       }
       ++i;
       ++i;
     }
     }
-    if (_text_string[n - 1]._character != text_soft_hyphen_key &&
-        _text_string[n - 1]._character != text_soft_break_key) {
+    if (_text_string[n - 1]._character != (char32_t)text_soft_hyphen_key &&
+        _text_string[n - 1]._character != (char32_t)text_soft_break_key) {
       ++c;
       ++c;
       if (_text_string[n - 1]._character == '\n') {
       if (_text_string[n - 1]._character == '\n') {
         is_real_char = false;
         is_real_char = false;
@@ -478,8 +478,8 @@ calc_index(int r, int c) const {
       // we have to scan past them to get n precisely.
       // we have to scan past them to get n precisely.
       int n = row._row_start;
       int n = row._row_start;
       while (c > 0) {
       while (c > 0) {
-        if (_text_string[n]._character != text_soft_hyphen_key &&
-            _text_string[n]._character != text_soft_break_key) {
+        if (_text_string[n]._character != (char32_t)text_soft_hyphen_key &&
+            _text_string[n]._character != (char32_t)text_soft_break_key) {
           --c;
           --c;
         }
         }
         ++n;
         ++n;
@@ -798,13 +798,13 @@ scan_wtext(TextAssembler::TextString &output_string,
            const wstring::const_iterator &send,
            const wstring::const_iterator &send,
            TextAssembler::ComputedProperties *current_cprops) {
            TextAssembler::ComputedProperties *current_cprops) {
   while (si != send) {
   while (si != send) {
-    if ((*si) == text_push_properties_key) {
+    if ((*si) == (wchar_t)text_push_properties_key) {
       // This indicates a nested properties structure.  Pull off the name of
       // This indicates a nested properties structure.  Pull off the name of
       // the TextProperties structure, which is everything until the next
       // the TextProperties structure, which is everything until the next
       // text_push_properties_key.
       // text_push_properties_key.
       wstring wname;
       wstring wname;
       ++si;
       ++si;
-      while (si != send && (*si) != text_push_properties_key) {
+      while (si != send && (*si) != (wchar_t)text_push_properties_key) {
         wname += (*si);
         wname += (*si);
         ++si;
         ++si;
       }
       }
@@ -835,20 +835,20 @@ scan_wtext(TextAssembler::TextString &output_string,
         }
         }
       }
       }
 
 
-    } else if ((*si) == text_pop_properties_key) {
+    } else if ((*si) == (wchar_t)text_pop_properties_key) {
       // This indicates the undoing of a previous push_properties_key.  We
       // This indicates the undoing of a previous push_properties_key.  We
       // simply return to the previous level.
       // simply return to the previous level.
       ++si;
       ++si;
       return;
       return;
 
 
-    } else if ((*si) == text_embed_graphic_key) {
+    } else if ((*si) == (wchar_t)text_embed_graphic_key) {
       // This indicates an embedded graphic.  Pull off the name of the
       // This indicates an embedded graphic.  Pull off the name of the
       // TextGraphic structure, which is everything until the next
       // TextGraphic structure, which is everything until the next
       // text_embed_graphic_key.
       // text_embed_graphic_key.
 
 
       wstring graphic_wname;
       wstring graphic_wname;
       ++si;
       ++si;
-      while (si != send && (*si) != text_embed_graphic_key) {
+      while (si != send && (*si) != (wchar_t)text_embed_graphic_key) {
         graphic_wname += (*si);
         graphic_wname += (*si);
         ++si;
         ++si;
       }
       }
@@ -980,7 +980,7 @@ wordwrap_text() {
       }
       }
 
 
       if (isspacew(_text_string[q]._character) ||
       if (isspacew(_text_string[q]._character) ||
-          _text_string[q]._character == text_soft_break_key) {
+          _text_string[q]._character == (char32_t)text_soft_break_key) {
         if (!last_was_space) {
         if (!last_was_space) {
           any_spaces = true;
           any_spaces = true;
           // We only care about logging whether there is a soft-hyphen
           // We only care about logging whether there is a soft-hyphen
@@ -997,7 +997,7 @@ wordwrap_text() {
 
 
       // A soft hyphen character is not printed, but marks a point at which we
       // A soft hyphen character is not printed, but marks a point at which we
       // might hyphenate a word if we need to.
       // might hyphenate a word if we need to.
-      if (_text_string[q]._character == text_soft_hyphen_key) {
+      if (_text_string[q]._character == (char32_t)text_soft_hyphen_key) {
         if (wordwrap_width > 0.0f) {
         if (wordwrap_width > 0.0f) {
           // We only consider this as a possible hyphenation point if (a) it
           // We only consider this as a possible hyphenation point if (a) it
           // is not the very first character, and (b) there is enough room for
           // is not the very first character, and (b) there is enough room for
@@ -1104,8 +1104,8 @@ wordwrap_text() {
     }
     }
 
 
     for (size_t pi = p; pi < q; pi++) {
     for (size_t pi = p; pi < q; pi++) {
-      if (_text_string[pi]._character != text_soft_hyphen_key &&
-          _text_string[pi]._character != text_soft_break_key) {
+      if (_text_string[pi]._character != (char32_t)text_soft_hyphen_key &&
+          _text_string[pi]._character != (char32_t)text_soft_break_key) {
         _text_block.back()._string.push_back(_text_string[pi]);
         _text_block.back()._string.push_back(_text_string[pi]);
       } else {
       } else {
         _text_block.back()._got_soft_hyphens = true;
         _text_block.back()._got_soft_hyphens = true;
@@ -1577,7 +1577,7 @@ assemble_row(TextAssembler::TextRow &row,
       xpos = (floor(xpos / tab_width) + 1.0f) * tab_width;
       xpos = (floor(xpos / tab_width) + 1.0f) * tab_width;
       prev_char = -1;
       prev_char = -1;
 
 
-    } else if (character == text_soft_hyphen_key) {
+    } else if (character == (char32_t)text_soft_hyphen_key) {
       // And so is the 'soft-hyphen' key character.
       // And so is the 'soft-hyphen' key character.
 
 
     } else if (graphic != nullptr) {
     } else if (graphic != nullptr) {